com.evolveum.midpoint.testing.model.client.sample.Upload.java Source code

Java tutorial

Introduction

Here is the source code for com.evolveum.midpoint.testing.model.client.sample.Upload.java

Source

/*
 * 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;
    }

}