it.intecs.pisa.develenv.model.launch.ToolboxScriptRunLaunch.java Source code

Java tutorial

Introduction

Here is the source code for it.intecs.pisa.develenv.model.launch.ToolboxScriptRunLaunch.java

Source

/*
 * ****************************************************************************
 *  Copyright 2003*2004 Intecs
 ****************************************************************************
 *  This file is part of TOOLBOX.
 *
 *  TOOLBOX is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation; either version 2 of the License, or
 *  (at your option) any later version.
 *
 *  TOOLBOX is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with TOOLBOX; if not, write to the Free Software
 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 */

package it.intecs.pisa.develenv.model.launch;

import it.intecs.pisa.common.tbx.Operation;
import it.intecs.pisa.common.tbx.Service;
import it.intecs.pisa.develenv.model.asynchJobs.AsynchInfoDialogs;
import it.intecs.pisa.develenv.model.project.ToolboxEclipseProject;
import it.intecs.pisa.develenv.model.project.ToolboxEclipseProjectPreferences;
import it.intecs.pisa.develenv.model.project.ToolboxEclipseProjectUtil;
import it.intecs.pisa.util.DOMUtil;
import it.intecs.pisa.util.SOAPMessageBuilder;
import it.intecs.pisa.util.SOAPUtil;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Iterator;
import java.util.LinkedList;

import org.apache.commons.httpclient.HttpClient;
import org.apache.commons.httpclient.HttpException;
import org.apache.commons.httpclient.MultiThreadedHttpConnectionManager;
import org.apache.commons.httpclient.methods.GetMethod;
import org.apache.commons.httpclient.methods.InputStreamRequestEntity;
import org.apache.commons.httpclient.methods.PostMethod;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IFolder;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.IWorkspace;
import org.eclipse.core.resources.IWorkspaceRoot;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.Path;
import org.eclipse.debug.core.ILaunch;
import org.eclipse.debug.core.ILaunchConfiguration;
import org.eclipse.jface.dialogs.MessageDialog;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.xml.sax.SAXException;

/**
 * This class is used to execute a run
 * @author Massimiliano
 *
 */
public class ToolboxScriptRunLaunch {

    public static boolean execute(ILaunchConfiguration configuration, String mode, ILaunch launch,
            IProgressMonitor monitor) throws CoreException {
        String url;
        String pushUrl;
        String serviceName;
        String operationName;
        String testFilePath;
        String fileName;
        String pollingRate;
        IProject project;
        IFile testFile;
        IFile outputFile;
        IFile pushedMessageFile;
        IFile serviceDescriptorFile;
        IPath serviceDescriptorPath;
        IFolder testFolder;
        String soapAction;
        Service descriptor;
        SimpleDateFormat format;
        boolean isAsynchronous = false;
        Operation operation;
        InputStream inputStream;
        InputStream responseStream;
        InputStream pushedMessageStream;
        String messageId;
        final int monitorSteps = 8;
        String monitorTaskText;
        IWorkspace wrkSpace = ResourcesPlugin.getWorkspace();
        IWorkspaceRoot root = wrkSpace.getRoot();
        long checkEach = 1000;

        try {
            //retrieving configuration parameters
            serviceName = configuration.getAttribute(ToolboxScriptLaunchConfiguration.CONFIGURATION_SERVICE,
                    (String) null);
            operationName = configuration.getAttribute(ToolboxScriptLaunchConfiguration.CONFIGURATION_OPERATION,
                    (String) null);
            testFilePath = configuration.getAttribute(ToolboxScriptLaunchConfiguration.CONFIGURATION_TESTFILE,
                    (String) null);
            pollingRate = configuration.getAttribute(ToolboxScriptLaunchConfiguration.CONFIGURATION_POLLING_RATE,
                    (String) null);

            monitorTaskText = "Testing operation " + operationName + " exposed by the service " + serviceName;
            monitor.beginTask(monitorTaskText, monitorSteps);

            monitor.setTaskName("Retrieving TOOLBOX Url");
            //   preparing host url
            project = ToolboxEclipseProjectUtil.getProject(serviceName);
            url = getTestUrl(project);
            if (url == null) {
                notifyToolboxUrlError(serviceName);

                return false;
            }
            monitor.worked(1);

            //checking if the service is deployed
            monitor.setTaskName("Checking if the service is deployed");
            if (checkIfDeployed(project, serviceName, operationName) == false) {
                notifyServiceOrOperationNotDeployed(serviceName, operationName);

                return false;
            }
            monitor.worked(1);

            monitor.setTaskName("Updating polling rate");
            if (pollingRate != null) {
                if (updatePollingRate(project, serviceName, operationName, pollingRate) == false) {
                    return false;
                }
            }
            monitor.worked(1);

            monitor.setTaskName("Creating Push Url");
            pushUrl = getPushUrl(project);
            if (pushUrl == null) {
                notifyToolboxUrlError(serviceName);
                return false;
            }
            monitor.worked(1);

            monitor.setTaskName("Creating directory for storing messages");
            //getting Service descriptor
            serviceDescriptorFile = project.getFile(ToolboxEclipseProject.FILE_SERVICE_DESCRIPTOR);
            serviceDescriptorPath = root.getLocation().append(serviceDescriptorFile.getFullPath());

            descriptor = new Service();
            descriptor.loadFromFile(serviceDescriptorPath.toFile());

            operation = descriptor.getImplementedInterface().getOperationByName(operationName);
            soapAction = operation.getSoapAction();
            checkEach = getPollingRateInMilliseconds(operation, configuration);

            isAsynchronous = operation.getType().equals(Operation.OPERATION_TYPE_ASYNCHRONOUS);

            //creating test directory
            testFolder = createTestFolder(project);
            project.refreshLocal(IResource.DEPTH_INFINITE, monitor);

            testFile = testFolder.getFile("Input.xml");

            //creating test file
            format = new SimpleDateFormat("yyyyMMddHHmmss");
            messageId = serviceName + "_" + operationName + "_" + format.format(new Date());
            inputStream = createInputTestFile(testFilePath, pushUrl, messageId);

            //saving input test file
            saveFile(inputStream, testFile);
            //AsynchEditorOpener.openFileOnEditorWhenSizeGreaterThanZero(testFile);

            inputStream.close();
            project.refreshLocal(IResource.DEPTH_INFINITE, monitor);
            monitor.worked(1);

            inputStream = createInputTestFile(testFilePath, pushUrl, messageId);
            monitor.setTaskName("Invoking operation");
            responseStream = sendFile(url, soapAction, inputStream);
            project.refreshLocal(IResource.DEPTH_INFINITE, monitor);
            monitor.worked(1);

            monitor.setTaskName("Saving operation response");

            if (isAsynchronous)
                fileName = "InputAck.xml";
            else
                fileName = "Output.xml";

            outputFile = testFolder.getFile(fileName);
            saveFile(responseStream, outputFile);

            responseStream.close();
            project.refreshLocal(IResource.DEPTH_INFINITE, monitor);
            monitor.worked(1);

            if (checkIfSOAPFault(outputFile)) {
                AsynchInfoDialogs.showErrorDialog("Error while running operation", "Toolbox returned a SOAP fault");
                return false;
            }

            if (isAsynchronous)
                retrieveExecutionTree(project, serviceName, "A", messageId, "executionResult_responseBuilder.xml",
                        testFolder);
            else
                retrieveExecutionTree(project, serviceName, "S", messageId, "executionResult.xml", testFolder);

            if (isAsynchronous && monitor.isCanceled() == false) {
                monitor.setTaskName("Checking for pushed message");
                //performing wait until pushed message arrives
                pushedMessageStream = performCheckForPushedMessage(project, messageId, checkEach, monitor, launch);

                if (pushedMessageStream != null) {
                    pushedMessageFile = testFolder.getFile("Output.xml");
                    saveFile(pushedMessageStream, pushedMessageFile);
                    pushedMessageStream.close();

                    project.refreshLocal(IResource.DEPTH_INFINITE, monitor);
                    monitor.worked(1);

                    outputFile = pushedMessageFile;
                }
            }

            retrieveExecutionTree(project, serviceName, "A", messageId, "executionResult_firstScript.xml",
                    testFolder);
            retrieveExecutionTree(project, serviceName, "A", messageId, "executionResult_secondScript.xml",
                    testFolder);
            retrieveExecutionTree(project, serviceName, "A", messageId, "executionResult_thirdScript.xml",
                    testFolder);

            if (monitor.isCanceled())
                AsynchInfoDialogs.showInfoDialog("Running operation", "Execution terminated by the user.");
            else if (checkIfSOAPFault(outputFile))
                AsynchInfoDialogs.showErrorDialog("Error while running operation", "Toolbox returned a SOAP fault");
            else
                AsynchInfoDialogs.showInfoDialog("Running operation", "Test completed.");

        } catch (Exception e) {
            AsynchInfoDialogs.showErrorDialog("Running operation",
                    "The following error has occurred while testing the operation: " + e.getMessage());

            return false;
        } finally {
            monitor.done();
        }
        return true;
    }

    private static void retrieveExecutionTree(IProject prj, String serviceName, String instanceType,
            String messageId, String resourceKey, IFolder folder) {
        String url;
        HttpClient client;
        GetMethod method;
        int statusCode;
        InputStream response;
        Document doc;
        DOMUtil util;
        IFile file;
        try {
            util = new DOMUtil();

            url = ToolboxEclipseProjectPreferences.getToolboxHostURL(prj);
            url += "/manager?cmd=getResource&serviceName=" + serviceName;
            url += "&instanceId=" + messageId;
            url += "&resourceKey=" + resourceKey;
            url += "&instanceType=" + instanceType;

            client = new HttpClient();
            method = new GetMethod(url);

            statusCode = client.executeMethod(method);
            if (statusCode != 200)
                return;

            response = method.getResponseBodyAsStream();
            doc = util.inputStreamToDocument(response);

            file = folder.getFile(resourceKey);

            DOMUtil.dumpXML(doc, new File(file.getLocationURI()));
        } catch (Exception e) {
            e.printStackTrace();
        }

    }

    protected static long getPollingRateInMilliseconds(Operation operation, ILaunchConfiguration configuration) {
        String pollingRateStr = null;

        try {
            if (operation.isAsynchronous() == false)
                return 10000;

            pollingRateStr = configuration.getAttribute(ToolboxScriptLaunchConfiguration.CONFIGURATION_POLLING_RATE,
                    "");

            if (pollingRateStr.equals("")) {
                pollingRateStr = operation.getPollingRate();
            }

            return getPollingRateInSeconds(pollingRateStr) * 1000;
        } catch (Exception e) {
            return 10000;
        }
    }

    protected static long getPollingRateInSeconds(String pr) {
        char granularity;
        long multiplier = 0;
        String value;

        granularity = pr.charAt(pr.length() - 1);

        switch (granularity) {
        case 's':
            multiplier = 1;
            break;

        case 'm':
            multiplier = 60;
            break;

        case 'h':
            multiplier = 3600;
            break;

        case 'd':
            multiplier = 86400;
            break;

        case 'w':
            multiplier = 604800;
            break;
        }

        value = pr.substring(0, pr.length() - 1);
        return Long.parseLong(value) * multiplier;
    }

    protected static boolean updatePollingRate(IProject project, String serviceName, String operationName,
            String pollingRate) {
        String url;
        HttpClient client;
        GetMethod method;
        int statusCode;

        url = ToolboxEclipseProjectPreferences.getToolboxHostURL(project);
        url += "/manager?cmd=configureOperation&&serviceName=";
        url += serviceName;
        url += "&&operationName=";
        url += operationName;
        url += "&&pollingRate=";
        url += pollingRate;

        try {
            client = new HttpClient();
            method = new GetMethod(url);

            statusCode = client.executeMethod(method);

            if (statusCode != 200)
                return false;
            else
                return true;
        } catch (Exception e) {
            return false;
        }
    }

    protected static void notifyServiceOrOperationNotDeployed(String serviceName, String operationName)
            throws CoreException {
        String message = null;

        message = "The service " + serviceName + " and/or the operation " + operationName + " are not deployed";

        AsynchInfoDialogs.showErrorDialog("Error while running operation", message);
    }

    protected static void notifyToolboxUrlError(String serviceName) throws CoreException {
        String message = null;

        message = "Toolbox host has not properly set to the service " + serviceName;

        AsynchInfoDialogs.showErrorDialog("Error while running operation", message);
    }

    protected static boolean checkIfSOAPFault(IFile testFile) {
        try {
            InputStream fileContent = testFile.getContents();

            DOMUtil util;

            util = new DOMUtil();
            Document doc;

            doc = util.inputStreamToDocument(fileContent);

            return SOAPUtil.isSOAPFault(doc);
        } catch (Exception e) {
            return true;
        }
    }

    protected static boolean checkIfDeployed(IProject project, String serviceName, String operationName) {
        HttpClient client;
        GetMethod method;
        int statusCode;
        DOMUtil util;
        Document doc;
        Element root;
        Element ithServiceTag;
        Element ithOperationTag;
        Iterator serviceIterator;
        Iterator operationIterator;
        LinkedList serviceTags;
        LinkedList operationTags;
        String url;

        util = new DOMUtil();

        client = new HttpClient();

        url = ToolboxEclipseProjectPreferences.getToolboxHostURL(project);
        url += "/manager?cmd=GetServiceList";

        method = new GetMethod(url);

        try {
            statusCode = client.executeMethod(method);
            if (statusCode != 200)
                return false;

            InputStream serviceList;

            serviceList = method.getResponseBodyAsStream();

            doc = util.inputStreamToDocument(serviceList);

            root = doc.getDocumentElement();
            serviceTags = util.getChildren(root);

            serviceIterator = serviceTags.iterator();
            while (serviceIterator.hasNext()) {
                ithServiceTag = (Element) serviceIterator.next();

                if (ithServiceTag.getAttribute("name").equals(serviceName)) {
                    operationTags = util.getChildren(ithServiceTag);

                    operationIterator = operationTags.iterator();
                    while (operationIterator.hasNext()) {
                        ithOperationTag = (Element) operationIterator.next();
                        if (ithOperationTag.getAttribute("name").equals(operationName))
                            return true;
                    }
                }
            }
            return false;
        } catch (Exception e) {
            return false;
        }
    }

    protected static InputStream performCheckForPushedMessage(IProject project, String messageId, long checkEach,
            IProgressMonitor monitor, ILaunch launch) {
        String pushedMessageUrl;
        int loopCount = 0;
        int maxLoops = 10; //should be configurable
        int waitInterval = 60000; //should be configurable
        HttpClient client;
        GetMethod method;
        int statusCode = 404;

        try {
            pushedMessageUrl = GetPushedMessageUrl(project, messageId);
            if (pushedMessageUrl != null) {
                client = new HttpClient();

                method = new GetMethod(pushedMessageUrl);

                while (monitor.isCanceled() == false && statusCode == 404 && loopCount < maxLoops) {
                    statusCode = client.executeMethod(method);
                    if (statusCode == 404)
                        Thread.sleep(checkEach);

                    if (monitor.isCanceled())
                        return null;
                }

                return method.getResponseBodyAsStream();
            }

            return null;
        } catch (Exception e) {
            MessageDialog.openError(null, "Retrieving pushed message",
                    "An error has occurred while trying to retrieve the pushed message");
            return null;
        }
    }

    protected static String GetPushedMessageUrl(IProject project, String messageId) {
        String url;

        url = ToolboxEclipseProjectPreferences.getToolboxHostURL(project);
        if (url != null && url.equals("") == false)
            url += "/Push?cmd=GetPushedMessage&&MessageId=" + messageId;
        else
            url = null;

        return url;
    }

    protected static String getPushUrl(IProject project) {
        String url;

        url = ToolboxEclipseProjectPreferences.getToolboxHostURL(project);
        if (url != null && url.equals("") == false)
            url += "/Push";
        else
            url = null;

        return url;
    }

    protected static String getManagerUrl(IProject project) {
        String url;

        url = ToolboxEclipseProjectPreferences.getToolboxHostURL(project);
        if (url != null && url.equals("") == false)
            url += "/manager";
        else
            url = null;

        return url;
    }

    protected static void saveFile(InputStream inputStream, IFile file) throws Exception {
        DOMUtil util;
        Document doc;

        util = new DOMUtil();

        doc = util.inputStreamToDocument(inputStream);
        DOMUtil.dumpXML(doc, file.getLocation().toFile(), true);

    }

    protected static InputStream createInputTestFile(String testFilePath, String pushUrl, String messageId)
            throws IOException, SAXException, Exception {
        Document testFileDoc;
        Document soapTestFile;
        IPath path;
        File tempFile;
        DOMUtil util;
        IWorkspace wrkSpace = ResourcesPlugin.getWorkspace();
        IWorkspaceRoot root = wrkSpace.getRoot();
        InputStream inputStream;

        util = new DOMUtil(true);
        path = new Path(testFilePath);

        path = root.getLocation().append(path);

        testFileDoc = util.fileToDocument(path.toFile());
        soapTestFile = SOAPMessageBuilder.buildSOAPMessage(testFileDoc, messageId, pushUrl);

        inputStream = util.getDocumentAsInputStream(soapTestFile);
        return inputStream;
    }

    protected static IFolder createTestFolder(IProject project) throws CoreException {
        SimpleDateFormat format;

        IFolder execResults = project.getFolder("Test Results");
        if (!execResults.exists())
            execResults.create(true, true, null);

        format = new SimpleDateFormat("yyyyMMddHHmmss");
        IFolder currentExecutionResultFolder = execResults.getFolder("Test " + format.format(new Date()));
        if (!currentExecutionResultFolder.exists())
            currentExecutionResultFolder.create(true, true, null);

        return currentExecutionResultFolder;

    }

    protected static InputStream sendFile(String url, String soapAction, InputStream stream)
            throws FileNotFoundException, IOException, HttpException {
        PostMethod post;
        int result;

        MultiThreadedHttpConnectionManager connectionManager = new MultiThreadedHttpConnectionManager();

        HttpClient client = new HttpClient(connectionManager);

        post = new PostMethod(url);

        post.setRequestEntity(new InputStreamRequestEntity(stream, "text/xml"));
        post.setRequestHeader("soapaction", soapAction);

        result = client.executeMethod(post);

        InputStream in = post.getResponseBodyAsStream();
        return in;
    }

    protected static String getTestUrl(IProject project) {
        String url;

        url = ToolboxEclipseProjectPreferences.getToolboxHostURL(project);
        if (url != null && url.equals("") == false)
            url += "/services/" + project.getName();
        else
            url = null;

        return url;
    }

}