Skip to content

Commit

Permalink
Uploader (preliminary version)
Browse files Browse the repository at this point in the history
  • Loading branch information
mederly committed Mar 9, 2015
1 parent f3e21c3 commit 2bbe7e7
Show file tree
Hide file tree
Showing 2 changed files with 325 additions and 0 deletions.
4 changes: 4 additions & 0 deletions samples/model-client-sample/src/main/bin/upload.bat
@@ -0,0 +1,4 @@
rem Sets the basedir to the directory where libraries are located
set BASEDIR=%~dp0

java -classpath "%BASEDIR%*;%BASEDIR%lib\*" com.evolveum.midpoint.testing.model.client.sample.Upload %*
@@ -0,0 +1,321 @@
/*
* Copyright (c) 2010-2015 Evolveum
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.evolveum.midpoint.testing.model.client.sample;

import com.evolveum.midpoint.model.client.ModelClientUtil;
import com.evolveum.midpoint.xml.ns._public.common.api_types_3.ExecuteScriptsOptionsType;
import com.evolveum.midpoint.xml.ns._public.common.api_types_3.ObjectDeltaListType;
import com.evolveum.midpoint.xml.ns._public.common.api_types_3.ObjectDeltaOperationListType;
import com.evolveum.midpoint.xml.ns._public.common.api_types_3.OutputFormatType;
import com.evolveum.midpoint.xml.ns._public.common.api_types_3.SingleScriptOutputType;
import com.evolveum.midpoint.xml.ns._public.common.common_3.ModelExecuteOptionsType;
import com.evolveum.midpoint.xml.ns._public.common.common_3.ObjectDeltaOperationType;
import com.evolveum.midpoint.xml.ns._public.common.common_3.ObjectType;
import com.evolveum.midpoint.xml.ns._public.common.common_3.OperationResultStatusType;
import com.evolveum.midpoint.xml.ns._public.common.common_3.OperationResultType;
import com.evolveum.midpoint.xml.ns._public.common.fault_3.FaultMessage;
import com.evolveum.midpoint.xml.ns._public.model.model_3.ExecuteChangesType;
import com.evolveum.midpoint.xml.ns._public.model.model_3.ExecuteScriptsResponseType;
import com.evolveum.midpoint.xml.ns._public.model.model_3.ExecuteScriptsType;
import com.evolveum.midpoint.xml.ns._public.model.model_3.ModelPortType;
import com.evolveum.midpoint.xml.ns._public.model.model_3.ModelService;
import com.evolveum.prism.xml.ns._public.types_3.ChangeTypeType;
import com.evolveum.prism.xml.ns._public.types_3.ObjectDeltaType;
import org.apache.commons.cli.CommandLine;
import org.apache.commons.cli.CommandLineParser;
import org.apache.commons.cli.GnuParser;
import org.apache.commons.cli.HelpFormatter;
import org.apache.commons.cli.OptionBuilder;
import org.apache.commons.cli.Options;
import org.apache.commons.io.IOUtils;
import org.apache.cxf.frontend.ClientProxy;
import org.apache.cxf.ws.security.wss4j.WSS4JOutInterceptor;
import org.apache.wss4j.dom.WSConstants;
import org.apache.wss4j.dom.handler.WSHandlerConstants;

import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBElement;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Marshaller;
import javax.xml.bind.Unmarshaller;
import javax.xml.namespace.QName;
import javax.xml.ws.BindingProvider;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.FilenameFilter;
import java.io.IOException;
import java.io.InputStream;
import java.io.StringWriter;
import java.util.HashMap;
import java.util.Map;
import java.util.Properties;

/**
* @author mederly
*
*/
public class Upload {

// Configuration
public static final String ADM_USERNAME = "administrator";
public static final String ADM_PASSWORD = "5ecr3t";
private static final String DEFAULT_ENDPOINT_URL = "http://localhost:8080/midpoint/model/model-3";

private static final String OPT_HELP = "h";
public static final String OPT_FILE_TO_UPLOAD = "f";
public static final String OPT_DIR_TO_UPLOAD = "d";
public static final String OPT_URL = "url";
public static final String OPT_USER = "u";
public static final String OPT_PASSWORD = "p";
public static final String OPT_FILE_FOR_RESULT = "fr";
public static final String OPT_HIDE_RESULT = "hr";
public static final String OPT_SHOW_RESULT = "sr";

private static boolean error = false; // TODO implement seriously

public static void main(String[] args) {
try {

Options options = new Options();
options.addOption(OPT_HELP, "help", false, "Print this help information");
options.addOption(OPT_FILE_TO_UPLOAD, "file", true, "File to be uploaded (XML for the moment)");
options.addOption(OPT_DIR_TO_UPLOAD, "dir", true, "Whole directory to be uploaded (XML files only for the moment)");
options.addOption(OPT_URL, true, "Endpoint URL (default: " + DEFAULT_ENDPOINT_URL + ")");
options.addOption(OPT_USER, "user", true, "User name (default: " + ADM_USERNAME + ")");
options.addOption(OPT_PASSWORD, "password", true, "Password");
options.addOption(OPT_FILE_FOR_RESULT, "file-for-result", true, "Name of the file to write operation result into");
options.addOption(OPT_HIDE_RESULT, "hide-result", false, "Don't display detailed operation result (default: showing if not SUCCESS)");
options.addOption(OPT_SHOW_RESULT, "show-result", false, "Always show detailed operation result (default: showing if not SUCCESS)");
CommandLineParser parser = new GnuParser();
CommandLine cmdline = parser.parse(options, args);

if (cmdline.hasOption(OPT_HELP) || (!cmdline.hasOption(OPT_FILE_TO_UPLOAD) && !cmdline.hasOption(OPT_DIR_TO_UPLOAD))) {
HelpFormatter helpFormatter = new HelpFormatter();
helpFormatter.printHelp("upload", options);
System.out.println("\nNote that currently it is possible to upload only one object per file (i.e. no <objects> tag), and the " +
"file must be written using fully specified XML namespaces (i.e. namespace-guessing algorithm allowing to write data " +
"without namespaces is not available).");
System.exit(-1);
}

System.out.println("=================================================================");

ModelPortType modelPort = createModelPort(cmdline);
if (cmdline.hasOption(OPT_FILE_TO_UPLOAD)) {
uploadFile(new File(cmdline.getOptionValue(OPT_FILE_TO_UPLOAD)), cmdline, modelPort);
}
if (cmdline.hasOption(OPT_DIR_TO_UPLOAD)) {
uploadDir(cmdline.getOptionValue(OPT_DIR_TO_UPLOAD), cmdline, modelPort);
}

} catch (Exception e) {
e.printStackTrace();
System.exit(-1);
}

if (error) {
System.exit(-1);
}
}

private static void uploadDir(String dirname, CommandLine cmdline, ModelPortType modelPort) {
File[] files = new File(dirname).listFiles(new FilenameFilter() {
@Override
public boolean accept(File dir, String name) {
return name.toUpperCase().endsWith(".XML");
}
});
for (File file : files) {
uploadFile(file, cmdline, modelPort);
}
}

private static void uploadFile(File file, CommandLine cmdline, ModelPortType modelPort) {
System.out.println("Uploading file " + file);
Object content;
try {
content = unmarshalFile(file);
} catch (JAXBException|FileNotFoundException e) {
System.err.println("Cannot read " + file + ": " + e.getMessage());
e.printStackTrace();
error = true;
return;
}
if (content == null) {
System.err.println("Nothing to be uploaded.");
error = true;
return;
}
if (!(content instanceof ObjectType)) {
System.err.println("Expected an ObjectType to be uploaded; found " + content.getClass());
error = true;
return;
}

ObjectType objectType = (ObjectType) content;
ObjectDeltaType objectDeltaType = new ObjectDeltaType();
objectDeltaType.setChangeType(ChangeTypeType.ADD);
objectDeltaType.setObjectType(ModelClientUtil.getTypeQName(objectType.getClass()));
objectDeltaType.setObjectToAdd(objectType);

ObjectDeltaListType objectDeltaListType = new ObjectDeltaListType();
objectDeltaListType.getDelta().add(objectDeltaType);

ModelExecuteOptionsType optionsType = new ModelExecuteOptionsType();
optionsType.setIsImport(true);
optionsType.setReevaluateSearchFilters(true);
optionsType.setRaw(true);
optionsType.setOverwrite(true);

ExecuteChangesType executeChangesType = new ExecuteChangesType();
executeChangesType.setDeltaList(objectDeltaListType);
executeChangesType.setOptions(optionsType);

ObjectDeltaOperationListType response;
try {
response = modelPort.executeChanges(objectDeltaListType, optionsType);
} catch (Exception e) {
System.err.println("Got exception when trying to execute the changes " + e.getMessage());
error = true;
return;
}

System.out.println("-----------------------------------------------------------------");

if (response == null) {
System.err.println("Unexpected empty response");
error = true;
return;
}
OperationResultType overallResult = new OperationResultType();
boolean allSuccess = true;
for (ObjectDeltaOperationType objectDeltaOperation : response.getDeltaOperation()) {
if (objectDeltaOperation.getObjectDelta() != null) {
ObjectDeltaType delta = objectDeltaOperation.getObjectDelta();
System.out.print(delta.getChangeType() + " delta with OID " + delta.getOid() + " ");
}
OperationResultType resultType = objectDeltaOperation.getExecutionResult();
System.out.println("resulted in " + getResultStatus(resultType));
if (resultType == null || resultType.getStatus() != OperationResultStatusType.SUCCESS) {
allSuccess = false;
error = true;
}
overallResult.getPartialResults().add(resultType);
}

if (!cmdline.hasOption(OPT_HIDE_RESULT) && (cmdline.hasOption(OPT_SHOW_RESULT) || !allSuccess)) {
System.out.println("\n\n" + marshalResult(overallResult));
}
if (cmdline.hasOption(OPT_FILE_FOR_RESULT)) {
String filename = cmdline.getOptionValue(OPT_FILE_FOR_RESULT);
try {
FileWriter fileWriter = new FileWriter(filename, true);
IOUtils.write(marshalResult(overallResult), fileWriter);
} catch (IOException e) {
System.err.println("Couldn't write operation result to file " + filename + ": " + e.getMessage());
e.printStackTrace();
error = true;
}
}

}

private static String getResultStatus(OperationResultType result) {
if (result == null) {
return "(null)";
} else {
return result.getStatus() + (result.getMessage() != null ? (": " + result.getMessage()) : "");
}
}

private static String marshalResult(OperationResultType result) {
if (result == null) {
return "";
} else {
try {
return marshalObject(new JAXBElement<>(new QName("result"), OperationResultType.class, result));
} catch (JAXBException|FileNotFoundException e) {
error = true;
return("Couldn't marshall result: " + e.getMessage());
}
}
}

private static JAXBContext jaxbContext = null;

private static JAXBContext getJaxbContext() throws JAXBException {
if (jaxbContext == null) {
jaxbContext = ModelClientUtil.instantiateJaxbContext();
}
return jaxbContext;
}

private static String marshalObject(Object object) throws JAXBException, FileNotFoundException {
JAXBContext jc = getJaxbContext();
Marshaller marshaller = jc.createMarshaller();
marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);

StringWriter sw = new StringWriter();
marshaller.marshal(object, sw);
return sw.toString();
}

private static Object unmarshalFile(File file) throws JAXBException, FileNotFoundException {
JAXBContext jc = ModelClientUtil.instantiateJaxbContext();
Unmarshaller unmarshaller = jc.createUnmarshaller();

Object o = unmarshaller.unmarshal(new FileInputStream(file));
if (o instanceof JAXBElement) {
return ((JAXBElement) o).getValue();
} else {
return o;
}
}

public static ModelPortType createModelPort(CommandLine cmdLine) {
String endpointUrl = cmdLine.getOptionValue(OPT_URL, DEFAULT_ENDPOINT_URL);
String user = cmdLine.getOptionValue(OPT_USER, ADM_USERNAME);
ClientPasswordHandler.setPassword(cmdLine.getOptionValue(OPT_PASSWORD, ADM_PASSWORD));
System.out.println("Endpoint URL: " + endpointUrl);

ModelService modelService = new ModelService();
ModelPortType modelPort = modelService.getModelPort();
BindingProvider bp = (BindingProvider)modelPort;
Map<String, Object> requestContext = bp.getRequestContext();
requestContext.put(BindingProvider.ENDPOINT_ADDRESS_PROPERTY, endpointUrl);

org.apache.cxf.endpoint.Client client = ClientProxy.getClient(modelPort);
org.apache.cxf.endpoint.Endpoint cxfEndpoint = client.getEndpoint();

Map<String,Object> outProps = new HashMap<>();

outProps.put(WSHandlerConstants.ACTION, WSHandlerConstants.USERNAME_TOKEN);
outProps.put(WSHandlerConstants.USER, user);
outProps.put(WSHandlerConstants.PASSWORD_TYPE, WSConstants.PW_DIGEST);
outProps.put(WSHandlerConstants.PW_CALLBACK_CLASS, ClientPasswordHandler.class.getName());

WSS4JOutInterceptor wssOut = new WSS4JOutInterceptor(outProps);
cxfEndpoint.getOutInterceptors().add(wssOut);

return modelPort;
}

}

0 comments on commit 2bbe7e7

Please sign in to comment.