Package org.apache.airavata.xbaya.gridchem.gui

Source Code of org.apache.airavata.xbaya.gridchem.gui.GridChemRunnerWindow

/*
*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements.  See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership.  The ASF licenses this file
* to you 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 org.apache.airavata.xbaya.gridchem.gui;

import java.awt.event.ActionEvent;
import java.io.File;
import java.io.IOException;
import java.net.URI;
import java.net.URISyntaxException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.UUID;

import javax.swing.AbstractAction;
import javax.swing.JButton;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.xml.namespace.QName;

import org.apache.airavata.common.utils.StringUtil;
import org.apache.airavata.common.utils.XMLUtil;
import org.apache.airavata.xbaya.XBayaConfiguration;
import org.apache.airavata.xbaya.XBayaConstants;
import org.apache.airavata.xbaya.XBayaEngine;
import org.apache.airavata.xbaya.XBayaException;
import org.apache.airavata.xbaya.component.ws.WSComponent;
import org.apache.airavata.xbaya.graph.GraphException;
import org.apache.airavata.xbaya.graph.system.InputNode;
import org.apache.airavata.xbaya.graph.util.GraphUtil;
import org.apache.airavata.xbaya.graph.ws.WSNode;
import org.apache.airavata.xbaya.gui.ErrorMessages;
import org.apache.airavata.xbaya.gui.GridPanel;
import org.apache.airavata.xbaya.gui.XBayaDialog;
import org.apache.airavata.xbaya.gui.XBayaLabel;
import org.apache.airavata.xbaya.gui.XBayaTextField;
import org.apache.airavata.xbaya.jython.runner.JythonRunner;
import org.apache.airavata.xbaya.jython.script.JythonScript;
import org.apache.airavata.xbaya.monitor.MonitorConfiguration;
import org.apache.airavata.xbaya.monitor.gui.MonitorStarter;
import org.apache.airavata.xbaya.wf.Workflow;
import org.apache.commons.httpclient.HttpClient;
import org.apache.commons.httpclient.HttpStatus;
import org.apache.commons.httpclient.NameValuePair;
import org.apache.commons.httpclient.methods.PostMethod;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.xmlpull.infoset.XmlElement;

import xsul5.wsdl.WsdlDefinitions;

public class GridChemRunnerWindow {

    private static final Logger logger = LoggerFactory.getLogger(GridChemRunnerWindow.class);

    private XBayaEngine engine;

    private Workflow workflow;

    private XBayaDialog dialog;

    private GridPanel parameterPanel;

    private XBayaTextField topicTextField;

    private XBayaTextField gfacTextField;

    private List<XBayaTextField> parameterTextFields = new ArrayList<XBayaTextField>();

    private List<File> tmpWSDLFiles = new ArrayList<File>();

    private JythonScript script;

    private JythonRunner runner;

    /*
     * Extended
     */
    private XBayaTextField gridchemBridgeTextField;

    private XBayaTextField usernameTextField;

    /**
     * Constructs a JythonRunnerWindow.
     *
     * @param engine
     *
     */
    public GridChemRunnerWindow(XBayaEngine engine) {
        this.engine = engine;
        this.runner = new JythonRunner();
        initGUI();
    }

    /**
     * Shows the dialog.
     */
    public void show() {
        this.workflow = this.engine.getWorkflow();
        this.script = new JythonScript(this.workflow, this.engine.getConfiguration());

        MonitorConfiguration notifConfig = this.engine.getMonitor().getConfiguration();
        if (notifConfig.getBrokerURL() == null) {
            this.engine.getErrorWindow().error(ErrorMessages.BROKER_URL_NOT_SET_ERROR);
            return;
        }

        // Check if the workflow is valid before the user types in input
        // values.
        ArrayList<String> warnings = new ArrayList<String>();
        if (!this.script.validate(warnings)) {
            StringBuilder buf = new StringBuilder();
            for (String warning : warnings) {
                buf.append("- ");
                buf.append(warning);
                buf.append("\n");
            }
            this.engine.getErrorWindow().warning(buf.toString());
            return;
        }

        // Create a script here. It might throw some exception because the
        // validation is not perfect.
        try {
            this.script.create();
        } catch (GraphException e) {
            this.engine.getErrorWindow().error(ErrorMessages.GRAPH_NOT_READY_ERROR, e);
            hide();
            return;
        } catch (RuntimeException e) {
            this.engine.getErrorWindow().error(ErrorMessages.UNEXPECTED_ERROR, e);
            hide();
            return;
        } catch (Error e) {
            this.engine.getErrorWindow().error(ErrorMessages.UNEXPECTED_ERROR, e);
            hide();
            return;
        }

        // Create input fields
        Collection<InputNode> inputNodes = GraphUtil.getInputNodes(this.workflow.getGraph());
        for (InputNode node : inputNodes) {
            String id = node.getID();
            QName parameterType = node.getParameterType();
            JLabel nameLabel = new JLabel(id);
            JLabel typeField = new JLabel(parameterType.getLocalPart());
            XBayaTextField paramField = new XBayaTextField();
            Object value = node.getDefaultValue();

            String valueString;
            if (value == null) {
                valueString = "";
            } else {
                if (value instanceof XmlElement) {
                    XmlElement valueElement = (XmlElement) value;
                    valueString = XMLUtil.xmlElementToString(valueElement);
                } else {
                    // Only string comes here for now.
                    valueString = value.toString();
                }
            }
            paramField.setText(valueString);
            this.parameterPanel.add(nameLabel);
            this.parameterPanel.add(typeField);
            this.parameterPanel.add(paramField);
            this.parameterTextFields.add(paramField);
        }
        this.parameterPanel.layout(inputNodes.size(), 3, GridPanel.WEIGHT_NONE, 2);

        if (notifConfig.getTopic() == null) {
            this.topicTextField.setText(UUID.randomUUID().toString());
        } else {
            this.topicTextField.setText(notifConfig.getTopic());
        }

        XBayaConfiguration config = this.engine.getConfiguration();

        URI gfacURL = config.getGFacURL();
        this.gfacTextField.setText(StringUtil.toString(gfacURL));

        this.dialog.show();
    }

    /**
     * Hides the dialog.
     */
    public void hide() {
        this.dialog.hide();

        this.parameterPanel.getContentPanel().removeAll();
        this.parameterTextFields.clear();
    }

    private void initGUI() {
        this.parameterPanel = new GridPanel(true);

        this.topicTextField = new XBayaTextField();
        XBayaLabel topicLabel = new XBayaLabel("Notification topic", this.topicTextField);

        this.gfacTextField = new XBayaTextField();
        XBayaLabel gfacLabel = new XBayaLabel("GFac URL", this.gfacTextField);

        /*
         * extend
         */
        this.gridchemBridgeTextField = new XBayaTextField();
        this.usernameTextField = new XBayaTextField();
        XBayaLabel gridchemBridgeLabel = new XBayaLabel("GridChem Bridge URL", this.gridchemBridgeTextField);
        XBayaLabel usernameLabel = new XBayaLabel("Username", this.usernameTextField);

        // default value
        gridchemBridgeTextField.setText("http://129.79.49.227:8080/ogce-gridchem-bridge/");

        GridPanel infoPanel = new GridPanel();
        infoPanel.add(topicLabel);
        infoPanel.add(this.topicTextField);
        infoPanel.add(gfacLabel);
        infoPanel.add(this.gfacTextField);

        /*
         * extend
         */
        infoPanel.add(gridchemBridgeLabel);
        infoPanel.add(this.gridchemBridgeTextField);
        infoPanel.add(usernameLabel);
        infoPanel.add(this.usernameTextField);
        infoPanel.layout(4, 2, GridPanel.WEIGHT_NONE, 1);

        GridPanel mainPanel = new GridPanel();
        mainPanel.add(this.parameterPanel);
        mainPanel.add(infoPanel);
        mainPanel.layout(2, 1, 0, 0);

        JButton okButton = new JButton("OK");
        okButton.addActionListener(new AbstractAction() {
            public void actionPerformed(ActionEvent e) {
                execute();
            }
        });

        JButton cancelButton = new JButton("Cancel");
        cancelButton.addActionListener(new AbstractAction() {
            public void actionPerformed(ActionEvent e) {
                hide();
            }
        });

        JPanel buttonPanel = new JPanel();
        buttonPanel.add(okButton);
        buttonPanel.add(cancelButton);

        this.dialog = new XBayaDialog(this.engine, "Execute Workflow (Jython)", mainPanel, buttonPanel);
        this.dialog.setDefaultButton(okButton);
    }

    public void execute() {
        final List<String> arguments = new ArrayList<String>();

        String topic = this.topicTextField.getText();
        if (topic.length() == 0) {
            this.engine.getErrorWindow().error(ErrorMessages.TOPIC_EMPTY_ERROR);
            return;
        }

        // Use topic as a base of workflow instance ID so that the monitor can
        // find it.
        URI workfowInstanceID = URI.create(StringUtil.convertToJavaIdentifier(topic));
        this.workflow.setGPELInstanceID(workfowInstanceID);

        MonitorConfiguration notifConfig = this.engine.getMonitor().getConfiguration();
        notifConfig.setTopic(topic);
        arguments.add("-" + JythonScript.TOPIC_VARIABLE);
        arguments.add(topic);

        // TODO error check for user inputs

        List<InputNode> inputNodes = GraphUtil.getInputNodes(this.workflow.getGraph());
        for (int i = 0; i < inputNodes.size(); i++) {
            InputNode inputNode = inputNodes.get(i);
            XBayaTextField parameterTextField = this.parameterTextFields.get(i);
            String id = inputNode.getID();
            String value = parameterTextField.getText();
            arguments.add("-" + id);
            arguments.add(value);
        }

        XBayaConfiguration config = this.engine.getConfiguration();

        String gfacString = this.gfacTextField.getText();
        if (gfacString.length() != 0) {
            try {
                URI uri = new URI(gfacString).parseServerAuthority();
                config.setGFacURL(uri);
            } catch (URISyntaxException e) {
                this.engine.getErrorWindow().error(ErrorMessages.GFAC_URL_WRONG, e);
                return;
            }
            arguments.add("-" + JythonScript.GFAC_VARIABLE);
            arguments.add(gfacString);
        }

        arguments.add("-" + JythonScript.BROKER_URL_VARIABLE);
        arguments.add(notifConfig.getBrokerURL().toString());

        if (notifConfig.isPullMode()) {
            arguments.add("-" + JythonScript.MESSAGE_BOX_URL_VARIABLE);
            arguments.add(notifConfig.getMessageBoxURL().toString());
        }

        try {
            for (WSNode node : GraphUtil.getWSNodes(this.workflow.getGraph())) {
                WSComponent component = node.getComponent();
                QName portTypeQName = component.getPortTypeQName();
                WsdlDefinitions wsdl = component.getWSDL();

                File file = File.createTempFile(".xbaya-" + portTypeQName.getLocalPart(), XBayaConstants.WSDL_SUFFIX);
                this.tmpWSDLFiles.add(file);
                XMLUtil.saveXML(wsdl.xml(), file);

                String wsdlID = JythonScript.getWSDLID(node);
                String wsdlURL = file.toURL().toString();
                arguments.add("-" + wsdlID);
                arguments.add(wsdlURL);
            }
        } catch (IOException e) {
            this.engine.getErrorWindow().error(ErrorMessages.UNEXPECTED_ERROR, e);
            hide();
            return;
        }

        final String scriptString = this.script.getJythonString(arguments);

        /*
         * set input in final, so we can use it in thread
         */
        final String topicString = topic;
        final String bridgeURL = this.gridchemBridgeTextField.getText();
        final String username = this.usernameTextField.getText();

        new Thread() {

            private void notifyGridChemService() {
                /*
                 * Method and data
                 */
                PostMethod method = new PostMethod(bridgeURL + "ogb/register");
                NameValuePair[] data = {
                        new NameValuePair("broker", GridChemRunnerWindow.this.engine.getMonitor().getConfiguration()
                                .getBrokerURL().toString()), new NameValuePair("jobname", topicString),
                        new NameValuePair("username", username), };
                method.setRequestBody(data);

                try {
                    /*
                     * Contact XGMS to update data to DB
                     */
                    HttpClient httpClient = new HttpClient();
                    int ret_status = httpClient.executeMethod(method);

                    if (ret_status != HttpStatus.SC_OK) {
                        GridChemRunnerWindow.this.engine.getErrorWindow().error(
                                "GridChem Bridge Service Error " + bridgeURL + ", return code:" + ret_status);
                    }
                } catch (Exception e) {
                    GridChemRunnerWindow.this.engine.getErrorWindow().error(e);
                } finally {
                    if (method != null) {
                        method.releaseConnection();
                    }
                }
            }

            @Override
            public synchronized void run() {

                // tell gridchem service
                notifyGridChemService();

                // Start monitoring.
                // Errors are handled in MonitorStarter.
                MonitorStarter monitorStarter = new MonitorStarter(GridChemRunnerWindow.this.engine);
                monitorStarter.start(true);

                try {
                    GridChemRunnerWindow.this.runner.run(scriptString, arguments);
                    logger.info("Done with the execution");
                    // try {
                    // // Wait for all notification to arrive.
                    // Thread.sleep(10 * 1000); // 10 secs
                    // } catch (InterruptedException e) {
                    // logger.error(e.getMessage(), e);
                    // }
                } catch (XBayaException e) {
                    GridChemRunnerWindow.this.engine.getErrorWindow().error(ErrorMessages.UNEXPECTED_ERROR, e);
                } catch (RuntimeException e) {
                    GridChemRunnerWindow.this.engine.getErrorWindow().error(ErrorMessages.UNEXPECTED_ERROR, e);
                } catch (Error e) {
                    GridChemRunnerWindow.this.engine.getErrorWindow().error(ErrorMessages.UNEXPECTED_ERROR, e);
                } finally {
                    // We don't need this because this might stop a new
                    // subscription initiated by a user.
                    // JythonRunnerWindow.this.engine.getMonitor()
                    // .asynchronousStop();

                    for (File file : GridChemRunnerWindow.this.tmpWSDLFiles) {
                        file.delete();
                    }
                    GridChemRunnerWindow.this.tmpWSDLFiles.clear();
                }
            }
        }.start();

        hide();
    }
}
TOP

Related Classes of org.apache.airavata.xbaya.gridchem.gui.GridChemRunnerWindow

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.