You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@taverna.apache.org by st...@apache.org on 2015/02/17 12:36:53 UTC
[33/70] [abbrv] incubator-taverna-common-activities git commit:
taverna-wsdl-activity/
http://git-wip-us.apache.org/repos/asf/incubator-taverna-common-activities/blob/77704689/taverna-wsdl-activity/src/main/java/net/sf/taverna/t2/activities/wsdl/WSDLActivity.java
----------------------------------------------------------------------
diff --git a/taverna-wsdl-activity/src/main/java/net/sf/taverna/t2/activities/wsdl/WSDLActivity.java b/taverna-wsdl-activity/src/main/java/net/sf/taverna/t2/activities/wsdl/WSDLActivity.java
new file mode 100644
index 0000000..763cbee
--- /dev/null
+++ b/taverna-wsdl-activity/src/main/java/net/sf/taverna/t2/activities/wsdl/WSDLActivity.java
@@ -0,0 +1,328 @@
+/*******************************************************************************
+ * Copyright (C) 2007 The University of Manchester
+ *
+ * Modifications to the initial code base are copyright of their
+ * respective authors, or their employers as appropriate.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * as published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This program 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+ ******************************************************************************/
+package net.sf.taverna.t2.activities.wsdl;
+
+import java.io.IOException;
+import java.net.MalformedURLException;
+import java.net.SocketTimeoutException;
+import java.net.URL;
+import java.net.URLConnection;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import javax.wsdl.WSDLException;
+import javax.xml.parsers.ParserConfigurationException;
+
+import net.sf.taverna.t2.reference.ReferenceService;
+import net.sf.taverna.t2.reference.ReferenceServiceException;
+import net.sf.taverna.t2.reference.T2Reference;
+import net.sf.taverna.t2.security.credentialmanager.CredentialManager;
+import net.sf.taverna.t2.workflowmodel.OutputPort;
+import net.sf.taverna.t2.workflowmodel.health.RemoteHealthChecker;
+import net.sf.taverna.t2.workflowmodel.processor.activity.AbstractAsynchronousActivity;
+import net.sf.taverna.t2.workflowmodel.processor.activity.ActivityConfigurationException;
+import net.sf.taverna.t2.workflowmodel.processor.activity.ActivityOutputPort;
+import net.sf.taverna.t2.workflowmodel.processor.activity.AsynchronousActivityCallback;
+import net.sf.taverna.wsdl.parser.TypeDescriptor;
+import net.sf.taverna.wsdl.parser.UnknownOperationException;
+import net.sf.taverna.wsdl.parser.WSDLParser;
+
+import org.apache.log4j.Logger;
+import org.xml.sax.SAXException;
+
+import com.fasterxml.jackson.databind.JsonNode;
+
+/**
+ * An asynchronous Activity that is concerned with WSDL based web-services.
+ * <p>
+ * The activity is configured according to the WSDL location and the operation.<br>
+ * The ports are defined dynamically according to the WSDL specification, and in
+ * addition an output<br>
+ * port <em>attachmentList</em> is added to represent any attachements that are
+ * returned by the webservice.
+ * </p>
+ *
+ * @author Stuart Owen
+ * @author Stian Soiland-Reyes
+ */
+public class WSDLActivity extends
+ AbstractAsynchronousActivity<JsonNode> implements
+ InputPortTypeDescriptorActivity, OutputPortTypeDescriptorActivity {
+
+ public static final String URI = "http://ns.taverna.org.uk/2010/activity/wsdl";
+
+ public static final String ENDPOINT_REFERENCE = "EndpointReference";
+ private JsonNode configurationBean;
+ private WSDLParser parser;
+// private Map<String, Integer> outputDepth = new HashMap<String, Integer>();
+ private boolean isWsrfService = false;
+// private String endpointReferenceInputPortName;
+ private CredentialManager credentialManager;
+
+ public WSDLActivity(CredentialManager credentialManager) {
+ this.credentialManager = credentialManager;
+ }
+
+ public boolean isWsrfService() {
+ return isWsrfService;
+ }
+
+ private static Logger logger = Logger.getLogger(WSDLActivity.class);
+
+ /**
+ * Configures the activity according to the information passed by the
+ * configuration bean.<br>
+ * During this process the WSDL is parsed to determine the input and output
+ * ports.
+ *
+ * @param bean
+ * the {@link WSDLActivityConfigurationBean} configuration bean
+ */
+ @Override
+ public void configure(JsonNode bean)
+ throws ActivityConfigurationException {
+ this.configurationBean = bean;
+ try {
+ parseWSDL();
+ } catch (Exception ex) {
+ throw new ActivityConfigurationException(
+ "Unable to parse the WSDL " + bean.get("operation").get("wsdl").textValue(), ex);
+ }
+ }
+
+ @Override
+ public JsonNode getConfiguration() {
+ return configurationBean;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @seenet.sf.taverna.t2.activities.wsdl.InputPortTypeDescriptorActivity#
+ * getTypeDescriptorForInputPort(java.lang.String)
+ */
+ public TypeDescriptor getTypeDescriptorForInputPort(String portName)
+ throws UnknownOperationException, IOException {
+ List<TypeDescriptor> inputDescriptors = parser
+ .getOperationInputParameters(configurationBean.get("operation").get("name").textValue());
+ TypeDescriptor result = null;
+ for (TypeDescriptor descriptor : inputDescriptors) {
+ if (descriptor.getName().equals(portName)) {
+ result = descriptor;
+ break;
+ }
+ }
+ return result;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @seenet.sf.taverna.t2.activities.wsdl.InputPortTypeDescriptorActivity#
+ * getTypeDescriptorsForInputPorts()
+ */
+ public Map<String, TypeDescriptor> getTypeDescriptorsForInputPorts()
+ throws UnknownOperationException, IOException {
+ Map<String, TypeDescriptor> descriptors = new HashMap<String, TypeDescriptor>();
+ List<TypeDescriptor> inputDescriptors = parser
+ .getOperationInputParameters(configurationBean.get("operation").get("name").textValue());
+ for (TypeDescriptor descriptor : inputDescriptors) {
+ descriptors.put(descriptor.getName(), descriptor);
+ }
+ return descriptors;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @seenet.sf.taverna.t2.activities.wsdl.OutputPortTypeDescriptorActivity#
+ * getTypeDescriptorForOutputPort(java.lang.String)
+ */
+ public TypeDescriptor getTypeDescriptorForOutputPort(String portName)
+ throws UnknownOperationException, IOException {
+ TypeDescriptor result = null;
+ List<TypeDescriptor> outputDescriptors = parser
+ .getOperationOutputParameters(configurationBean.get("operation").get("name").textValue());
+ for (TypeDescriptor descriptor : outputDescriptors) {
+ if (descriptor.getName().equals(portName)) {
+ result = descriptor;
+ break;
+ }
+ }
+ return result;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @seenet.sf.taverna.t2.activities.wsdl.OutputPortTypeDescriptorActivity#
+ * getTypeDescriptorsForOutputPorts()
+ */
+ public Map<String, TypeDescriptor> getTypeDescriptorsForOutputPorts()
+ throws UnknownOperationException, IOException {
+ Map<String, TypeDescriptor> descriptors = new HashMap<String, TypeDescriptor>();
+ List<TypeDescriptor> inputDescriptors = parser
+ .getOperationOutputParameters(configurationBean.get("operation").get("name").textValue());
+ for (TypeDescriptor descriptor : inputDescriptors) {
+ descriptors.put(descriptor.getName(), descriptor);
+ }
+ return descriptors;
+ }
+
+ private void parseWSDL() throws ParserConfigurationException,
+ WSDLException, IOException, SAXException, UnknownOperationException {
+ String wsdlLocation = configurationBean.get("operation").get("wsdl").textValue();
+ URLConnection connection = null;
+ try {
+ URL wsdlURL = new URL(wsdlLocation);
+ connection = wsdlURL.openConnection();
+ connection.setConnectTimeout(RemoteHealthChecker.getTimeoutInSeconds() * 1000);
+ connection.connect();
+ } catch (MalformedURLException e) {
+ throw new IOException("Malformed URL", e);
+ } catch (SocketTimeoutException e) {
+ throw new IOException("Timeout", e);
+ } catch (IOException e) {
+ throw e;
+ } finally {
+ if ((connection != null) && (connection.getInputStream() != null)) {
+ connection.getInputStream().close();
+ }
+ }
+ parser = new WSDLParser(wsdlLocation);
+ isWsrfService = parser.isWsrfService();
+ }
+
+ @Override
+ public void executeAsynch(final Map<String, T2Reference> data,
+ final AsynchronousActivityCallback callback) {
+
+ callback.requestRun(new Runnable() {
+
+ public void run() {
+
+ ReferenceService referenceService = callback.getContext()
+ .getReferenceService();
+
+ Map<String, T2Reference> outputData = new HashMap<String, T2Reference>();
+ Map<String, Object> invokerInputMap = new HashMap<String, Object>();
+ String endpointReferenceInputPortName = getEndpointReferenceInputPortName();
+
+ try {
+ String endpointReference = null;
+ for (String key : data.keySet()) {
+ Object renderIdentifier = referenceService
+ .renderIdentifier(data.get(key), String.class,
+ callback.getContext());
+ if (isWsrfService()
+ && key.equals(endpointReferenceInputPortName)) {
+ endpointReference = (String) renderIdentifier;
+ } else {
+ invokerInputMap.put(key, renderIdentifier);
+ }
+ }
+ List<String> outputNames = new ArrayList<String>();
+ for (OutputPort port : getOutputPorts()) {
+ outputNames.add(port.getName());
+ }
+
+ T2WSDLSOAPInvoker invoker = new T2WSDLSOAPInvoker(parser,
+ configurationBean.get("operation").get("name").textValue(), outputNames,
+ endpointReference, credentialManager);
+
+ Map<String, Object> invokerOutputMap = invoker.invoke(
+ invokerInputMap, configurationBean);
+
+ for (String outputName : invokerOutputMap.keySet()) {
+ Object value = invokerOutputMap.get(outputName);
+
+ if (value != null) {
+ Integer depth = getOutputPortDepth(outputName);
+ if (depth != null) {
+ outputData.put(outputName, referenceService
+ .register(value, depth, true, callback
+ .getContext()));
+ } else {
+ logger.info("Skipping unknown output port :"
+ + outputName);
+// // TODO what should the depth be in this case?
+// outputData.put(outputName, referenceService
+// .register(value, 0, true, callback
+// .getContext()));
+ }
+ }
+ }
+ callback.receiveResult(outputData, new int[0]);
+ } catch (ReferenceServiceException e) {
+ logger.error("Error finding the input data for "
+ + getConfiguration().get("operation"), e);
+ callback.fail("Unable to find input data", e);
+ return;
+ } catch (Exception e) {
+ logger.error("Error invoking WSDL service "
+ + getConfiguration().get("operation"), e);
+ callback.fail(
+ "An error occurred invoking the WSDL service", e);
+ return;
+ }
+
+ }
+
+ });
+
+ }
+
+ private Integer getOutputPortDepth(String portName) {
+ for (ActivityOutputPort outputPort : getOutputPorts()) {
+ if (outputPort.getName().equals(portName)) {
+ return outputPort.getDepth();
+ }
+ }
+ return null;
+ }
+
+ private String getEndpointReferenceInputPortName() {
+ String endpointReferenceInputPortName = null;
+ if (parser.isWsrfService()) {
+ Set<String> inputPorts = new HashSet<>();
+ try {
+ List<TypeDescriptor> inputDescriptors = parser.getOperationInputParameters(configurationBean
+ .get("operation").get("name").textValue());
+ for (TypeDescriptor descriptor : inputDescriptors) {
+ inputPorts.add(descriptor.getName());
+ }
+ } catch (UnknownOperationException | IOException e) {
+ }
+ // Make sure the port name is unique
+ endpointReferenceInputPortName = WSDLActivity.ENDPOINT_REFERENCE;
+ int counter = 0;
+ while (inputPorts.contains(endpointReferenceInputPortName)) {
+ endpointReferenceInputPortName = WSDLActivity.ENDPOINT_REFERENCE + counter++;
+ }
+ }
+ return endpointReferenceInputPortName;
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-taverna-common-activities/blob/77704689/taverna-wsdl-activity/src/main/java/net/sf/taverna/t2/activities/wsdl/WSDLActivityConfigurationBean.java
----------------------------------------------------------------------
diff --git a/taverna-wsdl-activity/src/main/java/net/sf/taverna/t2/activities/wsdl/WSDLActivityConfigurationBean.java b/taverna-wsdl-activity/src/main/java/net/sf/taverna/t2/activities/wsdl/WSDLActivityConfigurationBean.java
new file mode 100644
index 0000000..80b0bd5
--- /dev/null
+++ b/taverna-wsdl-activity/src/main/java/net/sf/taverna/t2/activities/wsdl/WSDLActivityConfigurationBean.java
@@ -0,0 +1,82 @@
+/*******************************************************************************
+ * Copyright (C) 2007 The University of Manchester
+ *
+ * Modifications to the initial code base are copyright of their
+ * respective authors, or their employers as appropriate.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * as published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This program 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+ ******************************************************************************/
+package net.sf.taverna.t2.activities.wsdl;
+
+import java.net.URI;
+
+import net.sf.taverna.t2.workflowmodel.processor.config.ConfigurationBean;
+import net.sf.taverna.t2.workflowmodel.processor.config.ConfigurationProperty;
+
+/**
+ * A standard Java Bean that provides the details required to configure a WSDLActivity.
+ * <p>
+ * This contains details about the WSDL and the Operation that the WSDLActivity is intended to invoke.
+ * </p>
+ * @author Stuart Owen
+ */
+@ConfigurationBean(uri = WSDLActivity.URI + "#Config")
+public class WSDLActivityConfigurationBean {
+ private WSDLOperationConfigurationBean operation;
+ private URI securityProfile;
+
+ // In the case service requires username and password for authentication,
+ // but do not serialise these variables to file
+ //transient private String username;
+ //transient private String password;
+
+ /** Creates a new instance of WSDLActivityConfigurationBean */
+ public WSDLActivityConfigurationBean() {
+ }
+
+ public WSDLOperationConfigurationBean getOperation() {
+ return operation;
+ }
+
+ @ConfigurationProperty(name = "operation", label = "WSDL Operation", description = "The WSDL operation")
+ public void setOperation(WSDLOperationConfigurationBean operation) {
+ this.operation = operation;
+ }
+
+ public URI getSecurityProfile() {
+ return securityProfile;
+ }
+
+ @ConfigurationProperty(name = "securityProfile", label = "Security Profile", description = "WS-Security settings required by the web service", required = false)
+ public void setSecurityProfile(URI securityProfile) {
+ this.securityProfile = securityProfile;
+ }
+
+// public void setUsername(String username) {
+// this.username = username;
+// }
+//
+// public String getUsername() {
+// return username;
+// }
+//
+// public void setPassword(String password) {
+// this.password = password;
+// }
+//
+// public String getPassword() {
+// return password;
+// }
+}
http://git-wip-us.apache.org/repos/asf/incubator-taverna-common-activities/blob/77704689/taverna-wsdl-activity/src/main/java/net/sf/taverna/t2/activities/wsdl/WSDLActivityDescriptorChecker.java
----------------------------------------------------------------------
diff --git a/taverna-wsdl-activity/src/main/java/net/sf/taverna/t2/activities/wsdl/WSDLActivityDescriptorChecker.java b/taverna-wsdl-activity/src/main/java/net/sf/taverna/t2/activities/wsdl/WSDLActivityDescriptorChecker.java
new file mode 100644
index 0000000..5a41cde
--- /dev/null
+++ b/taverna-wsdl-activity/src/main/java/net/sf/taverna/t2/activities/wsdl/WSDLActivityDescriptorChecker.java
@@ -0,0 +1,147 @@
+/**
+ *
+ */
+package net.sf.taverna.t2.activities.wsdl;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.Set;
+
+import net.sf.taverna.t2.visit.VisitReport;
+import net.sf.taverna.t2.visit.VisitReport.Status;
+import net.sf.taverna.t2.workflowmodel.Dataflow;
+import net.sf.taverna.t2.workflowmodel.Datalink;
+import net.sf.taverna.t2.workflowmodel.Merge;
+import net.sf.taverna.t2.workflowmodel.MergeInputPort;
+import net.sf.taverna.t2.workflowmodel.MergeOutputPort;
+import net.sf.taverna.t2.workflowmodel.MergePort;
+import net.sf.taverna.t2.workflowmodel.Port;
+import net.sf.taverna.t2.workflowmodel.Processor;
+import net.sf.taverna.t2.workflowmodel.ProcessorInputPort;
+import net.sf.taverna.t2.workflowmodel.ProcessorPort;
+import net.sf.taverna.t2.workflowmodel.health.HealthCheck;
+import net.sf.taverna.t2.workflowmodel.health.HealthChecker;
+import net.sf.taverna.t2.workflowmodel.processor.activity.Activity;
+import net.sf.taverna.t2.workflowmodel.processor.activity.ActivityInputPort;
+import net.sf.taverna.t2.workflowmodel.utils.Tools;
+import net.sf.taverna.wsdl.parser.ArrayTypeDescriptor;
+import net.sf.taverna.wsdl.parser.ComplexTypeDescriptor;
+import net.sf.taverna.wsdl.parser.TypeDescriptor;
+import net.sf.taverna.wsdl.parser.UnknownOperationException;
+
+import org.apache.log4j.Logger;
+
+/**
+ * @author alanrw
+ *
+ */
+public final class WSDLActivityDescriptorChecker implements HealthChecker<InputPortTypeDescriptorActivity> {
+
+ private static Logger logger = Logger.getLogger(WSDLActivityDescriptorChecker.class);
+
+ public boolean canVisit(Object o) {
+ return ((o != null) && (o instanceof InputPortTypeDescriptorActivity));
+ }
+
+ public boolean isTimeConsuming() {
+ return false;
+ }
+
+ public VisitReport visit(InputPortTypeDescriptorActivity o,
+ List<Object> ancestry) {
+ List<VisitReport> reports = new ArrayList<VisitReport>();
+ try {
+ Map<String, TypeDescriptor> typeMap = o.getTypeDescriptorsForInputPorts();
+ Processor p = (Processor) VisitReport.findAncestor(ancestry, Processor.class);
+ Dataflow d = (Dataflow) VisitReport.findAncestor(ancestry, Dataflow.class);
+
+
+ for (Entry<String, TypeDescriptor> entry : typeMap.entrySet()) {
+ TypeDescriptor descriptor = entry.getValue();
+ if (!descriptor.getMimeType().contains("'text/xml'")) {
+ continue;
+ }
+ if (!((descriptor instanceof ArrayTypeDescriptor) || (descriptor instanceof ComplexTypeDescriptor))) {
+ continue;
+ }
+ // Find the processor port, if any that corresponds to the activity port
+ ActivityInputPort aip = Tools.getActivityInputPort((Activity<?>) o, entry.getKey());
+ if (aip == null) {
+ continue;
+ }
+ ProcessorInputPort pip = Tools.getProcessorInputPort(p, (Activity<?>) o, aip);
+
+ if (pip == null) {
+ continue;
+ }
+
+ for (Datalink dl : d.getLinks()) {
+
+ if (dl.getSink().equals(pip)) {
+ Port source = dl.getSource();
+ Set<VisitReport> subReports = checkSource(source, d, (Activity<?>) o, aip);
+ for (VisitReport vr : subReports) {
+ vr.setProperty("activity", o);
+ vr.setProperty("sinkPort", pip);
+ }
+ reports.addAll(subReports);
+ }
+ }
+
+ }
+ } catch (UnknownOperationException e) {
+ logger.error("Problem getting type descriptors for activity", e);
+ } catch (IOException e) {
+ logger.error("Problem getting type descriptors for activity", e);
+ } catch (NullPointerException e) {
+ logger.error("Problem getting type desciptors for activity", e);
+ }
+ if (reports.isEmpty()) {
+ return null;
+ }
+ if (reports.size() == 1) {
+ return reports.get(0);
+ }
+ else {
+ return new VisitReport(HealthCheck.getInstance(), o, "Collation", HealthCheck.DEFAULT_VALUE, reports);
+ }
+ }
+
+ private Set<VisitReport> checkSource(Port source, Dataflow d, Activity<?> o, ActivityInputPort aip) {
+ Set<VisitReport> reports = new HashSet<VisitReport>();
+ if (source instanceof ProcessorPort) {
+ ProcessorPort processorPort = (ProcessorPort) source;
+ Processor sourceProcessor = processorPort.getProcessor();
+ Activity<?> sourceActivity = sourceProcessor.getActivityList().get(0);
+ if (!(sourceActivity instanceof InputPortTypeDescriptorActivity)) {
+ VisitReport newReport = new VisitReport(HealthCheck.getInstance(), o, "Source of " + aip.getName(), HealthCheck.DATATYPE_SOURCE, Status.WARNING);
+ newReport.setProperty("sinkPortName", aip.getName());
+ newReport.setProperty("sourceName", sourceProcessor.getLocalName());
+ newReport.setProperty("isProcessorSource", "true");
+ reports.add(newReport);
+ }
+ } else if (source instanceof MergeOutputPort) {
+ Merge merge = ((MergePort) source).getMerge();
+ for (MergeInputPort mip : merge.getInputPorts()) {
+ for (Datalink dl : d.getLinks()) {
+ if (dl.getSink().equals(mip)) {
+ reports.addAll(checkSource(dl.getSource(), d, o, aip));
+ }
+ }
+
+ }
+ } else /* if (source instanceof DataflowInputPort) */ {
+ VisitReport newReport = new VisitReport(HealthCheck.getInstance(), o, "Source of " + aip.getName(), HealthCheck.DATATYPE_SOURCE, Status.WARNING);
+ newReport.setProperty("sinkPortName", aip.getName());
+ newReport.setProperty("sourceName", source.getName());
+ newReport.setProperty("isProcessorSource", "false");
+ reports.add(newReport);
+ }
+ return reports;
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-taverna-common-activities/blob/77704689/taverna-wsdl-activity/src/main/java/net/sf/taverna/t2/activities/wsdl/WSDLActivityFactory.java
----------------------------------------------------------------------
diff --git a/taverna-wsdl-activity/src/main/java/net/sf/taverna/t2/activities/wsdl/WSDLActivityFactory.java b/taverna-wsdl-activity/src/main/java/net/sf/taverna/t2/activities/wsdl/WSDLActivityFactory.java
new file mode 100644
index 0000000..eeb7c5a
--- /dev/null
+++ b/taverna-wsdl-activity/src/main/java/net/sf/taverna/t2/activities/wsdl/WSDLActivityFactory.java
@@ -0,0 +1,141 @@
+/*******************************************************************************
+ * Copyright (C) 2010 The University of Manchester
+ *
+ * Modifications to the initial code base are copyright of their
+ * respective authors, or their employers as appropriate.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * as published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This program 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+ ******************************************************************************/
+package net.sf.taverna.t2.activities.wsdl;
+
+import java.io.IOException;
+import java.net.URI;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import javax.wsdl.WSDLException;
+import javax.xml.parsers.ParserConfigurationException;
+
+import net.sf.taverna.t2.security.credentialmanager.CredentialManager;
+import net.sf.taverna.t2.workflowmodel.Edits;
+import net.sf.taverna.t2.workflowmodel.processor.activity.ActivityFactory;
+import net.sf.taverna.t2.workflowmodel.processor.activity.ActivityInputPort;
+import net.sf.taverna.t2.workflowmodel.processor.activity.ActivityOutputPort;
+import net.sf.taverna.wsdl.parser.TypeDescriptor;
+import net.sf.taverna.wsdl.parser.UnknownOperationException;
+import net.sf.taverna.wsdl.parser.WSDLParser;
+
+import org.apache.log4j.Logger;
+import org.xml.sax.SAXException;
+
+import com.fasterxml.jackson.databind.JsonNode;
+import com.fasterxml.jackson.databind.ObjectMapper;
+
+/**
+ * An {@link ActivityFactory} for creating <code>WSDLActivity</code>.
+ *
+ * @author David Withers
+ */
+public class WSDLActivityFactory implements ActivityFactory {
+
+ private static Logger logger = Logger.getLogger(WSDLActivityFactory.class);
+
+ private CredentialManager credentialManager;
+ private Edits edits;
+
+ @Override
+ public WSDLActivity createActivity() {
+ return new WSDLActivity(credentialManager);
+ }
+
+ @Override
+ public URI getActivityType() {
+ return URI.create(WSDLActivity.URI);
+ }
+
+ @Override
+ public JsonNode getActivityConfigurationSchema() {
+ ObjectMapper objectMapper = new ObjectMapper();
+ try {
+ return objectMapper.readTree(getClass().getResource("/schema.json"));
+ } catch (IOException e) {
+ return objectMapper.createObjectNode();
+ }
+ }
+
+ public void setCredentialManager(CredentialManager credentialManager) {
+ this.credentialManager = credentialManager;
+ }
+
+ @Override
+ public Set<ActivityInputPort> getInputPorts(JsonNode configuration) {
+ Map<String, ActivityInputPort> inputPorts = new HashMap<>();
+ try {
+ WSDLParser parser = new WSDLParser(configuration.get("operation").get("wsdl").textValue());
+ List<TypeDescriptor> inputDescriptors = parser.getOperationInputParameters(configuration
+ .get("operation").get("name").textValue());
+ for (TypeDescriptor descriptor : inputDescriptors) {
+ inputPorts.put(descriptor.getName(), edits.createActivityInputPort(
+ descriptor.getName(), descriptor.getDepth(), true, null, String.class));
+ }
+ if (parser.isWsrfService()) {
+ // Make sure the port name is unique
+ String endpointReferenceInputPortName = WSDLActivity.ENDPOINT_REFERENCE;
+ int counter = 0;
+ while (inputPorts.containsKey(endpointReferenceInputPortName)) {
+ endpointReferenceInputPortName = WSDLActivity.ENDPOINT_REFERENCE + counter++;
+ }
+ inputPorts.put(endpointReferenceInputPortName, edits.createActivityInputPort(
+ endpointReferenceInputPortName, 0, true, null, String.class));
+ }
+ } catch (ParserConfigurationException | WSDLException | IOException | SAXException | UnknownOperationException e) {
+ logger.warn(
+ "Unable to parse the WSDL " + configuration.get("operation").get("wsdl").textValue(), e);
+ }
+
+ return new HashSet<>(inputPorts.values());
+ }
+
+ @Override
+ public Set<ActivityOutputPort> getOutputPorts(JsonNode configuration) {
+ Set<ActivityOutputPort> outputPorts = new HashSet<>();
+ try {
+ WSDLParser parser = new WSDLParser(configuration.get("operation").get("wsdl")
+ .textValue());
+ List<TypeDescriptor> outputDescriptors = parser
+ .getOperationOutputParameters(configuration.get("operation").get("name")
+ .textValue());
+ for (TypeDescriptor descriptor : outputDescriptors) {
+ outputPorts.add(edits.createActivityOutputPort(descriptor.getName(),
+ descriptor.getDepth(), descriptor.getDepth()));
+ }
+ // add output for attachment list
+ outputPorts.add(edits.createActivityOutputPort("attachmentList", 1, 1));
+ } catch (ParserConfigurationException | WSDLException | IOException | SAXException | UnknownOperationException e) {
+ logger.warn(
+ "Unable to parse the WSDL " + configuration.get("operation").get("wsdl").textValue(), e);
+ }
+
+ return outputPorts;
+ }
+
+ public void setEdits(Edits edits) {
+ this.edits = edits;
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-taverna-common-activities/blob/77704689/taverna-wsdl-activity/src/main/java/net/sf/taverna/t2/activities/wsdl/WSDLActivityHealthChecker.java
----------------------------------------------------------------------
diff --git a/taverna-wsdl-activity/src/main/java/net/sf/taverna/t2/activities/wsdl/WSDLActivityHealthChecker.java b/taverna-wsdl-activity/src/main/java/net/sf/taverna/t2/activities/wsdl/WSDLActivityHealthChecker.java
new file mode 100644
index 0000000..0437ff6
--- /dev/null
+++ b/taverna-wsdl-activity/src/main/java/net/sf/taverna/t2/activities/wsdl/WSDLActivityHealthChecker.java
@@ -0,0 +1,170 @@
+/*******************************************************************************
+ * Copyright (C) 2007 The University of Manchester
+ *
+ * Modifications to the initial code base are copyright of their
+ * respective authors, or their employers as appropriate.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * as published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This program 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+ ******************************************************************************/
+package net.sf.taverna.t2.activities.wsdl;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
+
+import javax.wsdl.WSDLException;
+import javax.xml.parsers.ParserConfigurationException;
+
+import net.sf.taverna.t2.visit.VisitReport;
+import net.sf.taverna.t2.visit.VisitReport.Status;
+import net.sf.taverna.t2.workflowmodel.health.HealthCheck;
+import net.sf.taverna.t2.workflowmodel.health.RemoteHealthChecker;
+import net.sf.taverna.t2.workflowmodel.processor.activity.Activity;
+import net.sf.taverna.t2.workflowmodel.processor.activity.DisabledActivity;
+import net.sf.taverna.wsdl.parser.UnknownOperationException;
+import net.sf.taverna.wsdl.parser.WSDLParser;
+
+import org.xml.sax.SAXException;
+
+import com.fasterxml.jackson.databind.JsonNode;
+
+public class WSDLActivityHealthChecker extends RemoteHealthChecker {
+
+ private Activity<?> activity;
+
+ public boolean canVisit(Object subject) {
+ if (subject == null) {
+ return false;
+ }
+ if (subject instanceof WSDLActivity) {
+ return true;
+ }
+ if (subject instanceof DisabledActivity) {
+ return (((DisabledActivity) subject).getActivity() instanceof WSDLActivity);
+ }
+ return false;
+ }
+
+ public VisitReport visit(Object o, List<Object> ancestors) {
+ List<VisitReport> reports = new ArrayList<VisitReport>();
+ activity = (Activity<?>) o;
+ String endpoint = null;
+
+ WSDLParser parser;
+ try {
+ JsonNode configuration = null;
+ if (activity instanceof WSDLActivity) {
+ configuration = ((WSDLActivity)activity).getConfiguration();
+ } else if (activity instanceof DisabledActivity) {
+ configuration = (JsonNode) ((DisabledActivity) activity).getActivityConfiguration();
+ }
+ endpoint = configuration.get("operation").get("wsdl").asText();
+ VisitReport wsdlEndpointReport = RemoteHealthChecker.contactEndpoint(activity, endpoint);
+ reports.add(wsdlEndpointReport);
+ if (!wsdlEndpointReport.getStatus().equals(Status.SEVERE)) {
+ parser = new WSDLParser(endpoint);
+
+ String operationName = configuration.get("operation").get("name").asText();
+ try {
+ reports.add(testStyleAndUse(endpoint,
+ parser,
+ operationName));
+ reports.add(testEndpoint(parser, operationName));
+ } catch (UnknownOperationException e) {
+ VisitReport vr = new VisitReport(HealthCheck.getInstance(), activity,
+ "Operation not found", HealthCheck.UNKNOWN_OPERATION,
+ Status.SEVERE);
+ vr.setProperty("operationName", operationName);
+ vr.setProperty("endpoint", endpoint);
+ reports.add(vr);
+ }
+ }
+
+ } catch (ParserConfigurationException e) {
+ VisitReport vr = new VisitReport(HealthCheck.getInstance(), activity, "Invalid WSDL", HealthCheck.BAD_WSDL, Status.SEVERE);
+ vr.setProperty("exception", e);
+ vr.setProperty("endpoint", endpoint);
+ reports.add(vr);
+ } catch (WSDLException e) {
+ VisitReport vr = new VisitReport(HealthCheck.getInstance(), activity, "Invalid WSDL", HealthCheck.BAD_WSDL, Status.SEVERE);
+ vr.setProperty("exception", e);
+ vr.setProperty("endpoint", endpoint);
+ reports.add(vr);
+ } catch (IOException e) {
+ VisitReport vr = new VisitReport(HealthCheck.getInstance(), activity, "Read problem", HealthCheck.IO_PROBLEM, Status.SEVERE);
+ vr.setProperty("exception", e);
+ vr.setProperty("endpoint", endpoint);
+ reports.add(vr);
+ } catch (SAXException e) {
+ VisitReport vr = new VisitReport(HealthCheck.getInstance(), activity, "Invalid WSDL", HealthCheck.BAD_WSDL, Status.SEVERE);
+ vr.setProperty("exception", e);
+ vr.setProperty("endpoint", endpoint);
+ reports.add(vr);
+ }
+
+ Status status = VisitReport.getWorstStatus(reports);
+ VisitReport report = new VisitReport(HealthCheck.getInstance(), activity, "WSDL Activity report", HealthCheck.NO_PROBLEM,
+ status, reports);
+
+ return report;
+ }
+
+ public static boolean checkStyleAndUse(String style, String use) {
+ return !(style.equalsIgnoreCase("rpc") && use.equalsIgnoreCase("literal"));
+ }
+
+ private VisitReport testStyleAndUse(String endpoint, WSDLParser parser, String operationName) throws
+ UnknownOperationException {
+ VisitReport report;
+ String style = parser.getStyle().toLowerCase();
+ String use = "?";
+ use = parser.getUse(operationName).toLowerCase();
+ if (!checkStyleAndUse(style, use)) {
+ report = new VisitReport(HealthCheck.getInstance(), activity,
+ "Unsupported style", HealthCheck.UNSUPPORTED_STYLE,
+ Status.SEVERE);
+ report.setProperty("use", use);
+ report.setProperty("style", style);
+ report.setProperty("endpoint", endpoint);
+ } else {
+ report = new VisitReport(HealthCheck.getInstance(), activity, style + "/"
+ + use + " is OK", HealthCheck.NO_PROBLEM, Status.OK);
+ }
+ return report;
+ }
+
+ private VisitReport testEndpoint(WSDLParser parser, String operationName) {
+ List<VisitReport> reports = new ArrayList<VisitReport>();
+ List<String> endpoints = parser
+ .getOperationEndpointLocations(operationName);
+ for (String endpoint : endpoints) {
+ reports.add(RemoteHealthChecker.contactEndpoint(activity, endpoint));
+ }
+
+ Status status = VisitReport.getWorstStatus(reports);
+ if (reports.size()==1) {
+ return reports.get(0);
+ }
+ else if (reports.size()==0) {
+ VisitReport report = new VisitReport(HealthCheck.getInstance(), activity, "Service could not be located.", HealthCheck.NO_ENDPOINTS, Status.SEVERE);
+ report.setProperty("operationName", operationName);
+ return report;
+ }
+ else {
+ return new VisitReport(HealthCheck.getInstance(), activity, "Endpoint tests", HealthCheck.NO_PROBLEM, status, reports);
+ }
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-taverna-common-activities/blob/77704689/taverna-wsdl-activity/src/main/java/net/sf/taverna/t2/activities/wsdl/WSDLOperationConfigurationBean.java
----------------------------------------------------------------------
diff --git a/taverna-wsdl-activity/src/main/java/net/sf/taverna/t2/activities/wsdl/WSDLOperationConfigurationBean.java b/taverna-wsdl-activity/src/main/java/net/sf/taverna/t2/activities/wsdl/WSDLOperationConfigurationBean.java
new file mode 100644
index 0000000..ac012ae
--- /dev/null
+++ b/taverna-wsdl-activity/src/main/java/net/sf/taverna/t2/activities/wsdl/WSDLOperationConfigurationBean.java
@@ -0,0 +1,57 @@
+/*******************************************************************************
+ * Copyright (C) 2011 The University of Manchester
+ *
+ * Modifications to the initial code base are copyright of their
+ * respective authors, or their employers as appropriate.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * as published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This program 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+ ******************************************************************************/
+package net.sf.taverna.t2.activities.wsdl;
+
+import java.net.URI;
+
+import net.sf.taverna.t2.workflowmodel.processor.config.ConfigurationBean;
+import net.sf.taverna.t2.workflowmodel.processor.config.ConfigurationProperty;
+
+/**
+ * Configuration for a WSDL operation.
+ *
+ * @author David Withers
+ */
+@ConfigurationBean(uri = WSDLActivity.URI + "/operation")
+public class WSDLOperationConfigurationBean {
+
+ private URI wsdl;
+ private String operationName;
+
+ public URI getWsdl() {
+ return wsdl;
+ }
+
+ @ConfigurationProperty(name = "wsdl", label = "WSDL URL", description = "The location of the WSDL definition for the web service")
+ public void setWsdl(URI wsdl) {
+ this.wsdl = wsdl;
+ }
+
+ public String getOperationName() {
+ return operationName;
+ }
+
+ @ConfigurationProperty(name = "name", label = "Operation Name", description = "The name of the WSDL operation")
+ public void setOperationName(String operationName) {
+ this.operationName = operationName;
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-taverna-common-activities/blob/77704689/taverna-wsdl-activity/src/main/java/net/sf/taverna/t2/activities/wsdl/package.html
----------------------------------------------------------------------
diff --git a/taverna-wsdl-activity/src/main/java/net/sf/taverna/t2/activities/wsdl/package.html b/taverna-wsdl-activity/src/main/java/net/sf/taverna/t2/activities/wsdl/package.html
new file mode 100644
index 0000000..e38a14e
--- /dev/null
+++ b/taverna-wsdl-activity/src/main/java/net/sf/taverna/t2/activities/wsdl/package.html
@@ -0,0 +1,3 @@
+<body>
+Contains the activity classes required to interact with a WSDL based web-service.
+</body>
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-taverna-common-activities/blob/77704689/taverna-wsdl-activity/src/main/java/net/sf/taverna/t2/activities/wsdl/security/SSLUtilities.java
----------------------------------------------------------------------
diff --git a/taverna-wsdl-activity/src/main/java/net/sf/taverna/t2/activities/wsdl/security/SSLUtilities.java b/taverna-wsdl-activity/src/main/java/net/sf/taverna/t2/activities/wsdl/security/SSLUtilities.java
new file mode 100644
index 0000000..69033bb
--- /dev/null
+++ b/taverna-wsdl-activity/src/main/java/net/sf/taverna/t2/activities/wsdl/security/SSLUtilities.java
@@ -0,0 +1,151 @@
+package net.sf.taverna.t2.activities.wsdl.security;
+
+import java.security.GeneralSecurityException;
+import java.security.SecureRandom;
+import java.security.cert.X509Certificate;
+import javax.net.ssl.HostnameVerifier;
+import javax.net.ssl.HttpsURLConnection;
+import javax.net.ssl.SSLContext;
+import javax.net.ssl.SSLSocketFactory;
+import javax.net.ssl.TrustManager;
+import javax.net.ssl.X509TrustManager;
+
+/**
+ * This class provide various static methods that relax X509 certificate and
+ * hostname verification while using the SSL over the HTTP protocol.
+ * <p>
+ * Call:
+ * SSLUtilities.trustAllHostnames() to turn off the default hostname verification on HTTPS connection;
+ * SSLUtilities.trustAllHttpsCertificates() to turn off the default certificate validation on HTTPS connection.
+ * SSLUtilities.stopTrustingAllHttpsCertificates() to stop trusting all hosts' certificates and go back to default Java settings.
+ *
+ * @author Francis Labrie
+ */
+public final class SSLUtilities {
+
+ /**
+ * Hostname verifier.
+ */
+ private static HostnameVerifier hostnameVerifier;
+ /**
+ * Thrust managers.
+ */
+ private static TrustManager[] trustManagers;
+
+ /**
+ * Set the default Hostname Verifier to an instance of a fake class that
+ * trust all hostnames.
+ */
+ public static void trustAllHostnames() {
+ // Create a trust manager that does not validate certificate chains
+ if(hostnameVerifier == null) {
+ hostnameVerifier = new FakeHostnameVerifier();
+ } // if
+ // Install the all-trusting host name verifier:
+ HttpsURLConnection.setDefaultHostnameVerifier(hostnameVerifier);
+ } // _trustAllHttpsCertificates
+
+ /**
+ * Set the default X509 Trust Manager to an instance of a fake class that
+ * trust all certificates, even the self-signed ones.
+ */
+ public static void trustAllHttpsCertificates() {
+ SSLContext context;
+
+ // Create a trust manager that does not validate certificate chains
+ if(trustManagers == null) {
+ trustManagers = new TrustManager[] {new FakeX509TrustManager()};
+ } // if
+ // Install the all-trusting trust manager:
+ try {
+ context = SSLContext.getInstance("SSL");
+ context.init(null, trustManagers, new SecureRandom());
+ } catch(GeneralSecurityException gse) {
+ throw new IllegalStateException(gse.getMessage());
+ } // catch
+ HttpsURLConnection.setDefaultSSLSocketFactory(context.
+ getSocketFactory());
+ } // _trustAllHttpsCertificates
+
+ /**
+ * This class implements a fake hostname verificator, trusting any host
+ * name.
+ *
+ * @author Francis Labrie
+ */
+ public static class FakeHostnameVerifier implements HostnameVerifier {
+
+ /**
+ * Always return true, indicating that the host name is
+ * an acceptable match with the server's authentication scheme.
+ *
+ * @param hostname the host name.
+ * @param session the SSL session used on the connection to
+ * host.
+ * @return the true boolean value
+ * indicating the host name is trusted.
+ */
+ public boolean verify(String hostname,
+ javax.net.ssl.SSLSession session) {
+ return(true);
+ } // verify
+ } // FakeHostnameVerifier
+
+ /**
+ * This class allow any X509 certificates to be used to authenticate the
+ * remote side of a secure socket, including self-signed certificates.
+ *
+ * @author Francis Labrie
+ */
+ public static class FakeX509TrustManager implements X509TrustManager {
+
+ /**
+ * Empty array of certificate authority certificates.
+ */
+ private static final X509Certificate[] _AcceptedIssuers =
+ new X509Certificate[] {};
+
+ /**
+ * Always trust for client SSL chain peer certificate
+ * chain with any authType authentication types.
+ *
+ * @param chain the peer certificate chain.
+ * @param authType the authentication type based on the client
+ * certificate.
+ */
+ public void checkClientTrusted(X509Certificate[] chain,
+ String authType) {
+ } // checkClientTrusted
+
+ /**
+ * Always trust for server SSL chain peer certificate
+ * chain with any authType exchange algorithm types.
+ *
+ * @param chain the peer certificate chain.
+ * @param authType the key exchange algorithm used.
+ */
+ public void checkServerTrusted(X509Certificate[] chain,
+ String authType) {
+ } // checkServerTrusted
+
+ /**
+ * Return an empty array of certificate authority certificates which
+ * are trusted for authenticating peers.
+ *
+ * @return a empty array of issuer certificates.
+ */
+ public X509Certificate[] getAcceptedIssuers() {
+ return(_AcceptedIssuers);
+ } // getAcceptedIssuers
+ } // FakeX509TrustManager
+
+ /**
+ * Stop trusting all certificates and go back to the default settings.
+ *
+ * @author Alex Nenadic
+ */
+ public static void stopTrustingAllHttpsCertificates(){
+ HttpsURLConnection.setDefaultSSLSocketFactory((SSLSocketFactory) SSLSocketFactory.getDefault());
+ }
+} // SSLUtilities
+
http://git-wip-us.apache.org/repos/asf/incubator-taverna-common-activities/blob/77704689/taverna-wsdl-activity/src/main/java/net/sf/taverna/t2/activities/wsdl/security/SecurityProfiles.java
----------------------------------------------------------------------
diff --git a/taverna-wsdl-activity/src/main/java/net/sf/taverna/t2/activities/wsdl/security/SecurityProfiles.java b/taverna-wsdl-activity/src/main/java/net/sf/taverna/t2/activities/wsdl/security/SecurityProfiles.java
new file mode 100644
index 0000000..aa8084b
--- /dev/null
+++ b/taverna-wsdl-activity/src/main/java/net/sf/taverna/t2/activities/wsdl/security/SecurityProfiles.java
@@ -0,0 +1,130 @@
+package net.sf.taverna.t2.activities.wsdl.security;
+
+import java.net.URI;
+
+import net.sf.taverna.t2.activities.wsdl.WSDLActivity;
+
+/**
+ * Various security profiles for Web services.
+ *
+ * @author Alex Nenadic
+ *
+ */
+public class SecurityProfiles {
+
+ public static URI SECURITY = URI.create(WSDLActivity.URI).resolve("wsdl/security");
+
+ /**
+ * Security profile for Web services that require
+ * UsernameToken authentication with plaintext password.
+ * Such services should typically be invoked over HTTPS.
+ */
+ public static final URI WSSECURITY_USERNAMETOKEN_PLAINTEXTPASSWORD = SECURITY.resolve("#WSSecurityUsernameTokenPlainTextPassword");
+ /**
+ * XML string for configuring Axis engine with wss4j handlers to handle setting security
+ * headers on the SOAP message for profile WSSECURITY_USERNAMETOKEN_PLAINTEXTPASSWORD.
+ */
+ public static final String WSSECURITY_USERNAMETOKEN_PLAINTEXTPASSWORD_CONFIG = "<deployment xmlns=\"http://xml.apache.org/axis/wsdd/\" xmlns:java=\"http://xml.apache.org/axis/wsdd/providers/java\">" +
+ "<globalConfiguration>" +
+ "<requestFlow>" +
+ "<handler type=\"java:org.apache.ws.axis.security.WSDoAllSender\">" +
+ "<parameter name=\"action\" value=\"UsernameToken\"/>" +
+ "<parameter name=\"passwordType\" value=\"PasswordText\"/>" +
+ "</handler>"+
+ "</requestFlow>" +
+ "</globalConfiguration>" +
+ "<transport name=\"http\" pivot=\"java:org.apache.axis.transport.http.HTTPSender\"/>"+
+ "</deployment>";
+
+ /**
+ * Security profile for Web services that require
+ * UsernameToken authentication with digest password.
+ * Such services would typically be invoked over HTTPS.
+ */
+ public static final URI WSSECURITY_USERNAMETOKEN_DIGESTPASSWORD = SECURITY.resolve("#WSSecurityUsernameTokenDigestPassword");
+ /**
+ * XML string for configuring Axis engine with wss4j handlers to handle setting security
+ * headers on the SOAP message for profile WSSECURITY_USERNAMETOKEN_DIGESTPASSWORD.
+ */
+ public static final String WSSECURITY_USERNAMETOKEN_DIGESTPASSWORD_CONFIG = "<deployment xmlns=\"http://xml.apache.org/axis/wsdd/\" xmlns:java=\"http://xml.apache.org/axis/wsdd/providers/java\">" +
+ "<globalConfiguration>" +
+ "<requestFlow>" +
+ "<handler type=\"java:org.apache.ws.axis.security.WSDoAllSender\">" +
+ "<parameter name=\"action\" value=\"UsernameToken\"/>" +
+ "<parameter name=\"passwordType\" value=\"PasswordDigest\"/>" +
+ "</handler>"+
+ "</requestFlow>" +
+ "</globalConfiguration>" +
+ "<transport name=\"http\" pivot=\"java:org.apache.axis.transport.http.HTTPSender\"/>"+
+ "</deployment>";
+
+ /**
+ * Security profile for Web services that require a timestamp SOAP header
+ * to be sent in addition to UsernameToken authentication with plaintext password.
+ * Such services should typically be invoked over HTTPS.
+ */
+ public static final URI WSSECURITY_TIMESTAMP_USERNAMETOKEN_PLAINTEXTPASSWORD = SECURITY.resolve("#WSSecurityTimestampUsernameTokenPlainTextPassword");
+ /**
+ * XML string for configuring Axis engine with wss4j handlers to handle setting security
+ * headers on the SOAP message for profile WSSECURITY_TIMESTAMP_USERNAMETOKEN_DIGESTPASSWORD.
+ */
+ public static final String WSSECURITY_TIMESTAMP_USERNAMETOKEN_PLAINTETPASSWORD_CONFIG = "<deployment xmlns=\"http://xml.apache.org/axis/wsdd/\" xmlns:java=\"http://xml.apache.org/axis/wsdd/providers/java\">" +
+ "<globalConfiguration>" +
+ "<requestFlow>" +
+ "<handler type=\"java:org.apache.ws.axis.security.WSDoAllSender\">" +
+ "<parameter name=\"action\" value=\"Timestamp UsernameToken\"/>" +
+ "<parameter name=\"passwordType\" value=\"PasswordText\"/>" +
+ "</handler>"+
+ "</requestFlow>" +
+ "<responseFlow>" +
+ "<handler type=\"java:org.apache.ws.axis.security.WSDoAllReceiver\">" +
+ "<parameter name=\"action\" value=\"Timestamp\"/>" +
+ "</handler>"+
+ "</responseFlow>" +
+ "</globalConfiguration>" +
+ "<transport name=\"http\" pivot=\"java:org.apache.axis.transport.http.HTTPSender\"/>"+
+ "</deployment>";
+
+ /**
+ * Security profile for Web services that require a timestamp SOAP header
+ * to be sent in addition to UsernameToken authentication with digest password.
+ * Such services would typically be invoked over HTTPS.
+ */
+ public static final URI WSSECURITY_TIMESTAMP_USERNAMETOKEN_DIGESTPASSWORD = SECURITY.resolve("#WSSecurityTimestampUsernameTokenDigestPassword");
+ /**
+ * XML string for configuring Axis engine with wss4j handlers to handle setting security
+ * headers on the SOAP message for profile WSSECURITY_TIMESTAMP_USERNAMETOKEN_DIGESTPASSWORD.
+ */
+ public static final String WSSECURITY_TIMESTAMP_USERNAMETOKEN_DIGESTPASSWORD_CONFIG = "<deployment xmlns=\"http://xml.apache.org/axis/wsdd/\" xmlns:java=\"http://xml.apache.org/axis/wsdd/providers/java\">" +
+ "<globalConfiguration>" +
+ "<requestFlow>" +
+ "<handler type=\"java:org.apache.ws.axis.security.WSDoAllSender\">" +
+ "<parameter name=\"action\" value=\"Timestamp UsernameToken\"/>" +
+ "<parameter name=\"passwordType\" value=\"PasswordDigest\"/>" +
+ "</handler>"+
+ "</requestFlow>" +
+ "<responseFlow>" +
+ "<handler type=\"java:org.apache.ws.axis.security.WSDoAllReceiver\">" +
+ "<parameter name=\"action\" value=\"Timestamp\"/>" +
+ "</handler>"+
+ "</responseFlow>" +
+ "</globalConfiguration>" +
+ "<transport name=\"http\" pivot=\"java:org.apache.axis.transport.http.HTTPSender\"/>"+
+ "</deployment>";
+
+ /**
+ * Security profile for Web services that require HTTP Basic Authentication.
+ * There is no WS-Security involved.
+ * Such services should typically be invoked over HTTPS.
+ */
+ public static final URI HTTP_BASIC_AUTHN = SECURITY.resolve("#HTTPBasicAuthNPlainTextPassword");
+
+ /**
+ * Security profile for Web services that require HTTP Digest Authentication.
+ * There is no WS-Security involved.
+ * Such services would typically be invoked over HTTPS.
+ */
+ public static final URI HTTP_DIGEST_AUTHN = SECURITY.resolve("#HTTPDigestAuthN");
+
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-taverna-common-activities/blob/77704689/taverna-wsdl-activity/src/main/java/net/sf/taverna/t2/activities/wsdl/security/TavernaAxisCustomSSLSocketFactory.java
----------------------------------------------------------------------
diff --git a/taverna-wsdl-activity/src/main/java/net/sf/taverna/t2/activities/wsdl/security/TavernaAxisCustomSSLSocketFactory.java b/taverna-wsdl-activity/src/main/java/net/sf/taverna/t2/activities/wsdl/security/TavernaAxisCustomSSLSocketFactory.java
new file mode 100644
index 0000000..19ecb14
--- /dev/null
+++ b/taverna-wsdl-activity/src/main/java/net/sf/taverna/t2/activities/wsdl/security/TavernaAxisCustomSSLSocketFactory.java
@@ -0,0 +1,40 @@
+package net.sf.taverna.t2.activities.wsdl.security;
+
+import java.io.IOException;
+import java.net.Socket;
+import java.util.Hashtable;
+
+import javax.net.ssl.SSLContext;
+
+import org.apache.axis.components.net.BooleanHolder;
+import org.apache.axis.components.net.JSSESocketFactory;
+
+public class TavernaAxisCustomSSLSocketFactory extends JSSESocketFactory {
+
+
+ public TavernaAxisCustomSSLSocketFactory(Hashtable attributes) {
+ super(attributes);
+ }
+
+ @Override
+ public Socket create(String host, int port, StringBuffer otherHeaders,
+ BooleanHolder useFullURL) throws Exception {
+ // Make sure we always pick up the default socket factory from SSLContext, which is based on
+ // Taverna's Keystore and Truststore and gets updated when they get updated (it may have
+ // been updated in the menatime so just refresh it here just in case).
+ initFactory();
+ return super.create(host, port, otherHeaders, useFullURL);
+ }
+
+ @Override
+ protected void initFactory() throws IOException {
+ try{
+ // Set it to the default one from the SSLContext which is set to use Taverna's Keystore and Truststore
+ sslFactory = SSLContext.getDefault().getSocketFactory();
+ }
+ catch (Exception e) {
+ throw new IOException("Could not get the Taverna's default SSLSocketFactory from SSLContext",e);
+ }
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-taverna-common-activities/blob/77704689/taverna-wsdl-activity/src/main/java/net/sf/taverna/t2/activities/wsdl/security/ThreadLocalSSLSocketFactory.java
----------------------------------------------------------------------
diff --git a/taverna-wsdl-activity/src/main/java/net/sf/taverna/t2/activities/wsdl/security/ThreadLocalSSLSocketFactory.java b/taverna-wsdl-activity/src/main/java/net/sf/taverna/t2/activities/wsdl/security/ThreadLocalSSLSocketFactory.java
new file mode 100644
index 0000000..5660cbe
--- /dev/null
+++ b/taverna-wsdl-activity/src/main/java/net/sf/taverna/t2/activities/wsdl/security/ThreadLocalSSLSocketFactory.java
@@ -0,0 +1,186 @@
+/*******************************************************************************
+ * Copyright (C) 2007 The University of Manchester
+ *
+ * Modifications to the initial code base are copyright of their
+ * respective authors, or their employers as appropriate.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * as published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This program 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+ ******************************************************************************/
+package net.sf.taverna.t2.activities.wsdl.security;
+
+import java.io.IOException;
+import java.net.InetAddress;
+import java.net.Socket;
+import java.net.UnknownHostException;
+import java.security.KeyManagementException;
+import java.security.NoSuchAlgorithmException;
+import java.security.SecureRandom;
+import java.security.cert.CertificateException;
+import java.security.cert.X509Certificate;
+
+import javax.net.ssl.HttpsURLConnection;
+import javax.net.ssl.SSLContext;
+import javax.net.ssl.SSLSocketFactory;
+import javax.net.ssl.TrustManager;
+import javax.net.ssl.X509TrustManager;
+
+import org.apache.log4j.Logger;
+
+/**
+ * An implementation of SSLSocketFactory which delegates to one of two internal
+ * SSLSocketFactory implementations. The implementation delegated to is
+ * determined by a thread local property and is either the default SSL socket or
+ * a customized one with a trust manager that allows the use of unsigned server
+ * certificates.
+ * <p>
+ * To set this as the default call install() prior to making any HTTPS
+ * connections, then bracket code which needs to trust unsigned certificates in
+ * the startTrustingEverything() and stopTrustingEverything() methods.
+ *
+ * @author Tom Oinn
+ *
+ */
+public class ThreadLocalSSLSocketFactory extends SSLSocketFactory {
+
+ private static Logger logger = Logger
+ .getLogger(ThreadLocalSSLSocketFactory.class);
+
+ /**
+ * Calls to open HTTPS connections will trust unsigned certificates afer
+ * this call is made, this is scoped to the current thread only.
+ */
+ public static void startTrustingEverything() {
+ threadLocalFactory.set(createAlwaysTrustingFactory());
+ }
+
+ /**
+ * Stop trusting unsigned certificates, reverting to the default behaviour
+ * for the current thread.
+ */
+ public static void stopTrustingEverything() {
+ threadLocalFactory.set(null);
+ }
+
+ /**
+ * Set this as the default global socket factory for HTTPS connections
+ */
+ public static void install() {
+ HttpsURLConnection
+ .setDefaultSSLSocketFactory(new ThreadLocalSSLSocketFactory());
+ }
+
+ /**
+ * Determine whether the current thread will trust unsigned certificates
+ */
+ public static boolean isTrustingEverything() {
+ return (threadLocalFactory.get() != null);
+ }
+
+ /**
+ * Never construct manually
+ */
+ private ThreadLocalSSLSocketFactory() {
+ super();
+ }
+
+ private static ThreadLocal<SSLSocketFactory> threadLocalFactory = new ThreadLocal<SSLSocketFactory>();
+
+ private static SSLSocketFactory createAlwaysTrustingFactory() {
+ SSLContext sc = null;
+ try {
+ sc = SSLContext.getInstance("SSL");
+ } catch (NoSuchAlgorithmException e1) {
+
+ logger.error("No SSL algorithm", e1);
+ }
+ TrustManager overlyTrusting = new X509TrustManager() {
+
+ public void checkClientTrusted(X509Certificate[] arg0, String arg1)
+ throws CertificateException {
+
+ }
+
+ public void checkServerTrusted(X509Certificate[] arg0, String arg1)
+ throws CertificateException {
+
+ }
+
+ public X509Certificate[] getAcceptedIssuers() {
+ return null;
+ }
+
+ };
+ try {
+ sc.init(null, new TrustManager[] { overlyTrusting },
+ new SecureRandom());
+ } catch (KeyManagementException e) {
+ logger.error("Unable to initialize SSLContext", e);
+ }
+ return sc.getSocketFactory();
+
+ }
+
+ private SSLSocketFactory getFactory() {
+ if (threadLocalFactory.get() == null) {
+ return (SSLSocketFactory) SSLSocketFactory.getDefault();
+ } else {
+ return threadLocalFactory.get();
+ }
+ }
+
+ @Override
+ public Socket createSocket(Socket arg0, String arg1, int arg2, boolean arg3)
+ throws IOException {
+ return getFactory().createSocket(arg0, arg1, arg2, arg3);
+ }
+
+ @Override
+ public String[] getDefaultCipherSuites() {
+ return getFactory().getDefaultCipherSuites();
+ }
+
+ @Override
+ public String[] getSupportedCipherSuites() {
+ return getFactory().getSupportedCipherSuites();
+ }
+
+ @Override
+ public Socket createSocket() throws IOException {
+ return getFactory().createSocket();
+ }
+
+ @Override
+ public Socket createSocket(String arg0, int arg1) throws IOException,
+ UnknownHostException {
+ return getFactory().createSocket(arg0, arg1);
+ }
+
+ @Override
+ public Socket createSocket(InetAddress arg0, int arg1) throws IOException {
+ return getFactory().createSocket(arg0, arg1);
+ }
+
+ @Override
+ public Socket createSocket(String arg0, int arg1, InetAddress arg2, int arg3)
+ throws IOException, UnknownHostException {
+ return getFactory().createSocket(arg0, arg1, arg2, arg3);
+ }
+
+ @Override
+ public Socket createSocket(InetAddress arg0, int arg1, InetAddress arg2,
+ int arg3) throws IOException {
+ return getFactory().createSocket(arg0, arg1, arg2, arg3);
+ }
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-taverna-common-activities/blob/77704689/taverna-wsdl-activity/src/main/java/net/sf/taverna/t2/activities/wsdl/wss4j/T2WSDoAllSender.java
----------------------------------------------------------------------
diff --git a/taverna-wsdl-activity/src/main/java/net/sf/taverna/t2/activities/wsdl/wss4j/T2WSDoAllSender.java b/taverna-wsdl-activity/src/main/java/net/sf/taverna/t2/activities/wsdl/wss4j/T2WSDoAllSender.java
new file mode 100644
index 0000000..7e9f909
--- /dev/null
+++ b/taverna-wsdl-activity/src/main/java/net/sf/taverna/t2/activities/wsdl/wss4j/T2WSDoAllSender.java
@@ -0,0 +1,231 @@
+/*******************************************************************************
+ * Copyright (C) 2007 The University of Manchester
+ *
+ * Modifications to the initial code base are copyright of their
+ * respective authors, or their employers as appropriate.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * as published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This program 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+ ******************************************************************************/
+
+package net.sf.taverna.t2.activities.wsdl.wss4j;
+
+import java.util.Vector;
+
+//import net.sf.taverna.t2.security.agents.SAException;
+//import net.sf.taverna.t2.security.agents.WSSecurityAgent;
+
+//import org.apache.commons.logging.Log;
+//import org.apache.commons.logging.LogFactory;
+//import org.apache.log4j.Logger;
+import org.apache.ws.axis.security.WSDoAllSender;
+import org.apache.ws.security.WSConstants;
+import org.apache.ws.security.WSEncryptionPart;
+import org.apache.ws.security.WSSConfig;
+import org.apache.ws.security.WSSecurityException;
+import org.apache.ws.security.handler.RequestData;
+import org.apache.ws.security.handler.WSHandlerConstants;
+import org.apache.ws.security.message.WSSecHeader;
+import org.apache.ws.security.util.WSSecurityUtil;
+import org.w3c.dom.Document;
+
+public class T2WSDoAllSender extends WSDoAllSender{
+
+ /**
+ * This is a security handler for wss4j that invokes security agents
+ * whenever access to the user's credentials (passwords, private keys)
+ * or secret keys is required. The security agent performs the necessary
+ * security operations on the message to be sent and returns the message.
+ */
+ private static final long serialVersionUID = 1L;
+
+ //private static Log log = LogFactory.getLog(T2WSDoAllSender.class.getName());
+
+ // private boolean doDebug = log.isDebugEnabled();
+
+ // private static Logger logger = Logger.getLogger(T2WSDoAllSender.class);
+
+ /**
+ * Performs all defined security actions to set-up the SOAP request.
+ *
+ * This method overrides the doSenderAction() method of WSHandler class
+ * by setting the actions to be executed to use T2 security agents.
+ *
+ *
+ * @param doAction a set defining the actions to do
+ * @param doc the request as DOM document
+ * @param reqData a data storage to pass values around bewteen methods
+ * @param actions a vector holding the actions to do in the order defined
+ * in the deployment file or property
+ * @throws WSSecurityException
+ */
+ @Override
+ protected void doSenderAction(int doAction, Document doc,
+ RequestData reqData, Vector actions,
+ boolean isRequest)
+ throws WSSecurityException {
+
+
+ boolean mu = decodeMustUnderstand(reqData);
+
+ WSSConfig wssConfig = WSSConfig.getNewInstance();
+
+ wssConfig
+ .setEnableSignatureConfirmation(decodeEnableSignatureConfirmation(reqData));
+
+ wssConfig
+ .setPrecisionInMilliSeconds(decodeTimestampPrecision(reqData));
+ reqData.setWssConfig(wssConfig);
+
+ Object mc = reqData.getMsgContext();
+ String actor = getString(WSHandlerConstants.ACTOR, mc);
+ reqData.setActor(actor);
+
+ WSSecHeader secHeader = new WSSecHeader(actor, mu);
+ secHeader.insertSecurityHeader(doc);
+
+ reqData.setSecHeader(secHeader);
+ reqData.setSoapConstants(WSSecurityUtil.getSOAPConstants(doc
+ .getDocumentElement()));
+ /*
+ * Here we have action, username, password, and actor, mustUnderstand.
+ * Now get the action specific parameters.
+ */
+ if ((doAction & WSConstants.UT) == WSConstants.UT) {
+ decodeUTParameter(reqData);
+ }
+ /*
+ * Here we have action, username, password, and actor, mustUnderstand.
+ * Now get the action specific parameters.
+ */
+ if ((doAction & WSConstants.UT_SIGN) == WSConstants.UT_SIGN) {
+ decodeUTParameter(reqData);
+ decodeSignatureParameter(reqData);
+ }
+ /*
+ * Get and check the Signature specific parameters first because they
+ * may be used for encryption too.
+ */
+ if ((doAction & WSConstants.SIGN) == WSConstants.SIGN) {
+ reqData.setSigCrypto(loadSignatureCrypto(reqData));
+ decodeSignatureParameter(reqData);
+ }
+ /*
+ * If we need to handle signed SAML token then we need may of the
+ * Signature parameters. The handle procedure loads the signature crypto
+ * file on demand, thus don't do it here.
+ */
+ if ((doAction & WSConstants.ST_SIGNED) == WSConstants.ST_SIGNED) {
+ decodeSignatureParameter(reqData);
+ }
+ /*
+ * Set and check the encryption specific parameters, if necessary take
+ * over signature parameters username and crypto instance.
+ */
+ if ((doAction & WSConstants.ENCR) == WSConstants.ENCR) {
+ reqData.setEncCrypto(loadEncryptionCrypto(reqData));
+ decodeEncryptionParameter(reqData);
+ }
+ /*
+ * If after all the parsing no Signature parts defined, set here a
+ * default set. This is necessary because we add SignatureConfirmation
+ * and therefore the default (Body) must be set here. The default setting
+ * in WSSignEnvelope doesn't work because the vector is not empty anymore.
+ */
+ if (reqData.getSignatureParts().isEmpty()) {
+ WSEncryptionPart encP = new WSEncryptionPart(reqData.getSoapConstants()
+ .getBodyQName().getLocalPart(), reqData.getSoapConstants()
+ .getEnvelopeURI(), "Content");
+ reqData.getSignatureParts().add(encP);
+ }
+ /*
+ * If SignatureConfirmation is enabled and this is a reqsponse then
+ * insert SignatureCOnfrmation elements, note their wsu:id in the signature
+ * parts. They will be signed automatically during a (probably) defined
+ * SIGN action.
+ */
+ if (wssConfig.isEnableSignatureConfirmation() && !isRequest) {
+ String done;
+ if ((done = (String) getProperty(reqData.getMsgContext(),
+ WSHandlerConstants.SIG_CONF_DONE)) == null
+ || !DONE.equals(done)) {
+ Vector results = null;
+ if ((results = (Vector) getProperty(reqData.getMsgContext(),
+ WSHandlerConstants.RECV_RESULTS)) != null) {
+ wssConfig.getAction(WSConstants.SC).execute(this, WSConstants.SC, doc, reqData);
+ }
+ }
+ }
+ /*
+ * Here we have all necessary information to perform the requested
+ * action(s).
+ */
+
+ // Get the security agent
+ /* WSSecurityAgent sa = (WSSecurityAgent) ((MessageContext)reqData.getMsgContext()).getProperty("security_agent");
+
+ // Perform security actions
+ for (int i = 0; i < actions.size(); i++) {
+
+ int actionToDo = ((Integer) actions.get(i)).intValue();
+ if (doDebug) {
+ log.debug("Performing Action: " + actionToDo);
+ }
+
+ switch (actionToDo) {
+ case WSConstants.UT:{
+ try {
+ sa.wssUsernameToken(doc, reqData);
+ } catch (SAException e) {
+ logger.error("", e);
+ } break;
+ }
+ case WSConstants.ENCR:
+ case WSConstants.SIGN:{//sa.wssSign(doc, reqData); break;}
+ case WSConstants.ST_SIGNED:
+ case WSConstants.ST_UNSIGNED:
+ case WSConstants.TS:
+ case WSConstants.UT_SIGN:
+ wssConfig.getAction(actionToDo).execute(this, actionToDo, doc, reqData);
+ break;
+ case WSConstants.NO_SERIALIZE:
+ reqData.setNoSerialization(true);
+ break;
+ }
+ } */
+
+ /*
+ * If this is a request then store all signature values. Add ours to
+ * already gathered values because of chained handlers, e.g. for
+ * other actors.
+ */
+
+ if (wssConfig.isEnableSignatureConfirmation() && isRequest) {
+ if (reqData.getSignatureValues().size() > 0) {
+ Vector sigv = null;
+ if ((sigv = (Vector) getProperty(reqData.getMsgContext(),
+ WSHandlerConstants.SEND_SIGV)) == null) {
+ sigv = new Vector();
+ setProperty(reqData.getMsgContext(),
+ WSHandlerConstants.SEND_SIGV, sigv);
+ }
+ // sigv.add(reqData.getSignatureValues());
+ sigv.addAll(reqData.getSignatureValues());
+ }
+ }
+ }
+
+}
+
+
http://git-wip-us.apache.org/repos/asf/incubator-taverna-common-activities/blob/77704689/taverna-wsdl-activity/src/main/java/net/sf/taverna/t2/activities/wsdl/xmlsplitter/AddXMLSplitterEdit.java
----------------------------------------------------------------------
diff --git a/taverna-wsdl-activity/src/main/java/net/sf/taverna/t2/activities/wsdl/xmlsplitter/AddXMLSplitterEdit.java b/taverna-wsdl-activity/src/main/java/net/sf/taverna/t2/activities/wsdl/xmlsplitter/AddXMLSplitterEdit.java
new file mode 100644
index 0000000..a30c6a2
--- /dev/null
+++ b/taverna-wsdl-activity/src/main/java/net/sf/taverna/t2/activities/wsdl/xmlsplitter/AddXMLSplitterEdit.java
@@ -0,0 +1,290 @@
+/*******************************************************************************
+ * Copyright (C) 2007 The University of Manchester
+ *
+ * Modifications to the initial code base are copyright of their
+ * respective authors, or their employers as appropriate.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * as published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This program 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+ ******************************************************************************/
+package net.sf.taverna.t2.activities.wsdl.xmlsplitter;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import net.sf.taverna.t2.activities.wsdl.WSDLActivity;
+import net.sf.taverna.t2.workflowmodel.CompoundEdit;
+import net.sf.taverna.t2.workflowmodel.Dataflow;
+import net.sf.taverna.t2.workflowmodel.Edit;
+import net.sf.taverna.t2.workflowmodel.EditException;
+import net.sf.taverna.t2.workflowmodel.Edits;
+import net.sf.taverna.t2.workflowmodel.EventForwardingOutputPort;
+import net.sf.taverna.t2.workflowmodel.EventHandlingInputPort;
+import net.sf.taverna.t2.workflowmodel.InputPort;
+import net.sf.taverna.t2.workflowmodel.OutputPort;
+import net.sf.taverna.t2.workflowmodel.Processor;
+import net.sf.taverna.t2.workflowmodel.ProcessorInputPort;
+import net.sf.taverna.t2.workflowmodel.ProcessorOutputPort;
+import net.sf.taverna.t2.workflowmodel.processor.activity.Activity;
+import net.sf.taverna.t2.workflowmodel.utils.Tools;
+import net.sf.taverna.wsdl.parser.ArrayTypeDescriptor;
+import net.sf.taverna.wsdl.parser.TypeDescriptor;
+
+import com.fasterxml.jackson.databind.JsonNode;
+
+public class AddXMLSplitterEdit implements Edit<Dataflow> {
+
+ private final Edits edits;
+ private final Activity<?> activity;
+ private final String portName;
+ private final boolean isInput;
+ private CompoundEdit compoundEdit1 = null;
+ private Edit<?> linkUpEdit;
+ private final Dataflow dataflow;
+ private boolean applied = false;
+
+ public AddXMLSplitterEdit(Dataflow dataflow, Activity<?> activity,
+ String portName, boolean isInput, Edits edits) {
+ this.dataflow = dataflow;
+ this.activity = activity;
+ this.portName = portName;
+ this.isInput = isInput;
+ this.edits = edits;
+ }
+
+ @Override
+ public Dataflow doEdit() throws EditException {
+ if (applied) throw new EditException("Edit has already been applied!");
+ List<Edit<?>> editList = new ArrayList<Edit<?>>();
+
+ Activity<JsonNode> splitter = null;
+ String sourcePortName = "";
+ Processor sourceProcessor = null;
+ Activity<?> sourceActivity = null;
+
+ String sinkPortName = "";
+ Processor sinkProcessor = null;
+ Activity<?> sinkActivity = null;
+
+
+ Processor activityProcessor = findProcessorForActivity(dataflow,
+ activity);
+ if (activityProcessor == null) {
+ throw new EditException(
+ "Cannot find the processor that the activity belongs to");
+ }
+
+
+ String displayName = portName;
+ if (portName.equals("parameters")) {
+ displayName = isInput ? "input" : "output";
+ }
+ String processorName = activityProcessor.getLocalName();
+ String candidateName;
+ if (displayName.startsWith(processorName)) {
+ // No need to make GetRequest_GetRequestResponse
+ candidateName = displayName;
+ } else {
+ // Combine with processor name
+ String displayProcessorName;
+ if (activity instanceof XMLOutputSplitterActivity || activity instanceof XMLInputSplitterActivity) {
+ // For splitters on splitters - avoid adding up blah_bluh_blih_more_stuff
+ String[] processorNameSplit = processorName.replace("_input", "").replace("_output", "").split("_");
+ displayProcessorName = processorNameSplit[processorNameSplit.length-1];
+ } else {
+ displayProcessorName = activityProcessor.getLocalName();
+ }
+ candidateName = displayProcessorName + "_" + displayName;
+ }
+ String name = Tools.uniqueProcessorName(candidateName, dataflow);
+ Processor splitterProcessor = edits.createProcessor(name);
+
+ try {
+ if (activity instanceof XMLInputSplitterActivity) {
+ if (!isInput) {
+ throw new EditException(
+ "Can only add an input splitter to another input splitter");
+ }
+ TypeDescriptor descriptor = ((XMLInputSplitterActivity) activity)
+ .getTypeDescriptorForInputPort(portName);
+ if (descriptor instanceof ArrayTypeDescriptor && !((ArrayTypeDescriptor)descriptor).isWrapped()) {
+ descriptor=((ArrayTypeDescriptor)descriptor).getElementType();
+ }
+
+ JsonNode bean = XMLSplitterConfigurationBeanBuilder
+ .buildBeanForInput(descriptor);
+ splitter = new XMLInputSplitterActivity();
+ editList.add(edits.getConfigureActivityEdit(splitter, bean));
+
+ } else if (activity instanceof XMLOutputSplitterActivity) {
+ if (isInput) {
+ throw new EditException(
+ "Can only add an output splitter to another output splitter");
+ }
+ TypeDescriptor descriptor = ((XMLOutputSplitterActivity) activity)
+ .getTypeDescriptorForOutputPort(portName);
+
+ if (descriptor instanceof ArrayTypeDescriptor && !((ArrayTypeDescriptor)descriptor).isWrapped()) {
+ descriptor=((ArrayTypeDescriptor)descriptor).getElementType();
+ }
+
+ JsonNode bean = XMLSplitterConfigurationBeanBuilder
+ .buildBeanForOutput(descriptor);
+ splitter = new XMLOutputSplitterActivity();
+ editList.add(edits.getConfigureActivityEdit(splitter, bean));
+
+ } else if (activity instanceof WSDLActivity) {
+ if (isInput) {
+ TypeDescriptor descriptor = ((WSDLActivity) activity)
+ .getTypeDescriptorForInputPort(portName);
+ JsonNode bean = XMLSplitterConfigurationBeanBuilder
+ .buildBeanForInput(descriptor);
+ splitter = new XMLInputSplitterActivity();
+ editList
+ .add(edits.getConfigureActivityEdit(splitter, bean));
+ } else {
+ TypeDescriptor descriptor = ((WSDLActivity) activity)
+ .getTypeDescriptorForOutputPort(portName);
+ JsonNode bean = XMLSplitterConfigurationBeanBuilder
+ .buildBeanForOutput(descriptor);
+ splitter = new XMLOutputSplitterActivity();
+ editList
+ .add(edits.getConfigureActivityEdit(splitter, bean));
+ }
+ } else {
+ throw new EditException(
+ "The activity type is not suitable for adding xml processing processors");
+ }
+ } catch (Exception e) {
+ throw new EditException(
+ "An error occured whilst tyring to add an XMLSplitter to the activity:"
+ + activity, e);
+ }
+
+ if (isInput) {
+ sourcePortName = "output";
+ sinkPortName = portName;
+ sinkProcessor = activityProcessor;
+ sinkActivity = activity;
+ sourceProcessor = splitterProcessor;
+ sourceActivity = splitter;
+ }
+ else {
+ sourcePortName = portName;
+ sinkPortName = "input";
+ sinkProcessor = splitterProcessor;
+ sinkActivity = splitter;
+ sourceProcessor = activityProcessor;
+ sourceActivity = activity;
+ }
+
+ editList.add(edits.getDefaultDispatchStackEdit(splitterProcessor));
+ editList.add(edits.getAddActivityEdit(splitterProcessor, splitter));
+// editList.add(edits
+// .getMapProcessorPortsForActivityEdit(splitterProcessor));
+ editList.add(edits.getAddProcessorEdit(dataflow, splitterProcessor));
+
+ compoundEdit1 = new CompoundEdit(editList);
+ compoundEdit1.doEdit();
+
+ List<Edit<?>> linkUpEditList = new ArrayList<Edit<?>>();
+
+ EventForwardingOutputPort source = getSourcePort(sourceProcessor, sourceActivity,
+ sourcePortName, linkUpEditList);
+ EventHandlingInputPort sink = getSinkPort(sinkProcessor, sinkActivity, sinkPortName, linkUpEditList);
+
+ if (source == null)
+ throw new EditException(
+ "Unable to find the source port when linking up "
+ + sourcePortName + " to " + sinkPortName);
+ if (sink == null)
+ throw new EditException(
+ "Unable to find the sink port when linking up "
+ + sourcePortName + " to " + sinkPortName);
+
+ linkUpEditList.add(net.sf.taverna.t2.workflowmodel.utils.Tools.getCreateAndConnectDatalinkEdit(dataflow, source, sink, edits));
+
+ linkUpEdit = new CompoundEdit(linkUpEditList);
+ linkUpEdit.doEdit();
+ applied = true;
+ return dataflow;
+ }
+
+ private EventHandlingInputPort getSinkPort(Processor processor, Activity<?> activity,
+ String portName, List<Edit<?>> editList) {
+ InputPort activityPort = net.sf.taverna.t2.workflowmodel.utils.Tools.getActivityInputPort(activity, portName);
+ //check if processor port exists
+ EventHandlingInputPort input = net.sf.taverna.t2.workflowmodel.utils.Tools.getProcessorInputPort(processor, activity, activityPort);
+ if (input == null) {
+ //port doesn't exist so create a processor port and map it
+ ProcessorInputPort processorInputPort =
+ edits.createProcessorInputPort(processor, activityPort.getName(), activityPort.getDepth());
+ editList.add(edits.getAddProcessorInputPortEdit(processor, processorInputPort));
+ editList.add(edits.getAddActivityInputPortMappingEdit(activity, activityPort.getName(), activityPort.getName()));
+ input = processorInputPort;
+ }
+ return input;
+ }
+
+ private EventForwardingOutputPort getSourcePort(Processor processor, Activity<?> activity,
+ String portName, List<Edit<?>> editList) {
+ OutputPort activityPort = net.sf.taverna.t2.workflowmodel.utils.Tools.getActivityOutputPort(activity, portName);
+ //check if processor port exists
+ EventForwardingOutputPort output = net.sf.taverna.t2.workflowmodel.utils.Tools.getProcessorOutputPort(processor, activity, activityPort);
+ if (output == null) {
+ //port doesn't exist so create a processor port and map it
+ ProcessorOutputPort processorOutputPort =
+ edits.createProcessorOutputPort(processor, activityPort.getName(), activityPort.getDepth(), activityPort.getGranularDepth());
+ editList.add(edits.getAddProcessorOutputPortEdit(processor, processorOutputPort));
+ editList.add(edits.getAddActivityOutputPortMappingEdit(activity, activityPort.getName(), activityPort.getName()));
+ output = processorOutputPort;
+ }
+ return output;
+ }
+
+ @Override
+ public void undo() {
+ if (!applied) {
+ throw new RuntimeException(
+ "Attempt to undo edit that was never applied");
+ }
+ if (linkUpEdit.isApplied())
+ linkUpEdit.undo();
+ if (compoundEdit1.isApplied())
+ compoundEdit1.undo();
+ applied = false;
+ }
+
+ @Override
+ public boolean isApplied() {
+ return applied;
+ }
+
+ private Processor findProcessorForActivity(Dataflow dataflow,
+ Activity<?> activity) {
+ for (Processor p : dataflow.getProcessors()) {
+ for (Activity<?> a : p.getActivityList()) {
+ if (a == activity)
+ return p;
+ }
+ }
+ return null;
+ }
+
+ @Override
+ public Object getSubject() {
+ return dataflow;
+ }
+
+}