You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@airavata.apache.org by sh...@apache.org on 2015/03/26 18:08:00 UTC
[01/50] [abbrv] airavata git commit: Implement Airavata default
parser to next iteration.
Repository: airavata
Updated Branches:
refs/heads/master 80d9df511 -> a6c483cdb
Implement Airavata default parser to next iteration.
Project: http://git-wip-us.apache.org/repos/asf/airavata/repo
Commit: http://git-wip-us.apache.org/repos/asf/airavata/commit/e3ce93e1
Tree: http://git-wip-us.apache.org/repos/asf/airavata/tree/e3ce93e1
Diff: http://git-wip-us.apache.org/repos/asf/airavata/diff/e3ce93e1
Branch: refs/heads/master
Commit: e3ce93e1f4b78d01125bc06a894533424723d9a6
Parents: c90662f
Author: shamrath <sh...@gmail.com>
Authored: Fri Feb 13 14:56:24 2015 -0500
Committer: shamrath <sh...@gmail.com>
Committed: Fri Feb 13 14:56:24 2015 -0500
----------------------------------------------------------------------
modules/simple-workflow/pom.xml | 18 ++
.../workflow/engine/AiravataDefaultParser.java | 111 ----------
.../workflow/engine/SimpleWorkflowEngine.java | 6 +
.../engine/SimpleWorkflowInterpreter.java | 20 +-
.../workflow/engine/dag/edge/DirectedEdge.java | 31 +++
.../workflow/engine/dag/edge/DirectedLink.java | 40 ----
.../simple/workflow/engine/dag/edge/Edge.java | 24 +-
.../engine/dag/nodes/ApplicationNode.java | 8 +-
.../engine/dag/nodes/ApplicationNodeImpl.java | 63 ++----
.../engine/dag/nodes/WorkflowInputNode.java | 7 +-
.../engine/dag/nodes/WorkflowInputNodeImpl.java | 25 ++-
.../dag/nodes/WorkflowOutputNodeImpl.java | 28 ++-
.../simple/workflow/engine/dag/port/InPort.java | 5 +-
.../workflow/engine/dag/port/InputPortIml.java | 58 ++++-
.../workflow/engine/dag/port/OutPort.java | 4 +-
.../workflow/engine/dag/port/OutPortImpl.java | 62 ++++++
.../simple/workflow/engine/dag/port/Port.java | 8 +
.../engine/parser/AiravataDefaultParser.java | 221 +++++++++++++++++++
.../workflow/engine/parser/PortContainer.java | 32 +++
.../simple/workflow/engine/WorkflowDAGTest.java | 25 +++
20 files changed, 536 insertions(+), 260 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/airavata/blob/e3ce93e1/modules/simple-workflow/pom.xml
----------------------------------------------------------------------
diff --git a/modules/simple-workflow/pom.xml b/modules/simple-workflow/pom.xml
index a296417..623934d 100644
--- a/modules/simple-workflow/pom.xml
+++ b/modules/simple-workflow/pom.xml
@@ -29,6 +29,24 @@
<artifactId>airavata-jpa-registry</artifactId>
<version>${project.version}</version>
</dependency>
+
+ <!-- Airavata default parser dependency -->
+ <dependency>
+ <groupId>org.apache.airavata</groupId>
+ <artifactId>airavata-workflow-model-core</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.airavata</groupId>
+ <artifactId>app-catalog-data</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.airavata</groupId>
+ <artifactId>app-catalog-cpi</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+ <!-- Messaging dependency -->
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
http://git-wip-us.apache.org/repos/asf/airavata/blob/e3ce93e1/modules/simple-workflow/src/main/java/org/apache/ariavata/simple/workflow/engine/AiravataDefaultParser.java
----------------------------------------------------------------------
diff --git a/modules/simple-workflow/src/main/java/org/apache/ariavata/simple/workflow/engine/AiravataDefaultParser.java b/modules/simple-workflow/src/main/java/org/apache/ariavata/simple/workflow/engine/AiravataDefaultParser.java
deleted file mode 100644
index 3819af4..0000000
--- a/modules/simple-workflow/src/main/java/org/apache/ariavata/simple/workflow/engine/AiravataDefaultParser.java
+++ /dev/null
@@ -1,111 +0,0 @@
-package org.apache.ariavata.simple.workflow.engine;
-
-import org.airavata.appcatalog.cpi.AppCatalogException;
-import org.airavata.appcatalog.cpi.WorkflowCatalog;
-import org.apache.aiaravata.application.catalog.data.impl.AppCatalogFactory;
-import org.apache.airavata.model.appcatalog.appinterface.InputDataObjectType;
-import org.apache.airavata.model.workspace.experiment.Experiment;
-import org.apache.airavata.persistance.registry.jpa.impl.RegistryFactory;
-import org.apache.airavata.registry.cpi.Registry;
-import org.apache.airavata.registry.cpi.RegistryException;
-import org.apache.airavata.registry.cpi.RegistryModelType;
-import org.apache.airavata.workflow.model.component.ComponentException;
-import org.apache.airavata.workflow.model.component.system.ConstantComponent;
-import org.apache.airavata.workflow.model.component.system.InputComponent;
-import org.apache.airavata.workflow.model.component.system.S3InputComponent;
-import org.apache.airavata.workflow.model.graph.GraphException;
-import org.apache.airavata.workflow.model.graph.Node;
-import org.apache.airavata.workflow.model.graph.impl.NodeImpl;
-import org.apache.airavata.workflow.model.wf.Workflow;
-import org.apache.ariavata.simple.workflow.engine.dag.edge.Edge;
-import org.apache.ariavata.simple.workflow.engine.dag.nodes.WorkflowInputNode;
-import org.apache.ariavata.simple.workflow.engine.dag.nodes.WorkflowNode;
-import org.apache.ariavata.simple.workflow.engine.dag.port.OutPort;
-
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-
-//import org.apache.airavata.model.Workflow;
-
-/**
- * Created by shameera on 2/11/15.
- */
-public class AiravataDefaultParser implements WorkflowParser {
-
- private String experimentId;
- private String credentialToken ;
- private Workflow workflow;
- private Experiment experiment;
-
-
- public AiravataDefaultParser(String experimentId, String credentialToken) {
- this.experimentId = experimentId;
- this.credentialToken = credentialToken;
- }
-
- @Override
- public List<WorkflowInputNode> parse() throws RegistryException, AppCatalogException,
- ComponentException, GraphException {
- return parseWorkflow(getWorkflowFromExperiment());
- }
-
- private List<WorkflowInputNode> parseWorkflow(Workflow workflow) {
- List<Node> gNodes = getInputNodes(workflow);
- List<WorkflowInputNode> wfInputNodes = new ArrayList<WorkflowInputNode>();
- List<WorkflowNode> wfNodes = new ArrayList<WorkflowNode>();
- List<InputDataObjectType> experimentInputs = experiment.getExperimentInputs();
- Map<String,InputDataObjectType> inputDataMap=new HashMap<String, InputDataObjectType>();
- WorkflowInputNode wfInputNode = null;
- for (InputDataObjectType dataObjectType : experimentInputs) {
- inputDataMap.put(dataObjectType.getName(), dataObjectType);
- }
- for (Node gNode : gNodes) {
- // create a new wfInputNode instance by passing node name and node Id
- wfInputNode.setInputObject(inputDataMap.get(wfInputNode.getNodeName()));
- if (wfInputNode.getInputObject() == null) {
- // TODO: throw an error and exit.
- }
- Edge edge = null;//= new Edge
- OutPort outPort = null;
- outPort.
- link.setOutPort(null); // new Output
- wfInputNodes.add(wfInputNode);
- }
-
-
-
-
-
- return null;
- }
-
- private WorkflowInputNode getWorkflowInputNode(Node inputNode) {
- // FIXME: create a new workflow input node implementation with input node data.
- return null;
- }
-
- private Workflow getWorkflowFromExperiment() throws RegistryException, AppCatalogException, GraphException, ComponentException {
- Registry registry = RegistryFactory.getDefaultRegistry();
- experiment = (Experiment)registry.get(RegistryModelType.EXPERIMENT, experimentId);
- WorkflowCatalog workflowCatalog = getWorkflowCatalog();
- return new Workflow(workflowCatalog.getWorkflow(experiment.getApplicationId()).getGraph());
- }
-
- private WorkflowCatalog getWorkflowCatalog() throws AppCatalogException {
- return AppCatalogFactory.getAppCatalog().getWorkflowCatalog();
- }
-
- private ArrayList<Node> getInputNodes(Workflow wf) {
- ArrayList<Node> list = new ArrayList<Node>();
- List<NodeImpl> nodes = wf.getGraph().getNodes();
- for (Node node : nodes) {
- String name = node.getComponent().getName();
- if (InputComponent.NAME.equals(name) || ConstantComponent.NAME.equals(name) || S3InputComponent.NAME.equals(name)) {
- list.add(node);
- }
- }
- return list;
- }
-}
http://git-wip-us.apache.org/repos/asf/airavata/blob/e3ce93e1/modules/simple-workflow/src/main/java/org/apache/ariavata/simple/workflow/engine/SimpleWorkflowEngine.java
----------------------------------------------------------------------
diff --git a/modules/simple-workflow/src/main/java/org/apache/ariavata/simple/workflow/engine/SimpleWorkflowEngine.java b/modules/simple-workflow/src/main/java/org/apache/ariavata/simple/workflow/engine/SimpleWorkflowEngine.java
index 5a61874..ff057fb 100644
--- a/modules/simple-workflow/src/main/java/org/apache/ariavata/simple/workflow/engine/SimpleWorkflowEngine.java
+++ b/modules/simple-workflow/src/main/java/org/apache/ariavata/simple/workflow/engine/SimpleWorkflowEngine.java
@@ -22,4 +22,10 @@
package org.apache.ariavata.simple.workflow.engine;
public class SimpleWorkflowEngine{
+
+
+ public void invoke () {
+ WorkflowParser parser = WorkflowFactoryImpl.getInstance().getWorkflowParser();
+
+ }
}
http://git-wip-us.apache.org/repos/asf/airavata/blob/e3ce93e1/modules/simple-workflow/src/main/java/org/apache/ariavata/simple/workflow/engine/SimpleWorkflowInterpreter.java
----------------------------------------------------------------------
diff --git a/modules/simple-workflow/src/main/java/org/apache/ariavata/simple/workflow/engine/SimpleWorkflowInterpreter.java b/modules/simple-workflow/src/main/java/org/apache/ariavata/simple/workflow/engine/SimpleWorkflowInterpreter.java
index 3266423..b4bc9a2 100644
--- a/modules/simple-workflow/src/main/java/org/apache/ariavata/simple/workflow/engine/SimpleWorkflowInterpreter.java
+++ b/modules/simple-workflow/src/main/java/org/apache/ariavata/simple/workflow/engine/SimpleWorkflowInterpreter.java
@@ -76,7 +76,7 @@ public class SimpleWorkflowInterpreter {
}
- public void launchWorkflow() {
+ public void launchWorkflow() throws Exception {
// process workflow input nodes
processWorkflowInputNodes(getWorkflowInputNodes());
processReadyList();
@@ -151,10 +151,10 @@ public class SimpleWorkflowInterpreter {
Set<WorkflowNode> tempNodeSet = new HashSet<WorkflowNode>();
for (WorkflowInputNode wfInputNode : wfInputNodes) {
if (wfInputNode.isSatisfy()) {
- for (Edge edge : wfInputNode.getOutputLinks()) {
- WorkflowUtil.copyValues(wfInputNode.getInputObject(), edge.getInPort().getInputObject());
- tempNodeSet.add(edge.getInPort().getNode());
- }
+// for (Edge edge : wfInputNode.getOutputLinks()) {
+// WorkflowUtil.copyValues(wfInputNode.getInputObject(), edge.getToPort().getInputObject());
+// tempNodeSet.add(edge.getToPort().getNode());
+// }
}
}
for (WorkflowNode workflowNode : tempNodeSet) {
@@ -167,7 +167,7 @@ public class SimpleWorkflowInterpreter {
}
- public List<WorkflowInputNode> getWorkflowInputNodes() {
+ public List<WorkflowInputNode> getWorkflowInputNodes() throws Exception {
if (workflowInputNodes == null) {
// read workflow description from registry and parse it
WorkflowFactoryImpl wfFactory = WorkflowFactoryImpl.getInstance();
@@ -215,10 +215,10 @@ public class SimpleWorkflowInterpreter {
ApplicationNode applicationNode = (ApplicationNode) workflowNode;
// Workflow node can have one to many output ports and each output port can have one to many links
for (OutPort outPort : applicationNode.getOutputPorts()) {
- for (Edge edge : outPort.getOutputLinks()) {
- WorkflowUtil.copyValues(outPort.getOutputObject(), edge.getInPort().getInputObject());
- tempWfNodeSet.add(edge.getInPort().getNode());
- }
+// for (Edge edge : outPort.getOutputLinks()) {
+// WorkflowUtil.copyValues(outPort.getOutputObject(), edge.getToPort().getInputObject());
+// tempWfNodeSet.add(edge.getToPort().getNode());
+// }
}
for (WorkflowNode node : tempWfNodeSet) {
http://git-wip-us.apache.org/repos/asf/airavata/blob/e3ce93e1/modules/simple-workflow/src/main/java/org/apache/ariavata/simple/workflow/engine/dag/edge/DirectedEdge.java
----------------------------------------------------------------------
diff --git a/modules/simple-workflow/src/main/java/org/apache/ariavata/simple/workflow/engine/dag/edge/DirectedEdge.java b/modules/simple-workflow/src/main/java/org/apache/ariavata/simple/workflow/engine/dag/edge/DirectedEdge.java
new file mode 100644
index 0000000..4b05740
--- /dev/null
+++ b/modules/simple-workflow/src/main/java/org/apache/ariavata/simple/workflow/engine/dag/edge/DirectedEdge.java
@@ -0,0 +1,31 @@
+package org.apache.ariavata.simple.workflow.engine.dag.edge;
+
+import org.apache.ariavata.simple.workflow.engine.dag.port.InPort;
+import org.apache.ariavata.simple.workflow.engine.dag.port.OutPort;
+
+
+public class DirectedEdge implements Edge {
+
+ private InPort inPort;
+ private OutPort outPort;
+
+ @Override
+ public InPort getToPort() {
+ return null; // TODO: Auto generated method body.
+ }
+
+ @Override
+ public void setToPort(InPort inPort) {
+ // TODO: Auto generated method body.
+ }
+
+ @Override
+ public OutPort getFromPort() {
+ return null; // TODO: Auto generated method body.
+ }
+
+ @Override
+ public void setFromPort(OutPort outPort) {
+ // TODO: Auto generated method body.
+ }
+}
http://git-wip-us.apache.org/repos/asf/airavata/blob/e3ce93e1/modules/simple-workflow/src/main/java/org/apache/ariavata/simple/workflow/engine/dag/edge/DirectedLink.java
----------------------------------------------------------------------
diff --git a/modules/simple-workflow/src/main/java/org/apache/ariavata/simple/workflow/engine/dag/edge/DirectedLink.java b/modules/simple-workflow/src/main/java/org/apache/ariavata/simple/workflow/engine/dag/edge/DirectedLink.java
deleted file mode 100644
index bff9079..0000000
--- a/modules/simple-workflow/src/main/java/org/apache/ariavata/simple/workflow/engine/dag/edge/DirectedLink.java
+++ /dev/null
@@ -1,40 +0,0 @@
-/*
-package org.apache.ariavata.simple.workflow.engine.dag.links;
-
-import org.apache.ariavata.simple.workflow.engine.dag.nodes.WorkflowNode;
-
-*/
-/**
- * Created by shameera on 1/29/15.
- *//*
-
-public class DirectedLink implements Edge{
-
- private WorkflowNode _fromNode;
-
- private WorkflowNode _toNode;
-
- public DirectedLink(WorkflowNode _fromNode, WorkflowNode _toNode) {
- this._fromNode = _fromNode;
- this._toNode = _toNode;
- }
-
- @Override
- public WorkflowNode fromNode() {
- return null;
- }
-
- @Override
- public WorkflowNode toNode() {
- return null;
- }
-
- public void set_fromNode(WorkflowNode _fromNode) {
- this._fromNode = _fromNode;
- }
-
- public void set_toNode(WorkflowNode _toNode) {
- this._toNode = _toNode;
- }
-}
-*/
http://git-wip-us.apache.org/repos/asf/airavata/blob/e3ce93e1/modules/simple-workflow/src/main/java/org/apache/ariavata/simple/workflow/engine/dag/edge/Edge.java
----------------------------------------------------------------------
diff --git a/modules/simple-workflow/src/main/java/org/apache/ariavata/simple/workflow/engine/dag/edge/Edge.java b/modules/simple-workflow/src/main/java/org/apache/ariavata/simple/workflow/engine/dag/edge/Edge.java
index ed86b67..667a01d 100644
--- a/modules/simple-workflow/src/main/java/org/apache/ariavata/simple/workflow/engine/dag/edge/Edge.java
+++ b/modules/simple-workflow/src/main/java/org/apache/ariavata/simple/workflow/engine/dag/edge/Edge.java
@@ -7,29 +7,19 @@ import org.apache.ariavata.simple.workflow.engine.dag.port.InPort;
import org.apache.ariavata.simple.workflow.engine.dag.port.OutPort;
/**
- * Created by shameera on 1/29/15.
+ * Edge is a link to one node to another, basically edge should have outPort of a workflow node ,
+ * which is starting point and inPort of a workflow node, which is end point of the edge.
*/
-public interface Edge {
-
-// public WorkflowNode fromNode();
-
-// public WorkflowNode toNode();
-
-/* public InputDataObjectType getInputObject();
- public void setInputObject();
-
- public OutputDataObjectType getOutputObject();
-
- public void setOutputObject();*/
+public interface Edge {
- public InPort getInPort();
+ public InPort getToPort();
- public void setInPort(InPort inPort);
+ public void setToPort(InPort inPort);
- public OutPort getOutPort();
+ public OutPort getFromPort();
- public void setOutPort(OutPort outPort);
+ public void setFromPort(OutPort outPort);
}
http://git-wip-us.apache.org/repos/asf/airavata/blob/e3ce93e1/modules/simple-workflow/src/main/java/org/apache/ariavata/simple/workflow/engine/dag/nodes/ApplicationNode.java
----------------------------------------------------------------------
diff --git a/modules/simple-workflow/src/main/java/org/apache/ariavata/simple/workflow/engine/dag/nodes/ApplicationNode.java b/modules/simple-workflow/src/main/java/org/apache/ariavata/simple/workflow/engine/dag/nodes/ApplicationNode.java
index daa0038..cd2a955 100644
--- a/modules/simple-workflow/src/main/java/org/apache/ariavata/simple/workflow/engine/dag/nodes/ApplicationNode.java
+++ b/modules/simple-workflow/src/main/java/org/apache/ariavata/simple/workflow/engine/dag/nodes/ApplicationNode.java
@@ -28,14 +28,14 @@ import java.util.List;
public interface ApplicationNode extends WorkflowNode {
- public void addInputPort(InPort inPort);
+ public String getApplicationId();
+
+// public void addInputPort(InPort inPort);
public List<InPort> getInputPorts();
- public void addOutputPort(OutPort outPort);
+// public void addOutputPort(OutPort outPort);
public List<OutPort> getOutputPorts();
- public String getApplicationId();
-
}
http://git-wip-us.apache.org/repos/asf/airavata/blob/e3ce93e1/modules/simple-workflow/src/main/java/org/apache/ariavata/simple/workflow/engine/dag/nodes/ApplicationNodeImpl.java
----------------------------------------------------------------------
diff --git a/modules/simple-workflow/src/main/java/org/apache/ariavata/simple/workflow/engine/dag/nodes/ApplicationNodeImpl.java b/modules/simple-workflow/src/main/java/org/apache/ariavata/simple/workflow/engine/dag/nodes/ApplicationNodeImpl.java
index 4f4f6f4..9388c43 100644
--- a/modules/simple-workflow/src/main/java/org/apache/ariavata/simple/workflow/engine/dag/nodes/ApplicationNodeImpl.java
+++ b/modules/simple-workflow/src/main/java/org/apache/ariavata/simple/workflow/engine/dag/nodes/ApplicationNodeImpl.java
@@ -17,27 +17,30 @@
* specific language governing permissions and limitations
* under the License.
*
- *//*
+ */
package org.apache.ariavata.simple.workflow.engine.dag.nodes;
-import org.apache.ariavata.simple.workflow.engine.dag.links.Edge;
-import org.apache.ariavata.simple.workflow.engine.dag.port.InputPort;
-import org.apache.ariavata.simple.workflow.engine.dag.port.OutputPort;
-import java.util.ArrayList;
+import org.apache.ariavata.simple.workflow.engine.dag.port.InPort;
+import org.apache.ariavata.simple.workflow.engine.dag.port.OutPort;
+
import java.util.List;
public class ApplicationNodeImpl implements ApplicationNode {
private final String nodeId;
private NodeState myState = NodeState.WAITING;
- private List<Edge> inputLinks = new ArrayList<Edge>();
- private List<Edge> outputLinks = new ArrayList<Edge>();
+ private String applicationId;
public ApplicationNodeImpl(String nodeId) {
+ this(nodeId, null);
+ }
+
+ public ApplicationNodeImpl(String nodeId, String applicationId) {
this.nodeId = nodeId;
+ this.applicationId = applicationId;
}
@Override
@@ -46,6 +49,11 @@ public class ApplicationNodeImpl implements ApplicationNode {
}
@Override
+ public String getNodeName() {
+ return null; // TODO: Auto generated method body.
+ }
+
+ @Override
public NodeType getNodeType() {
return NodeType.APPLICATION;
}
@@ -62,47 +70,22 @@ public class ApplicationNodeImpl implements ApplicationNode {
}
@Override
- public void addInputPort(InputPort inputPort) {
-
+ public boolean isSatisfy() {
+ return false; // TODO: Auto generated method body.
}
@Override
- public List<InputPort> getInputPorts() {
- return null;
+ public String getApplicationId() {
+ return null; // TODO: Auto generated method body.
}
@Override
- public void addOutputPort(OutputPort outputPort) {
-
+ public List<InPort> getInputPorts() {
+ return null; // TODO: Auto generated method body.
}
@Override
- public List<OutputPort> getOutputPorts() {
- return null;
- }
-
- public List<Edge> getInputLinks() {
- return inputLinks;
- }
-
- public List<Edge> getOutputLinks() {
- return outputLinks;
- }
-
- public void setInputLinks(List<Edge> inputLinks) {
- this.inputLinks = inputLinks;
- }
-
- public void setOutputLinks(List<Edge> outputLinks) {
- this.outputLinks = outputLinks;
- }
-
- public void addInputLink(Edge inputLink) {
- inputLinks.add(inputLink);
- }
-
- public void addOutputLink(Edge outputLink) {
- outputLinks.add(outputLink);
+ public List<OutPort> getOutputPorts() {
+ return null; // TODO: Auto generated method body.
}
}
-*/
http://git-wip-us.apache.org/repos/asf/airavata/blob/e3ce93e1/modules/simple-workflow/src/main/java/org/apache/ariavata/simple/workflow/engine/dag/nodes/WorkflowInputNode.java
----------------------------------------------------------------------
diff --git a/modules/simple-workflow/src/main/java/org/apache/ariavata/simple/workflow/engine/dag/nodes/WorkflowInputNode.java b/modules/simple-workflow/src/main/java/org/apache/ariavata/simple/workflow/engine/dag/nodes/WorkflowInputNode.java
index 55b19da..8d24c96 100644
--- a/modules/simple-workflow/src/main/java/org/apache/ariavata/simple/workflow/engine/dag/nodes/WorkflowInputNode.java
+++ b/modules/simple-workflow/src/main/java/org/apache/ariavata/simple/workflow/engine/dag/nodes/WorkflowInputNode.java
@@ -23,6 +23,7 @@ package org.apache.ariavata.simple.workflow.engine.dag.nodes;
import org.apache.airavata.model.appcatalog.appinterface.InputDataObjectType;
import org.apache.ariavata.simple.workflow.engine.dag.edge.Edge;
+import org.apache.ariavata.simple.workflow.engine.dag.port.OutPort;
import java.util.List;
@@ -32,10 +33,6 @@ public interface WorkflowInputNode extends WorkflowNode {
public void setInputObject(InputDataObjectType inputObject);
- public void addOutputLink(Edge outputEdge);
-
- public void addOutputLink(List<Edge> outputEdges);
-
- public List<Edge> getOutputLinks();
+ public OutPort getOutPort();
}
http://git-wip-us.apache.org/repos/asf/airavata/blob/e3ce93e1/modules/simple-workflow/src/main/java/org/apache/ariavata/simple/workflow/engine/dag/nodes/WorkflowInputNodeImpl.java
----------------------------------------------------------------------
diff --git a/modules/simple-workflow/src/main/java/org/apache/ariavata/simple/workflow/engine/dag/nodes/WorkflowInputNodeImpl.java b/modules/simple-workflow/src/main/java/org/apache/ariavata/simple/workflow/engine/dag/nodes/WorkflowInputNodeImpl.java
index 54ea438..31bd6b0 100644
--- a/modules/simple-workflow/src/main/java/org/apache/ariavata/simple/workflow/engine/dag/nodes/WorkflowInputNodeImpl.java
+++ b/modules/simple-workflow/src/main/java/org/apache/ariavata/simple/workflow/engine/dag/nodes/WorkflowInputNodeImpl.java
@@ -1,5 +1,4 @@
/*
- *
* 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
@@ -16,24 +15,29 @@
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
- *
- *//*
+ */
+
package org.apache.ariavata.simple.workflow.engine.dag.nodes;
import org.apache.airavata.model.appcatalog.appinterface.InputDataObjectType;
-import org.apache.ariavata.simple.workflow.engine.dag.port.OutputPort;
+import org.apache.ariavata.simple.workflow.engine.dag.port.OutPort;
-import java.util.List;
public class WorkflowInputNodeImpl implements WorkflowInputNode {
private NodeState myState = NodeState.READY;
private final String nodeId;
+ private String nodeName;
public WorkflowInputNodeImpl(String nodeId) {
+ this(nodeId, null);
+ }
+
+ public WorkflowInputNodeImpl(String nodeId, String nodeName) {
this.nodeId = nodeId;
+ this.nodeName = nodeName;
}
@Override
@@ -42,6 +46,11 @@ public class WorkflowInputNodeImpl implements WorkflowInputNode {
}
@Override
+ public String getNodeName() {
+ return null; // TODO: Auto generated method body.
+ }
+
+ @Override
public NodeType getNodeType() {
return NodeType.WORKFLOW_INPUT;
}
@@ -68,14 +77,14 @@ public class WorkflowInputNodeImpl implements WorkflowInputNode {
}
@Override
- public void addOutputPort(OutputPort outputPort) {
+ public void setInputObject(InputDataObjectType inputObject) {
// TODO: Auto generated method body.
}
@Override
- public List<OutputPort> getOutputPorts() {
+ public OutPort getOutPort() {
return null; // TODO: Auto generated method body.
}
+
}
-*/
http://git-wip-us.apache.org/repos/asf/airavata/blob/e3ce93e1/modules/simple-workflow/src/main/java/org/apache/ariavata/simple/workflow/engine/dag/nodes/WorkflowOutputNodeImpl.java
----------------------------------------------------------------------
diff --git a/modules/simple-workflow/src/main/java/org/apache/ariavata/simple/workflow/engine/dag/nodes/WorkflowOutputNodeImpl.java b/modules/simple-workflow/src/main/java/org/apache/ariavata/simple/workflow/engine/dag/nodes/WorkflowOutputNodeImpl.java
index 5978884..36ab1f6 100644
--- a/modules/simple-workflow/src/main/java/org/apache/ariavata/simple/workflow/engine/dag/nodes/WorkflowOutputNodeImpl.java
+++ b/modules/simple-workflow/src/main/java/org/apache/ariavata/simple/workflow/engine/dag/nodes/WorkflowOutputNodeImpl.java
@@ -17,22 +17,28 @@
* specific language governing permissions and limitations
* under the License.
*
- *//*
+ */
package org.apache.ariavata.simple.workflow.engine.dag.nodes;
-import org.apache.ariavata.simple.workflow.engine.dag.port.InputPort;
-import java.util.List;
+import org.apache.airavata.model.appcatalog.appinterface.OutputDataObjectType;
+import org.apache.ariavata.simple.workflow.engine.dag.edge.Edge;
public class WorkflowOutputNodeImpl implements WorkflowOutputNode {
private NodeState myState = NodeState.WAITING;
private final String nodeId;
+ private String nodeName;
public WorkflowOutputNodeImpl(String nodeId) {
+ this(nodeId, null);
+ }
+
+ public WorkflowOutputNodeImpl(String nodeId, String nodeName) {
this.nodeId = nodeId;
+ this.nodeName = nodeName;
}
@Override
@@ -41,6 +47,11 @@ public class WorkflowOutputNodeImpl implements WorkflowOutputNode {
}
@Override
+ public String getNodeName() {
+ return null; // TODO: Auto generated method body.
+ }
+
+ @Override
public NodeType getNodeType() {
return NodeType.WORKFLOW_OUTPUT;
}
@@ -62,14 +73,13 @@ public class WorkflowOutputNodeImpl implements WorkflowOutputNode {
}
@Override
- public void addInputPort(InputPort inputPort) {
-
+ public OutputDataObjectType getOutputObject() {
+ return null; // TODO: Auto generated method body.
}
@Override
- public List<InputPort> getInputPorts() {
- return null;
+ public Edge getInputLink() {
+ return null; // TODO: Auto generated method body.
}
-
}
-*/
+
http://git-wip-us.apache.org/repos/asf/airavata/blob/e3ce93e1/modules/simple-workflow/src/main/java/org/apache/ariavata/simple/workflow/engine/dag/port/InPort.java
----------------------------------------------------------------------
diff --git a/modules/simple-workflow/src/main/java/org/apache/ariavata/simple/workflow/engine/dag/port/InPort.java b/modules/simple-workflow/src/main/java/org/apache/ariavata/simple/workflow/engine/dag/port/InPort.java
index 346c0f7..c635bef 100644
--- a/modules/simple-workflow/src/main/java/org/apache/ariavata/simple/workflow/engine/dag/port/InPort.java
+++ b/modules/simple-workflow/src/main/java/org/apache/ariavata/simple/workflow/engine/dag/port/InPort.java
@@ -30,7 +30,8 @@ public interface InPort extends Port {
public InputDataObjectType getInputObject();
- public Edge getInputLink();
+ public Edge getEdge();
+
+ public void addEdge(Edge edge);
- public void setInputLink();
}
http://git-wip-us.apache.org/repos/asf/airavata/blob/e3ce93e1/modules/simple-workflow/src/main/java/org/apache/ariavata/simple/workflow/engine/dag/port/InputPortIml.java
----------------------------------------------------------------------
diff --git a/modules/simple-workflow/src/main/java/org/apache/ariavata/simple/workflow/engine/dag/port/InputPortIml.java b/modules/simple-workflow/src/main/java/org/apache/ariavata/simple/workflow/engine/dag/port/InputPortIml.java
index 59f64bd..b33b91b 100644
--- a/modules/simple-workflow/src/main/java/org/apache/ariavata/simple/workflow/engine/dag/port/InputPortIml.java
+++ b/modules/simple-workflow/src/main/java/org/apache/ariavata/simple/workflow/engine/dag/port/InputPortIml.java
@@ -1,5 +1,4 @@
/*
- *
* 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
@@ -16,29 +15,64 @@
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
- *
- *//*
-
-
+ */
package org.apache.ariavata.simple.workflow.engine.dag.port;
import org.apache.airavata.model.appcatalog.appinterface.InputDataObjectType;
-import org.apache.ariavata.simple.workflow.engine.dag.links.Edge;
+import org.apache.ariavata.simple.workflow.engine.dag.edge.Edge;
+import org.apache.ariavata.simple.workflow.engine.dag.nodes.WorkflowNode;
+
+import java.util.List;
+
+public class InputPortIml implements InPort {
+
+ private InputDataObjectType inputDataObjectType;
+ private boolean isSatisfy = false;
+ private String portId;
+ private Edge edge;
+
+ public InputPortIml(String portId) {
+ this.portId = portId;
+ }
+
+ @Override
+ public void setInputObject(InputDataObjectType inputObject) {
+ // TODO: Auto generated method body.
+ }
-public class InputPortIml implements InputPort {
@Override
public InputDataObjectType getInputObject() {
- return null;
+ return null; // TODO: Auto generated method body.
}
@Override
- public Edge getInputLink() {
- return null;
+ public Edge getEdge() {
+ return this.edge;
+ }
+
+ @Override
+ public void addEdge(Edge edge) {
+ this.edge = edge;
}
@Override
public boolean isSatisfy() {
- return false;
+ return false; // TODO: Auto generated method body.
+ }
+
+ @Override
+ public WorkflowNode getNode() {
+ return null; // TODO: Auto generated method body.
+ }
+
+ @Override
+ public void setNode(WorkflowNode workflowNode) {
+ // TODO: Auto generated method body.
+ }
+
+ @Override
+ public String getId() {
+ return null; // TODO: Auto generated method body.
}
+
}
-*/
http://git-wip-us.apache.org/repos/asf/airavata/blob/e3ce93e1/modules/simple-workflow/src/main/java/org/apache/ariavata/simple/workflow/engine/dag/port/OutPort.java
----------------------------------------------------------------------
diff --git a/modules/simple-workflow/src/main/java/org/apache/ariavata/simple/workflow/engine/dag/port/OutPort.java b/modules/simple-workflow/src/main/java/org/apache/ariavata/simple/workflow/engine/dag/port/OutPort.java
index fa5baa2..04a7e1e 100644
--- a/modules/simple-workflow/src/main/java/org/apache/ariavata/simple/workflow/engine/dag/port/OutPort.java
+++ b/modules/simple-workflow/src/main/java/org/apache/ariavata/simple/workflow/engine/dag/port/OutPort.java
@@ -32,8 +32,8 @@ public interface OutPort extends Port {
public OutputDataObjectType getOutputObject();
- public List<Edge> getOutputLinks();
+ public List<Edge> getOutEdges();
- public void addOutputLink();
+ public void addEdge(Edge edge);
}
http://git-wip-us.apache.org/repos/asf/airavata/blob/e3ce93e1/modules/simple-workflow/src/main/java/org/apache/ariavata/simple/workflow/engine/dag/port/OutPortImpl.java
----------------------------------------------------------------------
diff --git a/modules/simple-workflow/src/main/java/org/apache/ariavata/simple/workflow/engine/dag/port/OutPortImpl.java b/modules/simple-workflow/src/main/java/org/apache/ariavata/simple/workflow/engine/dag/port/OutPortImpl.java
new file mode 100644
index 0000000..bc7628f
--- /dev/null
+++ b/modules/simple-workflow/src/main/java/org/apache/ariavata/simple/workflow/engine/dag/port/OutPortImpl.java
@@ -0,0 +1,62 @@
+package org.apache.ariavata.simple.workflow.engine.dag.port;
+
+import org.apache.airavata.model.appcatalog.appinterface.OutputDataObjectType;
+import org.apache.ariavata.simple.workflow.engine.dag.edge.Edge;
+import org.apache.ariavata.simple.workflow.engine.dag.nodes.WorkflowNode;
+
+import java.util.List;
+
+/**
+ * Created by shameera on 2/11/15.
+ */
+public class OutPortImpl implements OutPort {
+
+ private OutputDataObjectType outputDataObjectType;
+ private List<Edge> outEdges;
+ private boolean isSatisfy = false;
+ private String portId;
+
+ public OutPortImpl(String portId) {
+ this.portId = portId;
+ }
+
+ @Override
+ public void setOutputObject(OutputDataObjectType outputObject) {
+ // TODO: Auto generated method body.
+ }
+
+ @Override
+ public OutputDataObjectType getOutputObject() {
+ return null; // TODO: Auto generated method body.
+ }
+
+ @Override
+ public List<Edge> getOutEdges() {
+ return null; // TODO: Auto generated method body.
+ }
+
+ @Override
+ public void addEdge(Edge edge) {
+ // TODO: Auto generated method body.
+ }
+
+ @Override
+ public boolean isSatisfy() {
+ return false; // TODO: Auto generated method body.
+ }
+
+ @Override
+ public WorkflowNode getNode() {
+ return null; // TODO: Auto generated method body.
+ }
+
+ @Override
+ public void setNode(WorkflowNode workflowNode) {
+ // TODO: Auto generated method body.
+ }
+
+ @Override
+ public String getId() {
+ return null; // TODO: Auto generated method body.
+ }
+}
http://git-wip-us.apache.org/repos/asf/airavata/blob/e3ce93e1/modules/simple-workflow/src/main/java/org/apache/ariavata/simple/workflow/engine/dag/port/Port.java
----------------------------------------------------------------------
diff --git a/modules/simple-workflow/src/main/java/org/apache/ariavata/simple/workflow/engine/dag/port/Port.java b/modules/simple-workflow/src/main/java/org/apache/ariavata/simple/workflow/engine/dag/port/Port.java
index ca8246a..8c5d6c5 100644
--- a/modules/simple-workflow/src/main/java/org/apache/ariavata/simple/workflow/engine/dag/port/Port.java
+++ b/modules/simple-workflow/src/main/java/org/apache/ariavata/simple/workflow/engine/dag/port/Port.java
@@ -21,11 +21,19 @@
package org.apache.ariavata.simple.workflow.engine.dag.port;
+import org.apache.ariavata.simple.workflow.engine.dag.edge.Edge;
import org.apache.ariavata.simple.workflow.engine.dag.nodes.WorkflowNode;
+import java.util.List;
+
public interface Port {
public boolean isSatisfy();
public WorkflowNode getNode();
+
+ public void setNode(WorkflowNode workflowNode);
+
+ public String getId();
+
}
http://git-wip-us.apache.org/repos/asf/airavata/blob/e3ce93e1/modules/simple-workflow/src/main/java/org/apache/ariavata/simple/workflow/engine/parser/AiravataDefaultParser.java
----------------------------------------------------------------------
diff --git a/modules/simple-workflow/src/main/java/org/apache/ariavata/simple/workflow/engine/parser/AiravataDefaultParser.java b/modules/simple-workflow/src/main/java/org/apache/ariavata/simple/workflow/engine/parser/AiravataDefaultParser.java
new file mode 100644
index 0000000..92e9811
--- /dev/null
+++ b/modules/simple-workflow/src/main/java/org/apache/ariavata/simple/workflow/engine/parser/AiravataDefaultParser.java
@@ -0,0 +1,221 @@
+package org.apache.ariavata.simple.workflow.engine.parser;
+
+import org.airavata.appcatalog.cpi.AppCatalogException;
+import org.airavata.appcatalog.cpi.WorkflowCatalog;
+import org.apache.aiaravata.application.catalog.data.impl.AppCatalogFactory;
+import org.apache.airavata.model.appcatalog.appinterface.InputDataObjectType;
+import org.apache.airavata.model.appcatalog.appinterface.OutputDataObjectType;
+import org.apache.airavata.model.workspace.experiment.Experiment;
+import org.apache.airavata.persistance.registry.jpa.impl.RegistryFactory;
+import org.apache.airavata.registry.cpi.Registry;
+import org.apache.airavata.registry.cpi.RegistryException;
+import org.apache.airavata.registry.cpi.RegistryModelType;
+import org.apache.airavata.workflow.model.component.ComponentException;
+import org.apache.airavata.workflow.model.component.system.ConstantComponent;
+import org.apache.airavata.workflow.model.component.system.InputComponent;
+import org.apache.airavata.workflow.model.component.system.S3InputComponent;
+import org.apache.airavata.workflow.model.graph.DataEdge;
+import org.apache.airavata.workflow.model.graph.DataPort;
+import org.apache.airavata.workflow.model.graph.GraphException;
+import org.apache.airavata.workflow.model.graph.Node;
+import org.apache.airavata.workflow.model.graph.impl.NodeImpl;
+import org.apache.airavata.workflow.model.graph.system.OutputNode;
+import org.apache.airavata.workflow.model.graph.ws.WSNode;
+import org.apache.airavata.workflow.model.graph.ws.WSPort;
+import org.apache.airavata.workflow.model.wf.Workflow;
+import org.apache.ariavata.simple.workflow.engine.WorkflowParser;
+import org.apache.ariavata.simple.workflow.engine.dag.edge.DirectedEdge;
+import org.apache.ariavata.simple.workflow.engine.dag.edge.Edge;
+import org.apache.ariavata.simple.workflow.engine.dag.nodes.ApplicationNode;
+import org.apache.ariavata.simple.workflow.engine.dag.nodes.ApplicationNodeImpl;
+import org.apache.ariavata.simple.workflow.engine.dag.nodes.WorkflowInputNode;
+import org.apache.ariavata.simple.workflow.engine.dag.nodes.WorkflowInputNodeImpl;
+import org.apache.ariavata.simple.workflow.engine.dag.nodes.WorkflowNode;
+import org.apache.ariavata.simple.workflow.engine.dag.port.InPort;
+import org.apache.ariavata.simple.workflow.engine.dag.port.InputPortIml;
+import org.apache.ariavata.simple.workflow.engine.dag.port.OutPort;
+import org.apache.ariavata.simple.workflow.engine.dag.port.OutPortImpl;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+//import org.apache.airavata.model.Workflow;
+
+/**
+ * Created by shameera on 2/11/15.
+ */
+public class AiravataDefaultParser implements WorkflowParser {
+
+ private String experimentId;
+ private String credentialToken ;
+ private Workflow workflow;
+ private Experiment experiment;
+ private Map<String, ApplicationNode> wfNodes = new HashMap<String, ApplicationNode>();
+
+
+ public AiravataDefaultParser(String experimentId, String credentialToken) {
+ this.experimentId = experimentId;
+ this.credentialToken = credentialToken;
+ }
+
+ @Override
+ public List<WorkflowInputNode> parse() throws RegistryException, AppCatalogException,
+ ComponentException, GraphException {
+ return parseWorkflow(getWorkflowFromExperiment());
+ }
+
+ private List<WorkflowInputNode> parseWorkflow(Workflow workflow) {
+ List<Node> gNodes = getInputNodes(workflow);
+ List<WorkflowInputNode> wfInputNodes = new ArrayList<WorkflowInputNode>();
+ List<PortContainer> portContainers = new ArrayList<PortContainer>();
+ List<InputDataObjectType> experimentInputs = experiment.getExperimentInputs();
+ Map<String,InputDataObjectType> inputDataMap=new HashMap<String, InputDataObjectType>();
+ WorkflowInputNode wfInputNode = null;
+ for (InputDataObjectType dataObjectType : experimentInputs) {
+ inputDataMap.put(dataObjectType.getName(), dataObjectType);
+ }
+ OutPort outPort = null;
+ InPort inPort = null;
+ Edge edge = null;
+ for (Node gNode : gNodes) {
+ wfInputNode = new WorkflowInputNodeImpl(gNode.getID(), gNode.getName());
+ wfInputNode.setInputObject(inputDataMap.get(wfInputNode.getNodeName()));
+ if (wfInputNode.getInputObject() == null) {
+ // TODO: throw an error and exit.
+ }
+ for (DataPort dataPort : gNode.getInputPorts()) {
+ outPort = new OutPortImpl(dataPort.getID());
+ for (DataEdge dataEdge : dataPort.getEdges()) {
+ edge = new DirectedEdge();
+ edge.setFromPort(outPort);
+ outPort.addEdge(edge);
+ inPort = getInPort(dataEdge.getToPort());
+ edge.setToPort(inPort);
+ inPort.addEdge(edge);
+ portContainers.add(new PortContainer(dataEdge.getToPort(), inPort));
+ }
+ outPort.setOutputObject(getOutputDataObject(wfInputNode.getInputObject()));
+ }
+ wfInputNodes.add(wfInputNode);
+ }
+
+ // while port container empty iterate graph and build the workflow DAG.
+ buildModel(portContainers);
+
+ return wfInputNodes;
+ }
+
+ private void buildModel(List<PortContainer> portContainerList) {
+ // end condition of recursive call.
+ if (portContainerList == null || portContainerList.size() == 0) {
+ return ;
+ }
+ DataPort dataPort = null;
+ InPort inPort = null;
+ WorkflowNode wfNode = null;
+ List<PortContainer> nextPortContainerList = new ArrayList<PortContainer>();
+ for (PortContainer portContainer : portContainerList) {
+ dataPort = portContainer.getDataPort();
+ inPort = portContainer.getInPort();
+ Node node = dataPort.getNode();
+ inPort.setInputObject(getInputDataObject(dataPort));
+ if (node instanceof WSNode) {
+ WSNode wsNode = (WSNode) node;
+ wfNode = wfNodes.get(wsNode.getID());
+ if (wfNode == null) {
+ wfNode = new ApplicationNodeImpl(wsNode.getID(),
+ wsNode.getComponent().getApplication().getApplicationId());
+ nextPortContainerList.addAll(processOutPorts(wsNode, wfNode));
+ }
+ }else if (node instanceof OutputNode) {
+ OutputNode oNode = (OutputNode) node;
+ wfNode = new WorkflowInputNodeImpl(oNode.getID(), oNode.getName());
+ }
+ inPort.setNode(wfNode);
+ buildModel(nextPortContainerList);
+ // set the workflow node to inPort
+ // if require check the types of inputs and output ports,
+ // add outputPorts to the workflow node
+ // add edges to each output port
+ // add inport and indataport to the list
+ // recursively call the function.
+ }
+
+ }
+
+ private List<PortContainer> processOutPorts(Node node, WorkflowNode wfNode) {
+ OutPort outPort ;
+ Edge edge;
+ InPort inPort;
+ List<PortContainer> portContainers = new ArrayList<PortContainer>();
+ for (DataPort dataPort : node.getOutputPorts()) {
+ outPort = new OutPortImpl(dataPort.getID());
+ for (DataEdge dataEdge : dataPort.getEdges()) {
+ edge = new DirectedEdge();
+ edge.setFromPort(outPort);
+ outPort.addEdge(edge);
+ inPort = getInPort(dataEdge.getToPort());
+ edge.setToPort(inPort);
+ inPort.addEdge(edge);
+ portContainers.add(new PortContainer(dataEdge.getToPort(), inPort));
+ }
+ }
+ return portContainers;
+ }
+
+ private InPort getInPort(DataPort toPort) {
+ return new InputPortIml(toPort.getID());
+ }
+
+ private InputDataObjectType getInputDataObject(DataPort dataPort) {
+ InputDataObjectType inputDataObject = new InputDataObjectType();
+ inputDataObject.setName(dataPort.getName());
+ if (dataPort instanceof WSPort) {
+ WSPort port = (WSPort) dataPort;
+ inputDataObject.setInputOrder(port.getComponentPort().getInputOrder());
+ inputDataObject.setApplicationArgument(port.getComponentPort().getApplicationArgument() == null ?
+ "" : port.getComponentPort().getApplicationArgument());
+ inputDataObject.setType(dataPort.getType());
+ }
+ return inputDataObject;
+ }
+
+ private OutputDataObjectType getOutputDataObject(InputDataObjectType inputObject) {
+ OutputDataObjectType outputDataObjectType = new OutputDataObjectType();
+ outputDataObjectType.setApplicationArgument(inputObject.getApplicationArgument());
+ outputDataObjectType.setName(inputObject.getName());
+ outputDataObjectType.setType(inputObject.getType());
+ outputDataObjectType.setValue(inputObject.getValue());
+ return outputDataObjectType;
+ }
+
+ private WorkflowInputNode getWorkflowInputNode(Node inputNode) {
+ // FIXME: create a new workflow input node implementation with input node data.
+ return null;
+ }
+
+ private Workflow getWorkflowFromExperiment() throws RegistryException, AppCatalogException, GraphException, ComponentException {
+ Registry registry = RegistryFactory.getDefaultRegistry();
+ experiment = (Experiment)registry.get(RegistryModelType.EXPERIMENT, experimentId);
+ WorkflowCatalog workflowCatalog = getWorkflowCatalog();
+ return new Workflow(workflowCatalog.getWorkflow(experiment.getApplicationId()).getGraph());
+ }
+
+ private WorkflowCatalog getWorkflowCatalog() throws AppCatalogException {
+ return AppCatalogFactory.getAppCatalog().getWorkflowCatalog();
+ }
+
+ private ArrayList<Node> getInputNodes(Workflow wf) {
+ ArrayList<Node> list = new ArrayList<Node>();
+ List<NodeImpl> nodes = wf.getGraph().getNodes();
+ for (Node node : nodes) {
+ String name = node.getComponent().getName();
+ if (InputComponent.NAME.equals(name) || ConstantComponent.NAME.equals(name) || S3InputComponent.NAME.equals(name)) {
+ list.add(node);
+ }
+ }
+ return list;
+ }
+}
http://git-wip-us.apache.org/repos/asf/airavata/blob/e3ce93e1/modules/simple-workflow/src/main/java/org/apache/ariavata/simple/workflow/engine/parser/PortContainer.java
----------------------------------------------------------------------
diff --git a/modules/simple-workflow/src/main/java/org/apache/ariavata/simple/workflow/engine/parser/PortContainer.java b/modules/simple-workflow/src/main/java/org/apache/ariavata/simple/workflow/engine/parser/PortContainer.java
new file mode 100644
index 0000000..292bd1f
--- /dev/null
+++ b/modules/simple-workflow/src/main/java/org/apache/ariavata/simple/workflow/engine/parser/PortContainer.java
@@ -0,0 +1,32 @@
+package org.apache.ariavata.simple.workflow.engine.parser;
+
+import org.apache.airavata.workflow.model.graph.DataPort;
+import org.apache.ariavata.simple.workflow.engine.dag.port.InPort;
+
+
+public class PortContainer {
+ private DataPort dataPort;
+ private InPort inPort;
+
+
+ public PortContainer(DataPort dataPort, InPort inPort) {
+ this.dataPort = dataPort;
+ this.inPort = inPort;
+ }
+
+ public DataPort getDataPort() {
+ return dataPort;
+ }
+
+ public void setDataPort(DataPort dataPort) {
+ this.dataPort = dataPort;
+ }
+
+ public InPort getInPort() {
+ return inPort;
+ }
+
+ public void setInPort(InPort inPort) {
+ this.inPort = inPort;
+ }
+}
http://git-wip-us.apache.org/repos/asf/airavata/blob/e3ce93e1/modules/simple-workflow/src/test/java/org/apache/ariavata/simple/workflow/engine/WorkflowDAGTest.java
----------------------------------------------------------------------
diff --git a/modules/simple-workflow/src/test/java/org/apache/ariavata/simple/workflow/engine/WorkflowDAGTest.java b/modules/simple-workflow/src/test/java/org/apache/ariavata/simple/workflow/engine/WorkflowDAGTest.java
new file mode 100644
index 0000000..4e3a120
--- /dev/null
+++ b/modules/simple-workflow/src/test/java/org/apache/ariavata/simple/workflow/engine/WorkflowDAGTest.java
@@ -0,0 +1,25 @@
+package org.apache.ariavata.simple.workflow.engine;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+
+import static org.junit.Assert.*;
+
+public class WorkflowDAGTest {
+
+ @Before
+ public void setUp() throws Exception {
+
+ }
+
+ @After
+ public void tearDown() throws Exception {
+
+ }
+
+ @Test
+ public void testWorkflowDAG() throws Exception {
+
+ }
+}
\ No newline at end of file
[08/50] [abbrv] airavata git commit: Merge branch 'master' into
simpleWorkflowEngine
Posted by sh...@apache.org.
Merge branch 'master' into simpleWorkflowEngine
Project: http://git-wip-us.apache.org/repos/asf/airavata/repo
Commit: http://git-wip-us.apache.org/repos/asf/airavata/commit/0ae7e833
Tree: http://git-wip-us.apache.org/repos/asf/airavata/tree/0ae7e833
Diff: http://git-wip-us.apache.org/repos/asf/airavata/diff/0ae7e833
Branch: refs/heads/master
Commit: 0ae7e833a80abec8b9507082ebc834ea30d5afad
Parents: 0bc98a3 d9ae024
Author: shamrath <sh...@gmail.com>
Authored: Wed Feb 18 08:37:30 2015 -0500
Committer: shamrath <sh...@gmail.com>
Committed: Wed Feb 18 08:37:30 2015 -0500
----------------------------------------------------------------------
.../client/samples/CreateLaunchExperiment.java | 68 +++---
.../client/samples/RegisterSampleData.java | 2 +-
.../tools/RegisterSampleApplications.java | 13 +-
.../common/utils/ApplicationSettings.java | 16 ++
.../apache/airavata/common/utils/Constants.java | 2 +
.../main/resources/airavata-server.properties | 5 +-
.../credential/store/client/TestSSLClient.java | 140 ++++++++++++
.../store/server/CredentialStoreServer.java | 109 ++++++----
.../server/CredentialStoreServerHandler.java | 37 +++-
.../airavata/credential/store/util/Utility.java | 14 +-
.../src/main/resources/bin/airavata-server.sh | 2 +-
modules/messaging/client/README | 15 ++
modules/messaging/client/pom.xml | 103 +++++++++
.../messaging/client/RabbitMQListner.java | 215 +++++++++++++++++++
.../messaging/core/impl/RabbitMQPublisher.java | 12 +-
.../messaging/core/stats/StatCounter.java | 69 ++++++
.../messaging/core/stats/WriterTask.java | 39 ++++
modules/messaging/pom.xml | 1 +
.../org/apache/airavata/server/ServerMain.java | 4 +-
19 files changed, 754 insertions(+), 112 deletions(-)
----------------------------------------------------------------------
[13/50] [abbrv] airavata git commit: Fixed AIRAVATA-1571,
and refactored the code
Posted by sh...@apache.org.
Fixed AIRAVATA-1571, and refactored the code
Project: http://git-wip-us.apache.org/repos/asf/airavata/repo
Commit: http://git-wip-us.apache.org/repos/asf/airavata/commit/8835097e
Tree: http://git-wip-us.apache.org/repos/asf/airavata/tree/8835097e
Diff: http://git-wip-us.apache.org/repos/asf/airavata/diff/8835097e
Branch: refs/heads/master
Commit: 8835097ed697583601bde6039801a95dbdd33422
Parents: 55319c9
Author: shamrath <sh...@gmail.com>
Authored: Mon Feb 23 14:14:26 2015 -0500
Committer: shamrath <sh...@gmail.com>
Committed: Mon Feb 23 14:14:26 2015 -0500
----------------------------------------------------------------------
.../engine/SimpleWorkflowInterpreter.java | 50 +++++++++++---------
.../engine/dag/nodes/ApplicationNodeImpl.java | 28 ++++++-----
.../engine/dag/nodes/WorkflowInputNodeImpl.java | 13 ++---
.../workflow/engine/dag/nodes/WorkflowNode.java | 10 ++--
.../dag/nodes/WorkflowOutputNodeImpl.java | 15 +++---
.../engine/parser/AiravataDefaultParser.java | 14 +++---
6 files changed, 70 insertions(+), 60 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/airavata/blob/8835097e/modules/simple-workflow/src/main/java/org/apache/ariavata/simple/workflow/engine/SimpleWorkflowInterpreter.java
----------------------------------------------------------------------
diff --git a/modules/simple-workflow/src/main/java/org/apache/ariavata/simple/workflow/engine/SimpleWorkflowInterpreter.java b/modules/simple-workflow/src/main/java/org/apache/ariavata/simple/workflow/engine/SimpleWorkflowInterpreter.java
index 3c2596d..93b3bc0 100644
--- a/modules/simple-workflow/src/main/java/org/apache/ariavata/simple/workflow/engine/SimpleWorkflowInterpreter.java
+++ b/modules/simple-workflow/src/main/java/org/apache/ariavata/simple/workflow/engine/SimpleWorkflowInterpreter.java
@@ -102,9 +102,6 @@ public class SimpleWorkflowInterpreter implements Runnable{
setWorkflowInputNodes(workflowParser.parse());
log.debug("Parsed the workflow and got the workflow input nodes");
processWorkflowInputNodes(getWorkflowInputNodes());
-// processReadyList();
- // process workflow application nodes
- // process workflow output nodes
}
// try to remove synchronization tag
@@ -113,7 +110,8 @@ public class SimpleWorkflowInterpreter implements Runnable{
try {
if (readyNode instanceof WorkflowOutputNode) {
WorkflowOutputNode wfOutputNode = (WorkflowOutputNode) readyNode;
- completeWorkflowOutputs.add(wfOutputNode);
+ wfOutputNode.getOutputObject().setValue(wfOutputNode.getInPort().getInputObject().getValue());
+ addToCompleteOutputNodeList(wfOutputNode);
continue;
}
WorkflowNodeDetails workflowNodeDetails = createWorkflowNodeDetails(readyNode);
@@ -128,6 +126,7 @@ public class SimpleWorkflowInterpreter implements Runnable{
}
}
+
private void publishToProcessQueue(TaskDetails process) {
Thread thread = new Thread(new TempPublisher(process, eventBus));
thread.start();
@@ -140,13 +139,13 @@ public class SimpleWorkflowInterpreter implements Runnable{
if (workflowNode instanceof ApplicationNode) {
ApplicationNode applicationNode = (ApplicationNode) workflowNode;
List<InPort> inputPorts = applicationNode.getInputPorts();
- if (applicationNode.getNodeName().equals("Add")) {
+ if (applicationNode.getName().equals("Add")) {
applicationNode.getOutputPorts().get(0).getOutputObject().setValue(String.valueOf(
Integer.parseInt(inputPorts.get(0).getInputObject().getValue()) + Integer.parseInt(inputPorts.get(1).getInputObject().getValue())));
- } else if (applicationNode.getNodeName().equals("Multiply")) {
+ } else if (applicationNode.getName().equals("Multiply")) {
applicationNode.getOutputPorts().get(0).getOutputObject().setValue(String.valueOf(
Integer.parseInt(inputPorts.get(0).getInputObject().getValue()) * Integer.parseInt(inputPorts.get(1).getInputObject().getValue())));
- } else if (applicationNode.getNodeName().equals("Subtract")) {
+ } else if (applicationNode.getName().equals("Subtract")) {
applicationNode.getOutputPorts().get(0).getOutputObject().setValue(String.valueOf(
Integer.parseInt(inputPorts.get(0).getInputObject().getValue()) - Integer.parseInt(inputPorts.get(1).getInputObject().getValue())));
} else {
@@ -178,7 +177,7 @@ public class SimpleWorkflowInterpreter implements Runnable{
}
private WorkflowNodeDetails createWorkflowNodeDetails(WorkflowNode readyNode) throws RegistryException {
- WorkflowNodeDetails wfNodeDetails = ExperimentModelUtil.createWorkflowNode(readyNode.getNodeId(), null);
+ WorkflowNodeDetails wfNodeDetails = ExperimentModelUtil.createWorkflowNode(readyNode.getId(), null);
ExecutionUnit executionUnit = ExecutionUnit.APPLICATION;
String executionData = null;
if (readyNode instanceof ApplicationNode) {
@@ -218,15 +217,15 @@ public class SimpleWorkflowInterpreter implements Runnable{
Set<WorkflowNode> tempNodeSet = new HashSet<WorkflowNode>();
for (WorkflowInputNode wfInputNode : wfInputNodes) {
if (wfInputNode.isReady()) {
- log.debug("Workflow node : " + wfInputNode.getNodeId() + " is ready to execute");
+ log.debug("Workflow node : " + wfInputNode.getId() + " is ready to execute");
for (Edge edge : wfInputNode.getOutPort().getOutEdges()) {
edge.getToPort().getInputObject().setValue(wfInputNode.getInputObject().getValue());
if (edge.getToPort().getNode().isReady()) {
addToReadyQueue(edge.getToPort().getNode());
- log.debug("Added workflow node : " + edge.getToPort().getNode().getNodeId() + " to the readyQueue");
+ log.debug("Added workflow node : " + edge.getToPort().getNode().getId() + " to the readyQueue");
} else {
addToWaitingQueue(edge.getToPort().getNode());
- log.debug("Added workflow node " + edge.getToPort().getNode().getNodeId() + " to the waitingQueue");
+ log.debug("Added workflow node " + edge.getToPort().getNode().getId() + " to the waitingQueue");
}
}
@@ -311,25 +310,25 @@ public class SimpleWorkflowInterpreter implements Runnable{
case STARTED:
break;
case PRE_PROCESSING:
- processPack.getWorkflowNode().setNodeState(NodeState.PRE_PROCESSING);
+ processPack.getWorkflowNode().setState(NodeState.PRE_PROCESSING);
break;
case INPUT_DATA_STAGING:
- processPack.getWorkflowNode().setNodeState(NodeState.PRE_PROCESSING);
+ processPack.getWorkflowNode().setState(NodeState.PRE_PROCESSING);
break;
case EXECUTING:
- processPack.getWorkflowNode().setNodeState(NodeState.EXECUTING);
+ processPack.getWorkflowNode().setState(NodeState.EXECUTING);
break;
case OUTPUT_DATA_STAGING:
- processPack.getWorkflowNode().setNodeState(NodeState.POST_PROCESSING);
+ processPack.getWorkflowNode().setState(NodeState.POST_PROCESSING);
break;
case POST_PROCESSING:
- processPack.getWorkflowNode().setNodeState(NodeState.POST_PROCESSING);
+ processPack.getWorkflowNode().setState(NodeState.POST_PROCESSING);
break;
case COMPLETED:
- processPack.getWorkflowNode().setNodeState(NodeState.EXECUTED);
+ processPack.getWorkflowNode().setState(NodeState.EXECUTED);
break;
case FAILED:
- processPack.getWorkflowNode().setNodeState(NodeState.FAILED);
+ processPack.getWorkflowNode().setState(NodeState.FAILED);
break;
case UNKNOWN:
break;
@@ -337,7 +336,7 @@ public class SimpleWorkflowInterpreter implements Runnable{
break;
case CANCELED:
case CANCELING:
- processPack.getWorkflowNode().setNodeState(NodeState.FAILED);
+ processPack.getWorkflowNode().setState(NodeState.FAILED);
break;
default:
break;
@@ -358,12 +357,12 @@ public class SimpleWorkflowInterpreter implements Runnable{
* @param workflowNode - Workflow Node
*/
private synchronized void addToReadyQueue(WorkflowNode workflowNode) {
- waitingList.remove(workflowNode.getNodeId());
- readList.put(workflowNode.getNodeId(), workflowNode);
+ waitingList.remove(workflowNode.getId());
+ readList.put(workflowNode.getId(), workflowNode);
}
private void addToWaitingQueue(WorkflowNode workflowNode) {
- waitingList.put(workflowNode.getNodeId(), workflowNode);
+ waitingList.put(workflowNode.getId(), workflowNode);
}
/**
@@ -372,7 +371,7 @@ public class SimpleWorkflowInterpreter implements Runnable{
* @param processPack - has both workflow and correspond workflowNodeDetails and TaskDetails
*/
private synchronized void addToProcessingQueue(ProcessPack processPack) {
- readList.remove(processPack.getWorkflowNode().getNodeId());
+ readList.remove(processPack.getWorkflowNode().getId());
processingQueue.put(processPack.getTaskDetails().getTaskID(), processPack);
}
@@ -382,6 +381,11 @@ public class SimpleWorkflowInterpreter implements Runnable{
}
+ private void addToCompleteOutputNodeList(WorkflowOutputNode wfOutputNode) {
+ completeWorkflowOutputs.add(wfOutputNode);
+ readList.remove(wfOutputNode.getId());
+ }
+
@Override
public void run() {
// TODO: Auto generated method body.
http://git-wip-us.apache.org/repos/asf/airavata/blob/8835097e/modules/simple-workflow/src/main/java/org/apache/ariavata/simple/workflow/engine/dag/nodes/ApplicationNodeImpl.java
----------------------------------------------------------------------
diff --git a/modules/simple-workflow/src/main/java/org/apache/ariavata/simple/workflow/engine/dag/nodes/ApplicationNodeImpl.java b/modules/simple-workflow/src/main/java/org/apache/ariavata/simple/workflow/engine/dag/nodes/ApplicationNodeImpl.java
index dd4415a..1282dd0 100644
--- a/modules/simple-workflow/src/main/java/org/apache/ariavata/simple/workflow/engine/dag/nodes/ApplicationNodeImpl.java
+++ b/modules/simple-workflow/src/main/java/org/apache/ariavata/simple/workflow/engine/dag/nodes/ApplicationNodeImpl.java
@@ -34,40 +34,46 @@ public class ApplicationNodeImpl implements ApplicationNode {
private String applicationId;
private List<InPort> inPorts = new ArrayList<InPort>();
private List<OutPort> outPorts = new ArrayList<OutPort>();
+ private String applicationName;
- public ApplicationNodeImpl(String nodeId) {
- this(nodeId, null);
- }
+// public ApplicationNodeImpl(String nodeId) {
+// this(nodeId, null);
+// }
+//
+// public ApplicationNodeImpl(String nodeId, String applicationId) {
+// this(nodeId, null, applicationId);
+// }
- public ApplicationNodeImpl(String nodeId, String applicationId) {
+ public ApplicationNodeImpl(String nodeId, String applicationName, String applicationId) {
this.nodeId = nodeId;
+ this.applicationName = applicationName;
this.applicationId = applicationId;
}
@Override
- public String getNodeId() {
+ public String getId() {
return this.nodeId;
}
@Override
- public String getNodeName() {
- return this.getNodeName();
+ public String getName() {
+ return applicationName;
}
@Override
- public NodeType getNodeType() {
+ public NodeType getType() {
return NodeType.APPLICATION;
}
@Override
- public NodeState getNodeState() {
+ public NodeState getState() {
return myState;
}
@Override
- public void setNodeState(NodeState newNodeState) {
+ public void setState(NodeState newState) {
// TODO: node state can't be reversed , correct order WAITING --> READY --> EXECUTING --> EXECUTED --> COMPLETE
- myState = newNodeState;
+ myState = newState;
}
@Override
http://git-wip-us.apache.org/repos/asf/airavata/blob/8835097e/modules/simple-workflow/src/main/java/org/apache/ariavata/simple/workflow/engine/dag/nodes/WorkflowInputNodeImpl.java
----------------------------------------------------------------------
diff --git a/modules/simple-workflow/src/main/java/org/apache/ariavata/simple/workflow/engine/dag/nodes/WorkflowInputNodeImpl.java b/modules/simple-workflow/src/main/java/org/apache/ariavata/simple/workflow/engine/dag/nodes/WorkflowInputNodeImpl.java
index f419ae2..a015909 100644
--- a/modules/simple-workflow/src/main/java/org/apache/ariavata/simple/workflow/engine/dag/nodes/WorkflowInputNodeImpl.java
+++ b/modules/simple-workflow/src/main/java/org/apache/ariavata/simple/workflow/engine/dag/nodes/WorkflowInputNodeImpl.java
@@ -29,6 +29,7 @@ public class WorkflowInputNodeImpl implements WorkflowInputNode {
private String nodeName;
private OutPort outPort;
private InputDataObjectType inputDataObjectType;
+ private String name;
public WorkflowInputNodeImpl(String nodeId) {
this(nodeId, null);
@@ -40,29 +41,29 @@ public class WorkflowInputNodeImpl implements WorkflowInputNode {
}
@Override
- public String getNodeId() {
+ public String getId() {
return this.nodeId;
}
@Override
- public String getNodeName() {
+ public String getName() {
return this.nodeName;
}
@Override
- public NodeType getNodeType() {
+ public NodeType getType() {
return NodeType.WORKFLOW_INPUT;
}
@Override
- public NodeState getNodeState() {
+ public NodeState getState() {
return myState;
}
@Override
- public void setNodeState(NodeState newNodeState) {
+ public void setState(NodeState newState) {
// TODO: node state can't be reversed , correct order WAITING --> READY --> EXECUTING --> EXECUTED --> COMPLETE
- myState = newNodeState;
+ myState = newState;
}
@Override
http://git-wip-us.apache.org/repos/asf/airavata/blob/8835097e/modules/simple-workflow/src/main/java/org/apache/ariavata/simple/workflow/engine/dag/nodes/WorkflowNode.java
----------------------------------------------------------------------
diff --git a/modules/simple-workflow/src/main/java/org/apache/ariavata/simple/workflow/engine/dag/nodes/WorkflowNode.java b/modules/simple-workflow/src/main/java/org/apache/ariavata/simple/workflow/engine/dag/nodes/WorkflowNode.java
index f8b0e0c..f875674 100644
--- a/modules/simple-workflow/src/main/java/org/apache/ariavata/simple/workflow/engine/dag/nodes/WorkflowNode.java
+++ b/modules/simple-workflow/src/main/java/org/apache/ariavata/simple/workflow/engine/dag/nodes/WorkflowNode.java
@@ -23,15 +23,15 @@ package org.apache.ariavata.simple.workflow.engine.dag.nodes;
public interface WorkflowNode {
- public String getNodeId();
+ public String getId();
- public String getNodeName();
+ public String getName();
- public NodeType getNodeType();
+ public NodeType getType();
- public NodeState getNodeState();
+ public NodeState getState();
- public void setNodeState(NodeState newNodeState);
+ public void setState(NodeState newState);
public boolean isReady();
http://git-wip-us.apache.org/repos/asf/airavata/blob/8835097e/modules/simple-workflow/src/main/java/org/apache/ariavata/simple/workflow/engine/dag/nodes/WorkflowOutputNodeImpl.java
----------------------------------------------------------------------
diff --git a/modules/simple-workflow/src/main/java/org/apache/ariavata/simple/workflow/engine/dag/nodes/WorkflowOutputNodeImpl.java b/modules/simple-workflow/src/main/java/org/apache/ariavata/simple/workflow/engine/dag/nodes/WorkflowOutputNodeImpl.java
index aa7f0a3..a44c05f 100644
--- a/modules/simple-workflow/src/main/java/org/apache/ariavata/simple/workflow/engine/dag/nodes/WorkflowOutputNodeImpl.java
+++ b/modules/simple-workflow/src/main/java/org/apache/ariavata/simple/workflow/engine/dag/nodes/WorkflowOutputNodeImpl.java
@@ -42,34 +42,35 @@ public class WorkflowOutputNodeImpl implements WorkflowOutputNode {
}
@Override
- public String getNodeId() {
+ public String getId() {
return this.nodeId;
}
@Override
- public String getNodeName() {
+ public String getName() {
return this.nodeName;
}
@Override
- public NodeType getNodeType() {
+ public NodeType getType() {
return NodeType.WORKFLOW_OUTPUT;
}
@Override
- public NodeState getNodeState() {
+ public NodeState getState() {
return myState;
}
@Override
- public void setNodeState(NodeState newNodeState) {
+ public void setState(NodeState newState) {
// TODO: node state can't be reversed , correct order WAITING --> READY --> EXECUTING --> EXECUTED --> COMPLETE
- myState = newNodeState;
+ myState = newState;
}
@Override
public boolean isReady() {
- return this.outputDataObjectType.getValue() != null && !this.outputDataObjectType.getValue().equals("");
+ return !(inPort.getInputObject() == null || inPort.getInputObject().getValue() == null
+ || inPort.getInputObject().getValue().equals(""));
}
@Override
http://git-wip-us.apache.org/repos/asf/airavata/blob/8835097e/modules/simple-workflow/src/main/java/org/apache/ariavata/simple/workflow/engine/parser/AiravataDefaultParser.java
----------------------------------------------------------------------
diff --git a/modules/simple-workflow/src/main/java/org/apache/ariavata/simple/workflow/engine/parser/AiravataDefaultParser.java b/modules/simple-workflow/src/main/java/org/apache/ariavata/simple/workflow/engine/parser/AiravataDefaultParser.java
index e7ac5cb..2961fde 100644
--- a/modules/simple-workflow/src/main/java/org/apache/ariavata/simple/workflow/engine/parser/AiravataDefaultParser.java
+++ b/modules/simple-workflow/src/main/java/org/apache/ariavata/simple/workflow/engine/parser/AiravataDefaultParser.java
@@ -21,7 +21,6 @@
package org.apache.ariavata.simple.workflow.engine.parser;
-import com.sun.corba.se.pept.encoding.OutputObject;
import org.airavata.appcatalog.cpi.AppCatalogException;
import org.airavata.appcatalog.cpi.WorkflowCatalog;
import org.apache.aiaravata.application.catalog.data.impl.AppCatalogFactory;
@@ -104,7 +103,7 @@ public class AiravataDefaultParser implements WorkflowParser {
}
for (Node gNode : gNodes) {
wfInputNode = new WorkflowInputNodeImpl(gNode.getID(), gNode.getName());
- wfInputNode.setInputObject(inputDataMap.get(wfInputNode.getNodeName()));
+ wfInputNode.setInputObject(inputDataMap.get(wfInputNode.getName()));
if (wfInputNode.getInputObject() == null) {
// TODO: throw an error and exit.
}
@@ -120,7 +119,7 @@ public class AiravataDefaultParser implements WorkflowParser {
private void buildModel(List<PortContainer> portContainerList) {
// end condition of recursive call.
- if (portContainerList == null || portContainerList.size() == 0) {
+ if (portContainerList == null || portContainerList.isEmpty()) {
return ;
}
DataPort dataPort = null;
@@ -132,13 +131,12 @@ public class AiravataDefaultParser implements WorkflowParser {
dataPort = portContainer.getDataPort();
inPort = portContainer.getInPort();
Node node = dataPort.getNode();
-// inPort.setInputObject(getInputDataObject(dataPort));
if (node instanceof WSNode) {
WSNode wsNode = (WSNode) node;
WorkflowNode wfNode = wfNodes.get(wsNode.getID());
if (wfNode == null) {
wfApplicationNode = createApplicationNode(wsNode);
- wfNodes.put(wfApplicationNode.getNodeId(), wfApplicationNode);
+ wfNodes.put(wfApplicationNode.getId(), wfApplicationNode);
nextPortContainerList.addAll(processOutPorts(wsNode, wfApplicationNode));
} else if (wfNode instanceof ApplicationNode) {
wfApplicationNode = (ApplicationNode) wfNode;
@@ -152,7 +150,8 @@ public class AiravataDefaultParser implements WorkflowParser {
OutputNode oNode = (OutputNode) node;
wfOutputNode = createWorkflowOutputNode(oNode);
wfOutputNode.setInPort(inPort);
- wfNodes.put(wfOutputNode.getNodeId(), wfOutputNode);
+ inPort.setNode(wfOutputNode);
+ wfNodes.put(wfOutputNode.getId(), wfOutputNode);
}
}
buildModel(nextPortContainerList);
@@ -169,8 +168,8 @@ public class AiravataDefaultParser implements WorkflowParser {
private ApplicationNode createApplicationNode(WSNode wsNode) {
ApplicationNode applicationNode = new ApplicationNodeImpl(wsNode.getID(),
+ wsNode.getComponent().getApplication().getName(),
wsNode.getComponent().getApplication().getApplicationId());
-// wsNode.getComponent().getInputPorts()
return applicationNode;
}
@@ -197,7 +196,6 @@ public class AiravataDefaultParser implements WorkflowParser {
} else if (wfNode instanceof ApplicationNode) {
ApplicationNode applicationNode = ((ApplicationNode) wfNode);
applicationNode.addOutPort(outPort);
-// applicationNode.addInPort(inPort);
}
}
return portContainers;
[23/50] [abbrv] airavata git commit: Fixed AIRAVATA-1612,
Enable to plug different workflow parser implementation through
airavata-server.properties file.
Posted by sh...@apache.org.
Fixed AIRAVATA-1612, Enable to plug different workflow parser implementation through airavata-server.properties file.
Project: http://git-wip-us.apache.org/repos/asf/airavata/repo
Commit: http://git-wip-us.apache.org/repos/asf/airavata/commit/ad44956f
Tree: http://git-wip-us.apache.org/repos/asf/airavata/tree/ad44956f
Diff: http://git-wip-us.apache.org/repos/asf/airavata/diff/ad44956f
Branch: refs/heads/master
Commit: ad44956fc29a6e7328e93fc182d9c35fb7b8775b
Parents: 8b2a6b0
Author: shamrath <sh...@gmail.com>
Authored: Mon Mar 2 16:03:03 2015 -0500
Committer: shamrath <sh...@gmail.com>
Committed: Mon Mar 2 16:03:03 2015 -0500
----------------------------------------------------------------------
.../airavata/common/utils/ServerSettings.java | 5 ++++
.../main/resources/airavata-server.properties | 3 +++
.../main/resources/airavata-server.properties | 3 +++
.../engine/SimpleWorkflowInterpreter.java | 9 +++----
.../simple/workflow/engine/WorkflowFactory.java | 2 +-
.../workflow/engine/WorkflowFactoryImpl.java | 28 ++++++++++++++------
6 files changed, 36 insertions(+), 14 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/airavata/blob/ad44956f/modules/commons/utils/src/main/java/org/apache/airavata/common/utils/ServerSettings.java
----------------------------------------------------------------------
diff --git a/modules/commons/utils/src/main/java/org/apache/airavata/common/utils/ServerSettings.java b/modules/commons/utils/src/main/java/org/apache/airavata/common/utils/ServerSettings.java
index 5073949..1c338d4 100644
--- a/modules/commons/utils/src/main/java/org/apache/airavata/common/utils/ServerSettings.java
+++ b/modules/commons/utils/src/main/java/org/apache/airavata/common/utils/ServerSettings.java
@@ -64,6 +64,7 @@ public class ServerSettings extends ApplicationSettings {
// Workflow Enactment Service component configuration.
private static final String ENACTMENT_THREAD_POOL_SIZE = "enactment.thread.pool.size";
private static final int DEFAULT_ENACTMENT_THREAD_POOL_SIZE = 10;
+ private static final String WORKFLOW_PARSER = "workflow.parser";
private static boolean stopAllThreads = false;
@@ -202,4 +203,8 @@ public class ServerSettings extends ApplicationSettings {
}
return Integer.valueOf(threadPoolSize);
}
+
+ public static String getWorkflowParser() throws ApplicationSettingsException {
+ return getSetting(WORKFLOW_PARSER);
+ }
}
http://git-wip-us.apache.org/repos/asf/airavata/blob/ad44956f/modules/configuration/server/src/main/resources/airavata-server.properties
----------------------------------------------------------------------
diff --git a/modules/configuration/server/src/main/resources/airavata-server.properties b/modules/configuration/server/src/main/resources/airavata-server.properties
index 12566ec..475017b 100644
--- a/modules/configuration/server/src/main/resources/airavata-server.properties
+++ b/modules/configuration/server/src/main/resources/airavata-server.properties
@@ -162,6 +162,9 @@ gfac.passive=false
#workflowserver=org.apache.airavata.api.server.WorkflowServer
enactment.thread.pool.size=10
+#to define custom workflow parser user following property
+#workflow.parser=org.apache.airavata.simple.workflow.engine.parser.AiravataWorkflowParser
+
###########################################################################
# API Server module Configuration
http://git-wip-us.apache.org/repos/asf/airavata/blob/ad44956f/modules/credential-store-service/credential-store-webapp/src/main/resources/airavata-server.properties
----------------------------------------------------------------------
diff --git a/modules/credential-store-service/credential-store-webapp/src/main/resources/airavata-server.properties b/modules/credential-store-service/credential-store-webapp/src/main/resources/airavata-server.properties
index 3cd3cdb..7c72dd5 100644
--- a/modules/credential-store-service/credential-store-webapp/src/main/resources/airavata-server.properties
+++ b/modules/credential-store-service/credential-store-webapp/src/main/resources/airavata-server.properties
@@ -146,6 +146,9 @@ trusted.cert.location=/Users/lahirugunathilake/Downloads/certificates
#workflowserver=org.apache.airavata.api.server.WorkflowServer
enactment.thread.pool.size=10
+#to define custom workflow parser user following property
+#workflow.parser=org.apache.airavata.simple.workflow.engine.parser.AiravataWorkflowParser
+
###########################################################################
# API Server module Configuration
http://git-wip-us.apache.org/repos/asf/airavata/blob/ad44956f/modules/simple-workflow/src/main/java/org/apache/airavata/simple/workflow/engine/SimpleWorkflowInterpreter.java
----------------------------------------------------------------------
diff --git a/modules/simple-workflow/src/main/java/org/apache/airavata/simple/workflow/engine/SimpleWorkflowInterpreter.java b/modules/simple-workflow/src/main/java/org/apache/airavata/simple/workflow/engine/SimpleWorkflowInterpreter.java
index edfa306..8eb5d5e 100644
--- a/modules/simple-workflow/src/main/java/org/apache/airavata/simple/workflow/engine/SimpleWorkflowInterpreter.java
+++ b/modules/simple-workflow/src/main/java/org/apache/airavata/simple/workflow/engine/SimpleWorkflowInterpreter.java
@@ -104,13 +104,12 @@ public class SimpleWorkflowInterpreter implements Runnable{
public void launchWorkflow() throws Exception {
- // process workflow input nodes
-// WorkflowFactoryImpl wfFactory = WorkflowFactoryImpl.getInstance();
-// WorkflowParser workflowParser = wfFactory.getWorkflowParser(experiment.getExperimentID(), credentialToken);
- WorkflowParser workflowParser = new AiravataWorkflowParser(experiment, credentialToken);
+ WorkflowFactoryImpl wfFactory = WorkflowFactoryImpl.getInstance();
+ WorkflowParser workflowParser = wfFactory.getWorkflowParser(experiment.getExperimentID(), credentialToken);
log.debug("Initialized workflow parser");
setWorkflowInputNodes(workflowParser.parse());
log.debug("Parsed the workflow and got the workflow input nodes");
+ // process workflow input nodes
processWorkflowInputNodes(getWorkflowInputNodes());
@@ -295,7 +294,7 @@ public class SimpleWorkflowInterpreter implements Runnable{
statusConsumer.stopListen(consumerId);
log.info("Successfully un-bind status consumer for experiment " + getExperiment().getExperimentID());
} catch (Exception e) {
- //TODO - handle this.
+ log.error("Error launching workflow", e);
}
}
http://git-wip-us.apache.org/repos/asf/airavata/blob/ad44956f/modules/simple-workflow/src/main/java/org/apache/airavata/simple/workflow/engine/WorkflowFactory.java
----------------------------------------------------------------------
diff --git a/modules/simple-workflow/src/main/java/org/apache/airavata/simple/workflow/engine/WorkflowFactory.java b/modules/simple-workflow/src/main/java/org/apache/airavata/simple/workflow/engine/WorkflowFactory.java
index 3de90f2..9631768 100644
--- a/modules/simple-workflow/src/main/java/org/apache/airavata/simple/workflow/engine/WorkflowFactory.java
+++ b/modules/simple-workflow/src/main/java/org/apache/airavata/simple/workflow/engine/WorkflowFactory.java
@@ -26,6 +26,6 @@ package org.apache.airavata.simple.workflow.engine;
*/
public interface WorkflowFactory {
- public WorkflowParser getWorkflowParser(String experimentId, String credentialToken);
+ public WorkflowParser getWorkflowParser(String experimentId, String credentialToken) throws Exception;
}
http://git-wip-us.apache.org/repos/asf/airavata/blob/ad44956f/modules/simple-workflow/src/main/java/org/apache/airavata/simple/workflow/engine/WorkflowFactoryImpl.java
----------------------------------------------------------------------
diff --git a/modules/simple-workflow/src/main/java/org/apache/airavata/simple/workflow/engine/WorkflowFactoryImpl.java b/modules/simple-workflow/src/main/java/org/apache/airavata/simple/workflow/engine/WorkflowFactoryImpl.java
index e8674f2..23fc4c2 100644
--- a/modules/simple-workflow/src/main/java/org/apache/airavata/simple/workflow/engine/WorkflowFactoryImpl.java
+++ b/modules/simple-workflow/src/main/java/org/apache/airavata/simple/workflow/engine/WorkflowFactoryImpl.java
@@ -21,17 +21,24 @@
package org.apache.airavata.simple.workflow.engine;
+import org.apache.airavata.common.exception.ApplicationSettingsException;
+import org.apache.airavata.common.utils.ServerSettings;
import org.apache.airavata.registry.cpi.RegistryException;
import org.apache.airavata.simple.workflow.engine.parser.AiravataWorkflowParser;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.lang.reflect.Constructor;
+import java.lang.reflect.InvocationTargetException;
/**
* Singleton class, only one instance can exist in runtime.
*/
public class WorkflowFactoryImpl implements WorkflowFactory {
- private static WorkflowFactoryImpl workflowFactoryImpl;
+ private static final Logger log = LoggerFactory.getLogger(WorkflowFactoryImpl.class);
- private WorkflowParser workflowParser;
+ private static WorkflowFactoryImpl workflowFactoryImpl;
private WorkflowFactoryImpl(){
@@ -50,13 +57,18 @@ public class WorkflowFactoryImpl implements WorkflowFactory {
@Override
- public WorkflowParser getWorkflowParser(String experimentId, String credentialToken) {
+ public WorkflowParser getWorkflowParser(String experimentId, String credentialToken) throws Exception {
+ WorkflowParser workflowParser = null;
+ try {
+ String wfParserClassName = ServerSettings.getWorkflowParser();
+ Class<?> aClass = Class.forName(wfParserClassName);
+ Constructor<?> constructor = aClass.getConstructor(String.class, String.class);
+ workflowParser = (WorkflowParser) constructor.newInstance(experimentId, credentialToken);
+ } catch (ApplicationSettingsException e) {
+ log.info("A custom workflow parser is not defined, Use default Airavata workflow parser");
+ }
if (workflowParser == null) {
- try {
- workflowParser = new AiravataWorkflowParser(experimentId, credentialToken);
- } catch (RegistryException e) {
- // TODO : handle this scenario
- }
+ workflowParser = new AiravataWorkflowParser(experimentId, credentialToken);
}
return workflowParser;
}
[25/50] [abbrv] airavata git commit: Fixed AIRAVATA-1619. and removed
WorkflowUtil class.
Posted by sh...@apache.org.
Fixed AIRAVATA-1619. and removed WorkflowUtil class.
Project: http://git-wip-us.apache.org/repos/asf/airavata/repo
Commit: http://git-wip-us.apache.org/repos/asf/airavata/commit/71db390f
Tree: http://git-wip-us.apache.org/repos/asf/airavata/tree/71db390f
Diff: http://git-wip-us.apache.org/repos/asf/airavata/diff/71db390f
Branch: refs/heads/master
Commit: 71db390f49bd4a129ee08e6ae20e87edce0c7115
Parents: 366ada0
Author: shamrath <sh...@gmail.com>
Authored: Wed Mar 4 14:15:25 2015 -0500
Committer: shamrath <sh...@gmail.com>
Committed: Wed Mar 4 14:15:25 2015 -0500
----------------------------------------------------------------------
.../simple/workflow/engine/WorkflowUtil.java | 63 --------------------
.../engine/parser/AiravataWorkflowParser.java | 2 +-
2 files changed, 1 insertion(+), 64 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/airavata/blob/71db390f/modules/simple-workflow/src/main/java/org/apache/airavata/simple/workflow/engine/WorkflowUtil.java
----------------------------------------------------------------------
diff --git a/modules/simple-workflow/src/main/java/org/apache/airavata/simple/workflow/engine/WorkflowUtil.java b/modules/simple-workflow/src/main/java/org/apache/airavata/simple/workflow/engine/WorkflowUtil.java
deleted file mode 100644
index a2b69ae..0000000
--- a/modules/simple-workflow/src/main/java/org/apache/airavata/simple/workflow/engine/WorkflowUtil.java
+++ /dev/null
@@ -1,63 +0,0 @@
-/*
- *
- * 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.simple.workflow.engine;
-
-import com.google.common.eventbus.EventBus;
-import org.apache.airavata.model.appcatalog.appinterface.InputDataObjectType;
-import org.apache.airavata.model.appcatalog.appinterface.OutputDataObjectType;
-import org.apache.airavata.model.messaging.event.TaskIdentifier;
-import org.apache.airavata.model.messaging.event.TaskStatusChangeEvent;
-import org.apache.airavata.model.workspace.experiment.TaskDetails;
-import org.apache.airavata.model.workspace.experiment.TaskState;
-import org.apache.airavata.persistance.registry.jpa.model.TaskDetail;
-
-public class WorkflowUtil {
-
- public static InputDataObjectType copyValues(InputDataObjectType fromInputObj, InputDataObjectType toInputObj){
- if (toInputObj == null) {
- // TODO : throw an error
- }
- toInputObj.setValue(fromInputObj.getValue());
- if (fromInputObj.getApplicationArgument() != null
- && !fromInputObj.getApplicationArgument().trim().equals("")) {
- toInputObj.setApplicationArgument(fromInputObj.getApplicationArgument());
- }
- if (toInputObj.getType() == null) {
- toInputObj.setType(fromInputObj.getType());
- }
- return fromInputObj;
- }
-
- public static InputDataObjectType copyValues(OutputDataObjectType outputData, InputDataObjectType inputData) {
- inputData.setValue(outputData.getValue());
- return inputData;
- }
-
-
- public static OutputDataObjectType copyValues(InputDataObjectType inputObject, OutputDataObjectType outputObject) {
- if (outputObject == null) {
- outputObject = new OutputDataObjectType();
- }
- outputObject.setValue(inputObject.getValue());
- return outputObject;
- }
-}
http://git-wip-us.apache.org/repos/asf/airavata/blob/71db390f/modules/simple-workflow/src/main/java/org/apache/airavata/simple/workflow/engine/parser/AiravataWorkflowParser.java
----------------------------------------------------------------------
diff --git a/modules/simple-workflow/src/main/java/org/apache/airavata/simple/workflow/engine/parser/AiravataWorkflowParser.java b/modules/simple-workflow/src/main/java/org/apache/airavata/simple/workflow/engine/parser/AiravataWorkflowParser.java
index 673fbdc..a430879 100644
--- a/modules/simple-workflow/src/main/java/org/apache/airavata/simple/workflow/engine/parser/AiravataWorkflowParser.java
+++ b/modules/simple-workflow/src/main/java/org/apache/airavata/simple/workflow/engine/parser/AiravataWorkflowParser.java
@@ -101,7 +101,7 @@ public class AiravataWorkflowParser implements WorkflowParser {
}
for (Node gNode : gNodes) {
wfInputNode = new WorkflowInputNodeImpl(gNode.getID(), gNode.getName());
- wfInputNode.setInputObject(inputDataMap.get(wfInputNode.getName()));
+ wfInputNode.setInputObject(inputDataMap.get(wfInputNode.getId()));
if (wfInputNode.getInputObject() == null) {
// TODO: throw an error and exit.
}
[26/50] [abbrv] airavata git commit: Fixed AIRAVATA-1618,
and optimized the imports.
Posted by sh...@apache.org.
Fixed AIRAVATA-1618, and optimized the imports.
Project: http://git-wip-us.apache.org/repos/asf/airavata/repo
Commit: http://git-wip-us.apache.org/repos/asf/airavata/commit/917adad5
Tree: http://git-wip-us.apache.org/repos/asf/airavata/tree/917adad5
Diff: http://git-wip-us.apache.org/repos/asf/airavata/diff/917adad5
Branch: refs/heads/master
Commit: 917adad5bbec9500a0524eeb7a3ce3763c89d961
Parents: 71db390
Author: shamrath <sh...@gmail.com>
Authored: Wed Mar 4 14:21:08 2015 -0500
Committer: shamrath <sh...@gmail.com>
Committed: Wed Mar 4 14:21:08 2015 -0500
----------------------------------------------------------------------
.../engine/SimpleWorkflowInterpreter.java | 112 ++++++++++---------
.../workflow/engine/WorkflowFactoryImpl.java | 2 -
.../workflow/engine/dag/edge/DirectedEdge.java | 2 +-
.../engine/dag/nodes/ApplicationNodeImpl.java | 7 +-
.../workflow/engine/dag/nodes/NodeState.java | 28 +++--
.../engine/dag/nodes/WorkflowInputNodeImpl.java | 7 +-
.../dag/nodes/WorkflowOutputNodeImpl.java | 7 +-
.../engine/parser/AiravataWorkflowParser.java | 24 ++--
.../workflow/engine/parser/PortContainer.java | 2 +-
.../parser/AiravataWorkflowParserTest.java | 2 +-
10 files changed, 111 insertions(+), 82 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/airavata/blob/917adad5/modules/simple-workflow/src/main/java/org/apache/airavata/simple/workflow/engine/SimpleWorkflowInterpreter.java
----------------------------------------------------------------------
diff --git a/modules/simple-workflow/src/main/java/org/apache/airavata/simple/workflow/engine/SimpleWorkflowInterpreter.java b/modules/simple-workflow/src/main/java/org/apache/airavata/simple/workflow/engine/SimpleWorkflowInterpreter.java
index 8eb5d5e..a052e5c 100644
--- a/modules/simple-workflow/src/main/java/org/apache/airavata/simple/workflow/engine/SimpleWorkflowInterpreter.java
+++ b/modules/simple-workflow/src/main/java/org/apache/airavata/simple/workflow/engine/SimpleWorkflowInterpreter.java
@@ -55,7 +55,6 @@ import org.apache.airavata.simple.workflow.engine.dag.nodes.WorkflowNode;
import org.apache.airavata.simple.workflow.engine.dag.nodes.WorkflowOutputNode;
import org.apache.airavata.simple.workflow.engine.dag.port.InPort;
import org.apache.airavata.simple.workflow.engine.dag.port.OutPort;
-import org.apache.airavata.simple.workflow.engine.parser.AiravataWorkflowParser;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -78,7 +77,7 @@ public class SimpleWorkflowInterpreter implements Runnable{
private String gatewayName;
- private Map<String, WorkflowNode> readList = new ConcurrentHashMap<String, WorkflowNode>();
+ private Map<String, WorkflowNode> readyList = new ConcurrentHashMap<String, WorkflowNode>();
private Map<String, WorkflowNode> waitingList = new ConcurrentHashMap<String, WorkflowNode>();
private Map<String, ProcessContext> processingQueue = new ConcurrentHashMap<String, ProcessContext>();
private Map<String, ProcessContext> completeList = new HashMap<String, ProcessContext>();
@@ -87,6 +86,7 @@ public class SimpleWorkflowInterpreter implements Runnable{
private RabbitMQProcessPublisher publisher;
private RabbitMQStatusConsumer statusConsumer;
private String consumerId;
+ private boolean continueWorkflow = true;
public SimpleWorkflowInterpreter(String experimentId, String credentialToken, String gatewayName, RabbitMQProcessPublisher publisher) throws RegistryException {
this.gatewayName = gatewayName;
@@ -111,33 +111,27 @@ public class SimpleWorkflowInterpreter implements Runnable{
log.debug("Parsed the workflow and got the workflow input nodes");
// process workflow input nodes
processWorkflowInputNodes(getWorkflowInputNodes());
-
-
+ // initialize the rabbitmq status consumer
statusConsumer = new RabbitMQStatusConsumer();
consumerId = statusConsumer.listen(new TaskMessageHandler());
+
+ processReadyList();
}
// try to remove synchronization tag
- private synchronized void processReadyList() {
- for (WorkflowNode readyNode : readList.values()) {
- try {
- if (readyNode instanceof WorkflowOutputNode) {
- WorkflowOutputNode wfOutputNode = (WorkflowOutputNode) readyNode;
- wfOutputNode.getOutputObject().setValue(wfOutputNode.getInPort().getInputObject().getValue());
- addToCompleteOutputNodeList(wfOutputNode);
- continue;
- }
- WorkflowNodeDetails workflowNodeDetails = createWorkflowNodeDetails(readyNode);
- TaskDetails process = getProcess(workflowNodeDetails);
- ProcessContext processContext = new ProcessContext(readyNode, workflowNodeDetails, process);
- addToProcessingQueue(processContext);
- publishToProcessQueue(process);
-// publishToProcessQueue(processPack);
- } catch (RegistryException e) {
- // FIXME : handle this exception
- } catch (AiravataException e) {
- log.error("Error while publishing process to the process queue");
+ private synchronized void processReadyList() throws RegistryException, AiravataException {
+ for (WorkflowNode readyNode : readyList.values()) {
+ if (readyNode instanceof WorkflowOutputNode) {
+ WorkflowOutputNode wfOutputNode = (WorkflowOutputNode) readyNode;
+ wfOutputNode.getOutputObject().setValue(wfOutputNode.getInPort().getInputObject().getValue());
+ addToCompleteOutputNodeList(wfOutputNode);
+ continue;
}
+ WorkflowNodeDetails workflowNodeDetails = createWorkflowNodeDetails(readyNode);
+ TaskDetails process = getProcess(workflowNodeDetails);
+ ProcessContext processContext = new ProcessContext(readyNode, workflowNodeDetails, process);
+ addToProcessingQueue(processContext);
+ publishToProcessQueue(process);
}
}
@@ -149,11 +143,6 @@ public class SimpleWorkflowInterpreter implements Runnable{
MessageContext messageContext = new MessageContext(processSubmitEvent, MessageType.TASK, process.getTaskID(), null);
messageContext.setUpdatedTime(AiravataUtils.getCurrentTimestamp());
publisher.publish(messageContext);
-
-
-// Thread thread = new Thread(new TempPublisher(process, eventBus));
-// thread.start();
- //TODO: publish to process queue.
}
private TaskDetails getProcess(WorkflowNodeDetails wfNodeDetails) throws RegistryException {
@@ -171,6 +160,7 @@ public class SimpleWorkflowInterpreter implements Runnable{
if (readyNode instanceof ApplicationNode) {
executionUnit = ExecutionUnit.APPLICATION;
executionData = ((ApplicationNode) readyNode).getApplicationId();
+ setupNodeDetailsInput(((ApplicationNode) readyNode), wfNodeDetails);
} else if (readyNode instanceof WorkflowInputNode) {
executionUnit = ExecutionUnit.INPUT;
} else if (readyNode instanceof WorkflowOutputNode) {
@@ -178,25 +168,19 @@ public class SimpleWorkflowInterpreter implements Runnable{
}
wfNodeDetails.setExecutionUnit(executionUnit);
wfNodeDetails.setExecutionUnitData(executionData);
- setupNodeDetailsInput(readyNode, wfNodeDetails);
wfNodeDetails.setNodeInstanceId((String) getRegistry()
.add(ChildDataType.WORKFLOW_NODE_DETAIL, wfNodeDetails, getExperiment().getExperimentID()));
-// nodeInstanceList.put(node, wfNodeDetails);
return wfNodeDetails;
}
- private void setupNodeDetailsInput(WorkflowNode readyNode, WorkflowNodeDetails wfNodeDetails) {
- if (readyNode instanceof ApplicationNode) {
- ApplicationNode applicationNode = (ApplicationNode) readyNode;
- if (applicationNode.isReady()) {
- for (InPort inPort : applicationNode.getInputPorts()) {
- wfNodeDetails.addToNodeInputs(inPort.getInputObject());
- }
- } else {
- // TODO: handle this scenario properly.
+ private void setupNodeDetailsInput(ApplicationNode readyAppNode, WorkflowNodeDetails wfNodeDetails) {
+ if (readyAppNode.isReady()) {
+ for (InPort inPort : readyAppNode.getInputPorts()) {
+ wfNodeDetails.addToNodeInputs(inPort.getInputObject());
}
} else {
- // TODO: do we support for other type of workflow nodes ?
+ throw new IllegalArgumentException("Application node should be in ready state to set inputs to the " +
+ "workflow node details, nodeId = " + readyAppNode.getId());
}
}
@@ -253,7 +237,7 @@ public class SimpleWorkflowInterpreter implements Runnable{
*/
private synchronized void addToReadyQueue(WorkflowNode workflowNode) {
waitingList.remove(workflowNode.getId());
- readList.put(workflowNode.getId(), workflowNode);
+ readyList.put(workflowNode.getId(), workflowNode);
}
private void addToWaitingQueue(WorkflowNode workflowNode) {
@@ -266,7 +250,7 @@ public class SimpleWorkflowInterpreter implements Runnable{
* @param processContext - has both workflow and correspond workflowNodeDetails and TaskDetails
*/
private synchronized void addToProcessingQueue(ProcessContext processContext) {
- readList.remove(processContext.getWorkflowNode().getId());
+ readyList.remove(processContext.getWorkflowNode().getId());
processingQueue.put(processContext.getTaskDetails().getTaskID(), processContext);
}
@@ -278,7 +262,7 @@ public class SimpleWorkflowInterpreter implements Runnable{
private void addToCompleteOutputNodeList(WorkflowOutputNode wfOutputNode) {
completeWorkflowOutputs.add(wfOutputNode);
- readList.remove(wfOutputNode.getId());
+ readyList.remove(wfOutputNode.getId());
}
@Override
@@ -286,15 +270,25 @@ public class SimpleWorkflowInterpreter implements Runnable{
try {
log.debug("Launching workflow");
launchWorkflow();
- while (!(waitingList.isEmpty() && readList.isEmpty())) {
- processReadyList();
+ while (continueWorkflow && !(waitingList.isEmpty() && readyList.isEmpty())) {
+// processReadyList();
Thread.sleep(1000);
}
- log.info("Successfully launched workflow for experiment : " + getExperiment().getExperimentID());
- statusConsumer.stopListen(consumerId);
- log.info("Successfully un-bind status consumer for experiment " + getExperiment().getExperimentID());
+ if (continueWorkflow) {
+ log.info("Successfully launched workflow for experiment : " + getExperiment().getExperimentID());
+ } else if (!(waitingList.isEmpty() || readyList.isEmpty())) {
+ log.error("Workflow couldn't execute all workflow nodes due to an error");
+ }
} catch (Exception e) {
log.error("Error launching workflow", e);
+ } finally {
+ try {
+ statusConsumer.stopListen(consumerId);
+ log.info("Successfully un-bind status consumer for experiment " + getExperiment().getExperimentID());
+ } catch (AiravataException e) {
+ log.error("Error while un-binding status consumer: " + consumerId + " for experiment "
+ + getExperiment().getExperimentID());
+ }
}
}
@@ -369,6 +363,12 @@ public class SimpleWorkflowInterpreter implements Runnable{
}
addToCompleteQueue(processContext);
log.debug("removed task from processing queue : " + taskId);
+ try {
+ processReadyList();
+ } catch (Exception e) {
+ log.error("Error while processing ready workflow nodes", e);
+ continueWorkflow = false;
+ }
}
}
@@ -378,39 +378,49 @@ public class SimpleWorkflowInterpreter implements Runnable{
String taskId = taskIdentity.getTaskId();
ProcessContext processContext = processingQueue.get(taskId);
if (processContext != null) {
- WorkflowNodeState wfNodeState = WorkflowNodeState.UNKNOWN;
+ WorkflowNodeState wfNodeState = WorkflowNodeState.INVOKED;
switch (taskState) {
case WAITING:
break;
case STARTED:
break;
case PRE_PROCESSING:
+ wfNodeState = WorkflowNodeState.INVOKED;
processContext.getWorkflowNode().setState(NodeState.PRE_PROCESSING);
break;
case INPUT_DATA_STAGING:
+ wfNodeState = WorkflowNodeState.INVOKED;
processContext.getWorkflowNode().setState(NodeState.PRE_PROCESSING);
break;
case EXECUTING:
+ wfNodeState = WorkflowNodeState.EXECUTING;
processContext.getWorkflowNode().setState(NodeState.EXECUTING);
break;
case OUTPUT_DATA_STAGING:
+ wfNodeState = WorkflowNodeState.COMPLETED;
processContext.getWorkflowNode().setState(NodeState.POST_PROCESSING);
break;
case POST_PROCESSING:
+ wfNodeState = WorkflowNodeState.COMPLETED;
processContext.getWorkflowNode().setState(NodeState.POST_PROCESSING);
break;
case COMPLETED:
+ wfNodeState = WorkflowNodeState.COMPLETED;
processContext.getWorkflowNode().setState(NodeState.EXECUTED);
break;
case FAILED:
+ wfNodeState = WorkflowNodeState.FAILED;
processContext.getWorkflowNode().setState(NodeState.FAILED);
break;
case UNKNOWN:
+ wfNodeState = WorkflowNodeState.UNKNOWN;
break;
case CONFIGURING_WORKSPACE:
+ wfNodeState = WorkflowNodeState.COMPLETED;
break;
case CANCELED:
case CANCELING:
+ wfNodeState = WorkflowNodeState.CANCELED;
processContext.getWorkflowNode().setState(NodeState.FAILED);
break;
default:
@@ -420,7 +430,9 @@ public class SimpleWorkflowInterpreter implements Runnable{
try {
updateWorkflowNodeStatus(processContext.getWfNodeDetails(), wfNodeState);
} catch (RegistryException e) {
- // TODO: handle this.
+ log.error("Error while updating workflow node status update to the registry. nodeInstanceId :"
+ + processContext.getWfNodeDetails().getNodeInstanceId() + " status to: "
+ + processContext.getWfNodeDetails().getWorkflowNodeStatus().toString() , e);
}
}
}
http://git-wip-us.apache.org/repos/asf/airavata/blob/917adad5/modules/simple-workflow/src/main/java/org/apache/airavata/simple/workflow/engine/WorkflowFactoryImpl.java
----------------------------------------------------------------------
diff --git a/modules/simple-workflow/src/main/java/org/apache/airavata/simple/workflow/engine/WorkflowFactoryImpl.java b/modules/simple-workflow/src/main/java/org/apache/airavata/simple/workflow/engine/WorkflowFactoryImpl.java
index 23fc4c2..e70f062 100644
--- a/modules/simple-workflow/src/main/java/org/apache/airavata/simple/workflow/engine/WorkflowFactoryImpl.java
+++ b/modules/simple-workflow/src/main/java/org/apache/airavata/simple/workflow/engine/WorkflowFactoryImpl.java
@@ -23,13 +23,11 @@ package org.apache.airavata.simple.workflow.engine;
import org.apache.airavata.common.exception.ApplicationSettingsException;
import org.apache.airavata.common.utils.ServerSettings;
-import org.apache.airavata.registry.cpi.RegistryException;
import org.apache.airavata.simple.workflow.engine.parser.AiravataWorkflowParser;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.lang.reflect.Constructor;
-import java.lang.reflect.InvocationTargetException;
/**
* Singleton class, only one instance can exist in runtime.
http://git-wip-us.apache.org/repos/asf/airavata/blob/917adad5/modules/simple-workflow/src/main/java/org/apache/airavata/simple/workflow/engine/dag/edge/DirectedEdge.java
----------------------------------------------------------------------
diff --git a/modules/simple-workflow/src/main/java/org/apache/airavata/simple/workflow/engine/dag/edge/DirectedEdge.java b/modules/simple-workflow/src/main/java/org/apache/airavata/simple/workflow/engine/dag/edge/DirectedEdge.java
index 3bc380d..ae7498a 100644
--- a/modules/simple-workflow/src/main/java/org/apache/airavata/simple/workflow/engine/dag/edge/DirectedEdge.java
+++ b/modules/simple-workflow/src/main/java/org/apache/airavata/simple/workflow/engine/dag/edge/DirectedEdge.java
@@ -21,8 +21,8 @@
package org.apache.airavata.simple.workflow.engine.dag.edge;
-import org.apache.airavata.simple.workflow.engine.dag.port.OutPort;
import org.apache.airavata.simple.workflow.engine.dag.port.InPort;
+import org.apache.airavata.simple.workflow.engine.dag.port.OutPort;
public class DirectedEdge implements Edge {
http://git-wip-us.apache.org/repos/asf/airavata/blob/917adad5/modules/simple-workflow/src/main/java/org/apache/airavata/simple/workflow/engine/dag/nodes/ApplicationNodeImpl.java
----------------------------------------------------------------------
diff --git a/modules/simple-workflow/src/main/java/org/apache/airavata/simple/workflow/engine/dag/nodes/ApplicationNodeImpl.java b/modules/simple-workflow/src/main/java/org/apache/airavata/simple/workflow/engine/dag/nodes/ApplicationNodeImpl.java
index 52b0595..1233a9d 100644
--- a/modules/simple-workflow/src/main/java/org/apache/airavata/simple/workflow/engine/dag/nodes/ApplicationNodeImpl.java
+++ b/modules/simple-workflow/src/main/java/org/apache/airavata/simple/workflow/engine/dag/nodes/ApplicationNodeImpl.java
@@ -72,8 +72,11 @@ public class ApplicationNodeImpl implements ApplicationNode {
@Override
public void setState(NodeState newState) {
- // TODO: node state can't be reversed , correct order WAITING --> READY --> EXECUTING --> EXECUTED --> COMPLETE
- myState = newState;
+ if (newState.getLevel() > myState.getLevel()) {
+ myState = newState;
+ } else {
+ throw new IllegalStateException("Node state can't be reversed. currentState : " + myState.toString() + " , newState " + newState.toString());
+ }
}
@Override
http://git-wip-us.apache.org/repos/asf/airavata/blob/917adad5/modules/simple-workflow/src/main/java/org/apache/airavata/simple/workflow/engine/dag/nodes/NodeState.java
----------------------------------------------------------------------
diff --git a/modules/simple-workflow/src/main/java/org/apache/airavata/simple/workflow/engine/dag/nodes/NodeState.java b/modules/simple-workflow/src/main/java/org/apache/airavata/simple/workflow/engine/dag/nodes/NodeState.java
index 333fcb2..edbeec5 100644
--- a/modules/simple-workflow/src/main/java/org/apache/airavata/simple/workflow/engine/dag/nodes/NodeState.java
+++ b/modules/simple-workflow/src/main/java/org/apache/airavata/simple/workflow/engine/dag/nodes/NodeState.java
@@ -22,13 +22,23 @@
package org.apache.airavata.simple.workflow.engine.dag.nodes;
public enum NodeState {
- WAITING, // waiting on inputs
- READY, // all inputs are available and ready to execute
- QUEUED, //
- PRE_PROCESSING, //
- EXECUTING, // task has been submitted , not yet finish
- EXECUTED, // task executed
- POST_PROCESSING, //
- FAILED,
- COMPLETE // all works done
+ WAITING(0), // waiting on inputs
+ READY(1), // all inputs are available and ready to execute
+ QUEUED(2), //
+ PRE_PROCESSING(3), //
+ EXECUTING(4), // task has been submitted , not yet finish
+ EXECUTED(5), // task executed
+ POST_PROCESSING(6), //
+ FAILED(7),
+ COMPLETE(8); // all works done
+
+ private int level;
+
+ NodeState(int level) {
+ this.level = level;
+ }
+
+ public int getLevel() {
+ return level;
+ }
}
http://git-wip-us.apache.org/repos/asf/airavata/blob/917adad5/modules/simple-workflow/src/main/java/org/apache/airavata/simple/workflow/engine/dag/nodes/WorkflowInputNodeImpl.java
----------------------------------------------------------------------
diff --git a/modules/simple-workflow/src/main/java/org/apache/airavata/simple/workflow/engine/dag/nodes/WorkflowInputNodeImpl.java b/modules/simple-workflow/src/main/java/org/apache/airavata/simple/workflow/engine/dag/nodes/WorkflowInputNodeImpl.java
index b3dfa62..7ba8908 100644
--- a/modules/simple-workflow/src/main/java/org/apache/airavata/simple/workflow/engine/dag/nodes/WorkflowInputNodeImpl.java
+++ b/modules/simple-workflow/src/main/java/org/apache/airavata/simple/workflow/engine/dag/nodes/WorkflowInputNodeImpl.java
@@ -62,8 +62,11 @@ public class WorkflowInputNodeImpl implements WorkflowInputNode {
@Override
public void setState(NodeState newState) {
- // TODO: node state can't be reversed , correct order WAITING --> READY --> EXECUTING --> EXECUTED --> COMPLETE
- myState = newState;
+ if (newState.getLevel() > myState.getLevel()) {
+ myState = newState;
+ } else {
+ throw new IllegalStateException("Node state can't be reversed. currentState : " + myState.toString() + " , newState " + newState.toString());
+ }
}
@Override
http://git-wip-us.apache.org/repos/asf/airavata/blob/917adad5/modules/simple-workflow/src/main/java/org/apache/airavata/simple/workflow/engine/dag/nodes/WorkflowOutputNodeImpl.java
----------------------------------------------------------------------
diff --git a/modules/simple-workflow/src/main/java/org/apache/airavata/simple/workflow/engine/dag/nodes/WorkflowOutputNodeImpl.java b/modules/simple-workflow/src/main/java/org/apache/airavata/simple/workflow/engine/dag/nodes/WorkflowOutputNodeImpl.java
index 5924212..6c80517 100644
--- a/modules/simple-workflow/src/main/java/org/apache/airavata/simple/workflow/engine/dag/nodes/WorkflowOutputNodeImpl.java
+++ b/modules/simple-workflow/src/main/java/org/apache/airavata/simple/workflow/engine/dag/nodes/WorkflowOutputNodeImpl.java
@@ -63,8 +63,11 @@ public class WorkflowOutputNodeImpl implements WorkflowOutputNode {
@Override
public void setState(NodeState newState) {
- // TODO: node state can't be reversed , correct order WAITING --> READY --> EXECUTING --> EXECUTED --> COMPLETE
- myState = newState;
+ if (newState.getLevel() > myState.getLevel()) {
+ myState = newState;
+ } else {
+ throw new IllegalStateException("Node state can't be reversed. currentState : " + myState.toString() + " , newState " + newState.toString());
+ }
}
@Override
http://git-wip-us.apache.org/repos/asf/airavata/blob/917adad5/modules/simple-workflow/src/main/java/org/apache/airavata/simple/workflow/engine/parser/AiravataWorkflowParser.java
----------------------------------------------------------------------
diff --git a/modules/simple-workflow/src/main/java/org/apache/airavata/simple/workflow/engine/parser/AiravataWorkflowParser.java b/modules/simple-workflow/src/main/java/org/apache/airavata/simple/workflow/engine/parser/AiravataWorkflowParser.java
index a430879..f7d53be 100644
--- a/modules/simple-workflow/src/main/java/org/apache/airavata/simple/workflow/engine/parser/AiravataWorkflowParser.java
+++ b/modules/simple-workflow/src/main/java/org/apache/airavata/simple/workflow/engine/parser/AiravataWorkflowParser.java
@@ -31,9 +31,19 @@ import org.apache.airavata.persistance.registry.jpa.impl.RegistryFactory;
import org.apache.airavata.registry.cpi.Registry;
import org.apache.airavata.registry.cpi.RegistryException;
import org.apache.airavata.registry.cpi.RegistryModelType;
+import org.apache.airavata.simple.workflow.engine.WorkflowParser;
+import org.apache.airavata.simple.workflow.engine.dag.edge.DirectedEdge;
+import org.apache.airavata.simple.workflow.engine.dag.edge.Edge;
+import org.apache.airavata.simple.workflow.engine.dag.nodes.ApplicationNode;
import org.apache.airavata.simple.workflow.engine.dag.nodes.ApplicationNodeImpl;
import org.apache.airavata.simple.workflow.engine.dag.nodes.WorkflowInputNode;
import org.apache.airavata.simple.workflow.engine.dag.nodes.WorkflowInputNodeImpl;
+import org.apache.airavata.simple.workflow.engine.dag.nodes.WorkflowNode;
+import org.apache.airavata.simple.workflow.engine.dag.nodes.WorkflowOutputNode;
+import org.apache.airavata.simple.workflow.engine.dag.nodes.WorkflowOutputNodeImpl;
+import org.apache.airavata.simple.workflow.engine.dag.port.InPort;
+import org.apache.airavata.simple.workflow.engine.dag.port.InputPortIml;
+import org.apache.airavata.simple.workflow.engine.dag.port.OutPort;
import org.apache.airavata.simple.workflow.engine.dag.port.OutPortImpl;
import org.apache.airavata.workflow.model.component.ComponentException;
import org.apache.airavata.workflow.model.component.system.ConstantComponent;
@@ -49,16 +59,6 @@ import org.apache.airavata.workflow.model.graph.system.SystemDataPort;
import org.apache.airavata.workflow.model.graph.ws.WSNode;
import org.apache.airavata.workflow.model.graph.ws.WSPort;
import org.apache.airavata.workflow.model.wf.Workflow;
-import org.apache.airavata.simple.workflow.engine.WorkflowParser;
-import org.apache.airavata.simple.workflow.engine.dag.edge.DirectedEdge;
-import org.apache.airavata.simple.workflow.engine.dag.edge.Edge;
-import org.apache.airavata.simple.workflow.engine.dag.nodes.ApplicationNode;
-import org.apache.airavata.simple.workflow.engine.dag.nodes.WorkflowNode;
-import org.apache.airavata.simple.workflow.engine.dag.nodes.WorkflowOutputNode;
-import org.apache.airavata.simple.workflow.engine.dag.nodes.WorkflowOutputNodeImpl;
-import org.apache.airavata.simple.workflow.engine.dag.port.InPort;
-import org.apache.airavata.simple.workflow.engine.dag.port.InputPortIml;
-import org.apache.airavata.simple.workflow.engine.dag.port.OutPort;
import java.util.ArrayList;
import java.util.HashMap;
@@ -103,7 +103,7 @@ public class AiravataWorkflowParser implements WorkflowParser {
wfInputNode = new WorkflowInputNodeImpl(gNode.getID(), gNode.getName());
wfInputNode.setInputObject(inputDataMap.get(wfInputNode.getId()));
if (wfInputNode.getInputObject() == null) {
- // TODO: throw an error and exit.
+ throw new RuntimeException("Workflow Input object is not set, workflow node id: " + wfInputNode.getId());
}
portContainers.addAll(processOutPorts(gNode, wfInputNode));
wfInputNodes.add(wfInputNode);
@@ -139,7 +139,7 @@ public class AiravataWorkflowParser implements WorkflowParser {
} else if (wfNode instanceof ApplicationNode) {
wfApplicationNode = (ApplicationNode) wfNode;
} else {
- // TODO : handle this scenario
+ throw new IllegalArgumentException("Only support for ApplicationNode implementation, but found other type for node implementation");
}
inPort.setNode(wfApplicationNode);
wfApplicationNode.addInPort(inPort);
http://git-wip-us.apache.org/repos/asf/airavata/blob/917adad5/modules/simple-workflow/src/main/java/org/apache/airavata/simple/workflow/engine/parser/PortContainer.java
----------------------------------------------------------------------
diff --git a/modules/simple-workflow/src/main/java/org/apache/airavata/simple/workflow/engine/parser/PortContainer.java b/modules/simple-workflow/src/main/java/org/apache/airavata/simple/workflow/engine/parser/PortContainer.java
index db3dda5..4ddb8b9 100644
--- a/modules/simple-workflow/src/main/java/org/apache/airavata/simple/workflow/engine/parser/PortContainer.java
+++ b/modules/simple-workflow/src/main/java/org/apache/airavata/simple/workflow/engine/parser/PortContainer.java
@@ -21,8 +21,8 @@
package org.apache.airavata.simple.workflow.engine.parser;
-import org.apache.airavata.workflow.model.graph.DataPort;
import org.apache.airavata.simple.workflow.engine.dag.port.InPort;
+import org.apache.airavata.workflow.model.graph.DataPort;
public class PortContainer {
http://git-wip-us.apache.org/repos/asf/airavata/blob/917adad5/modules/simple-workflow/src/test/java/org/apache/airavata/simple/workflow/engine/parser/AiravataWorkflowParserTest.java
----------------------------------------------------------------------
diff --git a/modules/simple-workflow/src/test/java/org/apache/airavata/simple/workflow/engine/parser/AiravataWorkflowParserTest.java b/modules/simple-workflow/src/test/java/org/apache/airavata/simple/workflow/engine/parser/AiravataWorkflowParserTest.java
index 6443806..d843abe 100644
--- a/modules/simple-workflow/src/test/java/org/apache/airavata/simple/workflow/engine/parser/AiravataWorkflowParserTest.java
+++ b/modules/simple-workflow/src/test/java/org/apache/airavata/simple/workflow/engine/parser/AiravataWorkflowParserTest.java
@@ -26,9 +26,9 @@ import org.apache.airavata.model.appcatalog.appinterface.InputDataObjectType;
import org.apache.airavata.model.workspace.experiment.Experiment;
import org.apache.airavata.simple.workflow.engine.dag.nodes.ApplicationNode;
import org.apache.airavata.simple.workflow.engine.dag.nodes.WorkflowInputNode;
+import org.apache.airavata.simple.workflow.engine.dag.nodes.WorkflowNode;
import org.apache.airavata.simple.workflow.engine.dag.nodes.WorkflowOutputNode;
import org.apache.airavata.workflow.model.wf.Workflow;
-import org.apache.airavata.simple.workflow.engine.dag.nodes.WorkflowNode;
import org.junit.After;
import org.junit.Assert;
import org.junit.Before;
[19/50] [abbrv] airavata git commit: Refactor renamed
RabbitMQListener class and fixed rename issue with RabbitMQStatusConsumer
class
Posted by sh...@apache.org.
Refactor renamed RabbitMQListener class and fixed rename issue with RabbitMQStatusConsumer class
Project: http://git-wip-us.apache.org/repos/asf/airavata/repo
Commit: http://git-wip-us.apache.org/repos/asf/airavata/commit/97ff3b7d
Tree: http://git-wip-us.apache.org/repos/asf/airavata/tree/97ff3b7d
Diff: http://git-wip-us.apache.org/repos/asf/airavata/diff/97ff3b7d
Branch: refs/heads/master
Commit: 97ff3b7d12ce1e6ac42e8a3d22c2bfc1de9b30a1
Parents: 249b440
Author: shamrath <sh...@gmail.com>
Authored: Tue Feb 24 11:20:07 2015 -0500
Committer: shamrath <sh...@gmail.com>
Committed: Tue Feb 24 11:20:07 2015 -0500
----------------------------------------------------------------------
modules/messaging/client/pom.xml | 2 +-
.../messaging/client/RabbitMQListener.java | 215 +++++++++++++++++++
.../messaging/client/RabbitMQListner.java | 215 -------------------
3 files changed, 216 insertions(+), 216 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/airavata/blob/97ff3b7d/modules/messaging/client/pom.xml
----------------------------------------------------------------------
diff --git a/modules/messaging/client/pom.xml b/modules/messaging/client/pom.xml
index 762bd10..5db9d4d 100644
--- a/modules/messaging/client/pom.xml
+++ b/modules/messaging/client/pom.xml
@@ -80,7 +80,7 @@
<configuration>
<archive>
<manifest>
- <mainClass>org.apache.airavata.messaging.client.RabbitMQListner</mainClass>
+ <mainClass>org.apache.airavata.messaging.client.RabbitMQListener</mainClass>
</manifest>
</archive>
<descriptorRefs>
http://git-wip-us.apache.org/repos/asf/airavata/blob/97ff3b7d/modules/messaging/client/src/main/java/org/apache/airavata/messaging/client/RabbitMQListener.java
----------------------------------------------------------------------
diff --git a/modules/messaging/client/src/main/java/org/apache/airavata/messaging/client/RabbitMQListener.java b/modules/messaging/client/src/main/java/org/apache/airavata/messaging/client/RabbitMQListener.java
new file mode 100644
index 0000000..c1bdc3d
--- /dev/null
+++ b/modules/messaging/client/src/main/java/org/apache/airavata/messaging/client/RabbitMQListener.java
@@ -0,0 +1,215 @@
+/*
+ *
+ * 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.messaging.client;
+
+import org.apache.airavata.common.exception.ApplicationSettingsException;
+import org.apache.airavata.common.utils.AiravataUtils;
+import org.apache.airavata.common.utils.ServerSettings;
+import org.apache.airavata.common.utils.ThriftUtils;
+import org.apache.airavata.messaging.core.MessageContext;
+import org.apache.airavata.messaging.core.MessageHandler;
+import org.apache.airavata.messaging.core.MessagingConstants;
+import org.apache.airavata.messaging.core.impl.RabbitMQStatusConsumer;
+import org.apache.airavata.model.messaging.event.*;
+import org.apache.commons.cli.*;
+import org.apache.thrift.TBase;
+import org.apache.thrift.TException;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+
+public class RabbitMQListener {
+ public static final String RABBITMQ_BROKER_URL = "rabbitmq.broker.url";
+ public static final String RABBITMQ_EXCHANGE_NAME = "rabbitmq.exchange.name";
+ private final static Logger logger = LoggerFactory.getLogger(RabbitMQListener.class);
+ private static String gatewayId = "*";
+ private static boolean gatewayLevelMessages = false;
+ private static boolean experimentLevelMessages = false;
+ private static boolean jobLevelMessages = false;
+ private static String experimentId = "*";
+ private static String jobId = "*";
+ private static boolean allMessages = false;
+
+ public static void main(String[] args) {
+ parseArguments(args);
+ try {
+ AiravataUtils.setExecutionAsServer();
+ String brokerUrl = ServerSettings.getSetting(RABBITMQ_BROKER_URL);
+ final String exchangeName = ServerSettings.getSetting(RABBITMQ_EXCHANGE_NAME);
+ RabbitMQStatusConsumer consumer = new RabbitMQStatusConsumer(brokerUrl, exchangeName);
+ consumer.listen(new MessageHandler() {
+ @Override
+ public Map<String, Object> getProperties() {
+ Map<String, Object> props = new HashMap<String, Object>();
+ List<String> routingKeys = new ArrayList<String>();
+ if (allMessages){
+ routingKeys.add("*");
+ routingKeys.add("*.*");
+ routingKeys.add("*.*.*");
+ routingKeys.add("*.*.*.*");
+ routingKeys.add("*.*.*.*.*");
+ }else {
+ if (gatewayLevelMessages){
+ routingKeys.add(gatewayId);
+ routingKeys.add(gatewayId + ".*");
+ routingKeys.add(gatewayId + ".*.*");
+ routingKeys.add(gatewayId + ".*.*.*");
+ routingKeys.add(gatewayId + ".*.*.*.*");
+ }else if (experimentLevelMessages){
+ routingKeys.add(gatewayId);
+ routingKeys.add(gatewayId + "." + experimentId);
+ routingKeys.add(gatewayId + "." + experimentId+ ".*");
+ routingKeys.add(gatewayId + "." + experimentId+ ".*.*");
+ routingKeys.add(gatewayId + "." + experimentId+ ".*.*.*");
+ }else if (jobLevelMessages){
+ routingKeys.add(gatewayId);
+ routingKeys.add(gatewayId + "." + experimentId);
+ routingKeys.add(gatewayId + "." + experimentId+ ".*");
+ routingKeys.add(gatewayId + "." + experimentId+ ".*.*");
+ routingKeys.add(gatewayId + "." + experimentId+ ".*." + jobId);
+ }
+ }
+ props.put(MessagingConstants.RABBIT_ROUTING_KEY, routingKeys);
+ return props;
+ }
+
+ @Override
+ public void onMessage(MessageContext message) {
+ if (message.getType().equals(MessageType.EXPERIMENT)){
+ try {
+ ExperimentStatusChangeEvent event = new ExperimentStatusChangeEvent();
+ TBase messageEvent = message.getEvent();
+ byte[] bytes = ThriftUtils.serializeThriftObject(messageEvent);
+ ThriftUtils.createThriftFromBytes(bytes, event);
+ System.out.println(" Message Received with message id '" + message.getMessageId()
+ + "' and with message type '" + message.getType() + "' and with state : '" + event.getState().toString() +
+ " for Gateway " + event.getGatewayId());
+ } catch (TException e) {
+ logger.error(e.getMessage(), e);
+ }
+ }else if (message.getType().equals(MessageType.WORKFLOWNODE)){
+ try {
+ WorkflowNodeStatusChangeEvent event = new WorkflowNodeStatusChangeEvent();
+ TBase messageEvent = message.getEvent();
+ byte[] bytes = ThriftUtils.serializeThriftObject(messageEvent);
+ ThriftUtils.createThriftFromBytes(bytes, event);
+ System.out.println(" Message Received with message id '" + message.getMessageId()
+ + "' and with message type '" + message.getType() + "' and with state : '" + event.getState().toString() +
+ " for Gateway " + event.getWorkflowNodeIdentity().getGatewayId());
+ } catch (TException e) {
+ logger.error(e.getMessage(), e);
+ }
+ }else if (message.getType().equals(MessageType.TASK)){
+ try {
+ TaskStatusChangeEvent event = new TaskStatusChangeEvent();
+ TBase messageEvent = message.getEvent();
+ byte[] bytes = ThriftUtils.serializeThriftObject(messageEvent);
+ ThriftUtils.createThriftFromBytes(bytes, event);
+ System.out.println(" Message Received with message id '" + message.getMessageId()
+ + "' and with message type '" + message.getType() + "' and with state : '" + event.getState().toString() +
+ " for Gateway " + event.getTaskIdentity().getGatewayId());
+ } catch (TException e) {
+ logger.error(e.getMessage(), e);
+ }
+ }else if (message.getType().equals(MessageType.JOB)){
+ try {
+ JobStatusChangeEvent event = new JobStatusChangeEvent();
+ TBase messageEvent = message.getEvent();
+ byte[] bytes = ThriftUtils.serializeThriftObject(messageEvent);
+ ThriftUtils.createThriftFromBytes(bytes, event);
+ System.out.println(" Message Received with message id '" + message.getMessageId()
+ + "' and with message type '" + message.getType() + "' and with state : '" + event.getState().toString() +
+ " for Gateway " + event.getJobIdentity().getGatewayId());
+ } catch (TException e) {
+ logger.error(e.getMessage(), e);
+ }
+ }
+ }
+ });
+ } catch (ApplicationSettingsException e) {
+ logger.error("Error reading airavata server properties", e);
+ }catch (Exception e) {
+ logger.error(e.getMessage(), e);
+ }
+
+ }
+
+ public static void parseArguments(String[] args) {
+ try{
+ Options options = new Options();
+
+ options.addOption("gId", true , "Gateway ID");
+ options.addOption("eId", true, "Experiment ID");
+ options.addOption("jId", true, "Job ID");
+ options.addOption("a", false, "All Notifications");
+
+ CommandLineParser parser = new PosixParser();
+ CommandLine cmd = parser.parse( options, args);
+ if (cmd.getOptions() == null || cmd.getOptions().length == 0){
+ logger.info("You have not specified any options. We assume you need to listen to all the messages...");
+ allMessages = true;
+ gatewayId = "*";
+ }
+ if (cmd.hasOption("a")){
+ logger.info("Listening to all the messages...");
+ allMessages = true;
+ gatewayId = "*";
+ }else {
+ gatewayId = cmd.getOptionValue("gId");
+ if (gatewayId == null){
+ gatewayId = "*";
+ logger.info("You have not specified a gateway id. We assume you need to listen to all the messages...");
+ } else {
+ gatewayLevelMessages = true;
+ }
+ experimentId = cmd.getOptionValue("eId");
+ if (experimentId == null && !gatewayId.equals("*")){
+ experimentId = "*";
+ logger.info("You have not specified a experiment id. We assume you need to listen to all the messages for the gateway with id " + gatewayId);
+ } else if (experimentId == null && gatewayId.equals("*")) {
+ experimentId = "*";
+ logger.info("You have not specified a experiment id and a gateway id. We assume you need to listen to all the messages...");
+ }else {
+ experimentLevelMessages = true;
+ }
+ jobId = cmd.getOptionValue("jId");
+ if (jobId == null && !gatewayId.equals("*") && !experimentId.equals("*")){
+ jobId = "*";
+ logger.info("You have not specified a job id. We assume you need to listen to all the messages for the gateway with id " + gatewayId
+ + " with experiment id : " + experimentId );
+ } else if (jobId == null && gatewayId.equals("*") && experimentId.equals("*")) {
+ jobId = "*";
+ logger.info("You have not specified a job Id or experiment Id or a gateway Id. We assume you need to listen to all the messages...");
+ }else {
+ jobLevelMessages = true;
+ }
+ }
+ } catch (ParseException e) {
+ logger.error("Error while reading command line parameters" , e);
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/airavata/blob/97ff3b7d/modules/messaging/client/src/main/java/org/apache/airavata/messaging/client/RabbitMQListner.java
----------------------------------------------------------------------
diff --git a/modules/messaging/client/src/main/java/org/apache/airavata/messaging/client/RabbitMQListner.java b/modules/messaging/client/src/main/java/org/apache/airavata/messaging/client/RabbitMQListner.java
deleted file mode 100644
index 215d531..0000000
--- a/modules/messaging/client/src/main/java/org/apache/airavata/messaging/client/RabbitMQListner.java
+++ /dev/null
@@ -1,215 +0,0 @@
-/*
- *
- * 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.messaging.client;
-
-import org.apache.airavata.common.exception.ApplicationSettingsException;
-import org.apache.airavata.common.utils.AiravataUtils;
-import org.apache.airavata.common.utils.ServerSettings;
-import org.apache.airavata.common.utils.ThriftUtils;
-import org.apache.airavata.messaging.core.MessageContext;
-import org.apache.airavata.messaging.core.MessageHandler;
-import org.apache.airavata.messaging.core.MessagingConstants;
-import org.apache.airavata.messaging.core.impl.RabbitMQConsumer;
-import org.apache.airavata.model.messaging.event.*;
-import org.apache.commons.cli.*;
-import org.apache.thrift.TBase;
-import org.apache.thrift.TException;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-
-
-public class RabbitMQListner {
- public static final String RABBITMQ_BROKER_URL = "rabbitmq.broker.url";
- public static final String RABBITMQ_EXCHANGE_NAME = "rabbitmq.exchange.name";
- private final static Logger logger = LoggerFactory.getLogger(RabbitMQListner.class);
- private static String gatewayId = "*";
- private static boolean gatewayLevelMessages = false;
- private static boolean experimentLevelMessages = false;
- private static boolean jobLevelMessages = false;
- private static String experimentId = "*";
- private static String jobId = "*";
- private static boolean allMessages = false;
-
- public static void main(String[] args) {
- parseArguments(args);
- try {
- AiravataUtils.setExecutionAsServer();
- String brokerUrl = ServerSettings.getSetting(RABBITMQ_BROKER_URL);
- final String exchangeName = ServerSettings.getSetting(RABBITMQ_EXCHANGE_NAME);
- RabbitMQConsumer consumer = new RabbitMQConsumer(brokerUrl, exchangeName);
- consumer.listen(new MessageHandler() {
- @Override
- public Map<String, Object> getProperties() {
- Map<String, Object> props = new HashMap<String, Object>();
- List<String> routingKeys = new ArrayList<String>();
- if (allMessages){
- routingKeys.add("*");
- routingKeys.add("*.*");
- routingKeys.add("*.*.*");
- routingKeys.add("*.*.*.*");
- routingKeys.add("*.*.*.*.*");
- }else {
- if (gatewayLevelMessages){
- routingKeys.add(gatewayId);
- routingKeys.add(gatewayId + ".*");
- routingKeys.add(gatewayId + ".*.*");
- routingKeys.add(gatewayId + ".*.*.*");
- routingKeys.add(gatewayId + ".*.*.*.*");
- }else if (experimentLevelMessages){
- routingKeys.add(gatewayId);
- routingKeys.add(gatewayId + "." + experimentId);
- routingKeys.add(gatewayId + "." + experimentId+ ".*");
- routingKeys.add(gatewayId + "." + experimentId+ ".*.*");
- routingKeys.add(gatewayId + "." + experimentId+ ".*.*.*");
- }else if (jobLevelMessages){
- routingKeys.add(gatewayId);
- routingKeys.add(gatewayId + "." + experimentId);
- routingKeys.add(gatewayId + "." + experimentId+ ".*");
- routingKeys.add(gatewayId + "." + experimentId+ ".*.*");
- routingKeys.add(gatewayId + "." + experimentId+ ".*." + jobId);
- }
- }
- props.put(MessagingConstants.RABBIT_ROUTING_KEY, routingKeys);
- return props;
- }
-
- @Override
- public void onMessage(MessageContext message) {
- if (message.getType().equals(MessageType.EXPERIMENT)){
- try {
- ExperimentStatusChangeEvent event = new ExperimentStatusChangeEvent();
- TBase messageEvent = message.getEvent();
- byte[] bytes = ThriftUtils.serializeThriftObject(messageEvent);
- ThriftUtils.createThriftFromBytes(bytes, event);
- System.out.println(" Message Received with message id '" + message.getMessageId()
- + "' and with message type '" + message.getType() + "' and with state : '" + event.getState().toString() +
- " for Gateway " + event.getGatewayId());
- } catch (TException e) {
- logger.error(e.getMessage(), e);
- }
- }else if (message.getType().equals(MessageType.WORKFLOWNODE)){
- try {
- WorkflowNodeStatusChangeEvent event = new WorkflowNodeStatusChangeEvent();
- TBase messageEvent = message.getEvent();
- byte[] bytes = ThriftUtils.serializeThriftObject(messageEvent);
- ThriftUtils.createThriftFromBytes(bytes, event);
- System.out.println(" Message Received with message id '" + message.getMessageId()
- + "' and with message type '" + message.getType() + "' and with state : '" + event.getState().toString() +
- " for Gateway " + event.getWorkflowNodeIdentity().getGatewayId());
- } catch (TException e) {
- logger.error(e.getMessage(), e);
- }
- }else if (message.getType().equals(MessageType.TASK)){
- try {
- TaskStatusChangeEvent event = new TaskStatusChangeEvent();
- TBase messageEvent = message.getEvent();
- byte[] bytes = ThriftUtils.serializeThriftObject(messageEvent);
- ThriftUtils.createThriftFromBytes(bytes, event);
- System.out.println(" Message Received with message id '" + message.getMessageId()
- + "' and with message type '" + message.getType() + "' and with state : '" + event.getState().toString() +
- " for Gateway " + event.getTaskIdentity().getGatewayId());
- } catch (TException e) {
- logger.error(e.getMessage(), e);
- }
- }else if (message.getType().equals(MessageType.JOB)){
- try {
- JobStatusChangeEvent event = new JobStatusChangeEvent();
- TBase messageEvent = message.getEvent();
- byte[] bytes = ThriftUtils.serializeThriftObject(messageEvent);
- ThriftUtils.createThriftFromBytes(bytes, event);
- System.out.println(" Message Received with message id '" + message.getMessageId()
- + "' and with message type '" + message.getType() + "' and with state : '" + event.getState().toString() +
- " for Gateway " + event.getJobIdentity().getGatewayId());
- } catch (TException e) {
- logger.error(e.getMessage(), e);
- }
- }
- }
- });
- } catch (ApplicationSettingsException e) {
- logger.error("Error reading airavata server properties", e);
- }catch (Exception e) {
- logger.error(e.getMessage(), e);
- }
-
- }
-
- public static void parseArguments(String[] args) {
- try{
- Options options = new Options();
-
- options.addOption("gId", true , "Gateway ID");
- options.addOption("eId", true, "Experiment ID");
- options.addOption("jId", true, "Job ID");
- options.addOption("a", false, "All Notifications");
-
- CommandLineParser parser = new PosixParser();
- CommandLine cmd = parser.parse( options, args);
- if (cmd.getOptions() == null || cmd.getOptions().length == 0){
- logger.info("You have not specified any options. We assume you need to listen to all the messages...");
- allMessages = true;
- gatewayId = "*";
- }
- if (cmd.hasOption("a")){
- logger.info("Listening to all the messages...");
- allMessages = true;
- gatewayId = "*";
- }else {
- gatewayId = cmd.getOptionValue("gId");
- if (gatewayId == null){
- gatewayId = "*";
- logger.info("You have not specified a gateway id. We assume you need to listen to all the messages...");
- } else {
- gatewayLevelMessages = true;
- }
- experimentId = cmd.getOptionValue("eId");
- if (experimentId == null && !gatewayId.equals("*")){
- experimentId = "*";
- logger.info("You have not specified a experiment id. We assume you need to listen to all the messages for the gateway with id " + gatewayId);
- } else if (experimentId == null && gatewayId.equals("*")) {
- experimentId = "*";
- logger.info("You have not specified a experiment id and a gateway id. We assume you need to listen to all the messages...");
- }else {
- experimentLevelMessages = true;
- }
- jobId = cmd.getOptionValue("jId");
- if (jobId == null && !gatewayId.equals("*") && !experimentId.equals("*")){
- jobId = "*";
- logger.info("You have not specified a job id. We assume you need to listen to all the messages for the gateway with id " + gatewayId
- + " with experiment id : " + experimentId );
- } else if (jobId == null && gatewayId.equals("*") && experimentId.equals("*")) {
- jobId = "*";
- logger.info("You have not specified a job Id or experiment Id or a gateway Id. We assume you need to listen to all the messages...");
- }else {
- jobLevelMessages = true;
- }
- }
- } catch (ParseException e) {
- logger.error("Error while reading command line parameters" , e);
- }
- }
-}
[11/50] [abbrv] airavata git commit: Added temporary pulisher to
publish task status change events and outputchange events,
Refactored workflow interpreter code and improved it to lauch and iterate the
workflow
Posted by sh...@apache.org.
Added temporary pulisher to publish task status change events and outputchange events, Refactored workflow interpreter code and improved it to lauch and iterate the workflow
Project: http://git-wip-us.apache.org/repos/asf/airavata/repo
Commit: http://git-wip-us.apache.org/repos/asf/airavata/commit/27f6f1b1
Tree: http://git-wip-us.apache.org/repos/asf/airavata/tree/27f6f1b1
Diff: http://git-wip-us.apache.org/repos/asf/airavata/diff/27f6f1b1
Branch: refs/heads/master
Commit: 27f6f1b12c83448b702064df5f90fb4103ec36c4
Parents: 20d6817
Author: shamrath <sh...@gmail.com>
Authored: Fri Feb 20 20:29:18 2015 -0500
Committer: shamrath <sh...@gmail.com>
Committed: Fri Feb 20 20:29:18 2015 -0500
----------------------------------------------------------------------
.../simple/workflow/engine/ProcessPack.java | 62 ++++++
.../engine/SimpleWorkflowInterpreter.java | 204 ++++++++++++++-----
.../simple/workflow/engine/WfNodeContainer.java | 51 -----
.../simple/workflow/engine/WorkflowUtil.java | 10 +
.../engine/dag/nodes/WorkflowInputNodeImpl.java | 3 +-
5 files changed, 228 insertions(+), 102 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/airavata/blob/27f6f1b1/modules/simple-workflow/src/main/java/org/apache/ariavata/simple/workflow/engine/ProcessPack.java
----------------------------------------------------------------------
diff --git a/modules/simple-workflow/src/main/java/org/apache/ariavata/simple/workflow/engine/ProcessPack.java b/modules/simple-workflow/src/main/java/org/apache/ariavata/simple/workflow/engine/ProcessPack.java
new file mode 100644
index 0000000..ab8b724
--- /dev/null
+++ b/modules/simple-workflow/src/main/java/org/apache/ariavata/simple/workflow/engine/ProcessPack.java
@@ -0,0 +1,62 @@
+/*
+ *
+ * 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.ariavata.simple.workflow.engine;
+
+import org.apache.airavata.model.workspace.experiment.TaskDetails;
+import org.apache.airavata.model.workspace.experiment.WorkflowNodeDetails;
+import org.apache.ariavata.simple.workflow.engine.dag.nodes.WorkflowNode;
+
+public class ProcessPack {
+ private WorkflowNode workflowNode;
+ private WorkflowNodeDetails wfNodeDetails;
+ private TaskDetails taskDetails;
+
+ public ProcessPack(WorkflowNode workflowNode, WorkflowNodeDetails wfNodeDetails, TaskDetails taskDetails) {
+ this.workflowNode = workflowNode;
+ this.wfNodeDetails = wfNodeDetails;
+ this.taskDetails = taskDetails;
+ }
+
+ public WorkflowNode getWorkflowNode() {
+ return workflowNode;
+ }
+
+ public void setWorkflowNode(WorkflowNode workflowNode) {
+ this.workflowNode = workflowNode;
+ }
+
+ public WorkflowNodeDetails getWfNodeDetails() {
+ return wfNodeDetails;
+ }
+
+ public void setWfNodeDetails(WorkflowNodeDetails wfNodeDetails) {
+ this.wfNodeDetails = wfNodeDetails;
+ }
+
+ public TaskDetails getTaskDetails() {
+ return taskDetails;
+ }
+
+ public void setTaskDetails(TaskDetails taskDetails) {
+ this.taskDetails = taskDetails;
+ }
+}
http://git-wip-us.apache.org/repos/asf/airavata/blob/27f6f1b1/modules/simple-workflow/src/main/java/org/apache/ariavata/simple/workflow/engine/SimpleWorkflowInterpreter.java
----------------------------------------------------------------------
diff --git a/modules/simple-workflow/src/main/java/org/apache/ariavata/simple/workflow/engine/SimpleWorkflowInterpreter.java b/modules/simple-workflow/src/main/java/org/apache/ariavata/simple/workflow/engine/SimpleWorkflowInterpreter.java
index b4ec3cb..e122fa6 100644
--- a/modules/simple-workflow/src/main/java/org/apache/ariavata/simple/workflow/engine/SimpleWorkflowInterpreter.java
+++ b/modules/simple-workflow/src/main/java/org/apache/ariavata/simple/workflow/engine/SimpleWorkflowInterpreter.java
@@ -21,13 +21,18 @@
package org.apache.ariavata.simple.workflow.engine;
+import com.google.common.eventbus.EventBus;
import com.google.common.eventbus.Subscribe;
+import org.apache.airavata.model.appcatalog.appinterface.InputDataObjectType;
+import org.apache.airavata.model.appcatalog.appinterface.OutputDataObjectType;
+import org.apache.airavata.model.messaging.event.TaskIdentifier;
import org.apache.airavata.model.messaging.event.TaskOutputChangeEvent;
import org.apache.airavata.model.messaging.event.TaskStatusChangeEvent;
import org.apache.airavata.model.util.ExperimentModelUtil;
import org.apache.airavata.model.workspace.experiment.ExecutionUnit;
import org.apache.airavata.model.workspace.experiment.Experiment;
import org.apache.airavata.model.workspace.experiment.TaskDetails;
+import org.apache.airavata.model.workspace.experiment.TaskState;
import org.apache.airavata.model.workspace.experiment.WorkflowNodeDetails;
import org.apache.airavata.model.workspace.experiment.WorkflowNodeState;
import org.apache.airavata.model.workspace.experiment.WorkflowNodeStatus;
@@ -36,6 +41,7 @@ import org.apache.airavata.registry.cpi.ChildDataType;
import org.apache.airavata.registry.cpi.Registry;
import org.apache.airavata.registry.cpi.RegistryException;
import org.apache.airavata.registry.cpi.RegistryModelType;
+import org.apache.ariavata.simple.workflow.engine.dag.edge.Edge;
import org.apache.ariavata.simple.workflow.engine.dag.nodes.ApplicationNode;
import org.apache.ariavata.simple.workflow.engine.dag.nodes.NodeState;
import org.apache.ariavata.simple.workflow.engine.dag.nodes.WorkflowInputNode;
@@ -43,6 +49,8 @@ import org.apache.ariavata.simple.workflow.engine.dag.nodes.WorkflowNode;
import org.apache.ariavata.simple.workflow.engine.dag.nodes.WorkflowOutputNode;
import org.apache.ariavata.simple.workflow.engine.dag.port.InPort;
import org.apache.ariavata.simple.workflow.engine.dag.port.OutPort;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
import java.util.ArrayList;
import java.util.HashMap;
@@ -53,6 +61,7 @@ import java.util.Set;
public class SimpleWorkflowInterpreter implements Runnable{
+ private static final Logger log = LoggerFactory.getLogger(SimpleWorkflowInterpreter.class);
private List<WorkflowInputNode> workflowInputNodes;
@@ -60,11 +69,12 @@ public class SimpleWorkflowInterpreter implements Runnable{
private String credentialToken;
- private List<WorkflowNode> readList = new ArrayList<WorkflowNode>();
- private List<WorkflowNode> waitingList = new ArrayList<WorkflowNode>();
- private Map<String,WfNodeContainer> processingQueue = new HashMap<String, WfNodeContainer>();
- private List<WorkflowNode> completeList = new ArrayList<WorkflowNode>();
+ private Map<String, WorkflowNode> readList = new HashMap<String, WorkflowNode>();
+ private Map<String, WorkflowNode> waitingList = new HashMap<String, WorkflowNode>();
+ private Map<String, ProcessPack> processingQueue = new HashMap<String, ProcessPack>();
+ private Map<String, ProcessPack> completeList = new HashMap<String, ProcessPack>();
private Registry registry;
+ private EventBus eventBus = new EventBus();
public SimpleWorkflowInterpreter(Experiment experiment, String credentialStoreToken) {
// read the workflow file and build the topology to a DAG. Then execute that dag
@@ -77,6 +87,9 @@ public class SimpleWorkflowInterpreter implements Runnable{
public void launchWorkflow() throws Exception {
// process workflow input nodes
+ WorkflowFactoryImpl wfFactory = WorkflowFactoryImpl.getInstance();
+ WorkflowParser workflowParser = wfFactory.getWorkflowParser(experiment.getExperimentID(), credentialToken);
+ setWorkflowInputNodes(workflowParser.parse());
processWorkflowInputNodes(getWorkflowInputNodes());
processReadyList();
// process workflow application nodes
@@ -85,11 +98,11 @@ public class SimpleWorkflowInterpreter implements Runnable{
// try to remove synchronization tag
private synchronized void processReadyList() {
- for (WorkflowNode readyNode : readList) {
+ for (WorkflowNode readyNode : readList.values()) {
try {
WorkflowNodeDetails workflowNodeDetails = createWorkflowNodeDetails(readyNode);
TaskDetails process = getProcess(workflowNodeDetails);
- processingQueue.put(process.getTaskID(), new WfNodeContainer(readyNode, workflowNodeDetails));
+ addToProcessingQueue(new ProcessPack(readyNode, workflowNodeDetails, process));
publishToProcessQueue(process);
} catch (RegistryException e) {
// FIXME : handle this exception
@@ -98,6 +111,8 @@ public class SimpleWorkflowInterpreter implements Runnable{
}
private void publishToProcessQueue(TaskDetails process) {
+ Thread thread = new Thread(new TempPublisher(process, eventBus));
+ thread.start();
//TODO: publish to process queue.
}
@@ -150,31 +165,21 @@ public class SimpleWorkflowInterpreter implements Runnable{
Set<WorkflowNode> tempNodeSet = new HashSet<WorkflowNode>();
for (WorkflowInputNode wfInputNode : wfInputNodes) {
if (wfInputNode.isReady()) {
-
-// for (Edge edge : wfInputNode.getOutputLinks()) {
-// WorkflowUtil.copyValues(wfInputNode.getInputObject(), edge.getToPort().getInputObject());
-// tempNodeSet.add(edge.getToPort().getNode());
-// }
- }
- }
- for (WorkflowNode workflowNode : tempNodeSet) {
- if (workflowNode.isReady()) {
- readList.add(workflowNode);
- } else {
- waitingList.add(workflowNode);
+ for (Edge edge : wfInputNode.getOutPort().getOutEdges()) {
+ edge.getToPort().setInputObject(
+ WorkflowUtil.copyValues(wfInputNode.getInputObject(), edge.getToPort().getInputObject()));
+ if (edge.getToPort().getNode().isReady()) {
+ addToReadyQueue(edge.getToPort().getNode());
+ } else {
+ addToWaitingQueue(edge.getToPort().getNode());
+ }
+ }
}
}
}
public List<WorkflowInputNode> getWorkflowInputNodes() throws Exception {
- if (workflowInputNodes == null) {
- // read workflow description from registry and parse it
- WorkflowFactoryImpl wfFactory = WorkflowFactoryImpl.getInstance();
- List<WorkflowInputNode> wfInputNodes = wfFactory.getWorkflowParser(experiment.getExperimentID(),
- credentialToken).parse();
- setWorkflowInputNodes(wfInputNodes);
- }
return workflowInputNodes;
}
@@ -208,29 +213,29 @@ public class SimpleWorkflowInterpreter implements Runnable{
@Subscribe
public void taskOutputChanged(TaskOutputChangeEvent taskOutputEvent){
String taskId = taskOutputEvent.getTaskIdentity().getTaskId();
- WfNodeContainer wfNodeContainer = processingQueue.get(taskId);
+ ProcessPack processPack = processingQueue.get(taskId);
Set<WorkflowNode> tempWfNodeSet = new HashSet<WorkflowNode>();
- if (wfNodeContainer != null) {
- WorkflowNode workflowNode = wfNodeContainer.getWorkflowNode();
+ if (processPack != null) {
+ WorkflowNode workflowNode = processPack.getWorkflowNode();
if (workflowNode instanceof ApplicationNode) {
ApplicationNode applicationNode = (ApplicationNode) workflowNode;
// Workflow node can have one to many output ports and each output port can have one to many links
for (OutPort outPort : applicationNode.getOutputPorts()) {
-// for (Edge edge : outPort.getOutputLinks()) {
-// WorkflowUtil.copyValues(outPort.getOutputObject(), edge.getToPort().getInputObject());
-// tempWfNodeSet.add(edge.getToPort().getNode());
-// }
- }
-
- for (WorkflowNode node : tempWfNodeSet) {
- if (node.isReady()) {
- waitingList.remove(node);
- readList.add(node);
+ for (OutputDataObjectType outputDataObjectType : taskOutputEvent.getOutput()) {
+ if (outPort.getOutputObject().getName().equals(outputDataObjectType.getName())) {
+ outPort.getOutputObject().setValue(outputDataObjectType.getValue());
+ break;
+ }
+ }
+ for (Edge edge : outPort.getOutEdges()) {
+ WorkflowUtil.copyValues(outPort.getOutputObject(), edge.getToPort().getInputObject());
+ if (edge.getToPort().getNode().isReady()) {
+ addToReadyQueue(edge.getToPort().getNode());
+ }
}
}
}
processingQueue.remove(taskId);
- processReadyList();
}
}
@@ -238,8 +243,8 @@ public class SimpleWorkflowInterpreter implements Runnable{
@Subscribe
public void taskStatusChanged(TaskStatusChangeEvent taskStatus){
String taskId = taskStatus.getTaskIdentity().getTaskId();
- WfNodeContainer wfNodeContainer = processingQueue.get(taskId);
- if (wfNodeContainer != null) {
+ ProcessPack processPack = processingQueue.get(taskId);
+ if (processPack != null) {
WorkflowNodeState wfNodeState = WorkflowNodeState.UNKNOWN;
switch (taskStatus.getState()) {
case WAITING:
@@ -247,25 +252,25 @@ public class SimpleWorkflowInterpreter implements Runnable{
case STARTED:
break;
case PRE_PROCESSING:
- wfNodeContainer.getWorkflowNode().setNodeState(NodeState.PRE_PROCESSING);
+ processPack.getWorkflowNode().setNodeState(NodeState.PRE_PROCESSING);
break;
case INPUT_DATA_STAGING:
- wfNodeContainer.getWorkflowNode().setNodeState(NodeState.PRE_PROCESSING);
+ processPack.getWorkflowNode().setNodeState(NodeState.PRE_PROCESSING);
break;
case OUTPUT_DATA_STAGING:
- wfNodeContainer.getWorkflowNode().setNodeState(NodeState.POST_PROCESSING);
+ processPack.getWorkflowNode().setNodeState(NodeState.POST_PROCESSING);
break;
case EXECUTING:
- wfNodeContainer.getWorkflowNode().setNodeState(NodeState.EXECUTING);
+ processPack.getWorkflowNode().setNodeState(NodeState.EXECUTING);
break;
case POST_PROCESSING:
- wfNodeContainer.getWorkflowNode().setNodeState(NodeState.POST_PROCESSING);
+ processPack.getWorkflowNode().setNodeState(NodeState.POST_PROCESSING);
break;
case COMPLETED:
- wfNodeContainer.getWorkflowNode().setNodeState(NodeState.EXECUTED);
+ processPack.getWorkflowNode().setNodeState(NodeState.EXECUTED);
break;
case FAILED:
- wfNodeContainer.getWorkflowNode().setNodeState(NodeState.FAILED);
+ processPack.getWorkflowNode().setNodeState(NodeState.FAILED);
break;
case UNKNOWN:
break;
@@ -273,14 +278,14 @@ public class SimpleWorkflowInterpreter implements Runnable{
break;
case CANCELED:
case CANCELING:
- wfNodeContainer.getWorkflowNode().setNodeState(NodeState.FAILED);
+ processPack.getWorkflowNode().setNodeState(NodeState.FAILED);
break;
default:
break;
}
if (wfNodeState != WorkflowNodeState.UNKNOWN) {
try {
- updateWorkflowNodeStatus(wfNodeContainer.getWfNodeDetails(), wfNodeState);
+ updateWorkflowNodeStatus(processPack.getWfNodeDetails(), wfNodeState);
} catch (RegistryException e) {
// TODO: handle this.
}
@@ -289,8 +294,107 @@ public class SimpleWorkflowInterpreter implements Runnable{
}
+ /**
+ * Remove the workflow node from waiting queue and add it to the ready queue.
+ * @param workflowNode - Workflow Node
+ */
+ private synchronized void addToReadyQueue(WorkflowNode workflowNode) {
+ waitingList.remove(workflowNode.getNodeId());
+ readList.put(workflowNode.getNodeId(), workflowNode);
+ }
+
+ private void addToWaitingQueue(WorkflowNode workflowNode) {
+ waitingList.put(workflowNode.getNodeId(), workflowNode);
+ }
+
+ /**
+ * First remove the node from ready list and then add the WfNodeContainer to the process queue.
+ * Note that underline data structure of the process queue is a Map.
+ * @param processPack - has both workflow and correspond workflowNodeDetails and TaskDetails
+ */
+ private synchronized void addToProcessingQueue(ProcessPack processPack) {
+ readList.remove(processPack.getWorkflowNode().getNodeId());
+ processingQueue.put(processPack.getTaskDetails().getTaskID(), processPack);
+ }
+
+ private synchronized void addToCompleteQueue(ProcessPack processPack) {
+ processingQueue.remove(processPack.getTaskDetails().getTaskID());
+ completeList.put(processPack.getTaskDetails().getTaskID(), processPack);
+ }
+
+
@Override
public void run() {
// TODO: Auto generated method body.
+ try {
+ launchWorkflow();
+ while (!(waitingList.isEmpty() && readList.isEmpty())) {
+ processReadyList();
+ }
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ }
+
+
+ class TempPublisher implements Runnable {
+ private TaskDetails tempTaskDetails;
+ private EventBus tempEventBus;
+
+ public TempPublisher(TaskDetails tempTaskDetails, EventBus tempEventBus) {
+ this.tempTaskDetails = tempTaskDetails;
+ this.tempEventBus = tempEventBus;
+ }
+
+ @Override
+ public void run() {
+ try {
+ TaskIdentifier identifier = new TaskIdentifier(tempTaskDetails.getTaskID(), null, null, null);
+ TaskStatusChangeEvent statusChangeEvent = new TaskStatusChangeEvent(TaskState.PRE_PROCESSING, identifier);
+ tempEventBus.post(statusChangeEvent);
+ Thread.sleep(1000);
+ statusChangeEvent = new TaskStatusChangeEvent(TaskState.WAITING, identifier);
+ tempEventBus.post(statusChangeEvent);
+ Thread.sleep(1000);
+ statusChangeEvent = new TaskStatusChangeEvent(TaskState.INPUT_DATA_STAGING, identifier);
+ tempEventBus.post(statusChangeEvent);
+ Thread.sleep(1000);
+ statusChangeEvent = new TaskStatusChangeEvent(TaskState.STARTED, identifier);
+ tempEventBus.post(statusChangeEvent);
+ Thread.sleep(1000);
+ statusChangeEvent = new TaskStatusChangeEvent(TaskState.EXECUTING, identifier);
+ tempEventBus.post(statusChangeEvent);
+ Thread.sleep(1000);
+ statusChangeEvent = new TaskStatusChangeEvent(TaskState.POST_PROCESSING, identifier);
+ tempEventBus.post(statusChangeEvent);
+ Thread.sleep(1000);
+ statusChangeEvent = new TaskStatusChangeEvent(TaskState.OUTPUT_DATA_STAGING, identifier);
+ tempEventBus.post(statusChangeEvent);
+ Thread.sleep(1000);
+ statusChangeEvent = new TaskStatusChangeEvent(TaskState.COMPLETED, identifier);
+ tempEventBus.post(statusChangeEvent);
+ Thread.sleep(1000);
+
+ List<InputDataObjectType> applicationInputs = tempTaskDetails.getApplicationInputs();
+ List<OutputDataObjectType> applicationOutputs = tempTaskDetails.getApplicationOutputs();
+ log.info("************** Task output change event fired for application id :" + tempTaskDetails.getApplicationId());
+ if (tempTaskDetails.getApplicationId().equals("Add") || tempTaskDetails.getApplicationId().equals("Add_2")) {
+ applicationOutputs.get(0).setValue((Integer.parseInt(applicationInputs.get(0).getValue()) +
+ Integer.parseInt(applicationInputs.get(1).getValue())) + "");
+ } else if (tempTaskDetails.getApplicationId().equals("Subtract")) {
+ applicationOutputs.get(0).setValue((Integer.parseInt(applicationInputs.get(0).getValue()) -
+ Integer.parseInt(applicationInputs.get(1).getValue())) + "");
+ } else if (tempTaskDetails.getApplicationId().equals("Multiply")) {
+ applicationOutputs.get(0).setValue((Integer.parseInt(applicationInputs.get(0).getValue()) *
+ Integer.parseInt(applicationInputs.get(1).getValue())) + "");
+ }
+ TaskOutputChangeEvent taskOutputChangeEvent = new TaskOutputChangeEvent(applicationOutputs, identifier);
+ eventBus.post(taskOutputChangeEvent);
+
+ } catch (InterruptedException e) {
+ log.error("Thread was interrupted while sleeping");
+ }
+
+ }
}
}
http://git-wip-us.apache.org/repos/asf/airavata/blob/27f6f1b1/modules/simple-workflow/src/main/java/org/apache/ariavata/simple/workflow/engine/WfNodeContainer.java
----------------------------------------------------------------------
diff --git a/modules/simple-workflow/src/main/java/org/apache/ariavata/simple/workflow/engine/WfNodeContainer.java b/modules/simple-workflow/src/main/java/org/apache/ariavata/simple/workflow/engine/WfNodeContainer.java
deleted file mode 100644
index e0cebd6..0000000
--- a/modules/simple-workflow/src/main/java/org/apache/ariavata/simple/workflow/engine/WfNodeContainer.java
+++ /dev/null
@@ -1,51 +0,0 @@
-/*
- *
- * 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.ariavata.simple.workflow.engine;
-
-import org.apache.airavata.model.workspace.experiment.WorkflowNodeDetails;
-import org.apache.ariavata.simple.workflow.engine.dag.nodes.WorkflowNode;
-
-public class WfNodeContainer {
- private WorkflowNode workflowNode;
- private WorkflowNodeDetails wfNodeDetails;
-
- public WfNodeContainer(WorkflowNode workflowNode, WorkflowNodeDetails wfNodeDetails) {
- this.workflowNode = workflowNode;
- this.wfNodeDetails = wfNodeDetails;
- }
-
- public WorkflowNode getWorkflowNode() {
- return workflowNode;
- }
-
- public void setWorkflowNode(WorkflowNode workflowNode) {
- this.workflowNode = workflowNode;
- }
-
- public WorkflowNodeDetails getWfNodeDetails() {
- return wfNodeDetails;
- }
-
- public void setWfNodeDetails(WorkflowNodeDetails wfNodeDetails) {
- this.wfNodeDetails = wfNodeDetails;
- }
-}
http://git-wip-us.apache.org/repos/asf/airavata/blob/27f6f1b1/modules/simple-workflow/src/main/java/org/apache/ariavata/simple/workflow/engine/WorkflowUtil.java
----------------------------------------------------------------------
diff --git a/modules/simple-workflow/src/main/java/org/apache/ariavata/simple/workflow/engine/WorkflowUtil.java b/modules/simple-workflow/src/main/java/org/apache/ariavata/simple/workflow/engine/WorkflowUtil.java
index 71d0288..d4bbad3 100644
--- a/modules/simple-workflow/src/main/java/org/apache/ariavata/simple/workflow/engine/WorkflowUtil.java
+++ b/modules/simple-workflow/src/main/java/org/apache/ariavata/simple/workflow/engine/WorkflowUtil.java
@@ -21,12 +21,21 @@
package org.apache.ariavata.simple.workflow.engine;
+import com.google.common.eventbus.EventBus;
import org.apache.airavata.model.appcatalog.appinterface.InputDataObjectType;
import org.apache.airavata.model.appcatalog.appinterface.OutputDataObjectType;
+import org.apache.airavata.model.messaging.event.TaskIdentifier;
+import org.apache.airavata.model.messaging.event.TaskStatusChangeEvent;
+import org.apache.airavata.model.workspace.experiment.TaskDetails;
+import org.apache.airavata.model.workspace.experiment.TaskState;
+import org.apache.airavata.persistance.registry.jpa.model.TaskDetail;
public class WorkflowUtil {
public static InputDataObjectType copyValues(InputDataObjectType fromInputObj, InputDataObjectType toInputObj){
+ if (toInputObj == null) {
+ // TODO : throw an error
+ }
toInputObj.setValue(fromInputObj.getValue());
if (fromInputObj.getApplicationArgument() != null
&& !fromInputObj.getApplicationArgument().trim().equals("")) {
@@ -40,4 +49,5 @@ public class WorkflowUtil {
return inputData;
}
+
}
http://git-wip-us.apache.org/repos/asf/airavata/blob/27f6f1b1/modules/simple-workflow/src/main/java/org/apache/ariavata/simple/workflow/engine/dag/nodes/WorkflowInputNodeImpl.java
----------------------------------------------------------------------
diff --git a/modules/simple-workflow/src/main/java/org/apache/ariavata/simple/workflow/engine/dag/nodes/WorkflowInputNodeImpl.java b/modules/simple-workflow/src/main/java/org/apache/ariavata/simple/workflow/engine/dag/nodes/WorkflowInputNodeImpl.java
index 2f912b3..f419ae2 100644
--- a/modules/simple-workflow/src/main/java/org/apache/ariavata/simple/workflow/engine/dag/nodes/WorkflowInputNodeImpl.java
+++ b/modules/simple-workflow/src/main/java/org/apache/ariavata/simple/workflow/engine/dag/nodes/WorkflowInputNodeImpl.java
@@ -67,7 +67,8 @@ public class WorkflowInputNodeImpl implements WorkflowInputNode {
@Override
public boolean isReady() {
- return inputDataObjectType.getValue() != null && !inputDataObjectType.getValue().equals("");
+ return (inputDataObjectType.getValue() != null && !inputDataObjectType.getValue().equals(""))
+ || !inputDataObjectType.isIsRequired();
}
@Override
[41/50] [abbrv] airavata git commit: Renamed simple-workflow module
to workflow and created a new workflow-core module which will keep all the
core code
Posted by sh...@apache.org.
http://git-wip-us.apache.org/repos/asf/airavata/blob/509f2037/modules/workflow/workflow-core/src/test/resources/ParamChemApplicationTest.awf
----------------------------------------------------------------------
diff --git a/modules/workflow/workflow-core/src/test/resources/ParamChemApplicationTest.awf b/modules/workflow/workflow-core/src/test/resources/ParamChemApplicationTest.awf
new file mode 100644
index 0000000..f0ab5eb
--- /dev/null
+++ b/modules/workflow/workflow-core/src/test/resources/ParamChemApplicationTest.awf
@@ -0,0 +1,593 @@
+{
+ "workflow": {
+ "version": "0.11",
+ "graph": {
+ "version": "0.11",
+ "id": "ParamchemApplication",
+ "name": "ParamchemApplication",
+ "description": "ParamChem workflow",
+ "node": [
+ {
+ "id": "model_refdata_prep",
+ "name": "model_refdata_prep",
+ "inputPort": [
+ "model_refdata_prep_in_0",
+ "model_refdata_prep_in_1",
+ "model_refdata_prep_in_2",
+ "model_refdata_prep_in_3",
+ "model_refdata_prep_in_4",
+ "model_refdata_prep_in_5",
+ "model_refdata_prep_in_6",
+ "model_refdata_prep_in_7",
+ "model_refdata_prep_in_8"
+ ],
+ "outputPort": [
+ "model_refdata_prep_out_0",
+ "model_refdata_prep_out_1",
+ "model_refdata_prep_out_2",
+ "model_refdata_prep_out_3"
+ ],
+ "controlInPort": "model_refdata_prep_ctrl_in_0",
+ "controlOutPort": [
+ "model_refdata_prep_ctrl_out_0"
+ ],
+ "x": "392",
+ "y": "154",
+ "type": "ws",
+ "Application": {
+ "description": "ParamChem Workflow Step 1. Model Reference Data Preparation Step",
+ "name": "model_refdata_prep",
+ "application": "model_refdata_prep_0a6fcb69-4c13-41ef-a604-c0157088970b",
+ "Input": [
+ {
+ "description": "This is a project name set by the user when constructing the workflow (experiment)",
+ "name": "GC_ProjectName",
+ "defaultValue": "cgenff_proj",
+ "dataType": "STRING",
+ "inputOrder": 8,
+ "appArgument": ""
+ },
+ {
+ "description": "UserName (ID) of the Individual in the Gateway Community",
+ "name": "GC_UserName",
+ "defaultValue": "",
+ "dataType": "STRING",
+ "inputOrder": 7,
+ "appArgument": ""
+ },
+ {
+ "description": "Name of the workflow set by the user",
+ "name": "GC_WorkflowName",
+ "defaultValue": "Cgenff_Workflow",
+ "dataType": "STRING",
+ "inputOrder": 9,
+ "appArgument": ""
+ },
+ {
+ "description": "Name of the mol2 file corresponding to the molecule Id defined above",
+ "name": "geom",
+ "defaultValue": "",
+ "dataType": "STRING",
+ "inputOrder": 2,
+ "appArgument": ""
+ },
+ {
+ "description": "Directory of the Molecular Inputs",
+ "name": "molecule_dir_in",
+ "defaultValue": "",
+ "dataType": "STRING",
+ "inputOrder": 6,
+ "appArgument": ""
+ },
+ {
+ "description": "This is the identifier of the molecule a name whose mol2 file is presented as input with other parameters which defines other files based on the ID.",
+ "name": "molecule_id",
+ "defaultValue": "",
+ "dataType": "STRING",
+ "inputOrder": 1,
+ "appArgument": ""
+ },
+ {
+ "description": "Main Topology Parameter File",
+ "name": "toppar_main",
+ "defaultValue": "toppar_main-tgz",
+ "dataType": "STRING",
+ "inputOrder": 3,
+ "appArgument": ""
+ },
+ {
+ "description": "Molecule Specific Topological Parameter File",
+ "name": "toppar_mol_str",
+ "defaultValue": "",
+ "dataType": "STRING",
+ "inputOrder": 5,
+ "appArgument": ""
+ },
+ {
+ "description": "User Specific Topology Parameter file",
+ "name": "toppar_user",
+ "defaultValue": "toppar_usr_tgz",
+ "dataType": "STRING",
+ "inputOrder": 4,
+ "appArgument": ""
+ }
+ ],
+ "Output": [
+ {
+ "description": "generate.out",
+ "name": "generate.out",
+ "dataType": "URI"
+ },
+ {
+ "description": "molecule_dir_out",
+ "name": "molecule_dir_out",
+ "dataType": "URI"
+ },
+ {
+ "description": "molecule_id_min.crd",
+ "name": "molecule_id_min.crd",
+ "dataType": "URI"
+ },
+ {
+ "description": "molecule_id_opt_freq_mp2.gjf",
+ "name": "molecule_id_opt_freq_mp2.gjf",
+ "dataType": "URI"
+ }
+ ]
+ }
+ },
+ {
+ "id": "GC_ProjectName",
+ "name": "GC_ProjectName",
+ "outputPort": [
+ "Input_out_2"
+ ],
+ "x": "316",
+ "y": "21",
+ "config": {
+ "description": "This is a project name set by the user when constructing the workflow (experiment)",
+ "dataType": "STRING",
+ "value": "cgenff_proj",
+ "visibility": true
+ },
+ "type": "input"
+ },
+ {
+ "id": "GC_UserName",
+ "name": "GC_UserName",
+ "outputPort": [
+ "Input_out_3"
+ ],
+ "x": "142",
+ "y": "28",
+ "config": {
+ "description": "UserName (ID) of the Individual in the Gateway Community",
+ "dataType": "STRING",
+ "value": "",
+ "visibility": true
+ },
+ "type": "input"
+ },
+ {
+ "id": "GC_WorkflowName",
+ "name": "GC_WorkflowName",
+ "outputPort": [
+ "Input_out_4"
+ ],
+ "x": "39",
+ "y": "88",
+ "config": {
+ "description": "Name of the workflow set by the user",
+ "dataType": "STRING",
+ "value": "Cgenff_Workflow",
+ "visibility": true
+ },
+ "type": "input"
+ },
+ {
+ "id": "geom",
+ "name": "geom",
+ "outputPort": [
+ "Input_out_5"
+ ],
+ "x": "27",
+ "y": "171",
+ "config": {
+ "description": "Name of the mol2 file corresponding to the molecule Id defined above",
+ "dataType": "STRING",
+ "value": "",
+ "visibility": true
+ },
+ "type": "input"
+ },
+ {
+ "id": "molecule_dir_in",
+ "name": "molecule_dir_in",
+ "outputPort": [
+ "Input_out_6"
+ ],
+ "x": "19",
+ "y": "241",
+ "config": {
+ "description": "Directory of the Molecular Inputs",
+ "dataType": "STRING",
+ "value": "",
+ "visibility": true
+ },
+ "type": "input"
+ },
+ {
+ "id": "molecule_id",
+ "name": "molecule_id",
+ "outputPort": [
+ "Input_out_7"
+ ],
+ "x": "70",
+ "y": "298",
+ "config": {
+ "description": "This is the identifier of the molecule a name whose mol2 file is presented as input with other parameters which defines other files based on the ID.",
+ "dataType": "STRING",
+ "value": "",
+ "visibility": true
+ },
+ "type": "input"
+ },
+ {
+ "id": "toppar_main",
+ "name": "toppar_main",
+ "outputPort": [
+ "Input_out_8"
+ ],
+ "x": "24",
+ "y": "366",
+ "config": {
+ "description": "Main Topology Parameter File",
+ "dataType": "STRING",
+ "value": "toppar_main-tgz",
+ "visibility": true
+ },
+ "type": "input"
+ },
+ {
+ "id": "toppar_mol_str",
+ "name": "toppar_mol_str",
+ "outputPort": [
+ "Input_out_9"
+ ],
+ "x": "119",
+ "y": "413",
+ "config": {
+ "description": "Molecule Specific Topological Parameter File",
+ "dataType": "STRING",
+ "value": "",
+ "visibility": true
+ },
+ "type": "input"
+ },
+ {
+ "id": "toppar_user",
+ "name": "toppar_user",
+ "outputPort": [
+ "Input_out_10"
+ ],
+ "x": "293",
+ "y": "413",
+ "config": {
+ "description": "User Specific Topology Parameter file",
+ "dataType": "STRING",
+ "value": "toppar_usr_tgz",
+ "visibility": true
+ },
+ "type": "input"
+ },
+ {
+ "id": "generate_out",
+ "name": "generate.out",
+ "inputPort": [
+ "Output_in_2"
+ ],
+ "x": "657",
+ "y": "50",
+ "config": {
+ "description": "generate.out",
+ "dataType": "URI"
+ },
+ "type": "output"
+ },
+ {
+ "id": "molecule_dir_out",
+ "name": "molecule_dir_out",
+ "inputPort": [
+ "Output_in_3"
+ ],
+ "x": "656",
+ "y": "128",
+ "config": {
+ "description": "molecule_dir_out",
+ "dataType": "URI"
+ },
+ "type": "output"
+ },
+ {
+ "id": "molecule_id_min_crd",
+ "name": "molecule_id_min.crd",
+ "inputPort": [
+ "Output_in_4"
+ ],
+ "x": "658",
+ "y": "204",
+ "config": {
+ "description": "molecule_id_min.crd",
+ "dataType": "URI"
+ },
+ "type": "output"
+ },
+ {
+ "id": "molecule_id_opt_freq_mp2_gjf",
+ "name": "molecule_id_opt_freq_mp2.gjf",
+ "inputPort": [
+ "Output_in_5"
+ ],
+ "x": "642",
+ "y": "297",
+ "config": {
+ "description": "molecule_id_opt_freq_mp2.gjf",
+ "dataType": "URI"
+ },
+ "type": "output"
+ }
+ ],
+ "port": [
+ {
+ "id": "model_refdata_prep_in_0",
+ "name": "GC_ProjectName",
+ "node": "model_refdata_prep",
+ "type": "ws",
+ "dataType": "STRING"
+ },
+ {
+ "id": "model_refdata_prep_in_1",
+ "name": "GC_UserName",
+ "node": "model_refdata_prep",
+ "type": "ws",
+ "dataType": "STRING"
+ },
+ {
+ "id": "model_refdata_prep_in_2",
+ "name": "GC_WorkflowName",
+ "node": "model_refdata_prep",
+ "type": "ws",
+ "dataType": "STRING"
+ },
+ {
+ "id": "model_refdata_prep_in_3",
+ "name": "geom",
+ "node": "model_refdata_prep",
+ "type": "ws",
+ "dataType": "STRING"
+ },
+ {
+ "id": "model_refdata_prep_in_4",
+ "name": "molecule_dir_in",
+ "node": "model_refdata_prep",
+ "type": "ws",
+ "dataType": "STRING"
+ },
+ {
+ "id": "model_refdata_prep_in_5",
+ "name": "molecule_id",
+ "node": "model_refdata_prep",
+ "type": "ws",
+ "dataType": "STRING"
+ },
+ {
+ "id": "model_refdata_prep_in_6",
+ "name": "toppar_main",
+ "node": "model_refdata_prep",
+ "type": "ws",
+ "dataType": "STRING"
+ },
+ {
+ "id": "model_refdata_prep_in_7",
+ "name": "toppar_mol_str",
+ "node": "model_refdata_prep",
+ "type": "ws",
+ "dataType": "STRING"
+ },
+ {
+ "id": "model_refdata_prep_in_8",
+ "name": "toppar_user",
+ "node": "model_refdata_prep",
+ "type": "ws",
+ "dataType": "STRING"
+ },
+ {
+ "id": "model_refdata_prep_out_0",
+ "name": "generate.out",
+ "node": "model_refdata_prep",
+ "type": "ws",
+ "dataType": "URI"
+ },
+ {
+ "id": "model_refdata_prep_out_1",
+ "name": "molecule_dir_out",
+ "node": "model_refdata_prep",
+ "type": "ws",
+ "dataType": "URI"
+ },
+ {
+ "id": "model_refdata_prep_out_2",
+ "name": "molecule_id_min.crd",
+ "node": "model_refdata_prep",
+ "type": "ws",
+ "dataType": "URI"
+ },
+ {
+ "id": "model_refdata_prep_out_3",
+ "name": "molecule_id_opt_freq_mp2.gjf",
+ "node": "model_refdata_prep",
+ "type": "ws",
+ "dataType": "URI"
+ },
+ {
+ "id": "model_refdata_prep_ctrl_in_0",
+ "name": "control",
+ "node": "model_refdata_prep",
+ "type": "control"
+ },
+ {
+ "id": "model_refdata_prep_ctrl_out_0",
+ "name": "control",
+ "node": "model_refdata_prep",
+ "type": "control"
+ },
+ {
+ "id": "Input_out_2",
+ "name": "Parameter",
+ "node": "GC_ProjectName",
+ "type": "systemData"
+ },
+ {
+ "id": "Input_out_3",
+ "name": "Parameter",
+ "node": "GC_UserName",
+ "type": "systemData"
+ },
+ {
+ "id": "Input_out_4",
+ "name": "Parameter",
+ "node": "GC_WorkflowName",
+ "type": "systemData"
+ },
+ {
+ "id": "Input_out_5",
+ "name": "Parameter",
+ "node": "geom",
+ "type": "systemData"
+ },
+ {
+ "id": "Input_out_6",
+ "name": "Parameter",
+ "node": "molecule_dir_in",
+ "type": "systemData"
+ },
+ {
+ "id": "Input_out_7",
+ "name": "Parameter",
+ "node": "molecule_id",
+ "type": "systemData"
+ },
+ {
+ "id": "Input_out_8",
+ "name": "Parameter",
+ "node": "toppar_main",
+ "type": "systemData"
+ },
+ {
+ "id": "Input_out_9",
+ "name": "Parameter",
+ "node": "toppar_mol_str",
+ "type": "systemData"
+ },
+ {
+ "id": "Input_out_10",
+ "name": "Parameter",
+ "node": "toppar_user",
+ "type": "systemData"
+ },
+ {
+ "id": "Output_in_2",
+ "name": "Parameter",
+ "node": "generate_out",
+ "type": "systemData"
+ },
+ {
+ "id": "Output_in_3",
+ "name": "Parameter",
+ "node": "molecule_dir_out",
+ "type": "systemData"
+ },
+ {
+ "id": "Output_in_4",
+ "name": "Parameter",
+ "node": "molecule_id_min_crd",
+ "type": "systemData"
+ },
+ {
+ "id": "Output_in_5",
+ "name": "Parameter",
+ "node": "molecule_id_opt_freq_mp2_gjf",
+ "type": "systemData"
+ }
+ ],
+ "edge": [
+ {
+ "fromPort": "Input_out_2",
+ "toPort": "model_refdata_prep_in_0",
+ "type": "data"
+ },
+ {
+ "fromPort": "Input_out_3",
+ "toPort": "model_refdata_prep_in_1",
+ "type": "data"
+ },
+ {
+ "fromPort": "Input_out_4",
+ "toPort": "model_refdata_prep_in_2",
+ "type": "data"
+ },
+ {
+ "fromPort": "Input_out_5",
+ "toPort": "model_refdata_prep_in_3",
+ "type": "data"
+ },
+ {
+ "fromPort": "Input_out_6",
+ "toPort": "model_refdata_prep_in_4",
+ "type": "data"
+ },
+ {
+ "fromPort": "Input_out_7",
+ "toPort": "model_refdata_prep_in_5",
+ "type": "data"
+ },
+ {
+ "fromPort": "Input_out_8",
+ "toPort": "model_refdata_prep_in_6",
+ "type": "data"
+ },
+ {
+ "fromPort": "Input_out_9",
+ "toPort": "model_refdata_prep_in_7",
+ "type": "data"
+ },
+ {
+ "fromPort": "Input_out_10",
+ "toPort": "model_refdata_prep_in_8",
+ "type": "data"
+ },
+ {
+ "fromPort": "model_refdata_prep_out_0",
+ "toPort": "Output_in_2",
+ "type": "data"
+ },
+ {
+ "fromPort": "model_refdata_prep_out_1",
+ "toPort": "Output_in_3",
+ "type": "data"
+ },
+ {
+ "fromPort": "model_refdata_prep_out_2",
+ "toPort": "Output_in_4",
+ "type": "data"
+ },
+ {
+ "fromPort": "model_refdata_prep_out_3",
+ "toPort": "Output_in_5",
+ "type": "data"
+ }
+ ]
+ },
+ "image": "iVBORw0KGgoAAAANSUhEUgAAA3UAAAHSCAYAAABLiOJfAACAAElEQVR42uy9aVxV97n276v/c3o+\r\n5znt6elp86Q9TZMmKZlspiZmMImJZm5ImsmkJqkm0WgSg1OUOIMTzjgFnHBCURRFRUUFFRVBRWSe\r\nZ1EZRMEBZQPX/zettX5r7YVJUzVG7hffz97AZoPbBaxrXfd9XR3Ky4tBEARBEARBEARB/DTpQC8C\r\nQRAEQRAEQRAEiTqCIAiCIAiCIAiCRB1BEARBEARBEARBoo4gCIIgCIIgCIJEHUEQBEEQBEEQBEGi\r\njiAIgiAIgiAIgiBRRxAEQRAEQRAEQZCoIwiCIAiCIAiCIFFHEARBEARBEARBkKgjCIIgCIIgCIIg\r\nSNQRBEEQBEEQBEGQqCMIgiAIgiAIgiBI1BEEQRAEQRAEQRAk6giCIAiCIAiCIAgSdQRBEARBEARB\r\nECTqCIIgCIIgCIIgCBJ1BEEQBEEQBEEQBIk6giAIgiAIgiAIgkQdQRAEQRAEQRAEiTqCIAiCIAiC\r\nIAiCRB1BEMS1pbi4CFFRUZgyZQrGjh2LMWPGEO2OsRg3MQiLly1GRkYq/VwQBEEQJOoIgiB+KlRU\r\nlIuT+p1xcag7U4+m5lYGBBc9Cna/kd2eb5KcuwScVdRftDjDON0I1F0ATjFqzyvY/Wp2W3VOcpJx\r\n4qzkeIOkknGMUVEPlJ+RlDFKFSWngeI6BrstYreFpyT5Gnm1QG4NkMPIZmRVSzIZGVVA+klJGuPo\r\nCSCVcYRzXN6msNtDlZKDjORjkiTGgQogsZzBbvez232cMmAvI0GxpxTYXQLsUsQXA3GKnUXADsX2\r\nQiCWsY2xtcBiC2NzPiMP2MSIzrXYkAOsZ0Qx1mVL1jIisyRrOJlABGNVhmRlOhCuWJEGLFcsOwos\r\nVSxJBcIYi4+0Yn5iPWas3of
AceOQlnaEfj4IgiAIEnUEQRA/BYduwoQJyMjMQnML4FFwQXep2RJz\r\nnAu6qGuSgq6BibgGJezONEpBZ4i6ukZL2NUoqs9Z4s4QdRxD0B2rlwhhV69E3WmJm6grUORrYs4Q\r\ndIaoy6ySmKKuyi7qUpWo44LuMBNyhx3CLumYBRd0pqhTgm6vQ9DtLtVEXYkm6oo1UVekRJ0h5piQ\r\ni1Fijou6TUrUbVTCboNivSbs1mZZGIJutSIiwxJ2pqhL10RdmiXolhw1RB2wSDFrc5YQ+uTYEQRB\r\nECTqCIIgrnP4yOXevfvQ0gpT1BmC7pLm1AlRpwm6c8qta7ikiTpN2AlRd8Fy6ZyC7qTm1h1X2Jw6\r\nTdQZws4QdULQKQqcLl2tEnXVdqfOKeiEqDupiTrl0rXp1FVIp85w6/aXuwi7UnenLt7h0sUWWugO\r\nXYwm7DY5nDrDpROCLlsinLoszakzBJ3DqVuZYTl1K5SgM+CCzhR1mrBbmAKErFqPFSuW088JQRAE\r\nQaKOIAjiembq1Kk4faYezVzUtSpRp/ASdZqwM0YvGxzjl6c1t+6UMYJ5QRN2hqg7KzHGLyuN8Uun\r\nS6c5dcWn23bp8hQ5ulunjV6a45eaS3dUc+lsTp2LqEs+5i3qnOOXlx29LHYZvSyQcJfOwHDqONyl\r\n2/g9xy/XKFY7hJ0QdZpTZ7h1y5yjlwoh6BQL9lcjKGgS/ZwQBEEQJOoIgiCuZ3goSktrq3DpdKeO\r\nizou5i41Wy7dBW2fznX8Ut+p00XdeUvQ6Xt15j7dWTV6qRD7dG24dIZTZwg73aXTnbocl306XdQ5\r\nnTrDpbM5dccsYWc4dcbopSHqDJduT6mFzaUrsQs63anT9+mM8UtzBFMJOnP80unU5VhOHRd23KUz\r\nhB0fvdTdOrd9Ouf4JXfodJeOi7rQQ61iBHPjxg04cuQQ/bwQBEEQJOoIgiCu
R/hJOx+9bGm19uls\r\nO3WO8Utjr+6c7tZdbGOnzm2fzhi9PGsPStFdOiMoxWufTnfq6jSnztipc4SkmDt1DmGXdtLFrVPC\r\nztinO6hEnblPV2Hfp9tfbt+ns+3Ufdc+ne7UFdrHLw2XbpNLUIq+TxelXDo9KMVw6JyCzmuf7qj3\r\nPl1YqrVPJ1y6FAk/PpYuXSLYvTuOfmYIgiAIEnVE+wmeWEfR8BTv/hMTdc0OUWfbqWtWo5ce+07d\r\n2UuNKM4vxdHsQmTkV6LgRKOrS1d7vhHZOYU4mFGIlJxK5J1stPbpXEYvbaJOT748bbl0RXXW6KUx\r\nfskFnYHYqau279TJvToPdu5NwfItKdhecpnRy2MSPfnygCbo9H06vkuXoIWkcOKdok4TdG7Jl7ad\r\nOj0oRRu93JBj7dJ5jV5meou6lRn25MsVhkunOXVh2vjlIi0oxU3UccixIwiCIEjUETc8zmj4S+xM\r\nWT85bnQJnDD2khocO0nO5MDqc1ocvFtqoEvAhO5weIVL1Lq4G9XuEfBuO0gp2omwvn+U5Ih/d46p\r\nuToabpHvLumAekKg22iaLUAi2wqPWKPSAI2xNOfJrp4GuPSoMY7Wivn7b/x4d92pM3fqmu1OnVvy\r\nZcqmEDzVoQM6OPlrGMovWJUGBzYE40m3x70ahsLL1RnUN2DaK87P64j3/MORcFzVGbgFpTgSMJ3J\r\nl2kn6zBAPV+/mDpZZ3DC/XgWyZcVimP28Usu6Izj2u7UNWBoN/n8vddUak5dAwbz93cKQXSRd1CK\r\nPoJ5ueTLtly6NVneISm6Uxfuknyp79Tpwk6MX7Yh6vgoJv2uJwiCIEjUETe0Q+cWDa+Lurb2krz2\r\nkS44nQ4p7Fw7vs46YuD1sTXlcBjCrlALmBCi7pQ9XEKPgM9wiYB3Swrk42rGqFpbfV6GsEtoI/rd\r\nEHR8RM0Uc204GbYQi
Tb2jfRUQD1A4nIx7849I/0kd/YNHO9uOnX66GWLS51BkyHqPNg+wdcUWj0n\r\nhGNbQhK2bo3G3Kn+eGdIJCrEBQkPYsZbj+szJRIbdyVhY0w0Zk72x5uDIr1Fne04bsDUV6SQGzgj\r\nHOPH+sFHPVenMUnmsZzvsktn26fzqjPwIDIyGlMXRCMq1+Pt1B23O3VJl+uoK/dg6sAe4nscGeeR\r\nx3UpE3XPGyK0C6YeMo5vS9RtMI5vdVybx7YekpJrD0lZrx3jrh11mS4hKRnf3VFnCroj38+pCw+n\r\nNEyCIAiCRB1xA6NHw1+u68s+vmZPEDQi4esc5c1ecfBupc3a6JpXwMRpe7hEQRvhEsYeUma1091Q\r\nTt1Jl04vbVxNTwm0ORrGiJrDpYvXXTrHiJru0m39rrh3x76Rq1PnkghopAGaMe9eZczWSe6NGu/u\r\nFHVOl865T1dfGGkKtaCEamufTq8zYFTnWY8bv7vOFpIiki/PqSqDBu86A+k4G6LOF9tq5DG8Y24P\r\n+ZxPhiClrgGz/Xrg0bcDsHR7NN69m73/7TAcZo/NKMjBaPaxO9XXf+QtP8zeUamO50bMHemHV970\r\nw8wDjeICxaHMFAz+1Nd0A/82PBpxep1BVg5GDOqNh+6yxNq4+AasmOVnuYg+HfFkv0hs1Zw6Qadg\r\nrBXHtV3UxeZWYuhXvdHxT+pxf+qC10dEIzzLOL4bMKxPD9z3WgBGhUfief64P3XEI73DEbKvEH3e\r\n6YIOd3bELc/6I2CXxxR14Qkp+OgD69/y3MBozDfGLx0XMMROncJZZ8AF3fzD3qKOQ7/vCYIgCBJ1\r\nxA2LGQ2vUgRtJ8cuBc56emC9S9CEHgdvJgc6xi+Nk2FnFHy5FjDB3TqbqKuzizpjB8k5fpmhuXVt\r\n9Xkddu4etdHl5QyUMPaOdrkESWwvcnfr9HRAfd/I2DX6vv1dxvil4W
Isb2P80ivm/QaNd+cn7eKY\r\nbXVxlxV6QErOJn8pGJ4ORoWj0kAPSUmLVo97KhgFjhHiky4jxJUNzn26BkxRom4TO57yS9Ix7GXl\r\n1E1MYcdwAwJe1sTTk13w6IfhOFyRjr+q9z37VRhCQ4JMcTdgSzXSTjZg5Ivy7a+31yG1MAUvq49/\r\nNica33zaRdx/aGyKFHVF6Xjd+Bov+GP4rHB88vfeGL29ARsiw/Cg+tgD7wdg4LwUxDFR97USdbep\r\nj90/NIkd2412py4rBc8ycfjZ9GhMWRmNdzrJx/59ZbUavWxAv+esf999z/naR1Ef8cW96v49w1Kk\r\nG52cgs7qfW8HRePjD+S/5e6hKd6C7qi9dJwf5wsdISkk6giCIAgSdUS7g4eiNLe0tjl6aYRNnG9y\r\nSQ/UnDrD6eDo/V41bfR7mS5HvRYH7xYFf9pln67Gu6zZa1ytDZeurZLmAy7R727lzLu1yHfb+GVh\r\nGz1eBd/PqXMbTTPH0jIcTl1b7sVRexqgPMG9MePdhahzjl86LkZc0Ng3XYmLv4bghHbs1tZU4uCh\r\ndCRnVYtjd9dU9bhXQ1CiVRoYLt1lky9t45cO7vFDTDmEqJukRF2fsHRzN3R7aG8l8oJxQDnOUVPU\r\n9/JWOA4yURegibqoeerxLwZjQ0EjdsRF4nb+9uMh2M2O57Vz1MfvCsBGxzG9r6wR/mrUctC2RnWx\r\nQjl1r4dj5Y5w8/v+amMhRr2niTqVfLn5aDWW7yvFqM+kAOs4IsV06r5Sou6jsEpxjH/zUUfpPA7a\r\nitXs+F4cFiDe/ot/irhwMT1Ifa/PBmNmciNC1kXi9/ztv4RgoV5n4Ei+dIakmE5dCok6giAIgkQd\r\n0c5wRsM3tbWbpAk7Q9TVO0bYnDt1ehy8Lux0QaeHpJQ6Ri+L1dilc5/OGQHvlRSoxb+35dQdcuzT\r\ncRJdCprb2qd
rKyHQmQ74fZIBbeOXjp061306t94u3b1wRLzfiPHubuOXl9oYv+THbGGsFBId7gtC\r\nsXbsHjsQLN9/bzCK2HGbtUU97t4AZDiCfk64lY6r49jqp2vAlJfVTt3ccMxcEIkV7MDINo7lOkPU\r\n+WLTMWuMODZECps7+0QjXQX+JO8Jkd/LEyHYx0TdWF3Uze3tLRwFAdhcYYm62z+JRkK5MySlwRR1\r\n/TfXqWNaOXVMvG1lx/TCcT3sz9tVjV9mFeLjrh29vm6n4SmmU9dfiLoemJ4mj++ZE+Rz9dnQII7x\r\n5etDTFG3Whd1Lv+WWY7j3CskxSHoyKkjCIIgSNQR7VrU6WNsbqLuvBaUYvV8NaIwrxSp7EQvLa8S\r\neccbvUYv5QlxIzKzC3EgrRAHsyqRzR5nE3Vu3V51LsmXp6yTYN2pa6uo2TZ+6RB0tuRLlRQoAiXK\r\nHTt1uqjTBJ3u1DnLmWNdypk3t9HfZYt6z3J36SKcLp1y6nRBp4ekmCNpN3C8u3Hc6sesU9jpFyPq\r\nC6NNsdBvaY4p6mqOhpkOXhk7bquKrMd9GJZuKx2/3PiwPn5p7NRtrZHHsj5CXHjKEnXry6wx4phZ\r\n1t7dQXU8b/m2tynqDrQl6u4KwJZKe0cdP6YjpqvnuytIOIT8gsW+ckvUDVaibiB36kq09MvHQhAt\r\nLlbUwU/fsesmRd23gdI9vPUf0djEju+5I+TbnQLSHU6dL6Ydlsf4jNHye+m1tk440W2KujsDME8b\r\nMTaO9cslX+oddeTUEQRBECTqCHLqlOuhCzpzL8lF0B3aGGLuwTij4Uu14uZ964PxhNvjXglD3uXq\r\nDE4YO0G+iC6zRN2RBHlC+NzUlO+sM3Bz6g47ipqTXdIv95c34Bt10ts3stIavyy1TnxjlEvXVpWB\r\nkXy52Zl86ezvukxIynclXy5vY59u0WWcuhsl3t0cv2xtI7HV
WWfAjlk9/bLzl8HYmJCCtbNVaMjT\r\nIcKp4xclNo+zHvdEryAsi0nA2vXRmDyihxjLzHE4dV47dS9bO3VihNjWUcdE3Uvy41Gl2n5oQRIe\r\nUV/zgylbsXpjOF5Vb3+8qhRHNVE3JLYORwpS8Iz6+MM9gjArKgHBoWHozu5HsGMxKTMJD6mP3/53\r\n9vHoJARNC8a0hAYm6hox6g35sSf7BWPymhzElVpO3WYjAOhQAu43g1OUqAtQYrFrAAIXhaCj+vgf\r\nXgtBaAo/vg2njom6FHlszxijibosTdQNk6IuIjkFD6vnufvtIAxdkoCh08Lw4ltBCDrovVMXluq9\r\nO7qIduoIgiAIEnVEexd1tp6vFofToYVNiDqDSx5s006O/zE+HFv2JCFmSzRmT/XH20MiUSqcOg82\r\naifHvSdHYkN8EjZsjsb0IH/8bVCkTdTpdQYiJOV4CroZoq7cGr9MNUTdeLuo0+sMMtzGLy+zU+fs\r\np+Oizl+Ld5+RYnTTKVGnnfjucBm95Nj66fKtsUu9w8stJGXtZfbp3GLe2+rtWngZUXcjxLvbjlvH\r\nPp2+U2ffBfXgwLog14sR93wcLnrqpNPsQWIbPXUvDopGicsIsXUcG05dDy9RJ8eIDaeuhxB1ei3H\r\noYNxeOcJe7/dgKU56li2O3X8IkViagJ6vuAchfRDeJF0nuP3xuHdx+zf/5DYBrFXtykmDA+Y7w/C\r\nRuPY7haCmBIrBCgyIsgcv1zP9+mSk8yAFv799ZwYZAq7f6ypE+OXX6nxSy7q1muirnekcuo2KFE3\r\nOsU8zpfFJ8D3We9/y4SD7oFAzv1RZ1gKiTqCIAiCRB3RLp26y9UZWF1fwOkCK/J90p5qsUvHd+qc\r\ndQYncq3HjdtVZ4uDd6YGutUZlJxIga/DqeOYom5CiqwyYIIuaU80Pn2ri/n17nzCHxtKZVDK4cwU\r\nDOntH
fsuBV0DJnzRAw/9LQCzN0bjdR79/kYYtmtOneCxYGwo0Zw6Q9TlVcLfrzfu9zHi4bvgjRHR\r\niMgxRi/Z83zWAx1fC8DY8Ei8qOLdH+0TjgWJhfiMx7uzt295zh/jdntMp27V3hT0/NAe777AZSxN\r\n7+1yqzNYeAOf4Brpl14jw/rFCMcFCSPcp4E9qPJENXKKK5FTXoeK0x5x/Jr9iub4cCOyCyuRVlCJ\r\noyXVKDzDxy89KD7egAJGPiNPkcsO6IKTHvM4NvdCT1uCTt8NNceItdAfw3FOzq/D/rw6MSqcwZ73\r\ngDiWS9Hvbnk8zDjksTnP+wvqEJddh91FHst51hJdd2bUYVtGA3YVy5HiveZIcSM2p9Vha55HjBYb\r\nNR26A+2+K+rBusMNWJ8tL1pEp9Yh4kgj1ushQC77om2lu+oddUuT6rBgXx0WHvR4BQJ5jRq77I9y\r\nl46cOoIgCIJEHdE+nToVDe/m1Dn36bK1aPgyLfnSVmfATohTN1jR8HlacqCto67BGlsTQSla8Th3\r\n6gxRt6HM2qdL2WM5dULUlaebY2qfz4vDklXh+Lh3ENbzE2E99n2uFfv+cECK2j1qwLAXdPHWBQ/+\r\nPRzbtSCJPxrR7/5J2FXSaB9Ry0lB1w5d0G96NKZHRKO7inf/YFW1LGdmou6LrpeJd3/Uine/95sU\r\necJ70Ip3fycoGp8Y8e7DUixBl265F24x71zM6cERN6qoa2l1CUnRnbom+7FrJLfWX3SvM6jT6jhq\r\nnSE/ihMnknCXa6gH45sk02k201s1l05PcTW7FmvsKa7OUeKkHUGOr+OPGM11tpWOu4wTuyW6GuPE\r\nRvjPLkeia1tVHYaw21LgcKLzvEOAvqt4XIwYZ3mPGK90XLxoc8z4iFbb4QhJoZ06giAIgkQd0W5F\r\nXVvJl7YTY8beaVY0fKUm6qqrK5F0MB1J7GyUnxTHT7
Gi4QvPeYs6s8rAGL10Jl+e8BZ1nBTH+GVW\r\nOe/NMnaRorElq9EcvVyvxb5HFzRipyP2/SBTliOVqPsoNF0GpYhACeXUvRGOyDgr3n3g5kKMeV/u\r\n1G3Wki+3pldjVWIpxva14t3lTl0DBihR13NppTjpHa7i3R8dvBXr2InvEhXv/ogSdcFTrHj34ORG\r\nhEapePdHQrCoreRLlx0j3bm4UUVdq7ZT5ywe9xobbqOKQ6/jMAXd5eo4zjYiNbsUB7NKkaxIyizF\r\nAcbB0kbbhQkjJEUP+9EDf/K0wJ82Q39KSxE8Mxj9vg6A32R2fBd6jxO7pblernfRKex2acLO6dRt\r\n18J/jKqOrW2IOq+dUceI8VoNM+FV72F0jBivMC5cOFy6JS7HOqVfEgRBECTqCBJ1jrAJPRLeVjzO\r\nTobzt1nR8EVa8Xh5ohUNz0ub02OsaPijbQg606U7Ywk7M/mynLtgUtRFak5dekKY5dSpk+BNiwLs\r\nbsaLAYhkJ5hml5dLVHqMGr8c8YL8GisKLUdjn+HUMfG2k530LpngiHfvppy67EJ82s073v0xJupk\r\nP50h6npgZro82Z2lnqtvdIMYS1uh9osMUTfjMvHus9O8Q1L03q4wzbm40ZMAhahrYepLcB6tzewA\r\nE7ADq7kerR52MHnYwdRcx+6zg8dTg9amasZJxQm0XjrOqGQcQ+vFCnbL/vMZrRdLGSWMYkljoeRC\r\nHvtyuew2h5HNvmwWWs9nClrOp7PbNEHLuVTGEbQKUtBy9hBaGS1nD6KlIYmRKKnfJ2nYy273KHaj\r\n5cwuRjwjjrGTsYOxHS2nY9k/Zyu75Wxh9zczNqGlbiOaT0Wj5dQGQfOpKDTXrmOsZW+vZbdr0FK7\r\nGs01EYxVjJWMcDRXr2AsZyxDc9USRhi7z6haxFioWIDmk6GKb+E5MY8xF80Mz/HZjFns/ix2O5Mx\r\
nA83Hp8NTOY0xlTEFzZWT4TkWxJjEmAhPxXjFOEaAYiyaysfAUz6aMQqeshGM4YxvFMMYQ+Ep/RpN\r\nJUPQVDoYnpJB7P5AxgB2fwCair9i9Gf3+7PbL0jUEQRBECTqiPa7U2c4dRebvXu+DKfjdIE9Gt4Y\r\nX6tKtaLheWnzCS1C/oNF6WYUvBkw4TZ6aeuoq4TfPVYwhCHqdoXJtMJH1fil2VFXWYeojeF4RX3N\r\nv4xLsZy6uwKwzTX50hJ1YTl6R51y6njKpdg9qsPA571F3XwVBHNrT+mgfKvi3R8LSDdFnV9X+fwz\r\nj0gXY9ZYKeo+XlcnXAxT1PmnCPdi5mQr3v3bTK10PMOefGk4GEu+o6PuRhZ1TGkxYXdeiDqmopiw\r\nMwQdF3On2S0TdE21AkPUoalKirpLJ9h9S9ThEhN1F5mgu1QGz/kS1J8qwqmqQtQKCiQn89kt42Se\r\nRi4jR3Iim90yTmQpMhkZFsfT2S3jeBrjqCJV44igpjKF3TIqD7P7h9gt5yC7f5DdJgtqjiWx2yR2\r\newC1gkR2P5Hd7kdNxX52u4/dcvYqEhh7UMuoqdiNmvLd7D6/3cWIV8RJynayW0bZDsV2RaxiG2Or\r\npHSLRoxis2ITako2akRLStfjdOkKXCxnYq98LIMJugol6MpHoomLunIp6ppK/RlS1DUxUecRDGZi\r\nbhC7ZcKu2I/d/4qJOS7qvoSH0VT0OYk6giAIgkQd0f5EnVskvNtOkuymgy39kkfDb9jDBIkRDf9U\r\niHDqeL/XxkB7NPySzQlYExWNScOZsHklBJm20mZrZM3YQ4oYZoSf9MC09SlYsyYEz6nnG7OnQTp1\r\n5en44kN/TF+XhC3JSfhcpQe+tbAQqYX22PfZ6xMwa34Y3mP31xQ5RF2uPqZmOXVbjRG1wwlWWmCn\r\nEGwq4qLOincfvzgEf1Yfv/W1ECxKVaJOxbvP
SPEWdXwkLVxz6iLVTt1fjETGt4MwbGkChk0Pw0tv\r\nBWHKoe8OSXF21N3I45e6S9eqXLpWJurQfEYIOghOsfu1mlPHRN2lk0zQGU6dcum4oLtYhrrqYhQV\r\nFqKQuAYwUVwSKUVduSXqPOUjmLAznDp/Jt4MUTfEEnQCh0tXLF06cuoIgiAIEnVEu92pEyEpl0m+\r\n1Dvq6pnqS2wjGv7uXuHCqasWeNrsqXthUDQKtX4vW0iKKeyqMWeYY/SxQ0cMXp5jxsBnV6TjHcdz\r\nd+kdhq0VcvfoAI99f9E99t0SdT2wOMdw6aRTJ0Td81LUGaXj69cEmU7dJtHjlWQ6g/z7+jjIinfv\r\nFVmnOXU9vETdZ8qpC49Wom50irlntGJXAl53iXefdMg7JOW7Oupu7PHL816jl5aoOy1EnRy9rJVi\r\njoG2Ri+ZqKurKSah9SNQW7KmjdFL5dKVSpdOirohttHLphI/F1FHTh1BEARBoo5ox07dZZMvmyyn\r\nzgyaYA+oOFGN7KJKZJfVoazOY8XBq+RAGTLRiMz8SqQyjhRXI7+O79V5UFjZgBxG9jFJFiOzgr3v\r\nuEcrawZ7TB32ZVUiIbMah0/Aq3ScB0ocLmpAMiOp1IOjLv10iQV1iFex72Y/XYUkUQVKGDt1RpCE\r\nVTpuCTtnOuAO9nzRKQ3YlCvDJGLS6rDmaCM2XiYZ0AyQyNE66rQACSPifVlyHRbur8Piwx6vRMBl\r\nLh11zjTA+Tf6+KVy6vjoJYRbJwWdHL08pQk6++glNFEHLuouVcBzvuyGdOiSYyMwPSgI0+csRnxK\r\n7nXr2F0sm4CmMunS8dHLJsOlK5OiTo5dDmEibrBy6wYqp87PHL1sKpIunYdEHUEQBEGijmiXO3UO\r\nQWdz6jyWqDtn9HyZos5eZ6CnBlYrjPTAEwpzn67yMtHw/klmamCbEfA1Vum4kRaYftIqHT9qi
Dqt\r\nz8u+T2fv8jL36cqcXV4y9t0Z/W5Gvhdake9GMqCRDqgXjxvpgHqPlyHo9P4ut6h3MxFQC0kRVQap\r\n3v10IiRFK2FecEOLOmP0skELSDktAlKkoDuldurYAeJRo5dOp065dPV1JddczKTFR8DPt5N27Pug\r\na9eeWJyQdWWeP0Y5y526wofdjozei9C+vug7J/a6E3anS5YKp65JOXVNmlPXJESdFHSdz/8OO4+/\r\n7erSGft0TcX9SNQRBEEQJOqI9hmUIhIwmy/fUWeNX1qR8KcdpeOGS1d1zi7ojG66SpV+WVHfiMOZ\r\npUjMkOxn7EsvxV5GYnGjLQbeCEnRi5qzFZlaBHx6lRJ0Lk6dEfuuR78nu3R57Su3BJ0h6ozYd73L\r\na6ejy0svZ5YhKZZTt1kJug2aS6eXMq9Vom6NVshsCDpbSIpeZ+Bw6cK00ctFerz7DS7q0Gy4dFLU\r\nOUcvrX26tl06nnp5qvrajl6mrB1pCrmRoRGIXrscQSP7CvHltzblinyN6JFcMA5Fsvm+NAT6dIDP\r\n0OjrTtTViN26kWZAiuHSCUFXZom6DpfYa3a2Azqf+i12VrwlQlKaxNjll8ql+4IJOxJ1BEEQBIk6\r\noh2KulZ1YmwfYZNhE8YIm3d6oPdOEg+akFHwnCIVBZ/PyJOoKPjW81nsfDxD0Ho+HS3njooY+FYe\r\nBX82hd0/zO4flhHwZ5MZSWg9e0BFwe/XIuB3M3axb9WKf28+zaPfGWdiZfR73RZGDLvP0OLfm0+t\r\nV0SJ6Pfm2ki0MJprVovY9xYR/e6Ifa9eyuDR74vhOali308uYPfnq8j3EBH53izgse8q8v14sMCK\r\nfJ8Kz7HJiiAZ9X5sgkREvQcqxrqGSBipgB6vfaPBWsy7n3mye8Pu1PHj1ky9bBA1Bq2e0yok5ZQc\r\nu3RWGVxy7NOp1Mvaqmsp6hIx1EcKuj
mxDlcuNwtZuVfm68QGdkUHn0Bk/QTGRGuK15ounVFlYNun\r\nK5HHNxd0HeoZtYyqDniq4rfYUfKGGr/8XAi6pqK+JOoIgiAIEnVE+xN1XmETnjNmJLyRHmgmB4r0\r\nwOMqDl4KOhkHX2b1ezUWCVHXdK4A9bUFOCVi4PMdMfBGFLwzBj7rOyLgj9oj4LX4d8khFf1+EDXH\r\nZPx77bEkEQFvxL/XHNsvot9l/Ps+Ff8uY99rVfS7oHy3in/XY9+16Hcj9r3cGfu+TVKqx77rce+b\r\nNDbgTNkqXCyfxkTdeIkQdAGyu6tCijqxb2SMpnFBJ5wMI+Z9iJUIWDpQjKUZoo6Ppd2wTl3zOTP1\r\nEto+nenSqSoDY/QSLlUGxsWIaynqsmLlWGTXkd/hmKXFYmR3azzTp/tIxKZZrtsc9rGeQcuxeKSv\r\n5fotTxAfjwnqbn0eo3tQjPk53afHmF8jNzlahflwumLoyL7o1KkvYrOuvagz9umcVQZC2IldukGW\r\noKtmHGOUMwqZuCu4GTsKXxf7dOTUEQRBECTqiHYr6gzHo7XZIej4ThI/MVZuB5wunRpf4/1eemlz\r\nXXUhRcP/0/Hu60xBJ/q7hKAbZbl0wsUYbh9NU6LO7tINsHV33bjjl+dsqZfSpXMPSfHqprtoP3Zr\r\nq4qu3S5dTKAQUYExaZd5XAL8hNDqjuUxCUiIXYzuPjIFNSFXirogQ4wxEbZ47XIM7So/nsi/RmIM\r\nAnv6sLd7so+tRUx8ihy/7MREnikmE9BXfY3FsQmIXzsHXZW4W5v2Yzl1yoUWhePDzMJxo8rAcOh0\r\nQdchn5HFSO+AzmlM3OW+RqKOIH4gxcWFWLduHaZMmYKxY8eKnyXi+mX06DEYyf6fZoXMQkZGKh3D\r\nJOoIGr80HDrv0UuruNlw6U54OXWG29HSWGwKOhJpPzTefa0l6rTRS3nCO0JLBfS3jV4
2iZj3AV6j\r\nlzdqZ5ch6uSFCM2pUxcjDEGHpmp7lUGT9+ildOqunajLUgEmQZcRdYbwGxmdpn2e8T4l0LiI6xpo\r\n7szFBnHHrpMpyLzHL6Wo66REXdtfoxOifwRRp1cZ6BctjCoDIeq4oKtklGmCLlMKug6HmahLZaIu\r\nR4q6Xr16onfv3vjyyy/x9ddD2PtGsWN/MfbvT6Df/QThSpn42dm+YyeqamrRcOGi4Mz5RtSdvYBT\r\nZ8+jpuE8qs6cw4nTZ3G8rgHHTtWjvOYMympOo7iqDkUn65B/vBa5lTXIrqhGZnkVMspO4mjJCaSW\r\nHMeR4uM4VHgMyQUVSMqvQGJeOfbllGFvTin2ZJVgV2YxdqYXYTv7HbQtNR9bjuQhJiUPmw7lIvpQ\r\nDjYczEFUUhbWHshEZGImIvZnYNXedITvTcPyPUexbHcqwuKPYFFcCubvOISQ7QfxbexBzN2ahDmM\r\nWVsOYObmREzftB/TNu7DlOi9CNqQgEnrEzB+3W6MW7sbY9fEY/TqOIxctRPDV+6Af/h2DF0ei6+X\r\nb8OQZdswcMlW+IVtwVeLY/Dlos34fOEm9FuwEZ+FRuOTbzfg43nr0XNuFD6avQ4fzFqLHsGReH/m\r\nGnSfsRrvTl+Nt6euwptTVuKNySvhGxSO1yatwKsTl+Pl8cvwQuASPB+wBF3HhqHL6EV4etRCPDVy\r\nIZ4csQCPD5+Px76Zj0eHheAvQ7/Fw19/iweHzEWnIbPwpv9kjGHiLi3tCB3HJOqI9u3U8d0kw/Gw\r\ngibMvSRxclylToq10mZtfM1w6Tznin6SDt31E/3O492D5D5dxRg0mU7diMuc8MrRNE/JQC0RkDt1\r\n/UXM+427U6ePC1v7dHJc2HExwhGS4jx2r6lTFy3F1NDLBKKkKXEVkWK9Lzch1C7quEALtEYpY7iI\r\n69DVFGQxgZ2EqEu7rKjzwfLE
XG009McTdUbhuD56aRsv5uOXhkNXZBd0TwmHzlfs0zUVfSaOj9mz\r\nZ2Hq1CmYMGE8Ro4cgZ49P0Lnzk/i5ptvxs9//p94+umnMHToEMTGxtDfAoIcuuIi9rMyAWnpGWi8\r\n5MH5i004d/GSEHX15y/i9LlG1DZIUVdd7y3qDEFXcKIWeUzQ5RyrRvYxQ9RVIa30JFKZoEthHC6q\r\nxEEl6g4oUccF3e7MEsRlFGEH+/2z/WgBYhlbjuRLUXeYibqDXNRlIyo5W4o6xmom6lZqgm7JriNY\r\nHJ+ChTsPYwEjlIk6LuzmbUvG7C1K1MUoUceYEr0PQZqgC4jchTFM1I2KYKIuQoq6bxjDVmwXom4w\r\nE3WDlm7FAC7qGFzU9Z0vBV0fIerWo9e8KPScsw4fzVGijvH+zEhL1E2LEKLub4zXmah7dYIUdC8p\r\nUdctIAzPjVmMZxnPjFqEp5iw62yKulA86h8qRd1QLurmoePA2bh3wGy8MGSq+N1Hjh2JOqI9izoV\r\nkGLs0lk9XyoO3ja+dsLV6RCirrEY9aeKKPr9X413L11munSyu2ukOOFtcgRIPHX+f7Hj+Lteo5c2\r\np+4GFnVWsI927Gp7oDBDUqq8BB2M0csfQdTlJoaK46yDb5AmuJzCb6Qa0cxyCC6HqNP28n6YqOPi\r\n0nLq1gb62p7j2jt1lgvtvGjBj3GnQ9c5i4m5/NdF4XiT2qfzfI+glKNH2QnfghB88kkv/OEPfxD4\r\n+w9lJ0NH6e8C0S5ZFxWFhIS9uORpRmOTBxcuNeFs4yXl1F1UTt0F1DBBV3XmLE4yUScEXS136c6g\r\nRIm6whOnkNemU3cCKUzQcafuYMEx4dLtz7W7dPEZ3Kkr1Jw6S9RtPJSD9UzQrRNOXRYi9qdj1T67\r\nS7dkV6oUdXGHhVMXajh125RTFyOduhlC0HGXbq9w6Sas2yNEXaASdbpT9034D
gxdwZ26WAxmgm7g\r\nEsul+0K4dJuEqOsdEo1PL+PUvTdjDd5hgu6tqatcXbqXxi1lom6pFHXCqVOiTjl1T3BRxwQdd+oM\r\nl+7+wXPx50FzcB8Tdff4zUL/8ZOwYsVyOqZJ1BHt16k7a4uDb3U9MT5pjbCJOHij48u+S3eqiqLf\r\n//V493VmQIptn658uNndxd06I979qVO/w46Kt+UundbbxUcvm27QImbp1DXYQlLksVurBfvoaa1t\r\nj15e6/FLTsRQdZHCdySiE5KRlpaCxPhoTPfriSAu2rJi0Z1/vOtIxCSnIS05Ru3MdVchJm2LurXf\r\nU9QV5sajp/jZ6oShQUHoqwWmXHtRFykuWhj7dE2lhkvHhd1gFQQ00BR0nXN/ix0FfzNrDGRAinTp\r\nmor6/NPH/ObN0Xj77bfwi1/8AkOGDEJ+fg79fSDaFVOnTkVtXZ0p6oRTx0UdQ4xfnlOiruG8l0tX\r\nWn1aibpTKGCijo9fCqeOibosRjoTdWmlcvxSunTH7KOX2Zao406dGL88WsBEXQG2pmpOHRN1pkuX\r\naLl04QlS1C31cuqYqGPCToq6ZCHqgpmok6OXStQxQTcxao8QdYFrdwmnbqzm1I1gwo6PXw5Tos50\r\n6YzRSybo+imnrnfIBmv8Ujl1HzJhZ4g6y6Vbhb8pUffXiStMp+5FIeq4U7fEcupGW6KOu3SdDJfu\r\na+nS3c8EXceBTNQNnI27mah7Ysh0BAVNomOaRB3RfnfqGrxSL62OL3ZyfOmkd42BS0BKS2MROzmm\r\n6Pd//QQ3Sjl1o0yXzqOVMRsuhjPevXP5b7Gz9E2v3q4b16nTA1LqzNRLeLl0bqmXFbZj91qLusJC\r\ndoIy3U86dja6mg50VkKECkdR+PTEctOd9hZ1cqfOF9FZmsjrdBlRx0mJwcievujk4wPfoXOwPKin\r\nbS/vWlHNRJ1H3xfVRi
/l+OVAIeqeKmBirvBN+4ULs8qgnxB1HjV++UOO+cTEvejW7Tncc8/dyMvL\r\nor8RRLuBh6I0NTd7O3VK1EmX7rxw6UxRV1uPCkaZMX5ZJccv9Z26rIoqF5dO7dPlltmcut1ZJZao\r\nU04dF3V8n87u0ql9un0Op25PKsKUqDN26rioM/fpYrz36SYrp06MX67bbYq60avjpVPHMF06sU+3\r\nxbZP98XCzaZTZ4xf6k6dzaWbLl06a59uhd2pYzyvRJ2xU8dHL6VLJ0Wdvk/3gObU8fHLexh3fTVT\r\n/P7buHEDjhw5RMc2iTqi/Ym6erPjyxi9hFdp80lt9LLSu8qgsUSMX15JUddeo9+lqNMDUoabIRL6\r\nrlFb8e6d2YnvzsI3zHG0G1nUidFLEZBy2tarqIekOF06OMeGfxRRZ1ycSGNCIhHJyclITslyFX9p\r\naWmC3KsxCppl/1qhPTs4XOtr59Q5u+mMwnHDpZNBQH628WKPuHhhjF4aTt1n//Ix/8gjfxE/64cO\r\nJdHfCaLdnAt4mlukqFM7dUZIir5PV+Xcp6tVTh3DHL/URi9Nl862T2c5dVzUJXCnLts+filcusvt\r\n0xkhKVzUJRzFigT7Tp0cvZQunes+3UZr/FI4dVF7bDt1UtDtUC7ddny9zLlPZ41fip06hjF+2XOO\r\nFHQfztZCUqavtjt1U7TxywnL8coEa/ySu3Ri9FK5dJfbp+OiznDq+PjlXV8F237/7d4dR8c3iTqi\r\nfe3UNZgdX+LEuOlUGyNsulOnToobS8zRS95NV1tVQNHv/7Jrsc62T2crHBejafKE9/vFu/vewOOX\r\n9Wqn7ozp1NlrDKzUS9cqg+tB1P2opGCk+LnwRV8/P/gqV7BvaMI1/16kU2dPdfVoqZdyp46PF/uZ\r\nI8ZNLoLOI0Rd7ytyzP/jHx/i0UcfQUlJAf2tINrFuUATE3Xuo5eaqFP
7dJWnpKjjTh0XdcVq/DLP\r\nNnpZZRu9NJIvpagrt3bq1PildOkK2xy9tJIvs7AmMcOxU+cYvdxhjF4mi9HL2VryJd+nm6o5dROV\r\nU+cMSbFGL7dryZdbhKjrb3PqjORL6dL9wxy99E6+lE4d36kLt+3UWaOXYa6jl/bkyxA89PU8sVP3\r\nABd1g+aI0Usu6P7Uf6bX7z9y7EjUEe1M1JlOnUoP1EubrdRLtUvnclIsCscbC6+sU9dOo99rhKgz\r\ndumM1EtGqdXdJUTdd8S7PyXi3X1VvHsv9OnTB19++QUGDRoo9oaCg6cjMjICBw7sRVlZ0U/wuK1X\r\nxyx3mHWXrto6di/Z9+ng3KdrVLug1UXtskIjMWY5ggJHwo+JOr+hgYiITfmRRo7X2PbppButO3VS\r\n0HmEU/eV5dLx0cvifux+P9Olayq8MqKO/0w8/PBDmDVrBv2tINrFuQB36S6q0ctzWkiK6dTVuydf\r\nSpfO2qdzhqSYyZdFlTanjidfSpeuVHPpjNHLAqvOwMWpW6N26vg+HXfpjH06o85ggVZnIJ26A0LU\r\nBcfo45f7vFy6sS4hKVzUDXE6dUrUWS7dhsuEpEQKp46PXxpOHR+/tFw6Q9Qt1UYvF5t1BsKp+8bh\r\n1H39ratL59M/2Ov3Hx/FpGOcRB3RbsYvXQrHm+yjl3aXzrvKQDh1QtQVUPT7FRJ1+uil7YRXpQK2\r\nFe8uHbrX1Y6RTAIMDp4p4t0nTpwgdif69fsMr732V3HSyiPe//3f/x333/9nvPvuOxg9eiQ2bVqP\r\n4uL863r/w1ll4J56eVL1KjoCUi7pFySKUV9LHYk/JqdLFl829dKs6yixBwF5xE5dP+XU9RUhKefz\r\nrtzI8YwZ08SOHf2tINqLqLPVGSinzjZ+KTrqnCEplqjT6wxsISlq/JI7ddylO6CHpJijl5ZTx+sM\r\nuFO32SnqkqRL
Z4ak7LWLOludge7UKVHHnTrp0u1Br/eeZ3/H/4h3Z8czUbfr8k6dEnW8o44Luv5G\r\nSMoCu6gz6gz+oUJS/u4Yv5TJl+GiykCEpPB9uglGSMoiPPjsY+x7+h3u+WKB3alToo4LOunSqZCU\r\nQVZISltOXXg4pWGSqCPakVNXr7l0yu2wOXUntW66CldB18IE3ZUWde01+t3u1BmizgpI4e4FP+H1\r\njnf/LXbkvyFPdIs/V+5F3+91gpuZeRTr1q3BhAnj8NFHH8LHxwc/+9nP0KnToxgw4Cts3Bh1Xbl5\r\nU6ZMxpm6Y6pXsU67IOEdkGKvMvC+INHCRJ3nXOFPsl/xxiAXF0vHtlk43tY+XZNN0FkuXd6+IQgM\r\nDLwioi47Ox3/8R//QSOYRPsRdW51Bir50lk6XpC6FZ+/1FmuN7z4GUYGDsBrLz6JPvMTTafu6JHt\r\nGPrxi2of/S688fVi9nfKSL7MRmDv1/HAqwMwK2oF3n/ERzzu8bcCsTjJ2qnbsGMdPnnvOfUcd6Lb\r\n57OxWJSOc1F3AP17vIy7uvXF1/Nm4unb+GTOaMzatgUff/Q33HmrWr+49SE83XsyAjbIfrohg96x\r\nQqhuuQ13/W0sRjJRN2phKF58+Qn1sdvwwHsB8FsRawo6fZ/uc1udwQZ8PG0OnnjhafyXet6bHn4V\r\nzwyZL5Mvg2bhngcfxv/c44vnJsh+umf//ib++7a7cOcHU4Woe/LtF6zv6Te/w6+e7IcnRi3U9ulC\r\nvPbpZEjKLOHUcWHnJupuhJULEnUE8X2dOs8Z86TY2kmqskImhNNxXEsNdBu9LLrioq69Rr/LImbp\r\n0jXpiYCOAAlbvHvhm2IszTsR8IeHRmRlpWH58iXo27cP7rzzDvzXf/0X3nzzDSxZsuhHP8ldtSoc\r\ncTu3mN10rUrQWWPDJ9soHNePX2MfVB67p6oLSGD9CNQWr7Inu
/LRy5IhosrA6mC0BJ1V12FUGajR\r\ny8I+wqlbsmCiiGe/Uic1XNRxcUd/L4j2Mn6pF4/rVQbGPh0XdRWlCXhDCZDHvpqO+TP9TUHy6Nid\r\nsng8ZwdeUe/rO3MJ/Hs+Lu4/NGKLSr7MxuDnrITf2571xf3q/stT46RLl7AOz6j3dQ+Yg97dHxH3\r\n7/lqtQpJOYCeT2opwfc/DJ9Xx2H2lhV4pMNDeHvoVAyYMgXdOsqPvzhpsxi9HDHBH380vm63XvAd\r\nPB9jloeio3rf018G4sWX/izu//6DubZ9OjF6uVB11Ik6g43oM2cWblef+/vnv0DXf3yAX6i3/+y3\r\nAO9OnISbxdsP4+nAlfCdtALPvPGQ+Ph/vxogki+f/uQT/FJ9zi8eeh13vDUSTxj9dI59OiP50nDq\r\n7hnQ9vgliToSdUS7cuq0GgN1YmwEpNhHL+U+nT31slidFBeg9UI+ak/mU/T7lXDquKgrN4SdHL20\r\nx7wPRueC32FH0VteZeNmCXNx3yuSBGjAd+/GjQvAgw8+IPq8eJDEtm0xP8pxm5GRKv5dmekHlbt8\r\nyiskxeyn0wWd02Xmx6+6IMGpq8pHUSGJu2vl0NUWR9guXOgXLYzRS+7SeXUwase5MXrJQ1Ji1owR\r\no7kLFiy4Yic1fDSZRB3RnsYv9ZAUPnpplY6fM0Vdyvpv5N/bJybhqEq+3Dz5ZfG+55io4yEpG2d9\r\nIB/TLRDRfFcuJlQKn0cnYqcIScmGvxJ1bwVtFUEpoSNkSnXHr9cLl+7bce/K53j6G8yLP4LFK2bg\r\nFv72gyMRpkRdbyXqXh2zxhGSchBz1m/D+BUb0PsdKaBu771YJV/G4e1H5ee9PmOH2Knr/9Vf5dd6\r\n+HN8zsSb36SR+DV/+67+6C9Kx7digKN43Nip695LuWx3foz3ZsvRy1ffkSm6HR7qjzcnTZTfNxN1\r\nzwbK5M
tn3pCO4G9eDVTJlwtwtzqXubNviLlPx0VdJ1U6/ggvHh9qFY/rO3Xcpbvjyxkk6kjUEe1d\r\n1NmDJnSn7rg1eunq0uknxUzUVeVT9PsVcOpkQMoIlzJmdcKrjaXp4RF2l66vcC+uxi/4ffv2YPDg\r\ngbjppptE/Hto6Lxr7t6lpR3B+PHjsSt+G07XlqLlkhWQYqRe2vbpvI7fUrULahy/BQLP2VzU1+bh\r\nVBUTHSd1ciQnshlZikxFhka65Hga46gilXFEUpkiOc5vDysOKQ4qkgU1x5JQe+yAoOZYIrtNZLf7\r\nBbX8tmIfY68iAbWMmoo9it2oKd/N3sdvdzHiFXGMnZKyHYrtGrGKbYytklLOFsVmjU2Sko2KaMUG\r\nxXpFlKjqqClZJ+oLTpeE4WJZoGv/orlPV2Lt08kLF1/ZjnO5T9cX5/O+QN7+r7EoZII41hcsmO91\r\nvP/QY76oKA//5//8fygtLaS/F8QNfy4gki8vWS6dUTpu7NMZISmVTNRtnfiKupD6DQ7zfrrjtdg2\r\n421T1PHRy2hD1HkxCBvV+KUUdd0Qckj204Wq6qHHhqzH5pRcS9R58TnmqvHLT4SoewYB21KwME7t\r\n022OwhuP3+71efcyUSd36mLx9iPyfa9M3oSAyHh82f/VNr7WB/jMJSRF7tRtEqOX7/R6Xjz2v571\r\nx4dzZEjKO0N7y8+//VO8ETTJFHVdAuVOXZe3pKj79StjVT9diCnqbv90NhN1C2z7dEbxuL5T5wxJ\r\nuZNEHYk6or2PX9qTA91qDLxTL0sc+3TyhPjKO3XtL/pdiLryEVoZsz31sskcSRugYt69HQwzDfAq\r\niToDHqYyb94cEbhyyy2/F8ES11LcccduxYrlCAoKEv9Oon3Cd+j4yKWbQ/evBAXwdNiOHTvS3wqi\r\nXZwLGKOX1j6d5tSpkBTDqdsX1k85dWNx8CQvHc9FwJs
d3EWdzxBss9UZyOTLvdlZGPasEnXJStSN\r\nsESdzam7/Uss1OoM5OglD0lJxKdK1I2OOSKcOt5RN+qrp8Xn/faNqZi1NQnD+jwlRd3ny8T45eQN\r\nsXhdiTrf6dtFSIop6n7/Efqv1Drqljt26pioM6sMVD/dWx8+rZy6PnhfddT5ftjNFHVvauOXXSbx\r\n5Mt5uO9++fV/w0TdC0rU+bTh1BnF49yp06sMnKLuji9I1JGoI2j80pYcWCVF3aUTWuG4m9NRbI6t\r\ntVzIZ7fc3cin6PcrEO/ORV2TVmVgd+oGKfdiQBvuheXS8R2ja/ULfu3a1cK1u/XWWxESMveaH8s8\r\nttnthJ4gfmik99ChQ/DJJ73obwXRbpw6MyTF7KhTTl39OeHUVRpVBgUbrbWIJ15W3a0dbOOX6dnb\r\n0UW97+H3hmN2RBRmzp6Gd9/9BuFHy7A3xxJ1ocky+dJ06r5eb+7UPWq4bK8PwjffLoX/uEC89NoA\r\nTInj/XSJplM3OiZF1BlIUfeS/H4e641+gUNxh3qO//fMEAyL2Iug9TvR/Wn5vrv+9gU+CFiKUctC\r\nzX/TLc99indHTcc7/Qfh4S4fo9dC++il4dIZISmfTJuM/6c+9+7uI/Cq31e41Xi791y8M20O/qTe\r\n/tUDL+GW26zX69emqJuPe9Tu36+efA/3fRQoduqEU+cfKgSd6dINnqNCUuzJl3d+SUEpJOqIdouI\r\nhm86ZasygHDrrG66tqPgi8yQCblTlyfG1mhX6F+Ndw8zu+ncxtKsREA/ayxND0gpthIBz+f2vea/\r\n4FeuXI677vLB448/hh07tl2zY5kXrJKAIdz4oeW7f/zjbYiKiqS/FUT7Gb+86N1Rp7t0pqirPYO0\r\nPSvx+t1ShHTqH4qQQDl++Yhy6nhH3cHkDejV7S7HOOPHWJZWhgTTqXudiTrZURc6Voq6LsPXmx11\r\n
a2JW4M2n7nQ8Rw9M2nlUiDrp1L0sRJ1ZZ7BmMTqbj70dr/l9bgaZvDJlC4I27MWIqcNwm/mYPhi2\r\nJp6Jxpl44uHbHF/rDXy4wD56yZ06sU/HRF0fxqdM2H04NgB/ulP/vFvw54+niyqDt6dGoOv7vubH\r\n/vPJXnjgRTl+efOb4/HCONlR17lPLzM9s0OHt/CoFpJiF3V8n2427hsgQ1K4sPPhO3Xk1JGoI9ov\r\nIhr+VJlw6Wyjl7Yo+ErNpSu17dNZo5f5aGGiju8jUdDEv0IeLpaNM8MjhKgrs7t0QtSVDrSNXpoh\r\nKTwgxYx473NF493/GfgOUkDAaPz3f/83vvzyc7GbdC2O592740jEEDb4MfFDjqVNmzbglltuua6q\r\nPAjiqoq6S8ZOXRPqVZWB1U931lE6fhIxUVuxO6sY2aVVyMyMR5+7pBjpvSJdlY4b/XSV2JeWhbjD\r\nWYjPKFF1BtypK8WeLEdHXVqh6Khzlo6vS8rCyrhELIlNxNJdR82OuuV7HB11cYfNkJS52xIxdU0c\r\npm1S/XRrtmHc6l0IiuZOXQImMSas24HhSzZhRPhO0VHHi8d5P93Xi9bjq9B18FsUo0YvN+HLb9eh\r\n77dr8dncSPSevQafMj4OjsDHs9dZHXVzo/Be0FK8M2kJE3NGP12E6KcTpeMTFuPlMYusjrrxy7Ti\r\n8TA8NzYMz4wOweNfz8JjTMSZpePDHHUGg6RTJ0Sd5tTd/uV0EnUk6oj2yqpVKxC3I0bs01mlzXoc\r\nvLNw3OnSFZiirvVCLiNHBEyQOPuh8e48DXC46qdzOnV6QIq9s8sjxi8/t/V2ea5CvPs/y9Gjh/Hc\r\nc88K5+5aJWVyV4aP2/E9KhI17RP+f8+PgR/q0HGef74bxo4dTX8niHaVfnmurX26+nMOUVcKf7dQ\r\nkcdHYUdxlVU6XnIcR5iwO1xUieSCCnOfToq6M
rN4nCdfckG3LbUAW47kiZAUIeoOcVGXg6jkbKw9\r\nkIk1iZmieJzv1K10FI8bo5eh2w+K0vF525IxZ2uSLB2PScT0TfvFPt2U6H0I2qBEXdQeUTxuCLqR\r\nTNANd+zT8TqDQaEz8CvXEBXGXyebgu6j2TIkxSwdnyFLx9+eFsFE3Uq8MVl21L02aYUQdq+o4nEu\r\n6LoyQddl9GI8M2qhCEnprNcZqJCUh7+2d9QZxeNi9JLGL0nUEe0bMxo+LcncpbPXGLgUjovES5ka\r\n2GKIugt5aFGizhB25Nj9cw4dF3QiIKXcqjHQy5ilQzfIDEjxLmKWo5dGlUFM5NgrHu/+Q5k6NQi/\r\n/OUvERQ0gX7uiOsePjb861//DwoKcuj1INqNqGtuacGlJinszrg4deb4Za0avzy4G/PnzcHIEWMw\r\nZMQEBK/Zg0PHqs3RS8ups4ekyI46Pn5Zqly6YptLZ5SOO506IyQlggk6IyhlmRB0qcKl46JOjF5u\r\nN5y6ZMw2RN3mRMxgom6qCEnZK8Yvx6/bLaoMAiM1URcRJ0TdN+E7MHRFLBN125RTtwGfTluCXlPC\r\n8I/Ji/FR0GL0mLgQ709YiL9PW4OP560Xou4fKvmyh0PUCaeOwUWdb9AKIeq4S/eSw6V7dgwXdYtE\r\nSIpIvnSEpOgddfcql06MXpo7dTR+SaKOaNfIaPhx2BW/FadrCtFiC0ipdN+nc6RetpqCLpuRxchE\r\nU0MG6muycOqkHgHvjIHX49/biID3in6Xse81x5JRe0xGv9eq6PcaR/S7Hvteq2Lfzej3chX7bot8\r\nj9Pgse/OyHcj6n2bink3It951HuMwi3uXY96lzHv1SLifS1OlyzFxbIJTMyNNB06IyCFj156x7w7\r\nertK+psunYx3H4pFIROveLz7lahBuOOO29G79yfIz6eTZeL65cknnyCXjmh/SdjN54Dms4wGtH
rO\r\nsNsztiC1Vk+Nqo0xJnmOWxd+HesZLUZVzEVr597rPOF8BlrOpTPS0HruKLs9wkhh9w+j5exBQevZ\r\nZLQ0HGAkMvajtWEfWuoTGHsYu9m3GI+WM3GC5tM70XJ6B7u/nd3fxu5vZWxBS10Mmus2sduNjGg0\r\nn9qAllPr0Vy7jrGWEclYg+aaCMYqxko0V69gLGf3GdVL0Vy1hBHG7jOqFjEWovnkAnhOhrLbEMa3\r\n8JyYy5iDZobn+Cw0Hw9mzGT3p8NTOY0xFc2VU+A5NpndD2K3E+GpGM8Yxwhk5wABjLHs/hg0lY9m\r\n9zmjVMXRcCsRW13stVYy7OsYJOpI1BHk2FE0PMW7X3VyczPx2mt/xUMPPYj09CP0s0dcdyxYECou\r\nPvC6Dno9iHaVhN1yjgm7Bibk6oWg43VHhqizd9ieNIPUYKZjGxd+5UVfKx27AE1neYhaPk5V5dm7\r\nP0/w7s9syfe+6JtqXfR16fus0bo+Rc9nZZK42Ktf9NUv+NYe22de8NV7Pq1+T0fHZ9lOSfkO925P\r\n40Jvmd7tqV/wjcbpslW4WDFDirpjExjjpagTwo6JuvIxQtA1lY38jiTswepi70Db9A6JOhJ1BEHR\r\n8BTvfs3o27cP/vCHP2Dv3t30M0dcN+TlZeG3v71Z7BrT60G0O1FnuHRM1LV6TjMhd9q9w1ZM82gu\r\nnbPuSK1ncFFXV11AqxguFPGVi9IoKeqEU8cJYIy1HDoxvSNduiazs9a73sgSdDIJm0QdiTqCoGh4\r\nine/powbF4CbbroJe/bE0c8dcV3w3nvv4v33u9NrQbTT8cvLjF6adUcnbXVHcIaoidUMS9CRgLs8\r\np0rX2Ucvy8cwAacEHd+xt4k6f2vPvmSwfc9eS8ImUUeijiBsUDQ8xbtfC4KDp+M3v/kNsrLS6OeO\r\n+FEJD1+Gm2++mY5Foh07dfbRS8Ols5K
xZZhaa5NWeeR06YSwK4LnXCE5dN+3xqh8iuXSVYxRTt1I\r\nJuRGtJGEPUSIOculG6ASsb8SO/Yk6kjUEYSrY0fR8BTvfrXp1u05EQudnLyffu6IH4VDh5Lwq1/9\r\nCpGREfR6EO2SW24pwq6d56zRy2Y+fsmEXZMMSDF36S6dsPfXmsnYJbbRy/raqyWC0hDq5wtfv1Bk\r\neX0sGUHdu2Lo4m0I7euLvnNifxLC7nTpCunUqdHLJjF6Ocq2T6d31hq7dE2OXTojCZtEHYk6giCI\r\nH41hw77GH/94G4WnENec0tJCPProIxg8eCC9HkT7PYnscIlxFk8/Vc/E3WmbU2cbvTT36SodqZcl\r\nVodtYyFOVV09ly4myJd9rz5Ynmx/f1ZskLhAOD3+IAJ9OsBnaPRPQtTVlKwzUy+du3RWErZMvTT2\r\n6QxR552ETaKORB1BEMSPzBdf9MPDDz9E3WDENeXzz/uic+cnhbij14Nov6LuLKOeUcuoYuLuOOJ3\r\nVNnHLrlL56wycHbYip26AtReRVFXmLwcPky8+U63O3ERfj7o4DMUyT+xEUxecWQFpNhTL+0BKUO8\r\nawy0gBTu1HlI1JGoIwiCuB544YXnRVgFvRbEtWDu3Nki7ZIcYoJEnSHoqhnHGOWMQibuSpi4q7RG\r\nL5uOqxoDl106o5uOcVVFXWEWpvt2sAu43Fh0N4VeGuZ074Tu02Osz0mJgV/XDsLJ4y5fYEQi+5wE\r\nDO3qg75z4s3nDe3bFT6+gebzpkQHwqeTHxJyr6aoi1I1BppTV65309mrDJwuHd+lM0Yvm4o+J1FH\r\noo4gCOLHh/fY8Y6w8eMD6fUgriqxsTH45S9/ia1bN9PrQdBJpHLodEHXoUM+I4uRjqc6Z2LXjlJv\r\nl05107UIl67I7KarPZl/Vd2t5OV+QqAFxWZJ8bV2qDaSmYbATh3gM9IYv0xAXy7mmFiL
TU7E8sDu\r\n6rFZTPyx93cKRBp/XNpadFWiLzQxl31eLkL5x7uHIvdqOnXFUVrZuObSlfqb3XQeU9C5VRlYLl1T\r\nMYk6EnUEQRDXCfv3J4iT7S1bNtHrQVwVDh5MFKmroaHz6PUgbmh4miv/XcqP9cDAMejf/wtR2/H8\r\n893QqdOjuO++e3HrrbcqQVfJKNMEXaYQdB06HGaiLh3x24vNXTqrysA5eqlEXdVVTr7MioEvE2A+\r\nfhHibSG+uk5X4SlS1HVSoi4tJlAIwL5zopGYkIiEmDlifHPo2hQkLu8rRFxEGhOGSihyes5JZJ8b\r\nI0Qef9zVHb+Mso9e6vt0YvzSSL0cbHfpVOKl4dJ5mKBrKupLoo5EHUEQxPXDnDnB4kSDl0HT60Fc\r\nSXJyMuDj44Phw/3p9SBuGPjvSp7eyoUbF20PPfQgfv7zn+NnP/uZON5ffPEFfPDB3zFgwFdiEmLh\r\nwvmIiAjHpk0bsGvXTs2hK7IJOu7QxW8vdSkct1w6vWycC7qWC3lM1OVf9V00sUPXoSdik6OF+Oq7\r\nPNFMyHQTdXZ8EBSThsKUCHRib/tFxAth2DVoLZbz5+0einjh/vkiNvfq/juqi9fZxi5FlUG56qYr\r\ntY9e6vt0ztRLPnrZVNSPRB2JOoIgiOuLd999h4qgiStKSUkBnnnmaQwZMoheD+InP6rOhdknn/RC\r\nx44d8W//9m9CyPHfmVzYrVu3Bqmp37/GxunQPdU5D7t2HhNBKfZuumOO1EurdJyLupYL+ew2/6qP\r\nX8q0y+lCoPn4dBDiKzqr0F3URY8UjxsZneZakRDEd+18OonHzElgj4+Qjl0nnqDZd/k1CEqJcumm\r\n8zcTL61uOsuls6VeCuToJTl1JOoIgiCuO7Kz03HTTTeJq8n0ehD/KmVlRfD1fQ3PP99ViDt6TYif\r\nGkeOHERAwGg8+eQTwoHjqa1Dh
w7B2rWr/+XUYEPQPfVUARNzlapwnCdenlSCrlIIOq+xS62bznDq\r\nhKi7Bk4d76Ub6iOdN5++i21CTRd1PBBF7NR16I7FMYlIS0tBfMxaxCTLfbz4Od2Ve+eHRBGqsla4\r\nd/x9gTFpV1/UCaeOiTpj9LLcKhw39ul4N53YpSsdJFMvnQEpStA1FX1Goo5EHUEQxPXHsmVh+N3v\r\nfktjmMS/zKeffiwqM/LzqTKD+OlQVJSH2bNnMrH1JP7jP/4Db7/9JhYsCBVO3ZX8OrfcspeJuSrR\r\nTScKx4VDJ7vp0CRTL+0unVvqJRN0F/LQciEXtSfzrkkdQPycnlJ8Rae0Leq80i/tgi03cbHYsetq\r\nPl65dx36IuEa/Bv4+KVRY8BdOj522aR103m00UuPmXop9+k8XNQVfSHGLpuK+5GoI1FHEARx/fLW\r\nW3/DZ5/1pteC+MHwcUu+V5SZeZReD+InwdGjh/Hll5/jV7/6FZ544nF8++2cq3pBggsBaGXjrVrZ\r\nuOXUVTq66dTYpRq9NFy61mso6v7pkc20NKQxcnOvo5464dQpUVfuXmOgJ16KsUvTpVOpl2qfzkPj\r\nlyTqCIIgrldSUpLFwv+ePXH0ehA/4GR1FG655RZxHNHrQfwUxFyfPp/iP//z/+Kjjz5EfPyOa/Rz\r\nMka6dEzUmaOXwqU7adulgxB1hkvH0y6tbjqxT3chj93Pu25F3XVZPq5EXZOWeimcOu7Slbm4dHrq\r\nZZEl6LhL11TUh0QdiTqCIIjrl5Ejh6NLl2fotSD+KaZOnSzKxZOS9tHrQVz3Y5ajRo3AL37xC3z4\r\n4QeiduPaXvzgTl2dHL1kog4ebfTyUqVVOO5SYyBFnQxI4aOXrRdycKoqlwTb9w5KiTR36UTiZdkw\r\nUWNguXRWlQEfu9T36fSAFO7SNRWSqCNRd40oLi5CVFQUpkyZgrFjx4oDjyD+Oc
Zi3MQgLF62GBkZ\r\nqfTD304oLs4XbsvKlcvp9SC+FzNmTMNvfvNrJCTE0+tBXNfwWoE77rgdTz3V+Uc7Xvk5GR+71F06\r\nK/GSCbqLFS77dN4BKdyla2Girr6WRN33pa5kiblP5xWQ4pV6KWsMPCX97QEpap/ufB5VGpCouwZU\r\nVJSLA21nXBzqztSjqbkVTS0QXGq2uOgBGhkXGOebgHOXJGcZDYr6i8AZxulGSd0FBbt/it3WnpfU\r\nMKrPAVWMkxonzgLHG4BKxbF6oEJRzig7IylllJyWFNcp2P0idlt4CihQ5NVa5LLfidnVDHabVS3J\r\nZGRUWaQz0k4CR09IjhxnnJCksPuHKxns9hC7PXhMksxIMqgAEhn7yyX7yhTs/l52m1Aq2cPYXSLZ\r\nxYhXxBUDO4uAHYrthUCsYlsBsFWxJR+IUWzOAzYpNjKic4ENOZL1iijGumxgbRaD3UZmSdYwVmda\r\nRDBWZQAr0yUr0hjpkuXs/rKjDHa7lN0uUYSlShYdacX8/fWYsXofAseNQ1raEfoF0E4ICZmLe+65\r\nW6QY0utBXA7udHBBx/u36PUgrld4Civfm/vlL38pysF/zO9lypTJOFNbqvbpqjSX7ri1S6cJuhYj\r\n8fKi1U3XKly6XLScz4HnbDaKCgtItH0nebhYNt5WZWCOXpqF44OswnHbPp1ROK5GLwv7IG/fEAQE\r\nBJCoI1F3dR26CRMmICMzC0zLoblF4lEYYs4UdE12UXdWE3Vc0BmcaZQYwu7UBU3UXbCLOiHszlqC\r\n7vhZS9RxKjRhZ4i6Mk3UGcJOF3T5BlzMaXBBl6PEXWaVQgm79JNS0AlRp0g1hN1xd1GXrIs6JuYO\r\nKBLLLXHHRd3eMk3UlVmibpch6ootQWcTdUVK0ClMUVdgCbrN+UrQ5UpBZ7BBibsoDS7sDHG3JlOh\r\nhF1EhhR0QtQpwg1hl6Z
EXZom6lItQbf4CBd1wMIUBrudtSlLXCggx679wHuYeDE5vRZEW0yYME4k\r\n2yUn76fXg7hu4fUEvJLg6aefwuHDP/6+56pVKxC3Y7Nw6qCHpDBRB8OpMwvHlUt30Z562apGL1sv\r\nZKP1fCZOVeWQaPsOaotX21w62U8nRy+NsUsh6vjYpaNwXAak9GO31j7dkgUTMXXqFBJ1JOquHnzk\r\ncu/efWjhgq7VEnRNzZKLikaHS2dgE3YXLadOF3Q2l04JOiHqzmuiTrl0bk7dMSXsys9IdKeu+LTm\r\n0Cl0Uae7dDmaoDOdOiXsDJfOEHaGU5eqSDFEnRJ0BjZhZwg6JepMp67cLuh2l1p4uXTF3oLOzaUz\r\nnLrNBsqlM506henUZdsFne7UrdFcOkPYGU5duMLp0i11uHSLU6WoM4TdAkbIqvVYsYJG8toLvOLg\r\nzjvvpNeCcGXWrBn49a//h3boiOsaHvrEq1p4qu/1MnnAL47yi6SZaYmmSwe9xsCWeFniVWVgOHV8\r\n9LLlfBa7z+HCjhy7thy62pLVZuplkxB09tFLZ+qlm6CTyF26mDVjxBjtggULSNSRqLuay+pTcfpM\r\nvSnqPJpL12SMXTqFnSHomtzHL/URzDoNIew0l65ac+kMDKfOcOts45duo5dK0BkUaKOX+froZW0b\r\noq7ae/QyTRN2qSfs45eGWycEXaX3+OUBTdi5unSlbbt0TqdOF3W6sDNcOkPUbdLGL21Oncv4pZuo\r\n8xq9/J4u3RLNpXM6dZwF+6sRFDSJfgm0I+6++y4sXryAXgvCxsyZ04Sgi4vbTq8Hcd2yd+9uUVPA\r\nL0Bcb98bX2cYP34cdsVvwelqJtQuVrqMXhqizlvQmS4dE3Qt5zPRej6DkY6m+jTU12Si9iTjhEEG\r\nI11yPE1xlJGqOKJIQW3lYcUhxkFFMmqOJavbJMYB1DJqjiWy20R2u5+x
j93fh5qKvahl1FQkMPaw\r\n+3vY7W7UlO9SxCviGDslZTsU2xmxGtsUW1FTukURw9is2CQp2ciIVmxQrGesw+nSZbhYNlGWjZuC\r\nzt+sMvBoVQb6Pl2Tc5+u6HNcyP8SefuHYlHIRCHKFyyY7yXoSNSRqLviC7gtra3SpVM49+ku59Sd\r\nVXt13KUzEKOXjr06Q9C16dSdtZy6tlw6c5/utObU1dmFXWGdfZ+Ou3W5Lk6dsVdnjF+mV1kYoi5V\r\nE3WGoEtpw6k74By9LHffpUswdukcwi5OE3b6Pp05ful06lzGL/Wdumjl0hlundOp43t1NkGX4XDp\r\nMuQenSHsvsupM1w6U9gxQg+1il9kGzduwJEjh+iXQTtg3rw5ePDBB+i1IEwmT56I3/zmN7RDR1zX\r\nJCTsEqPBwcHTr9vvkTt2fPolKCiIgtl+IgQGBgrzxM2h44SH0zQTiborHJXLNJ106nSX7vs4dZek\r\nW2eMXzp36vTxyzqHqHOOXuohKcb45bE29ulKlbBzunV8n865U3c5py7ToOo7duoUh7XxS+7SJTt2\r\n6szRS0dQius+Xanm1DlCUr6PU2cLStF26jbmeo9fRmmizhaSkmkXdrZ9uvTLO3VLNUGnj1+aLp0a\r\nwdSTnnbvpi6zG53S0kKRhBkZGUGvB4GAgNG4+eabKeWSuO5HLrmTPHjwwJ/M98wvlrqJBOKnBf9/\r\npJ9BEnVXVNS1uIm6ZkvUXXIRdHL8shElBaVIyy5EVkElik40uou6C43IzS3EocxCpOZWIr+qUQg7\r\nffTyhNvoZYN99LJcE3Q2p67OLuoKtZAU506dcOlsTl0jQsb54+0+wYgutYSd6dKJ9MsGhAT54+G7\r\nOuL2x7vgb8OjMS3AH298EozVRS4hKS7plwlllqAzMEYvbSEp2l6dc6fOJup0p+4yo5dR/+TopUG4\r\nLurUTt1yTdDpQ
SmLtaCURZcRdRxy7NqHM8Pjv+m1aN+MGOGP3//+f5GYuJdeD+K6JSsrDX/4wx/E\r\n762fVpjLIRJFNwB0TkSi7uo5da2aS6cQyZeaU3dBcWRzCJ7q0EGMK9j4axgqGq3Ry6ToYDzp9rhX\r\nw1B83t2pq2yoRkBn/riOCM1sVMKuEt/cw9/XBctyPMqlK0Vf/lwD47zSLwsu59TVWC5dRlUDRj3B\r\nn9cXKwq9Q1K4qItZ0Ft93x3x9Asd0eHxyRjwuPycRXneTp0h6PaXWy6d4dTt0esMXINSGjC4m3yN\r\nPo2o1Jy6Bgzsyt7fKQTrCr5HnYFy6rhDJ8ixnLq1RkDKd9QZuDp1mqBzC0pZqAWluIk6uirVPqLA\r\nb7rpJsTGxtDr0U756qsv8cc/3oaDBw/Q60Fct/AgFJ5w+emnH/8kv38+/ULC6KcLTS+RqLtqTp1Z\r\nZ9DadvqlrDPwYMdEX1Oc9ZoQjm17k7BtWzTmTfPHu19H4pjYp/Ngy3jrcZ9NjcTm3UnYHBONWVP8\r\n8dbgSBQbTp0h6DTWDOoiPu/vC3OkU5ezFT7qufqtrRRuXe6RcPF238hSy6lTe3X5xj5djSXo3Dvq\r\nGhD4ohRoEYUu+3THPZj8gfo3rKlW45dMCL4gP2dpnj358kAb45cJ2l6dmX5pOHVa8iUXdUO6GeK3\r\nC4KSpajbWmCJurXa6KUp6HId45da6uX36ajT6wzacuou11G3+Ih9/HJ+isQp6mh+vH0wYMBX+OCD\r\nHvRatEN69fqHCMw5evQwvR4Eru/zn1G4//4/o7g4/yf7b+BOD79Yyv+2klC6/uH/T5QzQKLu6jp1\r\ncHfqzH06jzV+2VAYaQq1yXur26wzqM2zHjdxT53XPp2+U1flqDPgpG8Lkp//bjgKmag7tNbffD6f\r\ngXFi/HLn3B7CPVtRIIVcbnEOAgb0wJ/U4x592w/fxleq0csGBP
v1wCNvBWDx1mi8czd7zFthSNZE\r\nnXTqGjF3ZG/ccXcPzE31IGqen/l173jcFw8/7odV+d6ibn9mDoZ+0QO3q8c++IYfJm2pFEEpK2b5\r\n44HHfDE4slqKurQkvPV8FzzRKxzRQtQ1YhL7vu/vFYmNRZZTJ+gUjNVi/FJz6rigy67EkP690fFP\r\n6nF/6oLXhkdjWaaxU9eAr3v3wL1/DcDIFZHodid7zJ0d8UjvcMzbW4je73QRb//+WX+MjfeYdQYr\r\n9qTgww98TWfy2QHRCE2zxi91UWeOXrrUGXDmH/YWdZT01D44eDARP//5fyI3N5Nej3a0T/nss11E\r\nX2Fm5lF6TYjrGp7EyovFqWKDIIgbStQ1O+oM9F26S47ky9zNSlw9HYxjmqDT6wz42GV6tPW4Iq14\r\n3Ey+dBSPc7fOVjxenoDHhbDogXgm4FYN6mgJnXsCcJR9kckvs/udg3GEj14eT4ev+nhXvzAsCg0y\r\nxd3gbdVC1I15SRNLT3TBIx+GI7naEnVrmTjbME+OWr45M104dds3hOAO9TlPfxmEQQHh2FRkF3VJ\r\nhel4UT3mqS/CMH1WEP5ouIrR1diyIVh+zfcjhTu3+ls/UzQFMeETl5OCJ9jb949KwU5N1N2qnuPP\r\nXycxUdcoRd2jStRlpKBLhy7oPS0ak8Kj8faj8rHvh1fL8cucBnz2nPXvvfc5X/v46yO+uEfdv2dY\r\nigxKSU4xR2XfmhSNXj2kW3rX0BT76KVL8fhirc5ggXLpSNS1b55/vhsmTZpAr0U7oKAgBy+++ILY\r\npczLy6LXhLjueeSRv4ggH3otCIK48cYvncmXhlOnuXSc/dOVOPhrCE42WR11dbWVOHQ4HYeyq4VT\r\nt2eq9biyC/aOOrOn7rx3nYG1V1eHsZ2lwJi2JwXfsNvnJ0Vi9DtSTC3ZH4fX2fu6TU8Ro5fxoWrv\r\n7clgHFb
7dJumqe/hrXCkMVE3QYm63ovSxeilDEoxRF0PTFwoxVeXkXFIMZIvjzdi/Ivy876Ja1RV\r\nBnZRt3aO+tqPByNWjV4uM0ZU3wjHzvx0PC/EUm+sLGzAiNctcfX+kmpsjpKu5De7Gq2dOt9wrIgN\r\nNx/XP7oQw7srUaft1EWnVmPp3lKM6CMF2H3DU0yn7ksl6j4MqxRjmMM+lML4kUFbsSoLWLQ4QLz9\r\nFybq+MjltCD17+gSjOlJjZi3LhL/y9/+SwgWuCRfmm5dGyEpbuOXJOraD7yM/L777qXX4gYnOzsd\r\njz/+GF555WUUFeXRa0Jc9/DexAceuP+6KRcnCIJE3ZXfqWt1Lx3Xd+qKYqUQ6HBfEEouWXUGxw8o\r\nN+reYJQwUZezVT3u3gBkN9qdOqegM9MvtcJxzpaZUhjddY8ULBMO1mHzJPk+n3ukQJmc1CBF3Xwp\r\nSP70WTSya+VO3ZGEECX0QpDMRN34l6QQW19uddRZO3UWPRbkaFUGDRjzouH41Yni8YPHNFGXa4m6\r\n2z+Jxl61S7d9u/raj4VgS1kjAt5X4uzbcOGG/XWgPx5gt7f1CsPwvvzf4o9wkXrJRJ0as9xUCIQE\r\n9rA7bF3VTl1GIXp27egVQPMoE3WGUydFXQ9MPSp36qaPl8/16foGsU+3NEp+jw8zURehizovAhCc\r\nZk+91AUdjV8SbYUQ/Pa3N2Pz5mh6PW5QUlMP4f9n78zjqqrz/89vHt/Hb+Y7NdXUNM2vmmk3srI9\r\nzUwzzdIybLGsMdPKfcN9X3EJdxQVXNBEFAUXVARkUVCRVVlEQHYUF0BQXFAu8P69P9s5n3O4YJbZ\r\n5fL54/k4l+VyuUe4niev9/LCC89Dz57f0PJLdU4Utk52dgZds+Hvv0WdD4VC0cSSOlP5ZUVOgHax\r\nP/jndE3qLiSv05K50yhxJbn65323LqVuSmet9NK0oy7z
iIckFk4QeA4gJchVep8z7CtmKw1ClvXU\r\nBC6JJ3VhWnrnAYlaUucEfrnWBqWg/Gx207725H1lPKkzSh3bUWeUOt9F/LFbe0AYT+q2Lu2nSV1w\r\nAcD2DRMMz2VVUhEMcdTFqfX4GL6jjid1KHXb6UqDMhjW0Sh1pPxy+Uwmt49/FwABmQBLJ7G3W85I\r\nMUmdE8yP51I3jX2fffzKqNRt4FJXJ6lrNhPcTYvHtUEppiEpstStUUmdwsT48WPhm296qHNhh5BV\r\nBWQnIZl0qc6HojENR/ngg07qXCgUCvtO6qz11ImVBmKVAdlPJ0+/bDvMDXYfTITt7rxPrJ0HTerI\r\nwvFAafplm+9dwTswCrbtDID5k1EuPvaATGnypbynTqR1p86nwGdCZt7xgBSyoy4rHN4S7xsYACf5\r\nKoOc3Bhoxd/fe2EQ7NjjA5/wt/tvzac9dULq/PPkpeN6T53faQD/eT018fJE0UnEb2qiSerM5Zcx\r\nx2PgNf5YX80NAi9/H15u6QDfbshn0y+Tw2kyR792p3UQgt/D8vHttfMzIqiC76nTpW6nWGcQGwUt\r\nxH15+eXymfz77DATpq/xgBf5xx//xAM8EsjkywoYwqVuQTybfGmQuuN1kzrSU/c6/zrNv3CFseui\r\nYMyCdfAh3v4pVu+pq29HneqpU5ghQwjuvfdeVZZnZ4SGBsNDDz0ELi7T1flQNBrI6xBZt6KqBxQK\r\nhd0nddVyUlddd/qlELsrNywQu83V6p6653/w0fbUleGd6ttT9+HoACiQ0jrDkBSe1J2uqATPPqzE\r\nsNNPiVCAUldwsQjG8167EQFFkFuu76dLTgiHHm3kx2kBYzam85UGovyyJ2zNMe6pE0kdWWmQdK4M\r\nJn8uhqm4Qgh+Y7P52xNFUqeVX/ZkUocyGH4wHLq1Nj72oLXp0o66MhjViQ8hWZ1N99Pt3S2SyAmw\r\nI
VMsHedS974HBPDl48GI72ZXQ/nlnpgYbTgLeazv5rhqYvfdljIqdVr5ZTxbZSCkru9WntTt4FI3\r\nNVFbZfBzRBQ4vWcu63SG2bGmHXXH6u6o08ROJXUK00CCtWtXqXNhJwQEbIcHHngA3N3d1PlQNCoW\r\nLVpAh/moc6FQKOxW6qob6KmTh6SQnrqrnCu07NICZ88VQ2ZeEWScKoOiixa60oAK3TUGG5BSCRk5\r\nRZCaXQQpecWQe4nInAUKzlVANuGsThaSU2zR+uoKUeQKLzGI1JH9dGSdAVk+ToROWzouQLk7hjfi\r\nkZRz+sJxsadO21FHUzoG+byUc1Z21J0lSZ1OAk3pgIsdW2Vg3lEXdrwMglPLICJH31En9tRFSjvq\r\niNTtl5aOiz11oXi/fdrCcbLKgBGE7JWXjtPF4xbYGl9BUziyn27H0TLwSayEbXxH3Q6+n07gnybt\r\nqDtu3FHna9pRtz6mDDwPlcHqOIuh/NKc1K07ZhySskZK6VRSpyDMmTMLunb9SJ0LO2D9+rVU6Ly9\r\n1e+xovFBhqOoPzApFAq7T+rk0ktD+WW1MaXTpK6q7jqDizyhK+fll2Vc7kolikVf3bkYaG51KAcy\r\nKYYndcAWj19kmKUup0yHyFzWBX3peGYpQywep1JXZ/E4yhxHCF3SWYZZ7BI4mtQV6UJHkjq6dLxQ\r\nXzpOF4/z5eNREpGS1EXkSkKXowvdPpPYBWXp7D2py51YPC6Wj4ul4zszdKnbLomdtcXjvhwhdJtQ\r\n6DbJy8dTjEJXp59OrDOwMiRFJXUKQkrKUbj77rshPT1VnY9GzIIF86jQ7dq1XZ0PRaMjODgQHn30\r\nETXxUqFQ2LfU1daCVoIpBqTUGZJiSumu3NDXGVRwubvIkaXuQr076iohOT0fEk4w4pE4Qlo+HC2s\r\nrJPUWU3pJLEjKV2WJHaa1JUwTvCk7kSxXnppTe
yS6knqzCmdIEZApI5zuFBP6ciycU3m8owp3X4p\r\npTOLnSGpy64rdCKt06Quk0mdEDtN6k4w/HlS58+Fbms9YrdJGpBiHpJiLaUzrDOQpE5Nv1TIdOzY\r\nARYvXqjORSNlzJhRdJJpZGS4Oh+KRknfvj/AsGFD1LlQKBR2LnU1aF81aGN4rK1G66ohoHlVX8a3\r\nK/CIVlV9EWotaFGWMjxegNqqEk4xco5zFmpvnEHQfJDaG6eg9nohUsDJQ3IpNZU5UFuZjWRBzbWT\r\nUHstE29n4u10vH2CcfU4fiupeEyh1FxJwmMSHo9CzeVEJIETh8RCLVJTcYRSezkaj4RDlNqKg1Bz\r\nKQqJRA7g04mAGko4VJeHQg3h4j68HYy3CUFQU7YXqssC8bgH2Y3sQgKg+sJOqC7dgcftyDa87U+p\r\nKfWD6pKteHsL3t6CtzcjmxAfqEGqi705P4Pl/HqoPr8O8cLba/G4hmI5twqqKZ7ISrCcXQHVlOWI\r\nO7IMLGcIbsgSRtEiSnXRQjzOp1QXzQPLaVfkJ2QuVJ+eA5ZTs/H2LDy6gKVwBmc6VBVOw+NUZApU\r\nFUwGS8EkzkRkAjKekT8WGQNV+aOhKm8UMhIZAVW5zshwsOQNx+NQZAhYkKqcQUrqFJQVK9yhfft3\r\n1bloZJA1Bb16fQuOjo6QkBCrzomiUULSuYce+qf6o4RCobB/qUPLQrG7hiJ3jQpdLcocWhIeL1Gh\r\nI0cidLrUleKRwKQOqs6jwDGpgyomdbU3ToPlaiFcKsuDC8W5UHo+RyKbkwWl57L48SSSKR0JGZx0\r\nKD17QiKNcxxJ5aTonEnmJHGOIUd1ihLxmMiORQmUkqJ4PBLi8HYcHmOh5HQMHmPoseT0EUrp6Wg8\r\nRuPxMKXk1CE8HsLjQUopPUYxCiPx7Ui8fQBvE/ZzIiTCGQVheCSE4u19nBBOMCM/CI9I/l6JQM4
e\r\nnbzdeETydnECkJ0SOzjboDxvA1wvnItix6TOUjgZxY4JXVX+BCZ1+ePw9lhkDN5mQkeOFi51Fip2\r\nROiG4e1hSuoUdcjIOA5//etfIS0tWZ2PRkJWVjp07vwhvPVWK7pgXJ0TRWMe7tOsWTN1LhQKRROQ\r\nOpHS1RhTOqiuQIG7SFM6qCZSV4Yid4FKXa0sdAiQpO6GntSVleRDTnY2ZCsaASjQeVtQ4FDqtKSO\r\npXRV+eOp1Fk0qRvDpE4WujxjSscYTFFSp5BLMJcuXazORSOAyDeZWvrxx13osmZ1ThSNGbJLccCA\r\nfupcKBSKpiB1lXVKL2uF1JlLL6tKKSKlq6VSJ0ovizShU6LU+CjN3cKkrnASVMlSV8CSOiZ0Iqkb\r\nZSi9JCmdufSyKmegkjqFNGjDFbp06azOhY0TG3sYnn32Wfj++95qqITCLnjxxRfAz89XnQuFQtFU\r\npI6VXkK1EDo9qauVkjrST0dKL0k/HVh0qQMidVVnwHLtdJNM6GJDfGGRqysscveCiMSMRvo8MuB6\r\nvosmdEzqxvFeunFa+SUTupE8rXOmKR0ll5VeVuWwlM6Sq8ovFTrJyYlw11130bI+dT5sE7JUnCxn\r\nnjx5ojofCrsgMTEW7rnnb5Cbe1KdD4VC0TSkrpb20l1hpZdyPx1J6ITQ0YTuAk/rUOrkpI6XXl4q\r\nK7A5WUmO8AVnp1bS2gRH6NixD3hFpd2erx/IF4O36giOeJwScBA8BzrBQPeQRid25XnraPkl66cb\r\nr0ldFU/pWE/dSHjn6iMQduZzltLl6UmdhaKSOoV1WrVqqfZE/cGcykyD0mVLoHzsaHokb5P3b926\r\nGf7+97+Du/tSdZ4UdgNZOK72ZCoUiiY0KKVSGpIi9dNJpZein86Y0p3TUzraS3cGLhTbVullov8U\r\nTeSmePpCgL83uE4ZSOXL2T/xtjxGwBQi
jOMgVntfMrg4OoDjuIBGJ3UluVv1qZe89FLupxMpncMN\r\nPKeXHeCdUpS7U5/r/XQkpUOhIyldVc4AJXUK0+vNVOje/Qt1Lv4gzgbuAstDDwG+YGmQt33HjqFC\r\nt2XLJnWeFHbFt9/+F6ZOnazOhUKhaBpSJyZfiqSulgqdLHVl9awy0AekiKmXpcV5NiQp0TDOkQmd\r\ne4gplctIg7SM2/M4IS4dwcHRBdLsoIy0JNePll9WaVI3Xu+nk1YZEKFzuISUIucdoG3hIxCa242L\r\nHUvplNQprPVrkQXWqlfrj0nozEInOPOnP0H47h3qPCnsjubNn6PTL9W5UCgUTaT8kgtdNSu9BG03\r\nnXGVgSi91FYZWIyll0TqLtiQ1KWFsLLIjlNukpglh8CUHnp5pmOPKRCSrKdu7vixPq7e4DXFSU/9\r\nvKPoxwNde+j3Q3q4Bmr36bEoUHuMjNgAcO4oyj87wrgpA6FVq4EQkmZ7UqftpjOtMtDWGRCpE0JX\r\njJxGCpFslLushyE024kndar8UlEXMlpcXWTdeUippTWhE5CPq/OksCfIKpU///nPkJOTqc6HQqFo\r\nOlKnT71kCZ3YTQe0p05K6TSh4/10ROikpeO2lNQlB7pQiXIJTG7g86LAmYpWD/AOjIKoEC/oQdM9\r\nZ4jKYFLnKmQMJczL3xvGdWQfjyaPER0ILn0c8e0++DF/CIxIZOWXrVDyNJmMgoH8MbxCoiDC3x06\r\ncrnzT7YtqSsmSV0+S+n0ISljDUJHpl6KhE4WOoeTSBqS4gDvJP8/CM3oqqROUYeBA/vDsGFD1Lm4\r\nw5AeuoakjnxcnSeFPeHr6wOvvfaqOhcKhaLpJXVyPx3w0kuwGPfT1VllcMO4cNyWpC6NDzBxbUDq\r\nhPhNCUiW7ifexwWNSFxHF61nLsSVJHatNCGrW37JpK4Vl7r6H6MVBCTbcFJn6KczrjKgQ
leEFEhC\r\nd5wJnUMCSt0xlLp0JnU9e/aE3r2/gx9++AH69+9PFxp/800PGDx4IJ2yt3jxQti8eSPs3x9G/7Kq\r\nXjTsGzJa/IUXnlfnQiV1CsXvCvn/5Ycf+qhzoVAompLUXeVDUi5rky9rTaWXdOKleZXBjXOGlI5I\r\nnS2VXyYHMJka18BAlGQuV76J+vsyojyNUkcEzUUvpQwkEufQUROyQJdWVOqSG5Q6R/COzpBKQ21X\r\n6qp4SleVb9xPZ8nTVxloCV2OUejaJj8MoRmf0H66quz+9Odr5coVdKLekiWLYeHCBfi2O8yZMwvG\r\njBkF/fr9CN26OdGpiI8//jgtlSHjp8lF/0cfdaGpzrx5c2HHDn84fjxJvaDYAXl5WXDvvfdAfHyM\r\nOh93sqcu4zjcePAfVoWO9NqJKZgKhb3Qvfvn4Oo6R50LhULRtKRO7KarlVO66nLjkBQtqTuvDUkR\r\n++lsManLiPakfW4OTq6ScJnFbwov0UwzCZdJ6qS+vF8ndUQu9aTO38XJ8DVsa/ol66djSd0YQ+kl\r\nLb/Mda6T0L2ThjJ3shsfksL66Sy/clBKamoS7N69A0XQjYrfl192hxYtWsBf//pXukOrXbu2MGTI\r\nIPD0XAHR0QfVi0wj5JNPuqqLrTtMaGgQdLz/frj0t7vrCB2ZiqnOkcLeIEvHVf+uQqFoUlJnHpIi\r\n99MxmdNXGdRa2U0nkjqwMakj+I7jA1CcpkBAVCxdgBwdEQCLnPuAK5G2tBDoQT7ecQoExiZDcmwg\r\n75nrwYeY1C91/r9Q6rIzIqAP7aFrBeNcXWGgNDDFFqWuSuqnq8pjUy/FfjpSemnJc9aE7p10lLms\r\nbnzZ+GBtlQGj/23tqSMTEw8fjoL169eCs/Mw6NDhPfjnPx+E+/FCtVOn92Hy5Amwc+c2tWS2EbBs\r\n2RL44INO6lzcwd4isrJg+fJlNL
GztqdOobAn8vOz4S9/+Qukp6eq86FQKJpaUndFWmNAyi9ZUlc3\r\npWNTL8E09ZKkdLXXT0Hp+VwbG9OfAQGLnFliZ6Cjtnw8LcqXD0fhOPYBb20xeV2pYz11ThCQJkle\r\nqwakjpAYCFP6OEErR0dwGucO3q59DH15NjMoJUdK6vLHGUovRT+dBWmb9QiEZn+mLRwnUqevMhhI\r\nhe52S119kDI+Ut753Xe94Pnnm8Ndd90F777bjvZTkHRCvQjZHklJCXD33XerqXR3APK7Qf7wQZaL\r\nq/OhaCpERUXAY4/9R50LhULR1KROXmUgkjpRfnlBW2XAUjo9qQOpn46kdLU3UOqKc21zB1tGMkRH\r\nR0NsbCzEJqZZlb/k5GRKxu9RCppmfCzPPg6mheW2lNSZeumk/XRE6KrynJHheHs4XzpOxG6IVHo5\r\n4I5KnRnSe0dKM8nS2SeeeIKmeWQwi5fXajh58oR6UbKF/q7MNBj7739Dco+vVFr0Ow+KICXLoaHB\r\n6nwomhTr1q2hpfrqXCgUiiZWfnmZ99RVcJnT++lE6SVYW2VgTupu2GJSZwskwhS6EsEJBjo7gxNP\r\nBQd6Rtnc90qTOqmfjpVeGlO6Kipzw7jQEZkbwpI6mtaxpeMWKnb9bGKlQWRkOL24JcNYSDrUtetH\r\nsGbNKirX6gXqzkP6t8xLsFVf1+2FlCr37fsDPPvss3ThuzoniqbG1KmToXfvXupcKBSKppfU1fKU\r\nTiwcN6R0FlNKd8M4IAV46SWRugs21lNnK0QHeoOryxRwRqlzHucCviGJNvl9luRuMfTTsbRulKGf\r\nriqXpXQWKnZDpJSODEcZSKde0qQuu6/N7akjQ1jI5M0333wD7r33XujR4yvab0T6L9SL1Z1J6MxC\r\npyYw3l7IHyvIIJrXX38N0tKS1TlRNEl69foW//+Zqs6FQqFoOlI3Y8aMOqsMSFK
nrTIw99OJISlV\r\ndVO62uuFcOmCkrrGTFnuGm0/nV5+OYqvM+BJXa6e1Il+OouU0rF1Bv3gauZAm14+ThKMSZMm0D48\r\nUqJJko0DB8LUi9bviNqV9vty4kQKvP12azo4KCsrXZ0TRZOlbds2+P+NlzoXCoWi6Ujd/Pnz4GLZ\r\nmXpKL8usTL48V6efTpY6y9V8yFFy1EjJgOt502j5pbWF4yyl05M6Wn5JSi9z5CEputRlHhoDLi4u\r\nNit1MmTx+fDhQ+GBBx6ANm3ehtWrPeg+NfUCdnshExcbkjrycXWefh0JCbHg6OhIe0lV8qxo6jz2\r\n2GN0WIo6FwqFoslI3ebNPhAeFiSVXl7UdtOxASklxoXjWkp3FsVOlzogUnejEMWuAMqKVV9dY6Q0\r\ndxMXurF8P90YaUDKyDoDUrSpl9oqg0Ha0nFSfrl+9VxYsGBBo5A6uXRt6dLF8Nprr9IBE2RP3tGj\r\nceqFTCV1Ng3pG33kkYfpz6s6H4omW97N13WU4e/Bf//0J8g9nmQ3zy03Nwe2bdsO8+fPpxVWpApG\r\noZg2bTpMwZ8Ht5VLITX1mHodaOpSR34IyA/G8dSEOkmdkDpReikWjlsbkEJSOiJ0tdfzUfCI2OWo\r\nxK4RJXSluZvpfjpaellgSup4Px1J6VhaN0ybeklTulxjSmdBoQvcOp3+x7N69epGJXUywcGBtOfu\r\nnnv+Bp9//ilERISqF7TbcNGleupuL7t2bacJ84IF89T5UKgBTHY5gKmQXqftCw2D4tILcPX6DbiC\r\nXK68AZeuXYeLVyuhHCm7fA1KK65C8aUrcK78Mpwpq4Ai5HTpJSgsvQiFJRchv7gccs+XQfa5C3Dy\r\nTClkFJVA+ukSOHG6GI4XnofUgnOQgiTln4VjuWfgKBKffRpis05BzMlTcCSzEA5nFMDB9HyIOpEP\r\nkWl5cOB4LuxHQlOyYV9S
FoQgQcdOwt6jmRCYmAm7EzJgV3w6BCA7Yk+A/5HjsDU6FbYcToXNh1Jg\r\n08FkysaoJNhw4Bj8jKzffxS8IhJhTVgCrAqNB899ceCBrAiJBfegGFi29wgsDTwCS/ZEw+Ldh2Hh\r\nrkMwP+AguO6Igp+QOdsjYfa2AzDL/wDM9NsPM7ZGwHRkim8YTNoUChN99sEEZJx3CIz1DoYxG4Jh\r\n1M9BMGL9XnBetxeGrt0DQ9bshsGrd8PAVbtggGcA9Ef6euyEH1fsgO+Xb4c+SK+l/vAt0tPND75Z\r\nshV6LN4CXy3aAl8u9IUvFmyGz+dvhk/nbQInVx/45KeN8PFcb+gyewN0nvUzfIh0mrke3p+5DjrO\r\nWAfvTfeC9tPWQtspa+Cdyavh7UmroDXSaoIntJzgAW+O94A3xq2E18augFdGL4eXRrnDiyOXwhsj\r\nl8Bn41xhOl5zJScfVa8HTVnqCOSHYPbs2bA/Yh+UlxZCTVWZ1k8nl16CtHS8TkonSV3t9TwkFyxX\r\nsuFSaTZcOJ8FpYJzJyUykQxOOucElJ49wY9pnONIqs6ZFDwiZ5KRJIljnKMSiVBaREjgxHPioKQo\r\nFo+c0zGUktNH8EiIxtvReDyMR+TUIbx9CI8HKaX0GIVE4u1Ieiw5dQBKCgn7ORGccIkwKCkIxSNS\r\nsE8ihBPMCYKS/L0SgRJ7GHm7Gfm78EgI4Ozk7OBsh5JcJG8bHgn+nK1QnucF1/NnarvpDCkdn3yp\r\nD0kZwVO6YXgcpk29FP10VzOHQObhsbDWYw79D2j16lV1hK4xSZ08XGXChHF019dHH3WBkJBA9cJ2\r\nmy++ruG5VdMvbx1v7/VU6NavX6vOh0INYLLDPxaRhG7OnDmQnJoK16ssUHnDAteQK9er4ApKXcW1\r\nG0zqrlTCBZS6EhQ6KnUXudRduASnLzCpKygphzwUupxzZZB1FqXubClko
tilo9CdOFUMaYiQumQu\r\ndQnZRZLUFUI0lbpCOJTOxC7yRB4VuvDUHAhLydGkLphIHQrdnsQMTep2xp2AbTFpKHVp4BfNxM4X\r\nxY4InQ+VumTYEHmMip1XxFFYE54AqyWpW4lCtzyYsWxvDCxFsVuMUkeEbgGVukPgupNJ3VwudS7+\r\n+8EFpW7alnCY6hsOkzeHUSb6hFKpG79xH4zdoEvdSJS64esCYdjaQCp1g1bvohCp64dC13flDvgR\r\n+X7FdujtjlK3bBv0XOoH/6VS50eljqBL3SYmdSh0Xeei1M3xho+Qzih2ROo+cPlZk7r2KHXtpq6h\r\nvDOFS91ET3gLacmF7nUUulfHrICXudS1GOkOL4xYCs87L4VOYxbQay+V2DVxqROJ3caN3uDq6qoi\r\nbcWvhvTQkZJLawkdwcfHu9H+ImfihQFZjfDgg/+Ajh070IREvcD9tjIp0kPn9X4HGDmgnzovt4i7\r\nuxv9Q4P6OVSosm77Levevn07RB08CJbqGrhhqYbKKiJ1VYak7tLV61ToSEpXgpy/yKTubPllltSh\r\n1J0qvYRSd5GmdDnnLjCp40kdgUgdTeoQKnR5LKVLyGFSF5d12pDUHUKhO3ginwodlToUutDkbNiH\r\nBB8TSd1JlDqW1AXEsZRuO5U6JnRU6g6l0LTOB4XOOzKJpnTreEq3NjxRlzpkZUgcrAjWk7olgSyl\r\nW4QQqZu38yBK3UFN6uZsi6RJnUjpiNRZT+pCYDRKnUjphnsRqdtD0zotqUP6e7CkjqZ07kTqtmlJ\r\n3X95Uvf14q1aUvc5St1nKHTd5vnQpK6rSOrmSEmdy3pDSvfuVD2pa4O0nriKSh1J60hSR1O6Mcs1\r\nqXtx5DKUumXQHKXuueFuMGz2XHotr14XmrjUGct5dlq9IFcofivkZ6ux/0KTqYKzZs2Ahx9+mA5V\r\n2bMnQL3Q/Qa2bt
0MLVq8qM7FLeDiMh0eeughCAsLUedDoQYw2fEAJvJH0gtl5VBVXc2k7gaTuqvX\r\nq6jUiZSuDDFInVR+KYROlF6SpE6UX2ZK5ZdpKHRy6WVibhGVOiJ0ovwyWkgdQkovidBF8KSOll+i\r\n1NHyy6N6+WUAT+mI1GlJHYodKb8UUkfSOpLSaaWX4UTqjEmdB0qdnNLJUifKL+dxqSPll3LpJU3q\r\ntrCkbtLmUCp2VOo2htCUbvTPwTSlG8Glrr7yyx9I6SVCSi+p1C0zll8KqROll1TqUOhIUkfLL2lS\r\nt4GWYBKpEyldB5LUEanj5ZdtTOWXWunlGJbUvWKSuudHMKl7a/RCcHX9Sb0uKKnTOXo0XgmI4neB\r\n/GzZyy92Tk4mzJs3lyZ3ZC/Y4cNR6gXvV55HshQ+KSlBnY9fgLPzMDrZLzr6oDofCoWdJ3WkN52k\r\ndFUWJnXXq3SpoykdIkovjUndFZbUXRBSV06lLu98OU3qsnlSx8ovSyDtlNRPl0eSurNSUldk6Kmj\r\nKV0676dDIlJzaemlnNQR9H66DE3qtvOeOk3qEJHSiX66dRFHKSKpI9B+Oq308giTOtJPR8ovSVIX\r\ncAjmaVKnp3RU6qTyyykITeoQWnrJU7pR64NMSR0pv9wDg1bvptDSS9JPt3Kn1k/33bJtFDmpI0LX\r\nfaEvhSR1pPRSlF9+wkswhdCRfjqC1aSOix0ROgItvaT9dCtpUkekjpResvJLltQ5DlsCzw5bTKum\r\nyB/Q7el6S0ndb+TAgXAlIYrbCvmZssdfcFKWOXKkM11mTnbdpaSoevZb5YMPOsEyNfmyQciagm+/\r\n7Un3Kh47pv6zViiawgAmcoFeXYNSh2J3nZdfipSuQgxJoUld3fJL0U93ivbTXYQ8KamTyy9ZP51p\r\nSEreGUjMKTKUX2opXXoBG5JywpTUodCF8qSOlV7q/XSi/NLcU6f
30yUZk7oIltSJQSlC6mjpJUKG\r\npLiZyi9JUqcPSYnU+ukM5Ze8p46ldHX76UZI5Zeip26A5y42JGUlG5Lyg5zUSYNS5H667ryf7rP5\r\nUvkl76nT++n0ISkdhNRJg1K0fjqe1L0+lg1JkXvqSFJH+umaD3fjUrfEsB/YXq+7lNT9ysSO2D7p\r\ng1JSovg1kJ+dpvIXo8TEWOjZ8xu47777YOLE8XSqqHoB/GW4us6haac6F/WnmV27fgStWrWkC8bV\r\nOVEomsb0S3KBTpO66rqllxXS5Eua1F1mky/Pi5SOl14WCqlDoTNLHR2SctrYT2dI6lDo4rNzYMnk\r\nIdDtu+mwKZmVXorJl3JPXVhKNh2QIvrp5MmXO1Hqtsem0Z46Inai9FJMviRJHe2pQ6Fbt/8IjBzy\r\nPbT7fDTMDGRCt5KXXi7nUucWaCy/FP10tJeOY5h8uYVIXRiVusGThsPL730EHceu45MvA6HvrGXw\r\n9YyVMHBNIJM6RC697Ef66fiQFCp17nr5pbH00pdJHUnq+ORLUX5pLr2UpY4ldWxQitxPRydfjvfg\r\nUrfCIHWs9JINSXmOSp0bNBu62CB19lYhpaROoVDcUcgi806d3ofHH38cNm/eqM7JLyA+Pgbuvfce\r\ntfC9niT4vffa058p0s+pzolCUX9id27xQpj0pz9Bsdsiu1iRIpI6ufRSDEmpMPTUsaTuvDT58oxp\r\nSIp5ncHNJl+KdQZxWZkwrqUDenInWJXIpl4epEkdG5Qiyi9FP12wtXUGUlKnDUmxMvmSJXWHoNfL\r\n5PHawYRdpJ8uvu46g71HqNjpKd0hw5CUhtYZfN+rNX5tB/jPt8tZP90Gf2jr4EDf133lXm3y5eA1\r\n0pAUK+sMSOklETox+fJr8zoDaVCKWGfwkTQkhU6+nGFM6ljppXmdgafVdQby5Eut/HLokjpSZw+z\r\nDJTUKRSK
PxQvr9V0ITRJoBISYtU5uQkvvPA8+Pn5qnMhcfx4Erz++mvQvfsXtPxSnROFomGioiJo\r\nz6m9PB9yga6VXvJ1BtbKL8V+OrGj7my5PiTllFhnUMxWGhiHpBTX3VGXx8ov9SEpmTC5I5O6dYmF\r\ndZI6UXqp7ag7WlfqtHUGMdKQlMMputRJPXVeEQfh+7eZ1NXyumAAAIAASURBVE3mUkfWGYieOnee\r\n1MnrDOY1sKOOpXT6OoMB/TtQgXuGSx1J6r4bNw06D5kLP64WQ1L2mJK6naz8EiFJHRE6mtIt9TPs\r\nqOvBe+qE1NGUTiq9JOsMrCV1ROjaTfWEF99thd/bo9BsgIdxRx1dZ7DSMCSlhSmpe9ZK+WVjnzqu\r\npE6hUNhUyjJ48EBakjlz5jR1Yd4Aw4YNgYED+6tzwSGDY5o3fw769PlOnQ+F4hfy889e0LZtG7uS\r\nOvM6A1nqyDqDMmlISvGlc7Bm5Ffw9peTwCdwA/R8HuWo+fPQyXk1HExLhFnftgGH556HZz90Bp+j\r\nZ7WeuuTUQzB18BfQjCdWr3frC4sCErWkTkidVyLrqTtweA8M/fZ9+rkODo7w0QhP2CEmX5Kk7kAw\r\nOA/4Cl58xoF/zpswxjcO/A8EwVcfvAfPt/0R5kWwyZfzXQZB81fegM/n7Ob9dCapC42H5Vs2QPdP\r\n2/Gv9TS0/n4ezDb108mTL+fwnjqS0k32dIM2r79M7/vP1z+DV5o7aFLHBqXsgs++7AbPvfs99PIk\r\nUucHnT9qD4+0+gY+mTAZmj+Kn99yGPT20IekyJMvxZCUHnMWw+sd3oF7+Tl88NXO0GqYO5O6WQvh\r\n2Zdfgwead4U2M5jUvd3jU7j/iefgya9/olL35mfifCL/fBTub90f3phw83UGWvklFzuz1DXG/cBK\r\n6hQKhc0SEREKLVu+SYdcBAer5eXWCAjYDs2aNVPnAomLO
wJPPfUkDB8+VJ0PheKWJGgq9Or1rX0l\r\ndRZ5nYFFK7809NMRqbtEhqSchXkfOWhy0LrLR7ooEN7uAq347ZYzw6nUpWUfgI/5+9oPWgLLl0yG\r\nZ/jbQ/2TITYrQ5K6QjiYsAfe5x/v47oKnHu2ordfGhfAeupidkNn8Xjt+sNQl/nw9adfgrMPSl24\r\nH7xBP/YezNrHpO6n0e3p5z43dBOdemmWOo+ADdCSf72Pxs2HL7u9Sm8/3c+LSR0KHZE6sniclF7O\r\nlfvpfNZCC37fxzoPhs9/+Fo7FyKpG7V+O3R8lbzvLfhyBRmS4gfvviKds2dfhIffGQW9xJAUFLrv\r\nZKlDoftm/gJ4nH/+wx0GQJtvvtHk7vlBK+CTGbPgX/Tt1+CtKaz88q2ur9CP/73zNCp1b/X+Hu7j\r\n97n3lU/gqc8nQ6uJbPKlvM7g5dHuutSNJJMv3ajUNRu6BJ4ZslhJnZI6hUJxJ3BzWwR///vfYcSI\r\n4XT4hTonRh544AGIiTnUpM8BWVXw738/CpMnT1A/EwrFLdK7dy+YOnWynZVfVktJHSu/rLh2g6Z0\r\n5Veu8SEp1/jky3OwhEvd5J2ZtPRyTf/n6dvvT/WDzPNlEOs3nr7dYWYELb8MXtaLyctbsyCKD0nZ\r\nMusD9j4nd4iSpG5tYgFsnP8N+9h702Aj6ZPbthyeJG+/4QI7jmWB15we7OPPDIP1ph112yL94B0u\r\ndXND2dLxuaOYeL5KpI4mdYcMUjdj/Kf8+xsJ00gKt2IOPEzebjEW5pDyywDWUyeSOm3yJTJ2Zj92\r\n3+f7wShefvnjD601qSP76Ub9vB0+4FL3NZU6f+jApe7V/kv5kJSd+pAULanbRssvSVL3iUgtn/4O\r\nnBb40smXHT5/nb3vlUHQxWUWPMKlrvUU1k/3Vte3WKJHpc4L3p3mAc8+yx73qb7LafllQ5MvRU8d\r\n7a
fjKZ2SOiV1CoXiDg8FIYMvnnvOUaV2JkjvGPlLe1PuByJL7clycfXzoFDcOu3atYV169bYXU+d\r\nGJTCUrrrpnUGck8dSl0XIgZfQVDRJSgsuQghS7+kojD7wCm6oy4pYiGXunBaehnEpa7ZDz9DIh+S\r\ncijIlQlJq58gXCq/XJuQD95C6uowHDYlZcHa2V/Rtx//ZgVsl4akkOmX/ge2alI3O4T1082bwKVu\r\niI/V8svpQurq8CNMlxaPk/105iEp/fu8zT+3N4zig1J++J711D3d050vHt/Bpa4VlTpSfsmkriV0\r\ndw/Qh6TwHXW9RVInrTPo+m1HlrC1HUN76QhdR/7AHvup76HzLCF1r8JbU9ZDJ5f10PpTIXXTeU+d\r\nuyZ1T/ywxDj5UtpR9/Iod+M6Az4khUy+fGaokjoldQqF4o6zaNECldqZWLt2FR3b3xSfO5ma+tBD\r\nD9GF9upnQaH4dTz22H/oH0fsrafO2joDw+JxktQZpO4jCCpg6wxCFjCpmxqaS9cZGKTudDHsXvgF\r\nT8LmwRG+oy5gSU9N6iJOZsCkDkLqCnSpazYC/LR1Bjl88mUWeE7/hCd1o2GDJnVslYFcfjknMgWl\r\nbj98/76DltSZpW5iQJwudU/0g1nyjro90VpP3Txt8mWUQeqGDvuYJ3WDYdzmMJi4KRi++uQlY/ml\r\nKamjUvcyk7ov3ALq3VEnpl+SfrqPvn6HJ3V9oRvdUbcZPvi6gyZ1H05zgYe41LWeSZK6ZfDcSw6G\r\npK7d1OXwtJTU0R112jqDukmduZ+OlF82G6p66pTUKRSKPzS1I712pO+uqZ8PMrL/7rvvpkNCmtLz\r\nDg/fB//854OwZMlC9XuhUPxK0tNT4S9/+YtdDaQiF+jyOoOGFo/TpePlZzWp25tvXeqOhXOpmxHG\r\n1hkcD4I3efrVc/Ym2LR1BXThb/deGwMxKHWTO+j
ll1Hxe6AN//jL3cfD3PW+MGfBT/DpF2Nh1REy\r\nJMVP62N7/LPRMNPLFyZOmQiT/ePA70godOMfa96pJ7wn9a6J8st1EYegd2smdZNQ6lbu3AAv8c9p\r\n1mUIDJjnAf0nTIJ2Hw6CsX58nYE0+ZIMSZnlv59K3bQV07Wv/1jn76Bthye1t0lSN5pLXadXmNT1\r\nWL4HhqDUvSdJHS2/9GBTL8WOOjH5Uqwz6DF7FvxT9Op9MQE6DBoC/xZv91kCH89dDE/xt+9/6QN4\r\n9An9eROpY0vHV8KzL/LPaf0VOPacAW9O8NDXGfCeOn1ICkvpCM8OW6J66pTUKRQKW2DBAlc6IXPu\r\n3NlN/lx06dKZno+m8nxTU5Pof+KzZs1UvwsKxW8ctvTiiy/Y2eCX6dKQFLKjrm5SR1I6bZ3BxbOw\r\nWJRfFrAddULqZqHUkaXjmtT9FM531J2H2Ch/+OItubTxORjqGUlXGsRoSd2nNKkje+pC92+F/77n\r\naCqH7A0rY9jScf+An8HpdWO5ZL+NKHXRx2HB9B+19/3nyykwaCArv2w9bisdlLImLIpLXWeYRAal\r\nhMTBEh9P+OCtp02P9xWM8j+kDUkx76ij0y9R7AaMlMpFm38N73/Ce+r6LNeljiZ17VHqyI66rTyp\r\nexe+WLpLT+pW7oDvV+j9dIbJl4u3wOcTp8BTT8vf33/g+e/msx11c7yh7VddtY/9rfV38GInVn75\r\nkNNMunSc7Khr9WMfbcCKg8Nn8LrUU2fsp1umlV+yxeNsR50qv1RSp1AobKT8joyw79SpI6SkHG2y\r\n52Hp0sXQsWOHJpPQ3XXXXU26j1ChuF24us6B7t0/tzupu24akkKk7hJN6q7rky+1pI7sqLtMd9Sx\r\nxeNsRx1ZOp5DdtSdZTvqMuiOuhIqdGRHHSEl/xwcPpYOB5DDmUV8nQGRulNwJLMQojP1HXVi6fje
\r\nmKOw42Ai7IrLkHbUnYQ9fEfd5vBY8A6LB9/DrPxS7KjziYiBNUEx4BOVBBsR78gkXnqZCGvDE2F1\r\nWAKsCq27o27R9lCY4xsCP22L4pMvI+nbLptDYMamYJjmEwRTNwbBFG9kY6i2o27Sht0wds0OGLsp\r\nFMZv3AfjvEPYOoOfg2Dk+r0wYt1eGO5lbUfdLrajzmMb9F68CXou8oFvFm6Er+d7Qw/kS9cN8NX8\r\nzfD14q108TjZUefksga6zlgNXedKO+rmsh11nWesgg6TPKHTTLKjbj28N50tHX+XLx5vM3k1sgLe\r\nHLkE3hizUttRJ0ovXzGtMxCTL0X55dNDFympU1KnUChsgezsDOjX70daird588YmeQ7S0pLhr3/9\r\nK2RkHLfr53ngQBj9dya9lepnX6H47fzwQx+YPHmi3Ukd7anj5ZdXKo3rDETpJVlnoC8evwxn+OJx\r\nInT5xVzqzl2ArLOl2uJxuqNOLB5Hknk/3dFcefH4KSp1ROgOZ7CULvJEHhxAqTMsHpd31B1laV2A\r\nafKlPwrd1uhUiu8hts6ADEoRS8dlqVvDpc5jXxyFSN2yvayXjvXT8R11Wzzh/1kdooJ8uRymbQmn\r\nTNnMhqRM9NkHE5BxG5nUjUKpG4FS5yxJHWHwGn3xOEnqflzsCvfX9zidZ1OpI4vHydJxwmfzN7HF\r\n4z9t1JI6snS88yy2zkAsHe8gpG7qWprWvUOlbrW2eFxbZyB21ElDUuSeOpLSNRumkjoldQqFwubY\r\ntMmbDs0YOnQw5OVlNbnn3779u7BihbvdPj8yyIH8+yqhUyhuH6+99ir4+vrYndRV19TQXXWV2joD\r\nvZ9OHpJCk7qLTOiKNKm7SKUu73w5lTpzUkfKL1N5SpeUx6QuEYWOSF18dpEmdSSpI0vHD55AqUvL\r\nY0kdEsaHpOyjQ1JOUqnbk5hBU7pd8Rkod
WLy5QkqdaT8kiR1vlzoSEJHIFLHdtQRqUtgUod4otCt\r\nDImjKd2yvTGwFMVuyR6UOrF4PCACpqzxhwmr/WC851YY47EVRq/0hZErfGH0+hCW1BGpI2kdkTqe\r\n1I3dEMx31JGkLgilLhCGeZF1BiSp202TukGI6Kf7cSVK26xV0N3FE76Y6QGfz1gJn01fCd2mr4BP\r\n52zUUrrufJ3BZ/M2waeIJnU0qWNLx8nkSyF1LKnz0sovidS9jUInpE7rp6Pll9YXjzvS8ksmdqqn\r\nTkmdQqGwQZKTE6FNm7fpNMjExNgm9dzJwJAOHd6zy+dG9vA9+ugjTapvUKH4vSEThP/85z/bXcJP\r\nLtBrayoBKNegtvoyAKUCuQS1losAlnK8XYa3L+DtUqitKkHOc85B7Y2zyBmkCGqvn8bjKQCk9noB\r\nko/kMSpzkGwkCx/qJNRey0Qy8HY6Hk9Qaq4eh9qrqZxkqLmSBLWEq8fwdgLeToCay3FQUxGLxxhG\r\nRTRymHHpIKW2IgqPkcgBZD8SATUXw5EwJBSqy0OghhKMT20v1BDKA/H2Hry9G9kF1RcCkJ1Qc2EH\r\npfrCNjz6Q3WpH1SXbEW2IL7IZmQT4gPVxd7IBs56qD6/DvHirGGcWwWWc5549KBYzq5AlkM1Yjmz\r\nDI+EpXjbDVmCLIbqM4vAUrQQqosW4HE+WE67cn4Cy6k5eCTMxtsunJnIDLAUTkemIVPBUjAZj5Pw\r\nOBGq8ieAJX88Mg5vj0XG4O3RUJU3Cix5IylVec5QlTscGYZvD8PjELAgSuqU1CkUChuETHEjKw8e\r\nfPAfsGXLpiY1xY5MwbS33kIi54899pjqoVMofochKaQn2d6eF7lAR8tCsbuKUke4gmJXQaWOCl31\r\nRTyWU6GTpQ4sxQBc6qBKlzq4gVJ3HYXuRiFYrubDpQt5cKE4B0rPE7I5WYxzJ5FMToZEOu
PsCTwi\r\nZ9OQ4xKpnBQoPZOMR+RMksQxRtFRPCJFiVBSlIBHRklRPB4JcXg7Do+xUHI6FkpPx1BKTh/B4xE8\r\nRuPxMB6RU4c4Byml9BiFROLtSCgpPIC3OYX7ORGccCQMSgrC+DGUsw8J4QTr5AfhEcnfywlE9ujk\r\n7cbjLjwSAjg7OduhPM8brhf+BFVU5pjQVRVMYVJXMAlvT8QjSl3BeJS5cXgcp0kdEzsudbnOeHSm\r\nUleVO5RKXZWSOiV1CoXC9ssxidiNGTMKCgpymsRz7tr1I5gzZ5bdPJ/jx5PA0dGR/huqn2mF4vYy\r\ndepk+Pbb/9qn1Gkp3RWKMakrZ0mdxZzUFdOkDkhSR6WuCGEpHRG6suJcyMnOhmzFHwSKct5WPaUr\r\nnGJI6ojUVZGkDoXOkj+WUpWnJ3VVeSO40PGkjkrdYDwOVlKnpE6hUNg6cXFH4PXXX6P9ZmQMvr0/\r\nX7KI/M0337CL53LyZDq8+uordAgOfV92BpR83xtK7r0HziCFeJu8T/2cKxS//o9A9tijyqTumiZ1\r\nQKi5jLcvaSmdUeiKKdBA6WVZSZ6SKhuBiR0pvUSpK5wMVTSpm8CSOqn0soqXXlbJpZd5QuiGaSld\r\nVc4gJXVK6hQKRWOADE3p2/dH+Pe/H4V9+/bafY/MvffeS3vQGvu/GVnR8Omn3bSUtaTPd1Dq4ABn\r\nkAIkG8kgYqd+xhWKX/U7ds89f4OEhFg7ljpWeklSOiZ0QurKKEDLL1HqLCUodFJKR6Su6gzeZkmd\r\n5VqhSuhsLLG7XjCbCh0pvTSndFU0pRvDYVInUjq59FIkdVW5SuqU1CkUikaFu7sb/P3vf6dHe36e\r\nPXt+A+PHj23Uz6FHj69oX2Ru7kntfSShO8uFLgtJQhJJYqd+thWKW8bPz9fulo4LHnssB/aHV/LS\r\ny8s0pYMauZ+uTEvqWC+dXnpZJ6l
DqbtUlm9DQpMMns5O4OTsCWl1PhYLrj06wjivYPAc6AQD3UPs\r\nVuzK89bT0suqAmlISoFR6rTSy/xRWj9dnaQuR0mdkjqFQtEoCQkJpIkdSe7IQBV7fI6Bgbvg4Ycf\r\nbrR9hBMnjofnnnOkg1/k95OSS5HQEaGLR6LvuQe2b98O8+fPhxkzZtD/mBWK34MZyPzZs2Drek9I\r\nTT3W6F8nBg7sD8OGDbHPC0iHG8hlaNe2AuWugk+/lCZfVoshKaUGoQNJ6ERKR0ovLxTbVulloKsT\r\nPj9H8I41vj8txJXugFsUEQcujg7gOC7AbqWuJM+P99NNZlLHyy+r8sWAlDGGXroqKaXTSy9ZP50q\r\nv1RSp1AoGimkt65t23fgrbda0RUI9vgcW7R4Ef9T8mp037en5wq6iy4uLrrux7/vrSV0ROgOIxtb\r\ntoTw8HC4VE4u0ix4gcapqtK5cQPg+nX9WFnJuHZN5+pVgCtXGJfxArCiQufSJZ2LeEGIj0UpKzNy\r\n4QJAaSmjpASguFg/nj/POHeOcfYs48wZnaIigNOnGadO6RQWAho6Iz9fJy9PJzcXICcH8GqHkZWl\r\nc/IkQGamTkYGIz1d58QJgLQ0nePHAX9R9GNysk5SEuPYMZ2jRwESE3USEnTi4wH/QRmxsQAxMYwj\r\nR4xERwMcPsw4dEjn4EGAqChGZCTjwAHG/v06ERGAPwyMsDCd0FCAfft0QkIYwcE6QUEAe/cCBAYy\r\n9uzR2b2bUrtrF1zy94dDq1bBHJeZeCoa95TZZs2a0emX9il1l5FLSClyHuXuLESElVKhqxWrDKpK\r\nWemleZVBFSu91IakXD8FpcW5tiU1sd7giK9/TouMSZyvsyM4OI6D2CZQglmc66+VXmopXb4YkMJS\r\nOn3q5QiW0smrDHKY1BGhq8oZqKROSZ1CoWiskJSOLCl/5JGH8ZovyO6en6vrHOjU
qWOj+p6DgvbA\r\nAw88QNNUq5+TlQ6ZKHYJ995DE7rNrVvDcSIUNTV4kVbNaEjszFInxE4WupuJnSx1QuyIzAnMUicQ\r\nUkcQQidLHRE6gZA6InMCIXVC7GSZE0InI4udkDpxFEInjkLoZLETMidISWHIUifEjgidQJY6InMC\r\na1InxI7InEBInSx2ZqkTQidLHRE6WeoaEjuzzAmhk6lH7ADFDk0I0tavpxeBjTWxi4wMh4ce+qfd\r\nTgXWha4YOY0UItkod/mwP+w876ljQ1JEUkeHpNzgqwxkqbPBpC47Ow0WOTkYBS4jBHpoopcM7j1a\r\nQY9Fgfp9EgPBuaMDTfJIyufiG433iYJxHR1hoHuE9nU9B3YERycX7esmBriAYytniMqwsaROljrT\r\nKgNLPUNSWE+dvsrAQhmspE5JnUKhsJc+u/vuuw9Wr/a0q+dFlgnfi/JjNfGyQchuPSLYy5cv+0Wf\r\nT0ouD5GL/dpaJnVC7G4mdAKz1AmxIzInhE4cZaETyGJnFjohdfWldHJSJ4udSOnkpE4InTmtM6d0\r\n9SV1ROQE5rROTunqEzohc0LorKV1ZqEjEJGzltIJ6hO7mwmdOakzi51Z6H5pSmctqRNHWei41BHC\r\nvDxg40bvRvn6QP6gRUrQ7fYCkid0stA5OJxE0pAUaNs2DeXuNE/qeC/dDeNuOnmVQen5XJtLqmK9\r\nnamguYakMfnyHyeVZCaDSysHcJwiyi+jYCCROZS1kNho8HbpwT83DeUP39/KBZLJ5yX7Q0cufZ7R\r\nGXi/DPAkH+/hCRnZtil1VVaGpFTl8f100m46kdLJQidSOiV1SuoUCoWdsGdPAC35Gz16pF09r2+/\r\n7UmHjTSG1LRNm7dhyJBBv/g+CxYsoCWXBqGT07pbSenMSZ0sdtakzlr5pTWha0jsrJVempM6WeyE\r\n1JnLL60lddbKL+WUzlr5p
bXSy1+S0snll0Ls5LJLa1JnrfxSTuvMpZf1lV+aSy/ltM6c0gm5M0ud\r\ntaTOXIJpSukEF7dtBVfXnxrd6wJJ5x599BF8+oE2930lJSXgP1Uw+Pr6wIoV7nTn5rhxY2DAgH7w\r\n3/9+DU5On9CpuK1bvwUvv/wS3WH5xBNP0B7if/zjH3Ty71133cWFrggpkITuOBU6B4cEaNc2FSJC\r\nC40pnbabzrRw/LptSl12WiA4oYA5OvvSt6l8dVzEh6cwqWvFpS450IUK4ED3AIiOioaoQHdavjnO\r\nPxGivQdSifNNRjHkokjo4x6N9w2kkkc+z+Z66nL9tKmXYpWBtdJLbTdd3nA8DjcNSGEpnUVJnZI6\r\nhUJhP5Cx3uQi4eOPu+C1b5rdDIX517/+RUeX2/L3OWrUCGjVquUtDa4hQ1FqhdCZxU5O64TQyUmd\r\nEDpyFFJn7qkzp3RmqSMiJ6d05tJLufxSFjpxtFZ+Kad0DZVgWiu/JBCZI1JHRE6InbWkTi6/FCmd\r\nOakTYvdLkjpzT521Xrr6kjpZ7KyldGahM5dgWuupIyInjnJSR2ROHM1SJ4udLHVC6MxJ3c6dUIuQ\r\nC8Fdu3bi049vNK8LZJflK6+8/Ic8NpE2MnVz/vyfaFpIJI3sESUp/f/8z//A/fffD08//RS0bPkm\r\n3aH3zTc96ECXSZMmwOzZLuDmtgjWrFkFW7Zswn+CbVRM9+8Pwx+pw/Q1nPRIp6UlSwldjkHo2rY9\r\nARE0oTPupzMPSTEkdUTqinNtsq+M9tA59IGQ2AAqXwO9o7UJmdakzogjuAYmQ3aiL7TCt519I6gY\r\ndnT1B2/ydXt4QgRN/5wgJCPbJqXOmNKNN6R0xoXjI26S1A1QUqekTqFQ2BNZWenw2Wfd4Pnnm9OL\r\nhFMod6XLlkD52NH0eKoRyl67dm1pf50tj1Unf2GPj4+5pfvRPVSk9FKUX1
oTuvrKL82DUqz11NXX\r\nT2ctqbuZ2BGRE0drpZfmlK6hpI5gbUCKnNI1lNRZG5RSn9BZS+rq66kzD0mpr5/ul/bUmcsvxVEI\r\nnVnszD115pTOnNSZxa6+lK6B8kvgUicuAA8cCG8UrwlkSNSdWDh+6FAkLMPXzb59f6DJGlknQ/bi\r\nvfrqK9C9+xcwcqQzLF26mL4GkM8lpX63r/zSmNC1bXsS9ofh75sYkqJJndxPd4ZNvRQpHRe62usF\r\nUHo+xyalLi1kERU0R0cHKl8BadnWpS5gCv28KQHJVlckuJJeO8dW9HPco/DzfVli14pM0BzobZvT\r\nLyWp0/rpaFI31rCfzqJNvhxu2k03WCu9VFKnpE6hUNgpkydPgPfuuw+u3X8/4P9sGpaHHoKzgbsa\r\n1XMhF0yPPfaYTa5vIH9RJ2VTPj4bbvm+mtRZK72Upa6+fjrz5EuBSOkE9fXTmadecvJ3LIR+vXqB\r\n25Y4Y1pn7qfTSi9zIWjmUOjXdyak5xRZ76m71dJLaz11mUchfEZ/aP/ss9CiZUvoN3oVVJqELt9r\r\nGvTr3h3cPILqFzohdeayS3PppbkEU07phNhZK720NvlSFjprSZ259NKa1Jn76qwJ3c1KL01JnVnq\r\nCLae2JFSc5Le5+Rk3vavTf4wM2/eXPjkk67wz38+SAexfPRRF7oz09ubnJu4O9hTx4SuXdtsOhiF\r\n7aYTawwucJkj++n0frpacz8dL70E2lOXY6NTIGNhnCNL3hwHehlETZY6MhCF9tQ59ACvwGiaaEYE\r\n+kNgLOvHi3DvwdM7Z4imQ1X8aXpH3ucSmGyzUkfLL/N1oavSSi/lheMjDAvHtdLLnEEoeIOo0FVl\r\n91dSp6ROoVDYIySRu/r3+wxCJ4tdY0vsyF/GSX+KrX1fX3/9FS2v+jX3rTepq6+nrr6Urr6+ul86\r\n+dK0ziBxTmd6IdR
+drj18ksidIbyyyzwaE0unj6AmMzT1pM68+TLm60zsJLU5S/9il+0PQtOHZ4F\r\nh5YTocyU1CVOeI997+O33rynrqF1BmJQijmpIzTUTydPvhQyJ5dfNrTS4JdOvmyop04I3U0mXzYk\r\ndaQU05ZfCz788AOYNm3KbS1bnzx5Irz00kt0MFO3bk60tPLIkYN/6PN87LGDsD+8FGqrK6Q1BuV8\r\n6biVlK7K+tRLW0/qmJD1YfIVkFi/1NWZfmkUtoxoL9pj11H7fJ7eOQyEKJtdaeBnTOnE1Etp4XiV\r\ntMpATurk0ksLTeqU1CmpUygUdgkptbQmdALy8cb0fLy8VkPz5s/Z1Pe0efNG2kfza/sXDUldQ+WX\r\nN9tRJ6d0clJX3466myR16cu604slp9lhdVcZyGmdltRlwboPmNQlnpSSuvp66cxSJ4SuoemXeI79\r\nvmIXcTPXR1svvcRj+uyP2fcuS52QOXKsMyQlAYIGdsH7PAM+2+OZ3JkTuvrKL62ldPUldbc6JMXa\r\n9EtyvFnpZX1JHZE5Kz111qTOx8d2p2H6+2+hyfjtKHMkFQBkZQoZTPLll93p73Nu7kmbea709UFa\r\nOK4ndUzqWEqnLx2vrbN0nE29rL1RgFKXb9NSd8slm/j7nIxkZDTy5eO0/JL30+WzqZcW09JxfZXB\r\ncFNSN4jDUjoldUrqFAqFnUJ66BqSOvLxxvacyKLhDRvW2cT3Qi7+nnnm6d+0RuKWpI4KXSn4jf0a\r\n2n89FYLCNkG/F1ByXngBnMasQ0dKBY/v29K3W3w8GqJOlmtiZymIB49RX0EL/pft9l8OgoAD6Vpa\r\nV3kiECZ0aUM/1qLzAOjXxoFLXbgmdZYTYeDW/0P+1/Hm0G/yz1AmJXXrPjRJnbn0Uiu/RDkb1A3a\r\ndxsB4TtWQz9SdtVtHlSg0FnidoFbn/e1NK7fWA8o46WX6Qt7a3+Z
b9GyA7Rv+R2kJKRDZeRGmNDh\r\nTfb+93pBvzcddKkjfXVJEeAz+Ato34z/Zb/ZG+A8zg2KE1hClz7nv/pf/Z95Bpz64PcSFww+Az6D\r\n9s/w9z/9GjiPWgjFR6xIXZ11BqHg1+sDaN/pRwj3/An6PUW+xlPQ/pPhkB4spC4I/P77PrR//3sI\r\nXzEH+j2Jn/P+OKhAobNs8wC3z9/m39OT0K+vC5Rp5ZcB4NfjPWiPzzN8yXTo9wT5nCegfZcBkL69\r\nAbEzD0qRhM6a1NnqhSCZLEnStCVLFv5mmSPJ/+OPP05LLW11qBT5d6EpHZc6JnNc6OpL6W5YT+ns\r\nTersBb380jj1Uh6QInbTCaHT+um41ImUTkmdkjqFQqGSukYD2f/2R028q3vBNRXeeafNb/9LfH1C\r\nJzBMviwFj6562VH7rl2Nk+DafgztxcfmHWRSdz4aevL3OY1cDkGrZ2hy5xqahUJ2SPt4+wFzwW+h\r\nPg5ck7rcMO1zZq74GTz6Melo77KvblKXebNVBmng0Un6nlu1QkldAhUpu/THWOQJHr3ZwIP2k3dQ\r\nqSvy0b9vp/6jwW3SAsiP0+/TvtcE8JvWT//ex29hUhe/BT/nDXD7aSlErXODCW/wx/DaT9O6Iq8Z\r\n+jn7fCB4zPMBy+GNeJ/XwW3WIohatRAmvMbv4xlsfUiKSeo83tGfn9Mnn2hf36HNeKjgUufRRjoH\r\nr7wC7T+eBBWBnvo5mOgCHp+/zL6vQSt42eVOXubKv3aXLvrXfmsEVJjLLwn19dMJsduxo9FcCM6c\r\nOQ3efPONX33/Y8fioWvXj+kqBDLcxBZ7dOsmdaz0kqR0cumlMaU7Z1hlwFI61k8HVOyY1F2w0emX\r\nTVvqttCUTu6nMw5I4fvp8oyll6SfzqINSRmgpE5JnUKhsOueuozjtHfOmtAV/Z//Az6rPRrdcyJ/\r\nqX/hhedh5
co/treOTBglQxTILqrbLnXW1hloJZilsI5LnWtQLi29DBjyArvAn7UTLFevQnHgZPY2\r\nkbqKCshey3pVHN5xhTJeepmyqAt7X/dVUBg4nQvHdCjmPXUpCzsbyi/TPXqxz/lwFl6I5ENxxGom\r\nWG/Pgwo6+fKkUeqsrTLQSjBPwDoudRNWBGmDUtIXf80eo+MUyE5Ow+fhzh6j5UyooGldKvh0YPfz\r\n2JVMyy+LN45m93lzFBTzEsyUae8Zyy95L50l5gAUhQVDwA9vMFEau5mXYMbAunf51916xDD90hK5\r\nD4r27oaA3q+z+4z8WZc6Oa0zlF6GwjoudW7Ld9DSy8r1E7iItYGYIFJ6GQTruNRNmL5WK79Mn8RK\r\nRx3eHgzZe4KgeNVUdg5eHg4VPKlbx6XObeEmWnpZuXIk/9pvQcx20wTMhtYZNFB+aYsXgjExh+iq\r\ngLCwkF91f7I+gAw9GTRoAP39bQyvd3TlieUST+l4T52lnqmXVfUvHSdCV3s9Dy6VqqTO1ijPW2vo\r\np2NSJ5K6UXxAir7KQNtPp5VfDuDll/3gaqbaU6ekTqFQ2C1kyqVZ7MjbEQvmwYMP/oPuTWpsz2nT\r\nJm86CfOP7H2ZMWMadOr0/u35S7y5/LK+dQZ0SIqQuq8hsYz106V4solvHnHn6XCUihg3JjWuUQap\r\nazHIFyy8p67i8CIucotg/1wueA7joZivMUhZ8IWe1OHbmtTVYQwUWUvqrK0z0Hrq0rjUvQ8pGfr0\r\ny/QlX9fzGMPRGdnky3Vc6ty2xVGpS5zYgX/OUF3qpn6sJ3VE6hL2gmv7ZnW+rhOROtpTd1iTOjef\r\n/ayX7vBOcG33dN37jNpgvadO3lF3aB+Xuk6QGMH76Q6s5wkcl7pIIXVvQ8o+vbdOk7o6fAdFdEiK\r\nkLr3IHEX76ULXMm/NkrdtgbWGdQjdI1B6sjvOtm/SdLxX3
N/d3c3+npHloE3pte6+fPnwcWyIi51\r\n5WyVAZG6KvMaA/PC8aI6pZc1lXlguZoDOUqkbIgMuJ4/w9BPZ144XsUXjhtKL3MGS7vpBmr9dJmH\r\nxsDMmTOV1CmpUygU9pzYWdtTR3bYkV12n3/+aaP5y7Wgfft3YcqUSX9YWvjYY/+hY9Vvq9TdbKWB\r\nQeq6QmIJG5SSsoxJnduh00zqYt0MSV36Sj4x8p0lUMGlLnt1b03qElaJ23OhgiZ15yDIuY2h/FKT\r\nuuZjocjaSgNrSZ05rbMidYmpuWxQSk6OntQ5OkORPChFWmewrqNR6tLnf8mTuglQQVcapEBQ3zcN\r\nSV3KlPZMansuBUtKCqSMY287TfbTpM5DJHVbomlKlzKxHbvP1wvBEh8PKaPa8a+5yXpPnWHypUjq\r\n3tGkzuI7lctZJ0gJNUpdYtABbUCKJnVP9oYiq+sMhNS1ZlIXHAwWr3H8a7eHlJ1Wpl/Wl9I1oqSO\r\n7Ih799129HfvVu8bELCdnp/t2/0a3Wv35s0+EB6211B6SXrpgFLCh6PwheMN9tMV0KSutjIXyoqV\r\nTNkKpbmbaUpH0QakGKdeWng/nSi9rMoZwpeOy6WXLKlbv3ouLFgwX0mdkjqFQtEUOXnyBN3BRIYP\r\nkLHejeX7jowMpxPrEhPv/PdMLg6feurJ29cz09CQFFF6qe2nk6SumCd1SyWpu3q1TlIHheFa35Xz\r\nYn+UiNVa39YEv2SwJK/Xe/QGjIeZ3zWXeur49MucUHASn/PtFAhCEQhavRice06G9NwGkjoic/I6\r\nA95Tt+59LnXHpT11Kbv0x+gxDoI2b4agZT+Bc4+xkJ5KxO4YeGhJXSydemkJd9O/915DYOaXzYw9\r\ndUTqeHLn0H4wBK2Yop2LFl0mQfZhssrgCPh04ff5fgw+L384NpGVnzq06w9BSyfo9/lwPGTvj7Xe\r\nT0e
EzlR+2aLTQAj3XAATXuGJ2/szwUImYGrll20gca80/TLQUz8HH/eFoEWLIGjqGHD+6EdI37PP\r\nUH7Z4r0fIHzJLJjQgn/t9hPBUt/icbmfrpENSiGDTJ544gk4fjzplu8bEhJIl4XbynClWyU19Rj9\r\ntzmeEm8ckkKSOitTL6Gq/iEptZUodddzkRwUuyzIyc5SYvUHJnRE6Kry9VUGVQ0MSZFLL7WkLldK\r\n6nL6Q+DW6bRcd/Xq1UrqlNQpFIqmzOjRI2m/ye7dOxvN9zxgQD/44ovP7vjj/vjj9zBu3JjbJ3Uk\r\nqSMy15DY1ZG6r+skdR6Hi4xJndtBbaVBRdIu6PeOXM73PLhuitXWGqSsG6F/rI0zuDnznrr5+kqD\r\nyuRdMOHD5qaywH6QkisndZ9ZT+rkHXV5x3lS102XOr50vDLaFya872h6jN6QksqSOp9PeKLGkzoi\r\ndilu+nAUhzf7gltf3lM3lffURfpAP+1rNQPXGc6apLluiKRpXbHPdH3giMMwKAtdL93naXCdOlS/\r\nz9qwuoNSrCZ1+D10elX/3joNg+wwffolk7r3mdRJqwwqty6BCW8/aToHn0GKSeqc3ntJ/3j7/pC9\r\nc2/9e+qs7agT2PCgFDLlkvSukj/i3Op9yUTLJ598gpZeNubX5uTkozB79mzYHxEC5aUFUFNVqvXT\r\nQT1CB9ZSOiJ0lTlINsVy5SRcKj0JF85nQuk5QYbO2XQ8nmCcTeMcl0jlpEDpmWQ8JrPjmSTOMeQo\r\noyiRk8CJ58RxYhmnY6AEKT19BI+EaLwdjcfDeDwMJacOUUpPHcQjIYoTie+LxOMBKCk8wI/7kQhO\r\nOCdMpyAU2ccJ4QQjQYz8vRKBnD2c3VCSh+TvwiMhgLOTswNKcrcz8shxG8cPyvPWwfUCFzbxsp79\r\ndHr5pXPdheO5+oCUq5lDIPPwWFjrMYf+Dq9evarO
77GSOjuQutzcbNi2fTvMnz+fmjv5x1b83syA\r\n2XNdYd2GdfSva+qHX9HYWLNmFdx3332wrJFMxSQXbf/+96P4n5bXHX3cFi1a0JHotz2pk3vqzKsM\r\nDGJ3/eY76urZT1eRnw9lSGVJ3R11lqICqCBixfvqKGLxuNhVd+4cVGZnQhkKVUXeKVMJZhHjNH59\r\n8nECSpfGiRNQmZltfem4gO+oq0xKgLKEBKhIPSGVX2YykRNIO+osx+KhAgWrkpRgkomXAm1P3TGo\r\nOHgEKhOT6L46S3QUlB2OwfvxpeOUI1C2fz9UHI7le+pioSI8Eipj2J46y/4w/HgUWGKjoRIFrAIF\r\njBIWplG5/6AkdZ0gJRzfDg+BCrJT7mZLx+UddeRr7d4BZShcFYHBevllyE6tpy6FlF/uwo/j//V1\r\nlo+bZc7a9EuR1Nmo1C1YMA/+93//F4KDA3/V/cePH3tb+l5tJbHbuNEbXF1d1bWWwoCLiwv+riyw\r\nmtDZ+s5JJXW/hFOF9B86NCwcSssvwXVLLYLXAMg1vEa4yrmM1wgV1xmXkIt4jVCOkN77C0gpUoLX\r\nB+ev4P/jeI1wFjmD1whFnNN4jVDIKbiI/0/jNUIekovXBzmc7Av4fzFeH2SUME4UM9KQ43h9kIqk\r\nIMnnAJLw2uAYchSvDRI5CUgcXiPEngaIweuH6ELGYeRQAcBBJAqJxGuEAwS8Pogg4LVBOBKGhOI1\r\nwj68jghBgrPw/zy8NtiLxz143J3JCMDrg50EvD7YgWzH64htiD/ih9cIW/HaYAvii9cGm5FNiE8K\r\ngHcyYwNeJ6w/VgtrjlyCJVsPgcusWfSva+oXQNHYINMcybjvoUMH2/y4bwIZfPCvf/0Lr+tT7sjj\r\nkXPy5z//X3SPzNsrdfWtM6hP7GSpE2J35Yq+dFxePn4ri8eJyJml7qaLx2WhwxfrzN3a6oE6jNxh\
r\nXDxuRejoUSwdN/TUcakTR7F0XF4+TkROFjtp+qW2gJygLR7nEKkTUy/55EsNsXRcLB7fv7b+5/fj\r\nKip1bq+St1+FmH31LB4nWFs8LpaOmxePC1Dq3F4iX/sliNkRbJQ5a+sMGpp+yYXOFssvZ82aSc/n\r\n0aNxv+r+KSlH6R+ojhw5aHev0bt27bR68a5QWIP8vKhrm0Yqdbm5OTBnzhz8fywNLHidcKOaQaSO\r\ncM3ChO4Kp+IGg0gdFbpKLnRXmdAVX+FSxyFip0kdcsqa1JUzmcviQkeljpNewoSOSl0xk7pUk9QR\r\nqNDh9UHcaUnqkCOnJKkrZFJHxY4L3X6OQehyuNAhQVzqAjlC6nZl6kJnkLo0JnVbJKnblMIwSB2y\r\nnoodwDrEfU8a/U9SJXaKxlnukwhvvdUK2rVrixdHtv8z/M03PeCrr768I4+VlpYMd9111+3dQ0XK\r\nL0UJprWkzlyCSYROICd1ROrMYicndrLQCWSpIzInC52c1JmFTls6bhI7WnKZDUUxMZBPOHKEER0N\r\n+YcPQ1HKSaPUyWInpE4MSDELncCc1hGhE1InhE5L6OoROoEsdULshMzFxzORE0dtQEokFKEI5RNQ\r\nijS2b4eiYBS0w1GQ4vYT+M1yg6IDB3WpM6d0clJnFjtrQ1JI2rcvCFJcZ4DfZFcoCpSkLsjKKgMh\r\ndPVNv7TBPXVkEMrAgf3pH5ZuteRSHgi1pdsn8OXHH9nl6/PRo/FKVhS/GPLzoq5rGqnUbcf/VA4e\r\nPATVeH1ApK6qRpc6kdQRrtxgSR3hYgMpXbGU1J3jSd0ZSeio1F1kUmdO6bK42GWakzoudkLoUs4x\r\nqSMclZI6InXxktBpUnfKlNTls6SOsF9O6XJMKZ2QuiwmdHsyGbsyGAFyUpeuC52W0h1nKd1mntJt\r\nTGZs4Endz5LUeSEevjtpuYT6JVA0RkgiRS
bOkfJGMmzA1sswySCFO9E7QxLBu++++7ZKXW01vsgS\r\naq7g7Qq6bBhqLrMx5tWX+OQ7vqNKm4B3QYeMNtem4RWzMecWaYAC3V/FpuOxPVZFEmxBMdtnpffh\r\nwA1pwALtx8k39OXUSL05Ndey8MiouZYJtYRKcsxA0iVOMK6mQc3V45Taq6l4TEFS8TYeryTjkVFz\r\nJQk5BrWEq8fw9lG8nYjHBDw9gngkjlJLjhUxeDsGb8fi7SOcaHybHA9zDkHNpYMSkToXD+BRsB/f\r\njmBcCsejIAz/GfZBTXko3t6Ht0PwNqO6PBiPQRrVZXuhpiwQbweyY9keZDdUX9iFH9uFt/F4IQDZ\r\nibfJcQelhh63Q3UpcmEbvr0Nb/tDDVJd6gfVJVvxyCnxZZSS42ZKTckmPBJ8KDUlG6G6GKHHDVB9\r\n/md2LMbj+fU2IXVkUBOZcNmmzdu3nNBZW91S+cD99P32+Pp84EC4EhbFTSE/J+p6phFLHamrLSu/\r\nBNU1YEjqCHL5pbWUTkhdqZWk7jxP6c5IJZhySpcnpXS07FIqvSQIsUsvMZZf1im9PKuXXdLSy9MM\r\nUX4ppC6aJ3WHePmlOaUTSd0+a0ldll5+SdiVaRS6bebSS44sdaL8ciNP637mUkeF7ijAWkJ0Mbi6\r\n/qR+CRSNGnf3pbSMydaHDezdu5suJj58OOp3fZy8vCz429/+9qsm8dVffnkV5Y1I3GUqc0LsyLJh\r\nKnNc6MT0O/MUPMMSYi5zYncVcKljo87PmPZYsQl5QMWukC0pvmEerpCvjUKnXM9hwxauC6nL4mJ3\r\nEo8nqczVcKmrkYSu5uoJJA1vM6GrvUaE7jgVOip2V1IMMld7VRc6InM1lxMpVOpQ5mpR7Gq50NVe\r\nIcdYCpM5InUxksxF6zJHhY4fK4jQReExShI7lLmL+6nQVVOZY1JXzWWOCR2ROSZ0VOao2BG
ZY1TL\r\nQlfOpK4aZa5aCB1SQ2FCx44odRRJ6kqFzDGhozLHha6G3iZCtwVvb+FiR2RuM5c5pJgJHZW5Ym8J\r\no9BVF//xUufhsZxOqSRl3+R37JYSusy0OkIn7+QUK1zsMbEjpXWkZ0oJjELuoSM/FyqhswOpI0NR\r\nqmtqqdDJSZ2W0lmY0Mn9dCSlu3jdlNRxqRM9dQSa0l02ll0S8i8yRFInl1+KpC6Tl16mm1O683pK\r\nJ/rpiNiRlE5O6mJ5SifKL839dJFyP10eS+nqJHVZvKcuy1h6GZCh99SJlE5InT9P6rby0ksidrLQ\r\nEYTQredSRyBStzqxlv5HqX65FI2/zy6IJnZ9+/74hy78vhmzZ7vAM888DRkZx3/Xx+nUqSMsWrTg\r\nNkrdFS5zktDRhO4SFzs9oUMjoOkcFTq+r4qMNpdTOjmhI1Px6P4qPhnPMPKcJnR89LlB5qSEjo5B\r\nlybn0WO2JHRZXOZO6imdlNDVmBI6InW1UkJXyxM6ltIlWRc6kdBRmUs0JHSa2HGZE0mdSOh0oWNS\r\nV2tI6aI45pROSuguygldKBc7KaETYifJHIULXXWZntAxmdtjSOhIOldDjih05pROFjqR0GkyxxM6\r\nKnSl5OjLZW6zIaHT0rkSbyZy4qgJ3c9/qNRFRUVA27bv0N/bX7v3kZRcWhM6QWkjGfykUCiU1NW5\r\nQKgRpZein05IndxPd8OY1F3k/XRaT508JIWndA320100JnWi/PLkBWNKZ+6n05K6c3o/nSi/JEIX\r\nx4k5VX8/nVx6KZdfhubU7amz1k8npG5Huknq0vSkTvTUbU7V++k2SkNSzKWXJK1bkwiG/yhVDK5o\r\n3NPXkujC7zfeeB3i4o7Y7PdJeus6d/7wd32MpUsXw2uvvfqrFiFbL79kKR0TOi5zVkouaUpXJWSO\r\nHUVCp8vceX3MuTbq/KyU0p3mI8+L
pHLLQtP483xjQnddT+lqhNBdz+bllid5uSWRugwudBlaSlfD\r\nhU5O6Wip5bXjWkJHSi4ZKHSa1B2lYldX6OIpLJ2L0xI6JnIxPKWzInQineMyV1shCx2TuWqe0DGp\r\nCzdKXXmoVHa5j8ucnNCRZE5InS5zLJ3bo6VztOzyApO6Gl52WS2ErlTI3HYmc6Lk8oIxpasu5emc\r\nlNBVywkdTek2GqWOipw3L7v8WZO56vPrKHda6uLiouHbb3vSKoCpUyf/psFDpIeuIakjH1ev4QqF\r\nolFKnbn00ix1YvLlZSF01/Wk7mall0VS6eUpLnQFpqROHpJiTunqTL48VzepS2yo9LLwl/XThVuZ\r\neimGpOw19dMFSP10ZECKeUjKVtPUS4LWT5dkRep4+aVZ6lTDqqKxQyRmzJhR8OCD/wAfnw02+T1m\r\nZaVT4SJlXL9nCWbLlm9Cq1Ytb09Sx8suRUInyi6Z1JVxsdP76PSyS1FyWULLLvWdVaKPTpc541Ji\r\nqY+uTtmlJHQI653LNSV0UkonlV2KhM5YdsnTOSmh08suSS+d3kMnEjqtj06UXV5JNCR0QuhqJamr\r\n1cROF7pacqQyZ+qjq5BTugOS2MkJHeujqy4P08outZJLLaUL0UouhdiRhK5a9NCVB0qllnpCx3rn\r\nAviRlVzWGProWNklS+r86iZ0XOZqDD10UkLHhY710XnrQicSOqnskkmd1x2TuvDwffDdd73gnnv+\r\nRvdMJiUl/OavqZI6hUJhv1JXz5CUSiuTL4XUWUvpzENSrCZ18pAUuZ+urO6QlAaTOmnqpZC6eD79\r\nkgidefLl4UK9/FJMviQrDepdZdBAUkcnX5rKL+usMuCIlM6Q1CUbyy+9ONakTo2WVdgDW7ZsoguB\r\nR4wYbpNrD8g486eeehLefPON3+0x0tNT6cj1Xr2+/U1f57HHcmB/2BVJ5i7pCZ2hj
06InBiMYr3k\r\nEmhSJ8oujX10dYTuhpzQ5RvRRE7vn6sR/XNWSi5rtHQuQ+uhs5rQSULH+ufqG4rCZE7vozMndFzo\r\nKkwyd/mIcSiKKaHThS7SkNLRPjoqcvt5Hx0fiCKErjyUpXQXQ6XBKMFaUldNZY730NGkTiR00mAU\r\nrX8uQOuhEyWXusxt14aiGProtP45aTCKOaWjPXSbUOb0Prq2lY4QVjZRGo7ChY5K3TqwoND93lJ3\r\n8uQJWLnSHd5+uzX9g9CwYUNui8zJUy+bYk+dQqFoQkldlXlIipC6G/puOsOQFLPUXdHTOnP5ZaGc\r\n0lkZkqKtM7hQt59OG5Jyzvoqg0RJ6OQdddaSuoP1DUnJMQ1JyTKuM9iTadpRZx6SkmYakpKql15u\r\nkgak1DckhQjdaitSp5ZAKuyFxMRYmlaRSXVkBYKtfX9kSiWRrlmzZvyu0/qaN3+O9thFR/+6fVgO\r\nDjeQy9Cu7SWUu4tU7Fgyd9EodDyhE0NR2JFPuuRll7V8wqU+5fKM1ktnGI5y3TjpsvaGqY9O66HL\r\nlQaiyAmdqYdOS+n+P3vnHV5VmXXxPNOd5qfjjOOMjo4FY0OxgQhhVMQK2CgqoqCiNOlVUCC0SIdQ\r\nQodQAoSSQAghIUCAQCABEhJIIL0AKfSee5P9vfvt7zknqDMoAc4f67mhZxjJvb+71l4r3dZyKRw6\r\nI3Ipb+iSL39DV4VDpxeiqFKU7ZpLt81sujwtIpdbqrih26SAzrij0xw6DnT00bHp0umGbo3Rdqlc\r\nOmy6dLqhW3GZGzoOdI4uneWGTkYug8Hnkg/4nPEBvxMPQkxpPw51czjQMZfup4A6vGudMWMaNGv2\r\nLi0Wwru5SZPGX7F9xx/Sfonfvl7bL125cnWDOnW6SydHxx2aL49VNWdg3ac7VcU+HXn9sT85Dtq/\r\n/gIbYX29K3w9vB80ee0F+G
LOAQl1yWlJ0PeLpnystSa8NyAM4o6q6OXOAwegf+dWcD8fc33qna4w\r\nKrKIN1+ehqEdW8GTbw+B0cuWQRNf8nN8a0K9Dgth8a5M6Pb+C/Tb977cD8bGe6qcM5AuXbpy6aqK\r\nXur3dALsREmKzaXbzV263c5Qd7UHXV25utKzBxhzvP32v1XLOCY2Yd5OXtiNHz/mJ/szDh48AD17\r\ndqe3Qc2avQerV6/6kVB3hugUURlRMYG7IxAbU8Zjl+qOzrih06cL9Ds6UYpy6YhDy2WhFrcscL6h\r\nE6UooumSu3QVGtDJlsvzPHJ5IUPe0il3jjt0FOr06QLRcqnHLvVylN0scilcurOs5VK4dBToqDO3\r\nU97R2Vsu47V2S+HSxWnFKBaH7pRy6Lwc5qQ7x4HOK2/oooyWS3VLt9Z2R+c17uhMh06owmi5FE6d\r\n7s5xqCtdIp06050zHTod5kTcEoHO5xRRGVExgbsiAndH+sjYJdOs//m5Cv8dhIYugb59e9M3em66\r\n6SaoX78eDBny7X89IP5jtW75Uuh821/oDR1GLl2HzpUrV9c81BnRS8uUge2e7oK2UWcZHteBzume\r\nLp8DnbynK0iCphzE6nSbBtMmDeHg5gPPDkti93TZSfAm/76OU8JgYDsGgM/4J7GNuuwUeI3/eINO\r\nc2BCYICEu45hJbAt/zT0auQjf99ajZrKj6meawpP8I8fH5hkOHVyykDc02WY93TW5ku9JEW/qRP3\r\ndLpLp5ekzNot2i9dqHN1YygkZCEFu3btPoPMzPRq9bnhgPEdd9zxkzp2okimX78+dC/vnnvugc8+\r\na0udiu+LmSmgKyEqJMonyiRwlwMbY45wl461XLK4pYhdEpDzaA7dJdOhs93QSahTTZdgc+iytUcO\r\ndUbLpcWls93R7decOuHQidgl36HTmi4R5NQd3W4D6iqpFNBVUmnFKMKhM+7
otrE7OsOh0+/nLtd0\r\nyd25UxssQBetilFORlXZdCkduhNii26NpRhFv6FbJR06CnO6Q3cslDt1yzSQY8Uoyp0L4TFLu0NX\r\nYYU6AXQlRIVE+USZBO6yCdwV9qZA92OhDiENAQ6B7f33W8CTT9aC3/3ud1CzZk349NM2MGvW9J+8\r\ngdZJb7/9Fnz9dT/3a7IrV66uM6izRC8vaNFLAXWnL6mSFKfoZbElenlYc+mcmi93hHGIqzcBdvGC\r\nlNVjGHS9hFBHXousntaO/ZxXJ0BE1gXYuHEZPIDffn4abCOvR8Im8x+vOwE28JKUhSM4uL2zEDYS\r\nqOvPoa794iJakDL805r028/3jYTobAJlC9jnUZdAnbyncxgd/6HNlyHa8Lg+ZWBtvpyrQV1V8UsX\r\n6lxdr8I7NowhYhxx48aYavW5bdmyicJW+/Zf/DyOwboI6NOnFzRo4Ac33/xnCpXoXnzySWvo378v\r\njaGhs4k/Tzh0OtD5+BwkSiNKAT+/NAJ3BbzlUqhYRS4vWYfFD5vD4rTpstAsRdEdOjlZoFw6MSxe\r\nYcQuD0qXTge6CsuweAUfFq/UxsUl0J1NsezQmbFLWYxiDIs7NF0akUu95TJe7dBp4+KVxg7dZrlD\r\nh49qi04fFo82HTqLS6daLs0tOlaMsoZA2mpaiqIil+GaO7fKMi6uDYvLYhQxWcAe1Q5diAQ6xy06\r\noxiFlaIIh04HOp+DRGlEKQTuUmtATF5P+lw1eXIgTJgwHsaMGU03VnEiBO9mW7X6AF599RV48MEH\r\nqQOHrvTTTz8FH374Pn2zBAEP7+au5r/x7du30M8Lvw65X49duXJ1XUKdKEnRR8dFSYpw6Y47uHQl\r\nHOxEQcphh5KUPEtJSriAL58hsIPPGayd2EpCHUYvJdTZNATWHQZYFch+/P7Pw2B7EStI2RA9jbtw\r\n02AdgbqvKdS1gpkZ
rPVy9ij2Z3SLPE1v6VZHsp9f95skx3s6Eb/E6GU4d+lEScplXboUc86ANl86\r\nxC+FS+dCnasbUSNGDCMgczOMHh1Q7aATWzFxa+/ndhHw3m7+/DkwePC39M9v2rQJ1K37HDzyyMMc\r\n6IqI8jSgS6VA5+OTCA389kFsdL7WdGnZoqOTBUe1yKVDMcqlgqqhTgyMW8fFnVw6Ebk8n2GfLtDG\r\nxSvFuLj1hs4yLm6DubOWcXHjhk6/pdtuOHSVli066tDp4+JOkUvdocOWS+sNnZB2Q2e0XOrTBSfM\r\ncfEKbVxcuXO6S7fCEer0UpQKLjlbwF26ijJ9umChQ+TSAnUIdEVEeRrQpTKg80kkUJdCoC6XQV3r\r\n1q2hbdu20K5dO+jYsSN88EFLWmqC4DZ9+lSIjFwDaWnJ1fLrTqNGL9Pop/s12JUrV9cd1DnNGZy3\r\n7NPpUwY2qDtr36gTYFfVPl3s3K7cqQuAHdSpK4HBzXycnbqHh0CMPmXAS1JCx7biTt002MSdutBJ\r\n7eT3RUunrinM3M+gbtYw9ms6hR+nrZcS6jSnLpKDne7UhYvmy6qil3rzpcM9nd586RS9nO5Cnasb\r\nVOjUIbC89NKLsGvXjmrzeeHdT/PmzejQ8datm6vHE4R06LIMoEOHLja6wJguEDAHRuRSb7p0Ghcv\r\nsN/QXbK6dNmO4+IVGtCplkvh0okNOt2lSzWaLiuMuGWyxaVTkcuqtuhEyyUFOjkqXpVLx5ouK/Wm\r\nS10ibnlSFaN4jWHxDZpDF8036KJk06XXuJ+L5G2X4oYuwnGLTrZcUrBTLZfijk5ELqsqRhHOnF6K\r\nYsQuRSlKid2hEy2X0qHLMoGOOnQE5rzFM8B7dMY1/VwVGDgB7r3335Dh3tC5cuXqur6p0126S+Y9\r\nndF8ed6yUXdOxS8PWwpSCpyaL3FwPHsD+ArnrV5TeElz4hDqcMYgN
SsJXuTf98xHATB5VRxMnjkH\r\nPmwVAMsJkCUe2AFP8x9vOTIS5q1YCK/yb7eenwtb8xTUzUhjzZezOdR1JFCHzZer11qgztp8eVBz\r\n6dJNl85akmJtvhRzBkb00qH5EjU90YU6VzeusOWua9ev4JZbboGxY0dXq88tIGA43HrrrTB69HfV\r\nAOpMh87PLwM2xhTJOzr9hk4Wo8gdOr5FJ0HusHPs0nDn8rS4pbqlqzDcucyqb+hoMYraoRNQJ4Cu\r\nkkcv9dilgjnnLTrZcHk2kYMd36HTY5cc6kQxinDopEunTxcIh06PXdLI5SZeiCJ26GL5DZ0AuhjT\r\noTu53nJDp4EddejWyhs6jFxSoNO26ETs0ryhWymHxcUWHQO6pYZLJwfGLxe5LOU3dKU60M03xsWt\r\nDp1f+oM0buktnqnp2oW6sLAV9GtMVFSE+3XXlStX1x/U2UpSqhgdlxt155n0mzqbS2cBO9voOAe7\r\n3VvDoOkjDMJqd10IUzhwPcvjlzhlkJgcB5+9WtMSv+wKS3OYWxcXvwHerqv/WE3oOPsAmzLIPw39\r\nePwSoU536rqt5lAnnLqhyqmTJSkH1eh4eFX3dJb4pWi+XKTd1M23uHTGPp3r1LlyZdyXPfSQb7Vz\r\n7fDz8vX1
<TRUNCATED>
[12/50] [abbrv] airavata git commit: Implemented execution logic of
the workflow data model
Posted by sh...@apache.org.
Implemented execution logic of the workflow data model
Project: http://git-wip-us.apache.org/repos/asf/airavata/repo
Commit: http://git-wip-us.apache.org/repos/asf/airavata/commit/55319c96
Tree: http://git-wip-us.apache.org/repos/asf/airavata/tree/55319c96
Diff: http://git-wip-us.apache.org/repos/asf/airavata/diff/55319c96
Branch: refs/heads/master
Commit: 55319c96d2c7ace7ab7b458dbd4fd259649d2e8e
Parents: 27f6f1b
Author: shamrath <sh...@gmail.com>
Authored: Sun Feb 22 16:55:55 2015 -0500
Committer: shamrath <sh...@gmail.com>
Committed: Sun Feb 22 16:55:55 2015 -0500
----------------------------------------------------------------------
.../engine/SimpleWorkflowInterpreter.java | 92 +++++++++++++++++---
.../workflow/engine/WorkflowFactoryImpl.java | 4 +-
.../simple/workflow/engine/WorkflowUtil.java | 10 +++
.../simple/workflow/engine/dag/port/InPort.java | 4 +
.../workflow/engine/dag/port/InputPortIml.java | 16 +++-
.../engine/parser/AiravataDefaultParser.java | 71 ++++++++++++---
6 files changed, 169 insertions(+), 28 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/airavata/blob/55319c96/modules/simple-workflow/src/main/java/org/apache/ariavata/simple/workflow/engine/SimpleWorkflowInterpreter.java
----------------------------------------------------------------------
diff --git a/modules/simple-workflow/src/main/java/org/apache/ariavata/simple/workflow/engine/SimpleWorkflowInterpreter.java b/modules/simple-workflow/src/main/java/org/apache/ariavata/simple/workflow/engine/SimpleWorkflowInterpreter.java
index e122fa6..3c2596d 100644
--- a/modules/simple-workflow/src/main/java/org/apache/ariavata/simple/workflow/engine/SimpleWorkflowInterpreter.java
+++ b/modules/simple-workflow/src/main/java/org/apache/ariavata/simple/workflow/engine/SimpleWorkflowInterpreter.java
@@ -49,6 +49,7 @@ import org.apache.ariavata.simple.workflow.engine.dag.nodes.WorkflowNode;
import org.apache.ariavata.simple.workflow.engine.dag.nodes.WorkflowOutputNode;
import org.apache.ariavata.simple.workflow.engine.dag.port.InPort;
import org.apache.ariavata.simple.workflow.engine.dag.port.OutPort;
+import org.apache.ariavata.simple.workflow.engine.parser.AiravataDefaultParser;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -58,6 +59,7 @@ import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
+import java.util.concurrent.ConcurrentHashMap;
public class SimpleWorkflowInterpreter implements Runnable{
@@ -69,12 +71,18 @@ public class SimpleWorkflowInterpreter implements Runnable{
private String credentialToken;
- private Map<String, WorkflowNode> readList = new HashMap<String, WorkflowNode>();
- private Map<String, WorkflowNode> waitingList = new HashMap<String, WorkflowNode>();
- private Map<String, ProcessPack> processingQueue = new HashMap<String, ProcessPack>();
+ private Map<String, WorkflowNode> readList = new ConcurrentHashMap<String, WorkflowNode>();
+ private Map<String, WorkflowNode> waitingList = new ConcurrentHashMap<String, WorkflowNode>();
+ private Map<String, ProcessPack> processingQueue = new ConcurrentHashMap<String, ProcessPack>();
private Map<String, ProcessPack> completeList = new HashMap<String, ProcessPack>();
private Registry registry;
private EventBus eventBus = new EventBus();
+ private List<WorkflowOutputNode> completeWorkflowOutputs = new ArrayList<WorkflowOutputNode>();
+
+ public SimpleWorkflowInterpreter(String experimentId, String credentialToken) throws RegistryException {
+ setExperiment(experimentId);
+ this.credentialToken = credentialToken;
+ }
public SimpleWorkflowInterpreter(Experiment experiment, String credentialStoreToken) {
// read the workflow file and build the topology to a DAG. Then execute that dag
@@ -87,11 +95,14 @@ public class SimpleWorkflowInterpreter implements Runnable{
public void launchWorkflow() throws Exception {
// process workflow input nodes
- WorkflowFactoryImpl wfFactory = WorkflowFactoryImpl.getInstance();
- WorkflowParser workflowParser = wfFactory.getWorkflowParser(experiment.getExperimentID(), credentialToken);
+// WorkflowFactoryImpl wfFactory = WorkflowFactoryImpl.getInstance();
+// WorkflowParser workflowParser = wfFactory.getWorkflowParser(experiment.getExperimentID(), credentialToken);
+ WorkflowParser workflowParser = new AiravataDefaultParser(experiment, credentialToken);
+ log.debug("Initialized workflow parser");
setWorkflowInputNodes(workflowParser.parse());
+ log.debug("Parsed the workflow and got the workflow input nodes");
processWorkflowInputNodes(getWorkflowInputNodes());
- processReadyList();
+// processReadyList();
// process workflow application nodes
// process workflow output nodes
}
@@ -100,10 +111,17 @@ public class SimpleWorkflowInterpreter implements Runnable{
private synchronized void processReadyList() {
for (WorkflowNode readyNode : readList.values()) {
try {
+ if (readyNode instanceof WorkflowOutputNode) {
+ WorkflowOutputNode wfOutputNode = (WorkflowOutputNode) readyNode;
+ completeWorkflowOutputs.add(wfOutputNode);
+ continue;
+ }
WorkflowNodeDetails workflowNodeDetails = createWorkflowNodeDetails(readyNode);
TaskDetails process = getProcess(workflowNodeDetails);
- addToProcessingQueue(new ProcessPack(readyNode, workflowNodeDetails, process));
- publishToProcessQueue(process);
+ ProcessPack processPack = new ProcessPack(readyNode, workflowNodeDetails, process);
+ addToProcessingQueue(processPack);
+// publishToProcessQueue(process);
+ publishToProcessQueue(processPack);
} catch (RegistryException e) {
// FIXME : handle this exception
}
@@ -116,6 +134,41 @@ public class SimpleWorkflowInterpreter implements Runnable{
//TODO: publish to process queue.
}
+ // TODO : remove this test method
+ private void publishToProcessQueue(ProcessPack process) {
+ WorkflowNode workflowNode = process.getWorkflowNode();
+ if (workflowNode instanceof ApplicationNode) {
+ ApplicationNode applicationNode = (ApplicationNode) workflowNode;
+ List<InPort> inputPorts = applicationNode.getInputPorts();
+ if (applicationNode.getNodeName().equals("Add")) {
+ applicationNode.getOutputPorts().get(0).getOutputObject().setValue(String.valueOf(
+ Integer.parseInt(inputPorts.get(0).getInputObject().getValue()) + Integer.parseInt(inputPorts.get(1).getInputObject().getValue())));
+ } else if (applicationNode.getNodeName().equals("Multiply")) {
+ applicationNode.getOutputPorts().get(0).getOutputObject().setValue(String.valueOf(
+ Integer.parseInt(inputPorts.get(0).getInputObject().getValue()) * Integer.parseInt(inputPorts.get(1).getInputObject().getValue())));
+ } else if (applicationNode.getNodeName().equals("Subtract")) {
+ applicationNode.getOutputPorts().get(0).getOutputObject().setValue(String.valueOf(
+ Integer.parseInt(inputPorts.get(0).getInputObject().getValue()) - Integer.parseInt(inputPorts.get(1).getInputObject().getValue())));
+ } else {
+ throw new RuntimeException("Invalid Application name");
+ }
+
+ for (Edge edge : applicationNode.getOutputPorts().get(0).getOutEdges()) {
+ WorkflowUtil.copyValues(applicationNode.getOutputPorts().get(0).getOutputObject(), edge.getToPort().getInputObject());
+ if (edge.getToPort().getNode().isReady()) {
+ addToReadyQueue(edge.getToPort().getNode());
+ } else {
+ addToWaitingQueue(edge.getToPort().getNode());
+ }
+ }
+ } else if (workflowNode instanceof WorkflowOutputNode) {
+ WorkflowOutputNode wfOutputNode = (WorkflowOutputNode) workflowNode;
+ throw new RuntimeException("Workflow output node in processing queue");
+ }
+
+ processingQueue.remove(process.getTaskDetails().getTaskID());
+ }
+
private TaskDetails getProcess(WorkflowNodeDetails wfNodeDetails) throws RegistryException {
// create workflow taskDetails from workflowNodeDetails
TaskDetails taskDetails = ExperimentModelUtil.cloneTaskFromWorkflowNodeDetails(getExperiment(), wfNodeDetails);
@@ -165,13 +218,16 @@ public class SimpleWorkflowInterpreter implements Runnable{
Set<WorkflowNode> tempNodeSet = new HashSet<WorkflowNode>();
for (WorkflowInputNode wfInputNode : wfInputNodes) {
if (wfInputNode.isReady()) {
+ log.debug("Workflow node : " + wfInputNode.getNodeId() + " is ready to execute");
for (Edge edge : wfInputNode.getOutPort().getOutEdges()) {
- edge.getToPort().setInputObject(
- WorkflowUtil.copyValues(wfInputNode.getInputObject(), edge.getToPort().getInputObject()));
+ edge.getToPort().getInputObject().setValue(wfInputNode.getInputObject().getValue());
if (edge.getToPort().getNode().isReady()) {
addToReadyQueue(edge.getToPort().getNode());
+ log.debug("Added workflow node : " + edge.getToPort().getNode().getNodeId() + " to the readyQueue");
} else {
addToWaitingQueue(edge.getToPort().getNode());
+ log.debug("Added workflow node " + edge.getToPort().getNode().getNodeId() + " to the waitingQueue");
+
}
}
}
@@ -213,6 +269,8 @@ public class SimpleWorkflowInterpreter implements Runnable{
@Subscribe
public void taskOutputChanged(TaskOutputChangeEvent taskOutputEvent){
String taskId = taskOutputEvent.getTaskIdentity().getTaskId();
+ log.debug("Task Output changed event received for workflow node : " +
+ taskOutputEvent.getTaskIdentity().getWorkflowNodeId() + ", task : " + taskId);
ProcessPack processPack = processingQueue.get(taskId);
Set<WorkflowNode> tempWfNodeSet = new HashSet<WorkflowNode>();
if (processPack != null) {
@@ -236,6 +294,7 @@ public class SimpleWorkflowInterpreter implements Runnable{
}
}
processingQueue.remove(taskId);
+ log.debug("removed task from processing queue : " + taskId);
}
}
@@ -257,12 +316,12 @@ public class SimpleWorkflowInterpreter implements Runnable{
case INPUT_DATA_STAGING:
processPack.getWorkflowNode().setNodeState(NodeState.PRE_PROCESSING);
break;
- case OUTPUT_DATA_STAGING:
- processPack.getWorkflowNode().setNodeState(NodeState.POST_PROCESSING);
- break;
case EXECUTING:
processPack.getWorkflowNode().setNodeState(NodeState.EXECUTING);
break;
+ case OUTPUT_DATA_STAGING:
+ processPack.getWorkflowNode().setNodeState(NodeState.POST_PROCESSING);
+ break;
case POST_PROCESSING:
processPack.getWorkflowNode().setNodeState(NodeState.POST_PROCESSING);
break;
@@ -327,15 +386,22 @@ public class SimpleWorkflowInterpreter implements Runnable{
public void run() {
// TODO: Auto generated method body.
try {
+ log.debug("Launching workflow");
launchWorkflow();
while (!(waitingList.isEmpty() && readList.isEmpty())) {
processReadyList();
+ Thread.sleep(1000);
}
} catch (Exception e) {
e.printStackTrace();
}
}
+ private void setExperiment(String experimentId) throws RegistryException {
+ experiment = (Experiment) getRegistry().get(RegistryModelType.EXPERIMENT, experimentId);
+ log.debug("Retrieve Experiment for experiment id : " + experimentId);
+ }
+
class TempPublisher implements Runnable {
private TaskDetails tempTaskDetails;
http://git-wip-us.apache.org/repos/asf/airavata/blob/55319c96/modules/simple-workflow/src/main/java/org/apache/ariavata/simple/workflow/engine/WorkflowFactoryImpl.java
----------------------------------------------------------------------
diff --git a/modules/simple-workflow/src/main/java/org/apache/ariavata/simple/workflow/engine/WorkflowFactoryImpl.java b/modules/simple-workflow/src/main/java/org/apache/ariavata/simple/workflow/engine/WorkflowFactoryImpl.java
index a6173ac..dd84df0 100644
--- a/modules/simple-workflow/src/main/java/org/apache/ariavata/simple/workflow/engine/WorkflowFactoryImpl.java
+++ b/modules/simple-workflow/src/main/java/org/apache/ariavata/simple/workflow/engine/WorkflowFactoryImpl.java
@@ -33,13 +33,15 @@ public class WorkflowFactoryImpl implements WorkflowFactory {
private WorkflowParser workflowParser;
+ private static final String synch = "sync";
+
private WorkflowFactoryImpl(){
}
public static WorkflowFactoryImpl getInstance() {
if (workflowFactoryImpl == null) {
- synchronized (workflowFactoryImpl) {
+ synchronized (synch) {
if (workflowFactoryImpl == null) {
workflowFactoryImpl = new WorkflowFactoryImpl();
}
http://git-wip-us.apache.org/repos/asf/airavata/blob/55319c96/modules/simple-workflow/src/main/java/org/apache/ariavata/simple/workflow/engine/WorkflowUtil.java
----------------------------------------------------------------------
diff --git a/modules/simple-workflow/src/main/java/org/apache/ariavata/simple/workflow/engine/WorkflowUtil.java b/modules/simple-workflow/src/main/java/org/apache/ariavata/simple/workflow/engine/WorkflowUtil.java
index d4bbad3..688b170 100644
--- a/modules/simple-workflow/src/main/java/org/apache/ariavata/simple/workflow/engine/WorkflowUtil.java
+++ b/modules/simple-workflow/src/main/java/org/apache/ariavata/simple/workflow/engine/WorkflowUtil.java
@@ -41,6 +41,9 @@ public class WorkflowUtil {
&& !fromInputObj.getApplicationArgument().trim().equals("")) {
toInputObj.setApplicationArgument(fromInputObj.getApplicationArgument());
}
+ if (toInputObj.getType() == null) {
+ toInputObj.setType(fromInputObj.getType());
+ }
return fromInputObj;
}
@@ -50,4 +53,11 @@ public class WorkflowUtil {
}
+ public static OutputDataObjectType copyValues(InputDataObjectType inputObject, OutputDataObjectType outputObject) {
+ if (outputObject == null) {
+ outputObject = new OutputDataObjectType();
+ }
+ outputObject.setValue(inputObject.getValue());
+ return outputObject;
+ }
}
http://git-wip-us.apache.org/repos/asf/airavata/blob/55319c96/modules/simple-workflow/src/main/java/org/apache/ariavata/simple/workflow/engine/dag/port/InPort.java
----------------------------------------------------------------------
diff --git a/modules/simple-workflow/src/main/java/org/apache/ariavata/simple/workflow/engine/dag/port/InPort.java b/modules/simple-workflow/src/main/java/org/apache/ariavata/simple/workflow/engine/dag/port/InPort.java
index c635bef..bac10ee 100644
--- a/modules/simple-workflow/src/main/java/org/apache/ariavata/simple/workflow/engine/dag/port/InPort.java
+++ b/modules/simple-workflow/src/main/java/org/apache/ariavata/simple/workflow/engine/dag/port/InPort.java
@@ -34,4 +34,8 @@ public interface InPort extends Port {
public void addEdge(Edge edge);
+ public String getDefaultValue();
+
+ public void setDefaultValue(String defaultValue);
+
}
http://git-wip-us.apache.org/repos/asf/airavata/blob/55319c96/modules/simple-workflow/src/main/java/org/apache/ariavata/simple/workflow/engine/dag/port/InputPortIml.java
----------------------------------------------------------------------
diff --git a/modules/simple-workflow/src/main/java/org/apache/ariavata/simple/workflow/engine/dag/port/InputPortIml.java b/modules/simple-workflow/src/main/java/org/apache/ariavata/simple/workflow/engine/dag/port/InputPortIml.java
index 1971a1d..82160a9 100644
--- a/modules/simple-workflow/src/main/java/org/apache/ariavata/simple/workflow/engine/dag/port/InputPortIml.java
+++ b/modules/simple-workflow/src/main/java/org/apache/ariavata/simple/workflow/engine/dag/port/InputPortIml.java
@@ -26,10 +26,11 @@ import org.apache.ariavata.simple.workflow.engine.dag.nodes.WorkflowNode;
public class InputPortIml implements InPort {
private InputDataObjectType inputDataObjectType;
- private boolean isSatisfy = false;
+ private boolean ready = false;
private String portId;
private Edge edge;
private WorkflowNode node;
+ private String defaultValue;
public InputPortIml(String portId) {
this.portId = portId;
@@ -38,6 +39,8 @@ public class InputPortIml implements InPort {
@Override
public void setInputObject(InputDataObjectType inputObject) {
this.inputDataObjectType = inputObject;
+ ready = (inputDataObjectType.getValue() != null && !inputDataObjectType.getValue().equals(""))
+ || !inputDataObjectType.isIsRequired();
}
@Override
@@ -56,8 +59,17 @@ public class InputPortIml implements InPort {
}
@Override
+ public String getDefaultValue() {
+ return defaultValue;
+ }
+
+ public void setDefaultValue(String defaultValue) {
+ this.defaultValue = defaultValue;
+ }
+
+ @Override
public boolean isReady() {
- return inputDataObjectType.getValue() != null && !inputDataObjectType.getValue().equals("");
+ return getInputObject() != null && inputDataObjectType.getValue() != null && !inputDataObjectType.getValue().equals("");
}
@Override
http://git-wip-us.apache.org/repos/asf/airavata/blob/55319c96/modules/simple-workflow/src/main/java/org/apache/ariavata/simple/workflow/engine/parser/AiravataDefaultParser.java
----------------------------------------------------------------------
diff --git a/modules/simple-workflow/src/main/java/org/apache/ariavata/simple/workflow/engine/parser/AiravataDefaultParser.java b/modules/simple-workflow/src/main/java/org/apache/ariavata/simple/workflow/engine/parser/AiravataDefaultParser.java
index 39e422a..e7ac5cb 100644
--- a/modules/simple-workflow/src/main/java/org/apache/ariavata/simple/workflow/engine/parser/AiravataDefaultParser.java
+++ b/modules/simple-workflow/src/main/java/org/apache/ariavata/simple/workflow/engine/parser/AiravataDefaultParser.java
@@ -21,6 +21,7 @@
package org.apache.ariavata.simple.workflow.engine.parser;
+import com.sun.corba.se.pept.encoding.OutputObject;
import org.airavata.appcatalog.cpi.AppCatalogException;
import org.airavata.appcatalog.cpi.WorkflowCatalog;
import org.apache.aiaravata.application.catalog.data.impl.AppCatalogFactory;
@@ -41,6 +42,7 @@ import org.apache.airavata.workflow.model.graph.GraphException;
import org.apache.airavata.workflow.model.graph.Node;
import org.apache.airavata.workflow.model.graph.impl.NodeImpl;
import org.apache.airavata.workflow.model.graph.system.OutputNode;
+import org.apache.airavata.workflow.model.graph.system.SystemDataPort;
import org.apache.airavata.workflow.model.graph.ws.WSNode;
import org.apache.airavata.workflow.model.graph.ws.WSPort;
import org.apache.airavata.workflow.model.wf.Workflow;
@@ -100,9 +102,6 @@ public class AiravataDefaultParser implements WorkflowParser {
for (InputDataObjectType dataObjectType : experimentInputs) {
inputDataMap.put(dataObjectType.getName(), dataObjectType);
}
- OutPort outPort = null;
- InPort inPort = null;
- Edge edge = null;
for (Node gNode : gNodes) {
wfInputNode = new WorkflowInputNodeImpl(gNode.getID(), gNode.getName());
wfInputNode.setInputObject(inputDataMap.get(wfInputNode.getNodeName()));
@@ -133,13 +132,12 @@ public class AiravataDefaultParser implements WorkflowParser {
dataPort = portContainer.getDataPort();
inPort = portContainer.getInPort();
Node node = dataPort.getNode();
- inPort.setInputObject(getInputDataObject(dataPort));
+// inPort.setInputObject(getInputDataObject(dataPort));
if (node instanceof WSNode) {
WSNode wsNode = (WSNode) node;
WorkflowNode wfNode = wfNodes.get(wsNode.getID());
if (wfNode == null) {
- wfApplicationNode = new ApplicationNodeImpl(wsNode.getID(),
- wsNode.getComponent().getApplication().getApplicationId());
+ wfApplicationNode = createApplicationNode(wsNode);
wfNodes.put(wfApplicationNode.getNodeId(), wfApplicationNode);
nextPortContainerList.addAll(processOutPorts(wsNode, wfApplicationNode));
} else if (wfNode instanceof ApplicationNode) {
@@ -152,7 +150,7 @@ public class AiravataDefaultParser implements WorkflowParser {
}else if (node instanceof OutputNode) {
OutputNode oNode = (OutputNode) node;
- wfOutputNode = new WorkflowOutputNodeImpl(oNode.getID(), oNode.getName());
+ wfOutputNode = createWorkflowOutputNode(oNode);
wfOutputNode.setInPort(inPort);
wfNodes.put(wfOutputNode.getNodeId(), wfOutputNode);
}
@@ -161,18 +159,33 @@ public class AiravataDefaultParser implements WorkflowParser {
}
+ private WorkflowOutputNode createWorkflowOutputNode(OutputNode oNode) {
+ WorkflowOutputNodeImpl workflowOutputNode = new WorkflowOutputNodeImpl(oNode.getID(), oNode.getName());
+ OutputDataObjectType outputDataObjectType = new OutputDataObjectType();
+ outputDataObjectType.setType(oNode.getParameterType());
+ workflowOutputNode.setOutputObject(outputDataObjectType);
+ return workflowOutputNode;
+ }
+
+ private ApplicationNode createApplicationNode(WSNode wsNode) {
+ ApplicationNode applicationNode = new ApplicationNodeImpl(wsNode.getID(),
+ wsNode.getComponent().getApplication().getApplicationId());
+// wsNode.getComponent().getInputPorts()
+ return applicationNode;
+ }
+
private List<PortContainer> processOutPorts(Node node, WorkflowNode wfNode) {
OutPort outPort ;
Edge edge;
InPort inPort = null;
List<PortContainer> portContainers = new ArrayList<PortContainer>();
for (DataPort dataPort : node.getOutputPorts()) {
- outPort = new OutPortImpl(dataPort.getID());
+ outPort = createOutPort(dataPort);
for (DataEdge dataEdge : dataPort.getEdges()) {
edge = new DirectedEdge();
edge.setFromPort(outPort);
outPort.addEdge(edge);
- inPort = getInPort(dataEdge.getToPort());
+ inPort = createInPort(dataEdge.getToPort());
edge.setToPort(inPort);
inPort.addEdge(edge);
portContainers.add(new PortContainer(dataEdge.getToPort(), inPort));
@@ -181,7 +194,7 @@ public class AiravataDefaultParser implements WorkflowParser {
if (wfNode instanceof WorkflowInputNode) {
WorkflowInputNode workflowInputNode = (WorkflowInputNode) wfNode;
workflowInputNode.setOutPort(outPort);
- }else if (wfNode instanceof ApplicationNode) {
+ } else if (wfNode instanceof ApplicationNode) {
ApplicationNode applicationNode = ((ApplicationNode) wfNode);
applicationNode.addOutPort(outPort);
// applicationNode.addInPort(inPort);
@@ -190,8 +203,42 @@ public class AiravataDefaultParser implements WorkflowParser {
return portContainers;
}
- private InPort getInPort(DataPort toPort) {
- return new InputPortIml(toPort.getID());
+ private OutPort createOutPort(DataPort dataPort) {
+ OutPortImpl outPort = new OutPortImpl(dataPort.getID());
+ OutputDataObjectType outputDataObjectType = new OutputDataObjectType();
+ if (dataPort instanceof WSPort) {
+ WSPort wsPort = (WSPort) dataPort;
+ outputDataObjectType.setName(wsPort.getFromNode().getName());
+ outputDataObjectType.setType(wsPort.getType());
+ }else if (dataPort instanceof SystemDataPort) {
+ SystemDataPort sysPort = (SystemDataPort) dataPort;
+ outputDataObjectType.setName(sysPort.getFromNode().getName());
+ outputDataObjectType.setType(sysPort.getType());
+ }
+
+ outPort.setOutputObject(outputDataObjectType);
+ return outPort;
+ }
+
+ private InPort createInPort(DataPort toPort) {
+ InPort inPort = new InputPortIml(toPort.getID());
+ InputDataObjectType inputDataObjectType = new InputDataObjectType();
+ if (toPort instanceof WSPort) {
+ WSPort wsPort = (WSPort) toPort;
+ inputDataObjectType.setName(wsPort.getName());
+ inputDataObjectType.setType(wsPort.getType());
+ inputDataObjectType.setApplicationArgument(wsPort.getComponentPort().getApplicationArgument());
+ inputDataObjectType.setIsRequired(!wsPort.getComponentPort().isOptional());
+ inputDataObjectType.setInputOrder(wsPort.getComponentPort().getInputOrder());
+
+ inPort.setDefaultValue(wsPort.getComponentPort().getDefaultValue());
+ }else if (toPort instanceof SystemDataPort) {
+ SystemDataPort sysPort = (SystemDataPort) toPort;
+ inputDataObjectType.setName(sysPort.getName());
+ inputDataObjectType.setType(sysPort.getType());
+ }
+ inPort.setInputObject(inputDataObjectType);
+ return inPort;
}
private InputDataObjectType getInputDataObject(DataPort dataPort) {
[27/50] [abbrv] airavata git commit: Removed sys out from the
WirterTask.
Posted by sh...@apache.org.
Removed sys out from the WirterTask.
Project: http://git-wip-us.apache.org/repos/asf/airavata/repo
Commit: http://git-wip-us.apache.org/repos/asf/airavata/commit/44d89ee4
Tree: http://git-wip-us.apache.org/repos/asf/airavata/tree/44d89ee4
Diff: http://git-wip-us.apache.org/repos/asf/airavata/diff/44d89ee4
Branch: refs/heads/master
Commit: 44d89ee486c0ecafa94ba2254ef226a9de0b7dd0
Parents: 917adad
Author: shamrath <sh...@gmail.com>
Authored: Fri Mar 6 15:14:00 2015 -0500
Committer: shamrath <sh...@gmail.com>
Committed: Fri Mar 6 15:14:00 2015 -0500
----------------------------------------------------------------------
.../java/org/apache/airavata/messaging/core/stats/WriterTask.java | 1 -
1 file changed, 1 deletion(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/airavata/blob/44d89ee4/modules/messaging/core/src/main/java/org/apache/airavata/messaging/core/stats/WriterTask.java
----------------------------------------------------------------------
diff --git a/modules/messaging/core/src/main/java/org/apache/airavata/messaging/core/stats/WriterTask.java b/modules/messaging/core/src/main/java/org/apache/airavata/messaging/core/stats/WriterTask.java
index b154ad7..e1a1b2f 100644
--- a/modules/messaging/core/src/main/java/org/apache/airavata/messaging/core/stats/WriterTask.java
+++ b/modules/messaging/core/src/main/java/org/apache/airavata/messaging/core/stats/WriterTask.java
@@ -21,7 +21,6 @@ public class WriterTask extends TimerTask {
@Override
public void run() {
try {
- System.out.println("########### calling Write Task ############");
StatCounter statCounter = StatCounter.getInstance();
List<Long> contPer10S = statCounter.getMessageContPer10S();
fos = new FileOutputStream(file, false);
[04/50] [abbrv] airavata git commit: Modified Test cases
Posted by sh...@apache.org.
Modified Test cases
Project: http://git-wip-us.apache.org/repos/asf/airavata/repo
Commit: http://git-wip-us.apache.org/repos/asf/airavata/commit/263522a2
Tree: http://git-wip-us.apache.org/repos/asf/airavata/tree/263522a2
Diff: http://git-wip-us.apache.org/repos/asf/airavata/diff/263522a2
Branch: refs/heads/master
Commit: 263522a29d601d547d05ee835709a8ae4e16cd40
Parents: 9445b7a
Author: shamrath <sh...@gmail.com>
Authored: Mon Feb 16 21:52:33 2015 -0500
Committer: shamrath <sh...@gmail.com>
Committed: Mon Feb 16 21:52:33 2015 -0500
----------------------------------------------------------------------
.../engine/parser/AiravataDefaultParser.java | 16 ++++++++++++----
.../engine/parser/AiravataDefaultParserTest.java | 13 +++++++++++++
2 files changed, 25 insertions(+), 4 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/airavata/blob/263522a2/modules/simple-workflow/src/main/java/org/apache/ariavata/simple/workflow/engine/parser/AiravataDefaultParser.java
----------------------------------------------------------------------
diff --git a/modules/simple-workflow/src/main/java/org/apache/ariavata/simple/workflow/engine/parser/AiravataDefaultParser.java b/modules/simple-workflow/src/main/java/org/apache/ariavata/simple/workflow/engine/parser/AiravataDefaultParser.java
index d2095c8..baca99e 100644
--- a/modules/simple-workflow/src/main/java/org/apache/ariavata/simple/workflow/engine/parser/AiravataDefaultParser.java
+++ b/modules/simple-workflow/src/main/java/org/apache/ariavata/simple/workflow/engine/parser/AiravataDefaultParser.java
@@ -134,12 +134,16 @@ public class AiravataDefaultParser implements WorkflowParser {
inPort.setInputObject(getInputDataObject(dataPort));
if (node instanceof WSNode) {
WSNode wsNode = (WSNode) node;
- wfApplicationNode = (ApplicationNode) wfNodes.get(wsNode.getID());
- if (wfApplicationNode == null) {
+ WorkflowNode wfNode = wfNodes.get(wsNode.getID());
+ if (wfNode == null) {
wfApplicationNode = new ApplicationNodeImpl(wsNode.getID(),
wsNode.getComponent().getApplication().getApplicationId());
wfNodes.put(wfApplicationNode.getNodeId(), wfApplicationNode);
nextPortContainerList.addAll(processOutPorts(wsNode, wfApplicationNode));
+ } else if (wfNode instanceof ApplicationNode) {
+ wfApplicationNode = (ApplicationNode) wfNode;
+ } else {
+ // TODO : handle this scenario
}
inPort.setNode(wfApplicationNode);
wfApplicationNode.addInPort(inPort);
@@ -149,7 +153,6 @@ public class AiravataDefaultParser implements WorkflowParser {
wfOutportNode = new WorkflowOutputNodeImpl(oNode.getID(), oNode.getName());
wfOutportNode.setInPort(inPort);
}
- buildModel(nextPortContainerList);
// set the workflow node to inPort
// if require check the types of inputs and output ports,
// add outputPorts to the workflow node
@@ -157,6 +160,7 @@ public class AiravataDefaultParser implements WorkflowParser {
// add inport and indataport to the list
// recursively call the function.
}
+ buildModel(nextPortContainerList);
}
@@ -183,7 +187,7 @@ public class AiravataDefaultParser implements WorkflowParser {
}else if (wfNode instanceof ApplicationNode) {
ApplicationNode applicationNode = ((ApplicationNode) wfNode);
applicationNode.addOutPort(outPort);
- applicationNode.addInPort(inPort);
+// applicationNode.addInPort(inPort);
}
}
return portContainers;
@@ -242,4 +246,8 @@ public class AiravataDefaultParser implements WorkflowParser {
}
return list;
}
+
+ public Map<String, WorkflowNode> getWfNodes() {
+ return wfNodes;
+ }
}
http://git-wip-us.apache.org/repos/asf/airavata/blob/263522a2/modules/simple-workflow/src/test/java/org/apache/ariavata/simple/workflow/engine/parser/AiravataDefaultParserTest.java
----------------------------------------------------------------------
diff --git a/modules/simple-workflow/src/test/java/org/apache/ariavata/simple/workflow/engine/parser/AiravataDefaultParserTest.java b/modules/simple-workflow/src/test/java/org/apache/ariavata/simple/workflow/engine/parser/AiravataDefaultParserTest.java
index 0d56aa4..ea955d8 100644
--- a/modules/simple-workflow/src/test/java/org/apache/ariavata/simple/workflow/engine/parser/AiravataDefaultParserTest.java
+++ b/modules/simple-workflow/src/test/java/org/apache/ariavata/simple/workflow/engine/parser/AiravataDefaultParserTest.java
@@ -5,7 +5,9 @@ import org.apache.airavata.model.appcatalog.appinterface.DataType;
import org.apache.airavata.model.appcatalog.appinterface.InputDataObjectType;
import org.apache.airavata.model.workspace.experiment.Experiment;
import org.apache.airavata.workflow.model.wf.Workflow;
+import org.apache.ariavata.simple.workflow.engine.dag.nodes.ApplicationNode;
import org.apache.ariavata.simple.workflow.engine.dag.nodes.WorkflowInputNode;
+import org.apache.ariavata.simple.workflow.engine.dag.nodes.WorkflowNode;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
@@ -15,6 +17,7 @@ import java.io.File;
import java.io.FileReader;
import java.util.ArrayList;
import java.util.List;
+import java.util.Map;
public class AiravataDefaultParserTest {
@@ -67,5 +70,15 @@ public class AiravataDefaultParserTest {
Assert.assertNotNull(workflowInputNodes);
Assert.assertEquals(3, workflowInputNodes.size());
+ Map<String, WorkflowNode> wfNodes = parser.getWfNodes();
+ for (String wfId : wfNodes.keySet()) {
+ WorkflowNode wfNode = wfNodes.get(wfId);
+ if (wfNode instanceof ApplicationNode) {
+ ApplicationNode node = (ApplicationNode) wfNode;
+ Assert.assertEquals(2, node.getInputPorts().size());
+ Assert.assertEquals(1, node.getOutputPorts().size());
+ }
+ }
+
}
}
\ No newline at end of file
[06/50] [abbrv] airavata git commit: Added Apache license header and
update AiravataDefaultParser test
Posted by sh...@apache.org.
Added Apache license header and update AiravataDefaultParser test
Project: http://git-wip-us.apache.org/repos/asf/airavata/repo
Commit: http://git-wip-us.apache.org/repos/asf/airavata/commit/308291f5
Tree: http://git-wip-us.apache.org/repos/asf/airavata/tree/308291f5
Diff: http://git-wip-us.apache.org/repos/asf/airavata/diff/308291f5
Branch: refs/heads/master
Commit: 308291f5296dc8d1325856a5aa1aba21eb7d2143
Parents: 9fcf226
Author: shamrath <sh...@gmail.com>
Authored: Wed Feb 18 07:53:20 2015 -0500
Committer: shamrath <sh...@gmail.com>
Committed: Wed Feb 18 07:53:20 2015 -0500
----------------------------------------------------------------------
.../engine/SimpleWorkflowInterpreter.java | 1 -
.../simple/workflow/engine/WfNodeContainer.java | 24 +++++++--
.../simple/workflow/engine/WorkflowFactory.java | 21 ++++++++
.../workflow/engine/WorkflowFactoryImpl.java | 8 ---
.../simple/workflow/engine/WorkflowParser.java | 2 -
.../simple/workflow/engine/WorkflowUtil.java | 24 +++++++--
.../workflow/engine/dag/edge/DirectedEdge.java | 21 ++++++++
.../simple/workflow/engine/dag/edge/Edge.java | 24 +++++++--
.../engine/dag/nodes/ApplicationNodeImpl.java | 2 -
.../workflow/engine/dag/nodes/NodeType.java | 24 +++++++--
.../engine/dag/nodes/WorkflowInputNode.java | 3 --
.../engine/dag/nodes/WorkflowInputNodeImpl.java | 3 --
.../engine/dag/nodes/WorkflowOutputNode.java | 1 -
.../dag/nodes/WorkflowOutputNodeImpl.java | 3 --
.../workflow/engine/dag/port/InputPortIml.java | 3 +-
.../workflow/engine/dag/port/OutPortImpl.java | 24 +++++++--
.../simple/workflow/engine/dag/port/Port.java | 3 --
.../engine/parser/AiravataDefaultParser.java | 53 ++++++++------------
.../workflow/engine/parser/PortContainer.java | 21 ++++++++
.../simple/workflow/engine/WorkflowDAGTest.java | 23 ++++++++-
.../parser/AiravataDefaultParserTest.java | 35 ++++++++++++-
21 files changed, 246 insertions(+), 77 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/airavata/blob/308291f5/modules/simple-workflow/src/main/java/org/apache/ariavata/simple/workflow/engine/SimpleWorkflowInterpreter.java
----------------------------------------------------------------------
diff --git a/modules/simple-workflow/src/main/java/org/apache/ariavata/simple/workflow/engine/SimpleWorkflowInterpreter.java b/modules/simple-workflow/src/main/java/org/apache/ariavata/simple/workflow/engine/SimpleWorkflowInterpreter.java
index 3d5b99a..bc9c9a2 100644
--- a/modules/simple-workflow/src/main/java/org/apache/ariavata/simple/workflow/engine/SimpleWorkflowInterpreter.java
+++ b/modules/simple-workflow/src/main/java/org/apache/ariavata/simple/workflow/engine/SimpleWorkflowInterpreter.java
@@ -36,7 +36,6 @@ import org.apache.airavata.registry.cpi.ChildDataType;
import org.apache.airavata.registry.cpi.Registry;
import org.apache.airavata.registry.cpi.RegistryException;
import org.apache.airavata.registry.cpi.RegistryModelType;
-import org.apache.ariavata.simple.workflow.engine.dag.edge.Edge;
import org.apache.ariavata.simple.workflow.engine.dag.nodes.ApplicationNode;
import org.apache.ariavata.simple.workflow.engine.dag.nodes.NodeState;
import org.apache.ariavata.simple.workflow.engine.dag.nodes.WorkflowInputNode;
http://git-wip-us.apache.org/repos/asf/airavata/blob/308291f5/modules/simple-workflow/src/main/java/org/apache/ariavata/simple/workflow/engine/WfNodeContainer.java
----------------------------------------------------------------------
diff --git a/modules/simple-workflow/src/main/java/org/apache/ariavata/simple/workflow/engine/WfNodeContainer.java b/modules/simple-workflow/src/main/java/org/apache/ariavata/simple/workflow/engine/WfNodeContainer.java
index d7e0c2a..e0cebd6 100644
--- a/modules/simple-workflow/src/main/java/org/apache/ariavata/simple/workflow/engine/WfNodeContainer.java
+++ b/modules/simple-workflow/src/main/java/org/apache/ariavata/simple/workflow/engine/WfNodeContainer.java
@@ -1,11 +1,29 @@
+/*
+ *
+ * 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.ariavata.simple.workflow.engine;
import org.apache.airavata.model.workspace.experiment.WorkflowNodeDetails;
import org.apache.ariavata.simple.workflow.engine.dag.nodes.WorkflowNode;
-/**
- * Created by shameera on 2/9/15.
- */
public class WfNodeContainer {
private WorkflowNode workflowNode;
private WorkflowNodeDetails wfNodeDetails;
http://git-wip-us.apache.org/repos/asf/airavata/blob/308291f5/modules/simple-workflow/src/main/java/org/apache/ariavata/simple/workflow/engine/WorkflowFactory.java
----------------------------------------------------------------------
diff --git a/modules/simple-workflow/src/main/java/org/apache/ariavata/simple/workflow/engine/WorkflowFactory.java b/modules/simple-workflow/src/main/java/org/apache/ariavata/simple/workflow/engine/WorkflowFactory.java
index 6cfceaf..b0ee4a1 100644
--- a/modules/simple-workflow/src/main/java/org/apache/ariavata/simple/workflow/engine/WorkflowFactory.java
+++ b/modules/simple-workflow/src/main/java/org/apache/ariavata/simple/workflow/engine/WorkflowFactory.java
@@ -1,3 +1,24 @@
+/*
+ *
+ * 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.ariavata.simple.workflow.engine;
/**
http://git-wip-us.apache.org/repos/asf/airavata/blob/308291f5/modules/simple-workflow/src/main/java/org/apache/ariavata/simple/workflow/engine/WorkflowFactoryImpl.java
----------------------------------------------------------------------
diff --git a/modules/simple-workflow/src/main/java/org/apache/ariavata/simple/workflow/engine/WorkflowFactoryImpl.java b/modules/simple-workflow/src/main/java/org/apache/ariavata/simple/workflow/engine/WorkflowFactoryImpl.java
index f84acc9..f489a12 100644
--- a/modules/simple-workflow/src/main/java/org/apache/ariavata/simple/workflow/engine/WorkflowFactoryImpl.java
+++ b/modules/simple-workflow/src/main/java/org/apache/ariavata/simple/workflow/engine/WorkflowFactoryImpl.java
@@ -30,7 +30,6 @@ public class WorkflowFactoryImpl implements WorkflowFactory {
private static WorkflowFactoryImpl workflowFactoryImpl;
- private WorkflowEnactor workflowEnactor;
private WorkflowParser workflowParser;
private WorkflowFactoryImpl(){
@@ -57,11 +56,4 @@ public class WorkflowFactoryImpl implements WorkflowFactory {
return workflowParser;
}
- @Override
- public WorkflowEnactor getWorkflowEnactor() {
- if (workflowEnactor == null) {
- workflowEnactor = new WorkflowEnactor();
- }
- return workflowEnactor;
- }
}
http://git-wip-us.apache.org/repos/asf/airavata/blob/308291f5/modules/simple-workflow/src/main/java/org/apache/ariavata/simple/workflow/engine/WorkflowParser.java
----------------------------------------------------------------------
diff --git a/modules/simple-workflow/src/main/java/org/apache/ariavata/simple/workflow/engine/WorkflowParser.java b/modules/simple-workflow/src/main/java/org/apache/ariavata/simple/workflow/engine/WorkflowParser.java
index b8b6367..adf0447 100644
--- a/modules/simple-workflow/src/main/java/org/apache/ariavata/simple/workflow/engine/WorkflowParser.java
+++ b/modules/simple-workflow/src/main/java/org/apache/ariavata/simple/workflow/engine/WorkflowParser.java
@@ -21,8 +21,6 @@
package org.apache.ariavata.simple.workflow.engine;
-import org.airavata.appcatalog.cpi.AppCatalogException;
-import org.apache.airavata.registry.cpi.RegistryException;
import org.apache.ariavata.simple.workflow.engine.dag.nodes.WorkflowInputNode;
import java.util.List;
http://git-wip-us.apache.org/repos/asf/airavata/blob/308291f5/modules/simple-workflow/src/main/java/org/apache/ariavata/simple/workflow/engine/WorkflowUtil.java
----------------------------------------------------------------------
diff --git a/modules/simple-workflow/src/main/java/org/apache/ariavata/simple/workflow/engine/WorkflowUtil.java b/modules/simple-workflow/src/main/java/org/apache/ariavata/simple/workflow/engine/WorkflowUtil.java
index 0d720b0..71d0288 100644
--- a/modules/simple-workflow/src/main/java/org/apache/ariavata/simple/workflow/engine/WorkflowUtil.java
+++ b/modules/simple-workflow/src/main/java/org/apache/ariavata/simple/workflow/engine/WorkflowUtil.java
@@ -1,11 +1,29 @@
+/*
+ *
+ * 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.ariavata.simple.workflow.engine;
import org.apache.airavata.model.appcatalog.appinterface.InputDataObjectType;
import org.apache.airavata.model.appcatalog.appinterface.OutputDataObjectType;
-/**
- * Created by shameera on 2/9/15.
- */
public class WorkflowUtil {
public static InputDataObjectType copyValues(InputDataObjectType fromInputObj, InputDataObjectType toInputObj){
http://git-wip-us.apache.org/repos/asf/airavata/blob/308291f5/modules/simple-workflow/src/main/java/org/apache/ariavata/simple/workflow/engine/dag/edge/DirectedEdge.java
----------------------------------------------------------------------
diff --git a/modules/simple-workflow/src/main/java/org/apache/ariavata/simple/workflow/engine/dag/edge/DirectedEdge.java b/modules/simple-workflow/src/main/java/org/apache/ariavata/simple/workflow/engine/dag/edge/DirectedEdge.java
index 000cd06..9e1544e 100644
--- a/modules/simple-workflow/src/main/java/org/apache/ariavata/simple/workflow/engine/dag/edge/DirectedEdge.java
+++ b/modules/simple-workflow/src/main/java/org/apache/ariavata/simple/workflow/engine/dag/edge/DirectedEdge.java
@@ -1,3 +1,24 @@
+/*
+ *
+ * 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.ariavata.simple.workflow.engine.dag.edge;
import org.apache.ariavata.simple.workflow.engine.dag.port.InPort;
http://git-wip-us.apache.org/repos/asf/airavata/blob/308291f5/modules/simple-workflow/src/main/java/org/apache/ariavata/simple/workflow/engine/dag/edge/Edge.java
----------------------------------------------------------------------
diff --git a/modules/simple-workflow/src/main/java/org/apache/ariavata/simple/workflow/engine/dag/edge/Edge.java b/modules/simple-workflow/src/main/java/org/apache/ariavata/simple/workflow/engine/dag/edge/Edge.java
index 667a01d..cc8116a 100644
--- a/modules/simple-workflow/src/main/java/org/apache/ariavata/simple/workflow/engine/dag/edge/Edge.java
+++ b/modules/simple-workflow/src/main/java/org/apache/ariavata/simple/workflow/engine/dag/edge/Edge.java
@@ -1,8 +1,26 @@
+/*
+ *
+ * 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.ariavata.simple.workflow.engine.dag.edge;
-import org.apache.airavata.model.appcatalog.appinterface.InputDataObjectType;
-import org.apache.airavata.model.appcatalog.appinterface.OutputDataObjectType;
-import org.apache.ariavata.simple.workflow.engine.dag.nodes.WorkflowNode;
import org.apache.ariavata.simple.workflow.engine.dag.port.InPort;
import org.apache.ariavata.simple.workflow.engine.dag.port.OutPort;
http://git-wip-us.apache.org/repos/asf/airavata/blob/308291f5/modules/simple-workflow/src/main/java/org/apache/ariavata/simple/workflow/engine/dag/nodes/ApplicationNodeImpl.java
----------------------------------------------------------------------
diff --git a/modules/simple-workflow/src/main/java/org/apache/ariavata/simple/workflow/engine/dag/nodes/ApplicationNodeImpl.java b/modules/simple-workflow/src/main/java/org/apache/ariavata/simple/workflow/engine/dag/nodes/ApplicationNodeImpl.java
index fd7e3c7..36d4349 100644
--- a/modules/simple-workflow/src/main/java/org/apache/ariavata/simple/workflow/engine/dag/nodes/ApplicationNodeImpl.java
+++ b/modules/simple-workflow/src/main/java/org/apache/ariavata/simple/workflow/engine/dag/nodes/ApplicationNodeImpl.java
@@ -19,10 +19,8 @@
*
*/
-
package org.apache.ariavata.simple.workflow.engine.dag.nodes;
-
import org.apache.ariavata.simple.workflow.engine.dag.port.InPort;
import org.apache.ariavata.simple.workflow.engine.dag.port.OutPort;
http://git-wip-us.apache.org/repos/asf/airavata/blob/308291f5/modules/simple-workflow/src/main/java/org/apache/ariavata/simple/workflow/engine/dag/nodes/NodeType.java
----------------------------------------------------------------------
diff --git a/modules/simple-workflow/src/main/java/org/apache/ariavata/simple/workflow/engine/dag/nodes/NodeType.java b/modules/simple-workflow/src/main/java/org/apache/ariavata/simple/workflow/engine/dag/nodes/NodeType.java
index cfb7c3d..9cef6ab 100644
--- a/modules/simple-workflow/src/main/java/org/apache/ariavata/simple/workflow/engine/dag/nodes/NodeType.java
+++ b/modules/simple-workflow/src/main/java/org/apache/ariavata/simple/workflow/engine/dag/nodes/NodeType.java
@@ -1,8 +1,26 @@
+/*
+ *
+ * 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.ariavata.simple.workflow.engine.dag.nodes;
-/**
- * Created by shameera on 1/29/15.
- */
public enum NodeType {
APPLICATION,
WORKFLOW_INPUT,
http://git-wip-us.apache.org/repos/asf/airavata/blob/308291f5/modules/simple-workflow/src/main/java/org/apache/ariavata/simple/workflow/engine/dag/nodes/WorkflowInputNode.java
----------------------------------------------------------------------
diff --git a/modules/simple-workflow/src/main/java/org/apache/ariavata/simple/workflow/engine/dag/nodes/WorkflowInputNode.java b/modules/simple-workflow/src/main/java/org/apache/ariavata/simple/workflow/engine/dag/nodes/WorkflowInputNode.java
index b27fdea..0c1d0b4 100644
--- a/modules/simple-workflow/src/main/java/org/apache/ariavata/simple/workflow/engine/dag/nodes/WorkflowInputNode.java
+++ b/modules/simple-workflow/src/main/java/org/apache/ariavata/simple/workflow/engine/dag/nodes/WorkflowInputNode.java
@@ -22,11 +22,8 @@
package org.apache.ariavata.simple.workflow.engine.dag.nodes;
import org.apache.airavata.model.appcatalog.appinterface.InputDataObjectType;
-import org.apache.ariavata.simple.workflow.engine.dag.edge.Edge;
import org.apache.ariavata.simple.workflow.engine.dag.port.OutPort;
-import java.util.List;
-
public interface WorkflowInputNode extends WorkflowNode {
public InputDataObjectType getInputObject();
http://git-wip-us.apache.org/repos/asf/airavata/blob/308291f5/modules/simple-workflow/src/main/java/org/apache/ariavata/simple/workflow/engine/dag/nodes/WorkflowInputNodeImpl.java
----------------------------------------------------------------------
diff --git a/modules/simple-workflow/src/main/java/org/apache/ariavata/simple/workflow/engine/dag/nodes/WorkflowInputNodeImpl.java b/modules/simple-workflow/src/main/java/org/apache/ariavata/simple/workflow/engine/dag/nodes/WorkflowInputNodeImpl.java
index 0f6ea92..38092dd 100644
--- a/modules/simple-workflow/src/main/java/org/apache/ariavata/simple/workflow/engine/dag/nodes/WorkflowInputNodeImpl.java
+++ b/modules/simple-workflow/src/main/java/org/apache/ariavata/simple/workflow/engine/dag/nodes/WorkflowInputNodeImpl.java
@@ -17,14 +17,11 @@
* under the License.
*/
-
-
package org.apache.ariavata.simple.workflow.engine.dag.nodes;
import org.apache.airavata.model.appcatalog.appinterface.InputDataObjectType;
import org.apache.ariavata.simple.workflow.engine.dag.port.OutPort;
-
public class WorkflowInputNodeImpl implements WorkflowInputNode {
private NodeState myState = NodeState.READY;
http://git-wip-us.apache.org/repos/asf/airavata/blob/308291f5/modules/simple-workflow/src/main/java/org/apache/ariavata/simple/workflow/engine/dag/nodes/WorkflowOutputNode.java
----------------------------------------------------------------------
diff --git a/modules/simple-workflow/src/main/java/org/apache/ariavata/simple/workflow/engine/dag/nodes/WorkflowOutputNode.java b/modules/simple-workflow/src/main/java/org/apache/ariavata/simple/workflow/engine/dag/nodes/WorkflowOutputNode.java
index a1ff6d4..63a52a3 100644
--- a/modules/simple-workflow/src/main/java/org/apache/ariavata/simple/workflow/engine/dag/nodes/WorkflowOutputNode.java
+++ b/modules/simple-workflow/src/main/java/org/apache/ariavata/simple/workflow/engine/dag/nodes/WorkflowOutputNode.java
@@ -22,7 +22,6 @@
package org.apache.ariavata.simple.workflow.engine.dag.nodes;
import org.apache.airavata.model.appcatalog.appinterface.OutputDataObjectType;
-import org.apache.ariavata.simple.workflow.engine.dag.edge.Edge;
import org.apache.ariavata.simple.workflow.engine.dag.port.InPort;
public interface WorkflowOutputNode extends WorkflowNode {
http://git-wip-us.apache.org/repos/asf/airavata/blob/308291f5/modules/simple-workflow/src/main/java/org/apache/ariavata/simple/workflow/engine/dag/nodes/WorkflowOutputNodeImpl.java
----------------------------------------------------------------------
diff --git a/modules/simple-workflow/src/main/java/org/apache/ariavata/simple/workflow/engine/dag/nodes/WorkflowOutputNodeImpl.java b/modules/simple-workflow/src/main/java/org/apache/ariavata/simple/workflow/engine/dag/nodes/WorkflowOutputNodeImpl.java
index ec3a1ea..32db82c 100644
--- a/modules/simple-workflow/src/main/java/org/apache/ariavata/simple/workflow/engine/dag/nodes/WorkflowOutputNodeImpl.java
+++ b/modules/simple-workflow/src/main/java/org/apache/ariavata/simple/workflow/engine/dag/nodes/WorkflowOutputNodeImpl.java
@@ -19,12 +19,9 @@
*
*/
-
package org.apache.ariavata.simple.workflow.engine.dag.nodes;
-
import org.apache.airavata.model.appcatalog.appinterface.OutputDataObjectType;
-import org.apache.ariavata.simple.workflow.engine.dag.edge.Edge;
import org.apache.ariavata.simple.workflow.engine.dag.port.InPort;
public class WorkflowOutputNodeImpl implements WorkflowOutputNode {
http://git-wip-us.apache.org/repos/asf/airavata/blob/308291f5/modules/simple-workflow/src/main/java/org/apache/ariavata/simple/workflow/engine/dag/port/InputPortIml.java
----------------------------------------------------------------------
diff --git a/modules/simple-workflow/src/main/java/org/apache/ariavata/simple/workflow/engine/dag/port/InputPortIml.java b/modules/simple-workflow/src/main/java/org/apache/ariavata/simple/workflow/engine/dag/port/InputPortIml.java
index 629a832..b42c11b 100644
--- a/modules/simple-workflow/src/main/java/org/apache/ariavata/simple/workflow/engine/dag/port/InputPortIml.java
+++ b/modules/simple-workflow/src/main/java/org/apache/ariavata/simple/workflow/engine/dag/port/InputPortIml.java
@@ -16,14 +16,13 @@
* specific language governing permissions and limitations
* under the License.
*/
+
package org.apache.ariavata.simple.workflow.engine.dag.port;
import org.apache.airavata.model.appcatalog.appinterface.InputDataObjectType;
import org.apache.ariavata.simple.workflow.engine.dag.edge.Edge;
import org.apache.ariavata.simple.workflow.engine.dag.nodes.WorkflowNode;
-import java.util.List;
-
public class InputPortIml implements InPort {
private InputDataObjectType inputDataObjectType;
http://git-wip-us.apache.org/repos/asf/airavata/blob/308291f5/modules/simple-workflow/src/main/java/org/apache/ariavata/simple/workflow/engine/dag/port/OutPortImpl.java
----------------------------------------------------------------------
diff --git a/modules/simple-workflow/src/main/java/org/apache/ariavata/simple/workflow/engine/dag/port/OutPortImpl.java b/modules/simple-workflow/src/main/java/org/apache/ariavata/simple/workflow/engine/dag/port/OutPortImpl.java
index 35b8c3b..f4a690b 100644
--- a/modules/simple-workflow/src/main/java/org/apache/ariavata/simple/workflow/engine/dag/port/OutPortImpl.java
+++ b/modules/simple-workflow/src/main/java/org/apache/ariavata/simple/workflow/engine/dag/port/OutPortImpl.java
@@ -1,3 +1,24 @@
+/*
+ *
+ * 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.ariavata.simple.workflow.engine.dag.port;
import org.apache.airavata.model.appcatalog.appinterface.OutputDataObjectType;
@@ -7,9 +28,6 @@ import org.apache.ariavata.simple.workflow.engine.dag.nodes.WorkflowNode;
import java.util.ArrayList;
import java.util.List;
-/**
- * Created by shameera on 2/11/15.
- */
public class OutPortImpl implements OutPort {
private OutputDataObjectType outputDataObjectType;
http://git-wip-us.apache.org/repos/asf/airavata/blob/308291f5/modules/simple-workflow/src/main/java/org/apache/ariavata/simple/workflow/engine/dag/port/Port.java
----------------------------------------------------------------------
diff --git a/modules/simple-workflow/src/main/java/org/apache/ariavata/simple/workflow/engine/dag/port/Port.java b/modules/simple-workflow/src/main/java/org/apache/ariavata/simple/workflow/engine/dag/port/Port.java
index 8c5d6c5..bcd7936 100644
--- a/modules/simple-workflow/src/main/java/org/apache/ariavata/simple/workflow/engine/dag/port/Port.java
+++ b/modules/simple-workflow/src/main/java/org/apache/ariavata/simple/workflow/engine/dag/port/Port.java
@@ -21,11 +21,8 @@
package org.apache.ariavata.simple.workflow.engine.dag.port;
-import org.apache.ariavata.simple.workflow.engine.dag.edge.Edge;
import org.apache.ariavata.simple.workflow.engine.dag.nodes.WorkflowNode;
-import java.util.List;
-
public interface Port {
public boolean isSatisfy();
http://git-wip-us.apache.org/repos/asf/airavata/blob/308291f5/modules/simple-workflow/src/main/java/org/apache/ariavata/simple/workflow/engine/parser/AiravataDefaultParser.java
----------------------------------------------------------------------
diff --git a/modules/simple-workflow/src/main/java/org/apache/ariavata/simple/workflow/engine/parser/AiravataDefaultParser.java b/modules/simple-workflow/src/main/java/org/apache/ariavata/simple/workflow/engine/parser/AiravataDefaultParser.java
index 62a76b3..b86e58b 100644
--- a/modules/simple-workflow/src/main/java/org/apache/ariavata/simple/workflow/engine/parser/AiravataDefaultParser.java
+++ b/modules/simple-workflow/src/main/java/org/apache/ariavata/simple/workflow/engine/parser/AiravataDefaultParser.java
@@ -1,9 +1,29 @@
+/*
+ *
+ * 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.ariavata.simple.workflow.engine.parser;
import org.airavata.appcatalog.cpi.AppCatalogException;
import org.airavata.appcatalog.cpi.WorkflowCatalog;
import org.apache.aiaravata.application.catalog.data.impl.AppCatalogFactory;
-import org.apache.aiaravata.application.catalog.data.model.WorkflowOutput;
import org.apache.airavata.model.appcatalog.appinterface.InputDataObjectType;
import org.apache.airavata.model.appcatalog.appinterface.OutputDataObjectType;
import org.apache.airavata.model.workspace.experiment.Experiment;
@@ -44,11 +64,6 @@ import java.util.HashMap;
import java.util.List;
import java.util.Map;
-//import org.apache.airavata.model.Workflow;
-
-/**
- * Created by shameera on 2/11/15.
- */
public class AiravataDefaultParser implements WorkflowParser {
private String experimentId;
@@ -95,23 +110,10 @@ public class AiravataDefaultParser implements WorkflowParser {
// TODO: throw an error and exit.
}
portContainers.addAll(processOutPorts(gNode, wfInputNode));
-/* for (DataPort dataPort : gNode.getOutputPorts()) {
- outPort = new OutPortImpl(dataPort.getID());
- for (DataEdge dataEdge : dataPort.getEdges()) {
- edge = new DirectedEdge();
- edge.setFromPort(outPort);
- outPort.addEdge(edge);
- inPort = getInPort(dataEdge.getToPort());
- edge.setToPort(inPort);
- inPort.addEdge(edge);
- portContainers.add(new PortContainer(dataEdge.getToPort(), inPort));
- }
-// outPort.setOutputObject(getOutputDataObject(wfInputNode.getInputObject()));
- }*/
wfInputNodes.add(wfInputNode);
}
- // while port container empty iterate graph and build the workflow DAG.
+ // while port container is not empty iterate graph and build the workflow DAG.
buildModel(portContainers);
return wfInputNodes;
@@ -154,12 +156,6 @@ public class AiravataDefaultParser implements WorkflowParser {
wfOutputNode.setInPort(inPort);
wfNodes.put(wfOutputNode.getNodeId(), wfOutputNode);
}
- // set the workflow node to inPort
- // if require check the types of inputs and output ports,
- // add outputPorts to the workflow node
- // add edges to each output port
- // add inport and indataport to the list
- // recursively call the function.
}
buildModel(nextPortContainerList);
@@ -220,11 +216,6 @@ public class AiravataDefaultParser implements WorkflowParser {
return outputDataObjectType;
}
- private WorkflowInputNode getWorkflowInputNode(Node inputNode) {
- // FIXME: create a new workflow input node implementation with input node data.
- return null;
- }
-
private Workflow getWorkflowFromExperiment() throws RegistryException, AppCatalogException, GraphException, ComponentException {
Registry registry = RegistryFactory.getDefaultRegistry();
experiment = (Experiment)registry.get(RegistryModelType.EXPERIMENT, experimentId);
http://git-wip-us.apache.org/repos/asf/airavata/blob/308291f5/modules/simple-workflow/src/main/java/org/apache/ariavata/simple/workflow/engine/parser/PortContainer.java
----------------------------------------------------------------------
diff --git a/modules/simple-workflow/src/main/java/org/apache/ariavata/simple/workflow/engine/parser/PortContainer.java b/modules/simple-workflow/src/main/java/org/apache/ariavata/simple/workflow/engine/parser/PortContainer.java
index 292bd1f..d18a104 100644
--- a/modules/simple-workflow/src/main/java/org/apache/ariavata/simple/workflow/engine/parser/PortContainer.java
+++ b/modules/simple-workflow/src/main/java/org/apache/ariavata/simple/workflow/engine/parser/PortContainer.java
@@ -1,3 +1,24 @@
+/*
+ *
+ * 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.ariavata.simple.workflow.engine.parser;
import org.apache.airavata.workflow.model.graph.DataPort;
http://git-wip-us.apache.org/repos/asf/airavata/blob/308291f5/modules/simple-workflow/src/test/java/org/apache/ariavata/simple/workflow/engine/WorkflowDAGTest.java
----------------------------------------------------------------------
diff --git a/modules/simple-workflow/src/test/java/org/apache/ariavata/simple/workflow/engine/WorkflowDAGTest.java b/modules/simple-workflow/src/test/java/org/apache/ariavata/simple/workflow/engine/WorkflowDAGTest.java
index 645af42..867ddc6 100644
--- a/modules/simple-workflow/src/test/java/org/apache/ariavata/simple/workflow/engine/WorkflowDAGTest.java
+++ b/modules/simple-workflow/src/test/java/org/apache/ariavata/simple/workflow/engine/WorkflowDAGTest.java
@@ -1,11 +1,30 @@
+/*
+ *
+ * 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.ariavata.simple.workflow.engine;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
-import static org.junit.Assert.*;
-
public class WorkflowDAGTest {
@Before
http://git-wip-us.apache.org/repos/asf/airavata/blob/308291f5/modules/simple-workflow/src/test/java/org/apache/ariavata/simple/workflow/engine/parser/AiravataDefaultParserTest.java
----------------------------------------------------------------------
diff --git a/modules/simple-workflow/src/test/java/org/apache/ariavata/simple/workflow/engine/parser/AiravataDefaultParserTest.java b/modules/simple-workflow/src/test/java/org/apache/ariavata/simple/workflow/engine/parser/AiravataDefaultParserTest.java
index 1f8e9c8..15b2864 100644
--- a/modules/simple-workflow/src/test/java/org/apache/ariavata/simple/workflow/engine/parser/AiravataDefaultParserTest.java
+++ b/modules/simple-workflow/src/test/java/org/apache/ariavata/simple/workflow/engine/parser/AiravataDefaultParserTest.java
@@ -1,3 +1,24 @@
+/*
+ *
+ * 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.ariavata.simple.workflow.engine.parser;
import junit.framework.Assert;
@@ -34,7 +55,8 @@ public class AiravataDefaultParserTest {
@Test
public void testWorkflowParse() throws Exception {
- File jsonWfFile = new File("modules/simple-workflow/src/test/resources/ComplexMathWorkflow.awf");
+// File jsonWfFile = new File("modules/simple-workflow/src/test/resources/ComplexMathWorkflow.awf");
+ File jsonWfFile = new File("/Users/shameera/work/source/git_airavata/modules/simple-workflow/src/test/resources/ComplexMathWorkflow.awf");
BufferedReader br = new BufferedReader(new FileReader(jsonWfFile));
StringBuffer sb = new StringBuffer();
String nextLine = br.readLine();
@@ -70,6 +92,10 @@ public class AiravataDefaultParserTest {
List<WorkflowInputNode> workflowInputNodes = parser.parseWorkflow(workflow);
Assert.assertNotNull(workflowInputNodes);
Assert.assertEquals(3, workflowInputNodes.size());
+ for (WorkflowInputNode workflowInputNode : workflowInputNodes) {
+ Assert.assertNotNull(workflowInputNode.getOutPort());
+ Assert.assertNotNull(workflowInputNode.getInputObject());
+ }
Map<String, WorkflowNode> wfNodes = parser.getWfNodes();
for (String wfId : wfNodes.keySet()) {
@@ -77,7 +103,14 @@ public class AiravataDefaultParserTest {
if (wfNode instanceof ApplicationNode) {
ApplicationNode node = (ApplicationNode) wfNode;
Assert.assertEquals(2, node.getInputPorts().size());
+ Assert.assertNotNull(node.getInputPorts().get(0).getInputObject());
+ Assert.assertNotNull(node.getInputPorts().get(1).getInputObject());
+ Assert.assertNotNull(node.getInputPorts().get(0).getEdge());
+ Assert.assertNotNull(node.getInputPorts().get(1).getEdge());
+
Assert.assertEquals(1, node.getOutputPorts().size());
+ Assert.assertEquals(1, node.getOutputPorts().get(0).getOutEdges().size());
+ Assert.assertNotNull(node.getOutputPorts().get(0).getOutEdges().get(0));
}else if (wfNode instanceof WorkflowOutputNode) {
WorkflowOutputNode workflowOutputNode = (WorkflowOutputNode) wfNode;
Assert.assertNotNull(workflowOutputNode.getInPort());
[47/50] [abbrv] airavata git commit: Renamed simple-workflow module
to workflow and created a new workflow-core module which will keep all the
core code
Posted by sh...@apache.org.
Renamed simple-workflow module to workflow and created a new workflow-core module which will keep all the core code
Project: http://git-wip-us.apache.org/repos/asf/airavata/repo
Commit: http://git-wip-us.apache.org/repos/asf/airavata/commit/509f2037
Tree: http://git-wip-us.apache.org/repos/asf/airavata/tree/509f2037
Diff: http://git-wip-us.apache.org/repos/asf/airavata/diff/509f2037
Branch: refs/heads/master
Commit: 509f2037eaa7a682548c777df284d9a292cf8e04
Parents: 5e5630d
Author: shamrath <sh...@gmail.com>
Authored: Wed Mar 25 16:25:01 2015 -0400
Committer: shamrath <sh...@gmail.com>
Committed: Wed Mar 25 16:25:01 2015 -0400
----------------------------------------------------------------------
airavata-api/airavata-api-server/pom.xml | 7 +-
.../server/handler/AiravataServerHandler.java | 3 +-
.../api/server/util/DataModelUtils.java | 3 +-
.../main/resources/airavata-server.properties | 2 +-
.../main/resources/airavata-server.properties | 2 +-
.../airavata-orchestrator-service/pom.xml | 7 +-
.../server/OrchestratorServerHandler.java | 2 +-
.../orchestrator/util/DataModelUtils.java | 5 +-
.../client/OrchestratorClientFactoryTest.java | 2 -
modules/simple-workflow/pom.xml | 70 ---
.../simple/workflow/engine/ProcessContext.java | 62 --
.../engine/SimpleWorkflowInterpreter.java | 400 -------------
.../engine/WorkflowEnactmentService.java | 183 ------
.../simple/workflow/engine/WorkflowFactory.java | 31 -
.../workflow/engine/WorkflowFactoryImpl.java | 74 ---
.../simple/workflow/engine/WorkflowParser.java | 32 -
.../workflow/engine/dag/edge/DirectedEdge.java | 52 --
.../simple/workflow/engine/dag/edge/Edge.java | 43 --
.../engine/dag/nodes/ApplicationNode.java | 41 --
.../engine/dag/nodes/ApplicationNodeImpl.java | 116 ----
.../workflow/engine/dag/nodes/NodeState.java | 44 --
.../workflow/engine/dag/nodes/NodeType.java | 28 -
.../engine/dag/nodes/WorkflowInputNode.java | 37 --
.../engine/dag/nodes/WorkflowInputNodeImpl.java | 99 ----
.../workflow/engine/dag/nodes/WorkflowNode.java | 38 --
.../engine/dag/nodes/WorkflowOutputNode.java | 37 --
.../dag/nodes/WorkflowOutputNodeImpl.java | 100 ----
.../simple/workflow/engine/dag/port/InPort.java | 41 --
.../workflow/engine/dag/port/InputPortIml.java | 91 ---
.../workflow/engine/dag/port/OutPort.java | 39 --
.../workflow/engine/dag/port/OutPortImpl.java | 83 ---
.../simple/workflow/engine/dag/port/Port.java | 36 --
.../engine/parser/AiravataWorkflowParser.java | 291 ---------
.../workflow/engine/parser/PortContainer.java | 53 --
.../simple/workflow/engine/WorkflowDAGTest.java | 46 --
.../parser/AiravataWorkflowParserTest.java | 119 ----
.../src/test/resources/ComplexMathWorkflow.awf | 465 ---------------
modules/workflow/pom.xml | 22 +
modules/workflow/workflow-core/pom.xml | 74 +++
.../airavata/workflow/core/ProcessContext.java | 62 ++
.../core/SimpleWorkflowInterpreter.java | 400 +++++++++++++
.../workflow/core/WorkflowEnactmentService.java | 183 ++++++
.../airavata/workflow/core/WorkflowFactory.java | 31 +
.../workflow/core/WorkflowFactoryImpl.java | 74 +++
.../airavata/workflow/core/WorkflowParser.java | 32 +
.../workflow/core/dag/edge/DirectedEdge.java | 52 ++
.../airavata/workflow/core/dag/edge/Edge.java | 43 ++
.../core/dag/nodes/ApplicationNode.java | 41 ++
.../core/dag/nodes/ApplicationNodeImpl.java | 116 ++++
.../workflow/core/dag/nodes/NodeState.java | 44 ++
.../workflow/core/dag/nodes/NodeType.java | 28 +
.../core/dag/nodes/WorkflowInputNode.java | 37 ++
.../core/dag/nodes/WorkflowInputNodeImpl.java | 99 ++++
.../workflow/core/dag/nodes/WorkflowNode.java | 38 ++
.../core/dag/nodes/WorkflowOutputNode.java | 37 ++
.../core/dag/nodes/WorkflowOutputNodeImpl.java | 100 ++++
.../airavata/workflow/core/dag/port/InPort.java | 41 ++
.../workflow/core/dag/port/InputPortIml.java | 91 +++
.../workflow/core/dag/port/OutPort.java | 39 ++
.../workflow/core/dag/port/OutPortImpl.java | 83 +++
.../airavata/workflow/core/dag/port/Port.java | 36 ++
.../core/parser/AiravataWorkflowParser.java | 291 +++++++++
.../workflow/core/parser/PortContainer.java | 53 ++
.../airavata/workflow/core/WorkflowDAGTest.java | 46 ++
.../core/parser/AiravataWorkflowParserTest.java | 119 ++++
.../src/test/resources/ComplexMathWorkflow.awf | 465 +++++++++++++++
.../test/resources/ParamChemApplicationTest.awf | 593 +++++++++++++++++++
pom.xml | 2 +-
68 files changed, 3384 insertions(+), 2772 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/airavata/blob/509f2037/airavata-api/airavata-api-server/pom.xml
----------------------------------------------------------------------
diff --git a/airavata-api/airavata-api-server/pom.xml b/airavata-api/airavata-api-server/pom.xml
index 7cb6376..bf6c555 100644
--- a/airavata-api/airavata-api-server/pom.xml
+++ b/airavata-api/airavata-api-server/pom.xml
@@ -66,9 +66,14 @@
<artifactId>airavata-orchestrator-stubs</artifactId>
<version>${project.version}</version>
</dependency>
+ <!--<dependency>-->
+ <!--<groupId>org.apache.airavata</groupId>-->
+ <!--<artifactId>airavata-workflow-engine</artifactId>-->
+ <!--<version>${project.version}</version>-->
+ <!--</dependency>-->
<dependency>
<groupId>org.apache.airavata</groupId>
- <artifactId>airavata-workflow-engine</artifactId>
+ <artifactId>airavata-messaging-core</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
http://git-wip-us.apache.org/repos/asf/airavata/blob/509f2037/airavata-api/airavata-api-server/src/main/java/org/apache/airavata/api/server/handler/AiravataServerHandler.java
----------------------------------------------------------------------
diff --git a/airavata-api/airavata-api-server/src/main/java/org/apache/airavata/api/server/handler/AiravataServerHandler.java b/airavata-api/airavata-api-server/src/main/java/org/apache/airavata/api/server/handler/AiravataServerHandler.java
index 6675bb8..aeb106c 100644
--- a/airavata-api/airavata-api-server/src/main/java/org/apache/airavata/api/server/handler/AiravataServerHandler.java
+++ b/airavata-api/airavata-api-server/src/main/java/org/apache/airavata/api/server/handler/AiravataServerHandler.java
@@ -83,7 +83,6 @@ import org.apache.airavata.registry.cpi.Registry;
import org.apache.airavata.registry.cpi.RegistryException;
import org.apache.airavata.registry.cpi.RegistryModelType;
import org.apache.airavata.registry.cpi.utils.Constants;
-import org.apache.airavata.workflow.catalog.WorkflowCatalogFactory;
import org.apache.thrift.TException;
import java.util.ArrayList;
@@ -3094,7 +3093,7 @@ public class AiravataServerHandler implements Airavata.Iface {
private WorkflowCatalog getWorkflowCatalog() {
if (workflowCatalog == null) {
try {
- workflowCatalog = WorkflowCatalogFactory.getWorkflowCatalog();
+ workflowCatalog = AppCatalogFactory.getAppCatalog().getWorkflowCatalog();
} catch (Exception e) {
logger.error("Unable to create Workflow Catalog", e);
}
http://git-wip-us.apache.org/repos/asf/airavata/blob/509f2037/airavata-api/airavata-api-server/src/main/java/org/apache/airavata/api/server/util/DataModelUtils.java
----------------------------------------------------------------------
diff --git a/airavata-api/airavata-api-server/src/main/java/org/apache/airavata/api/server/util/DataModelUtils.java b/airavata-api/airavata-api-server/src/main/java/org/apache/airavata/api/server/util/DataModelUtils.java
index 5f4db49..8af8956 100644
--- a/airavata-api/airavata-api-server/src/main/java/org/apache/airavata/api/server/util/DataModelUtils.java
+++ b/airavata-api/airavata-api-server/src/main/java/org/apache/airavata/api/server/util/DataModelUtils.java
@@ -27,7 +27,6 @@ import org.apache.aiaravata.application.catalog.data.impl.AppCatalogFactory;
import org.apache.airavata.common.utils.ServerSettings;
import org.apache.airavata.model.util.ExecutionType;
import org.apache.airavata.model.workspace.experiment.Experiment;
-import org.apache.airavata.workflow.catalog.WorkflowCatalogFactory;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -43,7 +42,7 @@ public class DataModelUtils {
if (allApplicationInterfaceIds.contains(applicationId)){
return ExecutionType.SINGLE_APP;
} else {
- List<String> allWorkflows = WorkflowCatalogFactory.getWorkflowCatalog().getAllWorkflows(ServerSettings.getDefaultUserGateway());
+ List<String> allWorkflows = AppCatalogFactory.getAppCatalog().getWorkflowCatalog().getAllWorkflows(ServerSettings.getDefaultUserGateway());
if (allWorkflows.contains(applicationId)){
return ExecutionType.WORKFLOW;
}
http://git-wip-us.apache.org/repos/asf/airavata/blob/509f2037/modules/configuration/server/src/main/resources/airavata-server.properties
----------------------------------------------------------------------
diff --git a/modules/configuration/server/src/main/resources/airavata-server.properties b/modules/configuration/server/src/main/resources/airavata-server.properties
index 8442472..6bb34ad 100644
--- a/modules/configuration/server/src/main/resources/airavata-server.properties
+++ b/modules/configuration/server/src/main/resources/airavata-server.properties
@@ -163,7 +163,7 @@ gfac.passive=false
enactment.thread.pool.size=10
#to define custom workflow parser user following property
-#workflow.parser=org.apache.airavata.simple.workflow.engine.parser.AiravataWorkflowParser
+#workflow.parser=org.apache.airavata.workflow.core.parser.AiravataWorkflowParser
###########################################################################
http://git-wip-us.apache.org/repos/asf/airavata/blob/509f2037/modules/credential-store/credential-store-webapp/src/main/resources/airavata-server.properties
----------------------------------------------------------------------
diff --git a/modules/credential-store/credential-store-webapp/src/main/resources/airavata-server.properties b/modules/credential-store/credential-store-webapp/src/main/resources/airavata-server.properties
index fe4de5d..6be04e6 100644
--- a/modules/credential-store/credential-store-webapp/src/main/resources/airavata-server.properties
+++ b/modules/credential-store/credential-store-webapp/src/main/resources/airavata-server.properties
@@ -147,7 +147,7 @@ trusted.cert.location=/Users/lahirugunathilake/Downloads/certificates
enactment.thread.pool.size=10
#to define custom workflow parser user following property
-#workflow.parser=org.apache.airavata.simple.workflow.engine.parser.AiravataWorkflowParser
+#workflow.parser=org.apache.airavata.workflow.core.parser.AiravataWorkflowParser
###########################################################################
http://git-wip-us.apache.org/repos/asf/airavata/blob/509f2037/modules/orchestrator/airavata-orchestrator-service/pom.xml
----------------------------------------------------------------------
diff --git a/modules/orchestrator/airavata-orchestrator-service/pom.xml b/modules/orchestrator/airavata-orchestrator-service/pom.xml
index b441023..c6ab2f4 100644
--- a/modules/orchestrator/airavata-orchestrator-service/pom.xml
+++ b/modules/orchestrator/airavata-orchestrator-service/pom.xml
@@ -52,12 +52,7 @@
</dependency>
<dependency>
<groupId>org.apache.airavata</groupId>
- <artifactId>airavata-workflow-engine</artifactId>
- <version>${project.version}</version>
- </dependency>
- <dependency>
- <groupId>org.apache.airavata</groupId>
- <artifactId>simple-workflow</artifactId>
+ <artifactId>workflow-core</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
http://git-wip-us.apache.org/repos/asf/airavata/blob/509f2037/modules/orchestrator/airavata-orchestrator-service/src/main/java/org/apache/airavata/orchestrator/server/OrchestratorServerHandler.java
----------------------------------------------------------------------
diff --git a/modules/orchestrator/airavata-orchestrator-service/src/main/java/org/apache/airavata/orchestrator/server/OrchestratorServerHandler.java b/modules/orchestrator/airavata-orchestrator-service/src/main/java/org/apache/airavata/orchestrator/server/OrchestratorServerHandler.java
index a0e25d7..53671af 100644
--- a/modules/orchestrator/airavata-orchestrator-service/src/main/java/org/apache/airavata/orchestrator/server/OrchestratorServerHandler.java
+++ b/modules/orchestrator/airavata-orchestrator-service/src/main/java/org/apache/airavata/orchestrator/server/OrchestratorServerHandler.java
@@ -73,7 +73,7 @@ import org.apache.airavata.registry.cpi.RegistryException;
import org.apache.airavata.registry.cpi.RegistryModelType;
import org.apache.airavata.registry.cpi.utils.Constants.FieldConstants.TaskDetailConstants;
import org.apache.airavata.registry.cpi.utils.Constants.FieldConstants.WorkflowNodeConstants;
-import org.apache.airavata.simple.workflow.engine.WorkflowEnactmentService;
+import org.apache.airavata.workflow.core.WorkflowEnactmentService;
import org.apache.thrift.TBase;
import org.apache.thrift.TException;
import org.apache.zookeeper.CreateMode;
http://git-wip-us.apache.org/repos/asf/airavata/blob/509f2037/modules/orchestrator/airavata-orchestrator-service/src/main/java/org/apache/airavata/orchestrator/util/DataModelUtils.java
----------------------------------------------------------------------
diff --git a/modules/orchestrator/airavata-orchestrator-service/src/main/java/org/apache/airavata/orchestrator/util/DataModelUtils.java b/modules/orchestrator/airavata-orchestrator-service/src/main/java/org/apache/airavata/orchestrator/util/DataModelUtils.java
index b6f8387..da11a59 100644
--- a/modules/orchestrator/airavata-orchestrator-service/src/main/java/org/apache/airavata/orchestrator/util/DataModelUtils.java
+++ b/modules/orchestrator/airavata-orchestrator-service/src/main/java/org/apache/airavata/orchestrator/util/DataModelUtils.java
@@ -26,11 +26,8 @@ import java.util.List;
import org.airavata.appcatalog.cpi.AppCatalogException;
import org.airavata.appcatalog.cpi.ApplicationInterface;
import org.apache.aiaravata.application.catalog.data.impl.AppCatalogFactory;
-import org.apache.airavata.common.exception.ApplicationSettingsException;
-import org.apache.airavata.common.utils.ServerSettings;
import org.apache.airavata.model.util.ExecutionType;
import org.apache.airavata.model.workspace.experiment.Experiment;
-import org.apache.airavata.workflow.catalog.WorkflowCatalogFactory;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -45,7 +42,7 @@ public class DataModelUtils {
if (allApplicationInterfaceIds.contains(applicationId)){
return ExecutionType.SINGLE_APP;
} else {
- List<String> allWorkflows = WorkflowCatalogFactory.getWorkflowCatalog().getAllWorkflows(gatewayId);
+ List<String> allWorkflows = AppCatalogFactory.getAppCatalog().getWorkflowCatalog().getAllWorkflows(gatewayId);
if (allWorkflows.contains(applicationId)){
return ExecutionType.WORKFLOW;
}
http://git-wip-us.apache.org/repos/asf/airavata/blob/509f2037/modules/orchestrator/airavata-orchestrator-service/src/test/java/org/apache/airavata/orchestrator/client/OrchestratorClientFactoryTest.java
----------------------------------------------------------------------
diff --git a/modules/orchestrator/airavata-orchestrator-service/src/test/java/org/apache/airavata/orchestrator/client/OrchestratorClientFactoryTest.java b/modules/orchestrator/airavata-orchestrator-service/src/test/java/org/apache/airavata/orchestrator/client/OrchestratorClientFactoryTest.java
index 28687c9..18168c7 100644
--- a/modules/orchestrator/airavata-orchestrator-service/src/test/java/org/apache/airavata/orchestrator/client/OrchestratorClientFactoryTest.java
+++ b/modules/orchestrator/airavata-orchestrator-service/src/test/java/org/apache/airavata/orchestrator/client/OrchestratorClientFactoryTest.java
@@ -21,8 +21,6 @@
package org.apache.airavata.orchestrator.client;
-import org.apache.airavata.api.Airavata;
-import org.apache.airavata.api.client.AiravataClientFactory;
//import org.apache.airavata.client.AiravataAPIFactory;
//import org.apache.airavata.client.api.exception.AiravataAPIInvocationException;
//import org.apache.airavata.client.tools.DocumentCreator;
http://git-wip-us.apache.org/repos/asf/airavata/blob/509f2037/modules/simple-workflow/pom.xml
----------------------------------------------------------------------
diff --git a/modules/simple-workflow/pom.xml b/modules/simple-workflow/pom.xml
deleted file mode 100644
index 5cb9dfb..0000000
--- a/modules/simple-workflow/pom.xml
+++ /dev/null
@@ -1,70 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<project xmlns="http://maven.apache.org/POM/4.0.0"
- xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
- xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
- <modelVersion>4.0.0</modelVersion>
-
- <groupId>org.apache.airavata</groupId>
- <artifactId>simple-workflow</artifactId>
- <version>0.15-SNAPSHOT</version>
-
- <dependencies>
- <dependency>
- <groupId>org.apache.airavata</groupId>
- <artifactId>airavata-data-models</artifactId>
- <version>${project.version}</version>
- </dependency>
- <dependency>
- <groupId>org.apache.airavata</groupId>
- <artifactId>airavata-registry-cpi</artifactId>
- <version>${project.version}</version>
- </dependency>
- <dependency>
- <groupId>org.apache.airavata</groupId>
- <artifactId>airavata-model-utils</artifactId>
- <version>${project.version}</version>
- </dependency>
- <dependency>
- <groupId>org.apache.airavata</groupId>
- <artifactId>airavata-jpa-registry</artifactId>
- <version>${project.version}</version>
- </dependency>
-
- <!-- Airavata default parser dependency -->
- <dependency>
- <groupId>org.apache.airavata</groupId>
- <artifactId>airavata-workflow-model-core</artifactId>
- <version>${project.version}</version>
- </dependency>
- <dependency>
- <groupId>org.apache.airavata</groupId>
- <artifactId>app-catalog-data</artifactId>
- <version>${project.version}</version>
- </dependency>
- <dependency>
- <groupId>org.apache.airavata</groupId>
- <artifactId>app-catalog-cpi</artifactId>
- <version>${project.version}</version>
- </dependency>
- <!-- Messaging dependency -->
- <dependency>
- <groupId>org.apache.airavata</groupId>
- <artifactId>airavata-messaging-core</artifactId>
- <version>${project.version}</version>
- </dependency>
- <dependency>
- <groupId>com.google.guava</groupId>
- <artifactId>guava</artifactId>
- <version>18.0</version>
- </dependency>
-
- <!--test-->
- <dependency>
- <groupId>junit</groupId>
- <artifactId>junit</artifactId>
- <version>4.11</version>
- <scope>test</scope>
- </dependency>
- </dependencies>
-
-</project>
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/airavata/blob/509f2037/modules/simple-workflow/src/main/java/org/apache/airavata/simple/workflow/engine/ProcessContext.java
----------------------------------------------------------------------
diff --git a/modules/simple-workflow/src/main/java/org/apache/airavata/simple/workflow/engine/ProcessContext.java b/modules/simple-workflow/src/main/java/org/apache/airavata/simple/workflow/engine/ProcessContext.java
deleted file mode 100644
index 849af85..0000000
--- a/modules/simple-workflow/src/main/java/org/apache/airavata/simple/workflow/engine/ProcessContext.java
+++ /dev/null
@@ -1,62 +0,0 @@
-/*
- *
- * 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.simple.workflow.engine;
-
-import org.apache.airavata.model.workspace.experiment.TaskDetails;
-import org.apache.airavata.model.workspace.experiment.WorkflowNodeDetails;
-import org.apache.airavata.simple.workflow.engine.dag.nodes.WorkflowNode;
-
-public class ProcessContext {
- private WorkflowNode workflowNode;
- private WorkflowNodeDetails wfNodeDetails;
- private TaskDetails taskDetails;
-
- public ProcessContext(WorkflowNode workflowNode, WorkflowNodeDetails wfNodeDetails, TaskDetails taskDetails) {
- this.workflowNode = workflowNode;
- this.wfNodeDetails = wfNodeDetails;
- this.taskDetails = taskDetails;
- }
-
- public WorkflowNode getWorkflowNode() {
- return workflowNode;
- }
-
- public void setWorkflowNode(WorkflowNode workflowNode) {
- this.workflowNode = workflowNode;
- }
-
- public WorkflowNodeDetails getWfNodeDetails() {
- return wfNodeDetails;
- }
-
- public void setWfNodeDetails(WorkflowNodeDetails wfNodeDetails) {
- this.wfNodeDetails = wfNodeDetails;
- }
-
- public TaskDetails getTaskDetails() {
- return taskDetails;
- }
-
- public void setTaskDetails(TaskDetails taskDetails) {
- this.taskDetails = taskDetails;
- }
-}
http://git-wip-us.apache.org/repos/asf/airavata/blob/509f2037/modules/simple-workflow/src/main/java/org/apache/airavata/simple/workflow/engine/SimpleWorkflowInterpreter.java
----------------------------------------------------------------------
diff --git a/modules/simple-workflow/src/main/java/org/apache/airavata/simple/workflow/engine/SimpleWorkflowInterpreter.java b/modules/simple-workflow/src/main/java/org/apache/airavata/simple/workflow/engine/SimpleWorkflowInterpreter.java
deleted file mode 100644
index 191988c..0000000
--- a/modules/simple-workflow/src/main/java/org/apache/airavata/simple/workflow/engine/SimpleWorkflowInterpreter.java
+++ /dev/null
@@ -1,400 +0,0 @@
-/*
- *
- * 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.simple.workflow.engine;
-
-import org.apache.airavata.common.exception.AiravataException;
-import org.apache.airavata.common.utils.AiravataUtils;
-import org.apache.airavata.messaging.core.MessageContext;
-import org.apache.airavata.messaging.core.impl.RabbitMQProcessPublisher;
-import org.apache.airavata.messaging.core.impl.RabbitMQStatusConsumer;
-import org.apache.airavata.model.appcatalog.appinterface.OutputDataObjectType;
-import org.apache.airavata.model.messaging.event.MessageType;
-import org.apache.airavata.model.messaging.event.ProcessSubmitEvent;
-import org.apache.airavata.model.messaging.event.TaskIdentifier;
-import org.apache.airavata.model.messaging.event.TaskOutputChangeEvent;
-import org.apache.airavata.model.messaging.event.TaskStatusChangeEvent;
-import org.apache.airavata.model.util.ExperimentModelUtil;
-import org.apache.airavata.model.workspace.experiment.ExecutionUnit;
-import org.apache.airavata.model.workspace.experiment.Experiment;
-import org.apache.airavata.model.workspace.experiment.TaskDetails;
-import org.apache.airavata.model.workspace.experiment.TaskState;
-import org.apache.airavata.model.workspace.experiment.WorkflowNodeDetails;
-import org.apache.airavata.model.workspace.experiment.WorkflowNodeState;
-import org.apache.airavata.model.workspace.experiment.WorkflowNodeStatus;
-import org.apache.airavata.persistance.registry.jpa.impl.RegistryFactory;
-import org.apache.airavata.registry.cpi.ChildDataType;
-import org.apache.airavata.registry.cpi.Registry;
-import org.apache.airavata.registry.cpi.RegistryException;
-import org.apache.airavata.registry.cpi.RegistryModelType;
-import org.apache.airavata.simple.workflow.engine.dag.edge.Edge;
-import org.apache.airavata.simple.workflow.engine.dag.nodes.ApplicationNode;
-import org.apache.airavata.simple.workflow.engine.dag.nodes.NodeState;
-import org.apache.airavata.simple.workflow.engine.dag.nodes.WorkflowInputNode;
-import org.apache.airavata.simple.workflow.engine.dag.nodes.WorkflowNode;
-import org.apache.airavata.simple.workflow.engine.dag.nodes.WorkflowOutputNode;
-import org.apache.airavata.simple.workflow.engine.dag.port.InPort;
-import org.apache.airavata.simple.workflow.engine.dag.port.OutPort;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-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 java.util.concurrent.ConcurrentHashMap;
-
-/**
- * Package-Private class
- */
-class SimpleWorkflowInterpreter{
-
- private static final Logger log = LoggerFactory.getLogger(SimpleWorkflowInterpreter.class);
- private List<WorkflowInputNode> workflowInputNodes;
-
- private Experiment experiment;
-
- private String credentialToken;
-
- private String gatewayName;
-
- private Map<String, WorkflowNode> readyList = new ConcurrentHashMap<String, WorkflowNode>();
- private Map<String, WorkflowNode> waitingList = new ConcurrentHashMap<String, WorkflowNode>();
- private Map<String, ProcessContext> processingQueue = new ConcurrentHashMap<String, ProcessContext>();
- private Map<String, ProcessContext> completeList = new HashMap<String, ProcessContext>();
- private Registry registry;
- private List<WorkflowOutputNode> completeWorkflowOutputs = new ArrayList<WorkflowOutputNode>();
- private RabbitMQProcessPublisher publisher;
- private RabbitMQStatusConsumer statusConsumer;
- private String consumerId;
- private boolean continueWorkflow = true;
-
- public SimpleWorkflowInterpreter(String experimentId, String credentialToken, String gatewayName, RabbitMQProcessPublisher publisher) throws RegistryException {
- this.gatewayName = gatewayName;
- setExperiment(experimentId);
- this.credentialToken = credentialToken;
- this.publisher = publisher;
- }
-
- public SimpleWorkflowInterpreter(Experiment experiment, String credentialStoreToken, String gatewayName, RabbitMQProcessPublisher publisher) {
- this.gatewayName = gatewayName;
- this.experiment = experiment;
- this.credentialToken = credentialStoreToken;
- this.publisher = publisher;
- }
-
- /**
- * Package-Private method.
- * @throws Exception
- */
- void launchWorkflow() throws Exception {
- WorkflowFactoryImpl wfFactory = WorkflowFactoryImpl.getInstance();
- WorkflowParser workflowParser = wfFactory.getWorkflowParser(experiment.getExperimentID(), credentialToken);
- log.debug("Initialized workflow parser");
- setWorkflowInputNodes(workflowParser.parse());
- log.debug("Parsed the workflow and got the workflow input nodes");
- // process workflow input nodes
- processWorkflowInputNodes(getWorkflowInputNodes());
- if (readyList.isEmpty()) {
- StringBuilder sb = new StringBuilder();
- for (WorkflowInputNode workflowInputNode : workflowInputNodes) {
- sb.append(", ");
- sb.append(workflowInputNode.getInputObject().getName());
- sb.append("=");
- sb.append(workflowInputNode.getInputObject().getValue());
- }
- throw new AiravataException("No workflow application node is in ready state to run with experiment inputs" + sb.toString());
- }
- processReadyList();
- }
-
- // try to remove synchronization tag
- /**
- * Package-Private method.
- * @throws RegistryException
- * @throws AiravataException
- */
- void processReadyList() throws RegistryException, AiravataException {
- if (readyList.isEmpty() && processingQueue.isEmpty() && !waitingList.isEmpty()) {
- throw new AiravataException("No workflow application node is in ready state to run");
- }
- for (WorkflowNode readyNode : readyList.values()) {
- if (readyNode instanceof WorkflowOutputNode) {
- WorkflowOutputNode wfOutputNode = (WorkflowOutputNode) readyNode;
- wfOutputNode.getOutputObject().setValue(wfOutputNode.getInPort().getInputObject().getValue());
- addToCompleteOutputNodeList(wfOutputNode);
- continue;
- }
- WorkflowNodeDetails workflowNodeDetails = createWorkflowNodeDetails(readyNode);
- TaskDetails process = getProcess(workflowNodeDetails);
- ProcessContext processContext = new ProcessContext(readyNode, workflowNodeDetails, process);
- addToProcessingQueue(processContext);
- publishToProcessQueue(process);
- }
- }
-
-
- private void publishToProcessQueue(TaskDetails process) throws AiravataException {
- ProcessSubmitEvent processSubmitEvent = new ProcessSubmitEvent();
- processSubmitEvent.setCredentialToken(credentialToken);
- processSubmitEvent.setTaskId(process.getTaskID());
- MessageContext messageContext = new MessageContext(processSubmitEvent, MessageType.TASK, process.getTaskID(), null);
- messageContext.setUpdatedTime(AiravataUtils.getCurrentTimestamp());
- publisher.publish(messageContext);
- }
-
- private TaskDetails getProcess(WorkflowNodeDetails wfNodeDetails) throws RegistryException {
- // create workflow taskDetails from workflowNodeDetails
- TaskDetails taskDetails = ExperimentModelUtil.cloneTaskFromWorkflowNodeDetails(getExperiment(), wfNodeDetails);
- taskDetails.setTaskID(getRegistry()
- .add(ChildDataType.TASK_DETAIL, taskDetails, wfNodeDetails.getNodeInstanceId()).toString());
- return taskDetails;
- }
-
- private WorkflowNodeDetails createWorkflowNodeDetails(WorkflowNode readyNode) throws RegistryException {
- WorkflowNodeDetails wfNodeDetails = ExperimentModelUtil.createWorkflowNode(readyNode.getId(), null);
- ExecutionUnit executionUnit = ExecutionUnit.APPLICATION;
- String executionData = null;
- if (readyNode instanceof ApplicationNode) {
- executionUnit = ExecutionUnit.APPLICATION;
- executionData = ((ApplicationNode) readyNode).getApplicationId();
- setupNodeDetailsInput(((ApplicationNode) readyNode), wfNodeDetails);
- } else if (readyNode instanceof WorkflowInputNode) {
- executionUnit = ExecutionUnit.INPUT;
- } else if (readyNode instanceof WorkflowOutputNode) {
- executionUnit = ExecutionUnit.OUTPUT;
- }
- wfNodeDetails.setExecutionUnit(executionUnit);
- wfNodeDetails.setExecutionUnitData(executionData);
- wfNodeDetails.setNodeInstanceId((String) getRegistry()
- .add(ChildDataType.WORKFLOW_NODE_DETAIL, wfNodeDetails, getExperiment().getExperimentID()));
- return wfNodeDetails;
- }
-
- private void setupNodeDetailsInput(ApplicationNode readyAppNode, WorkflowNodeDetails wfNodeDetails) {
- if (readyAppNode.isReady()) {
- for (InPort inPort : readyAppNode.getInputPorts()) {
- wfNodeDetails.addToNodeInputs(inPort.getInputObject());
- }
- } else {
- throw new IllegalArgumentException("Application node should be in ready state to set inputs to the " +
- "workflow node details, nodeId = " + readyAppNode.getId());
- }
- }
-
-
- private void processWorkflowInputNodes(List<WorkflowInputNode> wfInputNodes) {
- Set<WorkflowNode> tempNodeSet = new HashSet<WorkflowNode>();
- for (WorkflowInputNode wfInputNode : wfInputNodes) {
- if (wfInputNode.isReady()) {
- log.debug("Workflow node : " + wfInputNode.getId() + " is ready to execute");
- for (Edge edge : wfInputNode.getOutPort().getOutEdges()) {
- edge.getToPort().getInputObject().setValue(wfInputNode.getInputObject().getValue());
- if (edge.getToPort().getNode().isReady()) {
- addToReadyQueue(edge.getToPort().getNode());
- log.debug("Added workflow node : " + edge.getToPort().getNode().getId() + " to the readyQueue");
- } else {
- addToWaitingQueue(edge.getToPort().getNode());
- log.debug("Added workflow node " + edge.getToPort().getNode().getId() + " to the waitingQueue");
-
- }
- }
- }
- }
- }
-
-
- public List<WorkflowInputNode> getWorkflowInputNodes() throws Exception {
- return workflowInputNodes;
- }
-
- public void setWorkflowInputNodes(List<WorkflowInputNode> workflowInputNodes) {
- this.workflowInputNodes = workflowInputNodes;
- }
-
- private Registry getRegistry() throws RegistryException {
- if (registry==null){
- registry = RegistryFactory.getDefaultRegistry();
- }
- return registry;
- }
-
- public Experiment getExperiment() {
- return experiment;
- }
-
- private void updateWorkflowNodeStatus(WorkflowNodeDetails wfNodeDetails, WorkflowNodeState state) throws RegistryException{
- WorkflowNodeStatus status = ExperimentModelUtil.createWorkflowNodeStatus(state);
- wfNodeDetails.setWorkflowNodeStatus(status);
- getRegistry().update(RegistryModelType.WORKFLOW_NODE_STATUS, status, wfNodeDetails.getNodeInstanceId());
- }
-
- /**
- * Package-Private method.
- * Remove the workflow node from waiting queue and add it to the ready queue.
- * @param workflowNode - Workflow Node
- */
- synchronized void addToReadyQueue(WorkflowNode workflowNode) {
- waitingList.remove(workflowNode.getId());
- readyList.put(workflowNode.getId(), workflowNode);
- }
-
- private void addToWaitingQueue(WorkflowNode workflowNode) {
- waitingList.put(workflowNode.getId(), workflowNode);
- }
-
- /**
- * First remove the node from ready list and then add the WfNodeContainer to the process queue.
- * Note that underline data structure of the process queue is a Map.
- * @param processContext - has both workflow and correspond workflowNodeDetails and TaskDetails
- */
- private synchronized void addToProcessingQueue(ProcessContext processContext) {
- readyList.remove(processContext.getWorkflowNode().getId());
- processingQueue.put(processContext.getTaskDetails().getTaskID(), processContext);
- }
-
- private synchronized void addToCompleteQueue(ProcessContext processContext) {
- processingQueue.remove(processContext.getTaskDetails().getTaskID());
- completeList.put(processContext.getTaskDetails().getTaskID(), processContext);
- }
-
-
- private void addToCompleteOutputNodeList(WorkflowOutputNode wfOutputNode) {
- completeWorkflowOutputs.add(wfOutputNode);
- readyList.remove(wfOutputNode.getId());
- }
-
- boolean isAllDone() {
- return !continueWorkflow || (waitingList.isEmpty() && readyList.isEmpty() && processingQueue.isEmpty());
- }
-
- private void setExperiment(String experimentId) throws RegistryException {
- experiment = (Experiment) getRegistry().get(RegistryModelType.EXPERIMENT, experimentId);
- log.debug("Retrieve Experiment for experiment id : " + experimentId);
- }
-
- synchronized void handleTaskOutputChangeEvent(TaskOutputChangeEvent taskOutputChangeEvent) {
-
- String taskId = taskOutputChangeEvent.getTaskIdentity().getTaskId();
- log.debug("Task Output changed event received for workflow node : " +
- taskOutputChangeEvent.getTaskIdentity().getWorkflowNodeId() + ", task : " + taskId);
- ProcessContext processContext = processingQueue.get(taskId);
- Set<WorkflowNode> tempWfNodeSet = new HashSet<WorkflowNode>();
- if (processContext != null) {
- WorkflowNode workflowNode = processContext.getWorkflowNode();
- if (workflowNode instanceof ApplicationNode) {
- ApplicationNode applicationNode = (ApplicationNode) workflowNode;
- // Workflow node can have one to many output ports and each output port can have one to many links
- for (OutPort outPort : applicationNode.getOutputPorts()) {
- for (OutputDataObjectType outputDataObjectType : taskOutputChangeEvent.getOutput()) {
- if (outPort.getOutputObject().getName().equals(outputDataObjectType.getName())) {
- outPort.getOutputObject().setValue(outputDataObjectType.getValue());
- break;
- }
- }
- for (Edge edge : outPort.getOutEdges()) {
- edge.getToPort().getInputObject().setValue(outPort.getOutputObject().getValue());
- if (edge.getToPort().getNode().isReady()) {
- addToReadyQueue(edge.getToPort().getNode());
- }
- }
- }
- }
- addToCompleteQueue(processContext);
- log.debug("removed task from processing queue : " + taskId);
- try {
- processReadyList();
- } catch (Exception e) {
- log.error("Error while processing ready workflow nodes", e);
- continueWorkflow = false;
- }
- }
- }
-
- void handleTaskStatusChangeEvent(TaskStatusChangeEvent taskStatusChangeEvent) {
- TaskState taskState = taskStatusChangeEvent.getState();
- TaskIdentifier taskIdentity = taskStatusChangeEvent.getTaskIdentity();
- String taskId = taskIdentity.getTaskId();
- ProcessContext processContext = processingQueue.get(taskId);
- if (processContext != null) {
- WorkflowNodeState wfNodeState = WorkflowNodeState.INVOKED;
- switch (taskState) {
- case WAITING:
- break;
- case STARTED:
- break;
- case PRE_PROCESSING:
- wfNodeState = WorkflowNodeState.INVOKED;
- processContext.getWorkflowNode().setState(NodeState.PRE_PROCESSING);
- break;
- case INPUT_DATA_STAGING:
- wfNodeState = WorkflowNodeState.INVOKED;
- processContext.getWorkflowNode().setState(NodeState.PRE_PROCESSING);
- break;
- case EXECUTING:
- wfNodeState = WorkflowNodeState.EXECUTING;
- processContext.getWorkflowNode().setState(NodeState.EXECUTING);
- break;
- case OUTPUT_DATA_STAGING:
- wfNodeState = WorkflowNodeState.COMPLETED;
- processContext.getWorkflowNode().setState(NodeState.POST_PROCESSING);
- break;
- case POST_PROCESSING:
- wfNodeState = WorkflowNodeState.COMPLETED;
- processContext.getWorkflowNode().setState(NodeState.POST_PROCESSING);
- break;
- case COMPLETED:
- wfNodeState = WorkflowNodeState.COMPLETED;
- processContext.getWorkflowNode().setState(NodeState.EXECUTED);
- break;
- case FAILED:
- wfNodeState = WorkflowNodeState.FAILED;
- processContext.getWorkflowNode().setState(NodeState.FAILED);
- break;
- case UNKNOWN:
- wfNodeState = WorkflowNodeState.UNKNOWN;
- break;
- case CONFIGURING_WORKSPACE:
- wfNodeState = WorkflowNodeState.COMPLETED;
- break;
- case CANCELED:
- case CANCELING:
- wfNodeState = WorkflowNodeState.CANCELED;
- processContext.getWorkflowNode().setState(NodeState.FAILED);
- break;
- default:
- break;
- }
- if (wfNodeState != WorkflowNodeState.UNKNOWN) {
- try {
- updateWorkflowNodeStatus(processContext.getWfNodeDetails(), wfNodeState);
- } catch (RegistryException e) {
- log.error("Error while updating workflow node status update to the registry. nodeInstanceId :"
- + processContext.getWfNodeDetails().getNodeInstanceId() + " status to: "
- + processContext.getWfNodeDetails().getWorkflowNodeStatus().toString() , e);
- }
- }
- }
-
- }
-}
http://git-wip-us.apache.org/repos/asf/airavata/blob/509f2037/modules/simple-workflow/src/main/java/org/apache/airavata/simple/workflow/engine/WorkflowEnactmentService.java
----------------------------------------------------------------------
diff --git a/modules/simple-workflow/src/main/java/org/apache/airavata/simple/workflow/engine/WorkflowEnactmentService.java b/modules/simple-workflow/src/main/java/org/apache/airavata/simple/workflow/engine/WorkflowEnactmentService.java
deleted file mode 100644
index c7ab7b9..0000000
--- a/modules/simple-workflow/src/main/java/org/apache/airavata/simple/workflow/engine/WorkflowEnactmentService.java
+++ /dev/null
@@ -1,183 +0,0 @@
-/*
- *
- * 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.simple.workflow.engine;
-
-import org.apache.airavata.common.exception.AiravataException;
-import org.apache.airavata.common.utils.ServerSettings;
-import org.apache.airavata.messaging.core.MessageContext;
-import org.apache.airavata.messaging.core.MessageHandler;
-import org.apache.airavata.messaging.core.MessagingConstants;
-import org.apache.airavata.messaging.core.impl.RabbitMQProcessPublisher;
-import org.apache.airavata.messaging.core.impl.RabbitMQStatusConsumer;
-import org.apache.airavata.model.messaging.event.MessageType;
-import org.apache.airavata.model.messaging.event.TaskIdentifier;
-import org.apache.airavata.model.messaging.event.TaskOutputChangeEvent;
-import org.apache.airavata.model.messaging.event.TaskStatusChangeEvent;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.concurrent.ConcurrentHashMap;
-import java.util.concurrent.ExecutorService;
-import java.util.concurrent.Executors;
-
-public class WorkflowEnactmentService {
-
- private static WorkflowEnactmentService workflowEnactmentService;
- private final RabbitMQStatusConsumer statusConsumer;
- private String consumerId;
- private ExecutorService executor;
- private Map<String,SimpleWorkflowInterpreter> workflowMap;
-
- private WorkflowEnactmentService () throws AiravataException {
- executor = Executors.newFixedThreadPool(getThreadPoolSize());
- workflowMap = new ConcurrentHashMap<String, SimpleWorkflowInterpreter>();
- statusConsumer = new RabbitMQStatusConsumer();
- consumerId = statusConsumer.listen(new TaskMessageHandler());
- // register the shutdown hook to un-bind status consumer.
- Runtime.getRuntime().addShutdownHook(new EnactmentShutDownHook());
- }
-
- public static WorkflowEnactmentService getInstance() throws AiravataException {
- if (workflowEnactmentService == null) {
- synchronized (WorkflowEnactmentService.class) {
- if (workflowEnactmentService == null) {
- workflowEnactmentService = new WorkflowEnactmentService();
- }
- }
- }
- return workflowEnactmentService;
- }
-
- public void submitWorkflow(String experimentId,
- String credentialToken,
- String gatewayName,
- RabbitMQProcessPublisher publisher) throws Exception {
-
- SimpleWorkflowInterpreter simpleWorkflowInterpreter = new SimpleWorkflowInterpreter(
- experimentId, credentialToken,gatewayName, publisher);
- workflowMap.put(experimentId, simpleWorkflowInterpreter);
- simpleWorkflowInterpreter.launchWorkflow();
-
- }
-
- private int getThreadPoolSize() {
- return ServerSettings.getEnactmentThreadPoolSize();
- }
-
- private class TaskMessageHandler implements MessageHandler {
-
- @Override
- public Map<String, Object> getProperties() {
- Map<String, Object> props = new HashMap<String, Object>();
- String gatewayId = "*";
- String experimentId = "*";
- List<String> routingKeys = new ArrayList<String>();
- routingKeys.add(gatewayId);
- routingKeys.add(gatewayId + "." + experimentId);
- routingKeys.add(gatewayId + "." + experimentId+ ".*");
- routingKeys.add(gatewayId + "." + experimentId+ ".*.*");
- props.put(MessagingConstants.RABBIT_ROUTING_KEY, routingKeys);
- return props;
- }
-
- @Override
- public void onMessage(MessageContext msgCtx) {
- StatusHandler statusHandler = new StatusHandler(msgCtx);
- executor.execute(statusHandler);
- }
-
-
- }
-
- private class StatusHandler implements Runnable{
- private final Logger log = LoggerFactory.getLogger(StatusHandler.class);
-
- private final MessageContext msgCtx;
-
- public StatusHandler(MessageContext msgCtx) {
- this.msgCtx = msgCtx;
- }
-
- @Override
- public void run() {
- process();
- }
-
- private void process() {
- String message;
- SimpleWorkflowInterpreter simpleWorkflowInterpreter;
- if (msgCtx.getType() == MessageType.TASK) {
- TaskStatusChangeEvent event = (TaskStatusChangeEvent) msgCtx.getEvent();
- TaskIdentifier taskIdentifier = event.getTaskIdentity();
- simpleWorkflowInterpreter = getInterpreter(taskIdentifier.getExperimentId());
- if (simpleWorkflowInterpreter != null) {
- simpleWorkflowInterpreter.handleTaskStatusChangeEvent(event);
- } else {
- // this happens when Task status messages comes after the Taskoutput messages,as we have worked on
- // output changes it is ok to ignore this.
- }
- message = "Received task output change event , expId : " + taskIdentifier.getExperimentId() + ", taskId : " + taskIdentifier.getTaskId() + ", workflow node Id : " + taskIdentifier.getWorkflowNodeId();
- log.debug(message);
- }else if (msgCtx.getType() == MessageType.TASKOUTPUT) {
- TaskOutputChangeEvent event = (TaskOutputChangeEvent) msgCtx.getEvent();
- TaskIdentifier taskIdentifier = event.getTaskIdentity();
- simpleWorkflowInterpreter = getInterpreter(taskIdentifier.getExperimentId());
- if (simpleWorkflowInterpreter != null) {
- simpleWorkflowInterpreter.handleTaskOutputChangeEvent(event);
- if (simpleWorkflowInterpreter.isAllDone()) {
- workflowMap.remove(taskIdentifier.getExperimentId());
- }
- } else {
- throw new IllegalArgumentException("Error while processing TaskOutputChangeEvent, " +
- "There is no registered workflow for experiment Id : " + taskIdentifier.getExperimentId());
- }
- message = "Received task output change event , expId : " + taskIdentifier.getExperimentId() + ", taskId : " + taskIdentifier.getTaskId() + ", workflow node Id : " + taskIdentifier.getWorkflowNodeId();
- log.debug(message);
- } else {
- // not interested, ignores
- }
- }
-
- private SimpleWorkflowInterpreter getInterpreter(String experimentId){
- return workflowMap.get(experimentId);
- }
- }
-
-
- private class EnactmentShutDownHook extends Thread {
- private final Logger log = LoggerFactory.getLogger(EnactmentShutDownHook.class);
- @Override
- public void run() {
- super.run();
- try {
- statusConsumer.stopListen(consumerId);
- log.info("Successfully un-binded task status consumer");
- } catch (AiravataException e) {
- log.error("Error while un-bind enactment status consumer", e);
- }
- }
- }
-}
http://git-wip-us.apache.org/repos/asf/airavata/blob/509f2037/modules/simple-workflow/src/main/java/org/apache/airavata/simple/workflow/engine/WorkflowFactory.java
----------------------------------------------------------------------
diff --git a/modules/simple-workflow/src/main/java/org/apache/airavata/simple/workflow/engine/WorkflowFactory.java b/modules/simple-workflow/src/main/java/org/apache/airavata/simple/workflow/engine/WorkflowFactory.java
deleted file mode 100644
index 9631768..0000000
--- a/modules/simple-workflow/src/main/java/org/apache/airavata/simple/workflow/engine/WorkflowFactory.java
+++ /dev/null
@@ -1,31 +0,0 @@
-/*
- *
- * 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.simple.workflow.engine;
-
-/**
- * All classes implement this WorkflowFactory interface, should be abstract or singleton.
- */
-public interface WorkflowFactory {
-
- public WorkflowParser getWorkflowParser(String experimentId, String credentialToken) throws Exception;
-
-}
http://git-wip-us.apache.org/repos/asf/airavata/blob/509f2037/modules/simple-workflow/src/main/java/org/apache/airavata/simple/workflow/engine/WorkflowFactoryImpl.java
----------------------------------------------------------------------
diff --git a/modules/simple-workflow/src/main/java/org/apache/airavata/simple/workflow/engine/WorkflowFactoryImpl.java b/modules/simple-workflow/src/main/java/org/apache/airavata/simple/workflow/engine/WorkflowFactoryImpl.java
deleted file mode 100644
index e70f062..0000000
--- a/modules/simple-workflow/src/main/java/org/apache/airavata/simple/workflow/engine/WorkflowFactoryImpl.java
+++ /dev/null
@@ -1,74 +0,0 @@
-/*
- *
- * 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.simple.workflow.engine;
-
-import org.apache.airavata.common.exception.ApplicationSettingsException;
-import org.apache.airavata.common.utils.ServerSettings;
-import org.apache.airavata.simple.workflow.engine.parser.AiravataWorkflowParser;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import java.lang.reflect.Constructor;
-
-/**
- * Singleton class, only one instance can exist in runtime.
- */
-public class WorkflowFactoryImpl implements WorkflowFactory {
-
- private static final Logger log = LoggerFactory.getLogger(WorkflowFactoryImpl.class);
-
- private static WorkflowFactoryImpl workflowFactoryImpl;
-
- private WorkflowFactoryImpl(){
-
- }
-
- public static WorkflowFactoryImpl getInstance() {
- if (workflowFactoryImpl == null) {
- synchronized (WorkflowFactory.class) {
- if (workflowFactoryImpl == null) {
- workflowFactoryImpl = new WorkflowFactoryImpl();
- }
- }
- }
- return workflowFactoryImpl;
- }
-
-
- @Override
- public WorkflowParser getWorkflowParser(String experimentId, String credentialToken) throws Exception {
- WorkflowParser workflowParser = null;
- try {
- String wfParserClassName = ServerSettings.getWorkflowParser();
- Class<?> aClass = Class.forName(wfParserClassName);
- Constructor<?> constructor = aClass.getConstructor(String.class, String.class);
- workflowParser = (WorkflowParser) constructor.newInstance(experimentId, credentialToken);
- } catch (ApplicationSettingsException e) {
- log.info("A custom workflow parser is not defined, Use default Airavata workflow parser");
- }
- if (workflowParser == null) {
- workflowParser = new AiravataWorkflowParser(experimentId, credentialToken);
- }
- return workflowParser;
- }
-
-}
http://git-wip-us.apache.org/repos/asf/airavata/blob/509f2037/modules/simple-workflow/src/main/java/org/apache/airavata/simple/workflow/engine/WorkflowParser.java
----------------------------------------------------------------------
diff --git a/modules/simple-workflow/src/main/java/org/apache/airavata/simple/workflow/engine/WorkflowParser.java b/modules/simple-workflow/src/main/java/org/apache/airavata/simple/workflow/engine/WorkflowParser.java
deleted file mode 100644
index 6c4d6f2..0000000
--- a/modules/simple-workflow/src/main/java/org/apache/airavata/simple/workflow/engine/WorkflowParser.java
+++ /dev/null
@@ -1,32 +0,0 @@
-/*
- *
- * 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.simple.workflow.engine;
-
-import org.apache.airavata.simple.workflow.engine.dag.nodes.WorkflowInputNode;
-
-import java.util.List;
-
-public interface WorkflowParser {
-
- public List<WorkflowInputNode> parse() throws Exception;
-
-}
http://git-wip-us.apache.org/repos/asf/airavata/blob/509f2037/modules/simple-workflow/src/main/java/org/apache/airavata/simple/workflow/engine/dag/edge/DirectedEdge.java
----------------------------------------------------------------------
diff --git a/modules/simple-workflow/src/main/java/org/apache/airavata/simple/workflow/engine/dag/edge/DirectedEdge.java b/modules/simple-workflow/src/main/java/org/apache/airavata/simple/workflow/engine/dag/edge/DirectedEdge.java
deleted file mode 100644
index ae7498a..0000000
--- a/modules/simple-workflow/src/main/java/org/apache/airavata/simple/workflow/engine/dag/edge/DirectedEdge.java
+++ /dev/null
@@ -1,52 +0,0 @@
-/*
- *
- * 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.simple.workflow.engine.dag.edge;
-
-import org.apache.airavata.simple.workflow.engine.dag.port.InPort;
-import org.apache.airavata.simple.workflow.engine.dag.port.OutPort;
-
-
-public class DirectedEdge implements Edge {
-
- private InPort inPort;
- private OutPort outPort;
-
- @Override
- public InPort getToPort() {
- return inPort;
- }
-
- @Override
- public void setToPort(InPort inPort) {
- this.inPort = inPort;
- }
-
- @Override
- public OutPort getFromPort() {
- return outPort;
- }
-
- @Override
- public void setFromPort(OutPort outPort) {
- this.outPort = outPort;
- }
-}
http://git-wip-us.apache.org/repos/asf/airavata/blob/509f2037/modules/simple-workflow/src/main/java/org/apache/airavata/simple/workflow/engine/dag/edge/Edge.java
----------------------------------------------------------------------
diff --git a/modules/simple-workflow/src/main/java/org/apache/airavata/simple/workflow/engine/dag/edge/Edge.java b/modules/simple-workflow/src/main/java/org/apache/airavata/simple/workflow/engine/dag/edge/Edge.java
deleted file mode 100644
index e8bce2e..0000000
--- a/modules/simple-workflow/src/main/java/org/apache/airavata/simple/workflow/engine/dag/edge/Edge.java
+++ /dev/null
@@ -1,43 +0,0 @@
-/*
- *
- * 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.simple.workflow.engine.dag.edge;
-
-import org.apache.airavata.simple.workflow.engine.dag.port.InPort;
-import org.apache.airavata.simple.workflow.engine.dag.port.OutPort;
-
-/**
- * Edge is a link to one node to another, basically edge should have outPort of a workflow node ,
- * which is starting point and inPort of a workflow node, which is end point of the edge.
- */
-
-public interface Edge {
-
- public InPort getToPort();
-
- public void setToPort(InPort inPort);
-
- public OutPort getFromPort();
-
- public void setFromPort(OutPort outPort);
-
-
-}
http://git-wip-us.apache.org/repos/asf/airavata/blob/509f2037/modules/simple-workflow/src/main/java/org/apache/airavata/simple/workflow/engine/dag/nodes/ApplicationNode.java
----------------------------------------------------------------------
diff --git a/modules/simple-workflow/src/main/java/org/apache/airavata/simple/workflow/engine/dag/nodes/ApplicationNode.java b/modules/simple-workflow/src/main/java/org/apache/airavata/simple/workflow/engine/dag/nodes/ApplicationNode.java
deleted file mode 100644
index 37efded..0000000
--- a/modules/simple-workflow/src/main/java/org/apache/airavata/simple/workflow/engine/dag/nodes/ApplicationNode.java
+++ /dev/null
@@ -1,41 +0,0 @@
-/*
- *
- * 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.simple.workflow.engine.dag.nodes;
-
-import org.apache.airavata.simple.workflow.engine.dag.port.InPort;
-import org.apache.airavata.simple.workflow.engine.dag.port.OutPort;
-
-import java.util.List;
-
-public interface ApplicationNode extends WorkflowNode {
-
- public String getApplicationId();
-
- public void addInPort(InPort inPort);
-
- public List<InPort> getInputPorts();
-
- public void addOutPort(OutPort outPort);
-
- public List<OutPort> getOutputPorts();
-
-}
http://git-wip-us.apache.org/repos/asf/airavata/blob/509f2037/modules/simple-workflow/src/main/java/org/apache/airavata/simple/workflow/engine/dag/nodes/ApplicationNodeImpl.java
----------------------------------------------------------------------
diff --git a/modules/simple-workflow/src/main/java/org/apache/airavata/simple/workflow/engine/dag/nodes/ApplicationNodeImpl.java b/modules/simple-workflow/src/main/java/org/apache/airavata/simple/workflow/engine/dag/nodes/ApplicationNodeImpl.java
deleted file mode 100644
index 1233a9d..0000000
--- a/modules/simple-workflow/src/main/java/org/apache/airavata/simple/workflow/engine/dag/nodes/ApplicationNodeImpl.java
+++ /dev/null
@@ -1,116 +0,0 @@
-/*
- *
- * 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.simple.workflow.engine.dag.nodes;
-
-import org.apache.airavata.simple.workflow.engine.dag.port.InPort;
-import org.apache.airavata.simple.workflow.engine.dag.port.OutPort;
-
-import java.util.ArrayList;
-import java.util.List;
-
-public class ApplicationNodeImpl implements ApplicationNode {
-
- private final String nodeId;
- private NodeState myState = NodeState.WAITING;
- private String applicationId;
- private List<InPort> inPorts = new ArrayList<InPort>();
- private List<OutPort> outPorts = new ArrayList<OutPort>();
- private String applicationName;
-
-// public ApplicationNodeImpl(String nodeId) {
-// this(nodeId, null);
-// }
-//
-// public ApplicationNodeImpl(String nodeId, String applicationId) {
-// this(nodeId, null, applicationId);
-// }
-
- public ApplicationNodeImpl(String nodeId, String applicationName, String applicationId) {
- this.nodeId = nodeId;
- this.applicationName = applicationName;
- this.applicationId = applicationId;
- }
-
- @Override
- public String getId() {
- return this.nodeId;
- }
-
- @Override
- public String getName() {
- return applicationName;
- }
-
- @Override
- public NodeType getType() {
- return NodeType.APPLICATION;
- }
-
- @Override
- public NodeState getState() {
- return myState;
- }
-
- @Override
- public void setState(NodeState newState) {
- if (newState.getLevel() > myState.getLevel()) {
- myState = newState;
- } else {
- throw new IllegalStateException("Node state can't be reversed. currentState : " + myState.toString() + " , newState " + newState.toString());
- }
- }
-
- @Override
- public boolean isReady() {
- for (InPort inPort : getInputPorts()) {
- if (!inPort.isReady()) {
- return false;
- }
- }
- return true;
- }
-
- @Override
- public String getApplicationId() {
- return this.applicationId;
- }
-
- @Override
- public void addInPort(InPort inPort) {
- this.inPorts.add(inPort);
- }
-
- @Override
- public List<InPort> getInputPorts() {
- return this.inPorts;
- }
-
- @Override
- public void addOutPort(OutPort outPort) {
- this.outPorts.add(outPort);
- }
-
- @Override
- public List<OutPort> getOutputPorts() {
- return this.outPorts;
- }
-}
http://git-wip-us.apache.org/repos/asf/airavata/blob/509f2037/modules/simple-workflow/src/main/java/org/apache/airavata/simple/workflow/engine/dag/nodes/NodeState.java
----------------------------------------------------------------------
diff --git a/modules/simple-workflow/src/main/java/org/apache/airavata/simple/workflow/engine/dag/nodes/NodeState.java b/modules/simple-workflow/src/main/java/org/apache/airavata/simple/workflow/engine/dag/nodes/NodeState.java
deleted file mode 100644
index edbeec5..0000000
--- a/modules/simple-workflow/src/main/java/org/apache/airavata/simple/workflow/engine/dag/nodes/NodeState.java
+++ /dev/null
@@ -1,44 +0,0 @@
-/*
- *
- * 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.simple.workflow.engine.dag.nodes;
-
-public enum NodeState {
- WAITING(0), // waiting on inputs
- READY(1), // all inputs are available and ready to execute
- QUEUED(2), //
- PRE_PROCESSING(3), //
- EXECUTING(4), // task has been submitted , not yet finish
- EXECUTED(5), // task executed
- POST_PROCESSING(6), //
- FAILED(7),
- COMPLETE(8); // all works done
-
- private int level;
-
- NodeState(int level) {
- this.level = level;
- }
-
- public int getLevel() {
- return level;
- }
-}
http://git-wip-us.apache.org/repos/asf/airavata/blob/509f2037/modules/simple-workflow/src/main/java/org/apache/airavata/simple/workflow/engine/dag/nodes/NodeType.java
----------------------------------------------------------------------
diff --git a/modules/simple-workflow/src/main/java/org/apache/airavata/simple/workflow/engine/dag/nodes/NodeType.java b/modules/simple-workflow/src/main/java/org/apache/airavata/simple/workflow/engine/dag/nodes/NodeType.java
deleted file mode 100644
index 95710fb..0000000
--- a/modules/simple-workflow/src/main/java/org/apache/airavata/simple/workflow/engine/dag/nodes/NodeType.java
+++ /dev/null
@@ -1,28 +0,0 @@
-/*
- *
- * 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.simple.workflow.engine.dag.nodes;
-
-public enum NodeType {
- APPLICATION,
- WORKFLOW_INPUT,
- WORKFLOW_OUTPUT
-}
http://git-wip-us.apache.org/repos/asf/airavata/blob/509f2037/modules/simple-workflow/src/main/java/org/apache/airavata/simple/workflow/engine/dag/nodes/WorkflowInputNode.java
----------------------------------------------------------------------
diff --git a/modules/simple-workflow/src/main/java/org/apache/airavata/simple/workflow/engine/dag/nodes/WorkflowInputNode.java b/modules/simple-workflow/src/main/java/org/apache/airavata/simple/workflow/engine/dag/nodes/WorkflowInputNode.java
deleted file mode 100644
index 9ac800a..0000000
--- a/modules/simple-workflow/src/main/java/org/apache/airavata/simple/workflow/engine/dag/nodes/WorkflowInputNode.java
+++ /dev/null
@@ -1,37 +0,0 @@
-/*
- *
- * 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.simple.workflow.engine.dag.nodes;
-
-import org.apache.airavata.model.appcatalog.appinterface.InputDataObjectType;
-import org.apache.airavata.simple.workflow.engine.dag.port.OutPort;
-
-public interface WorkflowInputNode extends WorkflowNode {
-
- public InputDataObjectType getInputObject();
-
- public void setInputObject(InputDataObjectType inputObject);
-
- public OutPort getOutPort();
-
- public void setOutPort(OutPort outPort);
-
-}
http://git-wip-us.apache.org/repos/asf/airavata/blob/509f2037/modules/simple-workflow/src/main/java/org/apache/airavata/simple/workflow/engine/dag/nodes/WorkflowInputNodeImpl.java
----------------------------------------------------------------------
diff --git a/modules/simple-workflow/src/main/java/org/apache/airavata/simple/workflow/engine/dag/nodes/WorkflowInputNodeImpl.java b/modules/simple-workflow/src/main/java/org/apache/airavata/simple/workflow/engine/dag/nodes/WorkflowInputNodeImpl.java
deleted file mode 100644
index 7ba8908..0000000
--- a/modules/simple-workflow/src/main/java/org/apache/airavata/simple/workflow/engine/dag/nodes/WorkflowInputNodeImpl.java
+++ /dev/null
@@ -1,99 +0,0 @@
-/*
- * 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.simple.workflow.engine.dag.nodes;
-
-import org.apache.airavata.model.appcatalog.appinterface.InputDataObjectType;
-import org.apache.airavata.simple.workflow.engine.dag.port.OutPort;
-
-public class WorkflowInputNodeImpl implements WorkflowInputNode {
-
- private NodeState myState = NodeState.READY;
- private final String nodeId;
- private String nodeName;
- private OutPort outPort;
- private InputDataObjectType inputDataObjectType;
- private String name;
-
- public WorkflowInputNodeImpl(String nodeId) {
- this(nodeId, null);
- }
-
- public WorkflowInputNodeImpl(String nodeId, String nodeName) {
- this.nodeId = nodeId;
- this.nodeName = nodeName;
- }
-
- @Override
- public String getId() {
- return this.nodeId;
- }
-
- @Override
- public String getName() {
- return this.nodeName;
- }
-
- @Override
- public NodeType getType() {
- return NodeType.WORKFLOW_INPUT;
- }
-
- @Override
- public NodeState getState() {
- return myState;
- }
-
- @Override
- public void setState(NodeState newState) {
- if (newState.getLevel() > myState.getLevel()) {
- myState = newState;
- } else {
- throw new IllegalStateException("Node state can't be reversed. currentState : " + myState.toString() + " , newState " + newState.toString());
- }
- }
-
- @Override
- public boolean isReady() {
- return (inputDataObjectType.getValue() != null && !inputDataObjectType.getValue().equals(""))
- || !inputDataObjectType.isIsRequired();
- }
-
- @Override
- public InputDataObjectType getInputObject() {
- return this.inputDataObjectType;
- }
-
- @Override
- public void setInputObject(InputDataObjectType inputObject) {
- this.inputDataObjectType = inputObject;
- }
-
- @Override
- public OutPort getOutPort() {
- return this.outPort;
- }
-
- @Override
- public void setOutPort(OutPort outPort) {
- this.outPort = outPort;
- }
-
-
-}
http://git-wip-us.apache.org/repos/asf/airavata/blob/509f2037/modules/simple-workflow/src/main/java/org/apache/airavata/simple/workflow/engine/dag/nodes/WorkflowNode.java
----------------------------------------------------------------------
diff --git a/modules/simple-workflow/src/main/java/org/apache/airavata/simple/workflow/engine/dag/nodes/WorkflowNode.java b/modules/simple-workflow/src/main/java/org/apache/airavata/simple/workflow/engine/dag/nodes/WorkflowNode.java
deleted file mode 100644
index efcf9c7..0000000
--- a/modules/simple-workflow/src/main/java/org/apache/airavata/simple/workflow/engine/dag/nodes/WorkflowNode.java
+++ /dev/null
@@ -1,38 +0,0 @@
-/*
- *
- * 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.simple.workflow.engine.dag.nodes;
-
-public interface WorkflowNode {
-
- public String getId();
-
- public String getName();
-
- public NodeType getType();
-
- public NodeState getState();
-
- public void setState(NodeState newState);
-
- public boolean isReady();
-
-}
http://git-wip-us.apache.org/repos/asf/airavata/blob/509f2037/modules/simple-workflow/src/main/java/org/apache/airavata/simple/workflow/engine/dag/nodes/WorkflowOutputNode.java
----------------------------------------------------------------------
diff --git a/modules/simple-workflow/src/main/java/org/apache/airavata/simple/workflow/engine/dag/nodes/WorkflowOutputNode.java b/modules/simple-workflow/src/main/java/org/apache/airavata/simple/workflow/engine/dag/nodes/WorkflowOutputNode.java
deleted file mode 100644
index 14e4519..0000000
--- a/modules/simple-workflow/src/main/java/org/apache/airavata/simple/workflow/engine/dag/nodes/WorkflowOutputNode.java
+++ /dev/null
@@ -1,37 +0,0 @@
-/*
- *
- * 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.simple.workflow.engine.dag.nodes;
-
-import org.apache.airavata.model.appcatalog.appinterface.OutputDataObjectType;
-import org.apache.airavata.simple.workflow.engine.dag.port.InPort;
-
-public interface WorkflowOutputNode extends WorkflowNode {
-
- public OutputDataObjectType getOutputObject();
-
- public void setOutputObject(OutputDataObjectType outputObject);
-
- public InPort getInPort();
-
- public void setInPort(InPort inPort);
-
-}
http://git-wip-us.apache.org/repos/asf/airavata/blob/509f2037/modules/simple-workflow/src/main/java/org/apache/airavata/simple/workflow/engine/dag/nodes/WorkflowOutputNodeImpl.java
----------------------------------------------------------------------
diff --git a/modules/simple-workflow/src/main/java/org/apache/airavata/simple/workflow/engine/dag/nodes/WorkflowOutputNodeImpl.java b/modules/simple-workflow/src/main/java/org/apache/airavata/simple/workflow/engine/dag/nodes/WorkflowOutputNodeImpl.java
deleted file mode 100644
index 6c80517..0000000
--- a/modules/simple-workflow/src/main/java/org/apache/airavata/simple/workflow/engine/dag/nodes/WorkflowOutputNodeImpl.java
+++ /dev/null
@@ -1,100 +0,0 @@
-/*
- *
- * 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.simple.workflow.engine.dag.nodes;
-
-import org.apache.airavata.model.appcatalog.appinterface.OutputDataObjectType;
-import org.apache.airavata.simple.workflow.engine.dag.port.InPort;
-
-public class WorkflowOutputNodeImpl implements WorkflowOutputNode {
-
- private NodeState myState = NodeState.WAITING;
- private final String nodeId;
- private String nodeName;
- private OutputDataObjectType outputDataObjectType;
- private InPort inPort;
-
- public WorkflowOutputNodeImpl(String nodeId) {
- this(nodeId, null);
- }
-
- public WorkflowOutputNodeImpl(String nodeId, String nodeName) {
- this.nodeId = nodeId;
- this.nodeName = nodeName;
- }
-
- @Override
- public String getId() {
- return this.nodeId;
- }
-
- @Override
- public String getName() {
- return this.nodeName;
- }
-
- @Override
- public NodeType getType() {
- return NodeType.WORKFLOW_OUTPUT;
- }
-
- @Override
- public NodeState getState() {
- return myState;
- }
-
- @Override
- public void setState(NodeState newState) {
- if (newState.getLevel() > myState.getLevel()) {
- myState = newState;
- } else {
- throw new IllegalStateException("Node state can't be reversed. currentState : " + myState.toString() + " , newState " + newState.toString());
- }
- }
-
- @Override
- public boolean isReady() {
- return !(inPort.getInputObject() == null || inPort.getInputObject().getValue() == null
- || inPort.getInputObject().getValue().equals(""));
- }
-
- @Override
- public OutputDataObjectType getOutputObject() {
- return this.outputDataObjectType;
- }
-
- @Override
- public void setOutputObject(OutputDataObjectType outputObject) {
- this.outputDataObjectType = outputObject;
- }
-
- @Override
- public InPort getInPort() {
- return this.inPort;
- }
-
- @Override
- public void setInPort(InPort inPort) {
- this.inPort = inPort;
- }
-
-}
-
http://git-wip-us.apache.org/repos/asf/airavata/blob/509f2037/modules/simple-workflow/src/main/java/org/apache/airavata/simple/workflow/engine/dag/port/InPort.java
----------------------------------------------------------------------
diff --git a/modules/simple-workflow/src/main/java/org/apache/airavata/simple/workflow/engine/dag/port/InPort.java b/modules/simple-workflow/src/main/java/org/apache/airavata/simple/workflow/engine/dag/port/InPort.java
deleted file mode 100644
index bb4a112..0000000
--- a/modules/simple-workflow/src/main/java/org/apache/airavata/simple/workflow/engine/dag/port/InPort.java
+++ /dev/null
@@ -1,41 +0,0 @@
-/*
- *
- * 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.simple.workflow.engine.dag.port;
-
-import org.apache.airavata.model.appcatalog.appinterface.InputDataObjectType;
-import org.apache.airavata.simple.workflow.engine.dag.edge.Edge;
-
-public interface InPort extends Port {
-
- public void setInputObject(InputDataObjectType inputObject);
-
- public InputDataObjectType getInputObject();
-
- public Edge getEdge();
-
- public void addEdge(Edge edge);
-
- public String getDefaultValue();
-
- public void setDefaultValue(String defaultValue);
-
-}
[40/50] [abbrv] airavata git commit: Renamed simple-workflow module
to workflow and created a new workflow-core module which will keep all the
core code
Posted by sh...@apache.org.
http://git-wip-us.apache.org/repos/asf/airavata/blob/509f2037/pom.xml
----------------------------------------------------------------------
diff --git a/pom.xml b/pom.xml
index 9250888..3a48f23 100644
--- a/pom.xml
+++ b/pom.xml
@@ -536,7 +536,7 @@
<!--<module>modules/ws-messenger</module>-->
<module>modules/messaging</module>
<module>modules/integration-tests</module>
- <module>modules/simple-workflow</module>
+ <module>modules/workflow</module>
<module>modules/xbaya-gui</module>
</modules>
</profile>
[05/50] [abbrv] airavata git commit: Remove workflow engine class
from the module
Posted by sh...@apache.org.
Remove workflow engine class from the module
Project: http://git-wip-us.apache.org/repos/asf/airavata/repo
Commit: http://git-wip-us.apache.org/repos/asf/airavata/commit/9fcf2267
Tree: http://git-wip-us.apache.org/repos/asf/airavata/tree/9fcf2267
Diff: http://git-wip-us.apache.org/repos/asf/airavata/diff/9fcf2267
Branch: refs/heads/master
Commit: 9fcf22671b1423ca15d8953c51a4e12bdaf00fe0
Parents: 263522a
Author: shamrath <sh...@gmail.com>
Authored: Mon Feb 16 22:11:08 2015 -0500
Committer: shamrath <sh...@gmail.com>
Committed: Mon Feb 16 22:11:08 2015 -0500
----------------------------------------------------------------------
.../workflow/engine/SimpleWorkflowEngine.java | 31 --------------------
.../engine/SimpleWorkflowInterpreter.java | 11 +++++--
.../simple/workflow/engine/WorkflowFactory.java | 2 +-
.../workflow/engine/WorkflowFactoryImpl.java | 19 ++++++++++--
.../engine/parser/AiravataDefaultParser.java | 7 +++--
.../parser/AiravataDefaultParserTest.java | 4 +++
6 files changed, 35 insertions(+), 39 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/airavata/blob/9fcf2267/modules/simple-workflow/src/main/java/org/apache/ariavata/simple/workflow/engine/SimpleWorkflowEngine.java
----------------------------------------------------------------------
diff --git a/modules/simple-workflow/src/main/java/org/apache/ariavata/simple/workflow/engine/SimpleWorkflowEngine.java b/modules/simple-workflow/src/main/java/org/apache/ariavata/simple/workflow/engine/SimpleWorkflowEngine.java
deleted file mode 100644
index ff057fb..0000000
--- a/modules/simple-workflow/src/main/java/org/apache/ariavata/simple/workflow/engine/SimpleWorkflowEngine.java
+++ /dev/null
@@ -1,31 +0,0 @@
-/*
- *
- * 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.ariavata.simple.workflow.engine;
-
-public class SimpleWorkflowEngine{
-
-
- public void invoke () {
- WorkflowParser parser = WorkflowFactoryImpl.getInstance().getWorkflowParser();
-
- }
-}
http://git-wip-us.apache.org/repos/asf/airavata/blob/9fcf2267/modules/simple-workflow/src/main/java/org/apache/ariavata/simple/workflow/engine/SimpleWorkflowInterpreter.java
----------------------------------------------------------------------
diff --git a/modules/simple-workflow/src/main/java/org/apache/ariavata/simple/workflow/engine/SimpleWorkflowInterpreter.java b/modules/simple-workflow/src/main/java/org/apache/ariavata/simple/workflow/engine/SimpleWorkflowInterpreter.java
index b4bc9a2..3d5b99a 100644
--- a/modules/simple-workflow/src/main/java/org/apache/ariavata/simple/workflow/engine/SimpleWorkflowInterpreter.java
+++ b/modules/simple-workflow/src/main/java/org/apache/ariavata/simple/workflow/engine/SimpleWorkflowInterpreter.java
@@ -52,7 +52,7 @@ import java.util.List;
import java.util.Map;
import java.util.Set;
-public class SimpleWorkflowInterpreter {
+public class SimpleWorkflowInterpreter implements Runnable{
private List<WorkflowInputNode> workflowInputNodes;
@@ -151,6 +151,7 @@ public class SimpleWorkflowInterpreter {
Set<WorkflowNode> tempNodeSet = new HashSet<WorkflowNode>();
for (WorkflowInputNode wfInputNode : wfInputNodes) {
if (wfInputNode.isSatisfy()) {
+
// for (Edge edge : wfInputNode.getOutputLinks()) {
// WorkflowUtil.copyValues(wfInputNode.getInputObject(), edge.getToPort().getInputObject());
// tempNodeSet.add(edge.getToPort().getNode());
@@ -171,7 +172,8 @@ public class SimpleWorkflowInterpreter {
if (workflowInputNodes == null) {
// read workflow description from registry and parse it
WorkflowFactoryImpl wfFactory = WorkflowFactoryImpl.getInstance();
- List<WorkflowInputNode> wfInputNodes = wfFactory.getWorkflowParser().parse();
+ List<WorkflowInputNode> wfInputNodes = wfFactory.getWorkflowParser(experiment.getExperimentID(),
+ credentialToken).parse();
setWorkflowInputNodes(wfInputNodes);
}
return workflowInputNodes;
@@ -287,4 +289,9 @@ public class SimpleWorkflowInterpreter {
}
}
+
+ @Override
+ public void run() {
+ // TODO: Auto generated method body.
+ }
}
http://git-wip-us.apache.org/repos/asf/airavata/blob/9fcf2267/modules/simple-workflow/src/main/java/org/apache/ariavata/simple/workflow/engine/WorkflowFactory.java
----------------------------------------------------------------------
diff --git a/modules/simple-workflow/src/main/java/org/apache/ariavata/simple/workflow/engine/WorkflowFactory.java b/modules/simple-workflow/src/main/java/org/apache/ariavata/simple/workflow/engine/WorkflowFactory.java
index 867bc80..6cfceaf 100644
--- a/modules/simple-workflow/src/main/java/org/apache/ariavata/simple/workflow/engine/WorkflowFactory.java
+++ b/modules/simple-workflow/src/main/java/org/apache/ariavata/simple/workflow/engine/WorkflowFactory.java
@@ -5,6 +5,6 @@ package org.apache.ariavata.simple.workflow.engine;
*/
public interface WorkflowFactory {
- public WorkflowParser getWorkflowParser();
+ public WorkflowParser getWorkflowParser(String experimentId, String credentialToken);
}
http://git-wip-us.apache.org/repos/asf/airavata/blob/9fcf2267/modules/simple-workflow/src/main/java/org/apache/ariavata/simple/workflow/engine/WorkflowFactoryImpl.java
----------------------------------------------------------------------
diff --git a/modules/simple-workflow/src/main/java/org/apache/ariavata/simple/workflow/engine/WorkflowFactoryImpl.java b/modules/simple-workflow/src/main/java/org/apache/ariavata/simple/workflow/engine/WorkflowFactoryImpl.java
index a43f010..f84acc9 100644
--- a/modules/simple-workflow/src/main/java/org/apache/ariavata/simple/workflow/engine/WorkflowFactoryImpl.java
+++ b/modules/simple-workflow/src/main/java/org/apache/ariavata/simple/workflow/engine/WorkflowFactoryImpl.java
@@ -21,6 +21,8 @@
package org.apache.ariavata.simple.workflow.engine;
+import org.apache.ariavata.simple.workflow.engine.parser.AiravataDefaultParser;
+
/**
* Singleton class, only one instance can exist in runtime.
*/
@@ -28,6 +30,9 @@ public class WorkflowFactoryImpl implements WorkflowFactory {
private static WorkflowFactoryImpl workflowFactoryImpl;
+ private WorkflowEnactor workflowEnactor;
+ private WorkflowParser workflowParser;
+
private WorkflowFactoryImpl(){
}
@@ -45,8 +50,18 @@ public class WorkflowFactoryImpl implements WorkflowFactory {
@Override
- public WorkflowParser getWorkflowParser() {
+ public WorkflowParser getWorkflowParser(String experimentId, String credentialToken) {
+ if (workflowParser == null) {
+ workflowParser = new AiravataDefaultParser(experimentId, credentialToken);
+ }
+ return workflowParser;
+ }
- return null; // TODO: Auto generated method body.
+ @Override
+ public WorkflowEnactor getWorkflowEnactor() {
+ if (workflowEnactor == null) {
+ workflowEnactor = new WorkflowEnactor();
+ }
+ return workflowEnactor;
}
}
http://git-wip-us.apache.org/repos/asf/airavata/blob/9fcf2267/modules/simple-workflow/src/main/java/org/apache/ariavata/simple/workflow/engine/parser/AiravataDefaultParser.java
----------------------------------------------------------------------
diff --git a/modules/simple-workflow/src/main/java/org/apache/ariavata/simple/workflow/engine/parser/AiravataDefaultParser.java b/modules/simple-workflow/src/main/java/org/apache/ariavata/simple/workflow/engine/parser/AiravataDefaultParser.java
index baca99e..62a76b3 100644
--- a/modules/simple-workflow/src/main/java/org/apache/ariavata/simple/workflow/engine/parser/AiravataDefaultParser.java
+++ b/modules/simple-workflow/src/main/java/org/apache/ariavata/simple/workflow/engine/parser/AiravataDefaultParser.java
@@ -125,7 +125,7 @@ public class AiravataDefaultParser implements WorkflowParser {
DataPort dataPort = null;
InPort inPort = null;
ApplicationNode wfApplicationNode = null;
- WorkflowOutputNode wfOutportNode = null;
+ WorkflowOutputNode wfOutputNode = null;
List<PortContainer> nextPortContainerList = new ArrayList<PortContainer>();
for (PortContainer portContainer : portContainerList) {
dataPort = portContainer.getDataPort();
@@ -150,8 +150,9 @@ public class AiravataDefaultParser implements WorkflowParser {
}else if (node instanceof OutputNode) {
OutputNode oNode = (OutputNode) node;
- wfOutportNode = new WorkflowOutputNodeImpl(oNode.getID(), oNode.getName());
- wfOutportNode.setInPort(inPort);
+ wfOutputNode = new WorkflowOutputNodeImpl(oNode.getID(), oNode.getName());
+ wfOutputNode.setInPort(inPort);
+ wfNodes.put(wfOutputNode.getNodeId(), wfOutputNode);
}
// set the workflow node to inPort
// if require check the types of inputs and output ports,
http://git-wip-us.apache.org/repos/asf/airavata/blob/9fcf2267/modules/simple-workflow/src/test/java/org/apache/ariavata/simple/workflow/engine/parser/AiravataDefaultParserTest.java
----------------------------------------------------------------------
diff --git a/modules/simple-workflow/src/test/java/org/apache/ariavata/simple/workflow/engine/parser/AiravataDefaultParserTest.java b/modules/simple-workflow/src/test/java/org/apache/ariavata/simple/workflow/engine/parser/AiravataDefaultParserTest.java
index ea955d8..1f8e9c8 100644
--- a/modules/simple-workflow/src/test/java/org/apache/ariavata/simple/workflow/engine/parser/AiravataDefaultParserTest.java
+++ b/modules/simple-workflow/src/test/java/org/apache/ariavata/simple/workflow/engine/parser/AiravataDefaultParserTest.java
@@ -8,6 +8,7 @@ import org.apache.airavata.workflow.model.wf.Workflow;
import org.apache.ariavata.simple.workflow.engine.dag.nodes.ApplicationNode;
import org.apache.ariavata.simple.workflow.engine.dag.nodes.WorkflowInputNode;
import org.apache.ariavata.simple.workflow.engine.dag.nodes.WorkflowNode;
+import org.apache.ariavata.simple.workflow.engine.dag.nodes.WorkflowOutputNode;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
@@ -77,6 +78,9 @@ public class AiravataDefaultParserTest {
ApplicationNode node = (ApplicationNode) wfNode;
Assert.assertEquals(2, node.getInputPorts().size());
Assert.assertEquals(1, node.getOutputPorts().size());
+ }else if (wfNode instanceof WorkflowOutputNode) {
+ WorkflowOutputNode workflowOutputNode = (WorkflowOutputNode) wfNode;
+ Assert.assertNotNull(workflowOutputNode.getInPort());
}
}
[43/50] [abbrv] airavata git commit: Renamed simple-workflow module
to workflow and created a new workflow-core module which will keep all the
core code
Posted by sh...@apache.org.
http://git-wip-us.apache.org/repos/asf/airavata/blob/509f2037/modules/workflow/workflow-core/src/main/java/org/apache/airavata/workflow/core/parser/AiravataWorkflowParser.java
----------------------------------------------------------------------
diff --git a/modules/workflow/workflow-core/src/main/java/org/apache/airavata/workflow/core/parser/AiravataWorkflowParser.java b/modules/workflow/workflow-core/src/main/java/org/apache/airavata/workflow/core/parser/AiravataWorkflowParser.java
new file mode 100644
index 0000000..1e1a5c5
--- /dev/null
+++ b/modules/workflow/workflow-core/src/main/java/org/apache/airavata/workflow/core/parser/AiravataWorkflowParser.java
@@ -0,0 +1,291 @@
+/*
+ *
+ * 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.workflow.core.parser;
+
+import org.airavata.appcatalog.cpi.AppCatalogException;
+import org.airavata.appcatalog.cpi.WorkflowCatalog;
+import org.apache.aiaravata.application.catalog.data.impl.AppCatalogFactory;
+import org.apache.airavata.model.appcatalog.appinterface.InputDataObjectType;
+import org.apache.airavata.model.appcatalog.appinterface.OutputDataObjectType;
+import org.apache.airavata.model.workspace.experiment.Experiment;
+import org.apache.airavata.persistance.registry.jpa.impl.RegistryFactory;
+import org.apache.airavata.registry.cpi.Registry;
+import org.apache.airavata.registry.cpi.RegistryException;
+import org.apache.airavata.registry.cpi.RegistryModelType;
+import org.apache.airavata.workflow.core.WorkflowParser;
+import org.apache.airavata.workflow.core.dag.edge.DirectedEdge;
+import org.apache.airavata.workflow.core.dag.edge.Edge;
+import org.apache.airavata.workflow.core.dag.nodes.ApplicationNode;
+import org.apache.airavata.workflow.core.dag.nodes.ApplicationNodeImpl;
+import org.apache.airavata.workflow.core.dag.nodes.WorkflowInputNode;
+import org.apache.airavata.workflow.core.dag.nodes.WorkflowInputNodeImpl;
+import org.apache.airavata.workflow.core.dag.nodes.WorkflowNode;
+import org.apache.airavata.workflow.core.dag.nodes.WorkflowOutputNode;
+import org.apache.airavata.workflow.core.dag.nodes.WorkflowOutputNodeImpl;
+import org.apache.airavata.workflow.core.dag.port.InPort;
+import org.apache.airavata.workflow.core.dag.port.InputPortIml;
+import org.apache.airavata.workflow.core.dag.port.OutPort;
+import org.apache.airavata.workflow.core.dag.port.OutPortImpl;
+import org.apache.airavata.workflow.model.component.ComponentException;
+import org.apache.airavata.workflow.model.component.system.ConstantComponent;
+import org.apache.airavata.workflow.model.component.system.InputComponent;
+import org.apache.airavata.workflow.model.component.system.S3InputComponent;
+import org.apache.airavata.workflow.model.graph.DataEdge;
+import org.apache.airavata.workflow.model.graph.DataPort;
+import org.apache.airavata.workflow.model.graph.GraphException;
+import org.apache.airavata.workflow.model.graph.Node;
+import org.apache.airavata.workflow.model.graph.impl.NodeImpl;
+import org.apache.airavata.workflow.model.graph.system.OutputNode;
+import org.apache.airavata.workflow.model.graph.system.SystemDataPort;
+import org.apache.airavata.workflow.model.graph.ws.WSNode;
+import org.apache.airavata.workflow.model.graph.ws.WSPort;
+import org.apache.airavata.workflow.model.wf.Workflow;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+public class AiravataWorkflowParser implements WorkflowParser {
+
+ private String credentialToken ;
+
+ private Experiment experiment;
+ private Map<String, WorkflowNode> wfNodes = new HashMap<String, WorkflowNode>();
+
+
+ public AiravataWorkflowParser(String experimentId, String credentialToken) throws RegistryException {
+ this.experiment = getExperiment(experimentId);
+ this.credentialToken = credentialToken;
+ }
+
+ public AiravataWorkflowParser(Experiment experiment, String credentialToken) {
+ this.credentialToken = credentialToken;
+ this.experiment = experiment;
+ }
+
+ @Override
+ public List<WorkflowInputNode> parse() throws RegistryException, AppCatalogException,
+ ComponentException, GraphException {
+ return parseWorkflow(getWorkflowFromExperiment(experiment));
+ }
+
+ public List<WorkflowInputNode> parseWorkflow(Workflow workflow) {
+ List<Node> gNodes = getInputNodes(workflow);
+ List<WorkflowInputNode> wfInputNodes = new ArrayList<WorkflowInputNode>();
+ List<PortContainer> portContainers = new ArrayList<PortContainer>();
+ List<InputDataObjectType> experimentInputs = experiment.getExperimentInputs();
+ Map<String,InputDataObjectType> inputDataMap=new HashMap<String, InputDataObjectType>();
+ WorkflowInputNode wfInputNode = null;
+ for (InputDataObjectType dataObjectType : experimentInputs) {
+ inputDataMap.put(dataObjectType.getName(), dataObjectType);
+ }
+ for (Node gNode : gNodes) {
+ wfInputNode = new WorkflowInputNodeImpl(gNode.getID(), gNode.getName());
+ wfInputNode.setInputObject(inputDataMap.get(wfInputNode.getId()));
+ if (wfInputNode.getInputObject() == null) {
+ throw new RuntimeException("Workflow Input object is not set, workflow node id: " + wfInputNode.getId());
+ }
+ portContainers.addAll(processOutPorts(gNode, wfInputNode));
+ wfInputNodes.add(wfInputNode);
+ }
+
+ // while port container is not empty iterate graph and build the workflow DAG.
+ buildModel(portContainers);
+
+ return wfInputNodes;
+ }
+
+ private void buildModel(List<PortContainer> portContainerList) {
+ // end condition of recursive call.
+ if (portContainerList == null || portContainerList.isEmpty()) {
+ return ;
+ }
+ DataPort dataPort = null;
+ InPort inPort = null;
+ ApplicationNode wfApplicationNode = null;
+ WorkflowOutputNode wfOutputNode = null;
+ List<PortContainer> nextPortContainerList = new ArrayList<PortContainer>();
+ for (PortContainer portContainer : portContainerList) {
+ dataPort = portContainer.getDataPort();
+ inPort = portContainer.getInPort();
+ Node node = dataPort.getNode();
+ if (node instanceof WSNode) {
+ WSNode wsNode = (WSNode) node;
+ WorkflowNode wfNode = wfNodes.get(wsNode.getID());
+ if (wfNode == null) {
+ wfApplicationNode = createApplicationNode(wsNode);
+ wfNodes.put(wfApplicationNode.getId(), wfApplicationNode);
+ nextPortContainerList.addAll(processOutPorts(wsNode, wfApplicationNode));
+ } else if (wfNode instanceof ApplicationNode) {
+ wfApplicationNode = (ApplicationNode) wfNode;
+ } else {
+ throw new IllegalArgumentException("Only support for ApplicationNode implementation, but found other type for node implementation");
+ }
+ inPort.setNode(wfApplicationNode);
+ wfApplicationNode.addInPort(inPort);
+
+ }else if (node instanceof OutputNode) {
+ OutputNode oNode = (OutputNode) node;
+ wfOutputNode = createWorkflowOutputNode(oNode);
+ wfOutputNode.setInPort(inPort);
+ inPort.setNode(wfOutputNode);
+ wfNodes.put(wfOutputNode.getId(), wfOutputNode);
+ }
+ }
+ buildModel(nextPortContainerList);
+
+ }
+
+ private WorkflowOutputNode createWorkflowOutputNode(OutputNode oNode) {
+ WorkflowOutputNodeImpl workflowOutputNode = new WorkflowOutputNodeImpl(oNode.getID(), oNode.getName());
+ OutputDataObjectType outputDataObjectType = new OutputDataObjectType();
+ outputDataObjectType.setType(oNode.getParameterType());
+ workflowOutputNode.setOutputObject(outputDataObjectType);
+ return workflowOutputNode;
+ }
+
+ private ApplicationNode createApplicationNode(WSNode wsNode) {
+ ApplicationNode applicationNode = new ApplicationNodeImpl(wsNode.getID(),
+ wsNode.getComponent().getApplication().getName(),
+ wsNode.getComponent().getApplication().getApplicationId());
+ return applicationNode;
+ }
+
+ private List<PortContainer> processOutPorts(Node node, WorkflowNode wfNode) {
+ OutPort outPort ;
+ Edge edge;
+ InPort inPort = null;
+ List<PortContainer> portContainers = new ArrayList<PortContainer>();
+ for (DataPort dataPort : node.getOutputPorts()) {
+ outPort = createOutPort(dataPort);
+ for (DataEdge dataEdge : dataPort.getEdges()) {
+ edge = new DirectedEdge();
+ edge.setFromPort(outPort);
+ outPort.addEdge(edge);
+ inPort = createInPort(dataEdge.getToPort());
+ edge.setToPort(inPort);
+ inPort.addEdge(edge);
+ portContainers.add(new PortContainer(dataEdge.getToPort(), inPort));
+ }
+ outPort.setNode(wfNode);
+ if (wfNode instanceof WorkflowInputNode) {
+ WorkflowInputNode workflowInputNode = (WorkflowInputNode) wfNode;
+ workflowInputNode.setOutPort(outPort);
+ } else if (wfNode instanceof ApplicationNode) {
+ ApplicationNode applicationNode = ((ApplicationNode) wfNode);
+ applicationNode.addOutPort(outPort);
+ }
+ }
+ return portContainers;
+ }
+
+ private OutPort createOutPort(DataPort dataPort) {
+ OutPortImpl outPort = new OutPortImpl(dataPort.getID());
+ OutputDataObjectType outputDataObjectType = new OutputDataObjectType();
+ if (dataPort instanceof WSPort) {
+ WSPort wsPort = (WSPort) dataPort;
+ outputDataObjectType.setName(wsPort.getComponentPort().getName());
+ outputDataObjectType.setType(wsPort.getType());
+ }else if (dataPort instanceof SystemDataPort) {
+ SystemDataPort sysPort = (SystemDataPort) dataPort;
+ outputDataObjectType.setName(sysPort.getFromNode().getName());
+ outputDataObjectType.setType(sysPort.getType());
+ }
+
+ outPort.setOutputObject(outputDataObjectType);
+ return outPort;
+ }
+
+ private InPort createInPort(DataPort toPort) {
+ InPort inPort = new InputPortIml(toPort.getID());
+ InputDataObjectType inputDataObjectType = new InputDataObjectType();
+ if (toPort instanceof WSPort) {
+ WSPort wsPort = (WSPort) toPort;
+ inputDataObjectType.setName(wsPort.getName());
+ inputDataObjectType.setType(wsPort.getType());
+ inputDataObjectType.setApplicationArgument(wsPort.getComponentPort().getApplicationArgument());
+ inputDataObjectType.setIsRequired(!wsPort.getComponentPort().isOptional());
+ inputDataObjectType.setInputOrder(wsPort.getComponentPort().getInputOrder());
+
+ inPort.setDefaultValue(wsPort.getComponentPort().getDefaultValue());
+ }else if (toPort instanceof SystemDataPort) {
+ SystemDataPort sysPort = (SystemDataPort) toPort;
+ inputDataObjectType.setName(sysPort.getName());
+ inputDataObjectType.setType(sysPort.getType());
+ }
+ inPort.setInputObject(inputDataObjectType);
+ return inPort;
+ }
+
+ private InputDataObjectType getInputDataObject(DataPort dataPort) {
+ InputDataObjectType inputDataObject = new InputDataObjectType();
+ inputDataObject.setName(dataPort.getName());
+ if (dataPort instanceof WSPort) {
+ WSPort port = (WSPort) dataPort;
+ inputDataObject.setInputOrder(port.getComponentPort().getInputOrder());
+ inputDataObject.setApplicationArgument(port.getComponentPort().getApplicationArgument() == null ?
+ "" : port.getComponentPort().getApplicationArgument());
+ inputDataObject.setType(dataPort.getType());
+ }
+ return inputDataObject;
+ }
+
+ private OutputDataObjectType getOutputDataObject(InputDataObjectType inputObject) {
+ OutputDataObjectType outputDataObjectType = new OutputDataObjectType();
+ outputDataObjectType.setApplicationArgument(inputObject.getApplicationArgument());
+ outputDataObjectType.setName(inputObject.getName());
+ outputDataObjectType.setType(inputObject.getType());
+ outputDataObjectType.setValue(inputObject.getValue());
+ return outputDataObjectType;
+ }
+
+ private Experiment getExperiment(String experimentId) throws RegistryException {
+ Registry registry = RegistryFactory.getDefaultRegistry();
+ return (Experiment)registry.get(RegistryModelType.EXPERIMENT, experimentId);
+ }
+
+ private Workflow getWorkflowFromExperiment(Experiment experiment) throws RegistryException, AppCatalogException, GraphException, ComponentException {
+ WorkflowCatalog workflowCatalog = getWorkflowCatalog();
+ return new Workflow(workflowCatalog.getWorkflow(experiment.getApplicationId()).getGraph());
+ }
+
+ private WorkflowCatalog getWorkflowCatalog() throws AppCatalogException {
+ return AppCatalogFactory.getAppCatalog().getWorkflowCatalog();
+ }
+
+ private ArrayList<Node> getInputNodes(Workflow wf) {
+ ArrayList<Node> list = new ArrayList<Node>();
+ List<NodeImpl> nodes = wf.getGraph().getNodes();
+ for (Node node : nodes) {
+ String name = node.getComponent().getName();
+ if (InputComponent.NAME.equals(name) || ConstantComponent.NAME.equals(name) || S3InputComponent.NAME.equals(name)) {
+ list.add(node);
+ }
+ }
+ return list;
+ }
+
+ public Map<String, WorkflowNode> getWfNodes() {
+ return wfNodes;
+ }
+}
http://git-wip-us.apache.org/repos/asf/airavata/blob/509f2037/modules/workflow/workflow-core/src/main/java/org/apache/airavata/workflow/core/parser/PortContainer.java
----------------------------------------------------------------------
diff --git a/modules/workflow/workflow-core/src/main/java/org/apache/airavata/workflow/core/parser/PortContainer.java b/modules/workflow/workflow-core/src/main/java/org/apache/airavata/workflow/core/parser/PortContainer.java
new file mode 100644
index 0000000..536199c
--- /dev/null
+++ b/modules/workflow/workflow-core/src/main/java/org/apache/airavata/workflow/core/parser/PortContainer.java
@@ -0,0 +1,53 @@
+/*
+ *
+ * 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.workflow.core.parser;
+
+import org.apache.airavata.workflow.core.dag.port.InPort;
+import org.apache.airavata.workflow.model.graph.DataPort;
+
+
+public class PortContainer {
+ private DataPort dataPort;
+ private InPort inPort;
+
+
+ public PortContainer(DataPort dataPort, InPort inPort) {
+ this.dataPort = dataPort;
+ this.inPort = inPort;
+ }
+
+ public DataPort getDataPort() {
+ return dataPort;
+ }
+
+ public void setDataPort(DataPort dataPort) {
+ this.dataPort = dataPort;
+ }
+
+ public InPort getInPort() {
+ return inPort;
+ }
+
+ public void setInPort(InPort inPort) {
+ this.inPort = inPort;
+ }
+}
http://git-wip-us.apache.org/repos/asf/airavata/blob/509f2037/modules/workflow/workflow-core/src/test/java/org/apache/airavata/workflow/core/WorkflowDAGTest.java
----------------------------------------------------------------------
diff --git a/modules/workflow/workflow-core/src/test/java/org/apache/airavata/workflow/core/WorkflowDAGTest.java b/modules/workflow/workflow-core/src/test/java/org/apache/airavata/workflow/core/WorkflowDAGTest.java
new file mode 100644
index 0000000..09c1416
--- /dev/null
+++ b/modules/workflow/workflow-core/src/test/java/org/apache/airavata/workflow/core/WorkflowDAGTest.java
@@ -0,0 +1,46 @@
+/*
+ *
+ * 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.workflow.core;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+
+public class WorkflowDAGTest {
+
+ @Before
+ public void setUp() throws Exception {
+
+ }
+
+ @After
+ public void tearDown() throws Exception {
+
+ }
+
+ @Test
+ public void testWorkflowDAG() throws Exception {
+
+
+
+ }
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/airavata/blob/509f2037/modules/workflow/workflow-core/src/test/java/org/apache/airavata/workflow/core/parser/AiravataWorkflowParserTest.java
----------------------------------------------------------------------
diff --git a/modules/workflow/workflow-core/src/test/java/org/apache/airavata/workflow/core/parser/AiravataWorkflowParserTest.java b/modules/workflow/workflow-core/src/test/java/org/apache/airavata/workflow/core/parser/AiravataWorkflowParserTest.java
new file mode 100644
index 0000000..f7bffa2
--- /dev/null
+++ b/modules/workflow/workflow-core/src/test/java/org/apache/airavata/workflow/core/parser/AiravataWorkflowParserTest.java
@@ -0,0 +1,119 @@
+/*
+ *
+ * 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.workflow.core.parser;
+
+import org.apache.airavata.model.appcatalog.appinterface.DataType;
+import org.apache.airavata.model.appcatalog.appinterface.InputDataObjectType;
+import org.apache.airavata.model.workspace.experiment.Experiment;
+import org.apache.airavata.workflow.core.dag.nodes.ApplicationNode;
+import org.apache.airavata.workflow.core.dag.nodes.WorkflowInputNode;
+import org.apache.airavata.workflow.core.dag.nodes.WorkflowNode;
+import org.apache.airavata.workflow.core.dag.nodes.WorkflowOutputNode;
+import org.apache.airavata.workflow.model.wf.Workflow;
+import org.junit.After;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+
+import java.io.BufferedReader;
+import java.io.InputStreamReader;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+
+public class AiravataWorkflowParserTest {
+
+ @Before
+ public void setUp() throws Exception {
+
+ }
+
+ @After
+ public void tearDown() throws Exception {
+
+ }
+
+ @Test
+ public void testWorkflowParse() throws Exception {
+ Assert.assertNotNull("Test file (ComplexMathWorkflow.awf) is missing", getClass().getResource("/ComplexMathWorkflow.awf"));
+ InputStreamReader isr = new InputStreamReader(this.getClass().getResourceAsStream("/ComplexMathWorkflow.awf"));
+ BufferedReader br = new BufferedReader(isr);
+ StringBuffer sb = new StringBuffer();
+ String nextLine = br.readLine();
+ while (nextLine != null) {
+ sb.append(nextLine);
+ nextLine = br.readLine();
+ }
+ Workflow workflow = new Workflow(sb.toString());
+ Experiment experiment = new Experiment();
+ InputDataObjectType x = new InputDataObjectType();
+ x.setValue("6");
+ x.setType(DataType.STRING);
+ x.setName("x");
+
+ InputDataObjectType y = new InputDataObjectType();
+ y.setValue("8");
+ y.setType(DataType.STRING);
+ y.setName("y");
+
+ InputDataObjectType z = new InputDataObjectType();
+ z.setValue("10");
+ z.setType(DataType.STRING);
+ z.setName("y_2");
+
+ List<InputDataObjectType> inputs = new ArrayList<InputDataObjectType>();
+ inputs.add(x);
+ inputs.add(y);
+ inputs.add(z);
+ experiment.setExperimentInputs(inputs);
+ // create parser
+ AiravataWorkflowParser parser = new AiravataWorkflowParser(experiment, "testCredentialId");
+ List<WorkflowInputNode> workflowInputNodes = parser.parseWorkflow(workflow);
+ Assert.assertNotNull(workflowInputNodes);
+ Assert.assertEquals(3, workflowInputNodes.size());
+ for (WorkflowInputNode workflowInputNode : workflowInputNodes) {
+ Assert.assertNotNull(workflowInputNode.getOutPort());
+ Assert.assertNotNull(workflowInputNode.getInputObject());
+ }
+
+ Map<String, WorkflowNode> wfNodes = parser.getWfNodes();
+ for (String wfId : wfNodes.keySet()) {
+ WorkflowNode wfNode = wfNodes.get(wfId);
+ if (wfNode instanceof ApplicationNode) {
+ ApplicationNode node = (ApplicationNode) wfNode;
+ Assert.assertEquals(2, node.getInputPorts().size());
+ Assert.assertNotNull(node.getInputPorts().get(0).getInputObject());
+ Assert.assertNotNull(node.getInputPorts().get(1).getInputObject());
+ Assert.assertNotNull(node.getInputPorts().get(0).getEdge());
+ Assert.assertNotNull(node.getInputPorts().get(1).getEdge());
+
+ Assert.assertEquals(1, node.getOutputPorts().size());
+ Assert.assertEquals(1, node.getOutputPorts().get(0).getOutEdges().size());
+ Assert.assertNotNull(node.getOutputPorts().get(0).getOutEdges().get(0));
+ } else if (wfNode instanceof WorkflowOutputNode) {
+ WorkflowOutputNode workflowOutputNode = (WorkflowOutputNode) wfNode;
+ Assert.assertNotNull(workflowOutputNode.getInPort());
+ }
+ }
+
+ }
+}
\ No newline at end of file
[33/50] [abbrv] airavata git commit: Merge branch 'master' into
new-workflow-design
Posted by sh...@apache.org.
Merge branch 'master' into new-workflow-design
Project: http://git-wip-us.apache.org/repos/asf/airavata/repo
Commit: http://git-wip-us.apache.org/repos/asf/airavata/commit/29a0e4b6
Tree: http://git-wip-us.apache.org/repos/asf/airavata/tree/29a0e4b6
Diff: http://git-wip-us.apache.org/repos/asf/airavata/diff/29a0e4b6
Branch: refs/heads/master
Commit: 29a0e4b61ea68044a0c4ce97a8ca62e8b8d1231a
Parents: 0db33d2 c05d5e6
Author: shamrath <sh...@gmail.com>
Authored: Thu Mar 19 15:35:19 2015 -0400
Committer: shamrath <sh...@gmail.com>
Committed: Thu Mar 19 15:35:19 2015 -0400
----------------------------------------------------------------------
.../api/server/util/RegistryInitUtil.java | 43 +++++++++++++++-----
1 file changed, 32 insertions(+), 11 deletions(-)
----------------------------------------------------------------------
[22/50] [abbrv] airavata git commit: Fixed AIRAVATA-1611
Posted by sh...@apache.org.
Fixed AIRAVATA-1611
Project: http://git-wip-us.apache.org/repos/asf/airavata/repo
Commit: http://git-wip-us.apache.org/repos/asf/airavata/commit/8b2a6b06
Tree: http://git-wip-us.apache.org/repos/asf/airavata/tree/8b2a6b06
Diff: http://git-wip-us.apache.org/repos/asf/airavata/diff/8b2a6b06
Branch: refs/heads/master
Commit: 8b2a6b0625cef632cb75a7b8e04fb27582652112
Parents: d25441a
Author: shamrath <sh...@gmail.com>
Authored: Fri Feb 27 14:46:13 2015 -0500
Committer: shamrath <sh...@gmail.com>
Committed: Fri Feb 27 14:46:13 2015 -0500
----------------------------------------------------------------------
.../airavata/common/utils/ServerSettings.java | 15 +++++
.../main/resources/airavata-server.properties | 1 +
.../main/resources/airavata-server.properties | 1 +
.../server/OrchestratorServerHandler.java | 15 +----
.../engine/WorkflowEnactmentService.java | 64 ++++++++++++++++++++
.../workflow/engine/WorkflowFactoryImpl.java | 4 +-
6 files changed, 85 insertions(+), 15 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/airavata/blob/8b2a6b06/modules/commons/utils/src/main/java/org/apache/airavata/common/utils/ServerSettings.java
----------------------------------------------------------------------
diff --git a/modules/commons/utils/src/main/java/org/apache/airavata/common/utils/ServerSettings.java b/modules/commons/utils/src/main/java/org/apache/airavata/common/utils/ServerSettings.java
index b076e6a..5073949 100644
--- a/modules/commons/utils/src/main/java/org/apache/airavata/common/utils/ServerSettings.java
+++ b/modules/commons/utils/src/main/java/org/apache/airavata/common/utils/ServerSettings.java
@@ -61,6 +61,11 @@ public class ServerSettings extends ApplicationSettings {
public static final String GFAC_PASSIVE = "gfac.passive"; // by default this is desabled
+// Workflow Enactment Service component configuration.
+ private static final String ENACTMENT_THREAD_POOL_SIZE = "enactment.thread.pool.size";
+ private static final int DEFAULT_ENACTMENT_THREAD_POOL_SIZE = 10;
+
+
private static boolean stopAllThreads = false;
public static String getDefaultUser() throws ApplicationSettingsException {
@@ -187,4 +192,14 @@ public class ServerSettings extends ApplicationSettings {
}
return null;
}
+
+ public static int getEnactmentThreadPoolSize() {
+ String threadPoolSize = null;
+ try {
+ threadPoolSize = getSetting(ENACTMENT_THREAD_POOL_SIZE);
+ } catch (ApplicationSettingsException e) {
+ return DEFAULT_ENACTMENT_THREAD_POOL_SIZE;
+ }
+ return Integer.valueOf(threadPoolSize);
+ }
}
http://git-wip-us.apache.org/repos/asf/airavata/blob/8b2a6b06/modules/configuration/server/src/main/resources/airavata-server.properties
----------------------------------------------------------------------
diff --git a/modules/configuration/server/src/main/resources/airavata-server.properties b/modules/configuration/server/src/main/resources/airavata-server.properties
index e309901..12566ec 100644
--- a/modules/configuration/server/src/main/resources/airavata-server.properties
+++ b/modules/configuration/server/src/main/resources/airavata-server.properties
@@ -160,6 +160,7 @@ gfac.passive=false
#provenanceWriterThreadPoolSize=20
#gfac.embedded=true
#workflowserver=org.apache.airavata.api.server.WorkflowServer
+enactment.thread.pool.size=10
###########################################################################
http://git-wip-us.apache.org/repos/asf/airavata/blob/8b2a6b06/modules/credential-store-service/credential-store-webapp/src/main/resources/airavata-server.properties
----------------------------------------------------------------------
diff --git a/modules/credential-store-service/credential-store-webapp/src/main/resources/airavata-server.properties b/modules/credential-store-service/credential-store-webapp/src/main/resources/airavata-server.properties
index 2ecdeb6..3cd3cdb 100644
--- a/modules/credential-store-service/credential-store-webapp/src/main/resources/airavata-server.properties
+++ b/modules/credential-store-service/credential-store-webapp/src/main/resources/airavata-server.properties
@@ -144,6 +144,7 @@ trusted.cert.location=/Users/lahirugunathilake/Downloads/certificates
#provenanceWriterThreadPoolSize=20
#gfac.embedded=true
#workflowserver=org.apache.airavata.api.server.WorkflowServer
+enactment.thread.pool.size=10
###########################################################################
http://git-wip-us.apache.org/repos/asf/airavata/blob/8b2a6b06/modules/orchestrator/airavata-orchestrator-service/src/main/java/org/apache/airavata/orchestrator/server/OrchestratorServerHandler.java
----------------------------------------------------------------------
diff --git a/modules/orchestrator/airavata-orchestrator-service/src/main/java/org/apache/airavata/orchestrator/server/OrchestratorServerHandler.java b/modules/orchestrator/airavata-orchestrator-service/src/main/java/org/apache/airavata/orchestrator/server/OrchestratorServerHandler.java
index a4e105e..d168c26 100644
--- a/modules/orchestrator/airavata-orchestrator-service/src/main/java/org/apache/airavata/orchestrator/server/OrchestratorServerHandler.java
+++ b/modules/orchestrator/airavata-orchestrator-service/src/main/java/org/apache/airavata/orchestrator/server/OrchestratorServerHandler.java
@@ -66,6 +66,7 @@ import org.apache.airavata.registry.cpi.utils.Constants.FieldConstants.TaskDetai
import org.apache.airavata.registry.cpi.utils.Constants.FieldConstants.WorkflowNodeConstants;
import org.apache.airavata.orchestrator.util.DataModelUtils;
import org.apache.airavata.simple.workflow.engine.SimpleWorkflowInterpreter;
+import org.apache.airavata.simple.workflow.engine.WorkflowEnactmentService;
import org.apache.thrift.TBase;
import org.apache.thrift.TException;
import org.apache.zookeeper.*;
@@ -652,19 +653,9 @@ public class OrchestratorServerHandler implements OrchestratorService.Iface,
}
private void launchWorkflowExperiment(String experimentId, String airavataCredStoreToken) throws TException {
-// try {
-// WorkflowEngine workflowEngine = WorkflowEngineFactory.getWorkflowEngine();
-// workflowEngine.launchExperiment(experimentId, airavataCredStoreToken);
-// } catch (WorkflowEngineException e) {
-// log.errorId(experimentId, "Error while launching experiment.", e);
-// }
try {
- SimpleWorkflowInterpreter simpleWorkflowInterpreter = new SimpleWorkflowInterpreter(
- experimentId, airavataCredStoreToken,getGatewayName(), getRabbitMQProcessPublisher());
-
- Thread thread = new Thread(simpleWorkflowInterpreter);
- thread.start();
-// simpleWorkflowInterpreter.run();
+ WorkflowEnactmentService.getInstance().
+ submitWorkflow(experimentId, airavataCredStoreToken, getGatewayName(), getRabbitMQProcessPublisher());
} catch (RegistryException e) {
log.error("Error while launching workflow", e);
} catch (Exception e) {
http://git-wip-us.apache.org/repos/asf/airavata/blob/8b2a6b06/modules/simple-workflow/src/main/java/org/apache/airavata/simple/workflow/engine/WorkflowEnactmentService.java
----------------------------------------------------------------------
diff --git a/modules/simple-workflow/src/main/java/org/apache/airavata/simple/workflow/engine/WorkflowEnactmentService.java b/modules/simple-workflow/src/main/java/org/apache/airavata/simple/workflow/engine/WorkflowEnactmentService.java
new file mode 100644
index 0000000..ec5acfa
--- /dev/null
+++ b/modules/simple-workflow/src/main/java/org/apache/airavata/simple/workflow/engine/WorkflowEnactmentService.java
@@ -0,0 +1,64 @@
+/*
+ *
+ * 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.simple.workflow.engine;
+
+import org.apache.airavata.common.utils.ServerSettings;
+import org.apache.airavata.messaging.core.impl.RabbitMQProcessPublisher;
+import org.apache.airavata.registry.cpi.RegistryException;
+
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+
+public class WorkflowEnactmentService {
+
+ private static WorkflowEnactmentService workflowEnactmentService;
+ private ExecutorService executor;
+
+ private WorkflowEnactmentService () {
+ executor = Executors.newFixedThreadPool(getThreadPoolSize());
+ }
+
+ public static WorkflowEnactmentService getInstance(){
+ if (workflowEnactmentService == null) {
+ synchronized (WorkflowEnactmentService.class) {
+ if (workflowEnactmentService == null) {
+ workflowEnactmentService = new WorkflowEnactmentService();
+ }
+ }
+ }
+ return workflowEnactmentService;
+ }
+
+ public void submitWorkflow(String experimentId,
+ String credentialToken,
+ String gatewayName,
+ RabbitMQProcessPublisher publisher) throws RegistryException {
+
+ SimpleWorkflowInterpreter simpleWorkflowInterpreter = new SimpleWorkflowInterpreter(
+ experimentId, credentialToken,gatewayName, publisher);
+ executor.execute(simpleWorkflowInterpreter);
+ }
+
+ private int getThreadPoolSize() {
+ return ServerSettings.getEnactmentThreadPoolSize();
+ }
+}
http://git-wip-us.apache.org/repos/asf/airavata/blob/8b2a6b06/modules/simple-workflow/src/main/java/org/apache/airavata/simple/workflow/engine/WorkflowFactoryImpl.java
----------------------------------------------------------------------
diff --git a/modules/simple-workflow/src/main/java/org/apache/airavata/simple/workflow/engine/WorkflowFactoryImpl.java b/modules/simple-workflow/src/main/java/org/apache/airavata/simple/workflow/engine/WorkflowFactoryImpl.java
index b12260d..e8674f2 100644
--- a/modules/simple-workflow/src/main/java/org/apache/airavata/simple/workflow/engine/WorkflowFactoryImpl.java
+++ b/modules/simple-workflow/src/main/java/org/apache/airavata/simple/workflow/engine/WorkflowFactoryImpl.java
@@ -33,15 +33,13 @@ public class WorkflowFactoryImpl implements WorkflowFactory {
private WorkflowParser workflowParser;
- private static final String synch = "sync";
-
private WorkflowFactoryImpl(){
}
public static WorkflowFactoryImpl getInstance() {
if (workflowFactoryImpl == null) {
- synchronized (synch) {
+ synchronized (WorkflowFactory.class) {
if (workflowFactoryImpl == null) {
workflowFactoryImpl = new WorkflowFactoryImpl();
}
[24/50] [abbrv] airavata git commit: Added small code snippet to run
load test via XBaya.
Posted by sh...@apache.org.
Added small code snippet to run load test via XBaya.
Project: http://git-wip-us.apache.org/repos/asf/airavata/repo
Commit: http://git-wip-us.apache.org/repos/asf/airavata/commit/366ada03
Tree: http://git-wip-us.apache.org/repos/asf/airavata/tree/366ada03
Diff: http://git-wip-us.apache.org/repos/asf/airavata/diff/366ada03
Branch: refs/heads/master
Commit: 366ada03275079931d7c898cbbfe66c3409729d1
Parents: ad44956
Author: shamrath <sh...@gmail.com>
Authored: Mon Mar 2 16:05:26 2015 -0500
Committer: shamrath <sh...@gmail.com>
Committed: Mon Mar 2 16:05:26 2015 -0500
----------------------------------------------------------------------
.../experiment/WorkflowInterpreterLaunchWindow.java | 16 ++++++++++++++++
1 file changed, 16 insertions(+)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/airavata/blob/366ada03/modules/xbaya-gui/src/main/java/org/apache/airavata/xbaya/ui/experiment/WorkflowInterpreterLaunchWindow.java
----------------------------------------------------------------------
diff --git a/modules/xbaya-gui/src/main/java/org/apache/airavata/xbaya/ui/experiment/WorkflowInterpreterLaunchWindow.java b/modules/xbaya-gui/src/main/java/org/apache/airavata/xbaya/ui/experiment/WorkflowInterpreterLaunchWindow.java
index c542aa7..c0c6b45 100644
--- a/modules/xbaya-gui/src/main/java/org/apache/airavata/xbaya/ui/experiment/WorkflowInterpreterLaunchWindow.java
+++ b/modules/xbaya-gui/src/main/java/org/apache/airavata/xbaya/ui/experiment/WorkflowInterpreterLaunchWindow.java
@@ -353,6 +353,22 @@ public class WorkflowInterpreterLaunchWindow {
}else {
throw new RuntimeException("Resource scheduling failed, target computer resource host name is not defined");
}
+/*
+// code snippet for load test.
+ for (int i = 0; i < 20; i++) {
+ experiment.setName(instanceName + "_" + i);
+
+ experiment.setExperimentID(airavataClient.createExperiment(experiment));
+
+ try {
+ this.engine.getMonitor().subscribe(experiment.getExperimentID());
+ this.engine.getMonitor().fireStartMonitoring(workflow.getName());
+ } catch (MonitorException e) {
+ logger.error("Error while subscribing with experiment Id : " + experiment.getExperimentID(), e);
+ }
+ airavataClient.launchExperiment(experiment.getExperimentID(), "testToken");
+
+ }*/
experiment.setExperimentID(airavataClient.createExperiment(experiment));
[45/50] [abbrv] airavata git commit: Renamed simple-workflow module
to workflow and created a new workflow-core module which will keep all the
core code
Posted by sh...@apache.org.
http://git-wip-us.apache.org/repos/asf/airavata/blob/509f2037/modules/simple-workflow/src/test/resources/ComplexMathWorkflow.awf
----------------------------------------------------------------------
diff --git a/modules/simple-workflow/src/test/resources/ComplexMathWorkflow.awf b/modules/simple-workflow/src/test/resources/ComplexMathWorkflow.awf
deleted file mode 100644
index 4ffcad0..0000000
--- a/modules/simple-workflow/src/test/resources/ComplexMathWorkflow.awf
+++ /dev/null
@@ -1,465 +0,0 @@
-{
- "workflow": {
- "version": "0.11",
- "graph": {
- "version": "0.11",
- "id": "ComplexMathWorkflow",
- "name": "ComplexMathWorkflow",
- "description": "Sample workflow description",
- "node": [
- {
- "id": "Add",
- "name": "Add",
- "inputPort": [
- "Add_in_0",
- "Add_in_1"
- ],
- "outputPort": [
- "Add_out_0"
- ],
- "controlInPort": "Add_ctrl_in_0",
- "controlOutPort": [
- "Add_ctrl_out_0"
- ],
- "x": "247",
- "y": "106",
- "type": "ws",
- "Application": {
- "description": "Add two numbers",
- "name": "Add",
- "application": "Add_6c295199-f376-48af-b331-c83b2cf0fe9e",
- "Input": [
- {
- "description": "Add operation input_1",
- "name": "x",
- "defaultValue": "2",
- "dataType": "STRING",
- "inputOrder": 1
- },
- {
- "description": "Add operation input_2",
- "name": "y",
- "defaultValue": "3",
- "dataType": "STRING",
- "inputOrder": 2
- }
- ],
- "Output": [
- {
- "description": "Result",
- "name": "Result",
- "dataType": "STRING"
- }
- ]
- }
- },
- {
- "id": "Multiply",
- "name": "Multiply",
- "inputPort": [
- "Multiply_in_0",
- "Multiply_in_1"
- ],
- "outputPort": [
- "Multiply_out_0"
- ],
- "controlInPort": "Multiply_ctrl_in_0",
- "controlOutPort": [
- "Multiply_ctrl_out_0"
- ],
- "x": "287",
- "y": "232",
- "type": "ws",
- "Application": {
- "description": "Multiply two numbers",
- "name": "Multiply",
- "application": "Multiply_ccc3b4e6-8c5c-4b44-bdfa-b267337fce97",
- "Input": [
- {
- "description": "Multiply operation input_1",
- "name": "x",
- "defaultValue": "4",
- "dataType": "STRING",
- "inputOrder": 1
- },
- {
- "description": "Multiply operation input_2",
- "name": "y",
- "defaultValue": "5",
- "dataType": "STRING",
- "inputOrder": 2
- }
- ],
- "Output": [
- {
- "description": "Result",
- "name": "Result",
- "dataType": "STRING"
- }
- ]
- }
- },
- {
- "id": "Subtract",
- "name": "Subtract",
- "inputPort": [
- "Subtract_in_0",
- "Subtract_in_1"
- ],
- "outputPort": [
- "Subtract_out_0"
- ],
- "controlInPort": "Subtract_ctrl_in_0",
- "controlOutPort": [
- "Subtract_ctrl_out_0"
- ],
- "x": "426",
- "y": "136",
- "type": "ws",
- "Application": {
- "description": "Subtract two numbers",
- "name": "Subtract",
- "application": "Subtract_f1b296ad-b3bd-4a1b-82bc-407725bbdb96",
- "Input": [
- {
- "description": "Subtract operation input_1",
- "name": "x",
- "defaultValue": "6",
- "dataType": "STRING",
- "inputOrder": 1
- },
- {
- "description": "Subtract operation input_2",
- "name": "y",
- "defaultValue": "7",
- "dataType": "STRING",
- "inputOrder": 2
- }
- ],
- "Output": [
- {
- "description": "Result",
- "name": "Result",
- "dataType": "STRING"
- }
- ]
- }
- },
- {
- "id": "Add_2",
- "name": "Add",
- "inputPort": [
- "Add_2_in_0",
- "Add_2_in_1"
- ],
- "outputPort": [
- "Add_2_out_0"
- ],
- "controlInPort": "Add_2_ctrl_in_0",
- "controlOutPort": [
- "Add_2_ctrl_out_0"
- ],
- "x": "475",
- "y": "302",
- "type": "ws",
- "Application": {
- "description": "Add two numbers",
- "name": "Add",
- "application": "Add_6c295199-f376-48af-b331-c83b2cf0fe9e",
- "Input": [
- {
- "description": "Add operation input_1",
- "name": "x",
- "defaultValue": "2",
- "dataType": "STRING",
- "inputOrder": 1
- },
- {
- "description": "Add operation input_2",
- "name": "y",
- "defaultValue": "3",
- "dataType": "STRING",
- "inputOrder": 2
- }
- ],
- "Output": [
- {
- "description": "Result",
- "name": "Result",
- "dataType": "STRING"
- }
- ]
- }
- },
- {
- "id": "x",
- "name": "x",
- "outputPort": [
- "Input_out_2"
- ],
- "x": "97",
- "y": "88",
- "config": {
- "description": "Add operation input_1",
- "dataType": "STRING",
- "value": "2",
- "visibility": true
- },
- "type": "input"
- },
- {
- "id": "y",
- "name": "y",
- "outputPort": [
- "Input_out_3"
- ],
- "x": "97",
- "y": "194",
- "config": {
- "description": "Add operation input_2",
- "dataType": "STRING",
- "value": "3",
- "visibility": true
- },
- "type": "input"
- },
- {
- "id": "y_2",
- "name": "y",
- "outputPort": [
- "Input_out_4"
- ],
- "x": "105",
- "y": "311",
- "config": {
- "description": "Multiply operation input_2",
- "dataType": "STRING",
- "value": "5",
- "visibility": true
- },
- "type": "input"
- },
- {
- "id": "Result",
- "name": "Result",
- "inputPort": [
- "Output_in_2"
- ],
- "x": "729",
- "y": "248",
- "config": {
- "description": "Result",
- "dataType": "STRING"
- },
- "type": "output"
- }
- ],
- "port": [
- {
- "id": "Add_in_0",
- "name": "x",
- "node": "Add",
- "type": "ws",
- "dataType": "STRING"
- },
- {
- "id": "Add_in_1",
- "name": "y",
- "node": "Add",
- "type": "ws",
- "dataType": "STRING"
- },
- {
- "id": "Add_out_0",
- "name": "Result",
- "node": "Add",
- "type": "ws",
- "dataType": "STRING"
- },
- {
- "id": "Add_ctrl_in_0",
- "name": "control",
- "node": "Add",
- "type": "control"
- },
- {
- "id": "Add_ctrl_out_0",
- "name": "control",
- "node": "Add",
- "type": "control"
- },
- {
- "id": "Multiply_in_0",
- "name": "x",
- "node": "Multiply",
- "type": "ws",
- "dataType": "STRING"
- },
- {
- "id": "Multiply_in_1",
- "name": "y",
- "node": "Multiply",
- "type": "ws",
- "dataType": "STRING"
- },
- {
- "id": "Multiply_out_0",
- "name": "Result",
- "node": "Multiply",
- "type": "ws",
- "dataType": "STRING"
- },
- {
- "id": "Multiply_ctrl_in_0",
- "name": "control",
- "node": "Multiply",
- "type": "control"
- },
- {
- "id": "Multiply_ctrl_out_0",
- "name": "control",
- "node": "Multiply",
- "type": "control"
- },
- {
- "id": "Subtract_in_0",
- "name": "x",
- "node": "Subtract",
- "type": "ws",
- "dataType": "STRING"
- },
- {
- "id": "Subtract_in_1",
- "name": "y",
- "node": "Subtract",
- "type": "ws",
- "dataType": "STRING"
- },
- {
- "id": "Subtract_out_0",
- "name": "Result",
- "node": "Subtract",
- "type": "ws",
- "dataType": "STRING"
- },
- {
- "id": "Subtract_ctrl_in_0",
- "name": "control",
- "node": "Subtract",
- "type": "control"
- },
- {
- "id": "Subtract_ctrl_out_0",
- "name": "control",
- "node": "Subtract",
- "type": "control"
- },
- {
- "id": "Add_2_in_0",
- "name": "x",
- "node": "Add_2",
- "type": "ws",
- "dataType": "STRING"
- },
- {
- "id": "Add_2_in_1",
- "name": "y",
- "node": "Add_2",
- "type": "ws",
- "dataType": "STRING"
- },
- {
- "id": "Add_2_out_0",
- "name": "Result",
- "node": "Add_2",
- "type": "ws",
- "dataType": "STRING"
- },
- {
- "id": "Add_2_ctrl_in_0",
- "name": "control",
- "node": "Add_2",
- "type": "control"
- },
- {
- "id": "Add_2_ctrl_out_0",
- "name": "control",
- "node": "Add_2",
- "type": "control"
- },
- {
- "id": "Input_out_2",
- "name": "Parameter",
- "node": "x",
- "type": "systemData"
- },
- {
- "id": "Input_out_3",
- "name": "Parameter",
- "node": "y",
- "type": "systemData"
- },
- {
- "id": "Input_out_4",
- "name": "Parameter",
- "node": "y_2",
- "type": "systemData"
- },
- {
- "id": "Output_in_2",
- "name": "Parameter",
- "node": "Result",
- "type": "systemData"
- }
- ],
- "edge": [
- {
- "fromPort": "Input_out_2",
- "toPort": "Add_in_0",
- "type": "data"
- },
- {
- "fromPort": "Input_out_3",
- "toPort": "Add_in_1",
- "type": "data"
- },
- {
- "fromPort": "Input_out_3",
- "toPort": "Multiply_in_0",
- "type": "data"
- },
- {
- "fromPort": "Input_out_4",
- "toPort": "Multiply_in_1",
- "type": "data"
- },
- {
- "fromPort": "Input_out_4",
- "toPort": "Add_2_in_1",
- "type": "data"
- },
- {
- "fromPort": "Add_out_0",
- "toPort": "Subtract_in_0",
- "type": "data"
- },
- {
- "fromPort": "Multiply_out_0",
- "toPort": "Subtract_in_1",
- "type": "data"
- },
- {
- "fromPort": "Subtract_out_0",
- "toPort": "Add_2_in_0",
- "type": "data"
- },
- {
- "fromPort": "Add_2_out_0",
- "toPort": "Output_in_2",
- "type": "data"
- }
- ]
- },
- "image": "iVBORw0KGgoAAAANSUhEUgAAA0cAAAFwCAYAAABzWgC/AACAAElEQVR42uydeXiV9Zn+c80f06lO\r\ntS6t1g2r7YztVGxnulg70KHa/lqnLd0UtLSWtjJqXVJFkVZkRyMURFBREFBAkLCFPWQBw74EspKE\r\n7PtKNpaQ855znt93fd/v+573hCBbQu5c1+c6yCL2cELPJ/fz3E9MRUUJAQAAAAAAAEBfJwZPAgAA\r\nAAAAAABAjgAAAAAAAAAAcgQAAAAAAAAAkCMAAAAAAAAAgBwBAAAAAAAAAOQIAAAAAAAAACBHAAAA\r\nAAAAAAA5AgAAAAAAAADIEQAAAAAAAABAjgAAAAAAAAAAcgQAAAAAAAAAkCMAAAAAAAAAgBwBAAAA\r\nAAAAAOQIAAAAAAAAACBHAAAAAAAAAAA5AgAAAAAAAADIEQAAAAAAAABAjgAAAAAAAAAAcgQAAAAA\r\nAAAAkCMAAAAAAAAAgBwBAAAAAAAAAOQIAAAAAAAAACBHAAAAAAAAAAA5AgAAAAAAAADIEQAAAAAA\r\nAABAjgAAAAAAAAAAcgQAAAAAAAAAkCMAAAAAAAAAgBwBAAAAAAAAAOQIAAAAAAAAACBHAAAAAAAA\r\nAAA5AgAAAAAAAADIEQAAAAAAAABAjgAAAAAAAAAAcgQAAAAAAAAAkCMAAAAAAAAAgBwBAAAAAAAA\r\nAOQIAAAAAAAAACBHAAAAAAAAAAA5AgAAAAAAAADIEQAAAAAAAABAjgAAAAAAAAAAcgQAAAAAAAAA\r\nkCMAAAAAAAAAgBwBAAAAAAAAAOQIAAAAAAAAACBHAAAAAAAAAAA5AgAAAAAAAADIEQAAAAAAAABA\r\njgAAAAAAAAAAcgQAAAAAAAAAkCMAAAAAAAAAgBwBAAAAAAAAAOQIAAAAAAAAACBHAAAAAAAAAAA5\r\nAgAAAAAAAADIEQAAAAAAAAB
AjgAAAAAAAAAAcgQAAAAAAAAAkCMAAAAAAAAAgBwBAAAAAAAAAOQI\r\nAAAAAAAAACBHAAAAAAAAAAA5AgAAAAAAAADIEQAAAAAAAABAjgAAAAAAAAAAcgQAAAAAAAAAkCMA\r\nAAAAAAAAgBwBAAAAAAAAAOQIAAAAAAAAACBHAAAAAAAAAAA5AgAAAAAAAADIEQAAAAAAAABAjgAA\r\nAAAAAAAAcgQAAAAAAAAAkCMAAAAAAAAAgBwBAAAAAAAAAOQIAAAAAAAAACBHAAAAAAAAAAA5AgAA\r\nAAAAAADIEQAAAAAAAABAjgAAAAAAAAAAcgQAAAAAAAAAkCMAAAAAAAAAgBwBAAAAAAAAAOQITwQA\r\nAAAAAAAAcoQnAQAAAAAAAAAgRz2KkpIiWrlqFU2dOpXGjx9P48aNA+ed8TT5lTha8MECys4+hNch\r\nAAAAAADkCFx0KivEm/Wk5BRqammjU1aYQdTBOBkgOqE41knUfkrSxmjtIGphNJ8kOspoYjSeIKo/\r\nTlR3jKiWUdNOVK2oaiOqUJS3EpW1EJUySpqJihVFR4mONBHlN0oON0hyGTn1RNmMLEZmHVFGLdEh\r\nxsEaonTFAca+aqK9VUR7Kol2VUh2MnaUE21npDE+LiPaxiklSuWUEKUwkhlJxURbiogSGZsLiTYe\r\nYbDH9exxXYEkIZ9oDSePaDVj1WGilYwVjPhcouU5RB8xlmUTLWV8yFiSRbQoU/JBBtHCQ2Gat7uN\r\nXl++gyZOmkSZmQfxWgQAAAAAgByBi5cYFdOUKVMoOzuXrBBRZ1DC5Yhz0pJidFzR3inhciTEqEOJ\r\n0QkpRg3HlRwpuCDZcsSo9JOjFilFhUqMhBwp8hqlGAk5apBylO2RI44QIyZF+6oMOWLsrjTkqELK\r\nkRAkJUZbFS4xKlZixNik5GiDQsvR2gJHjFxylCvl6CNDjj7MkrjkiLFQCBLR
Asbs9blCUJEgAQAA\r\nAABAjsBFYtWqVbR9+w4KhknIUSDkyJFOjjjHO2VyxGntIjVqMJKjOpUc1RhiJOSoVcqRNzUqVIJU\r\n4E2OlCBpMcqqk3LEOWgkR1yO9htiZMtRpSc5KpPJEWermRoVe1IjLUeFUozWF0jW5ksSzOQozxEj\r\nOzXKkanRUpUaLc6UfKCSo/cNOZrPmLNsDS1evAivSwAAAAAAyBG4GEybNo2aW9ooGCJXcsQxx+r8\r\nUiMtR00+yVG9So1qjNE6MzUqNVIjMU5njNRxtCDlNbrH6iJG6mqdcToxUlcl0WN1Wo52qeRohxqr\r\n86ZGOjna4pccFTpjdZy1BW4xWukdqVOYcqTH6har9Oh9JUdCjA4SvcfZ1UBxca/idQkAAAAAADkC\r\nFwNevhAMhYUYmcmRnRpZUozMfSOeGrWe8iRHSo70zhFHpEbH3ON0nLJWiU6OzLE6nRwVqJG6PG9q\r\nVO+kRnrfiAsST43M5GivSo30WJ133+hjc9+oVKZGEclRodo5KnSP1CXkOztHOjXScrRCJUfL1Ugd\r\nFyRTjDhajBYqOeJwOZqbHhajdWvXrqGDB/fj9QkAAAAAADkCFxL+ZjykR+r0vpGWI3PfqNOdHLWq\r\nfSN758gsY1CpUZf7Rq3u5EiP1R056k6NvPtGdnJU5+wb6bE6Lkb7FHsqo+8bmSN15lhdUnHkzpHf\r\nvpGWo9V5HjnKdZIjvXO0NNvZN1pslDF4R+p4ejQvncSfx/vvLxRs25aC1ygAAAAAAOQIXEg58o7U\r\neeVIN9Ud02J0ykmOTjdSV22M1FUqMSr3JEdmGYM3NYpoqquLTI7Suxqpq+jevlGKT0udLmPY6Nk3\r\nSjD2jXgRg7eMYbmnpY5j7xtl+MiRGqvzyhEHCRIAAAAAAOQIXEg5ilLG0OHTVKflyC818pYx+CZH\r\nZhmDuW/UHFnG0GVyZ
LTUaTnar9rquBh5m+p2Vjhjdbqpjld5R63w7iI5Ek11nrG6iApvhU6NXMlR\r\npnusbr7CT474iB1epwAAAAAAkCNwgZOjgLeMQctRp3PbyFXG4JWj40565B2rqzBTI58yBrvG+2jk\r\nvpFdxlDnX+GdboiReePILznaHq2ModhTxlDorvFeX+C5ceQtY8j1lDFkOyN1HxpFDNHKGLgYzfWR\r\noyVL0F4HAAAAAAA5AhctOTJTI/v4q09T3dFoNd7e+0ZtUe4bNfvvGxV4bhz5HX/dtCKOvnnPYPqf\r\nX0+gj0p4GUMHvfH3EfSle2Lp/Vx3jbfffSMzNepOjbedGuU7qVG0kTpz30gLki5jiEiNDqrU6KC/\r\nHHHwOgUAAAAAgByBCyRHrpE6T4V3xL5Rh3HjyHMA1hQjv32jCiVG3jIGvnPE06Mjxr7RYWPfyHvf\r\nSJYxNNAz34uhmJgY+vKj8bR4SZz49vdfTXe11O30aarbZpYxlMqROlHjXeROjuwKb71vVODeN/I2\r\n1ZllDObOkd43MlMjs4zhvYO6rQ5yBAAAAAAAOQIXX448I3UdxkidlqP2TqeMwW+krt4zUldjpEZ+\r\nTXUcc6SuwHvfqFHuGkUkR7qpLieFvhkjBUlwz0za7Llv5B2pi9ZUl+zdN/I5/trdprplxgFYs8Lb\r\n21S30JCjaGN1kCMAAAAAAMgRuEhypMsYzOOvuoxBp0bNPqlRgxIkXcRQ41PGUO5XxnBUHX9VaDHy\r\nLWOoiyxjWPbqMFuOntvcbo/T+ZYxGPeNeHqkpcguY4iyb6TH6vhI3VqVGukyhi5Toyx3jbdoqvMZ\r\nq9OpEeQIAAAAAAByBHqAHPnVeJ/03DcyK7wj5Oh45I0jLUhd3TfyjtR5kyO7jMF7/JXLUd4e+okr\r\nOYqj9V0kR3qszkyN7JE6n32jTZ7kaK1uqos2Umc21fnsG5lNdX4jde
9CjgAAAAAAIEegB+0cmalR\r\np3vfyNVUd9Jz4+iEM1ZX4yliqPRrqmt2N9UVHo28cZTjc9+Ip0Z8rO5gTQP97cdcigbRPzan0UNK\r\nkL4/fo+rqY6L0Q6f1Ci1tIsyBm9T3REjNcp3p0beMgZvU52u8XaN1Pk01XHePdDL5agonxr/+Adq\r\nvPIKqmFUsG/z78PnGQAAAAAA5KjXyFFEGUOU46/2jaOTEnPnKCI18ghSxPFXU5CMnaP80xx/1ftG\r\nCXNHCBkavrBI3DjalrzATpDGb+9wUqMK/+Ovuowhxa+MocgoYzjiHH9dG23fyDNWp5vqPjR2jj7w\r\npEau+0aXSHLUOPwRamLPfw2jnFHEyOeChM8zAAAAAADIUa+RI+99I2PfqKsab+9InRYkLUaupjqf\r\nGu+ioz5lDE3OOJ2rqc5z/PWgceNon7pxJO4bVUW/b2QnR6WRyVFEhbfPfSPvvtEqnxtHthjp+0ZG\r\nU11XydElIUdXXkG1SowKGRmMdJ4g4fMMAAAAAABy1FvkKBjylDEYyZEoYzBSo5YoZQz1RhlDraeM\r\noULVeJcbLXXFhhzpkTqzjOGwt4zBK0c1/LaRPP6qD8D6lTHYyZFiW5kzVqfH6XxH6vxuHBVEjtV5\r\n7xvxkbplKjXSyZE+/hqtjEHLUW8vZOCjdDox4mK0n7Hriito1apVNHXqVBo/frz43wfOL/x5njo1\r\njpYvW0jZ2Yfw9xwAAAAAOQJnIkehMIlDsN4bR6KM4ZRTxmDuG3mPvzZEuXHEpeh0x1/1Adh8JUhm\r\ncpQTRYx0amTLUXXXyVGaJzVK9e4bFUdPjswbR3Zq5JGj+FynjCEiOcpy3zgyR+rMprpev3P0xz/Y\r\niREXo52Mxd/5DqWkpFBbWxuFw+xFho/z/sGfZ/5879ixg6ZMnkSZmQfxdx0AAAAAOQLdlaNwkL1x\r\nDTJ7CbZQ2Dr
KYJZiNVI4UM+oYzALCdRSuLOaUUXhUxWMMkYpo4RCHUUU7ihkHKHQyXwKn8xjHGbk\r\nUuhEDoVPZDOyKHQ8g8LHD7HHdAod28/Yx9hLofbdjF2MnRRq284et1O4PY19exuFWrcyUhkpjCTG\r\nFgq1bKZg80bGBgo1r6fg0bWMBPbtBPa4mrGKQkdXUrApnrGcsYxCTUsp2PghYzEFGxZRsP59xkLG\r\nArLq57PH9xjzyKp7l4J17zDmULD2LbJqZ7PHWYw3yKp5nYI1M8iqns6YpphKVlUc41XGK2RVTmZM\r\nYkxkjCerYizjZcYYssr/zvibIFD2ImMUWWUvUKB0JOM5skqf7d1yVJhHBUyQDlx5hUiMlt5zD+Uc\r\nOgRbuYgfubm54jWFBAkAAACAHIFuyhEF25kQMTmyWhjNTIYcOSIuR501SowqGVqMFB0l7LGYCZKU\r\no3BHARMkKUeB9hxqazxMTXWM2lxFjkE2I0tSk8nIUBwUNFans0dG9QH27f3skbOPfXsve+Tsocaq\r\n3dTEaKzaxR53Chord1BT5Xb2mMYe08RjY+XHjG2Siq2KVEaKpDxJsYWRaLCZsYkayzayx/XUWhFP\r\np6qYLFX/wxajYDUTo8op7NtMjKq0GE2kQMU49jhOyFGg/CVbjrgYWeWOGFllz7HHvzI5+uslU+XN\r\nR+l4coGPi/+RnJhAixcvwt93AAAAAOQIdE+O/FMj4slRZ61IjrQcERekU+UyNeJi1FHskxrlUXN9\r\nPhUXFVJRUdElSAE1lSUwEXqNCdJrPqnRBCZEPDUa56RGruSIyVHZKCZJz7NHJkcqNQqUxF4ycjRt\r\n2jQx2oWPi//R2tJIcXGv4u87AAAAAHIEujVWZ7UyoozUddYwIWJidEqnRhVKjsqijtRxMbo0pchN\r\nU9lqJUZTJOZInUeOAkZqpMfpuBjpkTqeHAVKnrlk5IiXAmDH
qOfsIPHX1dq1a+jgwf34ew8AAACA\r\nHIGukyM5TkdMjLgchQMNESN1ZO8albvG6cL2OB2DyZF1LK9HJUZ7E5fR9Lg4mj57PqWmn1tpKy4q\r\noFOVM2RqJORIp0bjFGOZFOnk6CUnNSrXqdHz9q6RVRrLuHTkSLyu8NFjPszX1bZtKfi7DwAAAIAc\r\ngahvYnVqpHaNyGrwjNOpfSMtRx2yiIGP1IWM1Ch08jC1NXVfQDJTl1Hs4Lvt460xMXfQffcNp/lp\r\nuedEXjI3xMl/79330R3scUzCdnrn8cH0+OzEcyZILeVLjZG6iRFFDHrXaMCJWyip5iElRmZy9KzY\r\nNeIjdYGSpyFHPfCjLGUOjRgxgmZuKjqrn9NT5IiDBAkAAACAHIEukiMuRxQlNbIb6jqNXSNRwuCM\r\n1IXVSF1TXffkKH3FGFuIxryzjBJWLKK4MY8LiYldkX5OxCVhDBevUbTX/r5MmnhHDN0xKuGcyVFj\r\n2WoKulKj8VKOKse5WupiOtn/1mMxNPDozZRUOUSlRs+qIoZYMVIXQHJ0QT6K4mPVa28Y7Wk//c9P\r\nnzlY/PxBM9PP6uf0JDniI3b4+w8AAACAHAHfnSNHjOwSBiFGvMLb3DcyU6PIXaPQidxuytEuGnWH\r\nFKPZiZ6UKD+XcvPPjbgkTryPYu6YSLnncWyvsTRBpka8pa5iQmR9d8VLFCgbLcQopo3RxKiPoQGV\r\nN1Fy2YN2EQMfqQuUPAU5Ov85EI22k8oYGrEk77S/Im/BMPFzB3chPt35OT1JjpYsQXsdAAAAADkC\r\nUeWIj9SFA2qkLlDn3DU6VekpYTDlqMhOjWR9d/fkKDdRjrvdN+Y0CU5mIo0Z6ozd3TF0DCVmOinQ\r\nbPZjw+MW0fwxg50UalGa+PENcUOdX8cYGrfB/jVDp2+wf4/8vQkUe59+s3wfjRrzON199+OUmNtd\r\nOVpj3
DXScuQuYgiU/80RowZGFaOCURRDA4tuoqTiX4uROsjR+f9o3jNT/Fn3H9Rf/ZmPZrrk/uio\r\nTqPRgwfJnzc4lkYMiokQn+78nJ4sR731dQUAAABAjsAF2DlSYiQa6szkSI7U2fXd3tToZIGrvpvf\r\nNuqOHGVumCjeSE7ckNnFz0ujWPHmdSgt2pBGaYnzaahIm2IpLV/KUZyWGiYz81csolH3yR/fxX+P\r\nXRto4vA72D8PZz+2gjakpsuxuruZLNlSlkaPq99jfmIapa6YTfcpSVqReaZy5KRGooShXDfUyZY6\r\nnRiZYhRzhJHLyIqhAZk3UHLBLyBH5/WjnZYMU0LEXsOxSp7j9jQbZpRFw9T3D4qdSfFzRtuSbYtP\r\nd34O5AgAAAAAkKPeLEcNrvpue9fIVd/d9Uhd6EQOk6O80ydHqighrgs50gI1JiHT+HX6+5TocBm6\r\nb6K9U5QYxxOku22xiRyrk3J0t5Kj6L/H3ZRwJnKkR+oibhu9ZNd3CzGqZpQbYpQjxSjmAJOjQzdQ\r\nUr6UoyFDhtBDDz1Ew4YNo9///vf0ta/9B33729+ie+/9AQ0e/HN65JHf01//+gxNmjSB3n33bVq3\r\nbjUdOrQfcnSaD6ssQfx5D1uQ5xqFixm2hDrUz2lIUyUeg+KoQX1f1pzBLvHpzs+BHAEAAAAActRr\r\nx+rMw6+GHJ3ya6gzU6MCu4iBp0bdlaPMBCklo7ooXshUkrIs3fm+/LR33HLERWeiMyK3gctQzH22\r\n2GyYeLeQo8wu5egOWrQr3xj5+wRyVOndNXKSo4Co7x7tJEbFbjEakHkjJRX8kgIlT1Kg+C/iz2Pe\r\nvLlMet6hOXPepjffnE2bNq2n+PhltHDhezRz5nQmRePpmWeeot/9bhj96Ef3Uf/+/enqq6+myy+/\r\nnO666y4aOnQIvfLKZEpOToQcGR9pcYNUwtOfBg0aRP
3t3aP+lFBmuYoVYmImGOLj3ifqzs+BHAEA\r\nAAAActRrk6NG39TIfdvIqO8+qW8bFbjEKHwim8nR4dMKRf6ud8QeUMzgOENcvAI1Ro3e5XrExSNH\r\nxt7SJ5MjLmlOcrRi4mDXv6N7cjSRAvZtI6ehzr5rVDYqIjEacPhGSi78tShisEqeEmIUKHnirN7E\r\nZmdn0Jo1K4UYDRnyIPXr14++8IUv0J///EdKTU3q23LUkS5H4QbHMumcwyRzpniMHSx3jwbFpck0\r\nackIlQrNJFlkZ9Gm0YNc4tOdnwM5AgAAAADkqLcmR0Z9t6uIQYzU+ZUw8OTIqe/mI3VhW47yuiUV\r\ny0apooXBYyghbS9lZqbTrtQEmh47nOK4/OQm0lD+4/eNoQ17Mylz7wa1UzRUlSVEl6MV3ZSjovxU\r\nGi4SgLtpVFwcPW4UM3RfjlZH1neXv6T2jeRIHb9rpMVoQP5NlFz0AAVK5V2jgGqp48mRVfKXc/4m\r\ndtu2ZIqNfZquvfZa+uUvf0HFxQV9Uo50ffecrA63M2XNsWu90zv46F28vT80KHYCTRjRP2KfqDs/\r\nB3IEAAAAAMhRb02OXKlRjXP0VRcxaDk6VezcNeooEEdfhRidzBHJUehEFjXVHu5mDXY+JUyPlQmS\r\ni/vsI7C5actUCYPijuG0yD4QGylHcudoMCXkGrJ0dxdyxEnfQGOGD6a777iDBo+aTYvihrv2lrol\r\nRz5HX2VqJEfquBwNLLyZkouHMBl6jr25flbdNpINdZYYqXuC8fh5exObn59Dt9xys3ge+bf7lhw1\r\n05xB7h0h56OB4lTT3OhNsrcuK94pWIgZNJpmjlb7RHMc8enOz4EcAQAAAABy1CuTI+/RV++uUZk4\r\n/Boy9o2cXSMnNQqdyDwDOdJ3jTJp165dtHfvXtqbnusrUZmZmYL883CnKD/X/Xu9MzzGczi2m3Lk\r\
nOfoaMMTIKnuBSdFIcfTVUodfeXJkeVKj8ylHnMqCXJpy59fog6/cQU2zXhf/3Lfa6s6gvKGjndqb\r\nm6njLH8O5AgAAAAAkKNeKEciOdIjdWZ9t19qxO8anThsy5FMjbKZIHE5yj1vB1fPPek0RlSBD6bH\r\nY2NpsEqpHn8n7QyOwK6igHH01azv5vtGWo6ssudlaiTkyEmNAkZqdD7lqHbDWrKuu47Y/0Ab/s/8\r\n+yFHl/4H5AgAAACAHIFuj9U5qZG7hKEsMjUy6rvNIobQ8UwKH8+go3W9SY6KaNeGRRQ3cQzFMjmK\r\nHTWRliWmn9GvbyxdKVKjgFHfHZEalY1UyZGSo5JYp4jBSI0CxY+dlzexPCHyipEpSOcjQYIcQY4A\r\nAAAAADnqdYwfP55CnbVOEUOnLmIot8WIN9TZJQwdniKGk1KOwieymCBlUGtjdq+So7OlpfQDo777\r\nJXdLXfkoJkbPM0EayXhOjNOZu0a8oU7sG5XI5OhEwRPn5U0sH6HzEyMN//HzkkhaLYxmIusohQPq\r\n0LDVoPbb5KFhcr3m3AUgIfG6k1Lu1Mbnu6Q8rBLL8IkM9vo7SKFj6YwDjP0Uat/LHvcwdrNv72Ts\r\norB43E6htjTGx4xtFGpNVSRTsGULhVoSGZsp2LyJQs0bGRvYt9exx7WMBAoeXcNYxVhJoaMrKNgU\r\nT6Gm5ezxIwo2LmMsZXxIwYbFjEWMDyhYv5A9chawb79Hwbp5jLns2++yxzmMtylY+xZZtbMZsyhY\r\n8wZZNa8LgjUzyKr+B2Ma+/Y09jiVrKo4xqsUZFhVUxiTRWuieW/LFHbIEQAAAAA5At1g6tQ4JjRH\r\njIa6KndLXYd7pM5MjcKqhIGnRnzfKHT8EAXaDlFxUWEfkaMC6ih/xTNSZ6ZGWo6ed/aNSp4RcmSV\r\nPu0Zqfs/KtjxPE2YMOGcv4lteWFkl3LEf/y8
JEfBVluO9KFh4s2InboVsUa93sxmRP26Y6+5U0Xs\r\n9XbEKAAx0sqT+rWXZaeWXI7CAi5H+yjMCLUzOWrfzb69i4nQDvbtHS4xCgopSnHEqHWLFKMWJkYt\r\nG5kUbRByFGpez2RIy9FqJkWrmQytZHA5Wi5hYhRqcsQo1LhYilHD+1KM6ucLLC5G9UyM6t5hIjSH\r\n/bOUI6v2TSZIHCZITI6CtTPZ4wxBsGa6lCMlRsFqLkfstVfJpWiSpELf2xpnC7soCIEcAQAAAJAj\r\n0D2WLl1MKUlr2ZtVuWsU+dV7o77bJzXib1D1V+7DTI5Cx9PpaF1Wn5CjptJ44/Crc9uI13dbriIG\r\nc9foGbuIwWyps4ofo4VzX6Fp06ZeMskRWS3u1CjQ4NltM15zne4xTinkfgUgh9Wem0wrw0LKndde\r\nyBSjY3vY426RGAkpssXISI3attpyFGpJYmxhYrSZPUo5CrXI1MgRozUuMQo1xYvEKCRSIyVGjUsk\r\ndmrE5Kh+geI9xjwmRDwxelcIUrD2bfb4lpKjWVKMamYy3KmRkxjJ1EjIEU+NuBhVTfIcIx7rGvOE\r\nHAEAAACQI9ANsrMPiTdOOZnb7dtG1FnuuW0k36CGvHeNDDkK2V+5TxdfueeCdOkmSAVKjJzRpYBo\r\nqBstUiNvS50eqdO7RnYRg7FrtGH5ODHiOHfu3HO/c5Sfc1F2jsJcjCwpRq6ROjs18runJVOjkM/r\r\nzrXjZr/uDtmpUUi99uyROpUayZG6ne7UqHWrS4zscbrWRCFGQTFKt54JkRYjJzUSI3VNeqTOSY24\r\nHIW0HGkxanifLCFFMjWyx+m4FInkSI/TvSlG6nhq5IzU8dRoujNSZ4zTucSIEdDjdKo1MVA+xh7z\r\nDJSNhhwBAAAAkCPQXTIzD9LkyZNoa8p6aqlnb0DFV+799o0KIlKjkLHvERZfuZc7H/wr94G2f
dTa\r\ncIiaajOoqUbD/rnmICOdGqsPUJNgv2KfYi9jDzVW7aYmRmPVLsZO9m3ODmqs3E5NjMbKNEFT5cfs\r\nkbONGiu2MlIVKYxkSXkSY4siUbGZsUlStpGxgbFesY4aS9cqEhhr2PetopayxXSqIk58hT5wutTI\r\n2DXS+0ZmanSi4Ckq2DmK3pvzinjzOnfuuxFvYHt1W50apyOrUTYidkoxooB3nK7cPU7XZVqpXnvH\r\n3a89R4yc1IjvGolxOi5Gbdt9xukYbXLXKNSaJEbq7NRI7RqFhCCtZULkjNOFhBwZu0bePSN7nM49\r\nUmep1IiP1FlCjpxdI9c4Xc1Me9eIj9MFq332jMQ43WRn1yhKamRVyNcl5AgAAACAHIEzTJAWL15E\r\ncXFx4o0UuDBMnDiRpk2b5psYcZYsWXTO/ox5gsRH6Pidoyeu+ux5vXPUr18xpSa3iD0jeUdLoosY\r\npByZY5ymjDu7Rjw1CvmM04lROqOEQYqRSo2MXSMxUqd2jcKiiMEsYXDvGpnjdGZqxMUopMfpVBGD\r\nlqNgo1nCoMbpzF0jOzVyj9PxXSO5Z/SWnRhZIjFSclQtd43M1ChY/ZqTGikxGnjyVkquG+46RCyT\r\nTJUaiRTzRcgRAAAAADkCn5S1a9f4vlEHFx7+Z3Gu/3xLSo6Ie04//vH/o3wmTOflkzumk3GMBg5o\r\npdSkRnuczkmNvJXxpW4x4ntGHc6uUUgUgOTaJSDuUc4uShiittOpPSOdGhm7Rs5I3Xr2uJZJkTNO\r\np1MjuWukSxiW+aRGZgmDs2ukixgkUo4iShi4GFVPt0sYLL9xOpUYxXTGUMyxGBrY3I+Sqx8RgmSP\r\n1FU4zYmQIwAAAAByBD4hBw/uh5j0EPifxfn4My4oyKVf/vIXdO2119IzzzxF27Yln2M5OsZoYzQx\r\n6pkkVVPqlipbjLz3tEJGauRtRtTjdC
G1axQxynlMilHIHqcz67vNkbptctdIjdMFeQGDEKNE33G6\r\n6O108VKOeGrUpFKjhiURu0ZCihoWkFVnpkbOOJ1up7NUCYOlxulkO51MjcRIXdVr7Nuv+csRE6OY\r\nNkYTo55JUuUtlFwxzE6N9P4b5OgMKcqnxj/+gRqvvIJqGBXs2/z78NwAAACAHPVRtm1LgZxcZPif\r\nwfn+c05NTaI///mP9IUvfIH69etHQ4Y8SFOmTKI1a1ZSdnbGWciRFqMGRhWjglFE3x9QzCSpLGpq\r\nJGu7zT0jlRjxXSNXQ90hVwEIH6fTqVGYy5FuqPPsGrnb6XR1t7xrJFMj2VAnRursXSM9UufcNXKP\r\n03WVGpmJ0VzVUDdHFDFYvrtGM3wb6uzqbvOmUeUER4waGFWMCkYRk6QiJkklD9s7cJCjM6Nx+CPU\r\nFBNDNYxyRhEjnwsSnhsAAACQo76dIPGxLr73Alm5MPDnmj/n5ysx6ork5ER65ZXJNHToELrrrrvo\r\n8ssvp6uuuoruvPNr9MMf3ku/+90wio19miZNGk8zZ06nhQvfo/j4ZbRx4zohWbt3b6cDB/ZSVtYh\r\nOzEyxSgmho/z5TKyaOCALNq6pTBi18ivoc5OjdRNI0eMDrpTo3ajulvsGamRunYpR0GVGgXtkTp3\r\naiRuGnVZ3R3vEiO7vtsnNbJ8qrt1CYNuqAt6qrv5OJ0jRlNlO525a1RpNtRNlMmRSoxMMYo5wshl\r\nZDFJyrqZko8MhRydqRxdeQXVKjEqZGQw0nmChOcGAAAA5AiAvktGxgFat241zZ07h0nRBCFHjzzy\r\nexo8+Od0770/oG9/+1tCnm677Yt04403iDG9K674jBKjaka5IUY5QoxiYg4wOcqg1MQC18FXs53O\r\nPPhq3jTy3tRypUb2OJ33rpHfrlGSKzESN43sg6/rXCN1ctfIuWskGuqaupMaqYOvRmI
k2unqdH33\r\nbM/BV/ddo2DUXSN106hivBSjaka5IUY5UoxiDsTQgIybKalAytGDDz5IQ4YMoYceeoh++9vf0i23\r\n3Exf+tLt4s/vW9/6Jg0cOIDuv/8n9Jvf/IqGD39EjFuOGfN3mj59mhDhtWtXCQEu6gPjZXyUTidG\r\nXIz2M3ZdcQWtWrWKpk6dKmr3UShz/uHP89TX4mj5soWiNAh/JwMAIEcAgN75yW0nRsUuMeKJUWri\r\nEeOmUfdSI3HbyEiNzOru0LG9PqmROU7nlqNgizNSF/SM0wWNhjozNXJuGvmN0+nUaFH0hrp61VBX\r\n+7brppGzazQjysFXKUZB0VBnpkayuttOjIrdYsQTo6QjD9m3tvgbzfnz59G8eXNFZfw777xNaWlb\r\nRVrIkz+eAH7wwQL2/W/RtGmv0dixY+i55/5Kf/rTcPrVr34hRLh//zvp+uuvp0996p/pmmuuEVL1\r\nk5/8mB57bATFxU1h4hBPOTkZl8Zr+I9/sBMjLkY7GYu/8x1KSUmhtrY2CofDhI/z/8GfZ/5879ix\r\ng6ZMniTOTuDvVwAA5AgA0AvlyJ0YDRyQR6lbSuRdo06/XaNCJkVOO11EdbeRGLlTo32qpW6vU93d\r\nvpPCdmq0rcvUKNjspEbBo+vsY68CJkfBJqe6WzfU2eN0Wo7UOJ1Vv1CmRg1ajpzq7sibRu5doyAv\r\nYqiebpcwyJE6/xIGAT/4WjEuIjEaePgWSi56WDTUWeWjKFD2PBOk58/5WB0fn+SJ4ttvz6YXXhjp\r\nGsW8+eab6Kc/vZ/9ni/T5s0beudruDCPCpggHbjyCpEYLb3nHso5dAi2chE/cnNzxesYCRIAAHIE\r\nAOiFciTFaOCAAtqaVBZx08hupzulxchdxKBH6sIqNTJLGOSh4f3ucbr23acpYTBSIyZHQXOkrnmj\r\nq7pb3zXSN414ahTyljDwPSNz
nK7+fZUaGUUMeqSuXrbUWbVGQ13NLNc4nazuNlIjQ4yCXjGqnEAB\r\nJkZCjpQYDchnUlQ8TLXTyRKGQNkLQoysspEXdOdo69ZkmjXrdXr44aF0++230ec+d6349kcffUjl\r\n5cW97rXMR+l4coGPi/+RnJgg7vHh71gAAOQIANCr6NdvO5OiSufg66lKmRqd8k+NnLtGsrpbipG8\r\naaTH6czEKKyPvRqpkX3XqC3yrpGrhEE11NmpkRqnCwnUnlGTvmmk6rsblxt3jSJTI2fXaAFZTIzE\r\nrpG6aWRFlDDwkTo5TmemRvyukV3dzUfqdEOdPU43yR6nsyrHiYOvAwuZFJXK6m5500hWd2sxCpQ+\r\nJ7iYhQy7dm2nv/3tRfrqV79Ct956qyj96E17S/xIMx/twsfF/2htaaS4uFfxdywAAHIEAOhd8Dfj\r\nXIyos5o9mmJUGnWcTpYwqJE6dfDVHqlTB19Dx9J9D746JQzb1b6RX3W3PPbqPvhqpEZH5cFXnRqF\r\nzOpuJUa+JQx6nM7eM5pv1He/a9w18pQwqF0jPU6nU6Ogd5yu0l3CIOSoYqykfAwF+MFX+66RHKez\r\njNQoUPpsj2mr43tJ3//+QFHgsXLl8l7xWualANgx6jk7SPy1fLEaPQEAAHIEADgLOapSYlTluWvk\r\nPfjqlxo51d364KvZTidKGI7pEgZn18iVGrVGjtPJ1MhoqFM3jUL2TaPV9jidc/B1uVHfvcyTGi1y\r\nNdSJg69qnM7yOfhqljAEjXY6nhpZZmpkVncbd42kGMnUyKoYw3jJSI1e9EmNniWr9K89rsp76tRX\r\nKSYmhpYtW9IrXsv46Dkf5mv5QtyCAwAAyBEA4Ny8oeSpkR6n63RSo1CUEoaQfew1x9VQx1MjMVLn\r\nTY1cu0ZKjNoNMTJTI3vPSI/TObtGQUOOQr4NdT4lDGZqpG4aWcbBVyFGuqFO1
Hf7V3e7UiMmRjI1\r\ninN2jYybRjI1GkcBIUZSjnhqFFByJHaNVGoUKBtpp0Y9UY44/NAwr37nDXl9WY6s9gYqKyqisrJq\r\nam7vOINf2UGbZo6mEbEzKa+jb8oRBwkSAAByBADoBTtHxZS6pd4YpzNSo1NmanQkakOdvmnkTY38\r\nxunCXRYxqJE6IzUK2jeNZAmD9+CrHqcLucbplBx5Dr7KsTr3wddujdOJ+m7PTaOoDXVmajSWCZGZ\r\nGo2WlI2yq7u5GFlKjAIlz/TYI7C8RpzXguflZfdBOWqnlJkjRIJmMjO9vdu/fs4g/msG0572vitH\r\nfMQOf+cCACBHAIAe3lbXyThGAwccpdTESv8SBiZGISM1EuN0J9WekdgxOqQeD0ZUdzt3jXb6ljAE\r\njeruoNozEqmRGqdz2ul0arRGjNQJOTJG6nzvGrnESKVGepxO7RnxxEiXMPiN1EXcNVLjdEG7hGGy\r\nnRoFKtwlDGKczrVnJFMjPlJnlbtH6gI9XI44Awf+N82ePbPPyVF71hwlRINpwaY02pOyieZMGE3x\r\ned2XowWD5a9Pj5ocWbRpwjD2c/rTkjzrfOZfF+j3iZSjJUvQXgcAgBwBAHq8HB1jtDGaGPVMkiqY\r\nJKnU6FSRrO42Guoi7hoZ43RhUd3tf9Mo7LdnFOWuUdDYNZJyJBvq/Mfpot00MkbqjF2jaKkRH6cT\r\n1d21s6LeNHKqu+OMxEilRlVOEUNAlzAwQdIlDHrXyJsa6XE6qzSW0bPlaPLkiTRkyIN9To6K4mOV\r\nHMVGjsV1FNGEYYNp0ODRlKV+LC9+Ag0aNIgmJBR55GgYJaQl0Ij+MUJOBo2YSdqv8pbEOqlU//40\r\neHQ8+1XtFD96GA0aNoFS9qhfN2wBtVvVtGTCCBrUX//8QRQ7M4EaTNdpzqMF5s+JGSRkzv/3uTBy\r\n1JNeywAAADkCAESRIy
1GDYwqRoW4fTRwQCGTpCOuhjq9a2SO08nqbtlOp3eNwsedIoaIu0bt7nE6\r\nu7pbNNMlGkdf1cFXTwmDefA11OTsGpmpUcgcp6s3Shh8xMhJjWaLm0ayvnuWXcTgumtk7xqZDXWT\r\nnHG6Cp0ayXY6Pk4XEFJkJEZiz+h5V0OdTo0CJU/3yDeUlQW51DTrdcp6aCi9dPtt4p/7khxZ1Zuo\r\nvzFON3rOJkdE2tNpcIx7ZC5rzmDx8wbNTPfIkWTwCCYt+t83eIGQk+q0Bfb3DRoxgebEp5PFx/GM\r\nXxfDhGvQiCXU3pFOw5jszFySQGlMtkYPkj8+Ia1BCVsWjbD//aNpwZIlNIH9nkuy2qP8PpAjAACA\r\nHAEAlBzJxMgUI34UNiYml5HFJCmDUjfn+KRG2fZInb5rFDIa6szUyClh2O4qYXBuGunUyN1Qp0fq\r\n7BKGZr8Sho98UiPvTSOdGqnq7jrPSF2dvms0y9VQ5z34Gl2M/BrqXrZH6pwShhcjShgCKjXiYhQo\r\nearHvaGs3bCWrOuuI/ZisOH/zL+/LxUytBdtUolPjD1it6mIaY0QFTUyZ8vRMClBPnI0M61a+csC\r\n+98jparD/jlzdARl/LrR8Vm+BRHV1WWUMHqQS8aKlqj9qP4TqNqnHCLy94EcAQAA5AiAS5iMjAO0\r\nbt0amjt3Dk2YMJaefPIJevjhoXT//T+he+75LvXvfyfdfvttdMMNNygxqmaUG2KUI8QoJuYAk6OD\r\nlLIpW900ynHG6U74t9NJ9tpFDGEuR23qrpEYqdsWMU4ndo1azZtGG4x2unWqgEHeNLKPvTa5ixjE\r\nwdeGJZElDEyOrNOM00WUMFTPUEUM01V191SJru723jVSu0Z6nE6UMHjFSFV3y3E6Xd3tFDHwkbqe\r\nJkc8IfKKkSlIPS1BOv9V3h2UlzLHSX1i4qjBR47yFkSTo2HOzpGVZf8
6KUeGQKU3R+wquTymo4ji\r\nBvePKIgY7JGj/rEJPqmQ3+8DOQIAAMgRAJcAhYV54lgnF6AHH3yAvv71u+jKK68Q9O/fn374w3vp\r\nd78bRi+8MJKmTJlEb701mz78cBFt2LCWUlK20K5d243EqNglRjoxkuN0h/13jU5kOKnRMaOhzr5r\r\npMToNNXdIWOczn3XSB58jdg1UuN0Qoyalrna6UJd7Bm5UiMhR3NcI3VmdTcvYQiaJQzVrzklDDo1\r\nMvaM5I6RGqkz7hrxIoauqrvN1ChQ8mSPekPJR+n8xEjDf7xvyZH2mjn2Hs+eGmesLl2YSAPNGRYT\r\nRY6cQgaraIn6dwxT4uOM0EUmR454mWN7Wn6yZsp/HjwnyyVnMf2ZvPk15yE5AgAAyBEAlwqJiRso\r\nNvZp+s53vk2f+tSnhBD99rcPUVzcFCFKPDU6s7E6d2I0cEAupWzOEyUMIbO6+0SkGIXUrlH06m7Z\r\nUCfru72pUaorNXKqu52bRlyMQmqczp0aaTHyNNR5UiNLNNQ543Q6NdI3jUR1d41MjYJmdbd508iu\r\n7zZG6nhipKq77Ya6CmfXSJcwBMpGy1E6PU7nKWEIlMS6UiOrh8lRC5PqruSI/3hfkCNeYjA4No7i\r\neVPdnk00YZhKbQbNpGYqo9F6h2dYLI0YFJnkuHaOhsVRCvt36D2hmGHxKt3poCVaqkbPpE1peWLn\r\nyF+OlPwMnkCbNjlJVv9hc4hP+lHzHuf7RvDfbw8lLJgpxwB9fx/IEQAAQI4A6EXwhIcL0c033yT4\r\nv/97lD74YAHl5+ecg50jKUYDB+RRamKBqu52t9OJ6m4xUpcld43skbqDnpG6vZEHX9v9bhr5H3wV\r\nJQwtG+27RnzXKGQXMUQ21GkxCkXbNdI3jezq7ncUaqTOc9fI3jWqkbtGdkOdGKczD77q+u4JnoOv\r\nOjFyN9Q5RQwe
OVKpkcWTo+InGX9BctQj5SjyxlH/YRMoXbUyZC0Z7Xx/7BxaEiflZdiCrIgEKHbE\r\nIOffM2wmFRnhTUP6AtfIXrM5jmdWyjXscQoXYvpT3II4+9fF7WlWO1IpFDvI/d88J6s9yu8DOQIA\r\nAMgRAL2ALVs20s9//jO6+uqr6ZFHfi9So3P9e/Trt51JUZHr4Ku7oc5/nC5kN9TpEgbvTSPj2Gu7\r\nJzVqM1IjY5xOHHxt2WCnRkGPGLlSI1diZKZGi2RDXb1/dbcVcfB1luvga/SbRjo1Mg6+VvgffJUN\r\ndaPdDXU8NSp9zkiNnnGN0wmKn+hZO0dMvrFzpMbgOtqpoaGaqqurqaG5w/fHm5u7V4rd0d5O7e3t\r\nUfeampuZFnWcLs+xqJ39fvqnWe3N1NzeEZECtbN/V7Px887894EcAQAA5AiAi0x2doaQoWuvvZZe\r\nfPEFOnIk77y+oeRiFNIHX703jXh9t50aaTE6JOQoLDjAhIjJUXtkauSM07l3jYItSXLXqFXLkRIj\r\no7pbkqDKGBw5CvHUqFGO04V0auRTwhC0R+pkamQZiZE89vqWffA1WPuG2DOyjNTIGafzlDBoMao0\r\nD746YuS6acQPv7ruGj0nShjEOJ26a2SVPm2LUU+TI7TV4QNyBAAAkCMALiorVy6nG2+8QbTL5eVl\r\nX5A3lDIxUnLUccROjfRInV3dbd81cpcw6HG6MMe8acTFqHWbMU5nHHxtSXJuGvEShmZvCcMaSdMq\r\n9zgdF6OmKHtGjYukHDEx0g11lihgYNT73DWqnaXEyChhEO10TgmDFiP3OJ1ZxKCru31KGERD3fNd\r\nVndLMfqLECOr+PGeeecoP0eM0L15042055mn+tydI3xAjgAAAHIEwEVg4cL3RFo0f/7cC/qG0hyn\r\nc5UwnPRLjZzESMrRPruhTqZGO/3vGhnjdDo1Copjr85NI7uEw
UiMIlIj864Rr+7mu0a6oa5elzAs\r\nMBrqvKmRkxjJPSM9Uve6XcQQdN01ivNJjSaqcbqxrptGAVHbPdqVGPFjr3ZqJCq8pRzpEga+a2SV\r\ncDl6nPFYj35DOXToEJo0aUKP/fwRr2WrhdFMZB2lcKCJ0ci+3cAe6yjcWcuoIeqsZo+VjAoKn+KU\r\nMUoZJRTqiBwvlejdu2xFlPFSnaDa46W7KOy3e+ctJbGPH6svFLhS1AT1xQJ1/PioUWPvLSUxd+/4\r\naKl39874QoG5dye+UFDjJKjmeGmwZpqryj4ovmDgGS9VXygwd+8gRwAAyBEA4BOTlrZVLEjHxy+7\r\noL/v+PHj2ZvAI3ZiFFZy5LdrZKdGx+TB1/BxMzXyHHz1HadTB1/Fm0FnpM6p7l5nH3x1lTA0dSM1\r\natB7Rgui7hqZqVFQpEaz7BIG166R702jScY4nTlS506N9F0j165RlNTI8qRGJwqe6NFvKGfPnkkD\r\nB/53j5YjCrbackQWl6MGIka4s449SjkKd1YZclTmyBEXo1NFzudDR4ErQQ2flF8oCB1Xu3fHvV8s\r\n2OdqbAwf0ze+drjEKOhz48tOUMUXCjbYpSTOFwsid++C5o0vJUb+Vfbz2evfKSURx49dI6bOFwtk\r\nlf0MtX833TVealfZmwlqReTxY9HWCDkCAECOAACflP3799A//dM/iQa6C/17T50aRy31GfauUciV\r\nGmX7pkY6MXLa6YxdI3XwNaxTozYlR2ZqxNvpjJtGzsFXZ5xOvBE8utI49hqvyhg8qVEXB1/lTSOd\r\nGs2x94wsVcJguRIjZ9fISY0cOQqau0YV+uCrFKOAz8FXq1ynRs85x179RuqM1Khg5ws0ceLEHvuG\r\nkrcj8nKQNWtW9lw5slrcqVFApUZCjKoVVTIx6ix35KijxFVKErZTo7yIG19hMV5q3Pg67k5QnS8U\r\nmGIUpb
FRjJducX0+mKUkUffuzARVf6HA/GJB/fvqCwULfA4gs8+JWn0A+U1XKUn0LxT4fLFA3/my\r\nU1TnxhdPUSFHAADIEQDgE/HAA7+hRx/900X5vZcu/YBSEuNd43Tyq+S5zq6RSo2kHMkRIpkaeRvq\r\n3CUMQW9qpBIj+UYw0b5rpN8MOiNEPtXdjcb4UIN6I2h+ldx+I+h8ldx5MyhTIz1Sxw++iuTIp6HO\r\nLmHgXyWv9EuNzDeC8q6R01CnW+p8UiOfm0ZajKy8EXTika9RzWWfprJPf5p2/eiHtOi9eT3yDeU7\r\n77wlEs6eKEhyrI6JkSXFyDVSZ6dGTI5OmalRqZ0amaUkEZ8PxhcKZIKqRuqOO3e+xEhdu2e8NEop\r\niWucrtUpJQmKCnstRs7ng77zJT8flkdW2Xd146vO/ELBO0aC+qZdZe+M1M0QpSQRnw8RKeokeeOr\r\nwklQRSmJceMLcgQAgBwBAM6Y3bu305VXXkmHD2ddpGa8Q+JNTM6hpIjUyK7uNr5Kbr8R1OND5jid\r\nWcTg2q0wvkruOviqx4e6GqdTbwTVboU9QuTbUOdNjZyDr/Kr5M5NI68YBe0ShqmuIgY5QmTcNfKp\r\n7vYdpyt73nXTSCdG9q6RbqgreUKIURMTjhpGOaOIkcwEqae+ofzww0VCkObOndMDkyM5TkcWl6N6\r\nMU7HxYgC3nG6cvc4nU8piRwvzZWfD3ykjo/TmbtGx9Pd43Rq10iM03nHS+1xOv/du1CLs2ukb3yZ\r\nnw8hIUfGrpF3z8j+QoH788GKsnsX9OzeBT2lJMFqnz0j/bngbWz0pEZWhfx8gBwBACBHAIAz5tln\r\nY+nPf/7jRf1vyMw8SJMnT6KtyauopXa/SIycr5KbI3XpSoz2e0oYouwaeXcrVGqkdytC6ivlYoTI\r\nO1LXtNL/zaAap7N3K4w9I6su8o2g+Cp5nTs1cnYrnBI
G567Ra85uhfFVcr1bEfApYZBy5DTUOQdf\r\nPXeNDDHiJQwnCp6igp2jRGJUq8SokJHB2HPZZT36DSVvVbztti/S978/kFavXtEj/pv69Sum1OQW\r\nsWfExYgUuohBylGVUcKgxumUHOldo5DR1ujeu8twlTA4pSTGFwtc46U7jPHSbZGfD61bIsZLQ8aN\r\nr5A9XrrKNWLqSlEbo6WoPnt3td4bX55Skmq5a2SmRkHvFwqYGA08eSsl1w33lJI446W6rRFyBACA\r\nHAEAzphvfOPrtHz50ov+38ETpMWLF1FcXJx4UwMuDHzHiI/S6cSIi9F+RpqSoyVLFvXY125RUT5N\r\nmTKJbr31VvrKV+6g0aNH0a5d2y/e/1HFdDKO0cABrZSa1GiP0zmpkRajyNRIiJF940ulRj53vkLd\r\nKWGI2k6nElR7986RI2ekbr34QkHoqDNOp1MjvXcnE9RlPqmRmaC6Gxv1SJ1fY6P4QgEXI7F3Nz16\r\nKYlKjGI6YyjmWAwNbO5HydWPOClquZMa8TtfkCMAAOQIAHDGfJq9Mb4Q94zOhLVr10S8qQHnD75j\r\nVGiI0U7GOjVWx/8sevpruLy8mD766EP67W8fos997lq6/fbbxJ2uN96YQampSRdQjo4x2hhNjHom\r\nSdWUuqXKFiPyyFHISI30OF3IM06nU9TQCW+CqktJ9DidWd9tpqjbXFX29gFks5TEGKeL3k4X7xxA\r\nbvLs3rkaGxeI6m6dolq6gMHTThdRSuI7YvqavxwxMYppYzQx6pkkVd5CyRXD7NRI791BjgAAkCMA\r\nwBlx6NB+uuqqq3rcf9fBg/shLReQRfPmUgqTod2XXSYSIy5GH6hCBv5n0dte15s3b2BvjF+mn/70\r\nfrrllpvp8ssvp7vuukvcSXr++efo7bdnM+lbRQcO7D3HcqTFqIFRxahgFNH3BxQzSSqLmhrJ2u4j\r\n
7hp7vWvkaqhzSkn07l3YLiXZ4zTUeffuXO10uro70di9c6rsg/aukdPY6FtK0mVqZCZGc31LSaLt\r\n3pmpkWu81NgzssWogVHFqGAUMUkqYpJU8rA9Xgo5AgBAjgAAZ8THH6eIvY2e+N+2bVsKxOUiw/8M\r\nLoXXeU5OBq1aFU+vvjqFHn/8/+j++39C/fvfSddccw196lP/TNdddx3deefX6Ac/GES/+tUv6E9/\r\nGk7PPfdXGjt2DE2bFica8njNPb8BtmHDWkpK2kxpaam0d+9Oysg4QFlZByk3N9NOjEwxiok5wshl\r\nZNHAAVm0dUthxK6RX0OdnRodz/K0NR50p0btRnW32DNSI3XtRmNjayp7TPGtshelJF1Wd8e7xMhV\r\nZe/bUOeu7nbt3tliNMu1Z+SI0VTZTmfuGkU0Nk60EyNTjGKOMHIZWUySsm6m5CNDIUcAAMgRAODM\r\n2LkzTXxlvaf+9/HUgo918b0XyMqFgT/X/DnvjYnRJ91b2rNnB61bt5oWLnyPpk+fRmPG/J2eeeYp\r\nGj78EXrggV8LmRo4cAB9+9vfElL15S9/ifr1u0VIFResK6+8QqRTUoyqGeWGGOUIMYqJOcDkKINS\r\nEwtcB1/Ndjrz4Kt500jf+fI2NpoNdZF3jfx2jZJciZEuJdGNjeZIndw1cu4aiVKSpu6kRqrK3kiM\r\nZFujeQB5tquUxLfKPmKcbpJ940uIUTWj3BCjHClGMQdiaEDGzZRUIOXo0UcfpSef/AuNHDmSXn75\r\nZVqwYJ5o6MTf/wAAyBEAwPcr6vxNHZ4LAM7FWJ1OjIpdYsQTo9TEI8ZNo+6lRt4bX2Z1tziAHJEa\r\nmeN0bjmy73y1miUM7oOvrnE6100jv3E6nRotit5QV68a6mrfdt00cnaNZkQ5+CrFKCga6iLvfNmJ\r\nUbFbjHhilHTkIfvGF5ejGTOm0yuvTGHfHssE6
TkaNOh/6POf/xx99rOfpR/96Ic0fvxY2rHjY7x+\r\nAQCQIwCA5LLLLutxhQwA9E45cidGAwfkUeqWEnnXqNNv16iQSZHTThdR3W0kRu7UaJ9qqdvrqrJ3\r\nDiBv6zI1CjYbVfZHnePHAl5n3+RUd+uGOnucTsuRGqezeJU9T40atBzNcx0/dt80cu8aBY0q+6BO\r\njaKUMAgq5I0vb2I08PAtlFz0sGios8pHqRtfz3c5VpeevpfefHMWPfjgA0KWvv71u+i1116hwsI8\r\nvJYBAJAjAPoy/E3BmjUr8VwAcNZyJMVo4IAC2ppUFnHTyG6nO6XFyF3EoEfqwio1MksYQl3e+IpW\r\nwmCkRkyOguZIXfNGV3W3vmukbxrx1CjkLWFQN77scbr691VqZBQx6JG6etlSZ9UaDXU+N76CNUZq\r\nZIhR0CtGlRMoII4fj7PFaEA+k6LiYa4bX4GyF4QY8QPI3d054m2Hixe/T/fe+wMxKsnr4UtLC/Ga\r\nBgBAjgDoi/D6Y97shecCgLOjX7/tTIoqnYOvpyplanTKPzVy7hrJ6m4pRvKmkR6nMxOjsD72aqRG\r\n9l2jtsi7Rq4SBtVQZ6dGapwuJFB7Rk36ppGq725cbtw1ikyNnF2jBWQxMRK7RuqmkRVRwsBH6uQ4\r\nnZka8btGdnU3H6nTDXWVxgFkNU5nVY4TB18HFjIpKh2mjh//za7u1mIUKH1O8EkKGTZtWk/f+c63\r\n6T//8xvYTQIAQI4A6Iu8/vo/6Gc/+188FwCcJfzNOBcj6qxmj6YYlUYdp5MlDGqkTh18tUfq1MHX\r\n0LF034OvTgnDdrVv5FfdLY+9ug++GqnRUXnwVadGIbO6W4mRbwmDHqez94zmG/Xd7xp3jTwlDGrX\r\nSI/T6dQo6B2nq3SXMAg5qhgrKR9DAX7w1b5rJMfpLCM1CpQ+e1ZtdU899ReK4Xe/9u/BaxsAAD
kC\r\noC/BZ+8/85nPYIwEgHMiR1VKjKo8d428B1/9UiOnulsffDXb6UQJwzFdwuDsGrlSo9bIcTqZGhkN\r\ndeqmUci+abTaHqdzDr4uN+q7l3lSo0Wuhjpx8FWN01k+B1/NEoag0U7HUyPLTI3M6m7jrpEUI5ka\r\nWRVjGC8ZqdGLPqnRs2SV/vWsq7z5F474UeFdu5AgAQAgRwD0KXg98dKli/FcAHCWciRSIz1O1+mk\r\nRqEoJQwh+9hrjquhjqdGYqTOmxq5do2UGLUbYmSmRvaekR6nc3aNgoYchXwb6nxKGMzUSN00soyD\r\nr0KMdEOdqO/2r+52pUZMjGRqFOfsGhk3jWRqNI4CQoykHPHUKKDkSOwaqdQoUDbSTo3OhRxx/vGP\r\nqaK6vaAgF69xAADkCIC+Ar/r8sADv8FzAcBZ7RwVU+qWemOczkiNTpmp0ZGoDXX6ppE3NfIbpwt3\r\nWcSgRuqM1Cho3zSSJQzeg696nC7kGqdTcuQ5+CrH6twHX7s1Tifquz03jaI21Jmp0VgmRGZqNFpS\r\nNsqu7uZiZCkxCpQ8c86OwN5zz3dp8uSJeI0DACBHAPQV+Fz9FVd8BjW2AJzN/1HFdDKO0cABRyk1\r\nsdK/hIGJUchIjcQ43Um1ZyR2jA6px4MR1d3OXaOdviUMQaO6O6j2jERqpMbpnHY6nRqtESN1Qo6M\r\nkTrfu0YuMVKpkR6nU3tGPDHSJQx+I3URd43UOF3QLmGYbKdGgQp3CYMYp3PtGcnUiI/UWeXukbrA\r\nOZaj1NQkuu66z1NxcQFe5wAAyBEAfYXvfvduevfdt/FcAPCJ5egYo43RxKhnklTBJEmlRqeKZHW3\r\n0VAXcdfIGKcLi+pu/5tGYb89oyh3jYLGrpGUI9lQ5z9OF+2mkTFSZ+waRUuN+DidqO6unRX1ppFT\r\n3R1nJEYqNapyihgCuoSBCZIuYdC7Rt7
USI/TWaWxjHMnR5w77riDVqz4CK9zAADkCIC+wuzZM8X4\r\nCJ4LAD6pHGkxamBUMSrE7aOBAwqZJB1xNdTpXSNznE5Wd8t2Or1rFD7uFDFE3DVqd4/T2dXdopku\r\n0Tj6qg6+ekoYzIOvoSZn18hMjULmOF29UcLgI0ZOajRb3DSS9d2z7CIG110je9fIbKib5IzTVejU\r\nSLbT8XG6gJAiIzESe0bPuxrqdGoUKHn6nMrRyJHP0uOP/x9e5wAAyBEAfQU+MnLNNdfQ1q3JeD4A\r\n+ERyJBMjU4z4UdiYmFxGFpOkDErdnOOTGmXbI3X6rlHIaKgzUyOnhGG7q4TBuWmkUyN3Q50eqbNL\r\nGJr9Shg+8kmNvDeNdGqkqrvrPCN1dfqu0SxXQ5334Gt0MfJrqHvZHqlzShhejChhCKjUiItRoOSp\r\ncypH/ItH//u/9+N1DgCAHAHQl+C3Pf7wh9/juQBAUV5eTPv27aZVq+Jp1qzXafToUfToo3+mX//6\r\nlzRo0P/Qf/3Xf9K///u/080336TEqJpRbohRjhCjmJgDTI4OUsqmbHXTKMcZpzvh304n2WsXMYS5\r\nHLWpu0ZipG5bxDid2DVqNW8abTDa6dapAgZ508g+9trkLmIQB18blkSWMDA5sk4zThdRwlA9QxUx\r\nTFfV3VMlurrbe9dI7RrpcTpRwuAVI1XdLcfpdHW3U8TAR+rOtRxt2LCW7rzza/icAABAjgDoS/A3\r\ngVdeeSXl5mbi+QB9Mj1dt24NjR8/lh544NfUv39/+vSnP03XX389feMbXxfHkp944jH6+99Hi4rn\r\nBQvm0Zo1KykxcQNt377NSIyKXWKkEyM5TnfYf9foRIaTGh0zGursu0ZKjE5T3R0yxuncd43kwdeI\r\nXSM1TifEqGmZq50u1MWekSs1EnI0xzVSZ1Z38xKGoFnCUP2aU8KgUyNjz0juGKmROuOu
ES9i6Kq6\r\n20yNAiVPnlM54q8LyBEAAHIEQB+Ef0V81Kjn8VyAPsHevTtp4sRxIgW6/PLLRQr08MNDadq0OFq9\r\nesUZfaHAmxgNHJBLKZvzRAlDyKzuPhEpRiG1axS9uls21Mn6bm9qlOpKjZzqbuemERejkBqnc6dG\r\nWow8DXWe1MgSDXXOOJ1OjfRNI1HdXSNTo6BZ3W3eNLLru42ROp4Yqepuu6Guwtk10iUMgbLRcpRO\r\nj9N5ShgCJbGu1Mg6D3LEZRmfMwAAyBEAfYwtWzZSv89dS3UzplHLCyOpadbrVIkDiOASoqTkCM2c\r\nOZ2+97176OqrrxYp0VtvzabDh7POcudIitHAAXmUmligqrvd7XSiuluM1GXJXSN7pO6gZ6Rub+TB\r\n13a/m0b+B19FCUPLRvuuEd81CtlFDJENdVqMQtF2jfRNI7u6+x2FGqnz3DWyd41q5K6R3VAnxunM\r\ng6+6vnuC5+CrTozcDXVOEYNHjlRqZPHkqPhJxl/OqRzxJs8f/vBefP4AACBHAPQ1ajespYZ//mdi\r\n7/JsrOuuE9+P5wf0ZkpLC2nSpAl0ww030H//9/fo7bdnU1FR/jn79/frt51JUZHr4Ku7oc5/nC5k\r\nN9TpEgbvTSPj2Gu7JzVqM1IjY5xOHHxt2WCnRkGPGLlSI1diZKZGi2RDXb1/dbcVcfB1luvga/Sb\r\nRjo1Mg6+VvgffJUNdaPdDXU8NSp9zkiNnnGN0wmKnzincsRHKf/85z/i8wgAADkCoC/BEyIuQqYY\r\nmYKEBAn0VvhCPb9Vw6Vo3brV5+X34G/GuRiF9MFX700jXt9tp0ZajA4JOQoLDjAhYnLUHpkaOeN0\r\n7l2jYEuS3DVq1XKkxMio7pYkqDIGR45CPDVqlON0IZ0a+ZQwBO2ROpkaWUZiJI+9vmUffA3WviH2\r\njCwjNXLG6TwlDFqMKs2Dr44Yu
W4a8cOvrrtGz4kSBjFOp+4aWaVP22J0ruVoyJAHacqUSfhcAgBA\r\njgDoS/AROj8x0vAfx/MEehu8YOGqq64So3Pn8/cRciTESMlRxxE7NdIjdXZ1t33XyF3CoMfpwhzz\r\nphEXo9ZtxjidcfC1Jcm5acRLGJq9JQxrJE2r3ON0XIyaouwZNS6ScsTESDfUWaKAgVHvc9eodpYS\r\nI6OEQbTTOSUMWozc43RmEYOu7vYpYRANdc93Wd0txegvQoys4sfPqRzddNONlJqahM8nAADkCIC+\r\nBN8x6kqO+I/jeQK9iZde+hvdfvttok3ufP9ejhzJcTpXCcNJv9TISYykHO2zG+pkarTT/66RMU6n\r\nU6OgOPbq3DSySxiMxCgiNTLvGvHqbr5rpBvq6nUJwwKjoc6bGjmJkdwz0iN1r9tFDEHXXaM4n9Ro\r\nohqnG+u6aRQQtd2jXYkRP/Zqp0aiwlvKkS5h4LtGVgmXo8cZj50zOeItnnw3DZ9PAADIEQBIjpAc\r\ngV4Lr9qOYa/bnTvTLlBCNZ4J0RE7MQorOfLbNbJTo2Py4Gv4uJkaeQ6++o7TqYOvYtfIGalzqrvX\r\n2QdfXSUMTd1IjRr0ntGCqLtGZmoUFKnRLLuEwbVr5HvTaJIxTmeO1LlTI33XyLVrFCU1sjyp0YmC\r\nczdWN27cy/Sb3/wKn1MAAMgRAH1u5yg/BztH4JIgLW2rGKXjFcwX6vecOjWOWuoz7F2jkCs1yvZN\r\njXRi5LTTGbtG6uBrWKdGbUqOzNSIt9MZN42cg6/OOJ0Qo6MrjWOv8aqMwZMadXHwVd400qnRHHvP\r\nyFIlDJYrMXJ2jZzUyJGjoLlrVKEPvkoxCvgcfLXKdWr0nHPs1W+kzkiNCna+QBMmTDgncvTNb/4X\r\nLVz4Hj6vAACQIwD6IryVzitIJ6++Cm11oFfx05/eTy+++MIF/T2XLv2AUhLjXe
N0orrbTo2y7dRI\r\nypHcNZKpkbehzl3CEPSmRioxkmKUaN810g11TgmDT3V3o3HTiIsRT43Mg6/2ON18sur0OJ1MjfSu\r\nkR6p4wdfRXLk01BnlzDwhrpKv9RIj9ONte8aOQ11uqXOJzXyuWmkxcjKG0EnHvka1Vz2aSr79Kdp\r\n149+SIvem/eJ5Wjfvl3iMDY/EIzPKwAA5AiAPpwg8RE6vmO0/rcP0f8b8N94XkCvge+IXHnlFWd9\r\nt+hMyc4+JEa5cg4lRaRGdnW3uGkkSxj0wVctRiFznM4sYtB3jbwlDK6DrxvUTaOuxumWK1RDXVOU\r\nkboGd3W3TI2cg6/BOvdNI68YBe0ShqmuIgZZwmDcNfKp7vYdpyt73nXTSCdG9q6RbqgreUKIUVNM\r\nDNUwyhlFjGQmSJ9Ujp588gn64x//gM8rAADkCAAg4XdgPv/5z4njsHg+QG+A3zJ64IHfXJTfOzPz\r\nIE2ePIm2Jq+iltr9IjHS43TmXSOZGu0XuEsYouwaGWIUNFKjoN4zEtXdqojBO1LXZI7ULXenRg2L\r\nKWSXMCw0EqPIEgaxZ1TnTo2EHNW6Sxicu0avqbtGZmo0yb5pFPApYZBy5DTUOQdfPXeNDDHiJQwn\r\nCp6igp2jRGJUq8SokJHB2HPZZZ9Ijvjffddccw1t25aMzysAAOQIAOAwatTz9Otf/xLPBegV3H//\r\nT2j27JkX7ffnCdLixYsoLi5OJEngwjBx4kQxSqcTIy5G+xlpSo6WLFl0Rn+Ob7wxg+6557v4nAIA\r\nQI4AAG5yczPF3D0fV8LzAXo6//EfX6WNG9f1iP+WtWvXRJQCgPMH3zEqNMRoJ2OdGqvjfxbd/XMr\r\nLy+m2277In344SJ8TgEAIEega0pKimjlypU0depUUV2Lr1heCMbT5FfiaMEHC8RXpS/Gn/vw4Y/Q\r\nU0/9BZ8DoMdz/fXX054
9O3rEf8vBg/shLReQRfPmUgqTod2XXSYSIy5GH6hCBv5n0d0/tzlz3qS7\r\n7roLn08AAMgROA2VFeLNenJKKh1taaNTVphB1ME4GSA6oTjWSdR+StLGaO0gamE0nyQ6ymhiNJ4g\r\nqj9OVHeMqJZR005UrahqI6pQlLcSlbUQlTJKmomKFUVHiY40EeU3Sg43SHIZOfVE2YwsRmYdUUYt\r\n0SHGwRqidMUBxr5qor1VRHsqiXZVSHYydpQTbWekMT4uI9rGKSVK5ZQQpTCSGUnFRFuKiBIZmwuJ\r\nNh5hsMf17HFdgSQhn2gNJ49oNWPVYaKVjBWM+Fyi5TlEHzGWZRMtZXzIWJJFtChT8kEG0cJDYZq3\r\nu41eX76DJk6aJPYaLvSf/datyWL+Hq1NoKfDX6cZGQd6zH/Ptm0pEJeLDP8zOJM/s69+9Ss0f/5c\r\nfD4BACBHoKvEqJimTJlC2dm5ZIWIOoMSLkeck5YUo+OK9k4JlyMhRh1KjE5IMWo4ruRIwQXJliNG\r\npZ8ctUgpKlRiJORIkdcoxUjIUYOUo2yPHHGEGDEp2ldlyBFjd6UhRxVSjoQgKTHaqnCJUbESI8Ym\r\nJUcbFFqO1hY4YuSSo1wpRx8ZcvRhlsQlR4yFQpCIFjBmr88VgnoxEqTvfe8emoVDsKCHc+utt/a4\r\nJXqeWvCxLr73Alm5MPDnmj/nZ5IYcV5//R/0n//5DXwuAQAgR6BrVq1aRdu376BgmIQcBUKOHOnk\r\niHO8UyZHnNYuUqMGIzmqU8lRjSFGQo5apRx5U6NCJUgF3uRICZIWo6w6KUecg0ZyxOVovyFGthxV\r\nepKjMpkccbaaqVGxJzXSclQoxWh9gWRtviTBTI7yHDGyU6McmRotVanR4kzJByo5et+Qo/mMOcvW\r\niIXvC/0amDv3Hbr77u/g8wH0aL797W9RfPwyPBfgjOENdTfeeAOtWPER
ng8AAOQIdM20adOouaWN\r\ngiFyJUccc6zOLzXSctTkkxzVq9SoxhitM1OjUiM1EuN0xkgdRwtSXqN7rC5ipK7WGacTI3VVEj1W\r\np+Vol0qOdqixOm9qpJOjLX7JUaEzVsdZW+AWo5XekTqFKUd6rG6xSo/eV3IkxOgg0XucXQ0UF/fq\r\nRXnjcMUVn0ExA+jRPPjgA+zzYwqeC3DGvPzyS3TffffiuQAAQI7A6eHlC8FQWIiRmRzZqZElxcjc\r\nN+KpUespT3Kk5EjvHHFEanTMPU7HKWuV6OTIHKvTyVGBGqnL86ZG9U5qpPeNuCDx1MhMjvaq1EiP\r\n1Xn3jT42941KZWoUkRwVqp2jQvdIXUK+s3OkUyMtRytUcrRcjdRxQTLFiKPFaKGSIw6Xo7npYTFa\r\n90lGRs7FG8+XXvobPidAj2XSpPE0ZMiDeC7AGZGevle0cn78cQqeDwAA5AicHv5mPKRH6vS+kZYj\r\nc9+o050ctap9I3vnyCxjUKlRl/tGre7kSI/VHTnqTo28+0Z2clTn7BvpsTouRvsUeyqj7xuZI3Xm\r\nWF1SceTOkd++kZaj1XkeOcp1kiO9c7Q029k3WmyUMXhH6nh6NC+dxJ/HJ102PhuWLVtC/fvfic8J\r\n0GPZtGk9felLt+O5AGfEb37zK3rssRF4LgAAkCPQfTnyjtR55Ug31R3TYnTKSY5ON1JXbYzUVSox\r\nKvckR2YZgzc1imiqq4tMjtK7Gqmr6N6+UYpPS50uY9jo2TdKMPaNeBGDt4xhuaeljmPvG2X4yJEa\r\nq/PK0ZnW1J4NpaWF9JnPfEZ8lRWfF6Cnwhvrduz4GM8F6BYJCavouuuuo7y8bDwfAADIETgDOYpS\r\nxtDh01Sn5cgvNfKWMfgmR2YZg7lv1BxZxtBlcmS01Gk52q/a6rgYeZvqdlY4Y3W6qY5XeUet8O4i\r\nORJNdZ6xuogKb
4VOjVzJUaZ7rG6+wk+OzuTA4dnys5/9r2h0wucF6KkMHTpE7I/guQCng58n+Ld/\r\n+zK99dZsPB8AAMgR+GTJUcBbxqDlqNO5beQqY/DK0XEnPfKO1VWYqZFPGYNd4300ct/ILmOo86/w\r\nTjfEyLxx5JccbY9WxlDsKWModNd4ry/w3DjyljHkesoYsp2Rug+NIoZoZQxcjOb6yBGvrb1Qr4Wx\r\nY8fQsGEP4/MC9Fg+/HARff3rOOIJTs/Ikc/Svff+AM8FAAByBM4+OTJTI/v4q09T3dFoNd7e+0Zt\r\nUe4bNfvvGxV4bhxFHn9tp2lPD6P/+fFgGrm82q7x3rEzgX7ylUH07EfVrhpvv/tGZmrUnRpvOzXK\r\nd1KjaCN15r6RFiRdxhCRGh1UqdFBfzniXKjXwpo1K/HGE/Ro+Pjnddd9npKTE/F8gKjw8oXPfvaz\r\ntGfPDjwfAADIEThzOXKN1HkqvCP2jTqMG0eeA7CmGPntG1UoMfKWMfCdI54eHTH2jQ4b+0be+0a8\r\njGHVWyMoJiaGYu6ZSam8qa6mg14dxv45ZjDNy4+yb6TKGLaZZQylcqRO1HgXuZMju8Jb7xsVuPeN\r\nvE11ZhmDuXOk943M1MgsY3jvoG6ru7hyxOfy/+Vf/gWfF6BH8+STT9Cjj/4JzwXwpby8mL75zf+i\r\nCRPG4vkAAECOwFnIkWekrsMYqdNy1N7plDH4jdTVe0bqaozUyK+pjmOO1BV47xs1yl2jiOSIlzHk\r\np9G3uBwxJu0i2ncwQXz7++PTXfeNvCN10Zrqkr37Rj7HX7vbVLfMOABrVnh7m+oWGnIUbazuQsoR\r\n51//9V8pOzsDnxugx7J370668sorKDc3E88HiICfJOAHg7kk4fkAAECOwFnLkS5jMI+/6jIGnRo1\r\n+6RGDUqQdBFDjU8ZQ7lfGcNRdfxVocXIt4zBtXNk0YxH+wsh+u
ZLCfTqyEHs24NoTq77vpGrjMG4\r\nb8TTIy1FdhlDlH0jPVbHR+rWqtRIlzF0mRpluWu8RVOdz1idTo16ghz163cL2sBAj2fw4J+zN8Gj\r\n8VwAF9u2JYubRvg7DAAAOQJnLUd+Nd4nPfeNzArvCDk6HnnjSAtSV/eNvCN13uTILmPwHn9lbE+Z\r\nI0frFP/19zR3GUOl/1idmRrZI3U++0abPMnRWt1UF22kzmyq89k3Mpvq/Ebq3u0BcvTFL36R0tJS\r\n8bkBejQbN66j66+/nkpKjuD5AIKysiKxMzlp0gQ8HwAAyBE4hztHZmrU6d43cjXVnfTcODrhjNXV\r\neIoYKv2a6prdTXWFRyNvHOX43DfiqREfq5P3jarpsa9oORpEb2ZGNtVxMdrhkxqllnZRxuBtqjti\r\npEb57tTIW8bgbarTNd6ukTqfpjrOuwcuvhzxJeaMjAP43AA9nrvv/g698cYMPBdA8MwzT9HAgQPw\r\nXAAAIEfg7OUooowhyvFX+8bRSYm5cxSRGnkEKeL4qylIxs5R/mmOv2YYyRFn5QxZzPClJ1PsG0eu\r\n1KjC//irLmNI8StjKDLKGI44x1/XRts38ozV6aa6D42dow88qZHrvlEPSY54IcNll12GWX3QK1i+\r\nfCndcsvNosEOz0ffhjdtXn311ThiDQCAHIFzJEfe+0bGvlFXNd7ekTotSFqMXE11PjXeRUd9yhia\r\nnHE6V1Od5/jrQXHjqIFG/pinRv3pH+mWTI2qot83spOj0sjkKKLC2+e+kXffaJXPjSNbjPR9I6Op\r\nrqvkqCfIUXz8MvrGN76OzwvQa/jud++madPi8Fz0YfLzc8Su5Lx57+L5AABAjsC5kaNgyFPGYCRH\r\noozBSI1aopQx1BtlDLWeMoYKVeNdbrTUFRtypEfqzDKGw94yBq8c1RAtmz5MjtQ9mkC7DTFyyVGF\r\ns2/E2Vb
mjNXpcTrfkTq/G0cFkWN13vtGfKRumUqNdHKkj79GK2PQcnSxCxl4PfKzz8bi8wL0Glas\r\n+IhuuulG7B718XKO3/72ITwXAADIETh3chQKkzgE671xJMoYTjllDOa+kff4a0OUG0dcik53/FUf\r\ngM1XgmQmRzlRxCi9poOWLEmgV99NoKVZFu2rpi6TozRPapTq3Tcqjp4cmTeO7NTII0fxuU4ZQ0Ry\r\nlOW+cWSO1JlNdRdz5+jw4SzR8rR793Z8XoBeBd8zmTJlEp6LPsi0aa/Rv/3bl+nIkcN4PgAAkCNw\r\n7uQoHGxjMHsJtlDYOspglmI1UjhQz6hjMBsJ1FK4s5pRReFTFYwyRimjhEIdRRTuKGQcodDJfAqf\r\nzGMcZuRS6EQOhU9kM7IodDyDwscPscd0Ch3bz9jH2Euh9t2MXYydFGrbzh63U7g9jX17G4VatzJS\r\nGSmMJMYWCrVspmDzRsYGCjWvp+DRtYwE9u0E9riasYpCR1dSsCmesZyxjEJNSynY+CFjMQUbFlGw\r\n/n3GQsYCsurns8f3GPPIqnuXgnXvMOZQsPYtsmpns8dZjDfIqnmdgjUzyKqezpimmEpWVRzjVcYr\r\nZFVOZkxiTGSMJ6tiLONlxhiyyv/O+JsgUPYiYxRZZS9QoHQk4zmySp+9aHL02GMj6IEHfoPPCdDr\r\n2LRpPX3uc9eKnTk8H32HrVuTRYFMcnIing8AAOQInFs5omA7EyImR1YLo5nJkCNHxOWos0aJUSVD\r\ni5Gio4Q9FjNBknIU7ihggiTlKNCeQ22Nh6mpjlGbq8gxyGZkSWoyGRmKg4LG6nT2yKg+wL69nz1y\r\n9rFv72WPnD3UWLWbmhiNVbvY405BY+UOaqrczh7T2GOaeGys/JixTVKxVZHKSJGUJym2MBINNjM2\r\nUWPZRva4nlor4ulUFZOl6n/YYhSsZmJUOYV9m4lRlRaj
iRSoGMcexwk5CpS/ZMsRFyOr3BEjq+w5\r\n9vhXJkd/vShyNGvW6/T5z3+O9u3bjc8J0Cv55S9/QbGxT+O56CMUFeXTV7/6FXr11Sl4PgAAkCNw\r\nPuTIPzUinhx11orkSMsRcUE6VS5TIy5GHcU+qVEeNdfnU3FRIfs/saJLkAJqKktgIvQaE6TXfFKj\r\nCUyIeGo0zkmNXMkRk6OyUUySnmePTI5UahQoib3gcsSXmPne1sqVy/H5AHotfBz0+is+QyWTJ1DL\r\nCyOpiQl/ZUEunptLlKFDh9DPf/4zPBcAAMgROE9jdVYrI8pIXWcNEyImRqd0alSh5Kgs6kgdF6NL\r\nU4rcNJWtVmI0RWKO1HnkKGCkRnqcjouRHqnjyVGg5JkLKkfvvfcuXXvttZSUtAmfC6BXU7thLbVc\r\nfhkx07exrrtOfD+en0uLGTP+IY5V85Y6PB8AAMgROE/JkRynIyZGXI7CgYaIkTqyd43KXeN0YXuc\r\njsHkyDqW16MSo72Jy2h6XBxNnz2fUtPPrbQVFxXQqcoZMjUScqRTo3GKsUyKdHL0kpMalevU6Hl7\r\n18gqjWVcGDniuxkPPzxUtHwhMQK9HZ4QcREyxcgUJCRIlw58v4jvGSUlbcbzAQCAHIHzKEc6NVK7\r\nRmQ1eMbp1L6RlqOO/8/emcBVWad9n/f9PM8zTc2TLTPTvDOVU9PMUE02S4s1aUPZvtBMWdZgZVOW\r\nzVRkllFaCWqRZpGmuKIiSeKGiooIKiqCchQQZN9BZJHNBT0L1/tf7/t/3+c+iMp28KLP93NYDkg3\r\nnHPzu3+/63fxIgYaqXMprpHr5CFoaei8AMlMioZA/8G8jpvhC8OGjYJFyTldIl4y40L51x08DHzJ\r\n7cTYnTB3jD+MmRXfZQKpqXy5EqkLcStikLNGQ05cCwmHnxfCSHWOxrJZIxqps5e83a3iqKAgFz78\r\n8
APmFr300otw8GAGPgYQr4dG6KyEkYR+HI+T90Mv6lx//XXMOcLjgSAIiiOk250jKo7Ag2ukNdSd\r\nVmaNWAmDHqlrF5G6hiOdE0e2lRM1QTRxbjTEroyE0IljmIgJXGnrEuESO5EKr/GQpr0vE0J8fcB3\r\nfGyXiaP6sjXgNLhGk7g4qvzM0FLnc5r8vx7zgaFHr4GEyueEazRWFDEEskidvZucoy1bNsKLL46E\r\nyy+/nOX06dv4u4/0F+iMUUfiiH4cj5P389BDD8LIkf/EY4EgCIojpCdmjnRhpJUwMGFEK7zVeSPV\r\nNXKfNXKdyOmkOEqB8b5cGM2KN7lEeTmQk9c1wiU+ZBj4+IZATjfG9upLY7lrRFvqKoLd67srJoC9\r\nLIgJI58WQgOh1geGVF4NW8ue1YoYaKTOXvJWl4gjmsVfujQCXn/9Nbj22mtYfO7dd9/BHUYIOkeI\r\nV/LRRx/Crbfeylrq8HggCILiCOkRcUQjde12EamzH9H3Gp2qNJUwqOKoSHONeH1358RRTjyPuw2b\r\neAYHJzMeJo7QY3e+IyZCfKbuAs0iHxsVGgmLJvrrLlRkMvt4XOgI/fMII0LjtM8ZMSNO+zfy0mIh\r\ncJiM9Q2D8RPHwODBYyA+p7PiaK2y10iKI2MRg738I10Y1RGqCBWEIh8YWnQ1JBQ/zSJ15yKOMjLS\r\nYfXqGAgNncq2xNM/IH70ox/BnXfewQTR5s1x+HuO9O+Zo7xsnDnqx6xYsVysGkjB44EgCIojpKdm\r\njoQwYg11qnPEI3VafbfZNTqZb6jvpruNOiOOMuNCmBgJicvs4H7JEMgEywiIjEuG5PhFMIK5TYGQ\r\nnMfFUagUNUTMLFoZCeOH8Y+n0H8jJQ5CRvmSt0eRj62EuCQbj9UNJmJJE2XJMEb8G4vikyFp5SwY\r\nJkTSysyzFUe6a8RKGMplQx1vqZOOkSqMfAoIOY
QsHxiS+UvYmv8U+3mEh8+BWbNmwrffhsH06dNg\r\n9uxZMGVKCHzwwTgYOTIAHnjgfhg0aBAMGHAp449/vBWefXY4BAd/CmvWrITCwlz83UYuKGgrnVkg\r\nHf6//xeKyB/WeHy8F+p20xnJ6OgoPB4IgqA4QnpaHNUZ6ru1WSNDfXfHkTrXiWwijnLP7ByJooTQ\r\nDsSRFFATYzOVz5PvE0KHiqFhIdpMUXwodZAGa8LGPVbHxdFgIY48/xuDIfZsxJGM1LntNpqg1Xcz\r\nYVRNKFeEUTYXRj7pRBwd+CUk5HFx9PTTTzOeeeYZGD58OFx88cVw2WUD4Oc//zlcd92viTC6BYYO\r\nHULu83d4443RTDRR8fTddzPZHxG0yYk6Svj7jVxoDhKN0Mk9R6OeG84eH3hsvBNaIHPzzTfBxIkf\r\n4/FAEATFEdLTsTp18asijk5ZNdSprlG+VsRAXaPOiqPMWC5KxndQvJApREq0TX9fXvJcoziiQidE\r\nj8jFUTHkM0wTNnEhg5k4yuxQHPlCZEqeEvk7B3FUaZ410p0jO6vvDtIdo2KjMBqS+StIyP872Ev+\r\nA/bif7Ofx8KF82H+/Hkwb95cmDt3DmzfvhXi4+MgNnY1i5jQ/UTffvs1TJ06mWXx33zzDRape+KJ\r\nx1ic7oYbfgNXXHEF/Nd//Rdcc83VcMcdtzMhRWN2YWEzIC5uHfnD4xD+/iP9GpstjTmrOGvnnfz9\r\n70/BU0/547FAEATFEdIbzlG9pWtk3G2k1HeflLuN8g3CqP3EQSKODp1RUOSlzGVzQD7+oYpwMQuo\r\niSJ6l2MSLiZxpMwtnZs4oiJNd45WhvgbvkbnxFEI2LXdRnpDnbbXqGy8m2M05NCvYGvh06yIwVHy\r\nFhNG9pI3u7StjsbrkpO3QUxMNEyfHgpvvfVv1lbn6+sLF110EQwcOBAef/xRCAoaz/YdYRwP6W8
E\r\nBr7N/sjGY+FdTJr0Kdx0043MPcLjgSAIiiOk550jpb7bUMTAInVWJQzUOdLru2mkrl0TR7mdEhXR\r\n40XRgv9EiE1Og8xMG6QkxcKMwFEQSsVPTjyMoB8fNhHi0jIhMy1OzBSNEGUJnsXRyk6Ko6K8JBjF\r\nZowGw/jQUBijFDN0Xhytca/vLp8g5o14pI7uNZLCaEje1bC1aDjYS/leI7toqaPOkaPk3z2yBJZS\r\nXl4MiYlbmJP06quvsKjeJZdcAkOG3AMTJgTBrl078PGBeD10N87PfvZT2LRpAx4PLyEqaimbM0LH\r\nD0EQFEdI7zlHBtfosL70VRYxSHF0qljfa9SWz5a+MmF0Mps5R64TWdBQc6iTNdh5EDsjkDtIBoZp\r\nS2BzkqNFCYPAdxREagti3cURnznyh9gcRSwN7kAcUWxxMHGUPwz29QX/8bMgMnSUYW6pU+LIYukr\r\nd414pI6Ko6GF18DW4ueIGHoPHGVjxW4j3lDnYJG6NwljekwcWUErwOfPnwsBAS/AlVdeyYoeJk+e\r\nxP7AxMcK4q18/vkUGDr0HjwWXkBychJ77qFuNx4PBEFQHCG96ByZl76aZ43K2OJXlzJvpM8a6a6R\r\n60TmWYgjudcoE1JSUiAtLQ3SbDmWIiozM5OR1w17ivJyjP/W3FE+psWxnRRHpqWvdkUYOco+IKJo\r\nHFv66hCLX6lz5DC5Rr0tjlTKyopg2bIl8MQTj7O5jf/8503Iytrv3b/v5Odb/8rLUE/+fw4TKsjr\r\nFbg3pd9TUlLAdn2tXPkDHo8+TE5OJvzmN9fDF19MxeOBIAiKI6T3xRFzjmSkTq3vtnKN6F6jE4c0\r\nccRdo4NEIFFxlNNtC1e7HhtMZFXg/jAmMBD8hUs1Zm7yWSyBXQ12ZemrWt9N542kOHKUvc9dIyaO\r\ndNfIrrhGfUkcqdB4y/PPP8eu6NLZJW/9
Xa8f9RI00IpnQjmhiJBHBRI+D/R7pk//EgYPvhOPRR+F\r\nXoy57z4/ePHFkXg8EARBcYT0hVid7hoZSxjK3F0jpb5bLWJwHc+E9uMZcPSIN4mjIkiJi4TQkIkQ\r\nSMRR4PgQiI63ndXn15euYq6RXanvdnONysYJ50iIo5JAvYhBcY3sxW/0SXEk2bJlI/zhDzfDO++8\r\nxWaWvE4cDbgUaoQwKiRkEGzUQcLngX5PaWkhDBx4Lfzww/d4PPogY8a8DnfdNZi5fHg8EARBcYT0\r\ncivQJHCdrtGLGE7LIoZyTRjRhjqthKHNVMRwkouj9hNZRCBlQHP9Qa8SR+dLU+lSpb57grGlrnw8\r\nEUbvE4E0jvAei9Ops0a0oY7NG5Vw5+hE/pt9WhxRiovzmbtGm6S8rd2ORumkY0SF0T5CyqWXwurV\r\nq2HatGnssUCPP9K90OM8bVoorIheDAcPHuixnz+tv6dV9/i837eYOfMbtnKAlvLg8UAQBMURHoRe\r\nh/6R0lxfoDTUVRlb6tqMkTrVNWoXJQzUNaLzRq7jB8DecgCKiwovEHGUD23ln5sidaprJMXR+/q8\r\nUck7TBw5St82Repeh/xd70NwcHCfFkcSGoEZOzbQuxykV17WHCMqjHYTlt15JyQmJkJLSwu0t7cD\r\nvnT/Cz3O9Hjv2rULpk6ZTP4o7plZNupK/L//9//Yni987u8brF+/lu1kS0jYhMcDQRAExVHfYPny\r\nZZCYsA7AzmeNeKROr+92qfXdFq4RFUd01qj9RAa0E3HkOm6Do0eyLghx1FAaoyx+1Xcb0fpuh6GI\r\nQZ01ekcrYlBb6hzFb8Di+Z/D9OnTvEIc0T80f//738OcObO85/e9MBfyiUBKH3Apc4yW3303ZB84\r\ngGqlF19ycnKYm9RTDhKtqff3fxKf+/sAe/fugV/84hdsqTUeDwRBEBRHfQb6Rwn94yQ7c
6e22whO\r\nl5t2G/GGOpd5r5EijmikznV8PxFINkI6E0j910HKF8JInzWys4a6IOYamVvqZKROzhppRQzKrFHc\r\nCh43mj9/vleII0pExAK4+eabvPL3nkbpqHOBL73/sjU+FpYti+yxRjTavpiWthuf/3uR/Pwc9txB\r\nF1Dj8UAQBEFx1OegsZYpUybDtsQN0FR7CFwsSmc1b5Tv5hq5hGskhRF1jlzH0qH92F6wt+yF5roD\r\n0FCTAQ2HJeTtw/sJNqivTocGxj7BXkEaIRXqq/ZAA6G+KoWwm7xO2QX1lTuhgVBfmcxoqNxBbinb\r\nob5iGyFJkEjYyilPIGwRxAs2EzZxyjYS4ggbBOuhvnSdIJawlrxvNTSVLYNTFaGsvtt+JtdImTWS\r\n80aqa3Qi/y3I3z0eFoZ/zgTq/Pnz3IRRXxZHFF9fX6/cSTJ9+nQW7cKX3n9pbqqH0NAveuxn/9pr\r\n/2LV9Pjc3zvQKO5DDz0Iw4c/jccDQRAExVHfdpDo1dvQ0FAcGu9BQkJC2B/qVo4RJSoqsk//3rzx\r\nxmh49913vLKIBGeM+s4MEn0srFu3Fvbv39ftP/utW+Phqqt+zhrs8Lm/53nrrX/Dbbf9he2Vw+OB\r\nIAiC4sgroH+kWP2hjvQ89GfRl39XlixZBEOHDvG633FWYY8vfeZFbWncvj2x23/+f/rTHyEqaik+\r\n3/cwYWEz2ELejIx0PB4IgiAojrwHevUWhUnfoCeupJ8rlfk5kP1xEEy74nJomPkNexvFUXe8tMGm\r\nsCAYHRgGuW2e7uOAsiwbpNqyoNHRlV+358VRT/zef/LJBBgx4jl8vu9B1qxZCZdffjlz7vB4IAiC\r\noDjyOujVWxQnvUtPXEE/V2ri1oHjqqsAfHw06Ns1XlKT3H3iqBUi/H3YLigfnwCwtaofK4PgQeJj\r\nARHQehZfM9yPfp4/pHr8pEYI9e
FfO7m1K79u74ij7nZMd+3aAT/96U+9cpmxN7Jnz052vJcujcDj\r\ngSAIguLIux0k+kcKnXtBsdIz0GPdU7MX5+MYmYWRKpC8wUHqGXHkA4GxZfpHbOHa+338womcOduv\r\n6S/ElgM2BQeQtwdBVK5Dc46yEmMhKiYRqh3n+nX7jjjqiVm73/72Bti0aQM+13czeXnZ8Lvf/Q6C\r\ngz/F44EgCILiCEH6HzRCZyWMJPTjF7Q4CtDFkY9/uHCIHBAbNMggjtj724ogOMAf/PyDIEtE23Jj\r\ngsHPzw+CY4ssRUxuVKD+dQYNAv+gGHKPNtgUGggBo0NFRK4VYoICwC8gGBJTY2E0c6wGgd/oMMht\r\ntRJH/P7+/v4QllitB++KYiFgkJ/hfT0hjnqipfG5556FyZMn4WO6GykrK4J77x0KI0f+E48HgiAI\r\niiME6Z80fTCuQ3FEP37BO0eD/MFfCJJYqitaU8GPHJtBfoOM4qjVBv4+xmhbVrg/u49fmM1SHFUn\r\nR7Cvxe4zOhjCY2xEerVCuL/6deTbHP/Ro7XP8fGXkT6z6Botvrcw4Wq1Qczonond9YY4Cg2dCs8+\r\nOxwf093IqFEvwZAh97Cl0Xg8EARBUBwhCDpHF6o4CgiHTeFcbARE5ULZpiAmMmI2hZucIxsE+Bij\r\nbVnhAVzQeBBHVLTI6F64tJvc7qPH+8KSuevTlhUhxJIuoAyf05isCagoalpVx5q+j/4ljuh+rjvu\r\nuB0f093E5MnB8JvfXA/Z2Rl4PBAEQVAcIUj/pTIvG2eOziSO/KOgrnoTDPLh7hG7DdwEdblRZxRH\r\nuRFnEkeK8LE1nuE+AWCT+smRpf1bluKIRv8CubPlFxoLMcF+5HU/SG6EfimOduxIhIEDB+Jjugtm\r\nEOkFEeoYy9bKyMglrICBFl/gMUIQBEFxhCD9HmyrO4M4IuKnjfzH2+CkkGkFR26
Ex1idjRUp1EG4\r\nmFnqSByFd9o58tfEkaMoSmvRy2qzLmRozVJKI5hISu6VQoaeEEd0184VV1yBj+cufh5ou/JK+Nul\r\nl8Lq1TF4jBAEQVAcIciF5SDRK8XTyB+YdN8R7jkyiiOqN8piZXnCaChi0bZwU1tdGQRJIRIQCKMV\r\nMdVRrC5KCqigMNiUnMtmjjy5S4MCQiExdRMEya8dEAMOj2111XrduI8fJNZBvxVHqam74Be/+AU+\r\nls/DMfLkIB8bMMCrng8QBEFQHCEI0mXQNqrFixd61ffc/bE6GZurg6zUVMgqqhPOTITbnqOsqCBN\r\nEA0KDIeoUB6rC4jIMokjfW9SnU0vZfDxCSVCy3wfXRz5B/jpblBAGBS1gcevy2N9fFZqUFBir1V5\r\n94Q42rhxPdx88034GL6AZw8R5EKgpKQIVq9eBdOmTYNJkyax51uke5lE+HJKCPwQMRsOHjyA4ghB\r\nLjTGjg2E119/DcXRebw42lqhsfFsK+HayOcQWdTm6GCHkYjQka/f2tqZr18HYf6yZc/Rr8XRrFlh\r\n8MgjD+Nj+BzpD62VCNLvHd7KCvb8mrh1K7QcPQrtp08DSE6dIueGNs7JkwAnTnCOHwc4doycRsg5\r\no6VFp7kZyEkHgHwdaGgAqK/Xqa0FOHKEU1MDcPgwp7oaoKqKU1kJ5JsCKCvjlJZySkoAiosBioo4\r\nhYUABQWc/HyAvDxObi7AoUMAOTkA2dlAVAdAVhYnMxMgI4Nz4ADA/v0ANhtAejpn3z5OWhpAaipn\r\nzx6AlBTOrl0AO3dykpMBduzgbN8OsG0bJykJIDERgBxLRkICwJYtAPHxAJs3A2zaxNm4Edo3bICW\r\nNWtg1/z5MDUkmHx7+1EcIciFBG39+v3vf4/iqE+9tEKYH4/GnU0Nd5Yog/AJjAVHD363vSGOhg9/\r\nhjWq4WMYnSME6Z+OUTFM
nToVcqiIcDg4dvvZiyMqipqauDCS4kgVSHV1HCqQpEgyiyMpjCjl5bpA\r\nosJIYhZHVBhJcUSFERVFUhh1VhxJgUSF0d691uJo926OKpCkMJLiSAojKY6oMKJQYWQhjiAuDoAI\r\nJErO0qXsHNdZBwnFEYL0E2g8KSJiAYqjvuNFQVZiLBGuidB5A6gNbJvo58RCVp2jR7/bnhZHhw5l\r\nwYABl5Jz5R58/J7HzKG3t1YiSH9m9erVsIv+oe9yATid1uKIogojKookqmNExZEUSFIcSdfILIyk\r\nc0SFkVkcUWEkxZHZOaJQYSTpyDWS4ohiFkZm50gKI7M4kq6RFEZSHFHnSLpHUiCprpEURtQ1Up0j\r\nChVGEiGOYP162LpoFixbFoniCEEuJObMmcXcI29Z9kj/GG93NBHIE73jKLTbGwjkSd5RR26PQPvp\r\nGgJ5cj9dTW4rCRXQfopSRigllICrrRja24oIheA6mQ/tJ/MEh8B1IhvaTxwUZBIywHV8P7iO2Qjp\r\nhH3gak0jt6mEPeT13YQUaGe3O8HVkkzYQdgOruYkwVZwNm0BV1M8YTM4GzeBq3EjIY68vp7criPE\r\ngvPoWsJqwipwHV0JzoYYcDWsILc/gLM+mrCc8D0465YRIglLwVm7mNxSIsjrC8F5ZAFhPnl9HrkN\r\nJ8wBZ81scNTMIswE5+FvwXH4G4bz8NfgqP6KMJ28Pp3cTgNHVSjhC3ASHFVTCVPAURkCjopgwiTC\r\nZ2Cv+ITcTiRM6HFx9OGHH8Bjjz2Kj93zJHFaKFT/n//jta2VCNKfmT59OrRQQUOFkSqOpECSzpEn\r\n14hChZFEOkcU6hqp0TqzMPIUqVOdI6tYnSfXSHWOOorVUWFkdozUSJ1EjdTJWJ0qjjxF6lSBZCWO\r\nqHNEXSPpHBFhBOvWQfPqHyA09AsURwhyIVFeXgxPPPEY3HDDb7zHOXI2a
+IIHFQc1ZGTBhFHp8kT\r\nvJ2Lo/bTVYo4KtPFERVGp4qIKCogr1Pyyeu5ujA6mU1us4ggohBxdJyLo3YGFUd7oZ3gaiXiqHUP\r\neT2FCKFd5PVdBmHkZKIoURdGzVu4MGoiwqhpIxFFcUwcuRo3EDEkxdEaIorWEDG0ikDF0QoOEUau\r\nBl0YueqXcWFUt4QLo9pFDAcVRrVEGB2ZS4RQOHmbiyNHzXdEIFGIQCLiyFkTRm6/ZjgPz+DiSAgj\r\nZzUVR58TQURF0WQOFUaVXBg5mDD6BOzlE3pcHCUkbIbLL7+cnP+24WP3PKA7jH72s5/C9/Pnuu05\r\nwuODIL0PLV9ol66R2TmSrhEVR1IYqc6ROm9kdo4oHblGZueICiOJ6hzJWJ153sgskKQ4ks4RRbpG\r\nVBhJ14hCHSOreSPpHKmROjVWp84bWblGEnXeSMbqpDBSnSMqjqgwEuKoPTaWnefWrVtLvr19KI4Q\r\n5EKhtLSQuUe3334bea7L7/viyNFkdI3swjViwqhaUMUdo9PlujhqKyG3umvUrrlGXBy1n8whwog6\r\nRlnMNXIRYdR+/AC5tREUYXQsldzuYY4RE0WaMFJco5ZtmjhyNSUQthBhtJnccnHkauKukS6M1hqE\r\nkashhjlGLuYaCWFUH8XRXCMijmojBAsJC4ggoo7RPCaQnDVzyO1sIY5mcmF0OIxgdI10x4i7Rkwc\r\nUdeICqMqKpCkOPpUwF0je/lHPSaObLY0uOiii+Dbb7/Gx+x5kJ2dwS6ETJ48CY8HgvTl85w5Umd2\r\njc7kHJlnjuSskad5IytxZI7VmeeNrMoYVOeIQoXR2ZYxWM0bmWN15nkjszg6k3N0hnkjTSAJcSTP\r\nb9u3J6I4QpALBSqKHn/8UfjDH24mzxsb+3isjggjBxdGhkid5hoRcXRKdY1KNdfIpQgjlyKMZJzO\r\npQmjA5prRMURd4
1EpE64RjxSt9voGjVvMwgjLU7XHM+EkZNF6TYQQSSFke4asUhdg4zU6a4RFUcu\r\nKY6kMKpbAg4mirhrpMXpqChizpGM033HInXUNdIjddQ1mqFH6pQ4nUEYEewyTlf5mXCMiDCirlH5\r\nx2AvC+oRcUSdIlo2ERo6FR+r5zXkXQBDhtwDo0a9hMcDQfp8QsLZeXFEhZEqjmScTnWMPEXqPDlH\r\nHUXqVHFknjeiAkmdN1IjdaprZI7UMedoD2waNwpGvzAOcndblDGorpFVpM5KHHkSRh3NGynOkVkc\r\nUTw5SCiOEKTfZp1D4corr4QRI54jz0E7+6hzxON04KDiqJbF6agwArs5TldujNMxYSTEEY3UCXHk\r\nOpHDXCMWqaNxOnXWSBNGumtEZ41YnI4Ko5adFnE6QgufNXI1J7BIneYaiVkjFxNI64gg0uN0LiaO\r\nlFkj85yRFqczRuocwjWikToHE0f6rJEhTnc4TJs1onE6Z7XFnBGL003RZ408uEaOio+JQOp+52j2\r\n7FksSjdp0qf4+DxPAgJeAD+/vzGnGI8HgniZc6RWeVuJIyvXyOwceWqqY1XeRRDxsL7MnHMjBLw3\r\nE6qLFdeoM011ZypjsBJHTCDtgvDb6L97L6Tu2Oe5qU66RlZNdWcqYzhTU506c2ThHFFoxA7FEYJc\r\nYGRl7Ye33vo3awV78sknYNmyJeT5sKhPfG8DBxZD0tYmNmdEhREIZBEDF0dVSgmDiNMJcSRnjahr\r\n5LKI07EonVLCwIWRcI2UWSMWqROzRu2siEEtYTDOGqlxOtU1osLIJeN0oohBiiNnvVrCIOJ06qyR\r\n5hoZ43R01ojPGc3WHCMHc4yEOKrms0aqa+Ss/lJ3jYQwGnry17D1yChFGPESBrt0jcqDwF72YbeJ\r\no/Xr18A99/wVfH192dJXfFye7wzDpyw6m5eXjccDQbxFHMkab/P
MUUeuUWedI4MwohXehUIc3QjB\r\nX8yA8HGvwiAhkvw+3+LZOVIdI1UcSWHkad7IHKtjkbqdEPE3Lo5sVBzt3QObRj9M3r4Bon5IcZ83\r\nstpx1NlIXUexOsU1grVr3c5zUVGRKI4Q5EIlN/cgm0344x9vZW4SvfI8f/7cXv0Dy8fnNOEYDB3S\r\nDEkJ9VqcTneNpDByd42YMKJzRm36rJGLiiPqHJ3IViJ1nShh8NhOJ+aMpGukzBrpkboN5HYdEUV6\r\nnE66RnzWSJYwRFu4RmoJgz5rJIsYOFwcuZUwUGFUPUMrYXBYxemEY+RzmpygjvnA0MaBsLX6JSaQ\r\ntEidcI0c5V0rjoqK8lh7IhVFv/zlL9kuI3Q5zp+lSyNYAUNKyk48Hgjizc7RmeaN1BpvirnGW43U\r\nue03kuLoIcgq4011qe/dyMXRZ3GaOHKkr4ewVx4QzpIvjB4/FxoVcdS4bjYEPXmn5j4NumM05O4n\r\nwsi2CYIfvw/87nsVstJ5jXfu9DfB7/bbIfibdSJWtwsi7tXFUW7I87qLdcMN4P/SVGi1Ekdnu/zV\r\nqsZbukbSMeogVufpPIfiCEEuwIarCRM+YjMLl1xyCQwadAu8+uorEBY2gzz3bGGtdz0jjo4RWggN\r\nhFoikqohaUuVJozAJI5cimsk43QuU5zOJWaN1Dhd+3FZ3b1XkGqq71Yjddv5rJGI0zlpAQMTRvGW\r\ncTrP7XQxXBxR16hBuEZ1UW6zRkwU1UWA44jqGulxOtlO5xAlDA4Rp+PtdNw1YpG6qi/J619aiyMi\r\njHxaCA2EWiKSKq+FrRUBmmvkYM7R+PMWR3Rv0XffzYRnnvkHXHHFFfDXv97Nfqe8pVq+r7N1azyL\r\nJa5ZsxKPB4J4kzhSHSOK2lKnNtWpwsgqVqfG6TqcNyrSxFHy/gKo2xYNgXdzYRK0NIW7RtnrIUCI\r\nleCv50H4
qMFcPE1Yy8VRlvLxaRGQPG8aBL34HhdHaT+Av49YcJ7Km+qyJvjxz38/ytI5qp7/CfhJ\r\n9+qp0RA+dTE4OjNvpDbVSedI3XFkdo3UOJ3qHFEsnCMURwiCuFFYmAurVq2Ajz76kJU4DBw4kDWJ\r\n0QgUjeHRSN60aV/AihXLyfNVEnnOzO1CcSSFUR2hilBBKLlq18kAAFpDSURBVIJ7hxQTkVTm0TXi\r\ntd3qnJFwjOiskaGh7oAmjmQJg3SN2qk4kg11plkjYzudrO7me424a8Qb6likTps1kpE6fa+RMU7X\r\nkWukOkbzRUNdOCticFjOGn1t2VCnVXerO40qg3VhVEeoIlQQiohIKiIiqeQFFqlznKU4ysnJJOeZ\r\nVWyu7YUXRrCYFxXa993nxxzKvXtT8PHVhWRkpMPVV/+KiU08HgjihYUMVmUMcvmrp6Y6c0udxDxv\r\n5FEcGRn9re4a5Ya9wN//wCdQlHUI6jZ+x6N3g4OhlbpHWauFAPKBwM9mQ9GuA3qkzrZCCCc/sO3J\r\nZM5R1oTH2H39PYgj2LtTOEk+EL5su3ukzkocqe6RpwWwaoW3p6Y6GatD5whBkHOloOAQeW5Zx6qW\r\nx44NZE7A4MF3wrXXXgP//d//za5e/+Y318Mdd9zO9ir985/Pw5tvvsEE1tSpk9nnLVgwD3744Xv2\r\nB/TmzXHkuW0rpKXthvT0NPI8amM1xNIxUoWRj08BIYeQBUOHZMG2LYVus0ZWDXWaayR2GunCaL/R\r\nNWpVqrvZnJGI1LVyceQUrpFTi9QZXSO206jD6u4YgzDS6rstXCOHRXW3LGGQDXVOU3U3jdPpwmga\r\nb6dTZ40q1Ya6EO4cCcdIFUY+BYQcQhYRSVnXwNaCEeykMXv2dzBz5rfwzTdfw5dfhsJXX02Djz8O\r\nYj9f+rP+85//BL/4xS/gxz/+MXMchw9/ms3ArF+/ts9Xx
3srNKJ4221/YRcq8HggiBeLI4p5v5Ea\r\nq+vINepMjbe2AFbG6u6GqOhICLpRiiN93ij3mxfcxBPnHagW80a5YW8bP3bffyArJRsg/QddHKXy\r\neaPcSUIcffC9ZawO9m7XxFHY4i2eyxg6EkZWrpFECqMOyhjQOUIQpNug4oZGfKj4oQ1kU6aEwAcf\r\njIM33hjNXATqOA0bdj/cffddbMaJulDXXXcdmz356U9/CgMGDICf/OQnQhhVE8oVYZTNhJGPTzoR\r\nRxmQFJ9vWPiqttOpC1/VnUbtIlIn9xoZXCMtTmfea2Q1a5RgcIzYTiNt4et6Q6SOzxrpe41YQ11D\r\nZ1wjsfBVcYxYO90RWd89y7Tw1bjXyOlx1kjsNKqYxIVRNaFcEUbZXBj5pPvAkIxrICGfi6ORI0fC\r\nyy+/DK+++iqMGTMGnn767/Daa69CUNB4Ipq+YS4jFbk9Fb1EStjP4JFHHsZjjiD91Tk6034jitk1\r\nsipj0Cq8iTh6SMwclVaCY9tXmsAJj8syOke+70K13HFkXv5Kyxiy0yBr2TQtYucXFAOQtkK4SveB\r\n7QAVR9sg/DEf3Tli+412GsVRGrlPZ5wj2VSnCiOreSNzrM7KOTJF6lAcIQjS59Edo2KDMKKOUVJ8\r\ngbLTqHOuEdttpLhGanW361iahWukxumM4sjZpEfqnKY4nVNpqFNdI32nkVWcTrpGkZ4b6mpFQ13N\r\nHMNOI33W6GsPC1+5MHKyhjrVNeLV3ZpjVGwURtQxSih4HhxlH4C9dFyPLYFFOg8VpTfffBP5OyUH\r\njweC9AdxZG6pk6hNdbKMQXWN1GidpyIGudtIEUep+XzHUfJ7dwmB9Hew5fCZIxmb83t+PGxavhw2\r\nzfwCAke8D7kH+cxR8HOvQ0xENBTFR0PwHcJ9+poIkINbIEh+7mMBMPp23V3SYnXpybo42r6Xxeqi\r\nRN
TP/6V3YdOc5Xzm6HzKGMxNdVaukRKpQ3GEIIgXiCOjYzR0SC4kbSnhe41OW80aFRJRpLfTuVV3\r\nK46R0TXaK1rq0vTq7tbd0K65Rts7dI2cjbpr5Dy6Xlv2yiDiyNmgV3fLhjotTifFkYjTOWoXc9eo\r\nToojvbrbfaeRcdbISYsYqmdoJQw8UmddwsCgC18rPnNzjIYeuha2Fr3AGuoc5ePBXvY+EUjvozjq\r\nYyxcOI9FGPfu3YPHA0G8vZDhbJe/SudIiiRPZQxWzlF1gRBH/wCbEEdQkgSBMh73whxoKy2Ftj0/\r\nQNADvqZY3cuQlZXPxNFoU+TO/8UpUJbJ9xtlffGq3mIXMAGiAh9lrwd8toI7R5o4ekQ4R2lQt2Si\r\nVsrg4/NvaPRUxiCLGKxidWZxZF7+ap43kgKJOkc4c4QgSN8XR1wYDR2SD9sSytx2GmntdKekMDIW\r\nMchIXbtwjdQSBhdrqNtnjNO17jlDCYPiGhFx5FQjdY0bDdXdcq+R3GlEXSOXuYSBzhmpcbraJcI1\r\nUooYZKSulrfUOWqUhrrDMw1xOl7drbhGijBymoVRZTDYiTBi4kgIoyF5RBQVB4h2Ol7CYC/7gAkj\r\nRxk6R32JhIRNrPGPznLh8UCQfiyOZKTufMsYKJpzRKiuZhXeTBhVVHA87Ddqy7RBIxE0rdm5bjuO\r\n2tLToXXfPmjdn6UvgBX7jRz7UqExOUXfb8SWv+4X4iidoy5/ZQtgd0AjETWt23ZalzGcyTnqzH4j\r\ndI4QBPFWBg7cSURRpb7w9VQld41OWbtG+l4jXt3NhRHfaSTjdKpj1C6XvSqukbbXqMV9r5GhhEE0\r\n1GmukYjTuRhizqhB7jQS9d31K5S9Ru6ukT5rFAEOIozYrJHYaeRwK2GgkToep1NdI7rXSKvuppE6\r\n2VCnxekma3E6R+VnbOHr0EIiikp5dTffacSru6U
wspe+x0Bx1Degi5tpMx2d8cLjgSD9JFZnnjWy\r\nco6s5o2s9ht5co7YjiNFHFFhJKHCSIojVSDJeSM5c9TR8lcpjKyWv1JhJMURi9UpwkiKo9RU4/JX\r\nGauTs0Zy3qgzLXVnK47QOUIQxFtOGlQYwelqcqsKo1KPcTpewiAidWLhqxapEwtfXcdslgtf9RKG\r\nnWLeyKq6my97NS58VVyjo3zhq3SNXGp1txBGliUMMk6nzRktUuq75yl7jUwlDGLWSMbppGvkNMfp\r\nKo0lDEwcVXzKKZ8IdrrwVdtrxON0DsU1speORXHUB6A7oe66azCMGfM6Hg8E6S/iqL1dnzsyzxx5\r\nco08LX81O0dSFJldo7NwjgzCSBVHZoFExZHiHDFU14gVMVi4Rqo4oqjCyMo5snKNOnKOOlr+Kl0j\r\ndI4QBPEecVQlhFGVaa+ReeGrlWukV3fLha9qOx0rYTgmSxj0WSODa9TsHqfjrpHSUCd2Grm0nUZr\r\ntDidvvB1hVLfHW1yjSINDXVs4auI0zksFr6qJQxOpZ2OukYO1TVSq7uVvUZcGHHXyFExkTBBcY0+\r\ntHCNxoKj9F0UR32AF18cyXZFlZUV4fFAkP5ynnO2EJqJQGqCdsdRAhE3jnpot9cSjhCIoLHXkPNg\r\ntSleXsrOhS6Lxef6zG22tt/PdVxvaXVpyYk09/Nf605obzUtPWcXCPXzH78oqC87Z1Fyt3ZWcVGw\r\nQUlL1IvzXq2MkNOkhKl8SJ73tIuBM0VSQp7vxLnOonhIvxAYolwEFOc67Tz3EYuO03OdLByi5zrH\r\nWVwERHGEIEjvXVGjJwMZpzutu0YuDyUMLm3Za7ahoa5dnhTMrpFh1kieGBRhpLpG2pyRjNPps0ZO\r\nRRy5LBvqLEoYVNdI7DRyKAtfmTCSDXWsvtu6utvgGhFhxF2jUH3WSNlpxF2jz8DOThb8hEFdI7s4
\r\nabBZI+Ea2cvGaa4RiqPe54svprL9YXTBLh4PBOlPsbpWIoiIOHI0ERqJGNLFEVBxxKLlaoKiTIfO\r\n3p4qJudEscaiLV9bY2FvzYaW+kPQcIRQkyPIVjhIyOIcziRkCPYz6qtt5JZQnU5e30duKXvJ62nk\r\nlpIK9VV7oIFQX5VCbncz6it3QUPlTnKbTG6T2W195Q7Cdk7FNkESIZFTniDYQohX2EzYBPVlG8nt\r\nBmiuiIFTVUQsiV1+fMH5Fzw6Ti8CVunnOzZXK+LjMh3hdp4rpec5ehHw3bM6z6E4QhCkl2aOiiFp\r\nS60Sp1Nco1Oqa1TgsaFO7jQyu0ZWcbr2DosYRKROcY2c2k4jXsJgXvgq43QuQ5xOXj0zLnzlsboI\r\n09WzTsTpWH23aaeRx4Y61TX6lJwsVNcoiFOmnjDGsStp9IRhL3kHxVEvEhMTDVdeeSUkJyfh8UCQ\r\nfieOrF0joM7R6RrmHElxBFQgyXi5tsbC7BrlQmNtHhQXFUJRUVE/JB8aymJ5SkI935nj44aExERD\r\nQoIXDr0vznPcNbKXBKI4QhCkr7fVnSYcg6FDjkJSfKV1CYNyQtDidCeztQgBb6fLsNhrtFfZa7Tb\r\nsoTBqVR3O8WcEXONRJxOb6eTrtFaFilg4kiJ1FnuNTIII+EayTidmDOijpEsYbCK1LntNRJxOqdW\r\nwqDHC+wVxhIGfqJQ54yUmEG5MVJnR3HUq+zZs5MtR46KWorHA0H6Y6zO0UzwEKmTc7daIZExXm4V\r\nqaPCqH+KIiMNZWuEMJpqmq0NcRNHajpCxul4MmKcONed3XkOxRGCIL0kjo4RWggNhFoikiqISBKu\r\n0akiXt2tNNS57TVS4nTtLGNtvdOo3WrOyMNeI6cya8TFEW+os47TedpppETqlFkjT64RjdOx6u6a\r\nmR53GunV3aGKY6TGDPiVNLssYTDFDOSVN
NU1knE6R2kgAcVRb1BQkAs33XQjBAd/iscDQfqtc8Tj\r\ndECEERVH7fY6t0gdmOdu22SCQsbpeILCcSy3HztGRoqL8uFU5ddK8ZA8132mJCTU2dqP3Pb3yVmj\r\nsz3PoThCEKSXxJEURnWEKkIF2300dEghEUkFhoY6OWukxul4dTdvp5OzRu3H9SIGt71GrcY4nVbd\r\nzZrp4pWlr2Lhq6mEQV346mrQZ41U18ilxulqlRIGC2Gku0az2E4jpxhMdRiqu82zRl+YThQhSkPd\r\nZ1o7HT1R2K0GU8UJQ4ojeTXNXvI2iqNe4IknHodnnvkHHgsE6acUFxJxY2/hrpGYNQJHnSlOJ+aN\r\npDhqK9VKiVyKa+Q6eQhaGs7VNcqEuYH+4B84F3LcPpYGoSOGwfhFm2HuGH8YMyu+zwikpvLlSlIi\r\nxK2IQW9i1WeNjM6RjI4HntV5DsURgiC9JI64Y6QKI7oU1scnh5BFRFIGJG3OtnCNDmqROq2ZR2mo\r\na/fQzqOWMOg7jaRrZGyok5E6rYSh0aqE4QcL18i800i6RqK6+4gpUndE7jWaaWioMy989SyMrBrq\r\nPtEidfpw6oduJQx24RrRE4a95C0URz3MxIkfw80338TcIzweCNI/OX38OByrr4fjDUfAcfyIpWuk\r\nNdSdVmaNWAmD+9xtw5Fzj9TFhfqTc6svRKYZ358TH0re7wMzkvZCiK8P+I6P7TPiqL5sjVI8pKyq\r\nMETI9R1++qzR+6bz3DvkdXSOEATpQTIzbbBx43qIiFgAX375OXzwwTh49dVXYPjwp+Ghhx6Eu+++\r\nCwYNugVuuOE3bMElnbHgwqiaUK4Io2wmjHx80ok42g+Jmw6KnUbZepzuhHU7nV5byl2jdiqOWsRe\r\noxZRW2qK07FZo2Z1p1Gc0k63XhQw8J1G2rLXBmMRA6swrYtyL2Eg4shxhjidWwlD9deiiG
GGqO6e\r\n5l5lqmavxayRjNOxEgazMBLV3Xprz1hDEQONGqA46lmio6PYY4DOG+HxQJD+CxVGLTU10FBSArX5\r\n+VBfcAjaGsuFMKIV3tXGBeiaa2Q9d3s+4qgoLRJ8iQjyn2F0hqIDfcHHdzyk9cFoXX1pLD/fVenn\r\nO0N9N01JlAUZVlVoFwKVIoazPc+hOEIQpFPQBZXx8XHw1VfT4M0332Ci53e/+y1cdNFFMGDApXDj\r\njb5sR8vw4c+wJZaffDIBpk8PhblzZ8P330dCXNw62Lo1Hnbt2gHp6WmKY1RsEEbSMeJxukPWs0Yn\r\n1H0OSkOdttdICKMzVHe7lDidca+RsttBnTUScTqX2O2gttO5OpgzMrhGTByFGyJ1anU3LWFwqiUM\r\n1V/qJQzyClqV2tjzqZa/Vvca0SKGjqq7VdfIXvIfFEc9xN69KfDzn/8MVqxYjscDQfo5UhjVFRRA\r\nVUYGVKSnQ9HOnVBlS4PjR/K5MDKUMKjiqEhzjXh993mKo6IcmOHvYxRCefEwQhNMmTBrxGAYMSNO\r\n/xxbHAQO82HOEnWdQqJTyOckw/hhvjBmVpL2deeOGQa+/iHa17XFhoDv4EBIzjtfcbTWGCGvdC9i\r\nsEvXqFxvqGPnuTJ+IdB+DgkJFEcIgliSlXUA5s8PZw7QrbfeCj/60Y+Y8/OPfzwF48aNhdmzZ0FC\r\nwmbIzT14jrE6o2M0dEgOJG7OZSUMhkV3J9yFkUvMGnmu7uYNdby+2+waJRlcI726W99pRIWRS8Tp\r\njK6RFEamhjqTa+RgDXV6nE66RnKnEavuPsxdI6da3a3uNNLqu01VpqK6W2uoq9BnjbT8NbuSpsTp\r\nTCUMPH+tu0YOFEc9QlFRHnssffTRh3g8EOQCQDpGqjAq2LYNcjZuhKzYWMjfuglaq7KtXSPDuZCf\r\nD89PHBVBWmQgEzqh8TlcxKwcr0T
tMiFksA/4TpSxumQYQ0URET3xaSkQGTJC3DeHiCjy/sEhkEnv\r\nl7kShgnxNDcljz3PzaUfHzEX8oq6ShzprhErYSiXDXUfu7tGym6jcz3PoThCEESDujo0EnfbbX+B\r\n//3f/4V77x3K3l69Ogby83O6eOaIC6OhQ3IhKT5fRAiM7XR8+zeN1GXxWSMtUrffFKlLc1/42mq1\r\n08h64SsrYWjaqO01orNGLq2Iwb2hTgojl6dZI7nTSKvunqtvBT8yR9kMPss4a3SYzxo5DZvB1YWv\r\npj0P2sJX6RhNsD5ZmFwjeSXNQa+mFf+H8G8URz3AyJH/ZI4rHgsE8ZaLhPshMXELc3rpBcEpU0LY\r\nOfH111+D559/Dh5//FH429/uhTvuuB3+8Iebteg4dYcHDBjAhFF1ZiaUK8IomwqjdesgPToacrds\r\ngOayDH23UQeROno+bDiSe35RtZw48CdCxjcwmr3NRMywGaKkgYujwUIcZcaFMCE1ZlYspCSnQHLc\r\nLBbLG7/SBimRY5gYis4kAksILsqoWSnkc+OYWKL3K+oKcSQjdW67jSYYlr5qs0ZlXBzJC4FSHNlR\r\nHCEI0lmo6KFzQn/8461w+eWXw6hRL0Fk5BJ29ac7/92BA3cSUVRkWPhqbKizjtO5tIY6WcJg3mmk\r\nLHttNblGLYprpMTp2MLXpjjNNXKahJHBNTI4RqprFMkb6mqtq7sdbgtfZxoWvnreaSRdI2Xha4X1\r\nwlcZLzA01JXy7LVdmTNS43SM4jdRHHUz33zzFVx33XXn7LQiCNIdMdc9bAkzjYC//fZ/WDLizjvv\r\nIOena+F//ud/4LLLLoPrr7+OiZ9HHnmYXeCgsfKgoPHw+edTYM6cWbB48UImnjZsiIVt27ayi4z0\r\n69JZ3CoijKhjVEyFUVKSJoyoY9RSmW3RUKe6RvmGBehdIo7kjJHPKIhPi2UiZkxk
itZoZyWOjPhC\r\naFwmFNmiYTB5OzA6iQmsYaErIZJ+3RFzIYm5Uf4Qn1fUNeKo0jxrpDtH+jnPyjUSRQzyXHcWFwFR\r\nHCHIBRybCwx8G6644goYNux+WLZsCZSWFvbYv8+W46mNPOadRrS+W3ONpDA6wMRROyOdCCIijlrd\r\nXSM9TmecNXI2JfBZo2YpjoQwUqq7ObGijEEXRy7qGtXzOJ1LukYWJQxOLVLHXSOH4hjxZa+ztYWv\r\nzppv2ZyRQ3GN9DidqYRBCqNKdeGrLowMO41Ea496spCDqXax78FR+rYmjFAcdS80fkr/yKIzd3g8\r\nEKR3SoPoouUJEz5i9fmDBg2CSy65BK688komfJ5++u/sfPj111+xwpQdOxKhoODQef+7BscoLo6I\r\npCRorT7EGuqMu42U+u6TcreROUVxkIijQ+ctOHLiZzCh4+vrw0RMbE6RtTiKncjuNzE207IaPJTO\r\nIvkOZveZlUzuH80dpMG08W5MZBcVMqwVMfLPjK6RaYefub7bruzwc1BxRISRveRNFEcIgnguVqBL\r\nJ6lLRMsTUlJ6pzGLiSNt6LTQNHjKTwZadbe218hYwiDjdO0UdacRFUbN25U4nbLwtSlB32lESxga\r\nzSUMazkNq41xOiqMGjzMGdVHcnFEhJFsqHOwAgZCrcVeo5qZQhgpJQysnU4vYZDCyBinU4sYzPEC\r\npYRB1Jl2VN0tr6RRYeQoHoPiqJvIy8tmV55nzJiOxwNBeoDi4nxYs2YlfPxxEDz22KMs5nbppf/L\r\nHKGXX36RJSXox+kFwm6fMxTCqHTPTjh+pADAXsPru7WGOqsSBnqxUK/vdokLhVwc5XaB6EiD8b7c\r\nCfIds8ggeFRxRIsX2MyRzwhYFJfCBGZS3EqIS+PzSkmzRgg3KRBSWHnDSuYm0feFxGV2kTha417f\r\nXT5BzBuZ9/iN09pYtRIGJ
VLnKEHnCEEQC+iV61tu+QPcdddgSE5O6tXvRRdHPE5nKGE4aeUa6Y4R\r\nF0d7tYY67hrttt5rpMTppGvkZMte9Z1GWgmD4hi5uUbqXiNa3U1njWRDXa0sYYhQGurMrpHuGPE5\r\nIxmp+0YrYnAa9hqFWrhGIRbxggliAV6QwTHiex6EayRiBvJKGjtZFPOThZ0II3vxGyiOugl//yfh\r\nueeexWOBIN1EWVkRrF27ihUFDR58J2tQpTvE/vWvURAWNgO2b9/aa9/bzjVr4EQtOc9pe40O60tf\r\n2eJXxTViEXPdNXKxi4R0AXq2uFiYBQ01h7pEdCTNGsVFTKzNszhya6szCp+8lEVsBmmYdn/hJvmM\r\ngeQuq/JeY7n01SGWnKuROn7Oe0+01OkXAh1aQmIMiiMEQYzMmzeHRehCQ6f2ie9n0qRJ5Mm/QFlw\r\nJ6+Suc8aaa7RMb7wtf246hqZFr5axunEwlc2a6RH6vTq7vXawldDCUNDJ1yjOjlnFOFx1kh1jZzM\r\nNZqplTAYZo0sdxqpNabB7gvwKox7jYzZa2vXyGFyjU7kY6yuO/jii6lw0003dvv8HoJcaBw8mMGE\r\nzxNPPMZcIbpK4rXXXmXzsocOZfWZ75NdBHRb+lppmjUqY4tfDRFz7WKh7hrRBEVXiaOzjuJlZkIm\r\nIS+vp/ccrbFc+mo1a6S7Ru9q8XHVNUJxhCCIgQUL5rEqbrprqK98T9OmhUJTbYY2a+QyuEYHLV0j\r\n6Rjp7XTKrJFY+NouXaMWIY5U14i20yk7jfSFr3qcjgmjo6uUZa8xoozB5Bp1sPCV7zSSrlG4Nmfk\r\nECUMDoNjpM8a6a6RLo6c6qxRhVz4Knc8uC98dZQrV9C0djqLSJ3iGuXv/gBCQkJQHHWxS0vnjOiA\r\nNh4PBDl/srMzWCRu6NAhcPHFF8PDDz/E3rbZ0vrs9yzFEXOOZKSOzRt14B
rReDm7SJgrLhTKiDkV\r\nRzl9blFr94qj1aZznnV9t3rOs7vFx98U5zoURwiCCKhTRK3wnTu396nva/nypZAYH2OI07GhU801\r\nOqi5Rlwc8Vkj7hqZG+qMJQxOs2skHCMujOK1vUayoU4vYbCo7q5XdhpRYURdI3XhqxanWwSOIzJO\r\nx10jOWskI3V04Stzjiwa6rQSBtpQV2nlGslowafaXiO9oc6qsUe4RhY7jaQwcuSOhhMv/QEOX/xj\r\nKPvxjyHlwQcgcuECFEfnSUFBLvz2tzfA9Olf4vFAkPOMzEVELIBHH32EFSjQ6mxaqd3VqyW6Uxyp\r\nrpGxhKHM3TVS6rvVIgbW1no8A44eudDE0Sq3lRVurhE7143TxVGJUsRQcm7xcRRHCNKPoTlsGqVL\r\nSkrog7GIA+yJKvtAgptrpFV3s51GvIRBLnyVwsilxunUIga518hcwmBY+Bondhp1FKdbIRANdQ0e\r\nInV1xupu7hrpC1+dR4w7jczCyKmVMEwzFDHwEoYppgV41g11xqHU9w07jaRjpEYM2JW0kjeZMGog\r\nwvkwoZxQRNhKBBKKo/Pjn/98ns0a4bFAkHPjwIF98O6778BVV13F1kzQi3zUOfK2/w8WHz9doxcx\r\nnJZFDOWaMKINdVoJQ5upiOFktnJOzIDm+oMXlDhqKl1qmK81trKO18536lyt5hoV/1tcDOTO0dnE\r\nx1EcIUi/vXp9CAYOHAjz58/tw/Wq+2HKlMmwbetqaKrZxxwjGadT9xpx12gfw1jC4GHWSBFGTsU1\r\ncso5I1bdLYoYzJG6BjVSt8LoGtUtA5dWwrBYcYzcSxjYnNERo2vExFGNsYRB32v0pdhrpLpGk7Wd\r\nRnaLEgZ+otAb6vSFr6a9Rqbs9Yn8tyB/93jmGNUIYVRIyCCkXnwxiqPzjLDSHSm0pQ6PB4KcHfRC\r\nHl2uSueI6E6hLVs
2evX/D42PN9cXKA11VcaWujZjpM5QTCRKGFiCQjS22lsOQHFR4QUijvKhrfxz\r\nU6ROdY2Uxa9y3kjs8TOuqqCu0euQv+t9CA4ORnGEIBcyY8cGwlNP+XvBYO0BWLYsEkJDQ9lVHaRn\r\noDNGNEonHSMqjPYRkoU4ioqKxMfRWUJnH6hTSx1bPB4I0nnWr18Dfn5/Y3uH6LkrIyO9X/x/LV++\r\nDBIT1gHY+awRj9Tp9d0ui3UWqmukzt7KFMXRI1kXhDhqKI1Rmlknus/XakUM6qyRKUIuxJGj+A1Y\r\nPP9zmD59GoojBLmQB1fpMHhq6i6v+r7XrVvr9sSFdB90xqhQEUa7CetFrI7+LPCxdHbQQfF33nkL\r\njwWCdJKEhE3w4IPDWHyOlisUFub2s1Y9ER/P3KntNoLT5abdRryhzmXea6SIIxqpkykKGjGnAqn/\r\nOkj5Qhjps0Z2scfPIbCblpyzhroSY0OdWjoUt+IzFnGcP38+iiMEuVAJCfkMnnjica/7vvfv34ei\r\npQeJXDAfEokY2nPxxcwxosJoqShkoD8LfCx1nsmTg9lsBB0gx+OBIB1Dl48/+eQTzCn65JMJ/U4U\r\nWcbHEzdAU+0hcLEondW8Ub6ba+Q6YYqXy2KiY3vB3rIXmusOQENNBjQclpC3D+8n2KC+Oh0aGPsE\r\newVphFSor9oDDYT6qhTCbvI6ZRfUV+6EBkJ9ZTKjoXIHuaVsh/qKbYQkQSJhK6c8gbBFEC/YTNjE\r\nKdtIiCNsEKyH+tJ1gljCWvK+1dBUtgxOVYSaouQeXCNl1si8x4+6RjI+vjD8cyZQ58+fZ3keRHGE\r\nIBcId9xxO2v48cbvffv2RBQuvQz9GeDjqPPs2rUDBgwY0KvLJhHEW5ocaWyOPl7ef/+9C2Y2D+Pj\r\nvRcfnz59uqVj1FF8HMURgvQzcnIy4Sc/+QmUlBR47f8DdS1orIs+
caFY6RnosabHHB2js6O8vJhd\r\njJgw4SM8HgjSAQsXzoNrrrma1XJ7W+Qb4+P9E0/xcRRHCNLPWLo0gs0+4LFAkO4nOPhTuO22vzCR\r\nhMcDQaxiZTZ44onH4Prrr4Pvv8eiF4yP9x08XQxEcYQg/YxJkz6FkSMD8FggSDdDr37T4pMdOzCG\r\niCBWzJs3h80VjR79KhQV5eExwfi4V8THURwhSD9j1KiXYOLEj/FYIEg3c//998G4cWPxWCCIiUOH\r\nstgi5Ouuuw5iY1fjMcH4uFfFx1EcIUg/Y9iw+1m2G48FgnQfs2fPgt/97rdQXJyPxwNBFOjOomuv\r\nvQYCAl5AtwjxSlAcIUg/Y+jQeyAycjEeCwTpJnJzD7K9LHhFHEGMfPxxEFuEPHfubDweCIojBEH6\r\nBrQ5a8WK5XgsEKSbGDPmdXj66b/jsUAQJUb34IMPwJ///KcLuokOQXGEIEgfhJ6c8Io2gnQPtHyB\r\n7mix2dLOfP+iPKh/5WWoH3ApHCZUkNcrMGaE9DMSEjbDr3/9axg58p9evUICQVAcIUg/5Z57/grL\r\nli3BY4Eg3VTC8MknEzp13/pRL0GDjw8cJpQTigh5VCDhcUT6CQsWzIPLL78cZsyYjscDQXGEIEjf\r\nhEYbaH0qHgsE6VpWrvwBfvWrX3Z6yJw6RjVCGBUSMgg26iDhsUS8iMq8bGiY+Q00fTCO3Vbm57D3\r\njx//Ppu927hxPR4nBMURgiB9FzoL8c03X+GxQJBuiKyezWOLRumkY0SF0T5CyqWXwurVq2HatGkw\r\nadIk+Oyzz5Buhh7nL7/8An5YvhgOHjyAv8tnQU3cOnAQAQTkd1fiuOrn8J7f32DQoFtg7949eJwQ\r\nFEcIgvRtXn/9Nfjwww/wWCBIF0Lr8W+66caz+7xXXtYcIyqMdhOW3XknJCYmQktLC7S3twO+dP8L\r\nPc70eO/at
QumTpkMmZn78Xe6M45Rfo6bMJI0XPQjKMy04XFCUBwhCNL3T2Y/PPUkrLrtL4b4A4Ig\r\n58ett94K4eHfnd3nFeZCPhFI6QMuZY7R8rvvhuwDB1Ct9OJLTk4Oc5PQQToz9BxiJYw0gUQ+jscJ\r\nQXGEIIiXxR+uYu/H44Mg587330fC9ddfB+Xlxef8NWiUjjoX+NL7L1vjY2HZskj83T4DdMaoI3FE\r\nP47HCUFxhCCI18Uf6PvRQUKQc+evf70bvv326/P6GtOnT2fRLnzp/ZfmpnoIDf0Cf7fROUIQFEcI\r\ngicxBEHOhu3bt8KVV17Z6YY6T9BSAJwx6jszSDRat27dWti/fx/+nnugMCOdzRbhRTcExRGCIBh/\r\nQBCE8a9/jYJ//3vMeX8d+sc4vvSdF/rzWLJkMWP79kT8XTdBW+hoG93Yv93L2ukwro2gOEIQBJ0j\r\nBLnAKS7Oh8suu4z8oZhyQYmjssRwGD16NIRtKjqv+5hf2lobobqsDIrKqqHV0XfEEQUdJB26t4ju\r\nL6J7jFhs28OeIwRBcYQgSN+dOSInL5w5QpCuZcmSRfCXv/y5S75Wb4qjophA8lTgQwiA1NYz398W\r\n5s/u7xdmO6/7KLIIYkb7iO9BMgiCY7LA0UfEEY3Y4e98CcyYMR0uv/xyWLBgHh4PBMUR0vcpKSmC\r\nVbg8sIeZBFM+D4WIpRF9vvoV2+oQpGsZPvxp+PTTiV4ujsogSBElo6Nyz/gZuREB7L7+HQifztxH\r\nf2mFmOAgCI9NhKzcLEiMCoZB4vuJrXb0CXEUFRV5gf99UQAjR/4Tfv3rX0NCwmZ8/CMojhAvoLKC\r\nPZknbE2EhqYWOOVoJwC0EU7aAU4Ijp0mp6FTnBZCcxtAE6HxJMBRQgOh/gRA7XGAI8cAagiHWwGq\r\nBVUtABWC8mZyWm0CKCWUNAIUC4qOAhQ0AOTVcw7VcXII2b
UABwlZhMwjABk1AAcI+w8D2ATphL3V\r\nAGlVAKmVACkVnN2EXeUAOwnJhB1lANsppQBJlBKARMJWQkIxwJYigHjC5kKAjQUEcruB3K7P58Tm\r\nAaylkL8F1hBWHwJYRVhJiMkBWJEN8AMh+iDAcsL3hKgsgMhMztIMgMUH2mHBnhb4ZsUuCJnc95cH\r\nyvjD6ttvY/uO0DFCkHOHFjF0RaSuN8VRY2oYEyGD/AYJgRRE5JLJ16lOhiB/P34//0AY7efjJnw6\r\nc5/Ov1RDoBBHoamNfUIcUS7U3/PU1F3w5z//CR588AE4dCgLH/sIiiM8CN5wRacYpk6dCgcP5oDD\r\nBXDayaHiiHLSwYXRcUHraQ4VR0wYtQlhdIILo7rjQhwJqEDSxBGh0kocNXFRVCiEERNHgtx6LoyY\r\nOKrj4uigSRxRmDAiomhvlSKOCHsqFXFUwcURE0hCGG0TGIRRsRBGhE1CHMUJpDhal68LI4M4yuHi\r\n6AdFHH2fxTGII8JiJpAAIgizNnjP8sCgoPEwevSr+PhBkHMkKSkBrr76V1329XpHHLVCVIAQRG1F\r\n1oKkLQsCxPv9AsMgJjxIc5k04dOZ+5yDYPPx8YPkOkBx1IvMnTsbrrjiCvj44yB83CMIiiPvgS4P\r\n3LlzFzjbgYkju0sXR9I5ohw/zZ0jSnMHrlGd4hwdEc7RYUUYMXHUzMWR2TUqFAIp3+wcCYEkhVHW\r\nES6OKPsV54iKo32KMNLEUaXJOSrjzhFlm+oaFZtcIymOCrkw2pDPWZfHiVWdo1xdGGmuUTZ3jZYL\r\n12hZJmepcI6WKOJoESE8eq1XLA/85puv4B//eAofPwhyjkydOhmee+5ZrxZHjrJYJkICInINUTif\r\ngChoE/epSw7l7/MLBalTssL9DcKnM/fptDDKitIidRG2XlJGKI6gsDAXAgJegGuvvQbWr1+Dj3kE\r\nQXH
kXdDlgY1NLeB0gcE5oqixOivXSIqjBgvnqFa4RoeVaJ3qGpUqrhGL0ymROooUSLn1xlidW6Su\r\nRo/TsUhdFUfG6qQ4ShHO0S4RqzO7RtI52mLlHBXqsTrKunyjMFpljtQJVHEkY3XLhHu0RIgjJoz2\r\nAyykpNR5xfLA+fPD4cEHh+HjB0HOkVdffaVLr6b3hjhKDvXTyg/8/Pw0UULfji1zGIoVfHyCFeFj\r\nnCfqzH0685IbG8y/zqBASK5u61NtdReSOIqNXQ3XX38d+Ps/iTE6BEFx5J3Q8gWnq50JI9U50lwj\r\nBxdG6rwRdY2aT5mcIyGO5MwRhblGx4xxOkpZM0c6R2qsTjpH+SJSl2t2jWp110jOG1GBRF0j1TlK\r\nE66RjNWZ5412qPNGpdw1cnOOCsXMUaExUhebp88cSddIiqOVwjlaISJ1VCCpwogihdFiIY4oVBzN\r\nt3nH8sBly5bAPff8FR8/CHKOPPDA/TBv3hzvFUdtNh6F8w+E8PBwCAsLY7eB/nz2yC80mQuWqNHC\r\nFQoDXmTngE1Bfgbh05n7nLEBL0J8jYBwaITef7kQxRFdZPzaa6+yWbqu/N1GEBRHSI9Dn8RdMlIn\r\n542kOFLnjU4bnaNmMW+kzRypZQzCNepw3qjZ6BzJWF3BUaNrZJ430pyjI/q8kYzVUWG0V5Ba6Xne\r\nSI3UqbG6hGL3mSOreSMpjtbkmsRRju4cyZmj5Qf1eaNlShmDOVJH3aMFNu9YHkivDNIBW3z8IMi5\r\nceutt3Zp3KinxZGs7w7PMjo0bVnhWq23rY1G72K0+SG/wGAIHj3IbZ6oM/fpePTJBn6aa+UPgYGj\r\n2Y6kAP/REJPbiuKoB4iKWsrcoieeeBwyM234GEcQFEfeL47MkTqzOJJNdcekMDqlO0dnitRVK5G6\r\nSiGMyk3OkVrGYHaN3Jrqjrg7RzYPkbrteY2wbk8Z
rNhTzQRPR/NGiRYtdbKMYaNp3ihWmTeiRQzm\r\nMoYVppY6ijZvlGEhjkSsziyO+urywJiYaLjjjtvx8YMg58igQbd4sThqhHA/44yQ/lIHoaJpLmgT\r\n763LitELFnz8giAsSMwThevCpzP3OaOLZUGYDcVRdzfRPfLIw3DNNVfDwoW4uwhBUBz1J3HkoYyh\r\nzaKpToojK9fIXMZg6RypZQzqvFGjexlDh86R0lInxdE+0VaXWtkGUwPclwL+a04WbFOa6miVt8cK\r\n7w6cI9ZUZ4rVuVV4C6RrZHCOMo2xukUCK3HUF5cHRkYugSFD7sHHD4KcI7fc8geI68IdYb25BLZT\r\n5Q1trdDa2Aht53QfB7S1ko9Z0Nbm6JP/v/1dHOXlZcP7778HAwZcCu+99y4rYMDHNYKgOOqXzpHd\r\nXMYgxdFpfbeRoYzBLI6O6+6ROVZXobpGFmUMWo33Ufd5I62M4Yh1hbdNEUa8xrsVpr4XBOMXJUJk\r\nUhZ8+20w/EaIpC/2OqzLGIpNZQyFxhrvDfmmHUfmMoYcUxnDQT1S971SxOCpjIEKo/k271geSK8Q\r\nDht2Pz5+EOQceeyxR2HWrLALRhydX2N4qlL2YCI4FcVRD7fQffLJBDZX9OSTT8CePTvx8YwgKI4u\r\nDOdIdY205a8WTXVHPdV4m/cbtXjYb9RoPW+U39AKYYEBcP8j/hC0qlqL1O1Li4XHbvKDD2Kq2cyR\r\nYflrtS6Q0kw13rsqquFZcTIds6bRzTXqTI235hrl6a6Rp0idOm8kBZIsY3BzjfYL12i/tTjqiydV\r\nenJ8+eUX8fGDIOfImDGvw7hxY1Ecda79AarLyqDMgurGNhRHPSSKvvzyc7jqqqtYU2lCwiZ8HCMI\r\niqP+LY4MkTpThbfbvFGbsuPItABWFUZW80YVQhiZyxjozBF1jwqUeaMN4aJ96K9hsJuJozb4aiQf\
r\nuI0s0mu89wthpM0cVRtb6mgZw6a1+lLAmTYujLQyhlIeqWM13kVG50ir8JbzRvnGeSNzU51axqDO\r\nHMl5I9U1UssYFu6XbXXecVJ98cWR5Pv8BB8/CHKOrFq1An7/+9936fN4u6OJQJ5IHUeh3d5AIE+k\r\njjpyewTaT9cQyJPk6WpyW0mogPZTlDJCKaEEXG3F0N5WRCgE18l8aD+ZJzgErhPZ0H7ioCCTkAGu\r\n4/vBdcxGSCfsA1drGrlNJewhr+8mpEA7u90JrpZkwg7CdnA1Jwm2grNpC7ia4gmbwdm4CVyNGwlx\r\n5PX15HYdIRacR9cSVhNWgevoSnA2xICrYQW5/QGc9dGE5YTvwVm3jBBJWArO2sXklhJBXl8IziML\r\nCPPJ6/PIbThhDjhrZoOjZhZhJjgPfwuOw98wnIe/Bkf1V4Tp5PXp5HYaOKpCCV+Ak+ComkqYAo7K\r\nEHBUBBMmET4De8Un5HYiYUK/EUcZGekwdmwgc4r8/P6GO4sQBMXRBSaOTJG6NiVSJ8VR62m9jMEq\r\nUldritQdVlwjq6Y6ihqpy1f3GxUmwx1y43oaEUeZfOGg32SbW1MdE0bV1vuNNm+J0iJ1QXF1Hpvq\r\ntprnjSyWv3a2qS5aWQCrVnibm+oWK+LIU6yuL55Uhw4dQr6vRfj4QZBzpLg4H37+859BUlJC1zlH\r\nzmZNHIGDiqM68sROxNFp8oRp5+Ko/XSVIo7KdHFEhdGpIiKKCsjrlHzyeq4ujE5mk9ssIogoRBwd\r\n5+KonUHF0V5oJ7haiThq3UNeTyFCaBd5fZdBGDmZKErUhVHzFi6MmogwatpIRFEcE0euxg1EDElx\r\ntIaIojVEDK0iUHG0gkOEkatBF0au+mVcGNUt4cKodhHDQYVRLRFGR+YSIRRO3ubiyFHzHRFIFCKQ\r\niDhy1oSR268ZzsMzuDgSwshZTcXR50QQUV
E0mUOFUSUXRg4mjD4Be/mEfiGOtmzZCCNH/hMuvfR/\r\n4fnnn+uy31MEQVAceaU4kmUM6vJXWcYgXaNGC9eoTggkWcRw2KKModyqjOGoWP4qkEUMufUOmPU6\r\nr3S945NYmPGBH3N+IvKNZQzSNZI13qnKfqPlC8VSwBsD4bu9bVpTnYzVSVGklTF4mDeSsToaqVsn\r\nXCNZxtCha5RlrPFmTXUWsTrpGnmDOCopKYCf/OQnkJ2dgY8fBDkPpkwJgbvvvqvrxJGjyega2YVr\r\nxIRRtaCKO0any3Vx1FZCbnXXqF1zjbg4aj+ZQ4QRdYyymGvkIsKo/fgBcmsjKMLoWCq53cMcIyaK\r\nNGGkuEYt2zRx5GpKIGwhwmgzueXiyNXEXSNdGK01CCNXQwxzjFzMNRLCqD6Ko7lGRBzVRggWEhYQ\r\nQUQdo3lMIDlr5pDb2UIczeTC6HAYwega6Y4Rd42YOKKuERVGVVQgSXH0qYC7Rvbyj7xSHNHn9NDQ\r\nqfDHP97K4nPvvvsOHDiwDx+rCILi6MIVR1Y13idN+43UCm83cXTcfceRFEgd7TcyR+rUHUf7doQb\r\nhm9vn5isV3ibxJG5xnvxVyKW9/dw2GRaAKu6RlqkzmLeaJPJOVonm+o8RerUpjqLeSO1qc4qUjfP\r\nC8TR4sUL4fbbb8PHDoKcJ/n5OfDb394AQUHjuyhWR4SRgwsjQ6ROc42IODqlukalmmvkUoSRSxFG\r\nMk7n0oTRAc01ouKIu0YiUidcIx6p2210jZq3GYSRFqdrjmfCyMmidBuIIJLCSHeNWKSuQUbqdNeI\r\niiOXFEdSGNUtAQcTRdw10uJ0VBQx50jG6b5jkTrqGumROuoazdAjdUqcziCMCHYZp6v8TDhGRBhR\r\n16j8Y7CXBXmNOKKtc999NxMef/xRuOSSS+DRRx+BiIgFUFZWhI9RBEFxhOJIrfHWXKPTxnk
jQ1Pd\r\nSdOOoxN6rO6wqYih0qqprtHYVFd41H3HUXZdNfznJh9tXmh+NneN1DIG6Rrtq+bCiImjPBv8RVkK\r\n+Oy/RsOTL4yGBx4cDZO2tvIyhtIOyhjMTXUFimuUZ3SNzGUM5qY6WeNtiNRZNNVR5qX3fXFEG4pC\r\nQj7Dxw6CdAG07Ys+T/3rX6O6wDnicTpwUHFUy+J0VBiB3RynKzfG6ZgwEuKIRuqEOHKdyGGuEYvU\r\n0TidOmukCSPdNaKzRixOR4VRy06LOB2hhc8auZoTWKROc43ErJGLCaR1RBDpcToXE0fKrJF5zkiL\r\n0xkjdQ7hGtFInYOJI33WyBCnOxymzRrROJ2z2mLOiMXppuizRh5cI0fFx0Qg9W3nKD09jTlEDz30\r\nIBNE9947lJUtYBoAQVAcIcpJ1a2MwcPyV23H0UmOOnPk5hqZBJLb8ldVICkzR3mm5a/rw7gD9Lu3\r\nE3mNt+Icae6R4hyxeaMiGzzkofr17Q2thjKGRKsyhiKljKFAX/66ztO8kSlWJ5vqvldmjpaaXCPD\r\nfiMvcY7owr/LLrsMT6II0oXs25cKP/vZT2HSpE/P+WsMHFgMSVub2JwRFUYgkEUMXBxVKSUMIk4n\r\nxJGcNaKukcsiTseidEoJAxdGwjVSZo1YpE7MGrWzIga1hME4a6TG6VTXiAojl4zTiSIGKY6c9WoJ\r\ng4jTqbNGmmtkjNPRWSM+ZzRbc4wczDES4qiazxqprpGz+kvdNRLCyHm8iHx+hCKMeAmDXbpG5UFg\r\nL/uwTz2PHzqUxXbTvfbaq3Djjb5sN9ETTzwO3377NRw8iM/lCILiCLEWR+b9Rsq8UUc13uZInRRI\r\nUhgZmuosaryLjlqUMRAOafuN6uDDh/kC128zHcqOIwcRQK2ws5CzvYCQT0QPYUexw9BUt0tE6naW\r\nK/NGpe7OkVuFt8V+I/O80WqLHUea
MJL7jZSmuo6cI28QR0895c+ai/BxgyBdy+7dyfDnP/8J7rpr\r\nMGzatOHsT7Y+pwnHYOiQZkhKqNfidLprJIWRu2vEhBGdM2rTZ41cVBxR5+hEthKp60QJg8d2OjFn\r\nJF0jZdZIj9RtILfriCjS43TSNeKzRrKEIdrCNVJLGPRZI1nEwOHiyK2EgQqj6hlaCYPDKk4nHKPT\r\nx4/Dsfp6OH7YBqfK5zCBpEXqhGvkKO9dcbR9+1YIC5vB3Mibb74JLrroIhg8+E5WHb927SqMzCEI\r\niiOkM+LI6TKVMSjOEStjUFyjJg9lDLVKGUONqYyhQtR4lystdcWKOJKROr2MgTtHa74N4I7P67Fw\r\noFZZAFuUCr/1tBTwvVSjOKrQ540oNFInY3UyTmcZqbPacZTvHqsz7zeikbpo4RpJ50guf/VUxiDF\r\nUV8uZFiwYB4MHHgtFBQcwscNgnQDpaWFrKSBDsPfd58fLFu2BMrLizspjo4RWggNhFoikqohaUuV\r\nJozAJI5cimsk43QuU5zOJWaN1Dhd+3FZ3b1XkGqq71Yjddv5rJGI0zlpAQMTRvGWcTrP7XQxXBxR\r\n16hBuEZ1UW6zRkwU1UWA44jqGulxOtlO5xAlDA4Rp+PtdNw1YpG6qi/J619aiiMqjFpqaqChpARq\r\n8/OhLjsBThR/o7lGDuYcje+R5/GsrAOwenUMi8S99NKLcMcdt7N2uauv/hVbMjxhQhCsWbOSNSPi\r\n4wtBUBwhZymOXO3AFsGadxyxMoZTehmDOm9kXv5a52HHERVFZ1r+KhfA5gmBxJ2jNoiJjoUZC2Nh\r\nVY7qGtF5ozbYvLcMNhDWC9YRYtPI+3LaLJ2jZJNrlGSeNyr27BypO44018gkjmJy9DIGN+coy7jj\r\nSI3UqU11fXXmKDk5Ca644gp21REfMwjSvdCFm9OmfcFaw2jd97PPDmdD8zZbWgfiS
AqjOkIVoYJQ\r\nBPcOKSYiqcyja8Rru9U5I+EY0VkjQ0PdAU0cyRIG6Rq1U3EkG+pMs0bGdjpZ3c33GnHXiDfUsUid\r\nNmskI3X6XiNjnK4j10h1jOaLhrpwVsTgsJw1+tqyoU6r7lZ3GlUGa8KorqAAqjIyoCI9HYp27oTK\r\nPauh9dAXLFLn6CJxRAs7qAsUHR0FX3/9Fbzzzlvwj388xUQQfT6m80K33norPPPMP2DixI/h++8j\r\nITPTho8hBEFxhHRJy5GzhUDUi7NJazzShnpZPOOw2JNRbcqty+WB7lcf9cx6tnaSNVTAyqz6sTQ9\r\nqy6vOrbuhPZW05VHdoJN0PdiNMqdGBv0nHqjGsdYxU+qrN1I2YdRLxYFsrrXxexqo8Mtoy6uNmr5\r\n9JmEb5UFgTJ+YRHB0PZghLjl0unVRR67+IidROkVRkfZB2AvHUd4DxylY/ucONqwIRauueZqNsCL\r\njxcE6Vl27drBZpEefPABNu9HxRJdxjlq1EtsEfOcObPYQlnpGKnCyMengJBDyIKhQ7Jg25ZCt1kj\r\nq4Y6zTUSO410YbTf6Bq1KtXdbM5IROpauThyiudupxapM7pG7Pm7w+ruGIMw0uq7LVwjh0V1tyxh\r\nkA11TlN1N43T6cJoGm+nU2eNKtWGuhCGdIxUYVSwbRvkbNwIWbGxkL9xATRlBrPn8fnz58HcueHk\r\nZzSbiNtZsH79WlixYjlrg6M/t88/n8KaCt988w22U+jhhx9iTaDXXXcdDBgwAH70o/+BgQMHwp13\r\n3gFPP/13Jo6mT/8SYmKi2ZwaPj4QBMUR0o3iCJytRBA1iz0ZjWxPhhRHwLarixpYt+WB+o4Ml2w6\r\nUpYH2luzoaX+EDQcIdTkCLIVDhKyOIczCRmC/Yz6ahu5JVSnk9f3kVvKXvJ6GrmlpEJ91R5oINRX\r\npZDb3Yz6yl3QULmT3CaT22
R2W1+5g7CdU7FNkERI5JQnCLYQ4hU2EzZBfdlGcrsBmiti4FQVEUvi\r\nhMqvMtITqbjCWKWfSO10OaBW9TpBE0fs6mK5LowcZe+R23eJOHq3T4mjH374nkUV6VVrfKwgSN9o\r\nt6N/XFOn4JVXXmZ/UFMngQujakK5IoyymTDy8Ukn4igDkuLzDQtf1XY6deGrutOoXUTq5EUtg2uk\r\nxenMe42sZo0SDI4R22mkLXxdb4jU6Re3+KyRS1zgOrNrJBa+Ko4Ra6c7Mke50KUufDXuNXJ6nDUS\r\nO40qJjFhVJ2ZCeWKMMqmwmjdOkiPjoZDG+bB0f2fsufxESNGwAsvvAABAQHw0ksvwS23/IH9rKi4\r\npdXZdLnq66+/Bh98MI7FKalgosKHLlzNytqPv+8IguII6V1xZO0aaW1Hdl0cARVILJ5RqlyBNLtG\r\nudBYmwfFRYVQVFTUD8mHhrJY92x6pfFEqm9On2hyjnj0wl72Prkl4ki4RvaSwD4jjqhTRKMbS5dG\r\n4OMEQfr6yVZzjIoNwog6RknxBcpOo865Rmy3keIaqdXd3O03u0ZqnM4ojpxNeqTOaYrTOZWGOtU1\r\n0ncaWcXppGsU6bmhrlY01NXMMew00meNvvaw8JU/lzvZ87nqGvHq7ioijKhjVEyFUVKSJoyoY9SY\r\nGaJd8PLGJbAIgqA4QtRYnaOZ4CFSd/owEUTq8kA1u24dqaPCqH+KIiMNZWvEyXSqiF8okTqTOLIr\r\nrpGM01FhJCN11Dmyl7zT6ydVOl909913saucW7fG42MEQbxCHBkdo6FDciFpSwl/zj5tNWtUSJ6v\r\n9XY6t+puxTEyukZ7RUudMQ7drrlG2zt0jZyNumvkPLpeW/bKIOLI2aBXd8uGOi1OJ8WRiNM5aCya\r\nukZ1Uhzp1d3uO42Ms0ZOWsRQPUMrYeCROusSBvX53OAYxcVBceIyaD44hV/
wKpcXvN5HcYQgCIoj\r\n73eOeJyOLhDkG9br3CJ15rYjGafTohkinuE4ltunHKO0+GiYERoKM2YtgiRb14q24qJ8OFX5tWl7\r\nerAQRZ+JmtdP9AWB0jVSTqJy1shRGkjoPXGUkrIThg9/Gi6//HI241BSUoCPDwTxGnHEhdHQIfmw\r\nLaHMbaeR1k53SgojYxGDjNS1C9dILWHQZ0SVOF3rnjOUMCiuERFHTjVS17jRUN0t9xrJnUbUNXKZ\r\nSxjonJEap6Mzo3VyblS4RjJSV8vnRh01SkPd4ZmGOB2v7lZcI0UYOc3CiDyn28VzuhRGJTuioSUn\r\nVLTTySTAB+w5nV70QnGEIAiKI28XR9I1ErNG4KgzxenEvJEUR228iIGebF2Ka0R3Y7Q0dF6AZCZF\r\nQ6D/YKWK2xeGDRsFi5JzukS8ZMaF8q87eBj4ktuJsTth7hh/GDMrvssEUlP5ciVSF+JWxCBnjYac\r\nuBYSDj8vhJHqHI1ls0Y0UmcvebtHT6q0OpguB7z//vuYKHr33XdYPSw+LhDEuxg4cCcRRZX6wlfN\r\n6bd2jfS9Rry6mwsjvtNIxulUx6hdK9DRXSNtr1GL+14jQwmDaKjTXCMRp3MxxJxRg9xpJOq761co\r\ne43cXSN91ogW6izks0Zip5HDrYRhlijUCTO4RnSvkVbdTSN1sqFOi9NN1uJ0cna0grbS5X6pRKR5\r\ndbcURjwF8B6KIwRBUBz1B+eIiiPw4BppVyFPK7NGrITBONRLT7QNRzonjmwrJ2qCaOLcaIhdGQmh\r\nE8cwERO40tYlwiV2IhVe4yFNe18mhPj6gO/42C4TR/Vla/iVRnXWSDmZylkjn9Pk//WYDww9eg0k\r\nVD4nTqRjRRFDIIvU2XvAOSoqymOCiLZdUUH0pz/9kdUGFxTk4uMBQbw5Hi0j0KdVYVTqMU7nEvOh\r\n7crCVy1SJxa+uo7Z
LBe+6iUMO8W8kVV1N1/2alz4qrhGR/nCV+kaudTqbiGMLEsYZJxOmzNapNR3\r\nz1P2GplKGMSskYzTSdfIaY7TmWdHtYtdhPKJ2gUvvtdIL9eRrpG9D7aOIgiC4gg565kjXRhpJQxM\r\nGNEK72rjVUjNNbJeHtg5cZQC4325MJoVb3KJ8nIgJ69rhEt8yDDw8Q2BnG6M7dWXxvKTKW2pqwj+\r\n/+2de3RV5ZnG4wURvNS1HEUBxSvS0bFrtNNJ1xjsdFK6RotRsRrroKLWchHMIBJgiAIB8QhDwaAD\r\ncnMMjojcAhwhhAQMEgwQ4BgCCSSQC/ccGxBROJe8s9/3+769v2+ffUKgQk18/3gWRYrQJD07v/M8\r\n7/PE1nfXjoRQ9XACo4RjloKWDidAUl1nWF39uF3EgJG60J6B3/tDFbcycCjw1Vdfgfvv7w6XX345\r\n/Pzn90J6+qtUE8z/H2CxWgsc7ZNgtC/mNtQcfPVyjZzqbjX4qrfTUQnDcVXC4JpeUK7R0dg4nZpe\r\nsBvq5KZR1N40WmzH6ZzB1/laffc8l2uUbTTU0eCrjNOFPQZf9RKGiNZOh65RWHeN9OpubddIvJ6P\r\nMl7P9WKdWNdo8A+udZTFYjEcsc4SjjBS1xiSkbrQIWfX6GRd7ICgDUeVrirY5sFRWa6IuyVnnMbB\r\nCeRCRqoTu+uWmgG5AccFmmr9Wh9fNszOSHFcqOxC+nW/L9X5fZZSfX7796RO8tt/RnlxDqQlq1hf\r\nMqRn9IPExH6QW9ZcOFoS02jkLmIIWQ9SG4yOWNpnqdZSZQJ0r+wMeVW9KFL318DRzp2lkJe3Et59\r\ndyq88sp/wiOPPAy33XYrtG3blsYk//jH52HGjGlQWrqNv+5bmOoswA1mTYaGoUPoR/w5f1xYMQkA\r\nvTjnlOMaReOUMETtsdftRkNdo9qjc7tGxq2R2qTTwEh3jew7IxWnc
26NIhocRT0b6jxKGHTXSG4a\r\nhbXBVwIj1VBH9d3e1d2Ga2SBkXCNfM6tkbZpJFyjURCi13L1ej7SKNexJxmwdVSLSTMcsVgshqMW\r\nf3MkwYga6nTnSETq7Pput2tk1MCKeEZz4CjgzyQYyfQHmvjvFUIaAUsqZPsLoTB3NqSS25QGheUC\r\njnwKaiyYmb0gG9KTxa8X4Z9R5IfMPt2sn/exfm0B+AtKRKwu0YIlG8oKoZ/8M2bnFkLBgqmQLCFp\r\nQeBM4chxjaiEoUY11IkHqXKMdDBK2GWpzNKXCZAU6AirKx6mz4caDpw6NQumTJlMy+fTp78LEyf6\r\nYOTIEdC374tUnoB7GT/9aTf4yU+uhEsvvRS6dr0dfvvbHjBgQD9aVM/N9XOxQgvXQf9SCHfoANYX\r\npS38Of5z/viwnJujKihYdViL02mu0ckqw+mP11CnNo3crpFXnK6xySIGGanTXKOIvWkkShjcg68q\r\nThc14nRquNscfBWxujmu4e5mxOmovtu1aRS3oU5/owtf03XXaLhQtb5VN0QW6/wwWkdZLBbDEet7\r\ngaMjRn23fWtk1Hc3HanDeEbw0M7TO0eyKMHXBBwpgMrICWi/T/0zCToIQ8mZ9k1Rrg8dpEQbbGJj\r\ndQKOEiUcxf8zEiHnTOBIRepqvSIY4h1GAqP9lmo0MNouwChhswVHWztCXrmAo169ehlSDtgFF1xA\r\nuvDCC+Giiy6CNm0uhksuuYTcocsuuwzat29PsbkrrriCgAlX1vGuCPeKrr76auhgfVONuv7666FT\r\np45www2drW+qboSbbroJbrnlZnKa7rjjDgKuO+/8e7j77n8g1+nee++h5XZcasea76Sk+6B79ySC\r\ns+Tkf4MePX5DY5QPPvgA9Oz5O3j00YfhsccehSeeeByeeupJ6N37P+jGCd0rHD1EeBs06CUqgBgy\r\nZDAMGzbUgr
7h8NprI2HMmNdpEPHNN9+gNfgpUyZZkPg2weHMme/B++/Pgrlz/xfmzfsQFiz4GJYs\r\nWQjLl+fAypV+cs7Wrl0N69athS+++JxW5AOBEigrC8CuXTtaHCiiQ+QGIx2Q2EFiOW11pywdh+5J\r\nX0FBbp13CYPH63Xjt/LOiG6Mtsoft8RUdzu7Rus9SxgiWnV3RN4ZkWsk43ROO51yjZZQpI7gSIvU\r\nee4aGWAkXSMVp5N3RugYqRIGr0hdzK6RjNNF7BIGZ4YhVDvG425UvzPSJhlqzEhdiOGIxWIxHLWW\r\nWJ0+/KrB0UmvhjrdNaqIqYJtDhwFcgSUpDdRvBCQkDKvxPln5YXTTThC0Ml0InJ+hKGEZBts/JmJ\r\nBEeBJuGoG2QXlWuRv7OAozr3rZHjHIVko5HtGFWZYJQU6AR5FY9YD9SXIFQ1wPVQnUM/YqscfmNf\r\nVVVBhQq7d++kAgX8hh9vilDl5dthx44vYfv2bRSdw4V1BIOtWzfBli0boaSkmGChuHg9bNiwDtav\r\nLySIwF0jBApcZcddo7y8FbBixXLw+5fCsmWLCT4WLpxPy+0ff/x/5GJhoQOOw86ZM5OA5b33/gem\r\nTXsH3nknC7KyJhPQINjgkCyCTmbmKHj99QwCoOHD0+n+afDgNHj55YHw0kv9yQlDcHruuWfh6ad7\r\nE1Clpj5B7lhKykO0Jo+OGILYr351P9x3379AYuI/0+0Uwttdd90J3bp1g9tvv41AD6Hvuuuug2uu\r\n+TsCQwTHtm0vIajEr5+LL76YnDaESITHa6+9Bjp27EigeOuttxAg4r8T/90IhQiECIP45yME9uz5\r\nIAHg44//nv6uzz77NP39+/fvS9CHsUYBfCOoFv2NN8aS64cfF4w9YrxRQd78+R/RTdiyZUvI6cvP\r\nX2V9TtbQ56hq7BhPMFLCiB2/hrEEHB23dMxS0NJhC5JqLUi
SrtHJSlHdrTXUxewaaXG6Rqru9t40\r\navS6M4qzaxTRbo0EHImGOu84XbxNIy1Sp90axXONME5H1d0Hs+JuGjnV3T7NMZKu0T6niCGkShi0\r\n1lF9xFt3jVSc7m89ycBisRiOWN+bc1Tv6RqZ20Zaffe3atuoImYjI3hox2mBorxoOt0BJaT4NHBx\r\nA1SGjN6VucDFBUfa3dLZwRFCmuMcLchMMf4dzYOjTHsHQ2+o0x+kbscoaUcnWL27Fz1Iw3sGEhiF\r\n9vTnh+p5EAImwiRCJMLjxo0baOcJQRHhBCEF3SgEQ4RCdKkQBhEEEQKnTp0CkyZNhLfeGk/wN2rU\r\nawR+Q4cOIegbOHAAAd8LLzwHzzzzNPzhD6nkoiHoPfDAv0OPHsk25P3iF/8E99zzjzS6i1CGcHbj\r\njTeQu5fZvn2TcDSmXTvo0OFa6Ny5E9x8880Uq0TH72c/E1D3y18muqDud+ToIXiim4cw+uKLLxCg\r\npqUNIhdvxIhh5OCNHTvadu/efvvPBtQhIOPHZfHiBQR16NohWH/2WT5B98aNRQTkWAuPt3AI8zU1\r\nVfy1d07hSIHREUv7LNXS9lH3pN0WJO0yGurUrZEepxPV3aKdTt0aNX7jFDHE7Bp9bcbp7OpuaqbL\r\n1UZf5eCrq4RBH3yNBp1bI901iupxusNaCYMHGDmu0VTaNBL13Vl2EYOxa2TfGr3p2qjL1BrqRtnt\r\ndFSqQ6/l5oi32qpTcKRco/M9ycBisRiOWOfCOdLqu40ihlO1cUoY0DnaZR722nC0s1lQMS9dFi2k\r\nZEBOYTG5HEUFOTAprQ/4EH7KciEVfz05A/zFAQgU++VNUaosS4gPRwuaCUeV5QXQhyJriZDu80E/\r\nrZih+XC0OLa+23W0iw9TBUZJ5Z1hdeXvrQep2DUKyZY6dI7CewbwQ5VlC52hpuBo7xuZBCLYOrhm\r\nzWpy
/dDxy8lZRPDy0UdzDahDVw9v0RB60M1DCEIYQihCOEJIQlhCaOrd+ymCKISphx7q6Ql1WAOP\r\nUIeuHUYyu3TpQnFNBDZ07K688gpoZwFcmzZt7FgoxkAx/nnVVVfZUU/8Pcq169q1q4x03k1xTvxz\r\nlHP361//K0U48e+Cf6devR4h9w7hE/++6OAhkOL/BnTxEFIV9GE7I/5vzcj4L3LzEP7Gjx9HNfaT\r\nJ/+3jG9OIQjEjxWC4KxZIsaJH0N0+fDjiU4ffmzR7cOPM8IhfswRqDHWiXCNnwsERXQA8XOD4I0x\r\nT4RwdG/RxUV43LZtM73uocuLoI6uL8Ikgju6wegMC+0kwESoR/cYXeTq6kpylJWUY6SDEY7CJiSU\r\nWfrSgqRtULByu4drVGpH6tSuUVRrqNNdI6eEYZ1RwuBsGinXyGyoU5E6u4ThL14lDB97uEbuTSPl\r\nGsnq7kOuSN0htWuUZTTUuQdf44ORV6nOa3akzilhGBZTwuBMMgw6J62jLBaL4Yh1vp0jwzU64Iy+\r\nqiIGBUd02Ou4RlFyjMootx6VA4LBgzuaWYNdDjmT0oSDZCjZHoEtK5wnSxikuvWBbHsgNhaOxM1R\r\nCuSUabCU2AQcoUr8kNEnBRKtb/BS0qdCtq+PcbfULDjyGH0Ny3ca1Uhg9903wOqqJyibHq4ebDxI\r\nwxSp62+pHz9UWc7NkfVNcmu6OcJv4vEbfYx/oquEkIAxT3SblGu3atWnBBtLly6iOCfCCDpVCCiz\r\nZ8+gCCcCDLpZCHro3mFsEWFHOHgjCILQxcN4I8IRQlK/fn8iaHr++T7k5iFMPfkkRjcfI8hCVw/j\r\nkghe6LIhCOI4MsIgghkCITpxCGvoyqHbhw4dwiHCHN7pYawTAQ9dPARFdADR1cPIJsY8VdQToRDh\r\nEQER7wLxPhAjnngviMLIJ94RYhQUhUCJgIlxULw1V
DeH6gYRJcBov6UaDYy2ExglJGy24GgL5K8o\r\nlZtG25043QnvdjqhYruIoRHh6JjcNaJI3dqYOB3dGh3VN438WjvdMlnAIDaN7LHXoFnEQIOvRz6M\r\nLWGw4Ch8mjhdTAnD/j/LIoZJsrp7gpCq7nbvGslbIxWnoxIGNxjJ6m4Rp1PV3U4Rw7maZGCxWAxH\r\nrPPuHLlHX923RtU0/BrV19XtWyPHNcIHbfPhSO0aBaCoqMj6Jsn6RqmkzBOiAoEAqfwc7BSVl5l/\r\n1vQ+Ca7h2GbCkWv0NaSBkcqmqwcpxS/2OttGyjViOGJxWx3r7GJ1yjGqMsBIOUYiTrfD+9boxDbH\r\nNTquNdTZu0YSjE5T3R3V4nTmrpEYfI25NZJxOgKj4DyjnS7axJ2R4RoRHE0zInV6dTeWMET0Eob9\r\nbzklDMo10u6MxJtcMlKn7RqF6LU8fnW3/mYXvp7z6ziLxWI4agVwRM6RitTp9d1erhFm1+lBu1M+\r\naNU7kQhHZedscPX7VwlkUBV4CvRLS4MU6VL1m154BiOwi+Q7jc6ukXskMKyNBAo4Mh+kyjViOGLF\r\nc5B454jVNByZjlH3pDLIX7nTNbeArlEsGEXlrVH86m7RUCfqu92uUYHhGjnV3c6mEYJRVMbpTNdI\r\ngZGroc7lGoWpoc6J0ynXSG0aUXX3AeEaRfTqbn3TyK7v1iJ1NN49zmyoq3VujVQKAEe8KUqn4nSu\r\nEgYc8dZdozDDEYvFYjhqDbE6xzWCmHV1l2uk1cHqRQyq7eirQy0JjiqhyJ8NvswMSLPgKC09E+bl\r\nlpzR76/fu1AbCtSPdzXXiB6kQxw42pPmFDForlGoqi8/VFks1lnAkQCj7kk7oSC3Qr5WV3iU5oj4\r\ns3L6RaRuiytSVxw7+Pq116aR9+ArlTA0fGrvGuGtUdQuYohtqFNgFI13a6Q2jezq7ulSMlLn2jWy\r
\nb40OiFsju6GO4nT64Os4Z6POGHxVjtFIzze63K6RerMrjG94VXm1jvLrOIvFYjhqURo9ejRETx10\r\nihhO1WlDggKMxFaGLGH4zlXE8K2AI7WVcbS+tEXB0V+rhr0feB7uinca02Wjkcqnu+IX1kOU7o32\r\nCOfoRAW31bFYrDNXly7rLCiqNAZfzYY67zhd1G6oUyUM7k0jbez1a5drdExzjbQ4HQ2+Nvht1yji\r\nAiPDNTIcI901yhYNdYe9q7vDMYOvWcbga/xNI+UaaYOvtd6Dr86bXMOMeHR47yuaa/SymQKQSQB+\r\nHWexWAxHLVgTJvgsoNmlNdTtM1vqvjMjdWZEQ7wLiQ/aqKyDDR3bClWVu38kcFQB39WMd0XqdNco\r\n3a57te+N5MM0vHeQK1L3J6j4/FUYM2YMP1RZLNaZx6Ot12njLlTfNJKNolFZ3S3AaCvBUSNpswVE\r\nFhx9HesaOXE689Yo0pAnbo2OKjiSYKRVdwvlyDIGB46i6BrVizhdVLlGHiUMETtSJ1yjsOYYibHX\r\nd+3B18jBt+nOKKy5Rk6czlXCoMCoTh98dcDIfJNruGvXyEkAqNtR8/Wc4YjFYjEctWhhPW1+3lKA\r\nkLg1EpE6p747qtd3e7hG+sNWHfV+dejLHwUcBfd+og2/ZsS0GjlFDPqtkZlNV3AUruoL788YDxMn\r\nTuCHKovFOnM48nitjmqROru62941MksYVJyuEaVvGiEYHV2rxem0wdeGPGfTCEsY/uIuYVgiFFxk\r\nxukQjIJx7ozqswUcWWCkGurCVMBg6bDHrtHBLAlGWgkDtdM5JQwKjMw4nV7EoBXquEsY5JtcTVV3\r\nqxFvfD0P8+0oi8ViOGrZKi3dSi/k2wPr7G0jOFXj2jbabRz22rtGGhyJrYwttK6O70IiILVeB6lC\r\ngpGTUQ/Jh2lYKuR6pzEkD3f1hrqQdmvknz+
KIo4zZszghyqLxTpLOBJxOsPh/9bLNXIcIwFHG+2G\r\nOuEarffeNdLidMo1itDYq7NpZJcwaI5RjGuk7xphdTfeGqmGusOqhGGO1lDndo0cx0jcGalI3WS7\r\niCFi7Br5PFyjTGOGwdmoGyFLGBzHSLj/0jXSItL263kV346yWCyGo1alQGALjBs3Ftbk
<TRUNCATED>
[31/50] [abbrv] airavata git commit: fixed typo
Posted by sh...@apache.org.
fixed typo
Project: http://git-wip-us.apache.org/repos/asf/airavata/repo
Commit: http://git-wip-us.apache.org/repos/asf/airavata/commit/48192d98
Tree: http://git-wip-us.apache.org/repos/asf/airavata/tree/48192d98
Diff: http://git-wip-us.apache.org/repos/asf/airavata/diff/48192d98
Branch: refs/heads/master
Commit: 48192d98f48f381d039decb3712512336610e533
Parents: 9700459
Author: shamrath <sh...@gmail.com>
Authored: Fri Mar 13 14:42:06 2015 -0400
Committer: shamrath <sh...@gmail.com>
Committed: Fri Mar 13 14:42:06 2015 -0400
----------------------------------------------------------------------
.../simple/workflow/engine/SimpleWorkflowInterpreter.java | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/airavata/blob/48192d98/modules/simple-workflow/src/main/java/org/apache/airavata/simple/workflow/engine/SimpleWorkflowInterpreter.java
----------------------------------------------------------------------
diff --git a/modules/simple-workflow/src/main/java/org/apache/airavata/simple/workflow/engine/SimpleWorkflowInterpreter.java b/modules/simple-workflow/src/main/java/org/apache/airavata/simple/workflow/engine/SimpleWorkflowInterpreter.java
index 5504f84..191988c 100644
--- a/modules/simple-workflow/src/main/java/org/apache/airavata/simple/workflow/engine/SimpleWorkflowInterpreter.java
+++ b/modules/simple-workflow/src/main/java/org/apache/airavata/simple/workflow/engine/SimpleWorkflowInterpreter.java
@@ -123,7 +123,7 @@ class SimpleWorkflowInterpreter{
sb.append("=");
sb.append(workflowInputNode.getInputObject().getValue());
}
- throw new AiravataException("No workflow application node in ready state to run with experiment inputs" + sb.toString());
+ throw new AiravataException("No workflow application node is in ready state to run with experiment inputs" + sb.toString());
}
processReadyList();
}
@@ -136,7 +136,7 @@ class SimpleWorkflowInterpreter{
*/
void processReadyList() throws RegistryException, AiravataException {
if (readyList.isEmpty() && processingQueue.isEmpty() && !waitingList.isEmpty()) {
- throw new AiravataException("No workflow application node in ready state to run");
+ throw new AiravataException("No workflow application node is in ready state to run");
}
for (WorkflowNode readyNode : readyList.values()) {
if (readyNode instanceof WorkflowOutputNode) {
[49/50] [abbrv] airavata git commit: Merge branch
'new-workflow-design'
Posted by sh...@apache.org.
Merge branch 'new-workflow-design'
Project: http://git-wip-us.apache.org/repos/asf/airavata/repo
Commit: http://git-wip-us.apache.org/repos/asf/airavata/commit/220e0419
Tree: http://git-wip-us.apache.org/repos/asf/airavata/tree/220e0419
Diff: http://git-wip-us.apache.org/repos/asf/airavata/diff/220e0419
Branch: refs/heads/master
Commit: 220e041937dd35da5f440fc6c43c546ded01e923
Parents: 4031e50 509f203
Author: shamrath <sh...@gmail.com>
Authored: Wed Mar 25 16:25:48 2015 -0400
Committer: shamrath <sh...@gmail.com>
Committed: Wed Mar 25 16:25:48 2015 -0400
----------------------------------------------------------------------
airavata-api/airavata-api-server/pom.xml | 7 +-
.../server/handler/AiravataServerHandler.java | 3 +-
.../api/server/util/DataModelUtils.java | 3 +-
.../main/resources/airavata-server.properties | 2 +-
.../main/resources/airavata-server.properties | 2 +-
.../airavata-orchestrator-service/pom.xml | 7 +-
.../server/OrchestratorServerHandler.java | 2 +-
.../orchestrator/util/DataModelUtils.java | 5 +-
.../client/OrchestratorClientFactoryTest.java | 2 -
modules/simple-workflow/pom.xml | 70 ---
.../simple/workflow/engine/ProcessContext.java | 62 --
.../engine/SimpleWorkflowInterpreter.java | 400 -------------
.../engine/WorkflowEnactmentService.java | 183 ------
.../simple/workflow/engine/WorkflowFactory.java | 31 -
.../workflow/engine/WorkflowFactoryImpl.java | 74 ---
.../simple/workflow/engine/WorkflowParser.java | 32 -
.../workflow/engine/dag/edge/DirectedEdge.java | 52 --
.../simple/workflow/engine/dag/edge/Edge.java | 43 --
.../engine/dag/nodes/ApplicationNode.java | 41 --
.../engine/dag/nodes/ApplicationNodeImpl.java | 116 ----
.../workflow/engine/dag/nodes/NodeState.java | 44 --
.../workflow/engine/dag/nodes/NodeType.java | 28 -
.../engine/dag/nodes/WorkflowInputNode.java | 37 --
.../engine/dag/nodes/WorkflowInputNodeImpl.java | 99 ----
.../workflow/engine/dag/nodes/WorkflowNode.java | 38 --
.../engine/dag/nodes/WorkflowOutputNode.java | 37 --
.../dag/nodes/WorkflowOutputNodeImpl.java | 100 ----
.../simple/workflow/engine/dag/port/InPort.java | 41 --
.../workflow/engine/dag/port/InputPortIml.java | 91 ---
.../workflow/engine/dag/port/OutPort.java | 39 --
.../workflow/engine/dag/port/OutPortImpl.java | 83 ---
.../simple/workflow/engine/dag/port/Port.java | 36 --
.../engine/parser/AiravataWorkflowParser.java | 291 ---------
.../workflow/engine/parser/PortContainer.java | 53 --
.../simple/workflow/engine/WorkflowDAGTest.java | 46 --
.../parser/AiravataWorkflowParserTest.java | 119 ----
.../src/test/resources/ComplexMathWorkflow.awf | 465 ---------------
modules/workflow/pom.xml | 22 +
modules/workflow/workflow-core/pom.xml | 74 +++
.../airavata/workflow/core/ProcessContext.java | 62 ++
.../core/SimpleWorkflowInterpreter.java | 400 +++++++++++++
.../workflow/core/WorkflowEnactmentService.java | 183 ++++++
.../airavata/workflow/core/WorkflowFactory.java | 31 +
.../workflow/core/WorkflowFactoryImpl.java | 74 +++
.../airavata/workflow/core/WorkflowParser.java | 32 +
.../workflow/core/dag/edge/DirectedEdge.java | 52 ++
.../airavata/workflow/core/dag/edge/Edge.java | 43 ++
.../core/dag/nodes/ApplicationNode.java | 41 ++
.../core/dag/nodes/ApplicationNodeImpl.java | 116 ++++
.../workflow/core/dag/nodes/NodeState.java | 44 ++
.../workflow/core/dag/nodes/NodeType.java | 28 +
.../core/dag/nodes/WorkflowInputNode.java | 37 ++
.../core/dag/nodes/WorkflowInputNodeImpl.java | 99 ++++
.../workflow/core/dag/nodes/WorkflowNode.java | 38 ++
.../core/dag/nodes/WorkflowOutputNode.java | 37 ++
.../core/dag/nodes/WorkflowOutputNodeImpl.java | 100 ++++
.../airavata/workflow/core/dag/port/InPort.java | 41 ++
.../workflow/core/dag/port/InputPortIml.java | 91 +++
.../workflow/core/dag/port/OutPort.java | 39 ++
.../workflow/core/dag/port/OutPortImpl.java | 83 +++
.../airavata/workflow/core/dag/port/Port.java | 36 ++
.../core/parser/AiravataWorkflowParser.java | 291 +++++++++
.../workflow/core/parser/PortContainer.java | 53 ++
.../airavata/workflow/core/WorkflowDAGTest.java | 46 ++
.../core/parser/AiravataWorkflowParserTest.java | 119 ++++
.../src/test/resources/ComplexMathWorkflow.awf | 465 +++++++++++++++
.../test/resources/ParamChemApplicationTest.awf | 593 +++++++++++++++++++
pom.xml | 2 +-
68 files changed, 3384 insertions(+), 2772 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/airavata/blob/220e0419/modules/configuration/server/src/main/resources/airavata-server.properties
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/airavata/blob/220e0419/modules/credential-store/credential-store-webapp/src/main/resources/airavata-server.properties
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/airavata/blob/220e0419/modules/orchestrator/airavata-orchestrator-service/src/main/java/org/apache/airavata/orchestrator/server/OrchestratorServerHandler.java
----------------------------------------------------------------------
[03/50] [abbrv] airavata git commit: Handle ouptprt of application
nodes and workflowOutputNodes
Posted by sh...@apache.org.
Handle ouptprt of application nodes and workflowOutputNodes
Project: http://git-wip-us.apache.org/repos/asf/airavata/repo
Commit: http://git-wip-us.apache.org/repos/asf/airavata/commit/9445b7a1
Tree: http://git-wip-us.apache.org/repos/asf/airavata/tree/9445b7a1
Diff: http://git-wip-us.apache.org/repos/asf/airavata/diff/9445b7a1
Branch: refs/heads/master
Commit: 9445b7a10596c509cbe7950a470add94b3deb32a
Parents: e3ce93e
Author: shamrath <sh...@gmail.com>
Authored: Mon Feb 16 11:19:18 2015 -0500
Committer: shamrath <sh...@gmail.com>
Committed: Mon Feb 16 11:19:18 2015 -0500
----------------------------------------------------------------------
.../workflow/engine/dag/edge/DirectedEdge.java | 8 +-
.../engine/dag/nodes/ApplicationNode.java | 4 +-
.../engine/dag/nodes/ApplicationNodeImpl.java | 28 +-
.../engine/dag/nodes/WorkflowInputNode.java | 2 +
.../engine/dag/nodes/WorkflowInputNodeImpl.java | 19 +-
.../engine/dag/nodes/WorkflowOutputNode.java | 7 +-
.../dag/nodes/WorkflowOutputNodeImpl.java | 26 +-
.../workflow/engine/dag/port/InputPortIml.java | 13 +-
.../workflow/engine/dag/port/OutPortImpl.java | 21 +-
.../engine/parser/AiravataDefaultParser.java | 50 +-
.../simple/workflow/engine/WorkflowDAGTest.java | 2 +
.../parser/AiravataDefaultParserTest.java | 71 +++
.../src/test/resources/ComplexMathWorkflow.awf | 465 +++++++++++++++++++
13 files changed, 664 insertions(+), 52 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/airavata/blob/9445b7a1/modules/simple-workflow/src/main/java/org/apache/ariavata/simple/workflow/engine/dag/edge/DirectedEdge.java
----------------------------------------------------------------------
diff --git a/modules/simple-workflow/src/main/java/org/apache/ariavata/simple/workflow/engine/dag/edge/DirectedEdge.java b/modules/simple-workflow/src/main/java/org/apache/ariavata/simple/workflow/engine/dag/edge/DirectedEdge.java
index 4b05740..000cd06 100644
--- a/modules/simple-workflow/src/main/java/org/apache/ariavata/simple/workflow/engine/dag/edge/DirectedEdge.java
+++ b/modules/simple-workflow/src/main/java/org/apache/ariavata/simple/workflow/engine/dag/edge/DirectedEdge.java
@@ -11,21 +11,21 @@ public class DirectedEdge implements Edge {
@Override
public InPort getToPort() {
- return null; // TODO: Auto generated method body.
+ return inPort;
}
@Override
public void setToPort(InPort inPort) {
- // TODO: Auto generated method body.
+ this.inPort = inPort;
}
@Override
public OutPort getFromPort() {
- return null; // TODO: Auto generated method body.
+ return outPort;
}
@Override
public void setFromPort(OutPort outPort) {
- // TODO: Auto generated method body.
+ this.outPort = outPort;
}
}
http://git-wip-us.apache.org/repos/asf/airavata/blob/9445b7a1/modules/simple-workflow/src/main/java/org/apache/ariavata/simple/workflow/engine/dag/nodes/ApplicationNode.java
----------------------------------------------------------------------
diff --git a/modules/simple-workflow/src/main/java/org/apache/ariavata/simple/workflow/engine/dag/nodes/ApplicationNode.java b/modules/simple-workflow/src/main/java/org/apache/ariavata/simple/workflow/engine/dag/nodes/ApplicationNode.java
index cd2a955..6ab5754 100644
--- a/modules/simple-workflow/src/main/java/org/apache/ariavata/simple/workflow/engine/dag/nodes/ApplicationNode.java
+++ b/modules/simple-workflow/src/main/java/org/apache/ariavata/simple/workflow/engine/dag/nodes/ApplicationNode.java
@@ -30,11 +30,11 @@ public interface ApplicationNode extends WorkflowNode {
public String getApplicationId();
-// public void addInputPort(InPort inPort);
+ public void addInPort(InPort inPort);
public List<InPort> getInputPorts();
-// public void addOutputPort(OutPort outPort);
+ public void addOutPort(OutPort outPort);
public List<OutPort> getOutputPorts();
http://git-wip-us.apache.org/repos/asf/airavata/blob/9445b7a1/modules/simple-workflow/src/main/java/org/apache/ariavata/simple/workflow/engine/dag/nodes/ApplicationNodeImpl.java
----------------------------------------------------------------------
diff --git a/modules/simple-workflow/src/main/java/org/apache/ariavata/simple/workflow/engine/dag/nodes/ApplicationNodeImpl.java b/modules/simple-workflow/src/main/java/org/apache/ariavata/simple/workflow/engine/dag/nodes/ApplicationNodeImpl.java
index 9388c43..fd7e3c7 100644
--- a/modules/simple-workflow/src/main/java/org/apache/ariavata/simple/workflow/engine/dag/nodes/ApplicationNodeImpl.java
+++ b/modules/simple-workflow/src/main/java/org/apache/ariavata/simple/workflow/engine/dag/nodes/ApplicationNodeImpl.java
@@ -26,6 +26,7 @@ package org.apache.ariavata.simple.workflow.engine.dag.nodes;
import org.apache.ariavata.simple.workflow.engine.dag.port.InPort;
import org.apache.ariavata.simple.workflow.engine.dag.port.OutPort;
+import java.util.ArrayList;
import java.util.List;
public class ApplicationNodeImpl implements ApplicationNode {
@@ -33,6 +34,8 @@ public class ApplicationNodeImpl implements ApplicationNode {
private final String nodeId;
private NodeState myState = NodeState.WAITING;
private String applicationId;
+ private List<InPort> inPorts = new ArrayList<InPort>();
+ private List<OutPort> outPorts = new ArrayList<OutPort>();
public ApplicationNodeImpl(String nodeId) {
this(nodeId, null);
@@ -50,7 +53,7 @@ public class ApplicationNodeImpl implements ApplicationNode {
@Override
public String getNodeName() {
- return null; // TODO: Auto generated method body.
+ return this.getNodeName();
}
@Override
@@ -71,21 +74,36 @@ public class ApplicationNodeImpl implements ApplicationNode {
@Override
public boolean isSatisfy() {
- return false; // TODO: Auto generated method body.
+ for (InPort inPort : getInputPorts()) {
+ if (!inPort.isSatisfy()) {
+ return false;
+ }
+ }
+ return true;
}
@Override
public String getApplicationId() {
- return null; // TODO: Auto generated method body.
+ return this.applicationId;
+ }
+
+ @Override
+ public void addInPort(InPort inPort) {
+ this.inPorts.add(inPort);
}
@Override
public List<InPort> getInputPorts() {
- return null; // TODO: Auto generated method body.
+ return this.inPorts;
+ }
+
+ @Override
+ public void addOutPort(OutPort outPort) {
+ this.outPorts.add(outPort);
}
@Override
public List<OutPort> getOutputPorts() {
- return null; // TODO: Auto generated method body.
+ return this.outPorts;
}
}
http://git-wip-us.apache.org/repos/asf/airavata/blob/9445b7a1/modules/simple-workflow/src/main/java/org/apache/ariavata/simple/workflow/engine/dag/nodes/WorkflowInputNode.java
----------------------------------------------------------------------
diff --git a/modules/simple-workflow/src/main/java/org/apache/ariavata/simple/workflow/engine/dag/nodes/WorkflowInputNode.java b/modules/simple-workflow/src/main/java/org/apache/ariavata/simple/workflow/engine/dag/nodes/WorkflowInputNode.java
index 8d24c96..b27fdea 100644
--- a/modules/simple-workflow/src/main/java/org/apache/ariavata/simple/workflow/engine/dag/nodes/WorkflowInputNode.java
+++ b/modules/simple-workflow/src/main/java/org/apache/ariavata/simple/workflow/engine/dag/nodes/WorkflowInputNode.java
@@ -35,4 +35,6 @@ public interface WorkflowInputNode extends WorkflowNode {
public OutPort getOutPort();
+ public void setOutPort(OutPort outPort);
+
}
http://git-wip-us.apache.org/repos/asf/airavata/blob/9445b7a1/modules/simple-workflow/src/main/java/org/apache/ariavata/simple/workflow/engine/dag/nodes/WorkflowInputNodeImpl.java
----------------------------------------------------------------------
diff --git a/modules/simple-workflow/src/main/java/org/apache/ariavata/simple/workflow/engine/dag/nodes/WorkflowInputNodeImpl.java b/modules/simple-workflow/src/main/java/org/apache/ariavata/simple/workflow/engine/dag/nodes/WorkflowInputNodeImpl.java
index 31bd6b0..0f6ea92 100644
--- a/modules/simple-workflow/src/main/java/org/apache/ariavata/simple/workflow/engine/dag/nodes/WorkflowInputNodeImpl.java
+++ b/modules/simple-workflow/src/main/java/org/apache/ariavata/simple/workflow/engine/dag/nodes/WorkflowInputNodeImpl.java
@@ -30,6 +30,8 @@ public class WorkflowInputNodeImpl implements WorkflowInputNode {
private NodeState myState = NodeState.READY;
private final String nodeId;
private String nodeName;
+ private OutPort outPort;
+ private InputDataObjectType inputDataObjectType;
public WorkflowInputNodeImpl(String nodeId) {
this(nodeId, null);
@@ -42,12 +44,12 @@ public class WorkflowInputNodeImpl implements WorkflowInputNode {
@Override
public String getNodeId() {
- return null;
+ return this.nodeId;
}
@Override
public String getNodeName() {
- return null; // TODO: Auto generated method body.
+ return this.nodeName;
}
@Override
@@ -68,22 +70,27 @@ public class WorkflowInputNodeImpl implements WorkflowInputNode {
@Override
public boolean isSatisfy() {
- return false; // TODO: Auto generated method body.
+ return inputDataObjectType.getValue() != null && !inputDataObjectType.getValue().equals("");
}
@Override
public InputDataObjectType getInputObject() {
- return null; // TODO: Auto generated method body.
+ return this.inputDataObjectType;
}
@Override
public void setInputObject(InputDataObjectType inputObject) {
- // TODO: Auto generated method body.
+ this.inputDataObjectType = inputObject;
}
@Override
public OutPort getOutPort() {
- return null; // TODO: Auto generated method body.
+ return this.outPort;
+ }
+
+ @Override
+ public void setOutPort(OutPort outPort) {
+ this.outPort = outPort;
}
http://git-wip-us.apache.org/repos/asf/airavata/blob/9445b7a1/modules/simple-workflow/src/main/java/org/apache/ariavata/simple/workflow/engine/dag/nodes/WorkflowOutputNode.java
----------------------------------------------------------------------
diff --git a/modules/simple-workflow/src/main/java/org/apache/ariavata/simple/workflow/engine/dag/nodes/WorkflowOutputNode.java b/modules/simple-workflow/src/main/java/org/apache/ariavata/simple/workflow/engine/dag/nodes/WorkflowOutputNode.java
index 55e1268..a1ff6d4 100644
--- a/modules/simple-workflow/src/main/java/org/apache/ariavata/simple/workflow/engine/dag/nodes/WorkflowOutputNode.java
+++ b/modules/simple-workflow/src/main/java/org/apache/ariavata/simple/workflow/engine/dag/nodes/WorkflowOutputNode.java
@@ -23,11 +23,16 @@ package org.apache.ariavata.simple.workflow.engine.dag.nodes;
import org.apache.airavata.model.appcatalog.appinterface.OutputDataObjectType;
import org.apache.ariavata.simple.workflow.engine.dag.edge.Edge;
+import org.apache.ariavata.simple.workflow.engine.dag.port.InPort;
public interface WorkflowOutputNode extends WorkflowNode {
public OutputDataObjectType getOutputObject();
- public Edge getInputLink();
+ public void setOutputObject(OutputDataObjectType outputObject);
+
+ public InPort getInPort();
+
+ public void setInPort(InPort inPort);
}
http://git-wip-us.apache.org/repos/asf/airavata/blob/9445b7a1/modules/simple-workflow/src/main/java/org/apache/ariavata/simple/workflow/engine/dag/nodes/WorkflowOutputNodeImpl.java
----------------------------------------------------------------------
diff --git a/modules/simple-workflow/src/main/java/org/apache/ariavata/simple/workflow/engine/dag/nodes/WorkflowOutputNodeImpl.java b/modules/simple-workflow/src/main/java/org/apache/ariavata/simple/workflow/engine/dag/nodes/WorkflowOutputNodeImpl.java
index 36ab1f6..ec3a1ea 100644
--- a/modules/simple-workflow/src/main/java/org/apache/ariavata/simple/workflow/engine/dag/nodes/WorkflowOutputNodeImpl.java
+++ b/modules/simple-workflow/src/main/java/org/apache/ariavata/simple/workflow/engine/dag/nodes/WorkflowOutputNodeImpl.java
@@ -25,12 +25,15 @@ package org.apache.ariavata.simple.workflow.engine.dag.nodes;
import org.apache.airavata.model.appcatalog.appinterface.OutputDataObjectType;
import org.apache.ariavata.simple.workflow.engine.dag.edge.Edge;
+import org.apache.ariavata.simple.workflow.engine.dag.port.InPort;
public class WorkflowOutputNodeImpl implements WorkflowOutputNode {
private NodeState myState = NodeState.WAITING;
private final String nodeId;
private String nodeName;
+ private OutputDataObjectType outputDataObjectType;
+ private InPort inPort;
public WorkflowOutputNodeImpl(String nodeId) {
this(nodeId, null);
@@ -43,12 +46,12 @@ public class WorkflowOutputNodeImpl implements WorkflowOutputNode {
@Override
public String getNodeId() {
- return null;
+ return this.nodeId;
}
@Override
public String getNodeName() {
- return null; // TODO: Auto generated method body.
+ return this.nodeName;
}
@Override
@@ -69,17 +72,28 @@ public class WorkflowOutputNodeImpl implements WorkflowOutputNode {
@Override
public boolean isSatisfy() {
- return false; // TODO: Auto generated method body.
+ return this.outputDataObjectType.getValue() != null && !this.outputDataObjectType.getValue().equals("");
}
@Override
public OutputDataObjectType getOutputObject() {
- return null; // TODO: Auto generated method body.
+ return this.outputDataObjectType;
}
@Override
- public Edge getInputLink() {
- return null; // TODO: Auto generated method body.
+ public void setOutputObject(OutputDataObjectType outputObject) {
+ this.outputDataObjectType = outputObject;
}
+
+ @Override
+ public InPort getInPort() {
+ return this.inPort;
+ }
+
+ @Override
+ public void setInPort(InPort inPort) {
+ this.inPort = inPort;
+ }
+
}
http://git-wip-us.apache.org/repos/asf/airavata/blob/9445b7a1/modules/simple-workflow/src/main/java/org/apache/ariavata/simple/workflow/engine/dag/port/InputPortIml.java
----------------------------------------------------------------------
diff --git a/modules/simple-workflow/src/main/java/org/apache/ariavata/simple/workflow/engine/dag/port/InputPortIml.java b/modules/simple-workflow/src/main/java/org/apache/ariavata/simple/workflow/engine/dag/port/InputPortIml.java
index b33b91b..629a832 100644
--- a/modules/simple-workflow/src/main/java/org/apache/ariavata/simple/workflow/engine/dag/port/InputPortIml.java
+++ b/modules/simple-workflow/src/main/java/org/apache/ariavata/simple/workflow/engine/dag/port/InputPortIml.java
@@ -30,6 +30,7 @@ public class InputPortIml implements InPort {
private boolean isSatisfy = false;
private String portId;
private Edge edge;
+ private WorkflowNode node;
public InputPortIml(String portId) {
this.portId = portId;
@@ -37,12 +38,12 @@ public class InputPortIml implements InPort {
@Override
public void setInputObject(InputDataObjectType inputObject) {
- // TODO: Auto generated method body.
+ this.inputDataObjectType = inputObject;
}
@Override
public InputDataObjectType getInputObject() {
- return null; // TODO: Auto generated method body.
+ return this.inputDataObjectType;
}
@Override
@@ -57,22 +58,22 @@ public class InputPortIml implements InPort {
@Override
public boolean isSatisfy() {
- return false; // TODO: Auto generated method body.
+ return inputDataObjectType.getValue() != null && !inputDataObjectType.getValue().equals("");
}
@Override
public WorkflowNode getNode() {
- return null; // TODO: Auto generated method body.
+ return this.node;
}
@Override
public void setNode(WorkflowNode workflowNode) {
- // TODO: Auto generated method body.
+ this.node = workflowNode;
}
@Override
public String getId() {
- return null; // TODO: Auto generated method body.
+ return this.portId;
}
}
http://git-wip-us.apache.org/repos/asf/airavata/blob/9445b7a1/modules/simple-workflow/src/main/java/org/apache/ariavata/simple/workflow/engine/dag/port/OutPortImpl.java
----------------------------------------------------------------------
diff --git a/modules/simple-workflow/src/main/java/org/apache/ariavata/simple/workflow/engine/dag/port/OutPortImpl.java b/modules/simple-workflow/src/main/java/org/apache/ariavata/simple/workflow/engine/dag/port/OutPortImpl.java
index bc7628f..35b8c3b 100644
--- a/modules/simple-workflow/src/main/java/org/apache/ariavata/simple/workflow/engine/dag/port/OutPortImpl.java
+++ b/modules/simple-workflow/src/main/java/org/apache/ariavata/simple/workflow/engine/dag/port/OutPortImpl.java
@@ -4,6 +4,7 @@ import org.apache.airavata.model.appcatalog.appinterface.OutputDataObjectType;
import org.apache.ariavata.simple.workflow.engine.dag.edge.Edge;
import org.apache.ariavata.simple.workflow.engine.dag.nodes.WorkflowNode;
+import java.util.ArrayList;
import java.util.List;
/**
@@ -12,9 +13,10 @@ import java.util.List;
public class OutPortImpl implements OutPort {
private OutputDataObjectType outputDataObjectType;
- private List<Edge> outEdges;
+ private List<Edge> outEdges = new ArrayList<Edge>();
private boolean isSatisfy = false;
private String portId;
+ private WorkflowNode node;
public OutPortImpl(String portId) {
this.portId = portId;
@@ -22,41 +24,42 @@ public class OutPortImpl implements OutPort {
@Override
public void setOutputObject(OutputDataObjectType outputObject) {
- // TODO: Auto generated method body.
+ this.outputDataObjectType = outputObject;
}
@Override
public OutputDataObjectType getOutputObject() {
- return null; // TODO: Auto generated method body.
+ return this.outputDataObjectType;
}
@Override
public List<Edge> getOutEdges() {
- return null; // TODO: Auto generated method body.
+ return this.outEdges;
}
@Override
public void addEdge(Edge edge) {
- // TODO: Auto generated method body.
+ this.outEdges.add(edge);
}
@Override
public boolean isSatisfy() {
- return false; // TODO: Auto generated method body.
+ return this.outputDataObjectType.getValue() != null
+ && !this.outputDataObjectType.getValue().equals("");
}
@Override
public WorkflowNode getNode() {
- return null; // TODO: Auto generated method body.
+ return this.node;
}
@Override
public void setNode(WorkflowNode workflowNode) {
- // TODO: Auto generated method body.
+ this.node = workflowNode;
}
@Override
public String getId() {
- return null; // TODO: Auto generated method body.
+ return portId;
}
}
http://git-wip-us.apache.org/repos/asf/airavata/blob/9445b7a1/modules/simple-workflow/src/main/java/org/apache/ariavata/simple/workflow/engine/parser/AiravataDefaultParser.java
----------------------------------------------------------------------
diff --git a/modules/simple-workflow/src/main/java/org/apache/ariavata/simple/workflow/engine/parser/AiravataDefaultParser.java b/modules/simple-workflow/src/main/java/org/apache/ariavata/simple/workflow/engine/parser/AiravataDefaultParser.java
index 92e9811..d2095c8 100644
--- a/modules/simple-workflow/src/main/java/org/apache/ariavata/simple/workflow/engine/parser/AiravataDefaultParser.java
+++ b/modules/simple-workflow/src/main/java/org/apache/ariavata/simple/workflow/engine/parser/AiravataDefaultParser.java
@@ -3,6 +3,7 @@ package org.apache.ariavata.simple.workflow.engine.parser;
import org.airavata.appcatalog.cpi.AppCatalogException;
import org.airavata.appcatalog.cpi.WorkflowCatalog;
import org.apache.aiaravata.application.catalog.data.impl.AppCatalogFactory;
+import org.apache.aiaravata.application.catalog.data.model.WorkflowOutput;
import org.apache.airavata.model.appcatalog.appinterface.InputDataObjectType;
import org.apache.airavata.model.appcatalog.appinterface.OutputDataObjectType;
import org.apache.airavata.model.workspace.experiment.Experiment;
@@ -31,6 +32,8 @@ import org.apache.ariavata.simple.workflow.engine.dag.nodes.ApplicationNodeImpl;
import org.apache.ariavata.simple.workflow.engine.dag.nodes.WorkflowInputNode;
import org.apache.ariavata.simple.workflow.engine.dag.nodes.WorkflowInputNodeImpl;
import org.apache.ariavata.simple.workflow.engine.dag.nodes.WorkflowNode;
+import org.apache.ariavata.simple.workflow.engine.dag.nodes.WorkflowOutputNode;
+import org.apache.ariavata.simple.workflow.engine.dag.nodes.WorkflowOutputNodeImpl;
import org.apache.ariavata.simple.workflow.engine.dag.port.InPort;
import org.apache.ariavata.simple.workflow.engine.dag.port.InputPortIml;
import org.apache.ariavata.simple.workflow.engine.dag.port.OutPort;
@@ -51,8 +54,14 @@ public class AiravataDefaultParser implements WorkflowParser {
private String experimentId;
private String credentialToken ;
private Workflow workflow;
+
+ // TODO : remove this setter method
+ public void setExperiment(Experiment experiment) {
+ this.experiment = experiment;
+ }
+
private Experiment experiment;
- private Map<String, ApplicationNode> wfNodes = new HashMap<String, ApplicationNode>();
+ private Map<String, WorkflowNode> wfNodes = new HashMap<String, WorkflowNode>();
public AiravataDefaultParser(String experimentId, String credentialToken) {
@@ -66,7 +75,7 @@ public class AiravataDefaultParser implements WorkflowParser {
return parseWorkflow(getWorkflowFromExperiment());
}
- private List<WorkflowInputNode> parseWorkflow(Workflow workflow) {
+ public List<WorkflowInputNode> parseWorkflow(Workflow workflow) {
List<Node> gNodes = getInputNodes(workflow);
List<WorkflowInputNode> wfInputNodes = new ArrayList<WorkflowInputNode>();
List<PortContainer> portContainers = new ArrayList<PortContainer>();
@@ -85,7 +94,8 @@ public class AiravataDefaultParser implements WorkflowParser {
if (wfInputNode.getInputObject() == null) {
// TODO: throw an error and exit.
}
- for (DataPort dataPort : gNode.getInputPorts()) {
+ portContainers.addAll(processOutPorts(gNode, wfInputNode));
+/* for (DataPort dataPort : gNode.getOutputPorts()) {
outPort = new OutPortImpl(dataPort.getID());
for (DataEdge dataEdge : dataPort.getEdges()) {
edge = new DirectedEdge();
@@ -96,8 +106,8 @@ public class AiravataDefaultParser implements WorkflowParser {
inPort.addEdge(edge);
portContainers.add(new PortContainer(dataEdge.getToPort(), inPort));
}
- outPort.setOutputObject(getOutputDataObject(wfInputNode.getInputObject()));
- }
+// outPort.setOutputObject(getOutputDataObject(wfInputNode.getInputObject()));
+ }*/
wfInputNodes.add(wfInputNode);
}
@@ -114,7 +124,8 @@ public class AiravataDefaultParser implements WorkflowParser {
}
DataPort dataPort = null;
InPort inPort = null;
- WorkflowNode wfNode = null;
+ ApplicationNode wfApplicationNode = null;
+ WorkflowOutputNode wfOutportNode = null;
List<PortContainer> nextPortContainerList = new ArrayList<PortContainer>();
for (PortContainer portContainer : portContainerList) {
dataPort = portContainer.getDataPort();
@@ -123,17 +134,21 @@ public class AiravataDefaultParser implements WorkflowParser {
inPort.setInputObject(getInputDataObject(dataPort));
if (node instanceof WSNode) {
WSNode wsNode = (WSNode) node;
- wfNode = wfNodes.get(wsNode.getID());
- if (wfNode == null) {
- wfNode = new ApplicationNodeImpl(wsNode.getID(),
+ wfApplicationNode = (ApplicationNode) wfNodes.get(wsNode.getID());
+ if (wfApplicationNode == null) {
+ wfApplicationNode = new ApplicationNodeImpl(wsNode.getID(),
wsNode.getComponent().getApplication().getApplicationId());
- nextPortContainerList.addAll(processOutPorts(wsNode, wfNode));
+ wfNodes.put(wfApplicationNode.getNodeId(), wfApplicationNode);
+ nextPortContainerList.addAll(processOutPorts(wsNode, wfApplicationNode));
}
+ inPort.setNode(wfApplicationNode);
+ wfApplicationNode.addInPort(inPort);
+
}else if (node instanceof OutputNode) {
OutputNode oNode = (OutputNode) node;
- wfNode = new WorkflowInputNodeImpl(oNode.getID(), oNode.getName());
+ wfOutportNode = new WorkflowOutputNodeImpl(oNode.getID(), oNode.getName());
+ wfOutportNode.setInPort(inPort);
}
- inPort.setNode(wfNode);
buildModel(nextPortContainerList);
// set the workflow node to inPort
// if require check the types of inputs and output ports,
@@ -148,7 +163,7 @@ public class AiravataDefaultParser implements WorkflowParser {
private List<PortContainer> processOutPorts(Node node, WorkflowNode wfNode) {
OutPort outPort ;
Edge edge;
- InPort inPort;
+ InPort inPort = null;
List<PortContainer> portContainers = new ArrayList<PortContainer>();
for (DataPort dataPort : node.getOutputPorts()) {
outPort = new OutPortImpl(dataPort.getID());
@@ -161,6 +176,15 @@ public class AiravataDefaultParser implements WorkflowParser {
inPort.addEdge(edge);
portContainers.add(new PortContainer(dataEdge.getToPort(), inPort));
}
+ outPort.setNode(wfNode);
+ if (wfNode instanceof WorkflowInputNode) {
+ WorkflowInputNode workflowInputNode = (WorkflowInputNode) wfNode;
+ workflowInputNode.setOutPort(outPort);
+ }else if (wfNode instanceof ApplicationNode) {
+ ApplicationNode applicationNode = ((ApplicationNode) wfNode);
+ applicationNode.addOutPort(outPort);
+ applicationNode.addInPort(inPort);
+ }
}
return portContainers;
}
http://git-wip-us.apache.org/repos/asf/airavata/blob/9445b7a1/modules/simple-workflow/src/test/java/org/apache/ariavata/simple/workflow/engine/WorkflowDAGTest.java
----------------------------------------------------------------------
diff --git a/modules/simple-workflow/src/test/java/org/apache/ariavata/simple/workflow/engine/WorkflowDAGTest.java b/modules/simple-workflow/src/test/java/org/apache/ariavata/simple/workflow/engine/WorkflowDAGTest.java
index 4e3a120..645af42 100644
--- a/modules/simple-workflow/src/test/java/org/apache/ariavata/simple/workflow/engine/WorkflowDAGTest.java
+++ b/modules/simple-workflow/src/test/java/org/apache/ariavata/simple/workflow/engine/WorkflowDAGTest.java
@@ -21,5 +21,7 @@ public class WorkflowDAGTest {
@Test
public void testWorkflowDAG() throws Exception {
+
+
}
}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/airavata/blob/9445b7a1/modules/simple-workflow/src/test/java/org/apache/ariavata/simple/workflow/engine/parser/AiravataDefaultParserTest.java
----------------------------------------------------------------------
diff --git a/modules/simple-workflow/src/test/java/org/apache/ariavata/simple/workflow/engine/parser/AiravataDefaultParserTest.java b/modules/simple-workflow/src/test/java/org/apache/ariavata/simple/workflow/engine/parser/AiravataDefaultParserTest.java
new file mode 100644
index 0000000..0d56aa4
--- /dev/null
+++ b/modules/simple-workflow/src/test/java/org/apache/ariavata/simple/workflow/engine/parser/AiravataDefaultParserTest.java
@@ -0,0 +1,71 @@
+package org.apache.ariavata.simple.workflow.engine.parser;
+
+import junit.framework.Assert;
+import org.apache.airavata.model.appcatalog.appinterface.DataType;
+import org.apache.airavata.model.appcatalog.appinterface.InputDataObjectType;
+import org.apache.airavata.model.workspace.experiment.Experiment;
+import org.apache.airavata.workflow.model.wf.Workflow;
+import org.apache.ariavata.simple.workflow.engine.dag.nodes.WorkflowInputNode;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.FileReader;
+import java.util.ArrayList;
+import java.util.List;
+
+public class AiravataDefaultParserTest {
+
+ @Before
+ public void setUp() throws Exception {
+
+ }
+
+ @After
+ public void tearDown() throws Exception {
+
+ }
+
+ @Test
+ public void testWorkflowParse() throws Exception {
+ File jsonWfFile = new File("modules/simple-workflow/src/test/resources/ComplexMathWorkflow.awf");
+ BufferedReader br = new BufferedReader(new FileReader(jsonWfFile));
+ StringBuffer sb = new StringBuffer();
+ String nextLine = br.readLine();
+ while (nextLine != null) {
+ sb.append(nextLine);
+ nextLine = br.readLine();
+ }
+
+ Workflow workflow = new Workflow(sb.toString());
+ AiravataDefaultParser parser = new AiravataDefaultParser("testExperimentId", "testCredentialId");
+ Experiment experiment = new Experiment();
+ InputDataObjectType x = new InputDataObjectType();
+ x.setValue("6");
+ x.setType(DataType.STRING);
+ x.setName("x");
+
+ InputDataObjectType y = new InputDataObjectType();
+ y.setValue("8");
+ y.setType(DataType.STRING);
+ y.setName("y");
+
+ InputDataObjectType z = new InputDataObjectType();
+ z.setValue("10");
+ z.setType(DataType.STRING);
+ z.setName("y_2");
+
+ List<InputDataObjectType> inputs = new ArrayList<InputDataObjectType>();
+ inputs.add(x);
+ inputs.add(y);
+ inputs.add(z);
+ experiment.setExperimentInputs(inputs);
+ parser.setExperiment(experiment);
+ List<WorkflowInputNode> workflowInputNodes = parser.parseWorkflow(workflow);
+ Assert.assertNotNull(workflowInputNodes);
+ Assert.assertEquals(3, workflowInputNodes.size());
+
+ }
+}
\ No newline at end of file
[14/50] [abbrv] airavata git commit: Renamed the wrong package name
Posted by sh...@apache.org.
http://git-wip-us.apache.org/repos/asf/airavata/blob/6bfb9563/modules/simple-workflow/src/main/java/org/apache/ariavata/simple/workflow/engine/dag/port/OutPortImpl.java
----------------------------------------------------------------------
diff --git a/modules/simple-workflow/src/main/java/org/apache/ariavata/simple/workflow/engine/dag/port/OutPortImpl.java b/modules/simple-workflow/src/main/java/org/apache/ariavata/simple/workflow/engine/dag/port/OutPortImpl.java
deleted file mode 100644
index a3591ef..0000000
--- a/modules/simple-workflow/src/main/java/org/apache/ariavata/simple/workflow/engine/dag/port/OutPortImpl.java
+++ /dev/null
@@ -1,83 +0,0 @@
-/*
- *
- * 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.ariavata.simple.workflow.engine.dag.port;
-
-import org.apache.airavata.model.appcatalog.appinterface.OutputDataObjectType;
-import org.apache.ariavata.simple.workflow.engine.dag.edge.Edge;
-import org.apache.ariavata.simple.workflow.engine.dag.nodes.WorkflowNode;
-
-import java.util.ArrayList;
-import java.util.List;
-
-public class OutPortImpl implements OutPort {
-
- private OutputDataObjectType outputDataObjectType;
- private List<Edge> outEdges = new ArrayList<Edge>();
- private boolean isSatisfy = false;
- private String portId;
- private WorkflowNode node;
-
- public OutPortImpl(String portId) {
- this.portId = portId;
- }
-
- @Override
- public void setOutputObject(OutputDataObjectType outputObject) {
- this.outputDataObjectType = outputObject;
- }
-
- @Override
- public OutputDataObjectType getOutputObject() {
- return this.outputDataObjectType;
- }
-
- @Override
- public List<Edge> getOutEdges() {
- return this.outEdges;
- }
-
- @Override
- public void addEdge(Edge edge) {
- this.outEdges.add(edge);
- }
-
- @Override
- public boolean isReady() {
- return this.outputDataObjectType.getValue() != null
- && !this.outputDataObjectType.getValue().equals("");
- }
-
- @Override
- public WorkflowNode getNode() {
- return this.node;
- }
-
- @Override
- public void setNode(WorkflowNode workflowNode) {
- this.node = workflowNode;
- }
-
- @Override
- public String getId() {
- return portId;
- }
-}
http://git-wip-us.apache.org/repos/asf/airavata/blob/6bfb9563/modules/simple-workflow/src/main/java/org/apache/ariavata/simple/workflow/engine/dag/port/Port.java
----------------------------------------------------------------------
diff --git a/modules/simple-workflow/src/main/java/org/apache/ariavata/simple/workflow/engine/dag/port/Port.java b/modules/simple-workflow/src/main/java/org/apache/ariavata/simple/workflow/engine/dag/port/Port.java
deleted file mode 100644
index ad8a644..0000000
--- a/modules/simple-workflow/src/main/java/org/apache/ariavata/simple/workflow/engine/dag/port/Port.java
+++ /dev/null
@@ -1,36 +0,0 @@
-/*
- *
- * 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.ariavata.simple.workflow.engine.dag.port;
-
-import org.apache.ariavata.simple.workflow.engine.dag.nodes.WorkflowNode;
-
-public interface Port {
-
- public boolean isReady();
-
- public WorkflowNode getNode();
-
- public void setNode(WorkflowNode workflowNode);
-
- public String getId();
-
-}
http://git-wip-us.apache.org/repos/asf/airavata/blob/6bfb9563/modules/simple-workflow/src/main/java/org/apache/ariavata/simple/workflow/engine/parser/AiravataDefaultParser.java
----------------------------------------------------------------------
diff --git a/modules/simple-workflow/src/main/java/org/apache/ariavata/simple/workflow/engine/parser/AiravataDefaultParser.java b/modules/simple-workflow/src/main/java/org/apache/ariavata/simple/workflow/engine/parser/AiravataDefaultParser.java
deleted file mode 100644
index 2961fde..0000000
--- a/modules/simple-workflow/src/main/java/org/apache/ariavata/simple/workflow/engine/parser/AiravataDefaultParser.java
+++ /dev/null
@@ -1,293 +0,0 @@
-/*
- *
- * 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.ariavata.simple.workflow.engine.parser;
-
-import org.airavata.appcatalog.cpi.AppCatalogException;
-import org.airavata.appcatalog.cpi.WorkflowCatalog;
-import org.apache.aiaravata.application.catalog.data.impl.AppCatalogFactory;
-import org.apache.airavata.model.appcatalog.appinterface.InputDataObjectType;
-import org.apache.airavata.model.appcatalog.appinterface.OutputDataObjectType;
-import org.apache.airavata.model.workspace.experiment.Experiment;
-import org.apache.airavata.persistance.registry.jpa.impl.RegistryFactory;
-import org.apache.airavata.registry.cpi.Registry;
-import org.apache.airavata.registry.cpi.RegistryException;
-import org.apache.airavata.registry.cpi.RegistryModelType;
-import org.apache.airavata.workflow.model.component.ComponentException;
-import org.apache.airavata.workflow.model.component.system.ConstantComponent;
-import org.apache.airavata.workflow.model.component.system.InputComponent;
-import org.apache.airavata.workflow.model.component.system.S3InputComponent;
-import org.apache.airavata.workflow.model.graph.DataEdge;
-import org.apache.airavata.workflow.model.graph.DataPort;
-import org.apache.airavata.workflow.model.graph.GraphException;
-import org.apache.airavata.workflow.model.graph.Node;
-import org.apache.airavata.workflow.model.graph.impl.NodeImpl;
-import org.apache.airavata.workflow.model.graph.system.OutputNode;
-import org.apache.airavata.workflow.model.graph.system.SystemDataPort;
-import org.apache.airavata.workflow.model.graph.ws.WSNode;
-import org.apache.airavata.workflow.model.graph.ws.WSPort;
-import org.apache.airavata.workflow.model.wf.Workflow;
-import org.apache.ariavata.simple.workflow.engine.WorkflowParser;
-import org.apache.ariavata.simple.workflow.engine.dag.edge.DirectedEdge;
-import org.apache.ariavata.simple.workflow.engine.dag.edge.Edge;
-import org.apache.ariavata.simple.workflow.engine.dag.nodes.ApplicationNode;
-import org.apache.ariavata.simple.workflow.engine.dag.nodes.ApplicationNodeImpl;
-import org.apache.ariavata.simple.workflow.engine.dag.nodes.WorkflowInputNode;
-import org.apache.ariavata.simple.workflow.engine.dag.nodes.WorkflowInputNodeImpl;
-import org.apache.ariavata.simple.workflow.engine.dag.nodes.WorkflowNode;
-import org.apache.ariavata.simple.workflow.engine.dag.nodes.WorkflowOutputNode;
-import org.apache.ariavata.simple.workflow.engine.dag.nodes.WorkflowOutputNodeImpl;
-import org.apache.ariavata.simple.workflow.engine.dag.port.InPort;
-import org.apache.ariavata.simple.workflow.engine.dag.port.InputPortIml;
-import org.apache.ariavata.simple.workflow.engine.dag.port.OutPort;
-import org.apache.ariavata.simple.workflow.engine.dag.port.OutPortImpl;
-
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-
-public class AiravataDefaultParser implements WorkflowParser {
-
- private String credentialToken ;
- private Workflow workflow;
-
-
- private Experiment experiment;
- private Map<String, WorkflowNode> wfNodes = new HashMap<String, WorkflowNode>();
-
-
- public AiravataDefaultParser(String experimentId, String credentialToken) throws RegistryException {
- this.experiment = getExperiment(experimentId);
- this.credentialToken = credentialToken;
- }
-
- public AiravataDefaultParser(Experiment experiment, String credentialToken) {
- this.credentialToken = credentialToken;
- this.experiment = experiment;
- }
-
- @Override
- public List<WorkflowInputNode> parse() throws RegistryException, AppCatalogException,
- ComponentException, GraphException {
- return parseWorkflow(getWorkflowFromExperiment(experiment));
- }
-
- public List<WorkflowInputNode> parseWorkflow(Workflow workflow) {
- List<Node> gNodes = getInputNodes(workflow);
- List<WorkflowInputNode> wfInputNodes = new ArrayList<WorkflowInputNode>();
- List<PortContainer> portContainers = new ArrayList<PortContainer>();
- List<InputDataObjectType> experimentInputs = experiment.getExperimentInputs();
- Map<String,InputDataObjectType> inputDataMap=new HashMap<String, InputDataObjectType>();
- WorkflowInputNode wfInputNode = null;
- for (InputDataObjectType dataObjectType : experimentInputs) {
- inputDataMap.put(dataObjectType.getName(), dataObjectType);
- }
- for (Node gNode : gNodes) {
- wfInputNode = new WorkflowInputNodeImpl(gNode.getID(), gNode.getName());
- wfInputNode.setInputObject(inputDataMap.get(wfInputNode.getName()));
- if (wfInputNode.getInputObject() == null) {
- // TODO: throw an error and exit.
- }
- portContainers.addAll(processOutPorts(gNode, wfInputNode));
- wfInputNodes.add(wfInputNode);
- }
-
- // while port container is not empty iterate graph and build the workflow DAG.
- buildModel(portContainers);
-
- return wfInputNodes;
- }
-
- private void buildModel(List<PortContainer> portContainerList) {
- // end condition of recursive call.
- if (portContainerList == null || portContainerList.isEmpty()) {
- return ;
- }
- DataPort dataPort = null;
- InPort inPort = null;
- ApplicationNode wfApplicationNode = null;
- WorkflowOutputNode wfOutputNode = null;
- List<PortContainer> nextPortContainerList = new ArrayList<PortContainer>();
- for (PortContainer portContainer : portContainerList) {
- dataPort = portContainer.getDataPort();
- inPort = portContainer.getInPort();
- Node node = dataPort.getNode();
- if (node instanceof WSNode) {
- WSNode wsNode = (WSNode) node;
- WorkflowNode wfNode = wfNodes.get(wsNode.getID());
- if (wfNode == null) {
- wfApplicationNode = createApplicationNode(wsNode);
- wfNodes.put(wfApplicationNode.getId(), wfApplicationNode);
- nextPortContainerList.addAll(processOutPorts(wsNode, wfApplicationNode));
- } else if (wfNode instanceof ApplicationNode) {
- wfApplicationNode = (ApplicationNode) wfNode;
- } else {
- // TODO : handle this scenario
- }
- inPort.setNode(wfApplicationNode);
- wfApplicationNode.addInPort(inPort);
-
- }else if (node instanceof OutputNode) {
- OutputNode oNode = (OutputNode) node;
- wfOutputNode = createWorkflowOutputNode(oNode);
- wfOutputNode.setInPort(inPort);
- inPort.setNode(wfOutputNode);
- wfNodes.put(wfOutputNode.getId(), wfOutputNode);
- }
- }
- buildModel(nextPortContainerList);
-
- }
-
- private WorkflowOutputNode createWorkflowOutputNode(OutputNode oNode) {
- WorkflowOutputNodeImpl workflowOutputNode = new WorkflowOutputNodeImpl(oNode.getID(), oNode.getName());
- OutputDataObjectType outputDataObjectType = new OutputDataObjectType();
- outputDataObjectType.setType(oNode.getParameterType());
- workflowOutputNode.setOutputObject(outputDataObjectType);
- return workflowOutputNode;
- }
-
- private ApplicationNode createApplicationNode(WSNode wsNode) {
- ApplicationNode applicationNode = new ApplicationNodeImpl(wsNode.getID(),
- wsNode.getComponent().getApplication().getName(),
- wsNode.getComponent().getApplication().getApplicationId());
- return applicationNode;
- }
-
- private List<PortContainer> processOutPorts(Node node, WorkflowNode wfNode) {
- OutPort outPort ;
- Edge edge;
- InPort inPort = null;
- List<PortContainer> portContainers = new ArrayList<PortContainer>();
- for (DataPort dataPort : node.getOutputPorts()) {
- outPort = createOutPort(dataPort);
- for (DataEdge dataEdge : dataPort.getEdges()) {
- edge = new DirectedEdge();
- edge.setFromPort(outPort);
- outPort.addEdge(edge);
- inPort = createInPort(dataEdge.getToPort());
- edge.setToPort(inPort);
- inPort.addEdge(edge);
- portContainers.add(new PortContainer(dataEdge.getToPort(), inPort));
- }
- outPort.setNode(wfNode);
- if (wfNode instanceof WorkflowInputNode) {
- WorkflowInputNode workflowInputNode = (WorkflowInputNode) wfNode;
- workflowInputNode.setOutPort(outPort);
- } else if (wfNode instanceof ApplicationNode) {
- ApplicationNode applicationNode = ((ApplicationNode) wfNode);
- applicationNode.addOutPort(outPort);
- }
- }
- return portContainers;
- }
-
- private OutPort createOutPort(DataPort dataPort) {
- OutPortImpl outPort = new OutPortImpl(dataPort.getID());
- OutputDataObjectType outputDataObjectType = new OutputDataObjectType();
- if (dataPort instanceof WSPort) {
- WSPort wsPort = (WSPort) dataPort;
- outputDataObjectType.setName(wsPort.getFromNode().getName());
- outputDataObjectType.setType(wsPort.getType());
- }else if (dataPort instanceof SystemDataPort) {
- SystemDataPort sysPort = (SystemDataPort) dataPort;
- outputDataObjectType.setName(sysPort.getFromNode().getName());
- outputDataObjectType.setType(sysPort.getType());
- }
-
- outPort.setOutputObject(outputDataObjectType);
- return outPort;
- }
-
- private InPort createInPort(DataPort toPort) {
- InPort inPort = new InputPortIml(toPort.getID());
- InputDataObjectType inputDataObjectType = new InputDataObjectType();
- if (toPort instanceof WSPort) {
- WSPort wsPort = (WSPort) toPort;
- inputDataObjectType.setName(wsPort.getName());
- inputDataObjectType.setType(wsPort.getType());
- inputDataObjectType.setApplicationArgument(wsPort.getComponentPort().getApplicationArgument());
- inputDataObjectType.setIsRequired(!wsPort.getComponentPort().isOptional());
- inputDataObjectType.setInputOrder(wsPort.getComponentPort().getInputOrder());
-
- inPort.setDefaultValue(wsPort.getComponentPort().getDefaultValue());
- }else if (toPort instanceof SystemDataPort) {
- SystemDataPort sysPort = (SystemDataPort) toPort;
- inputDataObjectType.setName(sysPort.getName());
- inputDataObjectType.setType(sysPort.getType());
- }
- inPort.setInputObject(inputDataObjectType);
- return inPort;
- }
-
- private InputDataObjectType getInputDataObject(DataPort dataPort) {
- InputDataObjectType inputDataObject = new InputDataObjectType();
- inputDataObject.setName(dataPort.getName());
- if (dataPort instanceof WSPort) {
- WSPort port = (WSPort) dataPort;
- inputDataObject.setInputOrder(port.getComponentPort().getInputOrder());
- inputDataObject.setApplicationArgument(port.getComponentPort().getApplicationArgument() == null ?
- "" : port.getComponentPort().getApplicationArgument());
- inputDataObject.setType(dataPort.getType());
- }
- return inputDataObject;
- }
-
- private OutputDataObjectType getOutputDataObject(InputDataObjectType inputObject) {
- OutputDataObjectType outputDataObjectType = new OutputDataObjectType();
- outputDataObjectType.setApplicationArgument(inputObject.getApplicationArgument());
- outputDataObjectType.setName(inputObject.getName());
- outputDataObjectType.setType(inputObject.getType());
- outputDataObjectType.setValue(inputObject.getValue());
- return outputDataObjectType;
- }
-
- private Experiment getExperiment(String experimentId) throws RegistryException {
- Registry registry = RegistryFactory.getDefaultRegistry();
- return (Experiment)registry.get(RegistryModelType.EXPERIMENT, experimentId);
- }
-
- private Workflow getWorkflowFromExperiment(Experiment experiment) throws RegistryException, AppCatalogException, GraphException, ComponentException {
- WorkflowCatalog workflowCatalog = getWorkflowCatalog();
- return new Workflow(workflowCatalog.getWorkflow(experiment.getApplicationId()).getGraph());
- }
-
- private WorkflowCatalog getWorkflowCatalog() throws AppCatalogException {
- return AppCatalogFactory.getAppCatalog().getWorkflowCatalog();
- }
-
- private ArrayList<Node> getInputNodes(Workflow wf) {
- ArrayList<Node> list = new ArrayList<Node>();
- List<NodeImpl> nodes = wf.getGraph().getNodes();
- for (Node node : nodes) {
- String name = node.getComponent().getName();
- if (InputComponent.NAME.equals(name) || ConstantComponent.NAME.equals(name) || S3InputComponent.NAME.equals(name)) {
- list.add(node);
- }
- }
- return list;
- }
-
- public Map<String, WorkflowNode> getWfNodes() {
- return wfNodes;
- }
-}
http://git-wip-us.apache.org/repos/asf/airavata/blob/6bfb9563/modules/simple-workflow/src/main/java/org/apache/ariavata/simple/workflow/engine/parser/PortContainer.java
----------------------------------------------------------------------
diff --git a/modules/simple-workflow/src/main/java/org/apache/ariavata/simple/workflow/engine/parser/PortContainer.java b/modules/simple-workflow/src/main/java/org/apache/ariavata/simple/workflow/engine/parser/PortContainer.java
deleted file mode 100644
index d18a104..0000000
--- a/modules/simple-workflow/src/main/java/org/apache/ariavata/simple/workflow/engine/parser/PortContainer.java
+++ /dev/null
@@ -1,53 +0,0 @@
-/*
- *
- * 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.ariavata.simple.workflow.engine.parser;
-
-import org.apache.airavata.workflow.model.graph.DataPort;
-import org.apache.ariavata.simple.workflow.engine.dag.port.InPort;
-
-
-public class PortContainer {
- private DataPort dataPort;
- private InPort inPort;
-
-
- public PortContainer(DataPort dataPort, InPort inPort) {
- this.dataPort = dataPort;
- this.inPort = inPort;
- }
-
- public DataPort getDataPort() {
- return dataPort;
- }
-
- public void setDataPort(DataPort dataPort) {
- this.dataPort = dataPort;
- }
-
- public InPort getInPort() {
- return inPort;
- }
-
- public void setInPort(InPort inPort) {
- this.inPort = inPort;
- }
-}
http://git-wip-us.apache.org/repos/asf/airavata/blob/6bfb9563/modules/simple-workflow/src/test/java/org/apache/airavata/simple/workflow/engine/WorkflowDAGTest.java
----------------------------------------------------------------------
diff --git a/modules/simple-workflow/src/test/java/org/apache/airavata/simple/workflow/engine/WorkflowDAGTest.java b/modules/simple-workflow/src/test/java/org/apache/airavata/simple/workflow/engine/WorkflowDAGTest.java
new file mode 100644
index 0000000..9ec95df
--- /dev/null
+++ b/modules/simple-workflow/src/test/java/org/apache/airavata/simple/workflow/engine/WorkflowDAGTest.java
@@ -0,0 +1,46 @@
+/*
+ *
+ * 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.simple.workflow.engine;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+
+public class WorkflowDAGTest {
+
+ @Before
+ public void setUp() throws Exception {
+
+ }
+
+ @After
+ public void tearDown() throws Exception {
+
+ }
+
+ @Test
+ public void testWorkflowDAG() throws Exception {
+
+
+
+ }
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/airavata/blob/6bfb9563/modules/simple-workflow/src/test/java/org/apache/airavata/simple/workflow/engine/parser/AiravataDefaultParserTest.java
----------------------------------------------------------------------
diff --git a/modules/simple-workflow/src/test/java/org/apache/airavata/simple/workflow/engine/parser/AiravataDefaultParserTest.java b/modules/simple-workflow/src/test/java/org/apache/airavata/simple/workflow/engine/parser/AiravataDefaultParserTest.java
new file mode 100644
index 0000000..e9b3e55
--- /dev/null
+++ b/modules/simple-workflow/src/test/java/org/apache/airavata/simple/workflow/engine/parser/AiravataDefaultParserTest.java
@@ -0,0 +1,119 @@
+/*
+ *
+ * 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.simple.workflow.engine.parser;
+
+import org.apache.airavata.model.appcatalog.appinterface.DataType;
+import org.apache.airavata.model.appcatalog.appinterface.InputDataObjectType;
+import org.apache.airavata.model.workspace.experiment.Experiment;
+import org.apache.airavata.simple.workflow.engine.dag.nodes.ApplicationNode;
+import org.apache.airavata.simple.workflow.engine.dag.nodes.WorkflowInputNode;
+import org.apache.airavata.simple.workflow.engine.dag.nodes.WorkflowOutputNode;
+import org.apache.airavata.workflow.model.wf.Workflow;
+import org.apache.airavata.simple.workflow.engine.dag.nodes.WorkflowNode;
+import org.junit.After;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+
+import java.io.BufferedReader;
+import java.io.InputStreamReader;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+
+public class AiravataDefaultParserTest {
+
+ @Before
+ public void setUp() throws Exception {
+
+ }
+
+ @After
+ public void tearDown() throws Exception {
+
+ }
+
+ @Test
+ public void testWorkflowParse() throws Exception {
+ Assert.assertNotNull("Test file (ComplexMathWorkflow.awf) is missing", getClass().getResource("/ComplexMathWorkflow.awf"));
+ InputStreamReader isr = new InputStreamReader(this.getClass().getResourceAsStream("/ComplexMathWorkflow.awf"));
+ BufferedReader br = new BufferedReader(isr);
+ StringBuffer sb = new StringBuffer();
+ String nextLine = br.readLine();
+ while (nextLine != null) {
+ sb.append(nextLine);
+ nextLine = br.readLine();
+ }
+ Workflow workflow = new Workflow(sb.toString());
+ Experiment experiment = new Experiment();
+ InputDataObjectType x = new InputDataObjectType();
+ x.setValue("6");
+ x.setType(DataType.STRING);
+ x.setName("x");
+
+ InputDataObjectType y = new InputDataObjectType();
+ y.setValue("8");
+ y.setType(DataType.STRING);
+ y.setName("y");
+
+ InputDataObjectType z = new InputDataObjectType();
+ z.setValue("10");
+ z.setType(DataType.STRING);
+ z.setName("y_2");
+
+ List<InputDataObjectType> inputs = new ArrayList<InputDataObjectType>();
+ inputs.add(x);
+ inputs.add(y);
+ inputs.add(z);
+ experiment.setExperimentInputs(inputs);
+ // create parser
+ AiravataDefaultParser parser = new AiravataDefaultParser(experiment, "testCredentialId");
+ List<WorkflowInputNode> workflowInputNodes = parser.parseWorkflow(workflow);
+ Assert.assertNotNull(workflowInputNodes);
+ Assert.assertEquals(3, workflowInputNodes.size());
+ for (WorkflowInputNode workflowInputNode : workflowInputNodes) {
+ Assert.assertNotNull(workflowInputNode.getOutPort());
+ Assert.assertNotNull(workflowInputNode.getInputObject());
+ }
+
+ Map<String, WorkflowNode> wfNodes = parser.getWfNodes();
+ for (String wfId : wfNodes.keySet()) {
+ WorkflowNode wfNode = wfNodes.get(wfId);
+ if (wfNode instanceof ApplicationNode) {
+ ApplicationNode node = (ApplicationNode) wfNode;
+ Assert.assertEquals(2, node.getInputPorts().size());
+ Assert.assertNotNull(node.getInputPorts().get(0).getInputObject());
+ Assert.assertNotNull(node.getInputPorts().get(1).getInputObject());
+ Assert.assertNotNull(node.getInputPorts().get(0).getEdge());
+ Assert.assertNotNull(node.getInputPorts().get(1).getEdge());
+
+ Assert.assertEquals(1, node.getOutputPorts().size());
+ Assert.assertEquals(1, node.getOutputPorts().get(0).getOutEdges().size());
+ Assert.assertNotNull(node.getOutputPorts().get(0).getOutEdges().get(0));
+ } else if (wfNode instanceof WorkflowOutputNode) {
+ WorkflowOutputNode workflowOutputNode = (WorkflowOutputNode) wfNode;
+ Assert.assertNotNull(workflowOutputNode.getInPort());
+ }
+ }
+
+ }
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/airavata/blob/6bfb9563/modules/simple-workflow/src/test/java/org/apache/ariavata/simple/workflow/engine/WorkflowDAGTest.java
----------------------------------------------------------------------
diff --git a/modules/simple-workflow/src/test/java/org/apache/ariavata/simple/workflow/engine/WorkflowDAGTest.java b/modules/simple-workflow/src/test/java/org/apache/ariavata/simple/workflow/engine/WorkflowDAGTest.java
deleted file mode 100644
index 867ddc6..0000000
--- a/modules/simple-workflow/src/test/java/org/apache/ariavata/simple/workflow/engine/WorkflowDAGTest.java
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
- *
- * 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.ariavata.simple.workflow.engine;
-
-import org.junit.After;
-import org.junit.Before;
-import org.junit.Test;
-
-public class WorkflowDAGTest {
-
- @Before
- public void setUp() throws Exception {
-
- }
-
- @After
- public void tearDown() throws Exception {
-
- }
-
- @Test
- public void testWorkflowDAG() throws Exception {
-
-
-
- }
-}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/airavata/blob/6bfb9563/modules/simple-workflow/src/test/java/org/apache/ariavata/simple/workflow/engine/parser/AiravataDefaultParserTest.java
----------------------------------------------------------------------
diff --git a/modules/simple-workflow/src/test/java/org/apache/ariavata/simple/workflow/engine/parser/AiravataDefaultParserTest.java b/modules/simple-workflow/src/test/java/org/apache/ariavata/simple/workflow/engine/parser/AiravataDefaultParserTest.java
deleted file mode 100644
index 432a1c6..0000000
--- a/modules/simple-workflow/src/test/java/org/apache/ariavata/simple/workflow/engine/parser/AiravataDefaultParserTest.java
+++ /dev/null
@@ -1,119 +0,0 @@
-/*
- *
- * 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.ariavata.simple.workflow.engine.parser;
-
-import org.apache.airavata.model.appcatalog.appinterface.DataType;
-import org.apache.airavata.model.appcatalog.appinterface.InputDataObjectType;
-import org.apache.airavata.model.workspace.experiment.Experiment;
-import org.apache.airavata.workflow.model.wf.Workflow;
-import org.apache.ariavata.simple.workflow.engine.dag.nodes.ApplicationNode;
-import org.apache.ariavata.simple.workflow.engine.dag.nodes.WorkflowInputNode;
-import org.apache.ariavata.simple.workflow.engine.dag.nodes.WorkflowNode;
-import org.apache.ariavata.simple.workflow.engine.dag.nodes.WorkflowOutputNode;
-import org.junit.After;
-import org.junit.Assert;
-import org.junit.Before;
-import org.junit.Test;
-
-import java.io.BufferedReader;
-import java.io.InputStreamReader;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Map;
-
-public class AiravataDefaultParserTest {
-
- @Before
- public void setUp() throws Exception {
-
- }
-
- @After
- public void tearDown() throws Exception {
-
- }
-
- @Test
- public void testWorkflowParse() throws Exception {
- Assert.assertNotNull("Test file (ComplexMathWorkflow.awf) is missing", getClass().getResource("/ComplexMathWorkflow.awf"));
- InputStreamReader isr = new InputStreamReader(this.getClass().getResourceAsStream("/ComplexMathWorkflow.awf"));
- BufferedReader br = new BufferedReader(isr);
- StringBuffer sb = new StringBuffer();
- String nextLine = br.readLine();
- while (nextLine != null) {
- sb.append(nextLine);
- nextLine = br.readLine();
- }
- Workflow workflow = new Workflow(sb.toString());
- Experiment experiment = new Experiment();
- InputDataObjectType x = new InputDataObjectType();
- x.setValue("6");
- x.setType(DataType.STRING);
- x.setName("x");
-
- InputDataObjectType y = new InputDataObjectType();
- y.setValue("8");
- y.setType(DataType.STRING);
- y.setName("y");
-
- InputDataObjectType z = new InputDataObjectType();
- z.setValue("10");
- z.setType(DataType.STRING);
- z.setName("y_2");
-
- List<InputDataObjectType> inputs = new ArrayList<InputDataObjectType>();
- inputs.add(x);
- inputs.add(y);
- inputs.add(z);
- experiment.setExperimentInputs(inputs);
- // create parser
- AiravataDefaultParser parser = new AiravataDefaultParser(experiment, "testCredentialId");
- List<WorkflowInputNode> workflowInputNodes = parser.parseWorkflow(workflow);
- Assert.assertNotNull(workflowInputNodes);
- Assert.assertEquals(3, workflowInputNodes.size());
- for (WorkflowInputNode workflowInputNode : workflowInputNodes) {
- Assert.assertNotNull(workflowInputNode.getOutPort());
- Assert.assertNotNull(workflowInputNode.getInputObject());
- }
-
- Map<String, WorkflowNode> wfNodes = parser.getWfNodes();
- for (String wfId : wfNodes.keySet()) {
- WorkflowNode wfNode = wfNodes.get(wfId);
- if (wfNode instanceof ApplicationNode) {
- ApplicationNode node = (ApplicationNode) wfNode;
- Assert.assertEquals(2, node.getInputPorts().size());
- Assert.assertNotNull(node.getInputPorts().get(0).getInputObject());
- Assert.assertNotNull(node.getInputPorts().get(1).getInputObject());
- Assert.assertNotNull(node.getInputPorts().get(0).getEdge());
- Assert.assertNotNull(node.getInputPorts().get(1).getEdge());
-
- Assert.assertEquals(1, node.getOutputPorts().size());
- Assert.assertEquals(1, node.getOutputPorts().get(0).getOutEdges().size());
- Assert.assertNotNull(node.getOutputPorts().get(0).getOutEdges().get(0));
- } else if (wfNode instanceof WorkflowOutputNode) {
- WorkflowOutputNode workflowOutputNode = (WorkflowOutputNode) wfNode;
- Assert.assertNotNull(workflowOutputNode.getInPort());
- }
- }
-
- }
-}
\ No newline at end of file
[02/50] [abbrv] airavata git commit: Handle ouptprt of application
nodes and workflowOutputNodes
Posted by sh...@apache.org.
http://git-wip-us.apache.org/repos/asf/airavata/blob/9445b7a1/modules/simple-workflow/src/test/resources/ComplexMathWorkflow.awf
----------------------------------------------------------------------
diff --git a/modules/simple-workflow/src/test/resources/ComplexMathWorkflow.awf b/modules/simple-workflow/src/test/resources/ComplexMathWorkflow.awf
new file mode 100644
index 0000000..4ffcad0
--- /dev/null
+++ b/modules/simple-workflow/src/test/resources/ComplexMathWorkflow.awf
@@ -0,0 +1,465 @@
+{
+ "workflow": {
+ "version": "0.11",
+ "graph": {
+ "version": "0.11",
+ "id": "ComplexMathWorkflow",
+ "name": "ComplexMathWorkflow",
+ "description": "Sample workflow description",
+ "node": [
+ {
+ "id": "Add",
+ "name": "Add",
+ "inputPort": [
+ "Add_in_0",
+ "Add_in_1"
+ ],
+ "outputPort": [
+ "Add_out_0"
+ ],
+ "controlInPort": "Add_ctrl_in_0",
+ "controlOutPort": [
+ "Add_ctrl_out_0"
+ ],
+ "x": "247",
+ "y": "106",
+ "type": "ws",
+ "Application": {
+ "description": "Add two numbers",
+ "name": "Add",
+ "application": "Add_6c295199-f376-48af-b331-c83b2cf0fe9e",
+ "Input": [
+ {
+ "description": "Add operation input_1",
+ "name": "x",
+ "defaultValue": "2",
+ "dataType": "STRING",
+ "inputOrder": 1
+ },
+ {
+ "description": "Add operation input_2",
+ "name": "y",
+ "defaultValue": "3",
+ "dataType": "STRING",
+ "inputOrder": 2
+ }
+ ],
+ "Output": [
+ {
+ "description": "Result",
+ "name": "Result",
+ "dataType": "STRING"
+ }
+ ]
+ }
+ },
+ {
+ "id": "Multiply",
+ "name": "Multiply",
+ "inputPort": [
+ "Multiply_in_0",
+ "Multiply_in_1"
+ ],
+ "outputPort": [
+ "Multiply_out_0"
+ ],
+ "controlInPort": "Multiply_ctrl_in_0",
+ "controlOutPort": [
+ "Multiply_ctrl_out_0"
+ ],
+ "x": "287",
+ "y": "232",
+ "type": "ws",
+ "Application": {
+ "description": "Multiply two numbers",
+ "name": "Multiply",
+ "application": "Multiply_ccc3b4e6-8c5c-4b44-bdfa-b267337fce97",
+ "Input": [
+ {
+ "description": "Multiply operation input_1",
+ "name": "x",
+ "defaultValue": "4",
+ "dataType": "STRING",
+ "inputOrder": 1
+ },
+ {
+ "description": "Multiply operation input_2",
+ "name": "y",
+ "defaultValue": "5",
+ "dataType": "STRING",
+ "inputOrder": 2
+ }
+ ],
+ "Output": [
+ {
+ "description": "Result",
+ "name": "Result",
+ "dataType": "STRING"
+ }
+ ]
+ }
+ },
+ {
+ "id": "Subtract",
+ "name": "Subtract",
+ "inputPort": [
+ "Subtract_in_0",
+ "Subtract_in_1"
+ ],
+ "outputPort": [
+ "Subtract_out_0"
+ ],
+ "controlInPort": "Subtract_ctrl_in_0",
+ "controlOutPort": [
+ "Subtract_ctrl_out_0"
+ ],
+ "x": "426",
+ "y": "136",
+ "type": "ws",
+ "Application": {
+ "description": "Subtract two numbers",
+ "name": "Subtract",
+ "application": "Subtract_f1b296ad-b3bd-4a1b-82bc-407725bbdb96",
+ "Input": [
+ {
+ "description": "Subtract operation input_1",
+ "name": "x",
+ "defaultValue": "6",
+ "dataType": "STRING",
+ "inputOrder": 1
+ },
+ {
+ "description": "Subtract operation input_2",
+ "name": "y",
+ "defaultValue": "7",
+ "dataType": "STRING",
+ "inputOrder": 2
+ }
+ ],
+ "Output": [
+ {
+ "description": "Result",
+ "name": "Result",
+ "dataType": "STRING"
+ }
+ ]
+ }
+ },
+ {
+ "id": "Add_2",
+ "name": "Add",
+ "inputPort": [
+ "Add_2_in_0",
+ "Add_2_in_1"
+ ],
+ "outputPort": [
+ "Add_2_out_0"
+ ],
+ "controlInPort": "Add_2_ctrl_in_0",
+ "controlOutPort": [
+ "Add_2_ctrl_out_0"
+ ],
+ "x": "475",
+ "y": "302",
+ "type": "ws",
+ "Application": {
+ "description": "Add two numbers",
+ "name": "Add",
+ "application": "Add_6c295199-f376-48af-b331-c83b2cf0fe9e",
+ "Input": [
+ {
+ "description": "Add operation input_1",
+ "name": "x",
+ "defaultValue": "2",
+ "dataType": "STRING",
+ "inputOrder": 1
+ },
+ {
+ "description": "Add operation input_2",
+ "name": "y",
+ "defaultValue": "3",
+ "dataType": "STRING",
+ "inputOrder": 2
+ }
+ ],
+ "Output": [
+ {
+ "description": "Result",
+ "name": "Result",
+ "dataType": "STRING"
+ }
+ ]
+ }
+ },
+ {
+ "id": "x",
+ "name": "x",
+ "outputPort": [
+ "Input_out_2"
+ ],
+ "x": "97",
+ "y": "88",
+ "config": {
+ "description": "Add operation input_1",
+ "dataType": "STRING",
+ "value": "2",
+ "visibility": true
+ },
+ "type": "input"
+ },
+ {
+ "id": "y",
+ "name": "y",
+ "outputPort": [
+ "Input_out_3"
+ ],
+ "x": "97",
+ "y": "194",
+ "config": {
+ "description": "Add operation input_2",
+ "dataType": "STRING",
+ "value": "3",
+ "visibility": true
+ },
+ "type": "input"
+ },
+ {
+ "id": "y_2",
+ "name": "y",
+ "outputPort": [
+ "Input_out_4"
+ ],
+ "x": "105",
+ "y": "311",
+ "config": {
+ "description": "Multiply operation input_2",
+ "dataType": "STRING",
+ "value": "5",
+ "visibility": true
+ },
+ "type": "input"
+ },
+ {
+ "id": "Result",
+ "name": "Result",
+ "inputPort": [
+ "Output_in_2"
+ ],
+ "x": "729",
+ "y": "248",
+ "config": {
+ "description": "Result",
+ "dataType": "STRING"
+ },
+ "type": "output"
+ }
+ ],
+ "port": [
+ {
+ "id": "Add_in_0",
+ "name": "x",
+ "node": "Add",
+ "type": "ws",
+ "dataType": "STRING"
+ },
+ {
+ "id": "Add_in_1",
+ "name": "y",
+ "node": "Add",
+ "type": "ws",
+ "dataType": "STRING"
+ },
+ {
+ "id": "Add_out_0",
+ "name": "Result",
+ "node": "Add",
+ "type": "ws",
+ "dataType": "STRING"
+ },
+ {
+ "id": "Add_ctrl_in_0",
+ "name": "control",
+ "node": "Add",
+ "type": "control"
+ },
+ {
+ "id": "Add_ctrl_out_0",
+ "name": "control",
+ "node": "Add",
+ "type": "control"
+ },
+ {
+ "id": "Multiply_in_0",
+ "name": "x",
+ "node": "Multiply",
+ "type": "ws",
+ "dataType": "STRING"
+ },
+ {
+ "id": "Multiply_in_1",
+ "name": "y",
+ "node": "Multiply",
+ "type": "ws",
+ "dataType": "STRING"
+ },
+ {
+ "id": "Multiply_out_0",
+ "name": "Result",
+ "node": "Multiply",
+ "type": "ws",
+ "dataType": "STRING"
+ },
+ {
+ "id": "Multiply_ctrl_in_0",
+ "name": "control",
+ "node": "Multiply",
+ "type": "control"
+ },
+ {
+ "id": "Multiply_ctrl_out_0",
+ "name": "control",
+ "node": "Multiply",
+ "type": "control"
+ },
+ {
+ "id": "Subtract_in_0",
+ "name": "x",
+ "node": "Subtract",
+ "type": "ws",
+ "dataType": "STRING"
+ },
+ {
+ "id": "Subtract_in_1",
+ "name": "y",
+ "node": "Subtract",
+ "type": "ws",
+ "dataType": "STRING"
+ },
+ {
+ "id": "Subtract_out_0",
+ "name": "Result",
+ "node": "Subtract",
+ "type": "ws",
+ "dataType": "STRING"
+ },
+ {
+ "id": "Subtract_ctrl_in_0",
+ "name": "control",
+ "node": "Subtract",
+ "type": "control"
+ },
+ {
+ "id": "Subtract_ctrl_out_0",
+ "name": "control",
+ "node": "Subtract",
+ "type": "control"
+ },
+ {
+ "id": "Add_2_in_0",
+ "name": "x",
+ "node": "Add_2",
+ "type": "ws",
+ "dataType": "STRING"
+ },
+ {
+ "id": "Add_2_in_1",
+ "name": "y",
+ "node": "Add_2",
+ "type": "ws",
+ "dataType": "STRING"
+ },
+ {
+ "id": "Add_2_out_0",
+ "name": "Result",
+ "node": "Add_2",
+ "type": "ws",
+ "dataType": "STRING"
+ },
+ {
+ "id": "Add_2_ctrl_in_0",
+ "name": "control",
+ "node": "Add_2",
+ "type": "control"
+ },
+ {
+ "id": "Add_2_ctrl_out_0",
+ "name": "control",
+ "node": "Add_2",
+ "type": "control"
+ },
+ {
+ "id": "Input_out_2",
+ "name": "Parameter",
+ "node": "x",
+ "type": "systemData"
+ },
+ {
+ "id": "Input_out_3",
+ "name": "Parameter",
+ "node": "y",
+ "type": "systemData"
+ },
+ {
+ "id": "Input_out_4",
+ "name": "Parameter",
+ "node": "y_2",
+ "type": "systemData"
+ },
+ {
+ "id": "Output_in_2",
+ "name": "Parameter",
+ "node": "Result",
+ "type": "systemData"
+ }
+ ],
+ "edge": [
+ {
+ "fromPort": "Input_out_2",
+ "toPort": "Add_in_0",
+ "type": "data"
+ },
+ {
+ "fromPort": "Input_out_3",
+ "toPort": "Add_in_1",
+ "type": "data"
+ },
+ {
+ "fromPort": "Input_out_3",
+ "toPort": "Multiply_in_0",
+ "type": "data"
+ },
+ {
+ "fromPort": "Input_out_4",
+ "toPort": "Multiply_in_1",
+ "type": "data"
+ },
+ {
+ "fromPort": "Input_out_4",
+ "toPort": "Add_2_in_1",
+ "type": "data"
+ },
+ {
+ "fromPort": "Add_out_0",
+ "toPort": "Subtract_in_0",
+ "type": "data"
+ },
+ {
+ "fromPort": "Multiply_out_0",
+ "toPort": "Subtract_in_1",
+ "type": "data"
+ },
+ {
+ "fromPort": "Subtract_out_0",
+ "toPort": "Add_2_in_0",
+ "type": "data"
+ },
+ {
+ "fromPort": "Add_2_out_0",
+ "toPort": "Output_in_2",
+ "type": "data"
+ }
+ ]
+ },
+ "image": "iVBORw0KGgoAAAANSUhEUgAAA0cAAAFwCAYAAABzWgC/AACAAElEQVR42uydeXiV9Zn+c80f06lO\r\ntS6t1g2r7YztVGxnulg70KHa/lqnLd0UtLSWtjJqXVJFkVZkRyMURFBREFBAkLCFPWQBw74EspKE\r\n7PtKNpaQ855znt93fd/v+573hCBbQu5c1+c6yCL2cELPJ/fz3E9MRUUJAQAAAAAAAEBfJwZPAgAA\r\nAAAAAABAjgAAAAAAAAAAcgQAAAAAAAAAkCMAAAAAAAAAgBwBAAAAAAAAAOQIAAAAAAAAACBHAAAA\r\nAAAAAAA5AgAAAAAAAADIEQAAAAAAAABAjgAAAAAAAAAAcgQAAAAAAAAAkCMAAAAAAAAAgBwBAAAA\r\nAAAAAOQIAAAAAAAAACBHAAAAAAAAAAA5AgAAAAAAAADIEQAAAAAAAABAjgAAAAAAAAAAcgQAAAAA\r\nAAAAkCMAAAAAAAAAgBwBAAAAAAAAAOQIAAAAAAAAACBHAAAAAAAAAAA5AgAAAAAAAADIEQAAAAAA\r\nAABAjgAAAAAAAAAAcgQAAAAAAAAAkCMAAAAAAAAAgBwBAAAAAAAAAOQIAAAAAAAAACBHAAAAAAAA\r\nAAA5AgAAAAAAAADIEQAAAAAAAABAjgAAAAAAAAAAcgQAAAAAAAAAkCMAAAAAAAAAgBwBAAAAAAAA\r\nAOQIAAAAAAAAACBHAAAAAAAAAAA5AgAAAAAAAADIEQAAAAAAAABAjgAAAAAAAAAAcgQAAAAAAAAA\r\nkCMAAAAAAAAAgBwBAAAAAAAAAOQIAAAAAAAAACBHAAAAAAAAAAA5AgAAAAAAAADIEQAAAAAAAABA\r\njgAAAAAAAAAAcgQAAAAAAAAAkCMAAAAAAAAAgBwBAAAAAAAAAOQIAAAAAAAAACBHAAAAAAAAAAA5\r\nAgAAAAAAAADIEQAAAAAAAAB
AjgAAAAAAAAAAcgQAAAAAAAAAkCMAAAAAAAAAgBwBAAAAAAAAAOQI\r\nAAAAAAAAACBHAAAAAAAAAAA5AgAAAAAAAADIEQAAAAAAAABAjgAAAAAAAAAAcgQAAAAAAAAAkCMA\r\nAAAAAAAAgBwBAAAAAAAAAOQIAAAAAAAAACBHAAAAAAAAAAA5AgAAAAAAAADIEQAAAAAAAABAjgAA\r\nAAAAAAAAcgQAAAAAAAAAkCMAAAAAAAAAgBwBAAAAAAAAAOQIAAAAAAAAACBHAAAAAAAAAAA5AgAA\r\nAAAAAADIEQAAAAAAAABAjgAAAAAAAAAAcgQAAAAAAAAAkCMAAAAAAAAAgBwBAAAAAAAAAOQITwQA\r\nAAAAAAAAcoQnAQAAAAAAAAAgRz2KkpIiWrlqFU2dOpXGjx9P48aNA+ed8TT5lTha8MECys4+hNch\r\nAAAAAADkCFx0KivEm/Wk5BRqammjU1aYQdTBOBkgOqE41knUfkrSxmjtIGphNJ8kOspoYjSeIKo/\r\nTlR3jKiWUdNOVK2oaiOqUJS3EpW1EJUySpqJihVFR4mONBHlN0oON0hyGTn1RNmMLEZmHVFGLdEh\r\nxsEaonTFAca+aqK9VUR7Kol2VUh2MnaUE21npDE+LiPaxiklSuWUEKUwkhlJxURbiogSGZsLiTYe\r\nYbDH9exxXYEkIZ9oDSePaDVj1WGilYwVjPhcouU5RB8xlmUTLWV8yFiSRbQoU/JBBtHCQ2Gat7uN\r\nXl++gyZOmkSZmQfxWgQAAAAAgByBi5cYFdOUKVMoOzuXrBBRZ1DC5Yhz0pJidFzR3inhciTEqEOJ\r\n0QkpRg3HlRwpuCDZcsSo9JOjFilFhUqMhBwp8hqlGAk5apBylO2RI44QIyZF+6oMOWLsrjTkqELK\r\nkRAkJUZbFS4xKlZixNik5GiDQsvR2gJHjFxylCvl6CNDjj7MkrjkiLFQCBLR
Asbs9blCUJEgAQAA\r\nAABAjsBFYtWqVbR9+w4KhknIUSDkyJFOjjjHO2VyxGntIjVqMJKjOpUc1RhiJOSoVcqRNzUqVIJU\r\n4E2OlCBpMcqqk3LEOWgkR1yO9htiZMtRpSc5KpPJEWermRoVe1IjLUeFUozWF0jW5ksSzOQozxEj\r\nOzXKkanRUpUaLc6UfKCSo/cNOZrPmLNsDS1evAivSwAAAAAAyBG4GEybNo2aW9ooGCJXcsQxx+r8\r\nUiMtR00+yVG9So1qjNE6MzUqNVIjMU5njNRxtCDlNbrH6iJG6mqdcToxUlcl0WN1Wo52qeRohxqr\r\n86ZGOjna4pccFTpjdZy1BW4xWukdqVOYcqTH6har9Oh9JUdCjA4SvcfZ1UBxca/idQkAAAAAADkC\r\nFwNevhAMhYUYmcmRnRpZUozMfSOeGrWe8iRHSo70zhFHpEbH3ON0nLJWiU6OzLE6nRwVqJG6PG9q\r\nVO+kRnrfiAsST43M5GivSo30WJ133+hjc9+oVKZGEclRodo5KnSP1CXkOztHOjXScrRCJUfL1Ugd\r\nFyRTjDhajBYqOeJwOZqbHhajdWvXrqGDB/fj9QkAAAAAADkCFxL+ZjykR+r0vpGWI3PfqNOdHLWq\r\nfSN758gsY1CpUZf7Rq3u5EiP1R056k6NvPtGdnJU5+wb6bE6Lkb7FHsqo+8bmSN15lhdUnHkzpHf\r\nvpGWo9V5HjnKdZIjvXO0NNvZN1pslDF4R+p4ejQvncSfx/vvLxRs25aC1ygAAAAAAOQIXEg58o7U\r\neeVIN9Ud02J0ykmOTjdSV22M1FUqMSr3JEdmGYM3NYpoqquLTI7Suxqpq+jevlGKT0udLmPY6Nk3\r\nSjD2jXgRg7eMYbmnpY5j7xtl+MiRGqvzyhEHCRIAAAAAAOQIXEg5ilLG0OHTVKflyC818pYx+CZH\r\nZhmDuW/UHFnG0GVyZ
LTUaTnar9rquBh5m+p2Vjhjdbqpjld5R63w7iI5Ek11nrG6iApvhU6NXMlR\r\npnusbr7CT474iB1epwAAAAAAkCNwgZOjgLeMQctRp3PbyFXG4JWj40565B2rqzBTI58yBrvG+2jk\r\nvpFdxlDnX+GdboiReePILznaHq2ModhTxlDorvFeX+C5ceQtY8j1lDFkOyN1HxpFDNHKGLgYzfWR\r\noyVL0F4HAAAAAAA5AhctOTJTI/v4q09T3dFoNd7e+0ZtUe4bNfvvGxV4bhz5HX/dtCKOvnnPYPqf\r\nX0+gj0p4GUMHvfH3EfSle2Lp/Vx3jbfffSMzNepOjbedGuU7qVG0kTpz30gLki5jiEiNDqrU6KC/\r\nHHHwOgUAAAAAgByBCyRHrpE6T4V3xL5Rh3HjyHMA1hQjv32jCiVG3jIGvnPE06Mjxr7RYWPfyHvf\r\nSJYxNNAz34uhmJgY+vKj8bR4SZz49vdfTXe11O30aarbZpYxlMqROlHjXeROjuwKb71vVODeN/I2\r\n1ZllDObOkd43MlMjs4zhvYO6rQ5yBAAAAAAAOQIXX448I3UdxkidlqP2TqeMwW+krt4zUldjpEZ+\r\nTXUcc6SuwHvfqFHuGkUkR7qpLieFvhkjBUlwz0za7Llv5B2pi9ZUl+zdN/I5/trdprplxgFYs8Lb\r\n21S30JCjaGN1kCMAAAAAAMgRuEhypMsYzOOvuoxBp0bNPqlRgxIkXcRQ41PGUO5XxnBUHX9VaDHy\r\nLWOoiyxjWPbqMFuOntvcbo/T+ZYxGPeNeHqkpcguY4iyb6TH6vhI3VqVGukyhi5Toyx3jbdoqvMZ\r\nq9OpEeQIAAAAAAByBHqAHPnVeJ/03DcyK7wj5Oh45I0jLUhd3TfyjtR5kyO7jMF7/JXLUd4e+okr\r\nOYqj9V0kR3qszkyN7JE6n32jTZ7kaK1uqos2Umc21fnsG5lNdX4jde
9CjgAAAAAAIEegB+0cmalR\r\np3vfyNVUd9Jz4+iEM1ZX4yliqPRrqmt2N9UVHo28cZTjc9+Ip0Z8rO5gTQP97cdcigbRPzan0UNK\r\nkL4/fo+rqY6L0Q6f1Ci1tIsyBm9T3REjNcp3p0beMgZvU52u8XaN1Pk01XHePdDL5agonxr/+Adq\r\nvPIKqmFUsG/z78PnGQAAAAAA5KjXyFFEGUOU46/2jaOTEnPnKCI18ghSxPFXU5CMnaP80xx/1ftG\r\nCXNHCBkavrBI3DjalrzATpDGb+9wUqMK/+Ovuowhxa+MocgoYzjiHH9dG23fyDNWp5vqPjR2jj7w\r\npEau+0aXSHLUOPwRamLPfw2jnFHEyOeChM8zAAAAAADIUa+RI+99I2PfqKsab+9InRYkLUaupjqf\r\nGu+ioz5lDE3OOJ2rqc5z/PWgceNon7pxJO4bVUW/b2QnR6WRyVFEhbfPfSPvvtEqnxtHthjp+0ZG\r\nU11XydElIUdXXkG1SowKGRmMdJ4g4fMMAAAAAABy1FvkKBjylDEYyZEoYzBSo5YoZQz1RhlDraeM\r\noULVeJcbLXXFhhzpkTqzjOGwt4zBK0c1/LaRPP6qD8D6lTHYyZFiW5kzVqfH6XxH6vxuHBVEjtV5\r\n7xvxkbplKjXSyZE+/hqtjEHLUW8vZOCjdDox4mK0n7Hriito1apVNHXqVBo/frz43wfOL/x5njo1\r\njpYvW0jZ2Yfw9xwAAAAAOQJnIkehMIlDsN4bR6KM4ZRTxmDuG3mPvzZEuXHEpeh0x1/1Adh8JUhm\r\ncpQTRYx0amTLUXXXyVGaJzVK9e4bFUdPjswbR3Zq5JGj+FynjCEiOcpy3zgyR+rMprpev3P0xz/Y\r\niREXo52Mxd/5DqWkpFBbWxuFw+xFho/z/sGfZ/5879ixg6ZMnkSZmQfxdx0AAAAAOQLdlaNwkL1x\r\nDTJ7CbZQ2Dr
KYJZiNVI4UM+oYzALCdRSuLOaUUXhUxWMMkYpo4RCHUUU7ihkHKHQyXwKn8xjHGbk\r\nUuhEDoVPZDOyKHQ8g8LHD7HHdAod28/Yx9hLofbdjF2MnRRq284et1O4PY19exuFWrcyUhkpjCTG\r\nFgq1bKZg80bGBgo1r6fg0bWMBPbtBPa4mrGKQkdXUrApnrGcsYxCTUsp2PghYzEFGxZRsP59xkLG\r\nArLq57PH9xjzyKp7l4J17zDmULD2LbJqZ7PHWYw3yKp5nYI1M8iqns6YpphKVlUc41XGK2RVTmZM\r\nYkxkjCerYizjZcYYssr/zvibIFD2ImMUWWUvUKB0JOM5skqf7d1yVJhHBUyQDlx5hUiMlt5zD+Uc\r\nOgRbuYgfubm54jWFBAkAAACAHIFuyhEF25kQMTmyWhjNTIYcOSIuR501SowqGVqMFB0l7LGYCZKU\r\no3BHARMkKUeB9hxqazxMTXWM2lxFjkE2I0tSk8nIUBwUNFans0dG9QH27f3skbOPfXsve+Tsocaq\r\n3dTEaKzaxR53Chord1BT5Xb2mMYe08RjY+XHjG2Siq2KVEaKpDxJsYWRaLCZsYkayzayx/XUWhFP\r\np6qYLFX/wxajYDUTo8op7NtMjKq0GE2kQMU49jhOyFGg/CVbjrgYWeWOGFllz7HHvzI5+uslU+XN\r\nR+l4coGPi/+RnJhAixcvwt93AAAAAOQIdE+O/FMj4slRZ61IjrQcERekU+UyNeJi1FHskxrlUXN9\r\nPhUXFVJRUdElSAE1lSUwEXqNCdJrPqnRBCZEPDUa56RGruSIyVHZKCZJz7NHJkcqNQqUxF4ycjRt\r\n2jQx2oWPi//R2tJIcXGv4u87AAAAAHIEujVWZ7UyoozUddYwIWJidEqnRhVKjsqijtRxMbo0pchN\r\nU9lqJUZTJOZInUeOAkZqpMfpuBjpkTqeHAVKnrlk5IiXAmDH
qOfsIPHX1dq1a+jgwf34ew8AAACA\r\nHIGukyM5TkdMjLgchQMNESN1ZO8albvG6cL2OB2DyZF1LK9HJUZ7E5fR9Lg4mj57PqWmn1tpKy4q\r\noFOVM2RqJORIp0bjFGOZFOnk6CUnNSrXqdHz9q6RVRrLuHTkSLyu8NFjPszX1bZtKfi7DwAAAIAc\r\ngahvYnVqpHaNyGrwjNOpfSMtRx2yiIGP1IWM1Ch08jC1NXVfQDJTl1Hs4Lvt460xMXfQffcNp/lp\r\nuedEXjI3xMl/79330R3scUzCdnrn8cH0+OzEcyZILeVLjZG6iRFFDHrXaMCJWyip5iElRmZy9KzY\r\nNeIjdYGSpyFHPfCjLGUOjRgxgmZuKjqrn9NT5IiDBAkAAACAHIEukiMuRxQlNbIb6jqNXSNRwuCM\r\n1IXVSF1TXffkKH3FGFuIxryzjBJWLKK4MY8LiYldkX5OxCVhDBevUbTX/r5MmnhHDN0xKuGcyVFj\r\n2WoKulKj8VKOKse5WupiOtn/1mMxNPDozZRUOUSlRs+qIoZYMVIXQHJ0QT6K4mPVa28Y7Wk//c9P\r\nnzlY/PxBM9PP6uf0JDniI3b4+w8AAACAHAHfnSNHjOwSBiFGvMLb3DcyU6PIXaPQidxuytEuGnWH\r\nFKPZiZ6UKD+XcvPPjbgkTryPYu6YSLnncWyvsTRBpka8pa5iQmR9d8VLFCgbLcQopo3RxKiPoQGV\r\nN1Fy2YN2EQMfqQuUPAU5Ov85EI22k8oYGrEk77S/Im/BMPFzB3chPt35OT1JjpYsQXsdAAAAADkC\r\nUeWIj9SFA2qkLlDn3DU6VekpYTDlqMhOjWR9d/fkKDdRjrvdN+Y0CU5mIo0Z6ozd3TF0DCVmOinQ\r\nbPZjw+MW0fwxg50UalGa+PENcUOdX8cYGrfB/jVDp2+wf4/8vQkUe59+s3wfjRrzON199+OUmNtd\r\nOVpj3
DXScuQuYgiU/80RowZGFaOCURRDA4tuoqTiX4uROsjR+f9o3jNT/Fn3H9Rf/ZmPZrrk/uio\r\nTqPRgwfJnzc4lkYMiokQn+78nJ4sR731dQUAAABAjsAF2DlSYiQa6szkSI7U2fXd3tToZIGrvpvf\r\nNuqOHGVumCjeSE7ckNnFz0ujWPHmdSgt2pBGaYnzaahIm2IpLV/KUZyWGiYz81csolH3yR/fxX+P\r\nXRto4vA72D8PZz+2gjakpsuxuruZLNlSlkaPq99jfmIapa6YTfcpSVqReaZy5KRGooShXDfUyZY6\r\nnRiZYhRzhJHLyIqhAZk3UHLBLyBH5/WjnZYMU0LEXsOxSp7j9jQbZpRFw9T3D4qdSfFzRtuSbYtP\r\nd34O5AgAAAAAkKPeLEcNrvpue9fIVd/d9Uhd6EQOk6O80ydHqighrgs50gI1JiHT+HX6+5TocBm6\r\nb6K9U5QYxxOku22xiRyrk3J0t5Kj6L/H3ZRwJnKkR+oibhu9ZNd3CzGqZpQbYpQjxSjmAJOjQzdQ\r\nUr6UoyFDhtBDDz1Ew4YNo9///vf0ta/9B33729+ie+/9AQ0e/HN65JHf01//+gxNmjSB3n33bVq3\r\nbjUdOrQfcnSaD6ssQfx5D1uQ5xqFixm2hDrUz2lIUyUeg+KoQX1f1pzBLvHpzs+BHAEAAAAActRr\r\nx+rMw6+GHJ3ya6gzU6MCu4iBp0bdlaPMBCklo7ooXshUkrIs3fm+/LR33HLERWeiMyK3gctQzH22\r\n2GyYeLeQo8wu5egOWrQr3xj5+wRyVOndNXKSo4Co7x7tJEbFbjEakHkjJRX8kgIlT1Kg+C/iz2Pe\r\nvLlMet6hOXPepjffnE2bNq2n+PhltHDhezRz5nQmRePpmWeeot/9bhj96Ef3Uf/+/enqq6+myy+/\r\nnO666y4aOnQIvfLKZEpOToQcGR9pcYNUwtOfBg0aRP
3t3aP+lFBmuYoVYmImGOLj3ifqzs+BHAEA\r\nAAAActRrk6NG39TIfdvIqO8+qW8bFbjEKHwim8nR4dMKRf6ud8QeUMzgOENcvAI1Ro3e5XrExSNH\r\nxt7SJ5MjLmlOcrRi4mDXv6N7cjSRAvZtI6ehzr5rVDYqIjEacPhGSi78tShisEqeEmIUKHnirN7E\r\nZmdn0Jo1K4UYDRnyIPXr14++8IUv0J///EdKTU3q23LUkS5H4QbHMumcwyRzpniMHSx3jwbFpck0\r\nackIlQrNJFlkZ9Gm0YNc4tOdnwM5AgAAAADkqLcmR0Z9t6uIQYzU+ZUw8OTIqe/mI3VhW47yuiUV\r\ny0apooXBYyghbS9lZqbTrtQEmh47nOK4/OQm0lD+4/eNoQ17Mylz7wa1UzRUlSVEl6MV3ZSjovxU\r\nGi4SgLtpVFwcPW4UM3RfjlZH1neXv6T2jeRIHb9rpMVoQP5NlFz0AAVK5V2jgGqp48mRVfKXc/4m\r\ndtu2ZIqNfZquvfZa+uUvf0HFxQV9Uo50ffecrA63M2XNsWu90zv46F28vT80KHYCTRjRP2KfqDs/\r\nB3IEAAAAAMhRb02OXKlRjXP0VRcxaDk6VezcNeooEEdfhRidzBHJUehEFjXVHu5mDXY+JUyPlQmS\r\ni/vsI7C5actUCYPijuG0yD4QGylHcudoMCXkGrJ0dxdyxEnfQGOGD6a777iDBo+aTYvihrv2lrol\r\nRz5HX2VqJEfquBwNLLyZkouHMBl6jr25flbdNpINdZYYqXuC8fh5exObn59Dt9xys3ge+bf7lhw1\r\n05xB7h0h56OB4lTT3OhNsrcuK94pWIgZNJpmjlb7RHMc8enOz4EcAQAAAABy1CuTI+/RV++uUZk4\r\n/Boy9o2cXSMnNQqdyDwDOdJ3jTJp165dtHfvXtqbnusrUZmZmYL883CnKD/X/Xu9MzzGczi2m3Lk\r\
nOfoaMMTIKnuBSdFIcfTVUodfeXJkeVKj8ylHnMqCXJpy59fog6/cQU2zXhf/3Lfa6s6gvKGjndqb\r\nm6njLH8O5AgAAAAAkKNeKEciOdIjdWZ9t19qxO8anThsy5FMjbKZIHE5yj1vB1fPPek0RlSBD6bH\r\nY2NpsEqpHn8n7QyOwK6igHH01azv5vtGWo6ssudlaiTkyEmNAkZqdD7lqHbDWrKuu47Y/0Ab/s/8\r\n+yFHl/4H5AgAAACAHIFuj9U5qZG7hKEsMjUy6rvNIobQ8UwKH8+go3W9SY6KaNeGRRQ3cQzFMjmK\r\nHTWRliWmn9GvbyxdKVKjgFHfHZEalY1UyZGSo5JYp4jBSI0CxY+dlzexPCHyipEpSOcjQYIcQY4A\r\nAAAAADnqdYwfP55CnbVOEUOnLmIot8WIN9TZJQwdniKGk1KOwieymCBlUGtjdq+So7OlpfQDo777\r\nJXdLXfkoJkbPM0EayXhOjNOZu0a8oU7sG5XI5OhEwRPn5U0sH6HzEyMN//HzkkhaLYxmIusohQPq\r\n0LDVoPbb5KFhcr3m3AUgIfG6k1Lu1Mbnu6Q8rBLL8IkM9vo7SKFj6YwDjP0Uat/LHvcwdrNv72Ts\r\norB43E6htjTGx4xtFGpNVSRTsGULhVoSGZsp2LyJQs0bGRvYt9exx7WMBAoeXcNYxVhJoaMrKNgU\r\nT6Gm5ezxIwo2LmMsZXxIwYbFjEWMDyhYv5A9chawb79Hwbp5jLns2++yxzmMtylY+xZZtbMZsyhY\r\n8wZZNa8LgjUzyKr+B2Ma+/Y09jiVrKo4xqsUZFhVUxiTRWuieW/LFHbIEQAAAAA5At1g6tQ4JjRH\r\njIa6KndLXYd7pM5MjcKqhIGnRnzfKHT8EAXaDlFxUWEfkaMC6ih/xTNSZ6ZGWo6ed/aNSp4RcmSV\r\nPu0Zqfs/KtjxPE2YMOGcv4lteWFkl3LEf/y8
JEfBVluO9KFh4s2InboVsUa93sxmRP26Y6+5U0Xs\r\n9XbEKAAx0sqT+rWXZaeWXI7CAi5H+yjMCLUzOWrfzb69i4nQDvbtHS4xCgopSnHEqHWLFKMWJkYt\r\nG5kUbRByFGpez2RIy9FqJkWrmQytZHA5Wi5hYhRqcsQo1LhYilHD+1KM6ucLLC5G9UyM6t5hIjSH\r\n/bOUI6v2TSZIHCZITI6CtTPZ4wxBsGa6lCMlRsFqLkfstVfJpWiSpELf2xpnC7soCIEcAQAAAJAj\r\n0D2WLl1MKUlr2ZtVuWsU+dV7o77bJzXib1D1V+7DTI5Cx9PpaF1Wn5CjptJ44/Crc9uI13dbriIG\r\nc9foGbuIwWyps4ofo4VzX6Fp06ZeMskRWS3u1CjQ4NltM15zne4xTinkfgUgh9Wem0wrw0LKndde\r\nyBSjY3vY426RGAkpssXISI3attpyFGpJYmxhYrSZPUo5CrXI1MgRozUuMQo1xYvEKCRSIyVGjUsk\r\ndmrE5Kh+geI9xjwmRDwxelcIUrD2bfb4lpKjWVKMamYy3KmRkxjJ1EjIEU+NuBhVTfIcIx7rGvOE\r\nHAEAAACQI9ANsrMPiTdOOZnb7dtG1FnuuW0k36CGvHeNDDkK2V+5TxdfueeCdOkmSAVKjJzRpYBo\r\nqBstUiNvS50eqdO7RnYRg7FrtGH5ODHiOHfu3HO/c5Sfc1F2jsJcjCwpRq6ROjs18runJVOjkM/r\r\nzrXjZr/uDtmpUUi99uyROpUayZG6ne7UqHWrS4zscbrWRCFGQTFKt54JkRYjJzUSI3VNeqTOSY24\r\nHIW0HGkxanifLCFFMjWyx+m4FInkSI/TvSlG6nhq5IzU8dRoujNSZ4zTucSIEdDjdKo1MVA+xh7z\r\nDJSNhhwBAAAAkCPQXTIzD9LkyZNoa8p6aqlnb0DFV+799o0KIlKjkLHvERZfuZc7H/wr94G2f
dTa\r\ncIiaajOoqUbD/rnmICOdGqsPUJNgv2KfYi9jDzVW7aYmRmPVLsZO9m3ODmqs3E5NjMbKNEFT5cfs\r\nkbONGiu2MlIVKYxkSXkSY4siUbGZsUlStpGxgbFesY4aS9cqEhhr2PetopayxXSqIk58hT5wutTI\r\n2DXS+0ZmanSi4Ckq2DmK3pvzinjzOnfuuxFvYHt1W50apyOrUTYidkoxooB3nK7cPU7XZVqpXnvH\r\n3a89R4yc1IjvGolxOi5Gbdt9xukYbXLXKNSaJEbq7NRI7RqFhCCtZULkjNOFhBwZu0bePSN7nM49\r\nUmep1IiP1FlCjpxdI9c4Xc1Me9eIj9MFq332jMQ43WRn1yhKamRVyNcl5AgAAACAHIEzTJAWL15E\r\ncXFx4o0UuDBMnDiRpk2b5psYcZYsWXTO/ox5gsRH6Pidoyeu+ux5vXPUr18xpSa3iD0jeUdLoosY\r\npByZY5ymjDu7Rjw1CvmM04lROqOEQYqRSo2MXSMxUqd2jcKiiMEsYXDvGpnjdGZqxMUopMfpVBGD\r\nlqNgo1nCoMbpzF0jOzVyj9PxXSO5Z/SWnRhZIjFSclQtd43M1ChY/ZqTGikxGnjyVkquG+46RCyT\r\nTJUaiRTzRcgRAAAAADkCn5S1a9f4vlEHFx7+Z3Gu/3xLSo6Ie04//vH/o3wmTOflkzumk3GMBg5o\r\npdSkRnuczkmNvJXxpW4x4ntGHc6uUUgUgOTaJSDuUc4uShiittOpPSOdGhm7Rs5I3Xr2uJZJkTNO\r\np1MjuWukSxiW+aRGZgmDs2ukixgkUo4iShi4GFVPt0sYLL9xOpUYxXTGUMyxGBrY3I+Sqx8RgmSP\r\n1FU4zYmQIwAAAAByBD4hBw/uh5j0EPifxfn4My4oyKVf/vIXdO2119IzzzxF27Yln2M5OsZoYzQx\r\n6pkkVVPqlipbjLz3tEJGauRtRtTjdC
G1axQxynlMilHIHqcz67vNkbptctdIjdMFeQGDEKNE33G6\r\n6O108VKOeGrUpFKjhiURu0ZCihoWkFVnpkbOOJ1up7NUCYOlxulkO51MjcRIXdVr7Nuv+csRE6OY\r\nNkYTo55JUuUtlFwxzE6N9P4b5OgMKcqnxj/+gRqvvIJqGBXs2/z78NwAAACAHPVRtm1LgZxcZPif\r\nwfn+c05NTaI///mP9IUvfIH69etHQ4Y8SFOmTKI1a1ZSdnbGWciRFqMGRhWjglFE3x9QzCSpLGpq\r\nJGu7zT0jlRjxXSNXQ90hVwEIH6fTqVGYy5FuqPPsGrnb6XR1t7xrJFMj2VAnRursXSM9UufcNXKP\r\n03WVGpmJ0VzVUDdHFDFYvrtGM3wb6uzqbvOmUeUER4waGFWMCkYRk6QiJkklD9s7cJCjM6Nx+CPU\r\nFBNDNYxyRhEjnwsSnhsAAACQo76dIPGxLr73Alm5MPDnmj/n5ysx6ork5ER65ZXJNHToELrrrrvo\r\n8ssvp6uuuoruvPNr9MMf3ku/+90wio19miZNGk8zZ06nhQvfo/j4ZbRx4zohWbt3b6cDB/ZSVtYh\r\nOzEyxSgmho/z5TKyaOCALNq6pTBi18ivoc5OjdRNI0eMDrpTo3ajulvsGamRunYpR0GVGgXtkTp3\r\naiRuGnVZ3R3vEiO7vtsnNbJ8qrt1CYNuqAt6qrv5OJ0jRlNlO525a1RpNtRNlMmRSoxMMYo5wshl\r\nZDFJyrqZko8MhRydqRxdeQXVKjEqZGQw0nmChOcGAAAA5AiAvktGxgFat241zZ07h0nRBCFHjzzy\r\nexo8+Od0770/oG9/+1tCnm677Yt04403iDG9K674jBKjaka5IUY5QoxiYg4wOcqg1MQC18FXs53O\r\nPPhq3jTy3tRypUb2OJ33rpHfrlGSKzESN43sg6/rXCN1ctfIuWskGuqaupMaqYOvRmI
k2unqdH33\r\nbM/BV/ddo2DUXSN106hivBSjaka5IUY5UoxiDsTQgIybKalAytGDDz5IQ4YMoYceeoh++9vf0i23\r\n3Exf+tLt4s/vW9/6Jg0cOIDuv/8n9Jvf/IqGD39EjFuOGfN3mj59mhDhtWtXCQEu6gPjZXyUTidG\r\nXIz2M3ZdcQWtWrWKpk6dKmr3UShz/uHP89TX4mj5soWiNAh/JwMAIEcAgN75yW0nRsUuMeKJUWri\r\nEeOmUfdSI3HbyEiNzOru0LG9PqmROU7nlqNgizNSF/SM0wWNhjozNXJuGvmN0+nUaFH0hrp61VBX\r\n+7brppGzazQjysFXKUZB0VBnpkayuttOjIrdYsQTo6QjD9m3tvgbzfnz59G8eXNFZfw777xNaWlb\r\nRVrIkz+eAH7wwQL2/W/RtGmv0dixY+i55/5Kf/rTcPrVr34hRLh//zvp+uuvp0996p/pmmuuEVL1\r\nk5/8mB57bATFxU1h4hBPOTkZl8Zr+I9/sBMjLkY7GYu/8x1KSUmhtrY2CofDhI/z/8GfZ/5879ix\r\ng6ZMniTOTuDvVwAA5AgA0AvlyJ0YDRyQR6lbSuRdo06/XaNCJkVOO11EdbeRGLlTo32qpW6vU93d\r\nvpPCdmq0rcvUKNjspEbBo+vsY68CJkfBJqe6WzfU2eN0Wo7UOJ1Vv1CmRg1ajpzq7sibRu5doyAv\r\nYqiebpcwyJE6/xIGAT/4WjEuIjEaePgWSi56WDTUWeWjKFD2PBOk58/5WB0fn+SJ4ttvz6YXXhjp\r\nGsW8+eab6Kc/vZ/9ni/T5s0beudruDCPCpggHbjyCpEYLb3nHso5dAi2chE/cnNzxesYCRIAAHIE\r\nAOiFciTFaOCAAtqaVBZx08hupzulxchdxKBH6sIqNTJLGOSh4f3ucbr23acpYTBSIyZHQXOkrnmj\r\nq7pb3zXSN414ahTyljDwPSNz
nK7+fZUaGUUMeqSuXrbUWbVGQ13NLNc4nazuNlIjQ4yCXjGqnEAB\r\nJkZCjpQYDchnUlQ8TLXTyRKGQNkLQoysspEXdOdo69ZkmjXrdXr44aF0++230ec+d6349kcffUjl\r\n5cW97rXMR+l4coGPi/+RnJgg7vHh71gAAOQIANCr6NdvO5OiSufg66lKmRqd8k+NnLtGsrpbipG8\r\naaTH6czEKKyPvRqpkX3XqC3yrpGrhEE11NmpkRqnCwnUnlGTvmmk6rsblxt3jSJTI2fXaAFZTIzE\r\nrpG6aWRFlDDwkTo5TmemRvyukV3dzUfqdEOdPU43yR6nsyrHiYOvAwuZFJXK6m5500hWd2sxCpQ+\r\nJ7iYhQy7dm2nv/3tRfrqV79Ct956qyj96E17S/xIMx/twsfF/2htaaS4uFfxdywAAHIEAOhd8Dfj\r\nXIyos5o9mmJUGnWcTpYwqJE6dfDVHqlTB19Dx9J9D746JQzb1b6RX3W3PPbqPvhqpEZH5cFXnRqF\r\nzOpuJUa+JQx6nM7eM5pv1He/a9w18pQwqF0jPU6nU6Ogd5yu0l3CIOSoYqykfAwF+MFX+66RHKez\r\njNQoUPpsj2mr43tJ3//+QFHgsXLl8l7xWualANgx6jk7SPy1fLEaPQEAAHIEADgLOapSYlTluWvk\r\nPfjqlxo51d364KvZTidKGI7pEgZn18iVGrVGjtPJ1MhoqFM3jUL2TaPV9jidc/B1uVHfvcyTGi1y\r\nNdSJg69qnM7yOfhqljAEjXY6nhpZZmpkVncbd42kGMnUyKoYw3jJSI1e9EmNniWr9K89rsp76tRX\r\nKSYmhpYtW9IrXsv46Dkf5mv5QtyCAwAAyBEA4Ny8oeSpkR6n63RSo1CUEoaQfew1x9VQx1MjMVLn\r\nTY1cu0ZKjNoNMTJTI3vPSI/TObtGQUOOQr4NdT4lDGZqpG4aWcbBVyFGuqFO1
Hf7V3e7UiMmRjI1\r\ninN2jYybRjI1GkcBIUZSjnhqFFByJHaNVGoUKBtpp0Y9UY44/NAwr37nDXl9WY6s9gYqKyqisrJq\r\nam7vOINf2UGbZo6mEbEzKa+jb8oRBwkSAAByBADoBTtHxZS6pd4YpzNSo1NmanQkakOdvmnkTY38\r\nxunCXRYxqJE6IzUK2jeNZAmD9+CrHqcLucbplBx5Dr7KsTr3wddujdOJ+m7PTaOoDXVmajSWCZGZ\r\nGo2WlI2yq7u5GFlKjAIlz/TYI7C8RpzXguflZfdBOWqnlJkjRIJmMjO9vdu/fs4g/msG0572vitH\r\nfMQOf+cCACBHAIAe3lbXyThGAwccpdTESv8SBiZGISM1EuN0J9WekdgxOqQeD0ZUdzt3jXb6ljAE\r\njeruoNozEqmRGqdz2ul0arRGjNQJOTJG6nzvGrnESKVGepxO7RnxxEiXMPiN1EXcNVLjdEG7hGGy\r\nnRoFKtwlDGKczrVnJFMjPlJnlbtH6gI9XI44Awf+N82ePbPPyVF71hwlRINpwaY02pOyieZMGE3x\r\ned2XowWD5a9Pj5ocWbRpwjD2c/rTkjzrfOZfF+j3iZSjJUvQXgcAgBwBAHq8HB1jtDGaGPVMkiqY\r\nJKnU6FSRrO42Guoi7hoZ43RhUd3tf9Mo7LdnFOWuUdDYNZJyJBvq/Mfpot00MkbqjF2jaKkRH6cT\r\n1d21s6LeNHKqu+OMxEilRlVOEUNAlzAwQdIlDHrXyJsa6XE6qzSW0bPlaPLkiTRkyIN9To6K4mOV\r\nHMVGjsV1FNGEYYNp0ODRlKV+LC9+Ag0aNIgmJBR55GgYJaQl0Ij+MUJOBo2YSdqv8pbEOqlU//40\r\neHQ8+1XtFD96GA0aNoFS9qhfN2wBtVvVtGTCCBrUX//8QRQ7M4EaTNdpzqMF5s+JGSRkzv/3uTBy\r\n1JNeywAAADkCAESRIy
1GDYwqRoW4fTRwQCGTpCOuhjq9a2SO08nqbtlOp3eNwsedIoaIu0bt7nE6\r\nu7pbNNMlGkdf1cFXTwmDefA11OTsGpmpUcgcp6s3Shh8xMhJjWaLm0ayvnuWXcTgumtk7xqZDXWT\r\nnHG6Cp0ayXY6Pk4XEFJkJEZiz+h5V0OdTo0CJU/3yDeUlQW51DTrdcp6aCi9dPtt4p/7khxZ1Zuo\r\nvzFON3rOJkdE2tNpcIx7ZC5rzmDx8wbNTPfIkWTwCCYt+t83eIGQk+q0Bfb3DRoxgebEp5PFx/GM\r\nXxfDhGvQiCXU3pFOw5jszFySQGlMtkYPkj8+Ia1BCVsWjbD//aNpwZIlNIH9nkuy2qP8PpAjAACA\r\nHAEAlBzJxMgUI34UNiYml5HFJCmDUjfn+KRG2fZInb5rFDIa6szUyClh2O4qYXBuGunUyN1Qp0fq\r\n7BKGZr8Sho98UiPvTSOdGqnq7jrPSF2dvms0y9VQ5z34Gl2M/BrqXrZH6pwShhcjShgCKjXiYhQo\r\nearHvaGs3bCWrOuuI/ZisOH/zL+/LxUytBdtUolPjD1it6mIaY0QFTUyZ8vRMClBPnI0M61a+csC\r\n+98jparD/jlzdARl/LrR8Vm+BRHV1WWUMHqQS8aKlqj9qP4TqNqnHCLy94EcAQAA5AiAS5iMjAO0\r\nbt0amjt3Dk2YMJaefPIJevjhoXT//T+he+75LvXvfyfdfvttdMMNNygxqmaUG2KUI8QoJuYAk6OD\r\nlLIpW900ynHG6U74t9NJ9tpFDGEuR23qrpEYqdsWMU4ndo1azZtGG4x2unWqgEHeNLKPvTa5ixjE\r\nwdeGJZElDEyOrNOM00WUMFTPUEUM01V191SJru723jVSu0Z6nE6UMHjFSFV3y3E6Xd3tFDHwkbqe\r\nJkc8IfKKkSlIPS1BOv9V3h2UlzLHSX1i4qjBR47yFkSTo2HOzpGVZf8
6KUeGQKU3R+wquTymo4ji\r\nBvePKIgY7JGj/rEJPqmQ3+8DOQIAAMgRAJcAhYV54lgnF6AHH3yAvv71u+jKK68Q9O/fn374w3vp\r\nd78bRi+8MJKmTJlEb701mz78cBFt2LCWUlK20K5d243EqNglRjoxkuN0h/13jU5kOKnRMaOhzr5r\r\npMToNNXdIWOczn3XSB58jdg1UuN0Qoyalrna6UJd7Bm5UiMhR3NcI3VmdTcvYQiaJQzVrzklDDo1\r\nMvaM5I6RGqkz7hrxIoauqrvN1ChQ8mSPekPJR+n8xEjDf7xvyZH2mjn2Hs+eGmesLl2YSAPNGRYT\r\nRY6cQgaraIn6dwxT4uOM0EUmR454mWN7Wn6yZsp/HjwnyyVnMf2ZvPk15yE5AgAAyBEAlwqJiRso\r\nNvZp+s53vk2f+tSnhBD99rcPUVzcFCFKPDU6s7E6d2I0cEAupWzOEyUMIbO6+0SkGIXUrlH06m7Z\r\nUCfru72pUaorNXKqu52bRlyMQmqczp0aaTHyNNR5UiNLNNQ543Q6NdI3jUR1d41MjYJmdbd508iu\r\n7zZG6nhipKq77Ya6CmfXSJcwBMpGy1E6PU7nKWEIlMS6UiOrh8lRC5PqruSI/3hfkCNeYjA4No7i\r\neVPdnk00YZhKbQbNpGYqo9F6h2dYLI0YFJnkuHaOhsVRCvt36D2hmGHxKt3poCVaqkbPpE1peWLn\r\nyF+OlPwMnkCbNjlJVv9hc4hP+lHzHuf7RvDfbw8lLJgpxwB9fx/IEQAAQI4A6EXwhIcL0c033yT4\r\nv/97lD74YAHl5+ecg50jKUYDB+RRamKBqu52t9OJ6m4xUpcld43skbqDnpG6vZEHX9v9bhr5H3wV\r\nJQwtG+27RnzXKGQXMUQ21GkxCkXbNdI3jezq7ncUaqTOc9fI3jWqkbtGdkOdGKczD77q+u4JnoOv\r\nOjFyN9Q5RQwe
OVKpkcWTo+InGX9BctQj5SjyxlH/YRMoXbUyZC0Z7Xx/7BxaEiflZdiCrIgEKHbE\r\nIOffM2wmFRnhTUP6AtfIXrM5jmdWyjXscQoXYvpT3II4+9fF7WlWO1IpFDvI/d88J6s9yu8DOQIA\r\nAMgRAL2ALVs20s9//jO6+uqr6ZFHfi9So3P9e/Trt51JUZHr4Ku7oc5/nC5kN9TpEgbvTSPj2Gu7\r\nJzVqM1IjY5xOHHxt2WCnRkGPGLlSI1diZKZGi2RDXb1/dbcVcfB1luvga/SbRjo1Mg6+VvgffJUN\r\ndaPdDXU8NSp9zkiNnnGN0wmKn+hZO0dMvrFzpMbgOtqpoaGaqqurqaG5w/fHm5u7V4rd0d5O7e3t\r\nUfeampuZFnWcLs+xqJ39fvqnWe3N1NzeEZECtbN/V7Px887894EcAQAA5AiAi0x2doaQoWuvvZZe\r\nfPEFOnIk77y+oeRiFNIHX703jXh9t50aaTE6JOQoLDjAhIjJUXtkauSM07l3jYItSXLXqFXLkRIj\r\no7pbkqDKGBw5CvHUqFGO04V0auRTwhC0R+pkamQZiZE89vqWffA1WPuG2DOyjNTIGafzlDBoMao0\r\nD746YuS6acQPv7ruGj0nShjEOJ26a2SVPm2LUU+TI7TV4QNyBAAAkCMALiorVy6nG2+8QbTL5eVl\r\nX5A3lDIxUnLUccROjfRInV3dbd81cpcw6HG6MMe8acTFqHWbMU5nHHxtSXJuGvEShmZvCcMaSdMq\r\n9zgdF6OmKHtGjYukHDEx0g11lihgYNT73DWqnaXEyChhEO10TgmDFiP3OJ1ZxKCru31KGERD3fNd\r\nVndLMfqLECOr+PGeeecoP0eM0L15042055mn+tydI3xAjgAAAHIEwEVg4cL3RFo0f/7cC/qG0hyn\r\nc5UwnPRLjZzESMrRPruhTqZGO/3vGhnjdDo1Copjr85NI7uEw
UiMIlIj864Rr+7mu0a6oa5elzAs\r\nMBrqvKmRkxjJPSM9Uve6XcQQdN01ivNJjSaqcbqxrptGAVHbPdqVGPFjr3ZqJCq8pRzpEga+a2SV\r\ncDl6nPFYj35DOXToEJo0aUKP/fwRr2WrhdFMZB2lcKCJ0ci+3cAe6yjcWcuoIeqsZo+VjAoKn+KU\r\nMUoZJRTqiBwvlejdu2xFlPFSnaDa46W7KOy3e+ctJbGPH6svFLhS1AT1xQJ1/PioUWPvLSUxd+/4\r\naKl39874QoG5dye+UFDjJKjmeGmwZpqryj4ovmDgGS9VXygwd+8gRwAAyBEA4BOTlrZVLEjHxy+7\r\noL/v+PHj2ZvAI3ZiFFZy5LdrZKdGx+TB1/BxMzXyHHz1HadTB1/Fm0FnpM6p7l5nH3x1lTA0dSM1\r\natB7Rgui7hqZqVFQpEaz7BIG166R702jScY4nTlS506N9F0j165RlNTI8qRGJwqe6NFvKGfPnkkD\r\nB/53j5YjCrbackQWl6MGIka4s449SjkKd1YZclTmyBEXo1NFzudDR4ErQQ2flF8oCB1Xu3fHvV8s\r\n2OdqbAwf0ze+drjEKOhz48tOUMUXCjbYpSTOFwsid++C5o0vJUb+Vfbz2evfKSURx49dI6bOFwtk\r\nlf0MtX833TVealfZmwlqReTxY9HWCDkCAECOAACflP3799A//dM/iQa6C/17T50aRy31GfauUciV\r\nGmX7pkY6MXLa6YxdI3XwNaxTozYlR2ZqxNvpjJtGzsFXZ5xOvBE8utI49hqvyhg8qVEXB1/lTSOd\r\nGs2x94wsVcJguRIjZ9fISY0cOQqau0YV+uCrFKOAz8FXq1ynRs85x179RuqM1Khg5ws0ceLEHvuG\r\nkrcj8nKQNWtW9lw5slrcqVFApUZCjKoVVTIx6ix35KijxFVKErZTo7yIG19hMV5q3Pg67k5QnS8U\r\nmGIUpb
FRjJducX0+mKUkUffuzARVf6HA/GJB/fvqCwULfA4gs8+JWn0A+U1XKUn0LxT4fLFA3/my\r\nU1TnxhdPUSFHAADIEQDgE/HAA7+hRx/900X5vZcu/YBSEuNd43Tyq+S5zq6RSo2kHMkRIpkaeRvq\r\n3CUMQW9qpBIj+UYw0b5rpN8MOiNEPtXdjcb4UIN6I2h+ldx+I+h8ldx5MyhTIz1Sxw++iuTIp6HO\r\nLmHgXyWv9EuNzDeC8q6R01CnW+p8UiOfm0ZajKy8EXTika9RzWWfprJPf5p2/eiHtOi9eT3yDeU7\r\n77wlEs6eKEhyrI6JkSXFyDVSZ6dGTI5OmalRqZ0amaUkEZ8PxhcKZIKqRuqOO3e+xEhdu2e8NEop\r\niWucrtUpJQmKCnstRs7ng77zJT8flkdW2Xd146vO/ELBO0aC+qZdZe+M1M0QpSQRnw8RKeokeeOr\r\nwklQRSmJceMLcgQAgBwBAM6Y3bu305VXXkmHD2ddpGa8Q+JNTM6hpIjUyK7uNr5Kbr8R1OND5jid\r\nWcTg2q0wvkruOviqx4e6GqdTbwTVboU9QuTbUOdNjZyDr/Kr5M5NI68YBe0ShqmuIgY5QmTcNfKp\r\n7vYdpyt73nXTSCdG9q6RbqgreUKIURMTjhpGOaOIkcwEqae+ofzww0VCkObOndMDkyM5TkcWl6N6\r\nMU7HxYgC3nG6cvc4nU8piRwvzZWfD3ykjo/TmbtGx9Pd43Rq10iM03nHS+1xOv/du1CLs2ukb3yZ\r\nnw8hIUfGrpF3z8j+QoH788GKsnsX9OzeBT2lJMFqnz0j/bngbWz0pEZWhfx8gBwBACBHAIAz5tln\r\nY+nPf/7jRf1vyMw8SJMnT6KtyauopXa/SIycr5KbI3XpSoz2e0oYouwaeXcrVGqkdytC6ivlYoTI\r\nO1LXtNL/zaAap7N3K4w9I6su8o2g+Cp5nTs1cnYrnBI
G567Ra85uhfFVcr1bEfApYZBy5DTUOQdf\r\nPXeNDDHiJQwnCp6igp2jRGJUq8SokJHB2HPZZT36DSVvVbztti/S978/kFavXtEj/pv69Sum1OQW\r\nsWfExYgUuohBylGVUcKgxumUHOldo5DR1ujeu8twlTA4pSTGFwtc46U7jPHSbZGfD61bIsZLQ8aN\r\nr5A9XrrKNWLqSlEbo6WoPnt3td4bX55Skmq5a2SmRkHvFwqYGA08eSsl1w33lJI446W6rRFyBACA\r\nHAEAzphvfOPrtHz50ov+38ETpMWLF1FcXJx4UwMuDHzHiI/S6cSIi9F+RpqSoyVLFvXY125RUT5N\r\nmTKJbr31VvrKV+6g0aNH0a5d2y/e/1HFdDKO0cABrZSa1GiP0zmpkRajyNRIiJF940ulRj53vkLd\r\nKWGI2k6nElR7986RI2ekbr34QkHoqDNOp1MjvXcnE9RlPqmRmaC6Gxv1SJ1fY6P4QgEXI7F3Nz16\r\nKYlKjGI6YyjmWAwNbO5HydWPOClquZMa8TtfkCMAAOQIAHDGfJq9Mb4Q94zOhLVr10S8qQHnD75j\r\nVGiI0U7GOjVWx/8sevpruLy8mD766EP67W8fos997lq6/fbbxJ2uN96YQampSRdQjo4x2hhNjHom\r\nSdWUuqXKFiPyyFHISI30OF3IM06nU9TQCW+CqktJ9DidWd9tpqjbXFX29gFks5TEGKeL3k4X7xxA\r\nbvLs3rkaGxeI6m6dolq6gMHTThdRSuI7YvqavxwxMYppYzQx6pkkVd5CyRXD7NRI791BjgAAkCMA\r\nwBlx6NB+uuqqq3rcf9fBg/shLReQRfPmUgqTod2XXSYSIy5GH6hCBv5n0dte15s3b2BvjF+mn/70\r\nfrrllpvp8ssvp7vuukvcSXr++efo7bdnM+lbRQcO7D3HcqTFqIFRxahgFNH3BxQzSSqLmhrJ2u4j\r\n
7hp7vWvkaqhzSkn07l3YLiXZ4zTUeffuXO10uro70di9c6rsg/aukdPY6FtK0mVqZCZGc31LSaLt\r\n3pmpkWu81NgzssWogVHFqGAUMUkqYpJU8rA9Xgo5AgBAjgAAZ8THH6eIvY2e+N+2bVsKxOUiw/8M\r\nLoXXeU5OBq1aFU+vvjqFHn/8/+j++39C/fvfSddccw196lP/TNdddx3deefX6Ac/GES/+tUv6E9/\r\nGk7PPfdXGjt2DE2bFica8njNPb8BtmHDWkpK2kxpaam0d+9Oysg4QFlZByk3N9NOjEwxiok5wshl\r\nZNHAAVm0dUthxK6RX0OdnRodz/K0NR50p0btRnW32DNSI3XtRmNjayp7TPGtshelJF1Wd8e7xMhV\r\nZe/bUOeu7nbt3tliNMu1Z+SI0VTZTmfuGkU0Nk60EyNTjGKOMHIZWUySsm6m5CNDIUcAAMgRAODM\r\n2LkzTXxlvaf+9/HUgo918b0XyMqFgT/X/DnvjYnRJ91b2rNnB61bt5oWLnyPpk+fRmPG/J2eeeYp\r\nGj78EXrggV8LmRo4cAB9+9vfElL15S9/ifr1u0VIFResK6+8QqRTUoyqGeWGGOUIMYqJOcDkKINS\r\nEwtcB1/Ndjrz4Kt500jf+fI2NpoNdZF3jfx2jZJciZEuJdGNjeZIndw1cu4aiVKSpu6kRqrK3kiM\r\nZFujeQB5tquUxLfKPmKcbpJ940uIUTWj3BCjHClGMQdiaEDGzZRUIOXo0UcfpSef/AuNHDmSXn75\r\nZVqwYJ5o6MTf/wAAyBEAwPcr6vxNHZ4LAM7FWJ1OjIpdYsQTo9TEI8ZNo+6lRt4bX2Z1tziAHJEa\r\nmeN0bjmy73y1miUM7oOvrnE6100jv3E6nRotit5QV68a6mrfdt00cnaNZkQ5+CrFKCga6iLvfNmJ\r\nUbFbjHhilHTkIfvGF5ejGTOm0yuvTGHfHssE6
TkaNOh/6POf/xx99rOfpR/96Ic0fvxY2rHjY7x+\r\nAQCQIwCA5LLLLutxhQwA9E45cidGAwfkUeqWEnnXqNNv16iQSZHTThdR3W0kRu7UaJ9qqdvrqrJ3\r\nDiBv6zI1CjYbVfZHnePHAl5n3+RUd+uGOnucTsuRGqezeJU9T40atBzNcx0/dt80cu8aBY0q+6BO\r\njaKUMAgq5I0vb2I08PAtlFz0sGios8pHqRtfz3c5VpeevpfefHMWPfjgA0KWvv71u+i1116hwsI8\r\nvJYBAJAjAPoy/E3BmjUr8VwAcNZyJMVo4IAC2ppUFnHTyG6nO6XFyF3EoEfqwio1MksYQl3e+IpW\r\nwmCkRkyOguZIXfNGV3W3vmukbxrx1CjkLWFQN77scbr691VqZBQx6JG6etlSZ9UaDXU+N76CNUZq\r\nZIhR0CtGlRMoII4fj7PFaEA+k6LiYa4bX4GyF4QY8QPI3d054m2Hixe/T/fe+wMxKsnr4UtLC/Ga\r\nBgBAjgDoi/D6Y97shecCgLOjX7/tTIoqnYOvpyplanTKPzVy7hrJ6m4pRvKmkR6nMxOjsD72aqRG\r\n9l2jtsi7Rq4SBtVQZ6dGapwuJFB7Rk36ppGq725cbtw1ikyNnF2jBWQxMRK7RuqmkRVRwsBH6uQ4\r\nnZka8btGdnU3H6nTDXWVxgFkNU5nVY4TB18HFjIpKh2mjh//za7u1mIUKH1O8EkKGTZtWk/f+c63\r\n6T//8xvYTQIAQI4A6Iu8/vo/6Gc/+188FwCcJfzNOBcj6qxmj6YYlUYdp5MlDGqkTh18tUfq1MHX\r\n0LF034OvTgnDdrVv5FfdLY+9ug++GqnRUXnwVadGIbO6W4mRbwmDHqez94zmG/Xd7xp3jTwlDGrX\r\nSI/T6dQo6B2nq3SXMAg5qhgrKR9DAX7w1b5rJMfpLCM1CpQ+e1ZtdU899ReK4Xe/9u/BaxsAAD
kC\r\noC/BZ+8/85nPYIwEgHMiR1VKjKo8d428B1/9UiOnulsffDXb6UQJwzFdwuDsGrlSo9bIcTqZGhkN\r\ndeqmUci+abTaHqdzDr4uN+q7l3lSo0Wuhjpx8FWN01k+B1/NEoag0U7HUyPLTI3M6m7jrpEUI5ka\r\nWRVjGC8ZqdGLPqnRs2SV/vWsq7z5F474UeFdu5AgAQAgRwD0KXg98dKli/FcAHCWciRSIz1O1+mk\r\nRqEoJQwh+9hrjquhjqdGYqTOmxq5do2UGLUbYmSmRvaekR6nc3aNgoYchXwb6nxKGMzUSN00soyD\r\nr0KMdEOdqO/2r+52pUZMjGRqFOfsGhk3jWRqNI4CQoykHPHUKKDkSOwaqdQoUDbSTo3OhRxx/vGP\r\nqaK6vaAgF69xAADkCIC+Ar/r8sADv8FzAcBZ7RwVU+qWemOczkiNTpmp0ZGoDXX6ppE3NfIbpwt3\r\nWcSgRuqM1Cho3zSSJQzeg696nC7kGqdTcuQ5+CrH6twHX7s1Tifquz03jaI21Jmp0VgmRGZqNFpS\r\nNsqu7uZiZCkxCpQ8c86OwN5zz3dp8uSJeI0DACBHAPQV+Fz9FVd8BjW2AJzN/1HFdDKO0cABRyk1\r\nsdK/hIGJUchIjcQ43Um1ZyR2jA6px4MR1d3OXaOdviUMQaO6O6j2jERqpMbpnHY6nRqtESN1Qo6M\r\nkTrfu0YuMVKpkR6nU3tGPDHSJQx+I3URd43UOF3QLmGYbKdGgQp3CYMYp3PtGcnUiI/UWeXukbrA\r\nOZaj1NQkuu66z1NxcQFe5wAAyBEAfYXvfvduevfdt/FcAPCJ5egYo43RxKhnklTBJEmlRqeKZHW3\r\n0VAXcdfIGKcLi+pu/5tGYb89oyh3jYLGrpGUI9lQ5z9OF+2mkTFSZ+waRUuN+DidqO6unRX1ppFT\r\n3R1nJEYqNapyihgCuoSBCZIuYdC7Rt7
USI/TWaWxjHMnR5w77riDVqz4CK9zAADkCIC+wuzZM8X4\r\nCJ4LAD6pHGkxamBUMSrE7aOBAwqZJB1xNdTpXSNznE5Wd8t2Or1rFD7uFDFE3DVqd4/T2dXdopku\r\n0Tj6qg6+ekoYzIOvoSZn18hMjULmOF29UcLgI0ZOajRb3DSS9d2z7CIG110je9fIbKib5IzTVejU\r\nSLbT8XG6gJAiIzESe0bPuxrqdGoUKHn6nMrRyJHP0uOP/x9e5wAAyBEAfQU+MnLNNdfQ1q3JeD4A\r\n+ERyJBMjU4z4UdiYmFxGFpOkDErdnOOTGmXbI3X6rlHIaKgzUyOnhGG7q4TBuWmkUyN3Q50eqbNL\r\nGJr9Shg+8kmNvDeNdGqkqrvrPCN1dfqu0SxXQ5334Gt0MfJrqHvZHqlzShhejChhCKjUiItRoOSp\r\ncypH/ItH//u/9+N1DgCAHAHQl+C3Pf7wh9/juQBAUV5eTPv27aZVq+Jp1qzXafToUfToo3+mX//6\r\nlzRo0P/Qf/3Xf9K///u/080336TEqJpRbohRjhCjmJgDTI4OUsqmbHXTKMcZpzvh304n2WsXMYS5\r\nHLWpu0ZipG5bxDid2DVqNW8abTDa6dapAgZ508g+9trkLmIQB18blkSWMDA5sk4zThdRwlA9QxUx\r\nTFfV3VMlurrbe9dI7RrpcTpRwuAVI1XdLcfpdHW3U8TAR+rOtRxt2LCW7rzza/icAABAjgDoS/A3\r\ngVdeeSXl5mbi+QB9Mj1dt24NjR8/lh544NfUv39/+vSnP03XX389feMbXxfHkp944jH6+99Hi4rn\r\nBQvm0Zo1KykxcQNt377NSIyKXWKkEyM5TnfYf9foRIaTGh0zGursu0ZKjE5T3R0yxuncd43kwdeI\r\nXSM1TifEqGmZq50u1MWekSs1EnI0xzVSZ1Z38xKGoFnCUP2aU8KgUyNjz0juGKmROuOu
ES9i6Kq6\r\n20yNAiVPnlM54q8LyBEAAHIEQB+Ef0V81Kjn8VyAPsHevTtp4sRxIgW6/PLLRQr08MNDadq0OFq9\r\nesUZfaHAmxgNHJBLKZvzRAlDyKzuPhEpRiG1axS9uls21Mn6bm9qlOpKjZzqbuemERejkBqnc6dG\r\nWow8DXWe1MgSDXXOOJ1OjfRNI1HdXSNTo6BZ3W3eNLLru42ROp4Yqepuu6Guwtk10iUMgbLRcpRO\r\nj9N5ShgCJbGu1Mg6D3LEZRmfMwAAyBEAfYwtWzZSv89dS3UzplHLCyOpadbrVIkDiOASoqTkCM2c\r\nOZ2+97176OqrrxYp0VtvzabDh7POcudIitHAAXmUmligqrvd7XSiuluM1GXJXSN7pO6gZ6Rub+TB\r\n13a/m0b+B19FCUPLRvuuEd81CtlFDJENdVqMQtF2jfRNI7u6+x2FGqnz3DWyd41q5K6R3VAnxunM\r\ng6+6vnuC5+CrTozcDXVOEYNHjlRqZPHkqPhJxl/OqRzxJs8f/vBefP4AACBHAPQ1ajespYZ//mdi\r\n7/JsrOuuE9+P5wf0ZkpLC2nSpAl0ww030H//9/fo7bdnU1FR/jn79/frt51JUZHr4Ku7oc5/nC5k\r\nN9TpEgbvTSPj2Gu7JzVqM1IjY5xOHHxt2WCnRkGPGLlSI1diZKZGi2RDXb1/dbcVcfB1luvga/Sb\r\nRjo1Mg6+VvgffJUNdaPdDXU8NSp9zkiNnnGN0wmKnzincsRHKf/85z/i8wgAADkCoC/BEyIuQqYY\r\nmYKEBAn0VvhCPb9Vw6Vo3brV5+X34G/GuRiF9MFX700jXt9tp0ZajA4JOQoLDjAhYnLUHpkaOeN0\r\n7l2jYEuS3DVq1XKkxMio7pYkqDIGR45CPDVqlON0IZ0a+ZQwBO2ROpkaWUZiJI+9vmUffA3WviH2\r\njCwjNXLG6TwlDFqMKs2Dr44Yu
W4a8cOvrrtGz4kSBjFOp+4aWaVP22J0ruVoyJAHacqUSfhcAgBA\r\njgDoS/AROj8x0vAfx/MEehu8YOGqq64So3Pn8/cRciTESMlRxxE7NdIjdXZ1t33XyF3CoMfpwhzz\r\nphEXo9ZtxjidcfC1Jcm5acRLGJq9JQxrJE2r3ON0XIyaouwZNS6ScsTESDfUWaKAgVHvc9eodpYS\r\nI6OEQbTTOSUMWozc43RmEYOu7vYpYRANdc93Wd0txegvQoys4sfPqRzddNONlJqahM8nAADkCIC+\r\nBN8x6kqO+I/jeQK9iZde+hvdfvttok3ufP9ejhzJcTpXCcNJv9TISYykHO2zG+pkarTT/66RMU6n\r\nU6OgOPbq3DSySxiMxCgiNTLvGvHqbr5rpBvq6nUJwwKjoc6bGjmJkdwz0iN1r9tFDEHXXaM4n9Ro\r\nohqnG+u6aRQQtd2jXYkRP/Zqp0aiwlvKkS5h4LtGVgmXo8cZj50zOeItnnw3DZ9PAADIEQBIjpAc\r\ngV4Lr9qOYa/bnTvTLlBCNZ4J0RE7MQorOfLbNbJTo2Py4Gv4uJkaeQ6++o7TqYOvYtfIGalzqrvX\r\n2QdfXSUMTd1IjRr0ntGCqLtGZmoUFKnRLLuEwbVr5HvTaJIxTmeO1LlTI33XyLVrFCU1sjyp0YmC\r\nczdWN27cy/Sb3/wKn1MAAMgRAH1u5yg/BztH4JIgLW2rGKXjFcwX6vecOjWOWuoz7F2jkCs1yvZN\r\njXRi5LTTGbtG6uBrWKdGbUqOzNSIt9MZN42cg6/OOJ0Qo6MrjWOv8aqMwZMadXHwVd400qnRHHvP\r\nyFIlDJYrMXJ2jZzUyJGjoLlrVKEPvkoxCvgcfLXKdWr0nHPs1W+kzkiNCna+QBMmTDgncvTNb/4X\r\nLVz4Hj6vAACQIwD6IryVzitIJ6++Cm11oFfx05/eTy+++MIF/T2XLv2AUhLjXe
N0orrbTo2y7dRI\r\nypHcNZKpkbehzl3CEPSmRioxkmKUaN810g11TgmDT3V3o3HTiIsRT43Mg6/2ON18sur0OJ1MjfSu\r\nkR6p4wdfRXLk01BnlzDwhrpKv9RIj9ONte8aOQ11uqXOJzXyuWmkxcjKG0EnHvka1Vz2aSr79Kdp\r\n149+SIvem/eJ5Wjfvl3iMDY/EIzPKwAA5AiAPpwg8RE6vmO0/rcP0f8b8N94XkCvge+IXHnlFWd9\r\nt+hMyc4+JEa5cg4lRaRGdnW3uGkkSxj0wVctRiFznM4sYtB3jbwlDK6DrxvUTaOuxumWK1RDXVOU\r\nkboGd3W3TI2cg6/BOvdNI68YBe0ShqmuIgZZwmDcNfKp7vYdpyt73nXTSCdG9q6RbqgreUKIUVNM\r\nDNUwyhlFjGQmSJ9Ujp588gn64x//gM8rAADkCAAg4XdgPv/5z4njsHg+QG+A3zJ64IHfXJTfOzPz\r\nIE2ePIm2Jq+iltr9IjHS43TmXSOZGu0XuEsYouwaGWIUNFKjoN4zEtXdqojBO1LXZI7ULXenRg2L\r\nKWSXMCw0EqPIEgaxZ1TnTo2EHNW6Sxicu0avqbtGZmo0yb5pFPApYZBy5DTUOQdfPXeNDDHiJQwn\r\nCp6igp2jRGJUq8SokJHB2HPZZZ9Ijvjffddccw1t25aMzysAAOQIAOAwatTz9Otf/xLPBegV3H//\r\nT2j27JkX7ffnCdLixYsoLi5OJEngwjBx4kQxSqcTIy5G+xlpSo6WLFl0Rn+Ob7wxg+6557v4nAIA\r\nQI4AAG5yczPF3D0fV8LzAXo6//EfX6WNG9f1iP+WtWvXRJQCgPMH3zEqNMRoJ2OdGqvjfxbd/XMr\r\nLy+m2277In344SJ8TgEAIEega0pKimjlypU0depUUV2Lr1heCMbT5FfiaMEHC8RXpS/Gn/vw4Y/Q\r\nU0/9BZ8DoMdz/fXX054
9O3rEf8vBg/shLReQRfPmUgqTod2XXSYSIy5GH6hCBv5n0d0/tzlz3qS7\r\n7roLn08AAMgROA2VFeLNenJKKh1taaNTVphB1ME4GSA6oTjWSdR+StLGaO0gamE0nyQ6ymhiNJ4g\r\nqj9OVHeMqJZR005UrahqI6pQlLcSlbUQlTJKmomKFUVHiY40EeU3Sg43SHIZOfVE2YwsRmYdUUYt\r\n0SHGwRqidMUBxr5qor1VRHsqiXZVSHYydpQTbWekMT4uI9rGKSVK5ZQQpTCSGUnFRFuKiBIZmwuJ\r\nNh5hsMf17HFdgSQhn2gNJ49oNWPVYaKVjBWM+Fyi5TlEHzGWZRMtZXzIWJJFtChT8kEG0cJDYZq3\r\nu41eX76DJk6aJPYaLvSf/datyWL+Hq1NoKfDX6cZGQd6zH/Ptm0pEJeLDP8zOJM/s69+9Ss0f/5c\r\nfD4BACBHoKvEqJimTJlC2dm5ZIWIOoMSLkeck5YUo+OK9k4JlyMhRh1KjE5IMWo4ruRIwQXJliNG\r\npZ8ctUgpKlRiJORIkdcoxUjIUYOUo2yPHHGEGDEp2ldlyBFjd6UhRxVSjoQgKTHaqnCJUbESI8Ym\r\nJUcbFFqO1hY4YuSSo1wpRx8ZcvRhlsQlR4yFQpCIFjBmr88VgnoxEqTvfe8emoVDsKCHc+utt/a4\r\nJXqeWvCxLr73Alm5MPDnmj/nZ5IYcV5//R/0n//5DXwuAQAgR6BrVq1aRdu376BgmIQcBUKOHOnk\r\niHO8UyZHnNYuUqMGIzmqU8lRjSFGQo5apRx5U6NCJUgF3uRICZIWo6w6KUecg0ZyxOVovyFGthxV\r\nepKjMpkccbaaqVGxJzXSclQoxWh9gWRtviTBTI7yHDGyU6McmRotVanR4kzJByo5et+Qo/mMOcvW\r\niIXvC/0amDv3Hbr77u/g8wH0aL797W9RfPwyPBfgjOENdTfeeAOtWPER
ng8AAOQIdM20adOouaWN\r\ngiFyJUccc6zOLzXSctTkkxzVq9SoxhitM1OjUiM1EuN0xkgdRwtSXqN7rC5ipK7WGacTI3VVEj1W\r\np+Vol0qOdqixOm9qpJOjLX7JUaEzVsdZW+AWo5XekTqFKUd6rG6xSo/eV3IkxOgg0XucXQ0UF/fq\r\nRXnjcMUVn0ExA+jRPPjgA+zzYwqeC3DGvPzyS3TffffiuQAAQI7A6eHlC8FQWIiRmRzZqZElxcjc\r\nN+KpUespT3Kk5EjvHHFEanTMPU7HKWuV6OTIHKvTyVGBGqnL86ZG9U5qpPeNuCDx1MhMjvaq1EiP\r\n1Xn3jT42941KZWoUkRwVqp2jQvdIXUK+s3OkUyMtRytUcrRcjdRxQTLFiKPFaKGSIw6Xo7npYTFa\r\n90lGRs7FG8+XXvobPidAj2XSpPE0ZMiDeC7AGZGevle0cn78cQqeDwAA5AicHv5mPKRH6vS+kZYj\r\nc9+o050ctap9I3vnyCxjUKlRl/tGre7kSI/VHTnqTo28+0Z2clTn7BvpsTouRvsUeyqj7xuZI3Xm\r\nWF1SceTOkd++kZaj1XkeOcp1kiO9c7Q029k3WmyUMXhH6nh6NC+dxJ/HJ102PhuWLVtC/fvfic8J\r\n0GPZtGk9felLt+O5AGfEb37zK3rssRF4LgAAkCPQfTnyjtR55Ug31R3TYnTKSY5ON1JXbYzUVSox\r\nKvckR2YZgzc1imiqq4tMjtK7Gqmr6N6+UYpPS50uY9jo2TdKMPaNeBGDt4xhuaeljmPvG2X4yJEa\r\nq/PK0ZnW1J4NpaWF9JnPfEZ8lRWfF6Cnwhvrduz4GM8F6BYJCavouuuuo7y8bDwfAADIETgDOYpS\r\nxtDh01Sn5cgvNfKWMfgmR2YZg7lv1BxZxtBlcmS01Gk52q/a6rgYeZvqdlY4Y3W6qY5XeUet8O4i\r\nORJNdZ6xuogKb
4VOjVzJUaZ7rG6+wk+OzuTA4dnys5/9r2h0wucF6KkMHTpE7I/guQCng58n+Ld/\r\n+zK99dZsPB8AAMgR+GTJUcBbxqDlqNO5beQqY/DK0XEnPfKO1VWYqZFPGYNd4300ct/ILmOo86/w\r\nTjfEyLxx5JccbY9WxlDsKWModNd4ry/w3DjyljHkesoYsp2Rug+NIoZoZQxcjOb6yBGvrb1Qr4Wx\r\nY8fQsGEP4/MC9Fg+/HARff3rOOIJTs/Ikc/Svff+AM8FAAByBM4+OTJTI/v4q09T3dFoNd7e+0Zt\r\nUe4bNfvvGxV4bhxFHn9tp2lPD6P/+fFgGrm82q7x3rEzgX7ylUH07EfVrhpvv/tGZmrUnRpvOzXK\r\nd1KjaCN15r6RFiRdxhCRGh1UqdFBfzniXKjXwpo1K/HGE/Ro+Pjnddd9npKTE/F8gKjw8oXPfvaz\r\ntGfPDjwfAADIEThzOXKN1HkqvCP2jTqMG0eeA7CmGPntG1UoMfKWMfCdI54eHTH2jQ4b+0be+0a8\r\njGHVWyMoJiaGYu6ZSam8qa6mg14dxv45ZjDNy4+yb6TKGLaZZQylcqRO1HgXuZMju8Jb7xsVuPeN\r\nvE11ZhmDuXOk943M1MgsY3jvoG6ru7hyxOfy/+Vf/gWfF6BH8+STT9Cjj/4JzwXwpby8mL75zf+i\r\nCRPG4vkAAECOwFnIkWekrsMYqdNy1N7plDH4jdTVe0bqaozUyK+pjmOO1BV47xs1yl2jiOSIlzHk\r\np9G3uBwxJu0i2ncwQXz7++PTXfeNvCN10Zrqkr37Rj7HX7vbVLfMOABrVnh7m+oWGnIUbazuQsoR\r\n51//9V8pOzsDnxugx7J370668sorKDc3E88HiICfJOAHg7kk4fkAAECOwFnLkS5jMI+/6jIGnRo1\r\n+6RGDUqQdBFDjU8ZQ7lfGcNRdfxVocXIt4zBtXNk0YxH+wsh+u
ZLCfTqyEHs24NoTq77vpGrjMG4\r\nb8TTIy1FdhlDlH0jPVbHR+rWqtRIlzF0mRpluWu8RVOdz1idTo16ghz163cL2sBAj2fw4J+zN8Gj\r\n8VwAF9u2JYubRvg7DAAAOQJnLUd+Nd4nPfeNzArvCDk6HnnjSAtSV/eNvCN13uTILmPwHn9lbE+Z\r\nI0frFP/19zR3GUOl/1idmRrZI3U++0abPMnRWt1UF22kzmyq89k3Mpvq/Ebq3u0BcvTFL36R0tJS\r\n8bkBejQbN66j66+/nkpKjuD5AIKysiKxMzlp0gQ8HwAAyBE4hztHZmrU6d43cjXVnfTcODrhjNXV\r\neIoYKv2a6prdTXWFRyNvHOX43DfiqREfq5P3jarpsa9oORpEb2ZGNtVxMdrhkxqllnZRxuBtqjti\r\npEb57tTIW8bgbarTNd6ukTqfpjrOuwcuvhzxJeaMjAP43AA9nrvv/g698cYMPBdA8MwzT9HAgQPw\r\nXAAAIEfg7OUooowhyvFX+8bRSYm5cxSRGnkEKeL4qylIxs5R/mmOv2YYyRFn5QxZzPClJ1PsG0eu\r\n1KjC//irLmNI8StjKDLKGI44x1/XRts38ozV6aa6D42dow88qZHrvlEPSY54IcNll12GWX3QK1i+\r\nfCndcsvNosEOz0ffhjdtXn311ThiDQCAHIFzJEfe+0bGvlFXNd7ekTotSFqMXE11PjXeRUd9yhia\r\nnHE6V1Od5/jrQXHjqIFG/pinRv3pH+mWTI2qot83spOj0sjkKKLC2+e+kXffaJXPjSNbjPR9I6Op\r\nrqvkqCfIUXz8MvrGN76OzwvQa/jud++madPi8Fz0YfLzc8Su5Lx57+L5AABAjsC5kaNgyFPGYCRH\r\noozBSI1aopQx1BtlDLWeMoYKVeNdbrTUFRtypEfqzDKGw94yBq8c1RAtmz5MjtQ9mkC7DTFyyVGF\r\ns2/E2Vb
mjNXpcTrfkTq/G0cFkWN13vtGfKRumUqNdHKkj79GK2PQcnSxCxl4PfKzz8bi8wL0Glas\r\n+IhuuulG7B718XKO3/72ITwXAADIETh3chQKkzgE671xJMoYTjllDOa+kff4a0OUG0dcik53/FUf\r\ngM1XgmQmRzlRxCi9poOWLEmgV99NoKVZFu2rpi6TozRPapTq3Tcqjp4cmTeO7NTII0fxuU4ZQ0Ry\r\nlOW+cWSO1JlNdRdz5+jw4SzR8rR793Z8XoBeBd8zmTJlEp6LPsi0aa/Rv/3bl+nIkcN4PgAAkCNw\r\n7uQoHGxjMHsJtlDYOspglmI1UjhQz6hjMBsJ1FK4s5pRReFTFYwyRimjhEIdRRTuKGQcodDJfAqf\r\nzGMcZuRS6EQOhU9kM7IodDyDwscPscd0Ch3bz9jH2Euh9t2MXYydFGrbzh63U7g9jX17G4VatzJS\r\nGSmMJMYWCrVspmDzRsYGCjWvp+DRtYwE9u0E9riasYpCR1dSsCmesZyxjEJNSynY+CFjMQUbFlGw\r\n/n3GQsYCsurns8f3GPPIqnuXgnXvMOZQsPYtsmpns8dZjDfIqnmdgjUzyKqezpimmEpWVRzjVcYr\r\nZFVOZkxiTGSMJ6tiLONlxhiyyv/O+JsgUPYiYxRZZS9QoHQk4zmySp+9aHL02GMj6IEHfoPPCdDr\r\n2LRpPX3uc9eKnTk8H32HrVuTRYFMcnIing8AAOQInFs5omA7EyImR1YLo5nJkCNHxOWos0aJUSVD\r\ni5Gio4Q9FjNBknIU7ihggiTlKNCeQ22Nh6mpjlGbq8gxyGZkSWoyGRmKg4LG6nT2yKg+wL69nz1y\r\n9rFv72WPnD3UWLWbmhiNVbvY405BY+UOaqrczh7T2GOaeGys/JixTVKxVZHKSJGUJym2MBINNjM2\r\nUWPZRva4nlor4ulUFZOl6n/YYhSsZmJUOYV9m4lRlRaj
iRSoGMcexwk5CpS/ZMsRFyOr3BEjq+w5\r\n9vhXJkd/vShyNGvW6/T5z3+O9u3bjc8J0Cv55S9/QbGxT+O56CMUFeXTV7/6FXr11Sl4PgAAkCNw\r\nPuTIPzUinhx11orkSMsRcUE6VS5TIy5GHcU+qVEeNdfnU3FRIfs/saJLkAJqKktgIvQaE6TXfFKj\r\nCUyIeGo0zkmNXMkRk6OyUUySnmePTI5UahQoib3gcsSXmPne1sqVy/H5AHotfBz0+is+QyWTJ1DL\r\nCyOpiQl/ZUEunptLlKFDh9DPf/4zPBcAAMgROE9jdVYrI8pIXWcNEyImRqd0alSh5Kgs6kgdF6NL\r\nU4rcNJWtVmI0RWKO1HnkKGCkRnqcjouRHqnjyVGg5JkLKkfvvfcuXXvttZSUtAmfC6BXU7thLbVc\r\nfhkx07exrrtOfD+en0uLGTP+IY5V85Y6PB8AAMgROE/JkRynIyZGXI7CgYaIkTqyd43KXeN0YXuc\r\njsHkyDqW16MSo72Jy2h6XBxNnz2fUtPPrbQVFxXQqcoZMjUScqRTo3GKsUyKdHL0kpMalevU6Hl7\r\n18gqjWVcGDniuxkPPzxUtHwhMQK9HZ4QcREyxcgUJCRIlw58v4jvGSUlbcbzAQCAHIHzKEc6NVK7\r\nRmQ1eMbp1L6RlqOO/8/emcBVWad9n/f9PM8zTc2TLTPTvDOVU9PMUE02S4s1aUPZvtBMWdZgZVOW\r\nzVRkllFaCWqRZpGmuKIiSeKGiooIKiqCchQQZN9BZJHNBT0L1/tf7/t/3+c+iMp28KLP93NYDkg3\r\nnHPzu3+/63fxIgYaqXMprpHr5CFoaei8AMlMioZA/8G8jpvhC8OGjYJFyTldIl4y40L51x08DHzJ\r\n7cTYnTB3jD+MmRXfZQKpqXy5EqkLcStikLNGQ05cCwmHnxfCSHWOxrJZIxqps5e83a3iqKAgFz78\r\n8
APmFr300otw8GAGPgYQr4dG6KyEkYR+HI+T90Mv6lx//XXMOcLjgSAIiiOk250jKo7Ag2ukNdSd\r\nVmaNWAmDHqlrF5G6hiOdE0e2lRM1QTRxbjTEroyE0IljmIgJXGnrEuESO5EKr/GQpr0vE0J8fcB3\r\nfGyXiaP6sjXgNLhGk7g4qvzM0FLnc5r8vx7zgaFHr4GEyueEazRWFDEEskidvZucoy1bNsKLL46E\r\nyy+/nOX06dv4u4/0F+iMUUfiiH4cj5P389BDD8LIkf/EY4EgCIojpCdmjnRhpJUwMGFEK7zVeSPV\r\nNXKfNXKdyOmkOEqB8b5cGM2KN7lEeTmQk9c1wiU+ZBj4+IZATjfG9upLY7lrRFvqKoLd67srJoC9\r\nLIgJI58WQgOh1geGVF4NW8ue1YoYaKTOXvJWl4gjmsVfujQCXn/9Nbj22mtYfO7dd9/BHUYIOkeI\r\nV/LRRx/Crbfeylrq8HggCILiCOkRcUQjde12EamzH9H3Gp2qNJUwqOKoSHONeH1358RRTjyPuw2b\r\neAYHJzMeJo7QY3e+IyZCfKbuAs0iHxsVGgmLJvrrLlRkMvt4XOgI/fMII0LjtM8ZMSNO+zfy0mIh\r\ncJiM9Q2D8RPHwODBYyA+p7PiaK2y10iKI2MRg738I10Y1RGqCBWEIh8YWnQ1JBQ/zSJ15yKOMjLS\r\nYfXqGAgNncq2xNM/IH70ox/BnXfewQTR5s1x+HuO9O+Zo7xsnDnqx6xYsVysGkjB44EgCIojpKdm\r\njoQwYg11qnPEI3VafbfZNTqZb6jvpruNOiOOMuNCmBgJicvs4H7JEMgEywiIjEuG5PhFMIK5TYGQ\r\nnMfFUagUNUTMLFoZCeOH8Y+n0H8jJQ5CRvmSt0eRj62EuCQbj9UNJmJJE2XJMEb8G4vikyFp5SwY\r\nJkTSysyzFUe6a8RKGMplQx1vqZOOkSqMfAoIOY
QsHxiS+UvYmv8U+3mEh8+BWbNmwrffhsH06dNg\r\n9uxZMGVKCHzwwTgYOTIAHnjgfhg0aBAMGHAp449/vBWefXY4BAd/CmvWrITCwlz83UYuKGgrnVkg\r\nHf6//xeKyB/WeHy8F+p20xnJ6OgoPB4IgqA4QnpaHNUZ6ru1WSNDfXfHkTrXiWwijnLP7ByJooTQ\r\nDsSRFFATYzOVz5PvE0KHiqFhIdpMUXwodZAGa8LGPVbHxdFgIY48/xuDIfZsxJGM1LntNpqg1Xcz\r\nYVRNKFeEUTYXRj7pRBwd+CUk5HFx9PTTTzOeeeYZGD58OFx88cVw2WUD4Oc//zlcd92viTC6BYYO\r\nHULu83d4443RTDRR8fTddzPZHxG0yYk6Svj7jVxoDhKN0Mk9R6OeG84eH3hsvBNaIHPzzTfBxIkf\r\n4/FAEATFEdLTsTp18asijk5ZNdSprlG+VsRAXaPOiqPMWC5KxndQvJApREq0TX9fXvJcoziiQidE\r\nj8jFUTHkM0wTNnEhg5k4yuxQHPlCZEqeEvk7B3FUaZ410p0jO6vvDtIdo2KjMBqS+StIyP872Ev+\r\nA/bif7Ofx8KF82H+/Hkwb95cmDt3DmzfvhXi4+MgNnY1i5jQ/UTffvs1TJ06mWXx33zzDRape+KJ\r\nx1ic7oYbfgNXXHEF/Nd//Rdcc83VcMcdtzMhRWN2YWEzIC5uHfnD4xD+/iP9GpstjTmrOGvnnfz9\r\n70/BU0/547FAEATFEdIbzlG9pWtk3G2k1HeflLuN8g3CqP3EQSKODp1RUOSlzGVzQD7+oYpwMQuo\r\niSJ6l2MSLiZxpMwtnZs4oiJNd45WhvgbvkbnxFEI2LXdRnpDnbbXqGy8m2M05NCvYGvh06yIwVHy\r\nFhNG9pI3u7StjsbrkpO3QUxMNEyfHgpvvfVv1lbn6+sLF110EQwcOBAef/xRCAoaz/YdYRwP6W8
E\r\nBr7N/sjGY+FdTJr0Kdx0043MPcLjgSAIiiOk550jpb7bUMTAInVWJQzUOdLru2mkrl0TR7mdEhXR\r\n40XRgv9EiE1Og8xMG6QkxcKMwFEQSsVPTjyMoB8fNhHi0jIhMy1OzBSNEGUJnsXRyk6Ko6K8JBjF\r\nZowGw/jQUBijFDN0Xhytca/vLp8g5o14pI7uNZLCaEje1bC1aDjYS/leI7toqaPOkaPk3z2yBJZS\r\nXl4MiYlbmJP06quvsKjeJZdcAkOG3AMTJgTBrl078PGBeD10N87PfvZT2LRpAx4PLyEqaimbM0LH\r\nD0EQFEdI7zlHBtfosL70VRYxSHF0qljfa9SWz5a+MmF0Mps5R64TWdBQc6iTNdh5EDsjkDtIBoZp\r\nS2BzkqNFCYPAdxREagti3cURnznyh9gcRSwN7kAcUWxxMHGUPwz29QX/8bMgMnSUYW6pU+LIYukr\r\nd414pI6Ko6GF18DW4ueIGHoPHGVjxW4j3lDnYJG6NwljekwcWUErwOfPnwsBAS/AlVdeyYoeJk+e\r\nxP7AxMcK4q18/vkUGDr0HjwWXkBychJ77qFuNx4PBEFQHCG96ByZl76aZ43K2OJXlzJvpM8a6a6R\r\n60TmWYgjudcoE1JSUiAtLQ3SbDmWIiozM5OR1w17ivJyjP/W3FE+psWxnRRHpqWvdkUYOco+IKJo\r\nHFv66hCLX6lz5DC5Rr0tjlTKyopg2bIl8MQTj7O5jf/8503Iytrv3b/v5Odb/8rLUE/+fw4TKsjr\r\nFbg3pd9TUlLAdn2tXPkDHo8+TE5OJvzmN9fDF19MxeOBIAiKI6T3xRFzjmSkTq3vtnKN6F6jE4c0\r\nccRdo4NEIFFxlNNtC1e7HhtMZFXg/jAmMBD8hUs1Zm7yWSyBXQ12ZemrWt9N542kOHKUvc9dIyaO\r\ndNfIrrhGfUkcqdB4y/PPP8eu6NLZJW/9
Xa8f9RI00IpnQjmhiJBHBRI+D/R7pk//EgYPvhOPRR+F\r\nXoy57z4/ePHFkXg8EARBcYT0hVid7hoZSxjK3F0jpb5bLWJwHc+E9uMZcPSIN4mjIkiJi4TQkIkQ\r\nSMRR4PgQiI63ndXn15euYq6RXanvdnONysYJ50iIo5JAvYhBcY3sxW/0SXEk2bJlI/zhDzfDO++8\r\nxWaWvE4cDbgUaoQwKiRkEGzUQcLngX5PaWkhDBx4Lfzww/d4PPogY8a8DnfdNZi5fHg8EARBcYT0\r\ncivQJHCdrtGLGE7LIoZyTRjRhjqthKHNVMRwkouj9hNZRCBlQHP9Qa8SR+dLU+lSpb57grGlrnw8\r\nEUbvE4E0jvAei9Ops0a0oY7NG5Vw5+hE/pt9WhxRiovzmbtGm6S8rd2ORumkY0SF0T5CyqWXwurV\r\nq2HatGnssUCPP9K90OM8bVoorIheDAcPHuixnz+tv6dV9/i837eYOfMbtnKAlvLg8UAQBMURHoRe\r\nh/6R0lxfoDTUVRlb6tqMkTrVNWoXJQzUNaLzRq7jB8DecgCKiwovEHGUD23ln5sidaprJMXR+/q8\r\nUck7TBw5St82Repeh/xd70NwcHCfFkcSGoEZOzbQuxykV17WHCMqjHYTlt15JyQmJkJLSwu0t7cD\r\nvnT/Cz3O9Hjv2rULpk6ZTP4o7plZNupK/L//9//Yni987u8brF+/lu1kS0jYhMcDQRAExVHfYPny\r\nZZCYsA7AzmeNeKROr+92qfXdFq4RFUd01qj9RAa0E3HkOm6Do0eyLghx1FAaoyx+1Xcb0fpuh6GI\r\nQZ01ekcrYlBb6hzFb8Di+Z/D9OnTvEIc0T80f//738OcObO85/e9MBfyiUBKH3Apc4yW3303ZB84\r\ngGqlF19ycnKYm9RTDhKtqff3fxKf+/sAe/fugV/84hdsqTUeDwRBEBRHfQb6Rwn94yQ7c
6e22whO\r\nl5t2G/GGOpd5r5EijmikznV8PxFINkI6E0j910HKF8JInzWys4a6IOYamVvqZKROzhppRQzKrFHc\r\nCh43mj9/vleII0pExAK4+eabvPL3nkbpqHOBL73/sjU+FpYti+yxRjTavpiWthuf/3uR/Pwc9txB\r\nF1Dj8UAQBEFx1OegsZYpUybDtsQN0FR7CFwsSmc1b5Tv5hq5hGskhRF1jlzH0qH92F6wt+yF5roD\r\n0FCTAQ2HJeTtw/sJNqivTocGxj7BXkEaIRXqq/ZAA6G+KoWwm7xO2QX1lTuhgVBfmcxoqNxBbinb\r\nob5iGyFJkEjYyilPIGwRxAs2EzZxyjYS4ggbBOuhvnSdIJawlrxvNTSVLYNTFaGsvtt+JtdImTWS\r\n80aqa3Qi/y3I3z0eFoZ/zgTq/Pnz3IRRXxZHFF9fX6/cSTJ9+nQW7cKX3n9pbqqH0NAveuxn/9pr\r\n/2LV9Pjc3zvQKO5DDz0Iw4c/jccDQRAExVHfdpDo1dvQ0FAcGu9BQkJC2B/qVo4RJSoqsk//3rzx\r\nxmh49913vLKIBGeM+s4MEn0srFu3Fvbv39ftP/utW+Phqqt+zhrs8Lm/53nrrX/Dbbf9he2Vw+OB\r\nIAiC4sgroH+kWP2hjvQ89GfRl39XlixZBEOHDvG633FWYY8vfeZFbWncvj2x23/+f/rTHyEqaik+\r\n3/cwYWEz2ELejIx0PB4IgiAojrwHevUWhUnfoCeupJ8rlfk5kP1xEEy74nJomPkNexvFUXe8tMGm\r\nsCAYHRgGuW2e7uOAsiwbpNqyoNHRlV+358VRT/zef/LJBBgx4jl8vu9B1qxZCZdffjlz7vB4IAiC\r\noDjyOujVWxQnvUtPXEE/V2ri1oHjqqsAfHw06Ns1XlKT3H3iqBUi/H3YLigfnwCwtaofK4PgQeJj\r\nARHQehZfM9yPfp4/pHr8pEYI9e
FfO7m1K79u74ij7nZMd+3aAT/96U+9cpmxN7Jnz052vJcujcDj\r\ngSAIguLIux0k+kcKnXtBsdIz0GPdU7MX5+MYmYWRKpC8wUHqGXHkA4GxZfpHbOHa+338womcOduv\r\n6S/ElgM2BQeQtwdBVK5Dc46yEmMhKiYRqh3n+nX7jjjqiVm73/72Bti0aQM+13czeXnZ8Lvf/Q6C\r\ngz/F44EgCILiCEH6HzRCZyWMJPTjF7Q4CtDFkY9/uHCIHBAbNMggjtj724ogOMAf/PyDIEtE23Jj\r\ngsHPzw+CY4ssRUxuVKD+dQYNAv+gGHKPNtgUGggBo0NFRK4VYoICwC8gGBJTY2E0c6wGgd/oMMht\r\ntRJH/P7+/v4QllitB++KYiFgkJ/hfT0hjnqipfG5556FyZMn4WO6GykrK4J77x0KI0f+E48HgiAI\r\niiME6Z80fTCuQ3FEP37BO0eD/MFfCJJYqitaU8GPHJtBfoOM4qjVBv4+xmhbVrg/u49fmM1SHFUn\r\nR7Cvxe4zOhjCY2xEerVCuL/6deTbHP/Ro7XP8fGXkT6z6Botvrcw4Wq1Qczonond9YY4Cg2dCs8+\r\nOxwf093IqFEvwZAh97Cl0Xg8EARBUBwhCDpHF6o4CgiHTeFcbARE5ULZpiAmMmI2hZucIxsE+Bij\r\nbVnhAVzQeBBHVLTI6F64tJvc7qPH+8KSuevTlhUhxJIuoAyf05isCagoalpVx5q+j/4ljuh+rjvu\r\nuB0f093E5MnB8JvfXA/Z2Rl4PBAEQVAcIUj/pTIvG2eOziSO/KOgrnoTDPLh7hG7DdwEdblRZxRH\r\nuRFnEkeK8LE1nuE+AWCT+smRpf1bluKIRv8CubPlFxoLMcF+5HU/SG6EfimOduxIhIEDB+Jjugtm\r\nEOkFEeoYy9bKyMglrICBFl/gMUIQBEFxhCD9HmyrO4M4IuKnjfzH2+CkkGkFR26
Ex1idjRUp1EG4\r\nmFnqSByFd9o58tfEkaMoSmvRy2qzLmRozVJKI5hISu6VQoaeEEd0184VV1yBj+cufh5ou/JK+Nul\r\nl8Lq1TF4jBAEQVAcIciF5SDRK8XTyB+YdN8R7jkyiiOqN8piZXnCaChi0bZwU1tdGQRJIRIQCKMV\r\nMdVRrC5KCqigMNiUnMtmjjy5S4MCQiExdRMEya8dEAMOj2111XrduI8fJNZBvxVHqam74Be/+AU+\r\nls/DMfLkIB8bMMCrng8QBEFQHCEI0mXQNqrFixd61ffc/bE6GZurg6zUVMgqqhPOTITbnqOsqCBN\r\nEA0KDIeoUB6rC4jIMokjfW9SnU0vZfDxCSVCy3wfXRz5B/jpblBAGBS1gcevy2N9fFZqUFBir1V5\r\n94Q42rhxPdx88034GL6AZw8R5EKgpKQIVq9eBdOmTYNJkyax51uke5lE+HJKCPwQMRsOHjyA4ghB\r\nLjTGjg2E119/DcXRebw42lqhsfFsK+HayOcQWdTm6GCHkYjQka/f2tqZr18HYf6yZc/Rr8XRrFlh\r\n8MgjD+Nj+BzpD62VCNLvHd7KCvb8mrh1K7QcPQrtp08DSE6dIueGNs7JkwAnTnCOHwc4doycRsg5\r\no6VFp7kZyEkHgHwdaGgAqK/Xqa0FOHKEU1MDcPgwp7oaoKqKU1kJ5JsCKCvjlJZySkoAiosBioo4\r\nhYUABQWc/HyAvDxObi7AoUMAOTkA2dlAVAdAVhYnMxMgI4Nz4ADA/v0ANhtAejpn3z5OWhpAaipn\r\nzx6AlBTOrl0AO3dykpMBduzgbN8OsG0bJykJIDERgBxLRkICwJYtAPHxAJs3A2zaxNm4Edo3bICW\r\nNWtg1/z5MDUkmHx7+1EcIciFBG39+v3vf4/iqE+9tEKYH4/GnU0Nd5Yog/AJjAVHD363vSGOhg9/\r\nhjWq4WMYnSME6Z+OUTFM
nToVcqiIcDg4dvvZiyMqipqauDCS4kgVSHV1HCqQpEgyiyMpjCjl5bpA\r\nosJIYhZHVBhJcUSFERVFUhh1VhxJgUSF0d691uJo926OKpCkMJLiSAojKY6oMKJQYWQhjiAuDoAI\r\nJErO0qXsHNdZBwnFEYL0E2g8KSJiAYqjvuNFQVZiLBGuidB5A6gNbJvo58RCVp2jR7/bnhZHhw5l\r\nwYABl5Jz5R58/J7HzKG3t1YiSH9m9erVsIv+oe9yATid1uKIogojKookqmNExZEUSFIcSdfILIyk\r\nc0SFkVkcUWEkxZHZOaJQYSTpyDWS4ohiFkZm50gKI7M4kq6RFEZSHFHnSLpHUiCprpEURtQ1Up0j\r\nChVGEiGOYP162LpoFixbFoniCEEuJObMmcXcI29Z9kj/GG93NBHIE73jKLTbGwjkSd5RR26PQPvp\r\nGgJ5cj9dTW4rCRXQfopSRigllICrrRja24oIheA6mQ/tJ/MEh8B1IhvaTxwUZBIywHV8P7iO2Qjp\r\nhH3gak0jt6mEPeT13YQUaGe3O8HVkkzYQdgOruYkwVZwNm0BV1M8YTM4GzeBq3EjIY68vp7criPE\r\ngvPoWsJqwipwHV0JzoYYcDWsILc/gLM+mrCc8D0465YRIglLwVm7mNxSIsjrC8F5ZAFhPnl9HrkN\r\nJ8wBZ81scNTMIswE5+FvwXH4G4bz8NfgqP6KMJ28Pp3cTgNHVSjhC3ASHFVTCVPAURkCjopgwiTC\r\nZ2Cv+ITcTiRM6HFx9OGHH8Bjjz2Kj93zJHFaKFT/n//jta2VCNKfmT59OrRQQUOFkSqOpECSzpEn\r\n14hChZFEOkcU6hqp0TqzMPIUqVOdI6tYnSfXSHWOOorVUWFkdozUSJ1EjdTJWJ0qjjxF6lSBZCWO\r\nqHNEXSPpHBFhBOvWQfPqHyA09AsURwhyIVFeXgxPPPEY3HDDb7zHOXI2a
+IIHFQc1ZGTBhFHp8kT\r\nvJ2Lo/bTVYo4KtPFERVGp4qIKCogr1Pyyeu5ujA6mU1us4ggohBxdJyLo3YGFUd7oZ3gaiXiqHUP\r\neT2FCKFd5PVdBmHkZKIoURdGzVu4MGoiwqhpIxFFcUwcuRo3EDEkxdEaIorWEDG0ikDF0QoOEUau\r\nBl0YueqXcWFUt4QLo9pFDAcVRrVEGB2ZS4RQOHmbiyNHzXdEIFGIQCLiyFkTRm6/ZjgPz+DiSAgj\r\nZzUVR58TQURF0WQOFUaVXBg5mDD6BOzlE3pcHCUkbIbLL7+cnP+24WP3PKA7jH72s5/C9/Pnuu05\r\nwuODIL0PLV9ol66R2TmSrhEVR1IYqc6ROm9kdo4oHblGZueICiOJ6hzJWJ153sgskKQ4ks4RRbpG\r\nVBhJ14hCHSOreSPpHKmROjVWp84bWblGEnXeSMbqpDBSnSMqjqgwEuKoPTaWnefWrVtLvr19KI4Q\r\n5EKhtLSQuUe3334bea7L7/viyNFkdI3swjViwqhaUMUdo9PlujhqKyG3umvUrrlGXBy1n8whwog6\r\nRlnMNXIRYdR+/AC5tREUYXQsldzuYY4RE0WaMFJco5ZtmjhyNSUQthBhtJnccnHkauKukS6M1hqE\r\nkashhjlGLuYaCWFUH8XRXCMijmojBAsJC4ggoo7RPCaQnDVzyO1sIY5mcmF0OIxgdI10x4i7Rkwc\r\nUdeICqMqKpCkOPpUwF0je/lHPSaObLY0uOiii+Dbb7/Gx+x5kJ2dwS6ETJ48CY8HgvTl85w5Umd2\r\njc7kHJlnjuSskad5IytxZI7VmeeNrMoYVOeIQoXR2ZYxWM0bmWN15nkjszg6k3N0hnkjTSAJcSTP\r\nb9u3J6I4QpALBSqKHn/8UfjDH24mzxsb+3isjggjBxdGhkid5hoRcXRKdY1KNdfIpQgjlyKMZJzO\r\npQmjA5prRMURd4
1EpE64RjxSt9voGjVvMwgjLU7XHM+EkZNF6TYQQSSFke4asUhdg4zU6a4RFUcu\r\nKY6kMKpbAg4mirhrpMXpqChizpGM033HInXUNdIjddQ1mqFH6pQ4nUEYEewyTlf5mXCMiDCirlH5\r\nx2AvC+oRcUSdIlo2ERo6FR+r5zXkXQBDhtwDo0a9hMcDQfp8QsLZeXFEhZEqjmScTnWMPEXqPDlH\r\nHUXqVHFknjeiAkmdN1IjdaprZI7UMedoD2waNwpGvzAOcndblDGorpFVpM5KHHkSRh3NGynOkVkc\r\nUTw5SCiOEKTfZp1D4corr4QRI54jz0E7+6hzxON04KDiqJbF6agwArs5TldujNMxYSTEEY3UCXHk\r\nOpHDXCMWqaNxOnXWSBNGumtEZ41YnI4Ko5adFnE6QgufNXI1J7BIneYaiVkjFxNI64gg0uN0LiaO\r\nlFkj85yRFqczRuocwjWikToHE0f6rJEhTnc4TJs1onE6Z7XFnBGL003RZ408uEaOio+JQOp+52j2\r\n7FksSjdp0qf4+DxPAgJeAD+/vzGnGI8HgniZc6RWeVuJIyvXyOwceWqqY1XeRRDxsL7MnHMjBLw3\r\nE6qLFdeoM011ZypjsBJHTCDtgvDb6L97L6Tu2Oe5qU66RlZNdWcqYzhTU506c2ThHFFoxA7FEYJc\r\nYGRl7Ye33vo3awV78sknYNmyJeT5sKhPfG8DBxZD0tYmNmdEhREIZBEDF0dVSgmDiNMJcSRnjahr\r\n5LKI07EonVLCwIWRcI2UWSMWqROzRu2siEEtYTDOGqlxOtU1osLIJeN0oohBiiNnvVrCIOJ06qyR\r\n5hoZ43R01ojPGc3WHCMHc4yEOKrms0aqa+Ss/lJ3jYQwGnry17D1yChFGPESBrt0jcqDwF72YbeJ\r\no/Xr18A99/wVfH192dJXfFye7wzDpyw6m5eXjccDQbxFHMkab/P
MUUeuUWedI4MwohXehUIc3QjB\r\nX8yA8HGvwiAhkvw+3+LZOVIdI1UcSWHkad7IHKtjkbqdEPE3Lo5sVBzt3QObRj9M3r4Bon5IcZ83\r\nstpx1NlIXUexOsU1grVr3c5zUVGRKI4Q5EIlN/cgm0344x9vZW4SvfI8f/7cXv0Dy8fnNOEYDB3S\r\nDEkJ9VqcTneNpDByd42YMKJzRm36rJGLiiPqHJ3IViJ1nShh8NhOJ+aMpGukzBrpkboN5HYdEUV6\r\nnE66RnzWSJYwRFu4RmoJgz5rJIsYOFwcuZUwUGFUPUMrYXBYxemEY+RzmpygjvnA0MaBsLX6JSaQ\r\ntEidcI0c5V0rjoqK8lh7IhVFv/zlL9kuI3Q5zp+lSyNYAUNKyk48Hgjizc7RmeaN1BpvirnGW43U\r\nue03kuLoIcgq4011qe/dyMXRZ3GaOHKkr4ewVx4QzpIvjB4/FxoVcdS4bjYEPXmn5j4NumM05O4n\r\nwsi2CYIfvw/87nsVstJ5jXfu9DfB7/bbIfibdSJWtwsi7tXFUW7I87qLdcMN4P/SVGi1Ekdnu/zV\r\nqsZbukbSMeogVufpPIfiCEEuwIarCRM+YjMLl1xyCQwadAu8+uorEBY2gzz3bGGtdz0jjo4RWggN\r\nhFoikqohaUuVJozAJI5cimsk43QuU5zOJWaN1Dhd+3FZ3b1XkGqq71Yjddv5rJGI0zlpAQMTRvGW\r\ncTrP7XQxXBxR16hBuEZ1UW6zRkwU1UWA44jqGulxOtlO5xAlDA4Rp+PtdNw1YpG6qi/J619aiyMi\r\njHxaCA2EWiKSKq+FrRUBmmvkYM7R+PMWR3Rv0XffzYRnnvkHXHHFFfDXv97Nfqe8pVq+r7N1azyL\r\nJa5ZsxKPB4J4kzhSHSOK2lKnNtWpwsgqVqfG6TqcNyrSxFHy/gKo2xYNgXdzYRK0NIW7RtnrIUCI\r\nleCv50H4
qMFcPE1Yy8VRlvLxaRGQPG8aBL34HhdHaT+Av49YcJ7Km+qyJvjxz38/ytI5qp7/CfhJ\r\n9+qp0RA+dTE4OjNvpDbVSedI3XFkdo3UOJ3qHFEsnCMURwiCuFFYmAurVq2Ajz76kJU4DBw4kDWJ\r\n0QgUjeHRSN60aV/AihXLyfNVEnnOzO1CcSSFUR2hilBBKLlq18kAAFpDSURBVIJ7hxQTkVTm0TXi\r\ntd3qnJFwjOiskaGh7oAmjmQJg3SN2qk4kg11plkjYzudrO7me424a8Qb6likTps1kpE6fa+RMU7X\r\nkWukOkbzRUNdOCticFjOGn1t2VCnVXerO40qg3VhVEeoIlQQiohIKiIiqeQFFqlznKU4ysnJJOeZ\r\nVWyu7YUXRrCYFxXa993nxxzKvXtT8PHVhWRkpMPVV/+KiU08HgjihYUMVmUMcvmrp6Y6c0udxDxv\r\n5FEcGRn9re4a5Ya9wN//wCdQlHUI6jZ+x6N3g4OhlbpHWauFAPKBwM9mQ9GuA3qkzrZCCCc/sO3J\r\nZM5R1oTH2H39PYgj2LtTOEk+EL5su3ukzkocqe6RpwWwaoW3p6Y6GatD5whBkHOloOAQeW5Zx6qW\r\nx44NZE7A4MF3wrXXXgP//d//za5e/+Y318Mdd9zO9ir985/Pw5tvvsEE1tSpk9nnLVgwD3744Xv2\r\nB/TmzXHkuW0rpKXthvT0NPI8amM1xNIxUoWRj08BIYeQBUOHZMG2LYVus0ZWDXWaayR2GunCaL/R\r\nNWpVqrvZnJGI1LVyceQUrpFTi9QZXSO206jD6u4YgzDS6rstXCOHRXW3LGGQDXVOU3U3jdPpwmga\r\nb6dTZ40q1Ya6EO4cCcdIFUY+BYQcQhYRSVnXwNaCEeykMXv2dzBz5rfwzTdfw5dfhsJXX02Djz8O\r\nYj9f+rP+85//BL/4xS/gxz/+MXMchw9/ms3ArF+/ts9Xx
3srNKJ4221/YRcq8HggiBeLI4p5v5Ea\r\nq+vINepMjbe2AFbG6u6GqOhICLpRiiN93ij3mxfcxBPnHagW80a5YW8bP3bffyArJRsg/QddHKXy\r\neaPcSUIcffC9ZawO9m7XxFHY4i2eyxg6EkZWrpFECqMOyhjQOUIQpNug4oZGfKj4oQ1kU6aEwAcf\r\njIM33hjNXATqOA0bdj/cffddbMaJulDXXXcdmz356U9/CgMGDICf/OQnQhhVE8oVYZTNhJGPTzoR\r\nRxmQFJ9vWPiqttOpC1/VnUbtIlIn9xoZXCMtTmfea2Q1a5RgcIzYTiNt4et6Q6SOzxrpe41YQ11D\r\nZ1wjsfBVcYxYO90RWd89y7Tw1bjXyOlx1kjsNKqYxIVRNaFcEUbZXBj5pPvAkIxrICGfi6ORI0fC\r\nyy+/DK+++iqMGTMGnn767/Daa69CUNB4Ipq+YS4jFbk9Fb1EStjP4JFHHsZjjiD91Tk6034jitk1\r\nsipj0Cq8iTh6SMwclVaCY9tXmsAJj8syOke+70K13HFkXv5Kyxiy0yBr2TQtYucXFAOQtkK4SveB\r\n7QAVR9sg/DEf3Tli+412GsVRGrlPZ5wj2VSnCiOreSNzrM7KOTJF6lAcIQjS59Edo2KDMKKOUVJ8\r\ngbLTqHOuEdttpLhGanW361iahWukxumM4sjZpEfqnKY4nVNpqFNdI32nkVWcTrpGkZ4b6mpFQ13N\r\nHMNOI33W6GsPC1+5MHKyhjrVNeLV3ZpjVGwURtQxSih4HhxlH4C9dFyPLYFFOg8VpTfffBP5OyUH\r\njweC9AdxZG6pk6hNdbKMQXWN1GidpyIGudtIEUep+XzHUfJ7dwmB9Hew5fCZIxmb83t+PGxavhw2\r\nzfwCAke8D7kH+cxR8HOvQ0xENBTFR0PwHcJ9+poIkINbIEh+7mMBMPp23V3SYnXpybo42r6Xxeqi\r\nRN
TP/6V3YdOc5Xzm6HzKGMxNdVaukRKpQ3GEIIgXiCOjYzR0SC4kbSnhe41OW80aFRJRpLfTuVV3\r\nK46R0TXaK1rq0vTq7tbd0K65Rts7dI2cjbpr5Dy6Xlv2yiDiyNmgV3fLhjotTifFkYjTOWoXc9eo\r\nToojvbrbfaeRcdbISYsYqmdoJQw8UmddwsCgC18rPnNzjIYeuha2Fr3AGuoc5ePBXvY+EUjvozjq\r\nYyxcOI9FGPfu3YPHA0G8vZDhbJe/SudIiiRPZQxWzlF1gRBH/wCbEEdQkgSBMh73whxoKy2Ftj0/\r\nQNADvqZY3cuQlZXPxNFoU+TO/8UpUJbJ9xtlffGq3mIXMAGiAh9lrwd8toI7R5o4ekQ4R2lQt2Si\r\nVsrg4/NvaPRUxiCLGKxidWZxZF7+ap43kgKJOkc4c4QgSN8XR1wYDR2SD9sSytx2GmntdKekMDIW\r\nMchIXbtwjdQSBhdrqNtnjNO17jlDCYPiGhFx5FQjdY0bDdXdcq+R3GlEXSOXuYSBzhmpcbraJcI1\r\nUooYZKSulrfUOWqUhrrDMw1xOl7drbhGijBymoVRZTDYiTBi4kgIoyF5RBQVB4h2Ol7CYC/7gAkj\r\nRxk6R32JhIRNrPGPznLh8UCQfiyOZKTufMsYKJpzRKiuZhXeTBhVVHA87Ddqy7RBIxE0rdm5bjuO\r\n2tLToXXfPmjdn6UvgBX7jRz7UqExOUXfb8SWv+4X4iidoy5/ZQtgd0AjETWt23ZalzGcyTnqzH4j\r\ndI4QBPFWBg7cSURRpb7w9VQld41OWbtG+l4jXt3NhRHfaSTjdKpj1C6XvSqukbbXqMV9r5GhhEE0\r\n1GmukYjTuRhizqhB7jQS9d31K5S9Ru6ukT5rFAEOIozYrJHYaeRwK2GgkToep1NdI7rXSKvuppE6\r\n2VCnxekma3E6R+VnbOHr0EIiikp5dTffacSru6U
wspe+x0Bx1Degi5tpMx2d8cLjgSD9JFZnnjWy\r\nco6s5o2s9ht5co7YjiNFHFFhJKHCSIojVSDJeSM5c9TR8lcpjKyWv1JhJMURi9UpwkiKo9RU4/JX\r\nGauTs0Zy3qgzLXVnK47QOUIQxFtOGlQYwelqcqsKo1KPcTpewiAidWLhqxapEwtfXcdslgtf9RKG\r\nnWLeyKq6my97NS58VVyjo3zhq3SNXGp1txBGliUMMk6nzRktUuq75yl7jUwlDGLWSMbppGvkNMfp\r\nKo0lDEwcVXzKKZ8IdrrwVdtrxON0DsU1speORXHUB6A7oe66azCMGfM6Hg8E6S/iqL1dnzsyzxx5\r\nco08LX81O0dSFJldo7NwjgzCSBVHZoFExZHiHDFU14gVMVi4Rqo4oqjCyMo5snKNOnKOOlr+Kl0j\r\ndI4QBPEecVQlhFGVaa+ReeGrlWukV3fLha9qOx0rYTgmSxj0WSODa9TsHqfjrpHSUCd2Grm0nUZr\r\ntDidvvB1hVLfHW1yjSINDXVs4auI0zksFr6qJQxOpZ2OukYO1TVSq7uVvUZcGHHXyFExkTBBcY0+\r\ntHCNxoKj9F0UR32AF18cyXZFlZUV4fFAkP5ynnO2EJqJQGqCdsdRAhE3jnpot9cSjhCIoLHXkPNg\r\ntSleXsrOhS6Lxef6zG22tt/PdVxvaXVpyYk09/Nf605obzUtPWcXCPXzH78oqC87Z1Fyt3ZWcVGw\r\nQUlL1IvzXq2MkNOkhKl8SJ73tIuBM0VSQp7vxLnOonhIvxAYolwEFOc67Tz3EYuO03OdLByi5zrH\r\nWVwERHGEIEjvXVGjJwMZpzutu0YuDyUMLm3Za7ahoa5dnhTMrpFh1kieGBRhpLpG2pyRjNPps0ZO\r\nRRy5LBvqLEoYVNdI7DRyKAtfmTCSDXWsvtu6utvgGhFhxF2jUH3WSNlpxF2jz8DOThb8hEFdI7s4
\r\nabBZI+Ea2cvGaa4RiqPe54svprL9YXTBLh4PBOlPsbpWIoiIOHI0ERqJGNLFEVBxxKLlaoKiTIfO\r\n3p4qJudEscaiLV9bY2FvzYaW+kPQcIRQkyPIVjhIyOIcziRkCPYz6qtt5JZQnU5e30duKXvJ62nk\r\nlpIK9VV7oIFQX5VCbncz6it3QUPlTnKbTG6T2W195Q7Cdk7FNkESIZFTniDYQohX2EzYBPVlG8nt\r\nBmiuiIFTVUQsiV1+fMH5Fzw6Ti8CVunnOzZXK+LjMh3hdp4rpec5ehHw3bM6z6E4QhCkl2aOiiFp\r\nS60Sp1Nco1Oqa1TgsaFO7jQyu0ZWcbr2DosYRKROcY2c2k4jXsJgXvgq43QuQ5xOXj0zLnzlsboI\r\n09WzTsTpWH23aaeRx4Y61TX6lJwsVNcoiFOmnjDGsStp9IRhL3kHxVEvEhMTDVdeeSUkJyfh8UCQ\r\nfieOrF0joM7R6RrmHElxBFQgyXi5tsbC7BrlQmNtHhQXFUJRUVE/JB8aymJ5SkI935nj44aExERD\r\nQoIXDr0vznPcNbKXBKI4QhCkr7fVnSYcg6FDjkJSfKV1CYNyQtDidCeztQgBb6fLsNhrtFfZa7Tb\r\nsoTBqVR3O8WcEXONRJxOb6eTrtFaFilg4kiJ1FnuNTIII+EayTidmDOijpEsYbCK1LntNRJxOqdW\r\nwqDHC+wVxhIGfqJQ54yUmEG5MVJnR3HUq+zZs5MtR46KWorHA0H6Y6zO0UzwEKmTc7daIZExXm4V\r\nqaPCqH+KIiMNZWuEMJpqmq0NcRNHajpCxul4MmKcONed3XkOxRGCIL0kjo4RWggNhFoikiqISBKu\r\n0akiXt2tNNS57TVS4nTtLGNtvdOo3WrOyMNeI6cya8TFEW+os47TedpppETqlFkjT64RjdOx6u6a\r\nmR53GunV3aGKY6TGDPiVNLssYTDFDOSVN
NU1knE6R2kgAcVRb1BQkAs33XQjBAd/iscDQfqtc8Tj\r\ndECEERVH7fY6t0gdmOdu22SCQsbpeILCcSy3HztGRoqL8uFU5ddK8ZA8132mJCTU2dqP3Pb3yVmj\r\nsz3PoThCEKSXxJEURnWEKkIF2300dEghEUkFhoY6OWukxul4dTdvp5OzRu3H9SIGt71GrcY4nVbd\r\nzZrp4pWlr2Lhq6mEQV346mrQZ41U18ilxulqlRIGC2Gku0az2E4jpxhMdRiqu82zRl+YThQhSkPd\r\nZ1o7HT1R2K0GU8UJQ4ojeTXNXvI2iqNe4IknHodnnvkHHgsE6acUFxJxY2/hrpGYNQJHnSlOJ+aN\r\npDhqK9VKiVyKa+Q6eQhaGs7VNcqEuYH+4B84F3LcPpYGoSOGwfhFm2HuGH8YMyu+zwikpvLlSlIi\r\nxK2IQW9i1WeNjM6RjI4HntV5DsURgiC9JI64Y6QKI7oU1scnh5BFRFIGJG3OtnCNDmqROq2ZR2mo\r\na/fQzqOWMOg7jaRrZGyok5E6rYSh0aqE4QcL18i800i6RqK6+4gpUndE7jWaaWioMy989SyMrBrq\r\nPtEidfpw6oduJQx24RrRE4a95C0URz3MxIkfw80338TcIzweCNI/OX38OByrr4fjDUfAcfyIpWuk\r\nNdSdVmaNWAmD+9xtw5Fzj9TFhfqTc6svRKYZ358TH0re7wMzkvZCiK8P+I6P7TPiqL5sjVI8pKyq\r\nMETI9R1++qzR+6bz3DvkdXSOEATpQTIzbbBx43qIiFgAX375OXzwwTh49dVXYPjwp+Ghhx6Eu+++\r\nCwYNugVuuOE3bMElnbHgwqiaUK4Io2wmjHx80ok42g+Jmw6KnUbZepzuhHU7nV5byl2jdiqOWsRe\r\noxZRW2qK07FZo2Z1p1Gc0k63XhQw8J1G2rLXBmMRA6swrYtyL2Eg4shxhjidWwlD9deiiG
GGqO6e\r\n5l5lqmavxayRjNOxEgazMBLV3Xprz1hDEQONGqA46lmio6PYY4DOG+HxQJD+CxVGLTU10FBSArX5\r\n+VBfcAjaGsuFMKIV3tXGBeiaa2Q9d3s+4qgoLRJ8iQjyn2F0hqIDfcHHdzyk9cFoXX1pLD/fVenn\r\nO0N9N01JlAUZVlVoFwKVIoazPc+hOEIQpFPQBZXx8XHw1VfT4M0332Ci53e/+y1cdNFFMGDApXDj\r\njb5sR8vw4c+wJZaffDIBpk8PhblzZ8P330dCXNw62Lo1Hnbt2gHp6WmKY1RsEEbSMeJxukPWs0Yn\r\n1H0OSkOdttdICKMzVHe7lDidca+RsttBnTUScTqX2O2gttO5OpgzMrhGTByFGyJ1anU3LWFwqiUM\r\n1V/qJQzyClqV2tjzqZa/Vvca0SKGjqq7VdfIXvIfFEc9xN69KfDzn/8MVqxYjscDQfo5UhjVFRRA\r\nVUYGVKSnQ9HOnVBlS4PjR/K5MDKUMKjiqEhzjXh993mKo6IcmOHvYxRCefEwQhNMmTBrxGAYMSNO\r\n/xxbHAQO82HOEnWdQqJTyOckw/hhvjBmVpL2deeOGQa+/iHa17XFhoDv4EBIzjtfcbTWGCGvdC9i\r\nsEvXqFxvqGPnuTJ+IdB+DgkJFEcIgliSlXUA5s8PZw7QrbfeCj/60Y+Y8/OPfzwF48aNhdmzZ0FC\r\nwmbIzT14jrE6o2M0dEgOJG7OZSUMhkV3J9yFkUvMGnmu7uYNdby+2+waJRlcI726W99pRIWRS8Tp\r\njK6RFEamhjqTa+RgDXV6nE66RnKnEavuPsxdI6da3a3uNNLqu01VpqK6W2uoq9BnjbT8NbuSpsTp\r\nTCUMPH+tu0YOFEc9QlFRHnssffTRh3g8EOQCQDpGqjAq2LYNcjZuhKzYWMjfuglaq7KtXSPDuZCf\r\nD89PHBVBWmQgEzqh8TlcxKwcr0T
tMiFksA/4TpSxumQYQ0URET3xaSkQGTJC3DeHiCjy/sEhkEnv\r\nl7kShgnxNDcljz3PzaUfHzEX8oq6ShzprhErYSiXDXUfu7tGym6jcz3PoThCEESDujo0EnfbbX+B\r\n//3f/4V77x3K3l69Ogby83O6eOaIC6OhQ3IhKT5fRAiM7XR8+zeN1GXxWSMtUrffFKlLc1/42mq1\r\n08h64SsrYWjaqO01orNGLq2Iwb2hTgojl6dZI7nTSKvunqtvBT8yR9kMPss4a3SYzxo5DZvB1YWv\r\npj0P2sJX6RhNsD5ZmFwjeSXNQa+mFf+H8G8URz3AyJH/ZI4rHgsE8ZaLhPshMXELc3rpBcEpU0LY\r\nOfH111+D559/Dh5//FH429/uhTvuuB3+8Iebteg4dYcHDBjAhFF1ZiaUK8IomwqjdesgPToacrds\r\ngOayDH23UQeROno+bDiSe35RtZw48CdCxjcwmr3NRMywGaKkgYujwUIcZcaFMCE1ZlYspCSnQHLc\r\nLBbLG7/SBimRY5gYis4kAksILsqoWSnkc+OYWKL3K+oKcSQjdW67jSYYlr5qs0ZlXBzJC4FSHNlR\r\nHCEI0lmo6KFzQn/8461w+eWXw6hRL0Fk5BJ29ac7/92BA3cSUVRkWPhqbKizjtO5tIY6WcJg3mmk\r\nLHttNblGLYprpMTp2MLXpjjNNXKahJHBNTI4RqprFMkb6mqtq7sdbgtfZxoWvnreaSRdI2Xha4X1\r\nwlcZLzA01JXy7LVdmTNS43SM4jdRHHUz33zzFVx33XXn7LQiCNIdMdc9bAkzjYC//fZ/WDLizjvv\r\nIOena+F//ud/4LLLLoPrr7+OiZ9HHnmYXeCgsfKgoPHw+edTYM6cWbB48UImnjZsiIVt27ayi4z0\r\n69JZ3CoijKhjVEyFUVKSJoyoY9RSmW3RUKe6RvmGBehdIo7kjJHPKIhPi2UiZkxk
itZoZyWOjPhC\r\naFwmFNmiYTB5OzA6iQmsYaErIZJ+3RFzIYm5Uf4Qn1fUNeKo0jxrpDtH+jnPyjUSRQzyXHcWFwFR\r\nHCHIBRybCwx8G6644goYNux+WLZsCZSWFvbYv8+W46mNPOadRrS+W3ONpDA6wMRROyOdCCIijlrd\r\nXSM9TmecNXI2JfBZo2YpjoQwUqq7ObGijEEXRy7qGtXzOJ1LukYWJQxOLVLHXSOH4hjxZa+ztYWv\r\nzppv2ZyRQ3GN9DidqYRBCqNKdeGrLowMO41Ea496spCDqXax78FR+rYmjFAcdS80fkr/yKIzd3g8\r\nEKR3SoPoouUJEz5i9fmDBg2CSy65BK688komfJ5++u/sfPj111+xwpQdOxKhoODQef+7BscoLo6I\r\npCRorT7EGuqMu42U+u6TcreROUVxkIijQ+ctOHLiZzCh4+vrw0RMbE6RtTiKncjuNzE207IaPJTO\r\nIvkOZveZlUzuH80dpMG08W5MZBcVMqwVMfLPjK6RaYefub7bruzwc1BxRISRveRNFEcIgnguVqBL\r\nJ6lLRMsTUlJ6pzGLiSNt6LTQNHjKTwZadbe218hYwiDjdO0UdacRFUbN25U4nbLwtSlB32lESxga\r\nzSUMazkNq41xOiqMGjzMGdVHcnFEhJFsqHOwAgZCrcVeo5qZQhgpJQysnU4vYZDCyBinU4sYzPEC\r\npYRB1Jl2VN0tr6RRYeQoHoPiqJvIy8tmV55nzJiOxwNBeoDi4nxYs2YlfPxxEDz22KMs5nbppf/L\r\nHKGXX36RJSXox+kFwm6fMxTCqHTPTjh+pADAXsPru7WGOqsSBnqxUK/vdokLhVwc5XaB6EiD8b7c\r\nCfIds8ggeFRxRIsX2MyRzwhYFJfCBGZS3EqIS+PzSkmzRgg3KRBSWHnDSuYm0feFxGV2kTha417f\r\nXT5BzBuZ9/iN09pYtRIGJ
VLnKEHnCEEQC+iV61tu+QPcdddgSE5O6tXvRRdHPE5nKGE4aeUa6Y4R\r\nF0d7tYY67hrttt5rpMTppGvkZMte9Z1GWgmD4hi5uUbqXiNa3U1njWRDXa0sYYhQGurMrpHuGPE5\r\nIxmp+0YrYnAa9hqFWrhGIRbxggliAV6QwTHiex6EayRiBvJKGjtZFPOThZ0II3vxGyiOugl//yfh\r\nueeexWOBIN1EWVkRrF27ihUFDR58J2tQpTvE/vWvURAWNgO2b9/aa9/bzjVr4EQtOc9pe40O60tf\r\n2eJXxTViEXPdNXKxi4R0AXq2uFiYBQ01h7pEdCTNGsVFTKzNszhya6szCp+8lEVsBmmYdn/hJvmM\r\ngeQuq/JeY7n01SGWnKuROn7Oe0+01OkXAh1aQmIMiiMEQYzMmzeHRehCQ6f2ie9n0qRJ5Mm/QFlw\r\nJ6+Suc8aaa7RMb7wtf246hqZFr5axunEwlc2a6RH6vTq7vXawldDCUNDJ1yjOjlnFOFx1kh1jZzM\r\nNZqplTAYZo0sdxqpNabB7gvwKox7jYzZa2vXyGFyjU7kY6yuO/jii6lw0003dvv8HoJcaBw8mMGE\r\nzxNPPMZcIbpK4rXXXmXzsocOZfWZ75NdBHRb+lppmjUqY4tfDRFz7WKh7hrRBEVXiaOzjuJlZkIm\r\nIS+vp/ccrbFc+mo1a6S7Ru9q8XHVNUJxhCCIgQUL5rEqbrprqK98T9OmhUJTbYY2a+QyuEYHLV0j\r\n6Rjp7XTKrJFY+NouXaMWIY5U14i20yk7jfSFr3qcjgmjo6uUZa8xoozB5Bp1sPCV7zSSrlG4Nmfk\r\nECUMDoNjpM8a6a6RLo6c6qxRhVz4Knc8uC98dZQrV9C0djqLSJ3iGuXv/gBCQkJQHHWxS0vnjOiA\r\nNh4PBDl/srMzWCRu6NAhcPHFF8PDDz/E3rbZ0vrs9yzFEXOOZKSOzRt14B
rReDm7SJgrLhTKiDkV\r\nRzl9blFr94qj1aZznnV9t3rOs7vFx98U5zoURwiCCKhTRK3wnTu396nva/nypZAYH2OI07GhU801\r\nOqi5Rlwc8Vkj7hqZG+qMJQxOs2skHCMujOK1vUayoU4vYbCo7q5XdhpRYURdI3XhqxanWwSOIzJO\r\nx10jOWskI3V04Stzjiwa6rQSBtpQV2nlGslowafaXiO9oc6qsUe4RhY7jaQwcuSOhhMv/QEOX/xj\r\nKPvxjyHlwQcgcuECFEfnSUFBLvz2tzfA9Olf4vFAkPOMzEVELIBHH32EFSjQ6mxaqd3VqyW6Uxyp\r\nrpGxhKHM3TVS6rvVIgbW1no8A44eudDE0Sq3lRVurhE7143TxVGJUsRQcm7xcRRHCNKPoTlsGqVL\r\nSkrog7GIA+yJKvtAgptrpFV3s51GvIRBLnyVwsilxunUIga518hcwmBY+Bondhp1FKdbIRANdQ0e\r\nInV1xupu7hrpC1+dR4w7jczCyKmVMEwzFDHwEoYppgV41g11xqHU9w07jaRjpEYM2JW0kjeZMGog\r\nwvkwoZxQRNhKBBKKo/Pjn/98ns0a4bFAkHPjwIF98O6778BVV13F1kzQi3zUOfK2/w8WHz9doxcx\r\nnJZFDOWaMKINdVoJQ5upiOFktnJOzIDm+oMXlDhqKl1qmK81trKO18536lyt5hoV/1tcDOTO0dnE\r\nx1EcIUi/vXp9CAYOHAjz58/tw/Wq+2HKlMmwbetqaKrZxxwjGadT9xpx12gfw1jC4GHWSBFGTsU1\r\ncso5I1bdLYoYzJG6BjVSt8LoGtUtA5dWwrBYcYzcSxjYnNERo2vExFGNsYRB32v0pdhrpLpGk7Wd\r\nRnaLEgZ+otAb6vSFr6a9Rqbs9Yn8tyB/93jmGNUIYVRIyCCkXnwxiqPzjLDSHSm0pQ6PB4KcHfRC\r\nHl2uSueI6E6hLVs
2evX/D42PN9cXKA11VcaWujZjpM5QTCRKGFiCQjS22lsOQHFR4QUijvKhrfxz\r\nU6ROdY2Uxa9y3kjs8TOuqqCu0euQv+t9CA4ORnGEIBcyY8cGwlNP+XvBYO0BWLYsEkJDQ9lVHaRn\r\noDNGNEonHSMqjPYRkoU4ioqKxMfRWUJnH6hTSx1bPB4I0nnWr18Dfn5/Y3uH6LkrIyO9X/x/LV++\r\nDBIT1gHY+awRj9Tp9d0ui3UWqmukzt7KFMXRI1kXhDhqKI1Rmlknus/XakUM6qyRKUIuxJGj+A1Y\r\nPP9zmD59GoojBLmQB1fpMHhq6i6v+r7XrVvr9sSFdB90xqhQEUa7CetFrI7+LPCxdHbQQfF33nkL\r\njwWCdJKEhE3w4IPDWHyOlisUFub2s1Y9ER/P3KntNoLT5abdRryhzmXea6SIIxqpkykKGjGnAqn/\r\nOkj5Qhjps0Z2scfPIbCblpyzhroSY0OdWjoUt+IzFnGcP38+iiMEuVAJCfkMnnjica/7vvfv34ei\r\npQeJXDAfEokY2nPxxcwxosJoqShkoD8LfCx1nsmTg9lsBB0gx+OBIB1Dl48/+eQTzCn65JMJ/U4U\r\nWcbHEzdAU+0hcLEondW8Ub6ba+Q6YYqXy2KiY3vB3rIXmusOQENNBjQclpC3D+8n2KC+Oh0aGPsE\r\newVphFSor9oDDYT6qhTCbvI6ZRfUV+6EBkJ9ZTKjoXIHuaVsh/qKbYQkQSJhK6c8gbBFEC/YTNjE\r\nKdtIiCNsEKyH+tJ1gljCWvK+1dBUtgxOVYSaouQeXCNl1si8x4+6RjI+vjD8cyZQ58+fZ3keRHGE\r\nIBcId9xxO2v48cbvffv2RBQuvQz9GeDjqPPs2rUDBgwY0KvLJhHEW5ocaWyOPl7ef/+9C2Y2D+Pj\r\nvRcfnz59uqVj1FF8HMURgvQzcnIy4Sc/+QmUlBR47f8DdS1orIs+
caFY6RnosabHHB2js6O8vJhd\r\njJgw4SM8HgjSAQsXzoNrrrma1XJ7W+Qb4+P9E0/xcRRHCNLPWLo0gs0+4LFAkO4nOPhTuO22vzCR\r\nhMcDQaxiZTZ44onH4Prrr4Pvv8eiF4yP9x08XQxEcYQg/YxJkz6FkSMD8FggSDdDr37T4pMdOzCG\r\niCBWzJs3h80VjR79KhQV5eExwfi4V8THURwhSD9j1KiXYOLEj/FYIEg3c//998G4cWPxWCCIiUOH\r\nstgi5Ouuuw5iY1fjMcH4uFfFx1EcIUg/Y9iw+1m2G48FgnQfs2fPgt/97rdQXJyPxwNBFOjOomuv\r\nvQYCAl5AtwjxSlAcIUg/Y+jQeyAycjEeCwTpJnJzD7K9LHhFHEGMfPxxEFuEPHfubDweCIojBEH6\r\nBrQ5a8WK5XgsEKSbGDPmdXj66b/jsUAQJUb34IMPwJ///KcLuokOQXGEIEgfhJ6c8Io2gnQPtHyB\r\n7mix2dLOfP+iPKh/5WWoH3ApHCZUkNcrMGaE9DMSEjbDr3/9axg58p9evUICQVAcIUg/5Z57/grL\r\nli3BY4Eg3VTC8MknEzp13/pRL0GDjw8cJpQTigh5VCDhcUT6CQsWzIPLL78cZsyYjscDQXGEIEjf\r\nhEYbaH0qHgsE6VpWrvwBfvWrX3Z6yJw6RjVCGBUSMgg26iDhsUS8iMq8bGiY+Q00fTCO3Vbm57D3\r\njx//Ppu927hxPR4nBMURgiB9FzoL8c03X+GxQJBuiKyezWOLRumkY0SF0T5CyqWXwurVq2HatGkw\r\nadIk+Oyzz5Buhh7nL7/8An5YvhgOHjyAv8tnQU3cOnAQAQTkd1fiuOrn8J7f32DQoFtg7949eJwQ\r\nFEcIgvRtXn/9Nfjwww/wWCBIF0Lr8W+66caz+7xXXtYcIyqMdhOW3XknJCYmQktLC7S3twO+dP8L\r\nPc70eO/at
QumTpkMmZn78Xe6M45Rfo6bMJI0XPQjKMy04XFCUBwhCNL3T2Y/PPUkrLrtL4b4A4Ig\r\n58ett94K4eHfnd3nFeZCPhFI6QMuZY7R8rvvhuwDB1Ct9OJLTk4Oc5PQQToz9BxiJYw0gUQ+jscJ\r\nQXGEIIiXxR+uYu/H44Mg587330fC9ddfB+Xlxef8NWiUjjoX+NL7L1vjY2HZskj83T4DdMaoI3FE\r\nP47HCUFxhCCI18Uf6PvRQUKQc+evf70bvv326/P6GtOnT2fRLnzp/ZfmpnoIDf0Cf7fROUIQFEcI\r\ngicxBEHOhu3bt8KVV17Z6YY6T9BSAJwx6jszSDRat27dWti/fx/+nnugMCOdzRbhRTcExRGCIBh/\r\nQBCE8a9/jYJ//3vMeX8d+sc4vvSdF/rzWLJkMWP79kT8XTdBW+hoG93Yv93L2ukwro2gOEIQBJ0j\r\nBLnAKS7Oh8suu4z8oZhyQYmjssRwGD16NIRtKjqv+5hf2lobobqsDIrKqqHV0XfEEQUdJB26t4ju\r\nL6J7jFhs28OeIwRBcYQgSN+dOSInL5w5QpCuZcmSRfCXv/y5S75Wb4qjophA8lTgQwiA1NYz398W\r\n5s/u7xdmO6/7KLIIYkb7iO9BMgiCY7LA0UfEEY3Y4e98CcyYMR0uv/xyWLBgHh4PBMUR0vcpKSmC\r\nVbg8sIeZBFM+D4WIpRF9vvoV2+oQpGsZPvxp+PTTiV4ujsogSBElo6Nyz/gZuREB7L7+HQifztxH\r\nf2mFmOAgCI9NhKzcLEiMCoZB4vuJrXb0CXEUFRV5gf99UQAjR/4Tfv3rX0NCwmZ8/CMojhAvoLKC\r\nPZknbE2EhqYWOOVoJwC0EU7aAU4Ijp0mp6FTnBZCcxtAE6HxJMBRQgOh/gRA7XGAI8cAagiHWwGq\r\nBVUtABWC8mZyWm0CKCWUNAIUC4qOAhQ0AOTVcw7VcXII2b
UABwlZhMwjABk1AAcI+w8D2ATphL3V\r\nAGlVAKmVACkVnN2EXeUAOwnJhB1lANsppQBJlBKARMJWQkIxwJYigHjC5kKAjQUEcruB3K7P58Tm\r\nAaylkL8F1hBWHwJYRVhJiMkBWJEN8AMh+iDAcsL3hKgsgMhMztIMgMUH2mHBnhb4ZsUuCJnc95cH\r\nyvjD6ttvY/uO0DFCkHOHFjF0RaSuN8VRY2oYEyGD/AYJgRRE5JLJ16lOhiB/P34//0AY7efjJnw6\r\nc5/Ov1RDoBBHoamNfUIcUS7U3/PU1F3w5z//CR588AE4dCgLH/sIiiM8CN5wRacYpk6dCgcP5oDD\r\nBXDayaHiiHLSwYXRcUHraQ4VR0wYtQlhdIILo7rjQhwJqEDSxBGh0kocNXFRVCiEERNHgtx6LoyY\r\nOKrj4uigSRxRmDAiomhvlSKOCHsqFXFUwcURE0hCGG0TGIRRsRBGhE1CHMUJpDhal68LI4M4yuHi\r\n6AdFHH2fxTGII8JiJpAAIgizNnjP8sCgoPEwevSr+PhBkHMkKSkBrr76V1329XpHHLVCVIAQRG1F\r\n1oKkLQsCxPv9AsMgJjxIc5k04dOZ+5yDYPPx8YPkOkBx1IvMnTsbrrjiCvj44yB83CMIiiPvgS4P\r\n3LlzFzjbgYkju0sXR9I5ohw/zZ0jSnMHrlGd4hwdEc7RYUUYMXHUzMWR2TUqFAIp3+wcCYEkhVHW\r\nES6OKPsV54iKo32KMNLEUaXJOSrjzhFlm+oaFZtcIymOCrkw2pDPWZfHiVWdo1xdGGmuUTZ3jZYL\r\n12hZJmepcI6WKOJoESE8eq1XLA/85puv4B//eAofPwhyjkydOhmee+5ZrxZHjrJYJkICInINUTif\r\ngChoE/epSw7l7/MLBalTssL9DcKnM/fptDDKitIidRG2XlJGKI6gsDAXAgJegGuvvQbWr1+Dj3kE\r\nQXH
kXdDlgY1NLeB0gcE5oqixOivXSIqjBgvnqFa4RoeVaJ3qGpUqrhGL0ymROooUSLn1xlidW6Su\r\nRo/TsUhdFUfG6qQ4ShHO0S4RqzO7RtI52mLlHBXqsTrKunyjMFpljtQJVHEkY3XLhHu0RIgjJoz2\r\nAyykpNR5xfLA+fPD4cEHh+HjB0HOkVdffaVLr6b3hjhKDvXTyg/8/Pw0UULfji1zGIoVfHyCFeFj\r\nnCfqzH0685IbG8y/zqBASK5u61NtdReSOIqNXQ3XX38d+Ps/iTE6BEFx5J3Q8gWnq50JI9U50lwj\r\nBxdG6rwRdY2aT5mcIyGO5MwRhblGx4xxOkpZM0c6R2qsTjpH+SJSl2t2jWp110jOG1GBRF0j1TlK\r\nE66RjNWZ5412qPNGpdw1cnOOCsXMUaExUhebp88cSddIiqOVwjlaISJ1VCCpwogihdFiIY4oVBzN\r\nt3nH8sBly5bAPff8FR8/CHKOPPDA/TBv3hzvFUdtNh6F8w+E8PBwCAsLY7eB/nz2yC80mQuWqNHC\r\nFQoDXmTngE1Bfgbh05n7nLEBL0J8jYBwaITef7kQxRFdZPzaa6+yWbqu/N1GEBRHSI9Dn8RdMlIn\r\n542kOFLnjU4bnaNmMW+kzRypZQzCNepw3qjZ6BzJWF3BUaNrZJ430pyjI/q8kYzVUWG0V5Ba6Xne\r\nSI3UqbG6hGL3mSOreSMpjtbkmsRRju4cyZmj5Qf1eaNlShmDOVJH3aMFNu9YHkivDNIBW3z8IMi5\r\nceutt3Zp3KinxZGs7w7PMjo0bVnhWq23rY1G72K0+SG/wGAIHj3IbZ6oM/fpePTJBn6aa+UPgYGj\r\n2Y6kAP/REJPbiuKoB4iKWsrcoieeeBwyM234GEcQFEfeL47MkTqzOJJNdcekMDqlO0dnitRVK5G6\r\nSiGMyk3OkVrGYHaN3Jrqjrg7RzYPkbrteY2wbk8Z
rNhTzQRPR/NGiRYtdbKMYaNp3ihWmTeiRQzm\r\nMoYVppY6ijZvlGEhjkSsziyO+urywJiYaLjjjtvx8YMg58igQbd4sThqhHA/44yQ/lIHoaJpLmgT\r\n763LitELFnz8giAsSMwThevCpzP3OaOLZUGYDcVRdzfRPfLIw3DNNVfDwoW4uwhBUBz1J3HkoYyh\r\nzaKpToojK9fIXMZg6RypZQzqvFGjexlDh86R0lInxdE+0VaXWtkGUwPclwL+a04WbFOa6miVt8cK\r\n7w6cI9ZUZ4rVuVV4C6RrZHCOMo2xukUCK3HUF5cHRkYugSFD7sHHD4KcI7fc8geI68IdYb25BLZT\r\n5Q1trdDa2Aht53QfB7S1ko9Z0Nbm6JP/v/1dHOXlZcP7778HAwZcCu+99y4rYMDHNYKgOOqXzpHd\r\nXMYgxdFpfbeRoYzBLI6O6+6ROVZXobpGFmUMWo33Ufd5I62M4Yh1hbdNEUa8xrsVpr4XBOMXJUJk\r\nUhZ8+20w/EaIpC/2OqzLGIpNZQyFxhrvDfmmHUfmMoYcUxnDQT1S971SxOCpjIEKo/k271geSK8Q\r\nDht2Pz5+EOQceeyxR2HWrLALRhydX2N4qlL2YCI4FcVRD7fQffLJBDZX9OSTT8CePTvx8YwgKI4u\r\nDOdIdY205a8WTXVHPdV4m/cbtXjYb9RoPW+U39AKYYEBcP8j/hC0qlqL1O1Li4XHbvKDD2Kq2cyR\r\nYflrtS6Q0kw13rsqquFZcTIds6bRzTXqTI235hrl6a6Rp0idOm8kBZIsY3BzjfYL12i/tTjqiydV\r\nenJ8+eUX8fGDIOfImDGvw7hxY1Ecda79AarLyqDMgurGNhRHPSSKvvzyc7jqqqtYU2lCwiZ8HCMI\r\niqP+LY4MkTpThbfbvFGbsuPItABWFUZW80YVQhiZyxjozBF1jwqUeaMN4aJ96K9hsJuJozb4aiQf\
r\nuI0s0mu89wthpM0cVRtb6mgZw6a1+lLAmTYujLQyhlIeqWM13kVG50ir8JbzRvnGeSNzU51axqDO\r\nHMl5I9U1UssYFu6XbXXecVJ98cWR5Pv8BB8/CHKOrFq1An7/+9936fN4u6OJQJ5IHUeh3d5AIE+k\r\njjpyewTaT9cQyJPk6WpyW0mogPZTlDJCKaEEXG3F0N5WRCgE18l8aD+ZJzgErhPZ0H7ioCCTkAGu\r\n4/vBdcxGSCfsA1drGrlNJewhr+8mpEA7u90JrpZkwg7CdnA1Jwm2grNpC7ia4gmbwdm4CVyNGwlx\r\n5PX15HYdIRacR9cSVhNWgevoSnA2xICrYQW5/QGc9dGE5YTvwVm3jBBJWArO2sXklhJBXl8IziML\r\nCPPJ6/PIbThhDjhrZoOjZhZhJjgPfwuOw98wnIe/Bkf1V4Tp5PXp5HYaOKpCCV+Ak+ComkqYAo7K\r\nEHBUBBMmET4De8Un5HYiYUK/EUcZGekwdmwgc4r8/P6GO4sQBMXRBSaOTJG6NiVSJ8VR62m9jMEq\r\nUldritQdVlwjq6Y6ihqpy1f3GxUmwx1y43oaEUeZfOGg32SbW1MdE0bV1vuNNm+J0iJ1QXF1Hpvq\r\ntprnjSyWv3a2qS5aWQCrVnibm+oWK+LIU6yuL55Uhw4dQr6vRfj4QZBzpLg4H37+859BUlJC1zlH\r\nzmZNHIGDiqM68sROxNFp8oRp5+Ko/XSVIo7KdHFEhdGpIiKKCsjrlHzyeq4ujE5mk9ssIogoRBwd\r\n5+KonUHF0V5oJ7haiThq3UNeTyFCaBd5fZdBGDmZKErUhVHzFi6MmogwatpIRFEcE0euxg1EDElx\r\ntIaIojVEDK0iUHG0gkOEkatBF0au+mVcGNUt4cKodhHDQYVRLRFGR+YSIRRO3ubiyFHzHRFIFCKQ\r\niDhy1oSR268ZzsMzuDgSwshZTcXR50QQUV
E0mUOFUSUXRg4mjD4Be/mEfiGOtmzZCCNH/hMuvfR/\r\n4fnnn+uy31MEQVAceaU4kmUM6vJXWcYgXaNGC9eoTggkWcRw2KKModyqjOGoWP4qkEUMufUOmPU6\r\nr3S945NYmPGBH3N+IvKNZQzSNZI13qnKfqPlC8VSwBsD4bu9bVpTnYzVSVGklTF4mDeSsToaqVsn\r\nXCNZxtCha5RlrPFmTXUWsTrpGnmDOCopKYCf/OQnkJ2dgY8fBDkPpkwJgbvvvqvrxJGjyega2YVr\r\nxIRRtaCKO0any3Vx1FZCbnXXqF1zjbg4aj+ZQ4QRdYyymGvkIsKo/fgBcmsjKMLoWCq53cMcIyaK\r\nNGGkuEYt2zRx5GpKIGwhwmgzueXiyNXEXSNdGK01CCNXQwxzjFzMNRLCqD6Ko7lGRBzVRggWEhYQ\r\nQUQdo3lMIDlr5pDb2UIczeTC6HAYwega6Y4Rd42YOKKuERVGVVQgSXH0qYC7Rvbyj7xSHNHn9NDQ\r\nqfDHP97K4nPvvvsOHDiwDx+rCILi6MIVR1Y13idN+43UCm83cXTcfceRFEgd7TcyR+rUHUf7doQb\r\nhm9vn5isV3ibxJG5xnvxVyKW9/dw2GRaAKu6RlqkzmLeaJPJOVonm+o8RerUpjqLeSO1qc4qUjfP\r\nC8TR4sUL4fbbb8PHDoKcJ/n5OfDb394AQUHjuyhWR4SRgwsjQ6ROc42IODqlukalmmvkUoSRSxFG\r\nMk7n0oTRAc01ouKIu0YiUidcIx6p2210jZq3GYSRFqdrjmfCyMmidBuIIJLCSHeNWKSuQUbqdNeI\r\niiOXFEdSGNUtAQcTRdw10uJ0VBQx50jG6b5jkTrqGumROuoazdAjdUqcziCMCHYZp6v8TDhGRBhR\r\n16j8Y7CXBXmNOKKtc999NxMef/xRuOSSS+DRRx+BiIgFUFZWhI9RBEFxhOJIrfHWXKPTxnk
jQ1Pd\r\nSdOOoxN6rO6wqYih0qqprtHYVFd41H3HUXZdNfznJh9tXmh+NneN1DIG6Rrtq+bCiImjPBv8RVkK\r\n+Oy/RsOTL4yGBx4cDZO2tvIyhtIOyhjMTXUFimuUZ3SNzGUM5qY6WeNtiNRZNNVR5qX3fXFEG4pC\r\nQj7Dxw6CdAG07Ys+T/3rX6O6wDnicTpwUHFUy+J0VBiB3RynKzfG6ZgwEuKIRuqEOHKdyGGuEYvU\r\n0TidOmukCSPdNaKzRixOR4VRy06LOB2hhc8auZoTWKROc43ErJGLCaR1RBDpcToXE0fKrJF5zkiL\r\n0xkjdQ7hGtFInYOJI33WyBCnOxymzRrROJ2z2mLOiMXppuizRh5cI0fFx0Qg9W3nKD09jTlEDz30\r\nIBNE9947lJUtYBoAQVAcIcpJ1a2MwcPyV23H0UmOOnPk5hqZBJLb8ldVICkzR3mm5a/rw7gD9Lu3\r\nE3mNt+Icae6R4hyxeaMiGzzkofr17Q2thjKGRKsyhiKljKFAX/66ztO8kSlWJ5vqvldmjpaaXCPD\r\nfiMvcY7owr/LLrsMT6II0oXs25cKP/vZT2HSpE/P+WsMHFgMSVub2JwRFUYgkEUMXBxVKSUMIk4n\r\nxJGcNaKukcsiTseidEoJAxdGwjVSZo1YpE7MGrWzIga1hME4a6TG6VTXiAojl4zTiSIGKY6c9WoJ\r\ng4jTqbNGmmtkjNPRWSM+ZzRbc4wczDES4qiazxqprpGz+kvdNRLCyHm8iHx+hCKMeAmDXbpG5UFg\r\nL/uwTz2PHzqUxXbTvfbaq3Djjb5sN9ETTzwO3377NRw8iM/lCILiCLEWR+b9Rsq8UUc13uZInRRI\r\nUhgZmuosaryLjlqUMRAOafuN6uDDh/kC128zHcqOIwcRQK2ws5CzvYCQT0QPYUexw9BUt0tE6naW\r\nK/NGpe7OkVuFt8V+I/O80WqLHUea
MJL7jZSmuo6cI28QR0895c+ai/BxgyBdy+7dyfDnP/8J7rpr\r\nMGzatOHsT7Y+pwnHYOiQZkhKqNfidLprJIWRu2vEhBGdM2rTZ41cVBxR5+hEthKp60QJg8d2OjFn\r\nJF0jZdZIj9RtILfriCjS43TSNeKzRrKEIdrCNVJLGPRZI1nEwOHiyK2EgQqj6hlaCYPDKk4nHKPT\r\nx4/Dsfp6OH7YBqfK5zCBpEXqhGvkKO9dcbR9+1YIC5vB3Mibb74JLrroIhg8+E5WHb927SqMzCEI\r\niiOkM+LI6TKVMSjOEStjUFyjJg9lDLVKGUONqYyhQtR4lystdcWKOJKROr2MgTtHa74N4I7P67Fw\r\noFZZAFuUCr/1tBTwvVSjOKrQ540oNFInY3UyTmcZqbPacZTvHqsz7zeikbpo4RpJ50guf/VUxiDF\r\nUV8uZFiwYB4MHHgtFBQcwscNgnQDpaWFrKSBDsPfd58fLFu2BMrLizspjo4RWggNhFoikqohaUuV\r\nJozAJI5cimsk43QuU5zOJWaN1Dhd+3FZ3b1XkGqq71Yjddv5rJGI0zlpAQMTRvGWcTrP7XQxXBxR\r\n16hBuEZ1UW6zRkwU1UWA44jqGulxOtlO5xAlDA4Rp+PtdNw1YpG6qi/J619aiiMqjFpqaqChpARq\r\n8/OhLjsBThR/o7lGDuYcje+R5/GsrAOwenUMi8S99NKLcMcdt7N2uauv/hVbMjxhQhCsWbOSNSPi\r\n4wtBUBwhZymOXO3AFsGadxyxMoZTehmDOm9kXv5a52HHERVFZ1r+KhfA5gmBxJ2jNoiJjoUZC2Nh\r\nVY7qGtF5ozbYvLcMNhDWC9YRYtPI+3LaLJ2jZJNrlGSeNyr27BypO44018gkjmJy9DIGN+coy7jj\r\nSI3UqU11fXXmKDk5Ca644gp21REfMwjSvdCFm9OmfcFaw2jd97PPDmdD8zZbWgfiS
AqjOkIVoYJQ\r\nBPcOKSYiqcyja8Rru9U5I+EY0VkjQ0PdAU0cyRIG6Rq1U3EkG+pMs0bGdjpZ3c33GnHXiDfUsUid\r\nNmskI3X6XiNjnK4j10h1jOaLhrpwVsTgsJw1+tqyoU6r7lZ3GlUGa8KorqAAqjIyoCI9HYp27oTK\r\nPauh9dAXLFLn6CJxRAs7qAsUHR0FX3/9Fbzzzlvwj388xUQQfT6m80K33norPPPMP2DixI/h++8j\r\nITPTho8hBEFxhHRJy5GzhUDUi7NJazzShnpZPOOw2JNRbcqty+WB7lcf9cx6tnaSNVTAyqz6sTQ9\r\nqy6vOrbuhPZW05VHdoJN0PdiNMqdGBv0nHqjGsdYxU+qrN1I2YdRLxYFsrrXxexqo8Mtoy6uNmr5\r\n9JmEb5UFgTJ+YRHB0PZghLjl0unVRR67+IidROkVRkfZB2AvHUd4DxylY/ucONqwIRauueZqNsCL\r\njxcE6Vl27drBZpEefPABNu9HxRJdxjlq1EtsEfOcObPYQlnpGKnCyMengJBDyIKhQ7Jg25ZCt1kj\r\nq4Y6zTUSO410YbTf6Bq1KtXdbM5IROpauThyiudupxapM7pG7Pm7w+ruGIMw0uq7LVwjh0V1tyxh\r\nkA11TlN1N43T6cJoGm+nU2eNKtWGuhCGdIxUYVSwbRvkbNwIWbGxkL9xATRlBrPn8fnz58HcueHk\r\nZzSbiNtZsH79WlixYjlrg6M/t88/n8KaCt988w22U+jhhx9iTaDXXXcdDBgwAH70o/+BgQMHwp13\r\n3gFPP/13Jo6mT/8SYmKi2ZwaPj4QBMUR0o3iCJytRBA1iz0ZjWxPhhRHwLarixpYt+WB+o4Ml2w6\r\nUpYH2luzoaX+EDQcIdTkCLIVDhKyOIczCRmC/Yz6ahu5JVSnk9f3kVvKXvJ6GrmlpEJ91R5oINRX\r\npZDb3Yz6yl3QULmT3CaT22
R2W1+5g7CdU7FNkERI5JQnCLYQ4hU2EzZBfdlGcrsBmiti4FQVEUvi\r\nhMqvMtITqbjCWKWfSO10OaBW9TpBE0fs6mK5LowcZe+R23eJOHq3T4mjH374nkUV6VVrfKwgSN9o\r\nt6N/XFOn4JVXXmZ/UFMngQujakK5IoyymTDy8Ukn4igDkuLzDQtf1XY6deGrutOoXUTq5EUtg2uk\r\nxenMe42sZo0SDI4R22mkLXxdb4jU6Re3+KyRS1zgOrNrJBa+Ko4Ra6c7Mke50KUufDXuNXJ6nDUS\r\nO40qJjFhVJ2ZCeWKMMqmwmjdOkiPjoZDG+bB0f2fsufxESNGwAsvvAABAQHw0ksvwS23/IH9rKi4\r\npdXZdLnq66+/Bh98MI7FKalgosKHLlzNytqPv+8IguII6V1xZO0aaW1Hdl0cARVILJ5RqlyBNLtG\r\nudBYmwfFRYVQVFTUD8mHhrJY92x6pfFEqm9On2hyjnj0wl72Prkl4ki4RvaSwD4jjqhTRKMbS5dG\r\n4OMEQfr6yVZzjIoNwog6RknxBcpOo865Rmy3keIaqdXd3O03u0ZqnM4ojpxNeqTOaYrTOZWGOtU1\r\n0ncaWcXppGsU6bmhrlY01NXMMew00meNvvaw8JU/lzvZ87nqGvHq7ioijKhjVEyFUVKSJoyoY9SY\r\nGaJd8PLGJbAIgqA4QtRYnaOZ4CFSd/owEUTq8kA1u24dqaPCqH+KIiMNZWvEyXSqiF8okTqTOLIr\r\nrpGM01FhJCN11Dmyl7zT6ydVOl909913saucW7fG42MEQbxCHBkdo6FDciFpSwl/zj5tNWtUSJ6v\r\n9XY6t+puxTEyukZ7RUudMQ7drrlG2zt0jZyNumvkPLpeW/bKIOLI2aBXd8uGOi1OJ8WRiNM5aCya\r\nukZ1Uhzp1d3uO42Ms0ZOWsRQPUMrYeCROusSBvX53OAYxcVBceIyaD44hV/
wKpcXvN5HcYQgCIoj\r\n73eOeJyOLhDkG9br3CJ15rYjGafTohkinuE4ltunHKO0+GiYERoKM2YtgiRb14q24qJ8OFX5tWl7\r\nerAQRZ+JmtdP9AWB0jVSTqJy1shRGkjoPXGUkrIThg9/Gi6//HI241BSUoCPDwTxGnHEhdHQIfmw\r\nLaHMbaeR1k53SgojYxGDjNS1C9dILWHQZ0SVOF3rnjOUMCiuERFHTjVS17jRUN0t9xrJnUbUNXKZ\r\nSxjonJEap6Mzo3VyblS4RjJSV8vnRh01SkPd4ZmGOB2v7lZcI0UYOc3CiDyn28VzuhRGJTuioSUn\r\nVLTTySTAB+w5nV70QnGEIAiKI28XR9I1ErNG4KgzxenEvJEUR228iIGebF2Ka0R3Y7Q0dF6AZCZF\r\nQ6D/YKWK2xeGDRsFi5JzukS8ZMaF8q87eBj4ktuJsTth7hh/GDMrvssEUlP5ciVSF+JWxCBnjYac\r\nuBYSDj8vhJHqHI1ls0Y0UmcvebtHT6q0OpguB7z//vuYKHr33XdYPSw+LhDEuxg4cCcRRZX6wlfN\r\n6bd2jfS9Rry6mwsjvtNIxulUx6hdK9DRXSNtr1GL+14jQwmDaKjTXCMRp3MxxJxRg9xpJOq761co\r\ne43cXSN91ogW6izks0Zip5HDrYRhlijUCTO4RnSvkVbdTSN1sqFOi9NN1uJ0cna0grbS5X6pRKR5\r\ndbcURjwF8B6KIwRBUBz1B+eIiiPw4BppVyFPK7NGrITBONRLT7QNRzonjmwrJ2qCaOLcaIhdGQmh\r\nE8cwERO40tYlwiV2IhVe4yFNe18mhPj6gO/42C4TR/Vla/iVRnXWSDmZylkjn9Pk//WYDww9eg0k\r\nVD4nTqRjRRFDIIvU2XvAOSoqymOCiLZdUUH0pz/9kdUGFxTk4uMBQbw5Hi0j0KdVYVTqMU7nEvOh\r\n7crCVy1SJxa+uo7Z
LBe+6iUMO8W8kVV1N1/2alz4qrhGR/nCV+kaudTqbiGMLEsYZJxOmzNapNR3\r\nz1P2GplKGMSskYzTSdfIaY7TmWdHtYtdhPKJ2gUvvtdIL9eRrpG9D7aOIgiC4gg565kjXRhpJQxM\r\nGNEK72rjVUjNNbJeHtg5cZQC4325MJoVb3KJ8nIgJ69rhEt8yDDw8Q2BnG6M7dWXxvKTKW2pqwj+\r\n/+2de3RV5ZnG4wURvNS1HEUBxSvS0bFrtNNJ1xjsdFK6RotRsRrroKLWchHMIBJgiAIB8QhDwaAD\r\ncnMMjojcAhwhhAQMEgwQ4BgCCSSQC/ccGxBROJe8s9/3+769v2+ffUKgQk18/3gWRYrQJD07v/M8\r\n7/PE1nfXjoRQ9XACo4RjloKWDidAUl1nWF39uF3EgJG60J6B3/tDFbcycCjw1Vdfgfvv7w6XX345\r\n/Pzn90J6+qtUE8z/H2CxWgsc7ZNgtC/mNtQcfPVyjZzqbjX4qrfTUQnDcVXC4JpeUK7R0dg4nZpe\r\nsBvq5KZR1N40WmzH6ZzB1/laffc8l2uUbTTU0eCrjNOFPQZf9RKGiNZOh65RWHeN9OpubddIvJ6P\r\nMl7P9WKdWNdo8A+udZTFYjEcsc4SjjBS1xiSkbrQIWfX6GRd7ICgDUeVrirY5sFRWa6IuyVnnMbB\r\nCeRCRqoTu+uWmgG5AccFmmr9Wh9fNszOSHFcqOxC+nW/L9X5fZZSfX7796RO8tt/RnlxDqQlq1hf\r\nMqRn9IPExH6QW9ZcOFoS02jkLmIIWQ9SG4yOWNpnqdZSZQJ0r+wMeVW9KFL318DRzp2lkJe3Et59\r\ndyq88sp/wiOPPAy33XYrtG3blsYk//jH52HGjGlQWrqNv+5bmOoswA1mTYaGoUPoR/w5f1xYMQkA\r\nvTjnlOMaReOUMETtsdftRkNdo9qjc7tGxq2R2qTTwEh3jew7IxWnc
26NIhocRT0b6jxKGHTXSG4a\r\nhbXBVwIj1VBH9d3e1d2Ga2SBkXCNfM6tkbZpJFyjURCi13L1ej7SKNexJxmwdVSLSTMcsVgshqMW\r\nf3MkwYga6nTnSETq7Pput2tk1MCKeEZz4CjgzyQYyfQHmvjvFUIaAUsqZPsLoTB3NqSS25QGheUC\r\njnwKaiyYmb0gG9KTxa8X4Z9R5IfMPt2sn/exfm0B+AtKRKwu0YIlG8oKoZ/8M2bnFkLBgqmQLCFp\r\nQeBM4chxjaiEoUY11IkHqXKMdDBK2GWpzNKXCZAU6AirKx6mz4caDpw6NQumTJlMy+fTp78LEyf6\r\nYOTIEdC374tUnoB7GT/9aTf4yU+uhEsvvRS6dr0dfvvbHjBgQD9aVM/N9XOxQgvXQf9SCHfoANYX\r\npS38Of5z/viwnJujKihYdViL02mu0ckqw+mP11CnNo3crpFXnK6xySIGGanTXKOIvWkkShjcg68q\r\nThc14nRquNscfBWxujmu4e5mxOmovtu1aRS3oU5/owtf03XXaLhQtb5VN0QW6/wwWkdZLBbDEet7\r\ngaMjRn23fWtk1Hc3HanDeEbw0M7TO0eyKMHXBBwpgMrICWi/T/0zCToIQ8mZ9k1Rrg8dpEQbbGJj\r\ndQKOEiUcxf8zEiHnTOBIRepqvSIY4h1GAqP9lmo0MNouwChhswVHWztCXrmAo169ehlSDtgFF1xA\r\nuvDCC+Giiy6CNm0uhksuuYTcocsuuwzat29PsbkrrriCgAlX1vGuCPeKrr76auhgfVONuv7666FT\r\np45www2drW+qboSbbroJbrnlZnKa7rjjDgKuO+/8e7j77n8g1+nee++h5XZcasea76Sk+6B79ySC\r\ns+Tkf4MePX5DY5QPPvgA9Oz5O3j00YfhsccehSeeeByeeupJ6N37P+jGCd0rHD1EeBs06CUqgBgy\r\nZDAMGzbUgr
7h8NprI2HMmNdpEPHNN9+gNfgpUyZZkPg2weHMme/B++/Pgrlz/xfmzfsQFiz4GJYs\r\nWQjLl+fAypV+cs7Wrl0N69athS+++JxW5AOBEigrC8CuXTtaHCiiQ+QGIx2Q2EFiOW11pywdh+5J\r\nX0FBbp13CYPH63Xjt/LOiG6Mtsoft8RUdzu7Rus9SxgiWnV3RN4ZkWsk43ROO51yjZZQpI7gSIvU\r\nee4aGWAkXSMVp5N3RugYqRIGr0hdzK6RjNNF7BIGZ4YhVDvG425UvzPSJhlqzEhdiOGIxWIxHLWW\r\nWJ0+/KrB0UmvhjrdNaqIqYJtDhwFcgSUpDdRvBCQkDKvxPln5YXTTThC0Ml0InJ+hKGEZBts/JmJ\r\nBEeBJuGoG2QXlWuRv7OAozr3rZHjHIVko5HtGFWZYJQU6AR5FY9YD9SXIFQ1wPVQnUM/YqscfmNf\r\nVVVBhQq7d++kAgX8hh9vilDl5dthx44vYfv2bRSdw4V1BIOtWzfBli0boaSkmGChuHg9bNiwDtav\r\nLySIwF0jBApcZcddo7y8FbBixXLw+5fCsmWLCT4WLpxPy+0ff/x/5GJhoQOOw86ZM5OA5b33/gem\r\nTXsH3nknC7KyJhPQINjgkCyCTmbmKHj99QwCoOHD0+n+afDgNHj55YHw0kv9yQlDcHruuWfh6ad7\r\nE1Clpj5B7lhKykO0Jo+OGILYr351P9x3379AYuI/0+0Uwttdd90J3bp1g9tvv41AD6Hvuuuug2uu\r\n+TsCQwTHtm0vIajEr5+LL76YnDaESITHa6+9Bjp27EigeOuttxAg4r8T/90IhQiECIP45yME9uz5\r\nIAHg44//nv6uzz77NP39+/fvS9CHsUYBfCOoFv2NN8aS64cfF4w9YrxRQd78+R/RTdiyZUvI6cvP\r\nX2V9TtbQ56hq7BhPMFLCiB2/hrEEHB23dMxS0NJhC5JqLUi
SrtHJSlHdrTXUxewaaXG6Rqru9t40\r\navS6M4qzaxTRbo0EHImGOu84XbxNIy1Sp90axXONME5H1d0Hs+JuGjnV3T7NMZKu0T6niCGkShi0\r\n1lF9xFt3jVSc7m89ycBisRiOWN+bc1Tv6RqZ20Zaffe3atuoImYjI3hox2mBorxoOt0BJaT4NHBx\r\nA1SGjN6VucDFBUfa3dLZwRFCmuMcLchMMf4dzYOjTHsHQ2+o0x+kbscoaUcnWL27Fz1Iw3sGEhiF\r\n9vTnh+p5EAImwiRCJMLjxo0baOcJQRHhBCEF3SgEQ4RCdKkQBhEEEQKnTp0CkyZNhLfeGk/wN2rU\r\nawR+Q4cOIegbOHAAAd8LLzwHzzzzNPzhD6nkoiHoPfDAv0OPHsk25P3iF/8E99zzjzS6i1CGcHbj\r\njTeQu5fZvn2TcDSmXTvo0OFa6Ny5E9x8880Uq0TH72c/E1D3y18muqDud+ToIXiim4cw+uKLLxCg\r\npqUNIhdvxIhh5OCNHTvadu/efvvPBtQhIOPHZfHiBQR16NohWH/2WT5B98aNRQTkWAuPt3AI8zU1\r\nVfy1d07hSIHREUv7LNXS9lH3pN0WJO0yGurUrZEepxPV3aKdTt0aNX7jFDHE7Bp9bcbp7OpuaqbL\r\n1UZf5eCrq4RBH3yNBp1bI901iupxusNaCYMHGDmu0VTaNBL13Vl2EYOxa2TfGr3p2qjL1BrqRtnt\r\ndFSqQ6/l5oi32qpTcKRco/M9ycBisRiOWOfCOdLqu40ihlO1cUoY0DnaZR722nC0s1lQMS9dFi2k\r\nZEBOYTG5HEUFOTAprQ/4EH7KciEVfz05A/zFAQgU++VNUaosS4gPRwuaCUeV5QXQhyJriZDu80E/\r\nrZih+XC0OLa+23W0iw9TBUZJ5Z1hdeXvrQep2DUKyZY6dI7CewbwQ5VlC52hpuBo7xuZBCLYOrhm\r\nzWpy
/dDxy8lZRPDy0UdzDahDVw9v0RB60M1DCEIYQihCOEJIQlhCaOrd+ymCKISphx7q6Ql1WAOP\r\nUIeuHUYyu3TpQnFNBDZ07K688gpoZwFcmzZt7FgoxkAx/nnVVVfZUU/8Pcq169q1q4x03k1xTvxz\r\nlHP361//K0U48e+Cf6devR4h9w7hE/++6OAhkOL/BnTxEFIV9GE7I/5vzcj4L3LzEP7Gjx9HNfaT\r\nJ/+3jG9OIQjEjxWC4KxZIsaJH0N0+fDjiU4ffmzR7cOPM8IhfswRqDHWiXCNnwsERXQA8XOD4I0x\r\nT4RwdG/RxUV43LZtM73uocuLoI6uL8Ikgju6wegMC+0kwESoR/cYXeTq6kpylJWUY6SDEY7CJiSU\r\nWfrSgqRtULByu4drVGpH6tSuUVRrqNNdI6eEYZ1RwuBsGinXyGyoU5E6u4ThL14lDB97uEbuTSPl\r\nGsnq7kOuSN0htWuUZTTUuQdf44ORV6nOa3akzilhGBZTwuBMMgw6J62jLBaL4Yh1vp0jwzU64Iy+\r\nqiIGBUd02Ou4RlFyjMootx6VA4LBgzuaWYNdDjmT0oSDZCjZHoEtK5wnSxikuvWBbHsgNhaOxM1R\r\nCuSUabCU2AQcoUr8kNEnBRKtb/BS0qdCtq+PcbfULDjyGH0Ny3ca1Uhg9903wOqqJyibHq4ebDxI\r\nwxSp62+pHz9UWc7NkfVNcmu6OcJv4vEbfYx/oquEkIAxT3SblGu3atWnBBtLly6iOCfCCDpVCCiz\r\nZ8+gCCcCDLpZCHro3mFsEWFHOHgjCILQxcN4I8IRQlK/fn8iaHr++T7k5iFMPfkkRjcfI8hCVw/j\r\nkghe6LIhCOI4MsIgghkCITpxCGvoyqHbhw4dwiHCHN7pYawTAQ9dPARFdADR1cPIJsY8VdQToRDh\r\nEQER7wLxPhAjnngviMLIJ94RYhQUhUCJgIlxULw1V
DeH6gYRJcBov6UaDYy2ExglJGy24GgL5K8o\r\nlZtG25043QnvdjqhYruIoRHh6JjcNaJI3dqYOB3dGh3VN438WjvdMlnAIDaN7LHXoFnEQIOvRz6M\r\nLWGw4Ch8mjhdTAnD/j/LIoZJsrp7gpCq7nbvGslbIxWnoxIGNxjJ6m4Rp1PV3U4Rw7maZGCxWAxH\r\nrPPuHLlHX923RtU0/BrV19XtWyPHNcIHbfPhSO0aBaCoqMj6Jsn6RqmkzBOiAoEAqfwc7BSVl5l/\r\n1vQ+Ca7h2GbCkWv0NaSBkcqmqwcpxS/2OttGyjViOGJxWx3r7GJ1yjGqMsBIOUYiTrfD+9boxDbH\r\nNTquNdTZu0YSjE5T3R3V4nTmrpEYfI25NZJxOgKj4DyjnS7axJ2R4RoRHE0zInV6dTeWMET0Eob9\r\nbzklDMo10u6MxJtcMlKn7RqF6LU8fnW3/mYXvp7z6ziLxWI4agVwRM6RitTp9d1erhFm1+lBu1M+\r\naNU7kQhHZedscPX7VwlkUBV4CvRLS4MU6VL1m154BiOwi+Q7jc6ukXskMKyNBAo4Mh+kyjViOGLF\r\nc5B454jVNByZjlH3pDLIX7nTNbeArlEsGEXlrVH86m7RUCfqu92uUYHhGjnV3c6mEYJRVMbpTNdI\r\ngZGroc7lGoWpoc6J0ynXSG0aUXX3AeEaRfTqbn3TyK7v1iJ1NN49zmyoq3VujVQKAEe8KUqn4nSu\r\nEgYc8dZdozDDEYvFYjhqDbE6xzWCmHV1l2uk1cHqRQyq7eirQy0JjiqhyJ8NvswMSLPgKC09E+bl\r\nlpzR76/fu1AbCtSPdzXXiB6kQxw42pPmFDForlGoqi8/VFks1lnAkQCj7kk7oSC3Qr5WV3iU5oj4\r\ns3L6RaRuiytSVxw7+Pq116aR9+ArlTA0fGrvGuGtUdQuYohtqFNgFI13a6Q2jezq7ulSMlLn2jWy\r
\nb40OiFsju6GO4nT64Os4Z6POGHxVjtFIzze63K6RerMrjG94VXm1jvLrOIvFYjhqURo9ejRETx10\r\nihhO1WlDggKMxFaGLGH4zlXE8K2AI7WVcbS+tEXB0V+rhr0feB7uinca02Wjkcqnu+IX1kOU7o32\r\nCOfoRAW31bFYrDNXly7rLCiqNAZfzYY67zhd1G6oUyUM7k0jbez1a5drdExzjbQ4HQ2+Nvht1yji\r\nAiPDNTIcI901yhYNdYe9q7vDMYOvWcbga/xNI+UaaYOvtd6Dr86bXMOMeHR47yuaa/SymQKQSQB+\r\nHWexWAxHLVgTJvgsoNmlNdTtM1vqvjMjdWZEQ7wLiQ/aqKyDDR3bClWVu38kcFQB39WMd0XqdNco\r\n3a57te+N5MM0vHeQK1L3J6j4/FUYM2YMP1RZLNaZx6Ot12njLlTfNJKNolFZ3S3AaCvBUSNpswVE\r\nFhx9HesaOXE689Yo0pAnbo2OKjiSYKRVdwvlyDIGB46i6BrVizhdVLlGHiUMETtSJ1yjsOYYibHX\r\nd+3B18jBt+nOKKy5Rk6czlXCoMCoTh98dcDIfJNruGvXyEkAqNtR8/Wc4YjFYjEctWhhPW1+3lKA\r\nkLg1EpE6p747qtd3e7hG+sNWHfV+dejLHwUcBfd+og2/ZsS0GjlFDPqtkZlNV3AUruoL788YDxMn\r\nTuCHKovFOnM48nitjmqROru62941MksYVJyuEaVvGiEYHV2rxem0wdeGPGfTCEsY/uIuYVgiFFxk\r\nxukQjIJx7ozqswUcWWCkGurCVMBg6bDHrtHBLAlGWgkDtdM5JQwKjMw4nV7EoBXquEsY5JtcTVV3\r\nqxFvfD0P8+0oi8ViOGrZKi3dSi/k2wPr7G0jOFXj2jbabRz22rtGGhyJrYwttK6O70IiILVeB6lC\r\ngpGTUQ/Jh2lYKuR6pzEkD3f1hrqQdmvknz+
KIo4zZszghyqLxTpLOBJxOsPh/9bLNXIcIwFHG+2G\r\nOuEarffeNdLidMo1itDYq7NpZJcwaI5RjGuk7xphdTfeGqmGusOqhGGO1lDndo0cx0jcGalI3WS7\r\niCFi7Br5PFyjTGOGwdmoGyFLGBzHSLj/0jXSItL263kV346yWCyGo1alQGALjBs3FtbkL4eG
<TRUNCATED>
[09/50] [abbrv] airavata git commit: Refactor renamed,
isSatisfy method to isReady
Posted by sh...@apache.org.
Refactor renamed, isSatisfy method to isReady
Project: http://git-wip-us.apache.org/repos/asf/airavata/repo
Commit: http://git-wip-us.apache.org/repos/asf/airavata/commit/1a5daae1
Tree: http://git-wip-us.apache.org/repos/asf/airavata/tree/1a5daae1
Diff: http://git-wip-us.apache.org/repos/asf/airavata/diff/1a5daae1
Branch: refs/heads/master
Commit: 1a5daae1a2c87a0cf66b2df820e1460224dc998c
Parents: 0ae7e83
Author: shamrath <sh...@gmail.com>
Authored: Wed Feb 18 15:51:42 2015 -0500
Committer: shamrath <sh...@gmail.com>
Committed: Wed Feb 18 15:51:42 2015 -0500
----------------------------------------------------------------------
.../simple/workflow/engine/SimpleWorkflowInterpreter.java | 8 ++++----
.../workflow/engine/dag/nodes/ApplicationNodeImpl.java | 2 +-
.../workflow/engine/dag/nodes/WorkflowInputNodeImpl.java | 2 +-
.../simple/workflow/engine/dag/nodes/WorkflowNode.java | 2 +-
.../workflow/engine/dag/nodes/WorkflowOutputNodeImpl.java | 2 +-
5 files changed, 8 insertions(+), 8 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/airavata/blob/1a5daae1/modules/simple-workflow/src/main/java/org/apache/ariavata/simple/workflow/engine/SimpleWorkflowInterpreter.java
----------------------------------------------------------------------
diff --git a/modules/simple-workflow/src/main/java/org/apache/ariavata/simple/workflow/engine/SimpleWorkflowInterpreter.java b/modules/simple-workflow/src/main/java/org/apache/ariavata/simple/workflow/engine/SimpleWorkflowInterpreter.java
index bc9c9a2..b4ec3cb 100644
--- a/modules/simple-workflow/src/main/java/org/apache/ariavata/simple/workflow/engine/SimpleWorkflowInterpreter.java
+++ b/modules/simple-workflow/src/main/java/org/apache/ariavata/simple/workflow/engine/SimpleWorkflowInterpreter.java
@@ -133,7 +133,7 @@ public class SimpleWorkflowInterpreter implements Runnable{
private void setupNodeDetailsInput(WorkflowNode readyNode, WorkflowNodeDetails wfNodeDetails) {
if (readyNode instanceof ApplicationNode) {
ApplicationNode applicationNode = (ApplicationNode) readyNode;
- if (applicationNode.isSatisfy()) {
+ if (applicationNode.isReady()) {
for (InPort inPort : applicationNode.getInputPorts()) {
wfNodeDetails.addToNodeInputs(inPort.getInputObject());
}
@@ -149,7 +149,7 @@ public class SimpleWorkflowInterpreter implements Runnable{
private void processWorkflowInputNodes(List<WorkflowInputNode> wfInputNodes) {
Set<WorkflowNode> tempNodeSet = new HashSet<WorkflowNode>();
for (WorkflowInputNode wfInputNode : wfInputNodes) {
- if (wfInputNode.isSatisfy()) {
+ if (wfInputNode.isReady()) {
// for (Edge edge : wfInputNode.getOutputLinks()) {
// WorkflowUtil.copyValues(wfInputNode.getInputObject(), edge.getToPort().getInputObject());
@@ -158,7 +158,7 @@ public class SimpleWorkflowInterpreter implements Runnable{
}
}
for (WorkflowNode workflowNode : tempNodeSet) {
- if (workflowNode.isSatisfy()) {
+ if (workflowNode.isReady()) {
readList.add(workflowNode);
} else {
waitingList.add(workflowNode);
@@ -223,7 +223,7 @@ public class SimpleWorkflowInterpreter implements Runnable{
}
for (WorkflowNode node : tempWfNodeSet) {
- if (node.isSatisfy()) {
+ if (node.isReady()) {
waitingList.remove(node);
readList.add(node);
}
http://git-wip-us.apache.org/repos/asf/airavata/blob/1a5daae1/modules/simple-workflow/src/main/java/org/apache/ariavata/simple/workflow/engine/dag/nodes/ApplicationNodeImpl.java
----------------------------------------------------------------------
diff --git a/modules/simple-workflow/src/main/java/org/apache/ariavata/simple/workflow/engine/dag/nodes/ApplicationNodeImpl.java b/modules/simple-workflow/src/main/java/org/apache/ariavata/simple/workflow/engine/dag/nodes/ApplicationNodeImpl.java
index 36d4349..cfcd3fb 100644
--- a/modules/simple-workflow/src/main/java/org/apache/ariavata/simple/workflow/engine/dag/nodes/ApplicationNodeImpl.java
+++ b/modules/simple-workflow/src/main/java/org/apache/ariavata/simple/workflow/engine/dag/nodes/ApplicationNodeImpl.java
@@ -71,7 +71,7 @@ public class ApplicationNodeImpl implements ApplicationNode {
}
@Override
- public boolean isSatisfy() {
+ public boolean isReady() {
for (InPort inPort : getInputPorts()) {
if (!inPort.isSatisfy()) {
return false;
http://git-wip-us.apache.org/repos/asf/airavata/blob/1a5daae1/modules/simple-workflow/src/main/java/org/apache/ariavata/simple/workflow/engine/dag/nodes/WorkflowInputNodeImpl.java
----------------------------------------------------------------------
diff --git a/modules/simple-workflow/src/main/java/org/apache/ariavata/simple/workflow/engine/dag/nodes/WorkflowInputNodeImpl.java b/modules/simple-workflow/src/main/java/org/apache/ariavata/simple/workflow/engine/dag/nodes/WorkflowInputNodeImpl.java
index 38092dd..2f912b3 100644
--- a/modules/simple-workflow/src/main/java/org/apache/ariavata/simple/workflow/engine/dag/nodes/WorkflowInputNodeImpl.java
+++ b/modules/simple-workflow/src/main/java/org/apache/ariavata/simple/workflow/engine/dag/nodes/WorkflowInputNodeImpl.java
@@ -66,7 +66,7 @@ public class WorkflowInputNodeImpl implements WorkflowInputNode {
}
@Override
- public boolean isSatisfy() {
+ public boolean isReady() {
return inputDataObjectType.getValue() != null && !inputDataObjectType.getValue().equals("");
}
http://git-wip-us.apache.org/repos/asf/airavata/blob/1a5daae1/modules/simple-workflow/src/main/java/org/apache/ariavata/simple/workflow/engine/dag/nodes/WorkflowNode.java
----------------------------------------------------------------------
diff --git a/modules/simple-workflow/src/main/java/org/apache/ariavata/simple/workflow/engine/dag/nodes/WorkflowNode.java b/modules/simple-workflow/src/main/java/org/apache/ariavata/simple/workflow/engine/dag/nodes/WorkflowNode.java
index 043f6cb..f8b0e0c 100644
--- a/modules/simple-workflow/src/main/java/org/apache/ariavata/simple/workflow/engine/dag/nodes/WorkflowNode.java
+++ b/modules/simple-workflow/src/main/java/org/apache/ariavata/simple/workflow/engine/dag/nodes/WorkflowNode.java
@@ -33,6 +33,6 @@ public interface WorkflowNode {
public void setNodeState(NodeState newNodeState);
- public boolean isSatisfy();
+ public boolean isReady();
}
http://git-wip-us.apache.org/repos/asf/airavata/blob/1a5daae1/modules/simple-workflow/src/main/java/org/apache/ariavata/simple/workflow/engine/dag/nodes/WorkflowOutputNodeImpl.java
----------------------------------------------------------------------
diff --git a/modules/simple-workflow/src/main/java/org/apache/ariavata/simple/workflow/engine/dag/nodes/WorkflowOutputNodeImpl.java b/modules/simple-workflow/src/main/java/org/apache/ariavata/simple/workflow/engine/dag/nodes/WorkflowOutputNodeImpl.java
index 32db82c..aa7f0a3 100644
--- a/modules/simple-workflow/src/main/java/org/apache/ariavata/simple/workflow/engine/dag/nodes/WorkflowOutputNodeImpl.java
+++ b/modules/simple-workflow/src/main/java/org/apache/ariavata/simple/workflow/engine/dag/nodes/WorkflowOutputNodeImpl.java
@@ -68,7 +68,7 @@ public class WorkflowOutputNodeImpl implements WorkflowOutputNode {
}
@Override
- public boolean isSatisfy() {
+ public boolean isReady() {
return this.outputDataObjectType.getValue() != null && !this.outputDataObjectType.getValue().equals("");
}
[20/50] [abbrv] airavata git commit: Fixed AIRAVATA-1591 ,
AIRAVATA-1592 , AIRAVATA-1593
Posted by sh...@apache.org.
http://git-wip-us.apache.org/repos/asf/airavata/blob/d25441a0/modules/simple-workflow/src/main/java/org/apache/airavata/simple/workflow/engine/SimpleWorkflowInterpreter.java
----------------------------------------------------------------------
diff --git a/modules/simple-workflow/src/main/java/org/apache/airavata/simple/workflow/engine/SimpleWorkflowInterpreter.java b/modules/simple-workflow/src/main/java/org/apache/airavata/simple/workflow/engine/SimpleWorkflowInterpreter.java
index 6dcb8bd..edfa306 100644
--- a/modules/simple-workflow/src/main/java/org/apache/airavata/simple/workflow/engine/SimpleWorkflowInterpreter.java
+++ b/modules/simple-workflow/src/main/java/org/apache/airavata/simple/workflow/engine/SimpleWorkflowInterpreter.java
@@ -21,10 +21,16 @@
package org.apache.airavata.simple.workflow.engine;
-import com.google.common.eventbus.EventBus;
-import com.google.common.eventbus.Subscribe;
-import org.apache.airavata.model.appcatalog.appinterface.InputDataObjectType;
+import org.apache.airavata.common.exception.AiravataException;
+import org.apache.airavata.common.utils.AiravataUtils;
+import org.apache.airavata.messaging.core.MessageContext;
+import org.apache.airavata.messaging.core.MessageHandler;
+import org.apache.airavata.messaging.core.MessagingConstants;
+import org.apache.airavata.messaging.core.impl.RabbitMQProcessPublisher;
+import org.apache.airavata.messaging.core.impl.RabbitMQStatusConsumer;
import org.apache.airavata.model.appcatalog.appinterface.OutputDataObjectType;
+import org.apache.airavata.model.messaging.event.MessageType;
+import org.apache.airavata.model.messaging.event.ProcessSubmitEvent;
import org.apache.airavata.model.messaging.event.TaskIdentifier;
import org.apache.airavata.model.messaging.event.TaskOutputChangeEvent;
import org.apache.airavata.model.messaging.event.TaskStatusChangeEvent;
@@ -45,11 +51,11 @@ import org.apache.airavata.simple.workflow.engine.dag.edge.Edge;
import org.apache.airavata.simple.workflow.engine.dag.nodes.ApplicationNode;
import org.apache.airavata.simple.workflow.engine.dag.nodes.NodeState;
import org.apache.airavata.simple.workflow.engine.dag.nodes.WorkflowInputNode;
-import org.apache.airavata.simple.workflow.engine.dag.nodes.WorkflowOutputNode;
-import org.apache.airavata.simple.workflow.engine.parser.AiravataDefaultParser;
import org.apache.airavata.simple.workflow.engine.dag.nodes.WorkflowNode;
+import org.apache.airavata.simple.workflow.engine.dag.nodes.WorkflowOutputNode;
import org.apache.airavata.simple.workflow.engine.dag.port.InPort;
import org.apache.airavata.simple.workflow.engine.dag.port.OutPort;
+import org.apache.airavata.simple.workflow.engine.parser.AiravataWorkflowParser;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -64,32 +70,36 @@ import java.util.concurrent.ConcurrentHashMap;
public class SimpleWorkflowInterpreter implements Runnable{
private static final Logger log = LoggerFactory.getLogger(SimpleWorkflowInterpreter.class);
-
private List<WorkflowInputNode> workflowInputNodes;
private Experiment experiment;
private String credentialToken;
+ private String gatewayName;
+
private Map<String, WorkflowNode> readList = new ConcurrentHashMap<String, WorkflowNode>();
private Map<String, WorkflowNode> waitingList = new ConcurrentHashMap<String, WorkflowNode>();
- private Map<String, ProcessPack> processingQueue = new ConcurrentHashMap<String, ProcessPack>();
- private Map<String, ProcessPack> completeList = new HashMap<String, ProcessPack>();
+ private Map<String, ProcessContext> processingQueue = new ConcurrentHashMap<String, ProcessContext>();
+ private Map<String, ProcessContext> completeList = new HashMap<String, ProcessContext>();
private Registry registry;
- private EventBus eventBus = new EventBus();
private List<WorkflowOutputNode> completeWorkflowOutputs = new ArrayList<WorkflowOutputNode>();
+ private RabbitMQProcessPublisher publisher;
+ private RabbitMQStatusConsumer statusConsumer;
+ private String consumerId;
- public SimpleWorkflowInterpreter(String experimentId, String credentialToken) throws RegistryException {
+ public SimpleWorkflowInterpreter(String experimentId, String credentialToken, String gatewayName, RabbitMQProcessPublisher publisher) throws RegistryException {
+ this.gatewayName = gatewayName;
setExperiment(experimentId);
this.credentialToken = credentialToken;
+ this.publisher = publisher;
}
- public SimpleWorkflowInterpreter(Experiment experiment, String credentialStoreToken) {
- // read the workflow file and build the topology to a DAG. Then execute that dag
- // get workflowInputNode list and start processing
- // next() will return ready task and block the thread if no task in ready state.
+ public SimpleWorkflowInterpreter(Experiment experiment, String credentialStoreToken, String gatewayName, RabbitMQProcessPublisher publisher) {
+ this.gatewayName = gatewayName;
this.experiment = experiment;
this.credentialToken = credentialStoreToken;
+ this.publisher = publisher;
}
@@ -97,11 +107,15 @@ public class SimpleWorkflowInterpreter implements Runnable{
// process workflow input nodes
// WorkflowFactoryImpl wfFactory = WorkflowFactoryImpl.getInstance();
// WorkflowParser workflowParser = wfFactory.getWorkflowParser(experiment.getExperimentID(), credentialToken);
- WorkflowParser workflowParser = new AiravataDefaultParser(experiment, credentialToken);
+ WorkflowParser workflowParser = new AiravataWorkflowParser(experiment, credentialToken);
log.debug("Initialized workflow parser");
setWorkflowInputNodes(workflowParser.parse());
log.debug("Parsed the workflow and got the workflow input nodes");
processWorkflowInputNodes(getWorkflowInputNodes());
+
+
+ statusConsumer = new RabbitMQStatusConsumer();
+ consumerId = statusConsumer.listen(new TaskMessageHandler());
}
// try to remove synchronization tag
@@ -116,56 +130,31 @@ public class SimpleWorkflowInterpreter implements Runnable{
}
WorkflowNodeDetails workflowNodeDetails = createWorkflowNodeDetails(readyNode);
TaskDetails process = getProcess(workflowNodeDetails);
- ProcessPack processPack = new ProcessPack(readyNode, workflowNodeDetails, process);
- addToProcessingQueue(processPack);
-// publishToProcessQueue(process);
- publishToProcessQueue(processPack);
+ ProcessContext processContext = new ProcessContext(readyNode, workflowNodeDetails, process);
+ addToProcessingQueue(processContext);
+ publishToProcessQueue(process);
+// publishToProcessQueue(processPack);
} catch (RegistryException e) {
// FIXME : handle this exception
+ } catch (AiravataException e) {
+ log.error("Error while publishing process to the process queue");
}
}
}
- private void publishToProcessQueue(TaskDetails process) {
- Thread thread = new Thread(new TempPublisher(process, eventBus));
- thread.start();
- //TODO: publish to process queue.
- }
+ private void publishToProcessQueue(TaskDetails process) throws AiravataException {
+ ProcessSubmitEvent processSubmitEvent = new ProcessSubmitEvent();
+ processSubmitEvent.setCredentialToken(credentialToken);
+ processSubmitEvent.setTaskId(process.getTaskID());
+ MessageContext messageContext = new MessageContext(processSubmitEvent, MessageType.TASK, process.getTaskID(), null);
+ messageContext.setUpdatedTime(AiravataUtils.getCurrentTimestamp());
+ publisher.publish(messageContext);
- // TODO : remove this test method
- private void publishToProcessQueue(ProcessPack process) {
- WorkflowNode workflowNode = process.getWorkflowNode();
- if (workflowNode instanceof ApplicationNode) {
- ApplicationNode applicationNode = (ApplicationNode) workflowNode;
- List<InPort> inputPorts = applicationNode.getInputPorts();
- if (applicationNode.getName().equals("Add")) {
- applicationNode.getOutputPorts().get(0).getOutputObject().setValue(String.valueOf(
- Integer.parseInt(inputPorts.get(0).getInputObject().getValue()) + Integer.parseInt(inputPorts.get(1).getInputObject().getValue())));
- } else if (applicationNode.getName().equals("Multiply")) {
- applicationNode.getOutputPorts().get(0).getOutputObject().setValue(String.valueOf(
- Integer.parseInt(inputPorts.get(0).getInputObject().getValue()) * Integer.parseInt(inputPorts.get(1).getInputObject().getValue())));
- } else if (applicationNode.getName().equals("Subtract")) {
- applicationNode.getOutputPorts().get(0).getOutputObject().setValue(String.valueOf(
- Integer.parseInt(inputPorts.get(0).getInputObject().getValue()) - Integer.parseInt(inputPorts.get(1).getInputObject().getValue())));
- } else {
- throw new RuntimeException("Invalid Application name");
- }
- for (Edge edge : applicationNode.getOutputPorts().get(0).getOutEdges()) {
- WorkflowUtil.copyValues(applicationNode.getOutputPorts().get(0).getOutputObject(), edge.getToPort().getInputObject());
- if (edge.getToPort().getNode().isReady()) {
- addToReadyQueue(edge.getToPort().getNode());
- } else {
- addToWaitingQueue(edge.getToPort().getNode());
- }
- }
- } else if (workflowNode instanceof WorkflowOutputNode) {
- WorkflowOutputNode wfOutputNode = (WorkflowOutputNode) workflowNode;
- throw new RuntimeException("Workflow output node in processing queue");
- }
-
- processingQueue.remove(process.getTaskDetails().getTaskID());
+// Thread thread = new Thread(new TempPublisher(process, eventBus));
+// thread.start();
+ //TODO: publish to process queue.
}
private TaskDetails getProcess(WorkflowNodeDetails wfNodeDetails) throws RegistryException {
@@ -242,12 +231,6 @@ public class SimpleWorkflowInterpreter implements Runnable{
this.workflowInputNodes = workflowInputNodes;
}
-
- private List<WorkflowInputNode> parseWorkflowDescription(){
- return null;
- }
-
-
private Registry getRegistry() throws RegistryException {
if (registry==null){
registry = RegistryFactory.getDefaultRegistry();
@@ -265,93 +248,6 @@ public class SimpleWorkflowInterpreter implements Runnable{
getRegistry().update(RegistryModelType.WORKFLOW_NODE_STATUS, status, wfNodeDetails.getNodeInstanceId());
}
- @Subscribe
- public void taskOutputChanged(TaskOutputChangeEvent taskOutputEvent){
- String taskId = taskOutputEvent.getTaskIdentity().getTaskId();
- log.debug("Task Output changed event received for workflow node : " +
- taskOutputEvent.getTaskIdentity().getWorkflowNodeId() + ", task : " + taskId);
- ProcessPack processPack = processingQueue.get(taskId);
- Set<WorkflowNode> tempWfNodeSet = new HashSet<WorkflowNode>();
- if (processPack != null) {
- WorkflowNode workflowNode = processPack.getWorkflowNode();
- if (workflowNode instanceof ApplicationNode) {
- ApplicationNode applicationNode = (ApplicationNode) workflowNode;
- // Workflow node can have one to many output ports and each output port can have one to many links
- for (OutPort outPort : applicationNode.getOutputPorts()) {
- for (OutputDataObjectType outputDataObjectType : taskOutputEvent.getOutput()) {
- if (outPort.getOutputObject().getName().equals(outputDataObjectType.getName())) {
- outPort.getOutputObject().setValue(outputDataObjectType.getValue());
- break;
- }
- }
- for (Edge edge : outPort.getOutEdges()) {
- WorkflowUtil.copyValues(outPort.getOutputObject(), edge.getToPort().getInputObject());
- if (edge.getToPort().getNode().isReady()) {
- addToReadyQueue(edge.getToPort().getNode());
- }
- }
- }
- }
- processingQueue.remove(taskId);
- log.debug("removed task from processing queue : " + taskId);
- }
-
- }
-
- @Subscribe
- public void taskStatusChanged(TaskStatusChangeEvent taskStatus){
- String taskId = taskStatus.getTaskIdentity().getTaskId();
- ProcessPack processPack = processingQueue.get(taskId);
- if (processPack != null) {
- WorkflowNodeState wfNodeState = WorkflowNodeState.UNKNOWN;
- switch (taskStatus.getState()) {
- case WAITING:
- break;
- case STARTED:
- break;
- case PRE_PROCESSING:
- processPack.getWorkflowNode().setState(NodeState.PRE_PROCESSING);
- break;
- case INPUT_DATA_STAGING:
- processPack.getWorkflowNode().setState(NodeState.PRE_PROCESSING);
- break;
- case EXECUTING:
- processPack.getWorkflowNode().setState(NodeState.EXECUTING);
- break;
- case OUTPUT_DATA_STAGING:
- processPack.getWorkflowNode().setState(NodeState.POST_PROCESSING);
- break;
- case POST_PROCESSING:
- processPack.getWorkflowNode().setState(NodeState.POST_PROCESSING);
- break;
- case COMPLETED:
- processPack.getWorkflowNode().setState(NodeState.EXECUTED);
- break;
- case FAILED:
- processPack.getWorkflowNode().setState(NodeState.FAILED);
- break;
- case UNKNOWN:
- break;
- case CONFIGURING_WORKSPACE:
- break;
- case CANCELED:
- case CANCELING:
- processPack.getWorkflowNode().setState(NodeState.FAILED);
- break;
- default:
- break;
- }
- if (wfNodeState != WorkflowNodeState.UNKNOWN) {
- try {
- updateWorkflowNodeStatus(processPack.getWfNodeDetails(), wfNodeState);
- } catch (RegistryException e) {
- // TODO: handle this.
- }
- }
- }
-
- }
-
/**
* Remove the workflow node from waiting queue and add it to the ready queue.
* @param workflowNode - Workflow Node
@@ -368,16 +264,16 @@ public class SimpleWorkflowInterpreter implements Runnable{
/**
* First remove the node from ready list and then add the WfNodeContainer to the process queue.
* Note that underline data structure of the process queue is a Map.
- * @param processPack - has both workflow and correspond workflowNodeDetails and TaskDetails
+ * @param processContext - has both workflow and correspond workflowNodeDetails and TaskDetails
*/
- private synchronized void addToProcessingQueue(ProcessPack processPack) {
- readList.remove(processPack.getWorkflowNode().getId());
- processingQueue.put(processPack.getTaskDetails().getTaskID(), processPack);
+ private synchronized void addToProcessingQueue(ProcessContext processContext) {
+ readList.remove(processContext.getWorkflowNode().getId());
+ processingQueue.put(processContext.getTaskDetails().getTaskID(), processContext);
}
- private synchronized void addToCompleteQueue(ProcessPack processPack) {
- processingQueue.remove(processPack.getTaskDetails().getTaskID());
- completeList.put(processPack.getTaskDetails().getTaskID(), processPack);
+ private synchronized void addToCompleteQueue(ProcessContext processContext) {
+ processingQueue.remove(processContext.getTaskDetails().getTaskID());
+ completeList.put(processContext.getTaskDetails().getTaskID(), processContext);
}
@@ -388,7 +284,6 @@ public class SimpleWorkflowInterpreter implements Runnable{
@Override
public void run() {
- // TODO: Auto generated method body.
try {
log.debug("Launching workflow");
launchWorkflow();
@@ -396,8 +291,11 @@ public class SimpleWorkflowInterpreter implements Runnable{
processReadyList();
Thread.sleep(1000);
}
+ log.info("Successfully launched workflow for experiment : " + getExperiment().getExperimentID());
+ statusConsumer.stopListen(consumerId);
+ log.info("Successfully un-bind status consumer for experiment " + getExperiment().getExperimentID());
} catch (Exception e) {
- e.printStackTrace();
+ //TODO - handle this.
}
}
@@ -406,65 +304,129 @@ public class SimpleWorkflowInterpreter implements Runnable{
log.debug("Retrieve Experiment for experiment id : " + experimentId);
}
+ class TaskMessageHandler implements MessageHandler{
- class TempPublisher implements Runnable {
- private TaskDetails tempTaskDetails;
- private EventBus tempEventBus;
-
- public TempPublisher(TaskDetails tempTaskDetails, EventBus tempEventBus) {
- this.tempTaskDetails = tempTaskDetails;
- this.tempEventBus = tempEventBus;
+ @Override
+ public Map<String, Object> getProperties() {
+ Map<String, Object> props = new HashMap<String, Object>();
+ String gatewayId = "*";
+ String experimentId = getExperiment().getExperimentID();
+ List<String> routingKeys = new ArrayList<String>();
+// routingKeys.add(gatewayName+ "." + getExperiment().getExperimentID() + ".*");
+ routingKeys.add(gatewayId);
+ routingKeys.add(gatewayId + "." + experimentId);
+ routingKeys.add(gatewayId + "." + experimentId+ ".*");
+ routingKeys.add(gatewayId + "." + experimentId+ ".*.*");
+ props.put(MessagingConstants.RABBIT_ROUTING_KEY, routingKeys);
+ return props;
}
@Override
- public void run() {
- try {
- TaskIdentifier identifier = new TaskIdentifier(tempTaskDetails.getTaskID(), null, null, null);
- TaskStatusChangeEvent statusChangeEvent = new TaskStatusChangeEvent(TaskState.PRE_PROCESSING, identifier);
- tempEventBus.post(statusChangeEvent);
- Thread.sleep(1000);
- statusChangeEvent = new TaskStatusChangeEvent(TaskState.WAITING, identifier);
- tempEventBus.post(statusChangeEvent);
- Thread.sleep(1000);
- statusChangeEvent = new TaskStatusChangeEvent(TaskState.INPUT_DATA_STAGING, identifier);
- tempEventBus.post(statusChangeEvent);
- Thread.sleep(1000);
- statusChangeEvent = new TaskStatusChangeEvent(TaskState.STARTED, identifier);
- tempEventBus.post(statusChangeEvent);
- Thread.sleep(1000);
- statusChangeEvent = new TaskStatusChangeEvent(TaskState.EXECUTING, identifier);
- tempEventBus.post(statusChangeEvent);
- Thread.sleep(1000);
- statusChangeEvent = new TaskStatusChangeEvent(TaskState.POST_PROCESSING, identifier);
- tempEventBus.post(statusChangeEvent);
- Thread.sleep(1000);
- statusChangeEvent = new TaskStatusChangeEvent(TaskState.OUTPUT_DATA_STAGING, identifier);
- tempEventBus.post(statusChangeEvent);
- Thread.sleep(1000);
- statusChangeEvent = new TaskStatusChangeEvent(TaskState.COMPLETED, identifier);
- tempEventBus.post(statusChangeEvent);
- Thread.sleep(1000);
+ public void onMessage(MessageContext msgCtx) {
+ String message;
+ if (msgCtx.getType() == MessageType.TASK) {
+ TaskStatusChangeEvent event = (TaskStatusChangeEvent) msgCtx.getEvent();
+ TaskIdentifier taskIdentifier = event.getTaskIdentity();
+ handleTaskStatusChangeEvent(event);
+ message = "Received task output change event , expId : " + taskIdentifier.getExperimentId() + ", taskId : " + taskIdentifier.getTaskId() + ", workflow node Id : " + taskIdentifier.getWorkflowNodeId();
+ log.debug(message);
+ }else if (msgCtx.getType() == MessageType.TASKOUTPUT) {
+ TaskOutputChangeEvent event = (TaskOutputChangeEvent) msgCtx.getEvent();
+ TaskIdentifier taskIdentifier = event.getTaskIdentity();
+ handleTaskOutputChangeEvent(event);
+ message = "Received task output change event , expId : " + taskIdentifier.getExperimentId() + ", taskId : " + taskIdentifier.getTaskId() + ", workflow node Id : " + taskIdentifier.getWorkflowNodeId();
+ log.debug(message);
+ } else {
+ // not interesting, ignores
+ }
+ }
- List<InputDataObjectType> applicationInputs = tempTaskDetails.getApplicationInputs();
- List<OutputDataObjectType> applicationOutputs = tempTaskDetails.getApplicationOutputs();
- log.info("************** Task output change event fired for application id :" + tempTaskDetails.getApplicationId());
- if (tempTaskDetails.getApplicationId().equals("Add") || tempTaskDetails.getApplicationId().equals("Add_2")) {
- applicationOutputs.get(0).setValue((Integer.parseInt(applicationInputs.get(0).getValue()) +
- Integer.parseInt(applicationInputs.get(1).getValue())) + "");
- } else if (tempTaskDetails.getApplicationId().equals("Subtract")) {
- applicationOutputs.get(0).setValue((Integer.parseInt(applicationInputs.get(0).getValue()) -
- Integer.parseInt(applicationInputs.get(1).getValue())) + "");
- } else if (tempTaskDetails.getApplicationId().equals("Multiply")) {
- applicationOutputs.get(0).setValue((Integer.parseInt(applicationInputs.get(0).getValue()) *
- Integer.parseInt(applicationInputs.get(1).getValue())) + "");
+ private void handleTaskOutputChangeEvent(TaskOutputChangeEvent taskOutputChangeEvent) {
+
+ String taskId = taskOutputChangeEvent.getTaskIdentity().getTaskId();
+ log.debug("Task Output changed event received for workflow node : " +
+ taskOutputChangeEvent.getTaskIdentity().getWorkflowNodeId() + ", task : " + taskId);
+ ProcessContext processContext = processingQueue.get(taskId);
+ Set<WorkflowNode> tempWfNodeSet = new HashSet<WorkflowNode>();
+ if (processContext != null) {
+ WorkflowNode workflowNode = processContext.getWorkflowNode();
+ if (workflowNode instanceof ApplicationNode) {
+ ApplicationNode applicationNode = (ApplicationNode) workflowNode;
+ // Workflow node can have one to many output ports and each output port can have one to many links
+ for (OutPort outPort : applicationNode.getOutputPorts()) {
+ for (OutputDataObjectType outputDataObjectType : taskOutputChangeEvent.getOutput()) {
+ if (outPort.getOutputObject().getName().equals(outputDataObjectType.getName())) {
+ outPort.getOutputObject().setValue(outputDataObjectType.getValue());
+ break;
+ }
+ }
+ for (Edge edge : outPort.getOutEdges()) {
+ edge.getToPort().getInputObject().setValue(outPort.getOutputObject().getValue());
+ if (edge.getToPort().getNode().isReady()) {
+ addToReadyQueue(edge.getToPort().getNode());
+ }
+ }
+ }
}
- TaskOutputChangeEvent taskOutputChangeEvent = new TaskOutputChangeEvent(applicationOutputs, identifier);
- eventBus.post(taskOutputChangeEvent);
+ addToCompleteQueue(processContext);
+ log.debug("removed task from processing queue : " + taskId);
+ }
+ }
- } catch (InterruptedException e) {
- log.error("Thread was interrupted while sleeping");
+ private void handleTaskStatusChangeEvent(TaskStatusChangeEvent taskStatusChangeEvent) {
+ TaskState taskState = taskStatusChangeEvent.getState();
+ TaskIdentifier taskIdentity = taskStatusChangeEvent.getTaskIdentity();
+ String taskId = taskIdentity.getTaskId();
+ ProcessContext processContext = processingQueue.get(taskId);
+ if (processContext != null) {
+ WorkflowNodeState wfNodeState = WorkflowNodeState.UNKNOWN;
+ switch (taskState) {
+ case WAITING:
+ break;
+ case STARTED:
+ break;
+ case PRE_PROCESSING:
+ processContext.getWorkflowNode().setState(NodeState.PRE_PROCESSING);
+ break;
+ case INPUT_DATA_STAGING:
+ processContext.getWorkflowNode().setState(NodeState.PRE_PROCESSING);
+ break;
+ case EXECUTING:
+ processContext.getWorkflowNode().setState(NodeState.EXECUTING);
+ break;
+ case OUTPUT_DATA_STAGING:
+ processContext.getWorkflowNode().setState(NodeState.POST_PROCESSING);
+ break;
+ case POST_PROCESSING:
+ processContext.getWorkflowNode().setState(NodeState.POST_PROCESSING);
+ break;
+ case COMPLETED:
+ processContext.getWorkflowNode().setState(NodeState.EXECUTED);
+ break;
+ case FAILED:
+ processContext.getWorkflowNode().setState(NodeState.FAILED);
+ break;
+ case UNKNOWN:
+ break;
+ case CONFIGURING_WORKSPACE:
+ break;
+ case CANCELED:
+ case CANCELING:
+ processContext.getWorkflowNode().setState(NodeState.FAILED);
+ break;
+ default:
+ break;
+ }
+ if (wfNodeState != WorkflowNodeState.UNKNOWN) {
+ try {
+ updateWorkflowNodeStatus(processContext.getWfNodeDetails(), wfNodeState);
+ } catch (RegistryException e) {
+ // TODO: handle this.
+ }
+ }
}
}
}
+
}
http://git-wip-us.apache.org/repos/asf/airavata/blob/d25441a0/modules/simple-workflow/src/main/java/org/apache/airavata/simple/workflow/engine/WorkflowFactoryImpl.java
----------------------------------------------------------------------
diff --git a/modules/simple-workflow/src/main/java/org/apache/airavata/simple/workflow/engine/WorkflowFactoryImpl.java b/modules/simple-workflow/src/main/java/org/apache/airavata/simple/workflow/engine/WorkflowFactoryImpl.java
index 116a10d..b12260d 100644
--- a/modules/simple-workflow/src/main/java/org/apache/airavata/simple/workflow/engine/WorkflowFactoryImpl.java
+++ b/modules/simple-workflow/src/main/java/org/apache/airavata/simple/workflow/engine/WorkflowFactoryImpl.java
@@ -22,7 +22,7 @@
package org.apache.airavata.simple.workflow.engine;
import org.apache.airavata.registry.cpi.RegistryException;
-import org.apache.airavata.simple.workflow.engine.parser.AiravataDefaultParser;
+import org.apache.airavata.simple.workflow.engine.parser.AiravataWorkflowParser;
/**
* Singleton class, only one instance can exist in runtime.
@@ -55,7 +55,7 @@ public class WorkflowFactoryImpl implements WorkflowFactory {
public WorkflowParser getWorkflowParser(String experimentId, String credentialToken) {
if (workflowParser == null) {
try {
- workflowParser = new AiravataDefaultParser(experimentId, credentialToken);
+ workflowParser = new AiravataWorkflowParser(experimentId, credentialToken);
} catch (RegistryException e) {
// TODO : handle this scenario
}
http://git-wip-us.apache.org/repos/asf/airavata/blob/d25441a0/modules/simple-workflow/src/main/java/org/apache/airavata/simple/workflow/engine/parser/AiravataDefaultParser.java
----------------------------------------------------------------------
diff --git a/modules/simple-workflow/src/main/java/org/apache/airavata/simple/workflow/engine/parser/AiravataDefaultParser.java b/modules/simple-workflow/src/main/java/org/apache/airavata/simple/workflow/engine/parser/AiravataDefaultParser.java
deleted file mode 100644
index 644eda6..0000000
--- a/modules/simple-workflow/src/main/java/org/apache/airavata/simple/workflow/engine/parser/AiravataDefaultParser.java
+++ /dev/null
@@ -1,293 +0,0 @@
-/*
- *
- * 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.simple.workflow.engine.parser;
-
-import org.airavata.appcatalog.cpi.AppCatalogException;
-import org.airavata.appcatalog.cpi.WorkflowCatalog;
-import org.apache.aiaravata.application.catalog.data.impl.AppCatalogFactory;
-import org.apache.airavata.model.appcatalog.appinterface.InputDataObjectType;
-import org.apache.airavata.model.appcatalog.appinterface.OutputDataObjectType;
-import org.apache.airavata.model.workspace.experiment.Experiment;
-import org.apache.airavata.persistance.registry.jpa.impl.RegistryFactory;
-import org.apache.airavata.registry.cpi.Registry;
-import org.apache.airavata.registry.cpi.RegistryException;
-import org.apache.airavata.registry.cpi.RegistryModelType;
-import org.apache.airavata.simple.workflow.engine.dag.nodes.ApplicationNodeImpl;
-import org.apache.airavata.simple.workflow.engine.dag.nodes.WorkflowInputNode;
-import org.apache.airavata.simple.workflow.engine.dag.nodes.WorkflowInputNodeImpl;
-import org.apache.airavata.simple.workflow.engine.dag.port.OutPortImpl;
-import org.apache.airavata.workflow.model.component.ComponentException;
-import org.apache.airavata.workflow.model.component.system.ConstantComponent;
-import org.apache.airavata.workflow.model.component.system.InputComponent;
-import org.apache.airavata.workflow.model.component.system.S3InputComponent;
-import org.apache.airavata.workflow.model.graph.DataEdge;
-import org.apache.airavata.workflow.model.graph.DataPort;
-import org.apache.airavata.workflow.model.graph.GraphException;
-import org.apache.airavata.workflow.model.graph.Node;
-import org.apache.airavata.workflow.model.graph.impl.NodeImpl;
-import org.apache.airavata.workflow.model.graph.system.OutputNode;
-import org.apache.airavata.workflow.model.graph.system.SystemDataPort;
-import org.apache.airavata.workflow.model.graph.ws.WSNode;
-import org.apache.airavata.workflow.model.graph.ws.WSPort;
-import org.apache.airavata.workflow.model.wf.Workflow;
-import org.apache.airavata.simple.workflow.engine.WorkflowParser;
-import org.apache.airavata.simple.workflow.engine.dag.edge.DirectedEdge;
-import org.apache.airavata.simple.workflow.engine.dag.edge.Edge;
-import org.apache.airavata.simple.workflow.engine.dag.nodes.ApplicationNode;
-import org.apache.airavata.simple.workflow.engine.dag.nodes.WorkflowNode;
-import org.apache.airavata.simple.workflow.engine.dag.nodes.WorkflowOutputNode;
-import org.apache.airavata.simple.workflow.engine.dag.nodes.WorkflowOutputNodeImpl;
-import org.apache.airavata.simple.workflow.engine.dag.port.InPort;
-import org.apache.airavata.simple.workflow.engine.dag.port.InputPortIml;
-import org.apache.airavata.simple.workflow.engine.dag.port.OutPort;
-
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-
-public class AiravataDefaultParser implements WorkflowParser {
-
- private String credentialToken ;
- private Workflow workflow;
-
-
- private Experiment experiment;
- private Map<String, WorkflowNode> wfNodes = new HashMap<String, WorkflowNode>();
-
-
- public AiravataDefaultParser(String experimentId, String credentialToken) throws RegistryException {
- this.experiment = getExperiment(experimentId);
- this.credentialToken = credentialToken;
- }
-
- public AiravataDefaultParser(Experiment experiment, String credentialToken) {
- this.credentialToken = credentialToken;
- this.experiment = experiment;
- }
-
- @Override
- public List<WorkflowInputNode> parse() throws RegistryException, AppCatalogException,
- ComponentException, GraphException {
- return parseWorkflow(getWorkflowFromExperiment(experiment));
- }
-
- public List<WorkflowInputNode> parseWorkflow(Workflow workflow) {
- List<Node> gNodes = getInputNodes(workflow);
- List<WorkflowInputNode> wfInputNodes = new ArrayList<WorkflowInputNode>();
- List<PortContainer> portContainers = new ArrayList<PortContainer>();
- List<InputDataObjectType> experimentInputs = experiment.getExperimentInputs();
- Map<String,InputDataObjectType> inputDataMap=new HashMap<String, InputDataObjectType>();
- WorkflowInputNode wfInputNode = null;
- for (InputDataObjectType dataObjectType : experimentInputs) {
- inputDataMap.put(dataObjectType.getName(), dataObjectType);
- }
- for (Node gNode : gNodes) {
- wfInputNode = new WorkflowInputNodeImpl(gNode.getID(), gNode.getName());
- wfInputNode.setInputObject(inputDataMap.get(wfInputNode.getName()));
- if (wfInputNode.getInputObject() == null) {
- // TODO: throw an error and exit.
- }
- portContainers.addAll(processOutPorts(gNode, wfInputNode));
- wfInputNodes.add(wfInputNode);
- }
-
- // while port container is not empty iterate graph and build the workflow DAG.
- buildModel(portContainers);
-
- return wfInputNodes;
- }
-
- private void buildModel(List<PortContainer> portContainerList) {
- // end condition of recursive call.
- if (portContainerList == null || portContainerList.isEmpty()) {
- return ;
- }
- DataPort dataPort = null;
- InPort inPort = null;
- ApplicationNode wfApplicationNode = null;
- WorkflowOutputNode wfOutputNode = null;
- List<PortContainer> nextPortContainerList = new ArrayList<PortContainer>();
- for (PortContainer portContainer : portContainerList) {
- dataPort = portContainer.getDataPort();
- inPort = portContainer.getInPort();
- Node node = dataPort.getNode();
- if (node instanceof WSNode) {
- WSNode wsNode = (WSNode) node;
- WorkflowNode wfNode = wfNodes.get(wsNode.getID());
- if (wfNode == null) {
- wfApplicationNode = createApplicationNode(wsNode);
- wfNodes.put(wfApplicationNode.getId(), wfApplicationNode);
- nextPortContainerList.addAll(processOutPorts(wsNode, wfApplicationNode));
- } else if (wfNode instanceof ApplicationNode) {
- wfApplicationNode = (ApplicationNode) wfNode;
- } else {
- // TODO : handle this scenario
- }
- inPort.setNode(wfApplicationNode);
- wfApplicationNode.addInPort(inPort);
-
- }else if (node instanceof OutputNode) {
- OutputNode oNode = (OutputNode) node;
- wfOutputNode = createWorkflowOutputNode(oNode);
- wfOutputNode.setInPort(inPort);
- inPort.setNode(wfOutputNode);
- wfNodes.put(wfOutputNode.getId(), wfOutputNode);
- }
- }
- buildModel(nextPortContainerList);
-
- }
-
- private WorkflowOutputNode createWorkflowOutputNode(OutputNode oNode) {
- WorkflowOutputNodeImpl workflowOutputNode = new WorkflowOutputNodeImpl(oNode.getID(), oNode.getName());
- OutputDataObjectType outputDataObjectType = new OutputDataObjectType();
- outputDataObjectType.setType(oNode.getParameterType());
- workflowOutputNode.setOutputObject(outputDataObjectType);
- return workflowOutputNode;
- }
-
- private ApplicationNode createApplicationNode(WSNode wsNode) {
- ApplicationNode applicationNode = new ApplicationNodeImpl(wsNode.getID(),
- wsNode.getComponent().getApplication().getName(),
- wsNode.getComponent().getApplication().getApplicationId());
- return applicationNode;
- }
-
- private List<PortContainer> processOutPorts(Node node, WorkflowNode wfNode) {
- OutPort outPort ;
- Edge edge;
- InPort inPort = null;
- List<PortContainer> portContainers = new ArrayList<PortContainer>();
- for (DataPort dataPort : node.getOutputPorts()) {
- outPort = createOutPort(dataPort);
- for (DataEdge dataEdge : dataPort.getEdges()) {
- edge = new DirectedEdge();
- edge.setFromPort(outPort);
- outPort.addEdge(edge);
- inPort = createInPort(dataEdge.getToPort());
- edge.setToPort(inPort);
- inPort.addEdge(edge);
- portContainers.add(new PortContainer(dataEdge.getToPort(), inPort));
- }
- outPort.setNode(wfNode);
- if (wfNode instanceof WorkflowInputNode) {
- WorkflowInputNode workflowInputNode = (WorkflowInputNode) wfNode;
- workflowInputNode.setOutPort(outPort);
- } else if (wfNode instanceof ApplicationNode) {
- ApplicationNode applicationNode = ((ApplicationNode) wfNode);
- applicationNode.addOutPort(outPort);
- }
- }
- return portContainers;
- }
-
- private OutPort createOutPort(DataPort dataPort) {
- OutPortImpl outPort = new OutPortImpl(dataPort.getID());
- OutputDataObjectType outputDataObjectType = new OutputDataObjectType();
- if (dataPort instanceof WSPort) {
- WSPort wsPort = (WSPort) dataPort;
- outputDataObjectType.setName(wsPort.getFromNode().getName());
- outputDataObjectType.setType(wsPort.getType());
- }else if (dataPort instanceof SystemDataPort) {
- SystemDataPort sysPort = (SystemDataPort) dataPort;
- outputDataObjectType.setName(sysPort.getFromNode().getName());
- outputDataObjectType.setType(sysPort.getType());
- }
-
- outPort.setOutputObject(outputDataObjectType);
- return outPort;
- }
-
- private InPort createInPort(DataPort toPort) {
- InPort inPort = new InputPortIml(toPort.getID());
- InputDataObjectType inputDataObjectType = new InputDataObjectType();
- if (toPort instanceof WSPort) {
- WSPort wsPort = (WSPort) toPort;
- inputDataObjectType.setName(wsPort.getName());
- inputDataObjectType.setType(wsPort.getType());
- inputDataObjectType.setApplicationArgument(wsPort.getComponentPort().getApplicationArgument());
- inputDataObjectType.setIsRequired(!wsPort.getComponentPort().isOptional());
- inputDataObjectType.setInputOrder(wsPort.getComponentPort().getInputOrder());
-
- inPort.setDefaultValue(wsPort.getComponentPort().getDefaultValue());
- }else if (toPort instanceof SystemDataPort) {
- SystemDataPort sysPort = (SystemDataPort) toPort;
- inputDataObjectType.setName(sysPort.getName());
- inputDataObjectType.setType(sysPort.getType());
- }
- inPort.setInputObject(inputDataObjectType);
- return inPort;
- }
-
- private InputDataObjectType getInputDataObject(DataPort dataPort) {
- InputDataObjectType inputDataObject = new InputDataObjectType();
- inputDataObject.setName(dataPort.getName());
- if (dataPort instanceof WSPort) {
- WSPort port = (WSPort) dataPort;
- inputDataObject.setInputOrder(port.getComponentPort().getInputOrder());
- inputDataObject.setApplicationArgument(port.getComponentPort().getApplicationArgument() == null ?
- "" : port.getComponentPort().getApplicationArgument());
- inputDataObject.setType(dataPort.getType());
- }
- return inputDataObject;
- }
-
- private OutputDataObjectType getOutputDataObject(InputDataObjectType inputObject) {
- OutputDataObjectType outputDataObjectType = new OutputDataObjectType();
- outputDataObjectType.setApplicationArgument(inputObject.getApplicationArgument());
- outputDataObjectType.setName(inputObject.getName());
- outputDataObjectType.setType(inputObject.getType());
- outputDataObjectType.setValue(inputObject.getValue());
- return outputDataObjectType;
- }
-
- private Experiment getExperiment(String experimentId) throws RegistryException {
- Registry registry = RegistryFactory.getDefaultRegistry();
- return (Experiment)registry.get(RegistryModelType.EXPERIMENT, experimentId);
- }
-
- private Workflow getWorkflowFromExperiment(Experiment experiment) throws RegistryException, AppCatalogException, GraphException, ComponentException {
- WorkflowCatalog workflowCatalog = getWorkflowCatalog();
- return new Workflow(workflowCatalog.getWorkflow(experiment.getApplicationId()).getGraph());
- }
-
- private WorkflowCatalog getWorkflowCatalog() throws AppCatalogException {
- return AppCatalogFactory.getAppCatalog().getWorkflowCatalog();
- }
-
- private ArrayList<Node> getInputNodes(Workflow wf) {
- ArrayList<Node> list = new ArrayList<Node>();
- List<NodeImpl> nodes = wf.getGraph().getNodes();
- for (Node node : nodes) {
- String name = node.getComponent().getName();
- if (InputComponent.NAME.equals(name) || ConstantComponent.NAME.equals(name) || S3InputComponent.NAME.equals(name)) {
- list.add(node);
- }
- }
- return list;
- }
-
- public Map<String, WorkflowNode> getWfNodes() {
- return wfNodes;
- }
-}
http://git-wip-us.apache.org/repos/asf/airavata/blob/d25441a0/modules/simple-workflow/src/main/java/org/apache/airavata/simple/workflow/engine/parser/AiravataWorkflowParser.java
----------------------------------------------------------------------
diff --git a/modules/simple-workflow/src/main/java/org/apache/airavata/simple/workflow/engine/parser/AiravataWorkflowParser.java b/modules/simple-workflow/src/main/java/org/apache/airavata/simple/workflow/engine/parser/AiravataWorkflowParser.java
new file mode 100644
index 0000000..673fbdc
--- /dev/null
+++ b/modules/simple-workflow/src/main/java/org/apache/airavata/simple/workflow/engine/parser/AiravataWorkflowParser.java
@@ -0,0 +1,291 @@
+/*
+ *
+ * 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.simple.workflow.engine.parser;
+
+import org.airavata.appcatalog.cpi.AppCatalogException;
+import org.airavata.appcatalog.cpi.WorkflowCatalog;
+import org.apache.aiaravata.application.catalog.data.impl.AppCatalogFactory;
+import org.apache.airavata.model.appcatalog.appinterface.InputDataObjectType;
+import org.apache.airavata.model.appcatalog.appinterface.OutputDataObjectType;
+import org.apache.airavata.model.workspace.experiment.Experiment;
+import org.apache.airavata.persistance.registry.jpa.impl.RegistryFactory;
+import org.apache.airavata.registry.cpi.Registry;
+import org.apache.airavata.registry.cpi.RegistryException;
+import org.apache.airavata.registry.cpi.RegistryModelType;
+import org.apache.airavata.simple.workflow.engine.dag.nodes.ApplicationNodeImpl;
+import org.apache.airavata.simple.workflow.engine.dag.nodes.WorkflowInputNode;
+import org.apache.airavata.simple.workflow.engine.dag.nodes.WorkflowInputNodeImpl;
+import org.apache.airavata.simple.workflow.engine.dag.port.OutPortImpl;
+import org.apache.airavata.workflow.model.component.ComponentException;
+import org.apache.airavata.workflow.model.component.system.ConstantComponent;
+import org.apache.airavata.workflow.model.component.system.InputComponent;
+import org.apache.airavata.workflow.model.component.system.S3InputComponent;
+import org.apache.airavata.workflow.model.graph.DataEdge;
+import org.apache.airavata.workflow.model.graph.DataPort;
+import org.apache.airavata.workflow.model.graph.GraphException;
+import org.apache.airavata.workflow.model.graph.Node;
+import org.apache.airavata.workflow.model.graph.impl.NodeImpl;
+import org.apache.airavata.workflow.model.graph.system.OutputNode;
+import org.apache.airavata.workflow.model.graph.system.SystemDataPort;
+import org.apache.airavata.workflow.model.graph.ws.WSNode;
+import org.apache.airavata.workflow.model.graph.ws.WSPort;
+import org.apache.airavata.workflow.model.wf.Workflow;
+import org.apache.airavata.simple.workflow.engine.WorkflowParser;
+import org.apache.airavata.simple.workflow.engine.dag.edge.DirectedEdge;
+import org.apache.airavata.simple.workflow.engine.dag.edge.Edge;
+import org.apache.airavata.simple.workflow.engine.dag.nodes.ApplicationNode;
+import org.apache.airavata.simple.workflow.engine.dag.nodes.WorkflowNode;
+import org.apache.airavata.simple.workflow.engine.dag.nodes.WorkflowOutputNode;
+import org.apache.airavata.simple.workflow.engine.dag.nodes.WorkflowOutputNodeImpl;
+import org.apache.airavata.simple.workflow.engine.dag.port.InPort;
+import org.apache.airavata.simple.workflow.engine.dag.port.InputPortIml;
+import org.apache.airavata.simple.workflow.engine.dag.port.OutPort;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+public class AiravataWorkflowParser implements WorkflowParser {
+
+ private String credentialToken ;
+
+ private Experiment experiment;
+ private Map<String, WorkflowNode> wfNodes = new HashMap<String, WorkflowNode>();
+
+
+ public AiravataWorkflowParser(String experimentId, String credentialToken) throws RegistryException {
+ this.experiment = getExperiment(experimentId);
+ this.credentialToken = credentialToken;
+ }
+
+ public AiravataWorkflowParser(Experiment experiment, String credentialToken) {
+ this.credentialToken = credentialToken;
+ this.experiment = experiment;
+ }
+
+ @Override
+ public List<WorkflowInputNode> parse() throws RegistryException, AppCatalogException,
+ ComponentException, GraphException {
+ return parseWorkflow(getWorkflowFromExperiment(experiment));
+ }
+
+ public List<WorkflowInputNode> parseWorkflow(Workflow workflow) {
+ List<Node> gNodes = getInputNodes(workflow);
+ List<WorkflowInputNode> wfInputNodes = new ArrayList<WorkflowInputNode>();
+ List<PortContainer> portContainers = new ArrayList<PortContainer>();
+ List<InputDataObjectType> experimentInputs = experiment.getExperimentInputs();
+ Map<String,InputDataObjectType> inputDataMap=new HashMap<String, InputDataObjectType>();
+ WorkflowInputNode wfInputNode = null;
+ for (InputDataObjectType dataObjectType : experimentInputs) {
+ inputDataMap.put(dataObjectType.getName(), dataObjectType);
+ }
+ for (Node gNode : gNodes) {
+ wfInputNode = new WorkflowInputNodeImpl(gNode.getID(), gNode.getName());
+ wfInputNode.setInputObject(inputDataMap.get(wfInputNode.getName()));
+ if (wfInputNode.getInputObject() == null) {
+ // TODO: throw an error and exit.
+ }
+ portContainers.addAll(processOutPorts(gNode, wfInputNode));
+ wfInputNodes.add(wfInputNode);
+ }
+
+ // while port container is not empty iterate graph and build the workflow DAG.
+ buildModel(portContainers);
+
+ return wfInputNodes;
+ }
+
+ private void buildModel(List<PortContainer> portContainerList) {
+ // end condition of recursive call.
+ if (portContainerList == null || portContainerList.isEmpty()) {
+ return ;
+ }
+ DataPort dataPort = null;
+ InPort inPort = null;
+ ApplicationNode wfApplicationNode = null;
+ WorkflowOutputNode wfOutputNode = null;
+ List<PortContainer> nextPortContainerList = new ArrayList<PortContainer>();
+ for (PortContainer portContainer : portContainerList) {
+ dataPort = portContainer.getDataPort();
+ inPort = portContainer.getInPort();
+ Node node = dataPort.getNode();
+ if (node instanceof WSNode) {
+ WSNode wsNode = (WSNode) node;
+ WorkflowNode wfNode = wfNodes.get(wsNode.getID());
+ if (wfNode == null) {
+ wfApplicationNode = createApplicationNode(wsNode);
+ wfNodes.put(wfApplicationNode.getId(), wfApplicationNode);
+ nextPortContainerList.addAll(processOutPorts(wsNode, wfApplicationNode));
+ } else if (wfNode instanceof ApplicationNode) {
+ wfApplicationNode = (ApplicationNode) wfNode;
+ } else {
+ // TODO : handle this scenario
+ }
+ inPort.setNode(wfApplicationNode);
+ wfApplicationNode.addInPort(inPort);
+
+ }else if (node instanceof OutputNode) {
+ OutputNode oNode = (OutputNode) node;
+ wfOutputNode = createWorkflowOutputNode(oNode);
+ wfOutputNode.setInPort(inPort);
+ inPort.setNode(wfOutputNode);
+ wfNodes.put(wfOutputNode.getId(), wfOutputNode);
+ }
+ }
+ buildModel(nextPortContainerList);
+
+ }
+
+ private WorkflowOutputNode createWorkflowOutputNode(OutputNode oNode) {
+ WorkflowOutputNodeImpl workflowOutputNode = new WorkflowOutputNodeImpl(oNode.getID(), oNode.getName());
+ OutputDataObjectType outputDataObjectType = new OutputDataObjectType();
+ outputDataObjectType.setType(oNode.getParameterType());
+ workflowOutputNode.setOutputObject(outputDataObjectType);
+ return workflowOutputNode;
+ }
+
+ private ApplicationNode createApplicationNode(WSNode wsNode) {
+ ApplicationNode applicationNode = new ApplicationNodeImpl(wsNode.getID(),
+ wsNode.getComponent().getApplication().getName(),
+ wsNode.getComponent().getApplication().getApplicationId());
+ return applicationNode;
+ }
+
+ private List<PortContainer> processOutPorts(Node node, WorkflowNode wfNode) {
+ OutPort outPort ;
+ Edge edge;
+ InPort inPort = null;
+ List<PortContainer> portContainers = new ArrayList<PortContainer>();
+ for (DataPort dataPort : node.getOutputPorts()) {
+ outPort = createOutPort(dataPort);
+ for (DataEdge dataEdge : dataPort.getEdges()) {
+ edge = new DirectedEdge();
+ edge.setFromPort(outPort);
+ outPort.addEdge(edge);
+ inPort = createInPort(dataEdge.getToPort());
+ edge.setToPort(inPort);
+ inPort.addEdge(edge);
+ portContainers.add(new PortContainer(dataEdge.getToPort(), inPort));
+ }
+ outPort.setNode(wfNode);
+ if (wfNode instanceof WorkflowInputNode) {
+ WorkflowInputNode workflowInputNode = (WorkflowInputNode) wfNode;
+ workflowInputNode.setOutPort(outPort);
+ } else if (wfNode instanceof ApplicationNode) {
+ ApplicationNode applicationNode = ((ApplicationNode) wfNode);
+ applicationNode.addOutPort(outPort);
+ }
+ }
+ return portContainers;
+ }
+
+ private OutPort createOutPort(DataPort dataPort) {
+ OutPortImpl outPort = new OutPortImpl(dataPort.getID());
+ OutputDataObjectType outputDataObjectType = new OutputDataObjectType();
+ if (dataPort instanceof WSPort) {
+ WSPort wsPort = (WSPort) dataPort;
+ outputDataObjectType.setName(wsPort.getComponentPort().getName());
+ outputDataObjectType.setType(wsPort.getType());
+ }else if (dataPort instanceof SystemDataPort) {
+ SystemDataPort sysPort = (SystemDataPort) dataPort;
+ outputDataObjectType.setName(sysPort.getFromNode().getName());
+ outputDataObjectType.setType(sysPort.getType());
+ }
+
+ outPort.setOutputObject(outputDataObjectType);
+ return outPort;
+ }
+
+ private InPort createInPort(DataPort toPort) {
+ InPort inPort = new InputPortIml(toPort.getID());
+ InputDataObjectType inputDataObjectType = new InputDataObjectType();
+ if (toPort instanceof WSPort) {
+ WSPort wsPort = (WSPort) toPort;
+ inputDataObjectType.setName(wsPort.getName());
+ inputDataObjectType.setType(wsPort.getType());
+ inputDataObjectType.setApplicationArgument(wsPort.getComponentPort().getApplicationArgument());
+ inputDataObjectType.setIsRequired(!wsPort.getComponentPort().isOptional());
+ inputDataObjectType.setInputOrder(wsPort.getComponentPort().getInputOrder());
+
+ inPort.setDefaultValue(wsPort.getComponentPort().getDefaultValue());
+ }else if (toPort instanceof SystemDataPort) {
+ SystemDataPort sysPort = (SystemDataPort) toPort;
+ inputDataObjectType.setName(sysPort.getName());
+ inputDataObjectType.setType(sysPort.getType());
+ }
+ inPort.setInputObject(inputDataObjectType);
+ return inPort;
+ }
+
+ private InputDataObjectType getInputDataObject(DataPort dataPort) {
+ InputDataObjectType inputDataObject = new InputDataObjectType();
+ inputDataObject.setName(dataPort.getName());
+ if (dataPort instanceof WSPort) {
+ WSPort port = (WSPort) dataPort;
+ inputDataObject.setInputOrder(port.getComponentPort().getInputOrder());
+ inputDataObject.setApplicationArgument(port.getComponentPort().getApplicationArgument() == null ?
+ "" : port.getComponentPort().getApplicationArgument());
+ inputDataObject.setType(dataPort.getType());
+ }
+ return inputDataObject;
+ }
+
+ private OutputDataObjectType getOutputDataObject(InputDataObjectType inputObject) {
+ OutputDataObjectType outputDataObjectType = new OutputDataObjectType();
+ outputDataObjectType.setApplicationArgument(inputObject.getApplicationArgument());
+ outputDataObjectType.setName(inputObject.getName());
+ outputDataObjectType.setType(inputObject.getType());
+ outputDataObjectType.setValue(inputObject.getValue());
+ return outputDataObjectType;
+ }
+
+ private Experiment getExperiment(String experimentId) throws RegistryException {
+ Registry registry = RegistryFactory.getDefaultRegistry();
+ return (Experiment)registry.get(RegistryModelType.EXPERIMENT, experimentId);
+ }
+
+ private Workflow getWorkflowFromExperiment(Experiment experiment) throws RegistryException, AppCatalogException, GraphException, ComponentException {
+ WorkflowCatalog workflowCatalog = getWorkflowCatalog();
+ return new Workflow(workflowCatalog.getWorkflow(experiment.getApplicationId()).getGraph());
+ }
+
+ private WorkflowCatalog getWorkflowCatalog() throws AppCatalogException {
+ return AppCatalogFactory.getAppCatalog().getWorkflowCatalog();
+ }
+
+ private ArrayList<Node> getInputNodes(Workflow wf) {
+ ArrayList<Node> list = new ArrayList<Node>();
+ List<NodeImpl> nodes = wf.getGraph().getNodes();
+ for (Node node : nodes) {
+ String name = node.getComponent().getName();
+ if (InputComponent.NAME.equals(name) || ConstantComponent.NAME.equals(name) || S3InputComponent.NAME.equals(name)) {
+ list.add(node);
+ }
+ }
+ return list;
+ }
+
+ public Map<String, WorkflowNode> getWfNodes() {
+ return wfNodes;
+ }
+}
http://git-wip-us.apache.org/repos/asf/airavata/blob/d25441a0/modules/simple-workflow/src/test/java/org/apache/airavata/simple/workflow/engine/parser/AiravataDefaultParserTest.java
----------------------------------------------------------------------
diff --git a/modules/simple-workflow/src/test/java/org/apache/airavata/simple/workflow/engine/parser/AiravataDefaultParserTest.java b/modules/simple-workflow/src/test/java/org/apache/airavata/simple/workflow/engine/parser/AiravataDefaultParserTest.java
deleted file mode 100644
index e9b3e55..0000000
--- a/modules/simple-workflow/src/test/java/org/apache/airavata/simple/workflow/engine/parser/AiravataDefaultParserTest.java
+++ /dev/null
@@ -1,119 +0,0 @@
-/*
- *
- * 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.simple.workflow.engine.parser;
-
-import org.apache.airavata.model.appcatalog.appinterface.DataType;
-import org.apache.airavata.model.appcatalog.appinterface.InputDataObjectType;
-import org.apache.airavata.model.workspace.experiment.Experiment;
-import org.apache.airavata.simple.workflow.engine.dag.nodes.ApplicationNode;
-import org.apache.airavata.simple.workflow.engine.dag.nodes.WorkflowInputNode;
-import org.apache.airavata.simple.workflow.engine.dag.nodes.WorkflowOutputNode;
-import org.apache.airavata.workflow.model.wf.Workflow;
-import org.apache.airavata.simple.workflow.engine.dag.nodes.WorkflowNode;
-import org.junit.After;
-import org.junit.Assert;
-import org.junit.Before;
-import org.junit.Test;
-
-import java.io.BufferedReader;
-import java.io.InputStreamReader;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Map;
-
-public class AiravataDefaultParserTest {
-
- @Before
- public void setUp() throws Exception {
-
- }
-
- @After
- public void tearDown() throws Exception {
-
- }
-
- @Test
- public void testWorkflowParse() throws Exception {
- Assert.assertNotNull("Test file (ComplexMathWorkflow.awf) is missing", getClass().getResource("/ComplexMathWorkflow.awf"));
- InputStreamReader isr = new InputStreamReader(this.getClass().getResourceAsStream("/ComplexMathWorkflow.awf"));
- BufferedReader br = new BufferedReader(isr);
- StringBuffer sb = new StringBuffer();
- String nextLine = br.readLine();
- while (nextLine != null) {
- sb.append(nextLine);
- nextLine = br.readLine();
- }
- Workflow workflow = new Workflow(sb.toString());
- Experiment experiment = new Experiment();
- InputDataObjectType x = new InputDataObjectType();
- x.setValue("6");
- x.setType(DataType.STRING);
- x.setName("x");
-
- InputDataObjectType y = new InputDataObjectType();
- y.setValue("8");
- y.setType(DataType.STRING);
- y.setName("y");
-
- InputDataObjectType z = new InputDataObjectType();
- z.setValue("10");
- z.setType(DataType.STRING);
- z.setName("y_2");
-
- List<InputDataObjectType> inputs = new ArrayList<InputDataObjectType>();
- inputs.add(x);
- inputs.add(y);
- inputs.add(z);
- experiment.setExperimentInputs(inputs);
- // create parser
- AiravataDefaultParser parser = new AiravataDefaultParser(experiment, "testCredentialId");
- List<WorkflowInputNode> workflowInputNodes = parser.parseWorkflow(workflow);
- Assert.assertNotNull(workflowInputNodes);
- Assert.assertEquals(3, workflowInputNodes.size());
- for (WorkflowInputNode workflowInputNode : workflowInputNodes) {
- Assert.assertNotNull(workflowInputNode.getOutPort());
- Assert.assertNotNull(workflowInputNode.getInputObject());
- }
-
- Map<String, WorkflowNode> wfNodes = parser.getWfNodes();
- for (String wfId : wfNodes.keySet()) {
- WorkflowNode wfNode = wfNodes.get(wfId);
- if (wfNode instanceof ApplicationNode) {
- ApplicationNode node = (ApplicationNode) wfNode;
- Assert.assertEquals(2, node.getInputPorts().size());
- Assert.assertNotNull(node.getInputPorts().get(0).getInputObject());
- Assert.assertNotNull(node.getInputPorts().get(1).getInputObject());
- Assert.assertNotNull(node.getInputPorts().get(0).getEdge());
- Assert.assertNotNull(node.getInputPorts().get(1).getEdge());
-
- Assert.assertEquals(1, node.getOutputPorts().size());
- Assert.assertEquals(1, node.getOutputPorts().get(0).getOutEdges().size());
- Assert.assertNotNull(node.getOutputPorts().get(0).getOutEdges().get(0));
- } else if (wfNode instanceof WorkflowOutputNode) {
- WorkflowOutputNode workflowOutputNode = (WorkflowOutputNode) wfNode;
- Assert.assertNotNull(workflowOutputNode.getInPort());
- }
- }
-
- }
-}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/airavata/blob/d25441a0/modules/simple-workflow/src/test/java/org/apache/airavata/simple/workflow/engine/parser/AiravataWorkflowParserTest.java
----------------------------------------------------------------------
diff --git a/modules/simple-workflow/src/test/java/org/apache/airavata/simple/workflow/engine/parser/AiravataWorkflowParserTest.java b/modules/simple-workflow/src/test/java/org/apache/airavata/simple/workflow/engine/parser/AiravataWorkflowParserTest.java
new file mode 100644
index 0000000..6443806
--- /dev/null
+++ b/modules/simple-workflow/src/test/java/org/apache/airavata/simple/workflow/engine/parser/AiravataWorkflowParserTest.java
@@ -0,0 +1,119 @@
+/*
+ *
+ * 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.simple.workflow.engine.parser;
+
+import org.apache.airavata.model.appcatalog.appinterface.DataType;
+import org.apache.airavata.model.appcatalog.appinterface.InputDataObjectType;
+import org.apache.airavata.model.workspace.experiment.Experiment;
+import org.apache.airavata.simple.workflow.engine.dag.nodes.ApplicationNode;
+import org.apache.airavata.simple.workflow.engine.dag.nodes.WorkflowInputNode;
+import org.apache.airavata.simple.workflow.engine.dag.nodes.WorkflowOutputNode;
+import org.apache.airavata.workflow.model.wf.Workflow;
+import org.apache.airavata.simple.workflow.engine.dag.nodes.WorkflowNode;
+import org.junit.After;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+
+import java.io.BufferedReader;
+import java.io.InputStreamReader;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+
+public class AiravataWorkflowParserTest {
+
+ @Before
+ public void setUp() throws Exception {
+
+ }
+
+ @After
+ public void tearDown() throws Exception {
+
+ }
+
+ @Test
+ public void testWorkflowParse() throws Exception {
+ Assert.assertNotNull("Test file (ComplexMathWorkflow.awf) is missing", getClass().getResource("/ComplexMathWorkflow.awf"));
+ InputStreamReader isr = new InputStreamReader(this.getClass().getResourceAsStream("/ComplexMathWorkflow.awf"));
+ BufferedReader br = new BufferedReader(isr);
+ StringBuffer sb = new StringBuffer();
+ String nextLine = br.readLine();
+ while (nextLine != null) {
+ sb.append(nextLine);
+ nextLine = br.readLine();
+ }
+ Workflow workflow = new Workflow(sb.toString());
+ Experiment experiment = new Experiment();
+ InputDataObjectType x = new InputDataObjectType();
+ x.setValue("6");
+ x.setType(DataType.STRING);
+ x.setName("x");
+
+ InputDataObjectType y = new InputDataObjectType();
+ y.setValue("8");
+ y.setType(DataType.STRING);
+ y.setName("y");
+
+ InputDataObjectType z = new InputDataObjectType();
+ z.setValue("10");
+ z.setType(DataType.STRING);
+ z.setName("y_2");
+
+ List<InputDataObjectType> inputs = new ArrayList<InputDataObjectType>();
+ inputs.add(x);
+ inputs.add(y);
+ inputs.add(z);
+ experiment.setExperimentInputs(inputs);
+ // create parser
+ AiravataWorkflowParser parser = new AiravataWorkflowParser(experiment, "testCredentialId");
+ List<WorkflowInputNode> workflowInputNodes = parser.parseWorkflow(workflow);
+ Assert.assertNotNull(workflowInputNodes);
+ Assert.assertEquals(3, workflowInputNodes.size());
+ for (WorkflowInputNode workflowInputNode : workflowInputNodes) {
+ Assert.assertNotNull(workflowInputNode.getOutPort());
+ Assert.assertNotNull(workflowInputNode.getInputObject());
+ }
+
+ Map<String, WorkflowNode> wfNodes = parser.getWfNodes();
+ for (String wfId : wfNodes.keySet()) {
+ WorkflowNode wfNode = wfNodes.get(wfId);
+ if (wfNode instanceof ApplicationNode) {
+ ApplicationNode node = (ApplicationNode) wfNode;
+ Assert.assertEquals(2, node.getInputPorts().size());
+ Assert.assertNotNull(node.getInputPorts().get(0).getInputObject());
+ Assert.assertNotNull(node.getInputPorts().get(1).getInputObject());
+ Assert.assertNotNull(node.getInputPorts().get(0).getEdge());
+ Assert.assertNotNull(node.getInputPorts().get(1).getEdge());
+
+ Assert.assertEquals(1, node.getOutputPorts().size());
+ Assert.assertEquals(1, node.getOutputPorts().get(0).getOutEdges().size());
+ Assert.assertNotNull(node.getOutputPorts().get(0).getOutEdges().get(0));
+ } else if (wfNode instanceof WorkflowOutputNode) {
+ WorkflowOutputNode workflowOutputNode = (WorkflowOutputNode) wfNode;
+ Assert.assertNotNull(workflowOutputNode.getInPort());
+ }
+ }
+
+ }
+}
\ No newline at end of file
[42/50] [abbrv] airavata git commit: Renamed simple-workflow module
to workflow and created a new workflow-core module which will keep all the
core code
Posted by sh...@apache.org.
http://git-wip-us.apache.org/repos/asf/airavata/blob/509f2037/modules/workflow/workflow-core/src/test/resources/ComplexMathWorkflow.awf
----------------------------------------------------------------------
diff --git a/modules/workflow/workflow-core/src/test/resources/ComplexMathWorkflow.awf b/modules/workflow/workflow-core/src/test/resources/ComplexMathWorkflow.awf
new file mode 100644
index 0000000..4ffcad0
--- /dev/null
+++ b/modules/workflow/workflow-core/src/test/resources/ComplexMathWorkflow.awf
@@ -0,0 +1,465 @@
+{
+ "workflow": {
+ "version": "0.11",
+ "graph": {
+ "version": "0.11",
+ "id": "ComplexMathWorkflow",
+ "name": "ComplexMathWorkflow",
+ "description": "Sample workflow description",
+ "node": [
+ {
+ "id": "Add",
+ "name": "Add",
+ "inputPort": [
+ "Add_in_0",
+ "Add_in_1"
+ ],
+ "outputPort": [
+ "Add_out_0"
+ ],
+ "controlInPort": "Add_ctrl_in_0",
+ "controlOutPort": [
+ "Add_ctrl_out_0"
+ ],
+ "x": "247",
+ "y": "106",
+ "type": "ws",
+ "Application": {
+ "description": "Add two numbers",
+ "name": "Add",
+ "application": "Add_6c295199-f376-48af-b331-c83b2cf0fe9e",
+ "Input": [
+ {
+ "description": "Add operation input_1",
+ "name": "x",
+ "defaultValue": "2",
+ "dataType": "STRING",
+ "inputOrder": 1
+ },
+ {
+ "description": "Add operation input_2",
+ "name": "y",
+ "defaultValue": "3",
+ "dataType": "STRING",
+ "inputOrder": 2
+ }
+ ],
+ "Output": [
+ {
+ "description": "Result",
+ "name": "Result",
+ "dataType": "STRING"
+ }
+ ]
+ }
+ },
+ {
+ "id": "Multiply",
+ "name": "Multiply",
+ "inputPort": [
+ "Multiply_in_0",
+ "Multiply_in_1"
+ ],
+ "outputPort": [
+ "Multiply_out_0"
+ ],
+ "controlInPort": "Multiply_ctrl_in_0",
+ "controlOutPort": [
+ "Multiply_ctrl_out_0"
+ ],
+ "x": "287",
+ "y": "232",
+ "type": "ws",
+ "Application": {
+ "description": "Multiply two numbers",
+ "name": "Multiply",
+ "application": "Multiply_ccc3b4e6-8c5c-4b44-bdfa-b267337fce97",
+ "Input": [
+ {
+ "description": "Multiply operation input_1",
+ "name": "x",
+ "defaultValue": "4",
+ "dataType": "STRING",
+ "inputOrder": 1
+ },
+ {
+ "description": "Multiply operation input_2",
+ "name": "y",
+ "defaultValue": "5",
+ "dataType": "STRING",
+ "inputOrder": 2
+ }
+ ],
+ "Output": [
+ {
+ "description": "Result",
+ "name": "Result",
+ "dataType": "STRING"
+ }
+ ]
+ }
+ },
+ {
+ "id": "Subtract",
+ "name": "Subtract",
+ "inputPort": [
+ "Subtract_in_0",
+ "Subtract_in_1"
+ ],
+ "outputPort": [
+ "Subtract_out_0"
+ ],
+ "controlInPort": "Subtract_ctrl_in_0",
+ "controlOutPort": [
+ "Subtract_ctrl_out_0"
+ ],
+ "x": "426",
+ "y": "136",
+ "type": "ws",
+ "Application": {
+ "description": "Subtract two numbers",
+ "name": "Subtract",
+ "application": "Subtract_f1b296ad-b3bd-4a1b-82bc-407725bbdb96",
+ "Input": [
+ {
+ "description": "Subtract operation input_1",
+ "name": "x",
+ "defaultValue": "6",
+ "dataType": "STRING",
+ "inputOrder": 1
+ },
+ {
+ "description": "Subtract operation input_2",
+ "name": "y",
+ "defaultValue": "7",
+ "dataType": "STRING",
+ "inputOrder": 2
+ }
+ ],
+ "Output": [
+ {
+ "description": "Result",
+ "name": "Result",
+ "dataType": "STRING"
+ }
+ ]
+ }
+ },
+ {
+ "id": "Add_2",
+ "name": "Add",
+ "inputPort": [
+ "Add_2_in_0",
+ "Add_2_in_1"
+ ],
+ "outputPort": [
+ "Add_2_out_0"
+ ],
+ "controlInPort": "Add_2_ctrl_in_0",
+ "controlOutPort": [
+ "Add_2_ctrl_out_0"
+ ],
+ "x": "475",
+ "y": "302",
+ "type": "ws",
+ "Application": {
+ "description": "Add two numbers",
+ "name": "Add",
+ "application": "Add_6c295199-f376-48af-b331-c83b2cf0fe9e",
+ "Input": [
+ {
+ "description": "Add operation input_1",
+ "name": "x",
+ "defaultValue": "2",
+ "dataType": "STRING",
+ "inputOrder": 1
+ },
+ {
+ "description": "Add operation input_2",
+ "name": "y",
+ "defaultValue": "3",
+ "dataType": "STRING",
+ "inputOrder": 2
+ }
+ ],
+ "Output": [
+ {
+ "description": "Result",
+ "name": "Result",
+ "dataType": "STRING"
+ }
+ ]
+ }
+ },
+ {
+ "id": "x",
+ "name": "x",
+ "outputPort": [
+ "Input_out_2"
+ ],
+ "x": "97",
+ "y": "88",
+ "config": {
+ "description": "Add operation input_1",
+ "dataType": "STRING",
+ "value": "2",
+ "visibility": true
+ },
+ "type": "input"
+ },
+ {
+ "id": "y",
+ "name": "y",
+ "outputPort": [
+ "Input_out_3"
+ ],
+ "x": "97",
+ "y": "194",
+ "config": {
+ "description": "Add operation input_2",
+ "dataType": "STRING",
+ "value": "3",
+ "visibility": true
+ },
+ "type": "input"
+ },
+ {
+ "id": "y_2",
+ "name": "y",
+ "outputPort": [
+ "Input_out_4"
+ ],
+ "x": "105",
+ "y": "311",
+ "config": {
+ "description": "Multiply operation input_2",
+ "dataType": "STRING",
+ "value": "5",
+ "visibility": true
+ },
+ "type": "input"
+ },
+ {
+ "id": "Result",
+ "name": "Result",
+ "inputPort": [
+ "Output_in_2"
+ ],
+ "x": "729",
+ "y": "248",
+ "config": {
+ "description": "Result",
+ "dataType": "STRING"
+ },
+ "type": "output"
+ }
+ ],
+ "port": [
+ {
+ "id": "Add_in_0",
+ "name": "x",
+ "node": "Add",
+ "type": "ws",
+ "dataType": "STRING"
+ },
+ {
+ "id": "Add_in_1",
+ "name": "y",
+ "node": "Add",
+ "type": "ws",
+ "dataType": "STRING"
+ },
+ {
+ "id": "Add_out_0",
+ "name": "Result",
+ "node": "Add",
+ "type": "ws",
+ "dataType": "STRING"
+ },
+ {
+ "id": "Add_ctrl_in_0",
+ "name": "control",
+ "node": "Add",
+ "type": "control"
+ },
+ {
+ "id": "Add_ctrl_out_0",
+ "name": "control",
+ "node": "Add",
+ "type": "control"
+ },
+ {
+ "id": "Multiply_in_0",
+ "name": "x",
+ "node": "Multiply",
+ "type": "ws",
+ "dataType": "STRING"
+ },
+ {
+ "id": "Multiply_in_1",
+ "name": "y",
+ "node": "Multiply",
+ "type": "ws",
+ "dataType": "STRING"
+ },
+ {
+ "id": "Multiply_out_0",
+ "name": "Result",
+ "node": "Multiply",
+ "type": "ws",
+ "dataType": "STRING"
+ },
+ {
+ "id": "Multiply_ctrl_in_0",
+ "name": "control",
+ "node": "Multiply",
+ "type": "control"
+ },
+ {
+ "id": "Multiply_ctrl_out_0",
+ "name": "control",
+ "node": "Multiply",
+ "type": "control"
+ },
+ {
+ "id": "Subtract_in_0",
+ "name": "x",
+ "node": "Subtract",
+ "type": "ws",
+ "dataType": "STRING"
+ },
+ {
+ "id": "Subtract_in_1",
+ "name": "y",
+ "node": "Subtract",
+ "type": "ws",
+ "dataType": "STRING"
+ },
+ {
+ "id": "Subtract_out_0",
+ "name": "Result",
+ "node": "Subtract",
+ "type": "ws",
+ "dataType": "STRING"
+ },
+ {
+ "id": "Subtract_ctrl_in_0",
+ "name": "control",
+ "node": "Subtract",
+ "type": "control"
+ },
+ {
+ "id": "Subtract_ctrl_out_0",
+ "name": "control",
+ "node": "Subtract",
+ "type": "control"
+ },
+ {
+ "id": "Add_2_in_0",
+ "name": "x",
+ "node": "Add_2",
+ "type": "ws",
+ "dataType": "STRING"
+ },
+ {
+ "id": "Add_2_in_1",
+ "name": "y",
+ "node": "Add_2",
+ "type": "ws",
+ "dataType": "STRING"
+ },
+ {
+ "id": "Add_2_out_0",
+ "name": "Result",
+ "node": "Add_2",
+ "type": "ws",
+ "dataType": "STRING"
+ },
+ {
+ "id": "Add_2_ctrl_in_0",
+ "name": "control",
+ "node": "Add_2",
+ "type": "control"
+ },
+ {
+ "id": "Add_2_ctrl_out_0",
+ "name": "control",
+ "node": "Add_2",
+ "type": "control"
+ },
+ {
+ "id": "Input_out_2",
+ "name": "Parameter",
+ "node": "x",
+ "type": "systemData"
+ },
+ {
+ "id": "Input_out_3",
+ "name": "Parameter",
+ "node": "y",
+ "type": "systemData"
+ },
+ {
+ "id": "Input_out_4",
+ "name": "Parameter",
+ "node": "y_2",
+ "type": "systemData"
+ },
+ {
+ "id": "Output_in_2",
+ "name": "Parameter",
+ "node": "Result",
+ "type": "systemData"
+ }
+ ],
+ "edge": [
+ {
+ "fromPort": "Input_out_2",
+ "toPort": "Add_in_0",
+ "type": "data"
+ },
+ {
+ "fromPort": "Input_out_3",
+ "toPort": "Add_in_1",
+ "type": "data"
+ },
+ {
+ "fromPort": "Input_out_3",
+ "toPort": "Multiply_in_0",
+ "type": "data"
+ },
+ {
+ "fromPort": "Input_out_4",
+ "toPort": "Multiply_in_1",
+ "type": "data"
+ },
+ {
+ "fromPort": "Input_out_4",
+ "toPort": "Add_2_in_1",
+ "type": "data"
+ },
+ {
+ "fromPort": "Add_out_0",
+ "toPort": "Subtract_in_0",
+ "type": "data"
+ },
+ {
+ "fromPort": "Multiply_out_0",
+ "toPort": "Subtract_in_1",
+ "type": "data"
+ },
+ {
+ "fromPort": "Subtract_out_0",
+ "toPort": "Add_2_in_0",
+ "type": "data"
+ },
+ {
+ "fromPort": "Add_2_out_0",
+ "toPort": "Output_in_2",
+ "type": "data"
+ }
+ ]
+ },
+ "image": "iVBORw0KGgoAAAANSUhEUgAAA0cAAAFwCAYAAABzWgC/AACAAElEQVR42uydeXiV9Zn+c80f06lO\r\ntS6t1g2r7YztVGxnulg70KHa/lqnLd0UtLSWtjJqXVJFkVZkRyMURFBREFBAkLCFPWQBw74EspKE\r\n7PtKNpaQ855znt93fd/v+573hCBbQu5c1+c6yCL2cELPJ/fz3E9MRUUJAQAAAAAAAEBfJwZPAgAA\r\nAAAAAABAjgAAAAAAAAAAcgQAAAAAAAAAkCMAAAAAAAAAgBwBAAAAAAAAAOQIAAAAAAAAACBHAAAA\r\nAAAAAAA5AgAAAAAAAADIEQAAAAAAAABAjgAAAAAAAAAAcgQAAAAAAAAAkCMAAAAAAAAAgBwBAAAA\r\nAAAAAOQIAAAAAAAAACBHAAAAAAAAAAA5AgAAAAAAAADIEQAAAAAAAABAjgAAAAAAAAAAcgQAAAAA\r\nAAAAkCMAAAAAAAAAgBwBAAAAAAAAAOQIAAAAAAAAACBHAAAAAAAAAAA5AgAAAAAAAADIEQAAAAAA\r\nAABAjgAAAAAAAAAAcgQAAAAAAAAAkCMAAAAAAAAAgBwBAAAAAAAAAOQIAAAAAAAAACBHAAAAAAAA\r\nAAA5AgAAAAAAAADIEQAAAAAAAABAjgAAAAAAAAAAcgQAAAAAAAAAkCMAAAAAAAAAgBwBAAAAAAAA\r\nAOQIAAAAAAAAACBHAAAAAAAAAAA5AgAAAAAAAADIEQAAAAAAAABAjgAAAAAAAAAAcgQAAAAAAAAA\r\nkCMAAAAAAAAAgBwBAAAAAAAAAOQIAAAAAAAAACBHAAAAAAAAAAA5AgAAAAAAAADIEQAAAAAAAABA\r\njgAAAAAAAAAAcgQAAAAAAAAAkCMAAAAAAAAAgBwBAAAAAAAAAOQIAAAAAAAAACBHAAAAAAAAAAA5\r\nAgAAAAAAAADIEQAAAAAAAAB
AjgAAAAAAAAAAcgQAAAAAAAAAkCMAAAAAAAAAgBwBAAAAAAAAAOQI\r\nAAAAAAAAACBHAAAAAAAAAAA5AgAAAAAAAADIEQAAAAAAAABAjgAAAAAAAAAAcgQAAAAAAAAAkCMA\r\nAAAAAAAAgBwBAAAAAAAAAOQIAAAAAAAAACBHAAAAAAAAAAA5AgAAAAAAAADIEQAAAAAAAABAjgAA\r\nAAAAAAAAcgQAAAAAAAAAkCMAAAAAAAAAgBwBAAAAAAAAAOQIAAAAAAAAACBHAAAAAAAAAAA5AgAA\r\nAAAAAADIEQAAAAAAAABAjgAAAAAAAAAAcgQAAAAAAAAAkCMAAAAAAAAAgBwBAAAAAAAAAOQITwQA\r\nAAAAAAAAcoQnAQAAAAAAAAAgRz2KkpIiWrlqFU2dOpXGjx9P48aNA+ed8TT5lTha8MECys4+hNch\r\nAAAAAADkCFx0KivEm/Wk5BRqammjU1aYQdTBOBkgOqE41knUfkrSxmjtIGphNJ8kOspoYjSeIKo/\r\nTlR3jKiWUdNOVK2oaiOqUJS3EpW1EJUySpqJihVFR4mONBHlN0oON0hyGTn1RNmMLEZmHVFGLdEh\r\nxsEaonTFAca+aqK9VUR7Kol2VUh2MnaUE21npDE+LiPaxiklSuWUEKUwkhlJxURbiogSGZsLiTYe\r\nYbDH9exxXYEkIZ9oDSePaDVj1WGilYwVjPhcouU5RB8xlmUTLWV8yFiSRbQoU/JBBtHCQ2Gat7uN\r\nXl++gyZOmkSZmQfxWgQAAAAAgByBi5cYFdOUKVMoOzuXrBBRZ1DC5Yhz0pJidFzR3inhciTEqEOJ\r\n0QkpRg3HlRwpuCDZcsSo9JOjFilFhUqMhBwp8hqlGAk5apBylO2RI44QIyZF+6oMOWLsrjTkqELK\r\nkRAkJUZbFS4xKlZixNik5GiDQsvR2gJHjFxylCvl6CNDjj7MkrjkiLFQCBLR
Asbs9blCUJEgAQAA\r\nAABAjsBFYtWqVbR9+w4KhknIUSDkyJFOjjjHO2VyxGntIjVqMJKjOpUc1RhiJOSoVcqRNzUqVIJU\r\n4E2OlCBpMcqqk3LEOWgkR1yO9htiZMtRpSc5KpPJEWermRoVe1IjLUeFUozWF0jW5ksSzOQozxEj\r\nOzXKkanRUpUaLc6UfKCSo/cNOZrPmLNsDS1evAivSwAAAAAAyBG4GEybNo2aW9ooGCJXcsQxx+r8\r\nUiMtR00+yVG9So1qjNE6MzUqNVIjMU5njNRxtCDlNbrH6iJG6mqdcToxUlcl0WN1Wo52qeRohxqr\r\n86ZGOjna4pccFTpjdZy1BW4xWukdqVOYcqTH6har9Oh9JUdCjA4SvcfZ1UBxca/idQkAAAAAADkC\r\nFwNevhAMhYUYmcmRnRpZUozMfSOeGrWe8iRHSo70zhFHpEbH3ON0nLJWiU6OzLE6nRwVqJG6PG9q\r\nVO+kRnrfiAsST43M5GivSo30WJ133+hjc9+oVKZGEclRodo5KnSP1CXkOztHOjXScrRCJUfL1Ugd\r\nFyRTjDhajBYqOeJwOZqbHhajdWvXrqGDB/fj9QkAAAAAADkCFxL+ZjykR+r0vpGWI3PfqNOdHLWq\r\nfSN758gsY1CpUZf7Rq3u5EiP1R056k6NvPtGdnJU5+wb6bE6Lkb7FHsqo+8bmSN15lhdUnHkzpHf\r\nvpGWo9V5HjnKdZIjvXO0NNvZN1pslDF4R+p4ejQvncSfx/vvLxRs25aC1ygAAAAAAOQIXEg58o7U\r\neeVIN9Ud02J0ykmOTjdSV22M1FUqMSr3JEdmGYM3NYpoqquLTI7Suxqpq+jevlGKT0udLmPY6Nk3\r\nSjD2jXgRg7eMYbmnpY5j7xtl+MiRGqvzyhEHCRIAAAAAAOQIXEg5ilLG0OHTVKflyC818pYx+CZH\r\nZhmDuW/UHFnG0GVyZ
LTUaTnar9rquBh5m+p2Vjhjdbqpjld5R63w7iI5Ek11nrG6iApvhU6NXMlR\r\npnusbr7CT474iB1epwAAAAAAkCNwgZOjgLeMQctRp3PbyFXG4JWj40565B2rqzBTI58yBrvG+2jk\r\nvpFdxlDnX+GdboiReePILznaHq2ModhTxlDorvFeX+C5ceQtY8j1lDFkOyN1HxpFDNHKGLgYzfWR\r\noyVL0F4HAAAAAAA5AhctOTJTI/v4q09T3dFoNd7e+0ZtUe4bNfvvGxV4bhz5HX/dtCKOvnnPYPqf\r\nX0+gj0p4GUMHvfH3EfSle2Lp/Vx3jbfffSMzNepOjbedGuU7qVG0kTpz30gLki5jiEiNDqrU6KC/\r\nHHHwOgUAAAAAgByBCyRHrpE6T4V3xL5Rh3HjyHMA1hQjv32jCiVG3jIGvnPE06Mjxr7RYWPfyHvf\r\nSJYxNNAz34uhmJgY+vKj8bR4SZz49vdfTXe11O30aarbZpYxlMqROlHjXeROjuwKb71vVODeN/I2\r\n1ZllDObOkd43MlMjs4zhvYO6rQ5yBAAAAAAAOQIXX448I3UdxkidlqP2TqeMwW+krt4zUldjpEZ+\r\nTXUcc6SuwHvfqFHuGkUkR7qpLieFvhkjBUlwz0za7Llv5B2pi9ZUl+zdN/I5/trdprplxgFYs8Lb\r\n21S30JCjaGN1kCMAAAAAAMgRuEhypMsYzOOvuoxBp0bNPqlRgxIkXcRQ41PGUO5XxnBUHX9VaDHy\r\nLWOoiyxjWPbqMFuOntvcbo/T+ZYxGPeNeHqkpcguY4iyb6TH6vhI3VqVGukyhi5Toyx3jbdoqvMZ\r\nq9OpEeQIAAAAAAByBHqAHPnVeJ/03DcyK7wj5Oh45I0jLUhd3TfyjtR5kyO7jMF7/JXLUd4e+okr\r\nOYqj9V0kR3qszkyN7JE6n32jTZ7kaK1uqos2Umc21fnsG5lNdX4jde
9CjgAAAAAAIEegB+0cmalR\r\np3vfyNVUd9Jz4+iEM1ZX4yliqPRrqmt2N9UVHo28cZTjc9+Ip0Z8rO5gTQP97cdcigbRPzan0UNK\r\nkL4/fo+rqY6L0Q6f1Ci1tIsyBm9T3REjNcp3p0beMgZvU52u8XaN1Pk01XHePdDL5agonxr/+Adq\r\nvPIKqmFUsG/z78PnGQAAAAAA5KjXyFFEGUOU46/2jaOTEnPnKCI18ghSxPFXU5CMnaP80xx/1ftG\r\nCXNHCBkavrBI3DjalrzATpDGb+9wUqMK/+Ovuowhxa+MocgoYzjiHH9dG23fyDNWp5vqPjR2jj7w\r\npEau+0aXSHLUOPwRamLPfw2jnFHEyOeChM8zAAAAAADIUa+RI+99I2PfqKsab+9InRYkLUaupjqf\r\nGu+ioz5lDE3OOJ2rqc5z/PWgceNon7pxJO4bVUW/b2QnR6WRyVFEhbfPfSPvvtEqnxtHthjp+0ZG\r\nU11XydElIUdXXkG1SowKGRmMdJ4g4fMMAAAAAABy1FvkKBjylDEYyZEoYzBSo5YoZQz1RhlDraeM\r\noULVeJcbLXXFhhzpkTqzjOGwt4zBK0c1/LaRPP6qD8D6lTHYyZFiW5kzVqfH6XxH6vxuHBVEjtV5\r\n7xvxkbplKjXSyZE+/hqtjEHLUW8vZOCjdDox4mK0n7Hriito1apVNHXqVBo/frz43wfOL/x5njo1\r\njpYvW0jZ2Yfw9xwAAAAAOQJnIkehMIlDsN4bR6KM4ZRTxmDuG3mPvzZEuXHEpeh0x1/1Adh8JUhm\r\ncpQTRYx0amTLUXXXyVGaJzVK9e4bFUdPjswbR3Zq5JGj+FynjCEiOcpy3zgyR+rMprpev3P0xz/Y\r\niREXo52Mxd/5DqWkpFBbWxuFw+xFho/z/sGfZ/5879ixg6ZMnkSZmQfxdx0AAAAAOQLdlaNwkL1x\r\nDTJ7CbZQ2Dr
KYJZiNVI4UM+oYzALCdRSuLOaUUXhUxWMMkYpo4RCHUUU7ihkHKHQyXwKn8xjHGbk\r\nUuhEDoVPZDOyKHQ8g8LHD7HHdAod28/Yx9hLofbdjF2MnRRq284et1O4PY19exuFWrcyUhkpjCTG\r\nFgq1bKZg80bGBgo1r6fg0bWMBPbtBPa4mrGKQkdXUrApnrGcsYxCTUsp2PghYzEFGxZRsP59xkLG\r\nArLq57PH9xjzyKp7l4J17zDmULD2LbJqZ7PHWYw3yKp5nYI1M8iqns6YpphKVlUc41XGK2RVTmZM\r\nYkxkjCerYizjZcYYssr/zvibIFD2ImMUWWUvUKB0JOM5skqf7d1yVJhHBUyQDlx5hUiMlt5zD+Uc\r\nOgRbuYgfubm54jWFBAkAAACAHIFuyhEF25kQMTmyWhjNTIYcOSIuR501SowqGVqMFB0l7LGYCZKU\r\no3BHARMkKUeB9hxqazxMTXWM2lxFjkE2I0tSk8nIUBwUNFans0dG9QH27f3skbOPfXsve+Tsocaq\r\n3dTEaKzaxR53Chord1BT5Xb2mMYe08RjY+XHjG2Siq2KVEaKpDxJsYWRaLCZsYkayzayx/XUWhFP\r\np6qYLFX/wxajYDUTo8op7NtMjKq0GE2kQMU49jhOyFGg/CVbjrgYWeWOGFllz7HHvzI5+uslU+XN\r\nR+l4coGPi/+RnJhAixcvwt93AAAAAOQIdE+O/FMj4slRZ61IjrQcERekU+UyNeJi1FHskxrlUXN9\r\nPhUXFVJRUdElSAE1lSUwEXqNCdJrPqnRBCZEPDUa56RGruSIyVHZKCZJz7NHJkcqNQqUxF4ycjRt\r\n2jQx2oWPi//R2tJIcXGv4u87AAAAAHIEujVWZ7UyoozUddYwIWJidEqnRhVKjsqijtRxMbo0pchN\r\nU9lqJUZTJOZInUeOAkZqpMfpuBjpkTqeHAVKnrlk5IiXAmDH
qOfsIPHX1dq1a+jgwf34ew8AAACA\r\nHIGukyM5TkdMjLgchQMNESN1ZO8albvG6cL2OB2DyZF1LK9HJUZ7E5fR9Lg4mj57PqWmn1tpKy4q\r\noFOVM2RqJORIp0bjFGOZFOnk6CUnNSrXqdHz9q6RVRrLuHTkSLyu8NFjPszX1bZtKfi7DwAAAIAc\r\ngahvYnVqpHaNyGrwjNOpfSMtRx2yiIGP1IWM1Ch08jC1NXVfQDJTl1Hs4Lvt460xMXfQffcNp/lp\r\nuedEXjI3xMl/79330R3scUzCdnrn8cH0+OzEcyZILeVLjZG6iRFFDHrXaMCJWyip5iElRmZy9KzY\r\nNeIjdYGSpyFHPfCjLGUOjRgxgmZuKjqrn9NT5IiDBAkAAACAHIEukiMuRxQlNbIb6jqNXSNRwuCM\r\n1IXVSF1TXffkKH3FGFuIxryzjBJWLKK4MY8LiYldkX5OxCVhDBevUbTX/r5MmnhHDN0xKuGcyVFj\r\n2WoKulKj8VKOKse5WupiOtn/1mMxNPDozZRUOUSlRs+qIoZYMVIXQHJ0QT6K4mPVa28Y7Wk//c9P\r\nnzlY/PxBM9PP6uf0JDniI3b4+w8AAACAHAHfnSNHjOwSBiFGvMLb3DcyU6PIXaPQidxuytEuGnWH\r\nFKPZiZ6UKD+XcvPPjbgkTryPYu6YSLnncWyvsTRBpka8pa5iQmR9d8VLFCgbLcQopo3RxKiPoQGV\r\nN1Fy2YN2EQMfqQuUPAU5Ov85EI22k8oYGrEk77S/Im/BMPFzB3chPt35OT1JjpYsQXsdAAAAADkC\r\nUeWIj9SFA2qkLlDn3DU6VekpYTDlqMhOjWR9d/fkKDdRjrvdN+Y0CU5mIo0Z6ozd3TF0DCVmOinQ\r\nbPZjw+MW0fwxg50UalGa+PENcUOdX8cYGrfB/jVDp2+wf4/8vQkUe59+s3wfjRrzON199+OUmNtd\r\nOVpj3
DXScuQuYgiU/80RowZGFaOCURRDA4tuoqTiX4uROsjR+f9o3jNT/Fn3H9Rf/ZmPZrrk/uio\r\nTqPRgwfJnzc4lkYMiokQn+78nJ4sR731dQUAAABAjsAF2DlSYiQa6szkSI7U2fXd3tToZIGrvpvf\r\nNuqOHGVumCjeSE7ckNnFz0ujWPHmdSgt2pBGaYnzaahIm2IpLV/KUZyWGiYz81csolH3yR/fxX+P\r\nXRto4vA72D8PZz+2gjakpsuxuruZLNlSlkaPq99jfmIapa6YTfcpSVqReaZy5KRGooShXDfUyZY6\r\nnRiZYhRzhJHLyIqhAZk3UHLBLyBH5/WjnZYMU0LEXsOxSp7j9jQbZpRFw9T3D4qdSfFzRtuSbYtP\r\nd34O5AgAAAAAkKPeLEcNrvpue9fIVd/d9Uhd6EQOk6O80ydHqighrgs50gI1JiHT+HX6+5TocBm6\r\nb6K9U5QYxxOku22xiRyrk3J0t5Kj6L/H3ZRwJnKkR+oibhu9ZNd3CzGqZpQbYpQjxSjmAJOjQzdQ\r\nUr6UoyFDhtBDDz1Ew4YNo9///vf0ta/9B33729+ie+/9AQ0e/HN65JHf01//+gxNmjSB3n33bVq3\r\nbjUdOrQfcnSaD6ssQfx5D1uQ5xqFixm2hDrUz2lIUyUeg+KoQX1f1pzBLvHpzs+BHAEAAAAActRr\r\nx+rMw6+GHJ3ya6gzU6MCu4iBp0bdlaPMBCklo7ooXshUkrIs3fm+/LR33HLERWeiMyK3gctQzH22\r\n2GyYeLeQo8wu5egOWrQr3xj5+wRyVOndNXKSo4Co7x7tJEbFbjEakHkjJRX8kgIlT1Kg+C/iz2Pe\r\nvLlMet6hOXPepjffnE2bNq2n+PhltHDhezRz5nQmRePpmWeeot/9bhj96Ef3Uf/+/enqq6+myy+/\r\nnO666y4aOnQIvfLKZEpOToQcGR9pcYNUwtOfBg0aRP
3t3aP+lFBmuYoVYmImGOLj3ifqzs+BHAEA\r\nAAAActRrk6NG39TIfdvIqO8+qW8bFbjEKHwim8nR4dMKRf6ud8QeUMzgOENcvAI1Ro3e5XrExSNH\r\nxt7SJ5MjLmlOcrRi4mDXv6N7cjSRAvZtI6ehzr5rVDYqIjEacPhGSi78tShisEqeEmIUKHnirN7E\r\nZmdn0Jo1K4UYDRnyIPXr14++8IUv0J///EdKTU3q23LUkS5H4QbHMumcwyRzpniMHSx3jwbFpck0\r\nackIlQrNJFlkZ9Gm0YNc4tOdnwM5AgAAAADkqLcmR0Z9t6uIQYzU+ZUw8OTIqe/mI3VhW47yuiUV\r\ny0apooXBYyghbS9lZqbTrtQEmh47nOK4/OQm0lD+4/eNoQ17Mylz7wa1UzRUlSVEl6MV3ZSjovxU\r\nGi4SgLtpVFwcPW4UM3RfjlZH1neXv6T2jeRIHb9rpMVoQP5NlFz0AAVK5V2jgGqp48mRVfKXc/4m\r\ndtu2ZIqNfZquvfZa+uUvf0HFxQV9Uo50ffecrA63M2XNsWu90zv46F28vT80KHYCTRjRP2KfqDs/\r\nB3IEAAAAAMhRb02OXKlRjXP0VRcxaDk6VezcNeooEEdfhRidzBHJUehEFjXVHu5mDXY+JUyPlQmS\r\ni/vsI7C5actUCYPijuG0yD4QGylHcudoMCXkGrJ0dxdyxEnfQGOGD6a777iDBo+aTYvihrv2lrol\r\nRz5HX2VqJEfquBwNLLyZkouHMBl6jr25flbdNpINdZYYqXuC8fh5exObn59Dt9xys3ge+bf7lhw1\r\n05xB7h0h56OB4lTT3OhNsrcuK94pWIgZNJpmjlb7RHMc8enOz4EcAQAAAABy1CuTI+/RV++uUZk4\r\n/Boy9o2cXSMnNQqdyDwDOdJ3jTJp165dtHfvXtqbnusrUZmZmYL883CnKD/X/Xu9MzzGczi2m3Lk\r\
nOfoaMMTIKnuBSdFIcfTVUodfeXJkeVKj8ylHnMqCXJpy59fog6/cQU2zXhf/3Lfa6s6gvKGjndqb\r\nm6njLH8O5AgAAAAAkKNeKEciOdIjdWZ9t19qxO8anThsy5FMjbKZIHE5yj1vB1fPPek0RlSBD6bH\r\nY2NpsEqpHn8n7QyOwK6igHH01azv5vtGWo6ssudlaiTkyEmNAkZqdD7lqHbDWrKuu47Y/0Ab/s/8\r\n+yFHl/4H5AgAAACAHIFuj9U5qZG7hKEsMjUy6rvNIobQ8UwKH8+go3W9SY6KaNeGRRQ3cQzFMjmK\r\nHTWRliWmn9GvbyxdKVKjgFHfHZEalY1UyZGSo5JYp4jBSI0CxY+dlzexPCHyipEpSOcjQYIcQY4A\r\nAAAAADnqdYwfP55CnbVOEUOnLmIot8WIN9TZJQwdniKGk1KOwieymCBlUGtjdq+So7OlpfQDo777\r\nJXdLXfkoJkbPM0EayXhOjNOZu0a8oU7sG5XI5OhEwRPn5U0sH6HzEyMN//HzkkhaLYxmIusohQPq\r\n0LDVoPbb5KFhcr3m3AUgIfG6k1Lu1Mbnu6Q8rBLL8IkM9vo7SKFj6YwDjP0Uat/LHvcwdrNv72Ts\r\norB43E6htjTGx4xtFGpNVSRTsGULhVoSGZsp2LyJQs0bGRvYt9exx7WMBAoeXcNYxVhJoaMrKNgU\r\nT6Gm5ezxIwo2LmMsZXxIwYbFjEWMDyhYv5A9chawb79Hwbp5jLns2++yxzmMtylY+xZZtbMZsyhY\r\n8wZZNa8LgjUzyKr+B2Ma+/Y09jiVrKo4xqsUZFhVUxiTRWuieW/LFHbIEQAAAAA5At1g6tQ4JjRH\r\njIa6KndLXYd7pM5MjcKqhIGnRnzfKHT8EAXaDlFxUWEfkaMC6ih/xTNSZ6ZGWo6ed/aNSp4RcmSV\r\nPu0Zqfs/KtjxPE2YMOGcv4lteWFkl3LEf/y8
JEfBVluO9KFh4s2InboVsUa93sxmRP26Y6+5U0Xs\r\n9XbEKAAx0sqT+rWXZaeWXI7CAi5H+yjMCLUzOWrfzb69i4nQDvbtHS4xCgopSnHEqHWLFKMWJkYt\r\nG5kUbRByFGpez2RIy9FqJkWrmQytZHA5Wi5hYhRqcsQo1LhYilHD+1KM6ucLLC5G9UyM6t5hIjSH\r\n/bOUI6v2TSZIHCZITI6CtTPZ4wxBsGa6lCMlRsFqLkfstVfJpWiSpELf2xpnC7soCIEcAQAAAJAj\r\n0D2WLl1MKUlr2ZtVuWsU+dV7o77bJzXib1D1V+7DTI5Cx9PpaF1Wn5CjptJ44/Crc9uI13dbriIG\r\nc9foGbuIwWyps4ofo4VzX6Fp06ZeMskRWS3u1CjQ4NltM15zne4xTinkfgUgh9Wem0wrw0LKndde\r\nyBSjY3vY426RGAkpssXISI3attpyFGpJYmxhYrSZPUo5CrXI1MgRozUuMQo1xYvEKCRSIyVGjUsk\r\ndmrE5Kh+geI9xjwmRDwxelcIUrD2bfb4lpKjWVKMamYy3KmRkxjJ1EjIEU+NuBhVTfIcIx7rGvOE\r\nHAEAAACQI9ANsrMPiTdOOZnb7dtG1FnuuW0k36CGvHeNDDkK2V+5TxdfueeCdOkmSAVKjJzRpYBo\r\nqBstUiNvS50eqdO7RnYRg7FrtGH5ODHiOHfu3HO/c5Sfc1F2jsJcjCwpRq6ROjs18runJVOjkM/r\r\nzrXjZr/uDtmpUUi99uyROpUayZG6ne7UqHWrS4zscbrWRCFGQTFKt54JkRYjJzUSI3VNeqTOSY24\r\nHIW0HGkxanifLCFFMjWyx+m4FInkSI/TvSlG6nhq5IzU8dRoujNSZ4zTucSIEdDjdKo1MVA+xh7z\r\nDJSNhhwBAAAAkCPQXTIzD9LkyZNoa8p6aqlnb0DFV+799o0KIlKjkLHvERZfuZc7H/wr94G2f
dTa\r\ncIiaajOoqUbD/rnmICOdGqsPUJNgv2KfYi9jDzVW7aYmRmPVLsZO9m3ODmqs3E5NjMbKNEFT5cfs\r\nkbONGiu2MlIVKYxkSXkSY4siUbGZsUlStpGxgbFesY4aS9cqEhhr2PetopayxXSqIk58hT5wutTI\r\n2DXS+0ZmanSi4Ckq2DmK3pvzinjzOnfuuxFvYHt1W50apyOrUTYidkoxooB3nK7cPU7XZVqpXnvH\r\n3a89R4yc1IjvGolxOi5Gbdt9xukYbXLXKNSaJEbq7NRI7RqFhCCtZULkjNOFhBwZu0bePSN7nM49\r\nUmep1IiP1FlCjpxdI9c4Xc1Me9eIj9MFq332jMQ43WRn1yhKamRVyNcl5AgAAACAHIEzTJAWL15E\r\ncXFx4o0UuDBMnDiRpk2b5psYcZYsWXTO/ox5gsRH6Pidoyeu+ux5vXPUr18xpSa3iD0jeUdLoosY\r\npByZY5ymjDu7Rjw1CvmM04lROqOEQYqRSo2MXSMxUqd2jcKiiMEsYXDvGpnjdGZqxMUopMfpVBGD\r\nlqNgo1nCoMbpzF0jOzVyj9PxXSO5Z/SWnRhZIjFSclQtd43M1ChY/ZqTGikxGnjyVkquG+46RCyT\r\nTJUaiRTzRcgRAAAAADkCn5S1a9f4vlEHFx7+Z3Gu/3xLSo6Ie04//vH/o3wmTOflkzumk3GMBg5o\r\npdSkRnuczkmNvJXxpW4x4ntGHc6uUUgUgOTaJSDuUc4uShiittOpPSOdGhm7Rs5I3Xr2uJZJkTNO\r\np1MjuWukSxiW+aRGZgmDs2ukixgkUo4iShi4GFVPt0sYLL9xOpUYxXTGUMyxGBrY3I+Sqx8RgmSP\r\n1FU4zYmQIwAAAAByBD4hBw/uh5j0EPifxfn4My4oyKVf/vIXdO2119IzzzxF27Yln2M5OsZoYzQx\r\n6pkkVVPqlipbjLz3tEJGauRtRtTjdC
G1axQxynlMilHIHqcz67vNkbptctdIjdMFeQGDEKNE33G6\r\n6O108VKOeGrUpFKjhiURu0ZCihoWkFVnpkbOOJ1up7NUCYOlxulkO51MjcRIXdVr7Nuv+csRE6OY\r\nNkYTo55JUuUtlFwxzE6N9P4b5OgMKcqnxj/+gRqvvIJqGBXs2/z78NwAAACAHPVRtm1LgZxcZPif\r\nwfn+c05NTaI///mP9IUvfIH69etHQ4Y8SFOmTKI1a1ZSdnbGWciRFqMGRhWjglFE3x9QzCSpLGpq\r\nJGu7zT0jlRjxXSNXQ90hVwEIH6fTqVGYy5FuqPPsGrnb6XR1t7xrJFMj2VAnRursXSM9UufcNXKP\r\n03WVGpmJ0VzVUDdHFDFYvrtGM3wb6uzqbvOmUeUER4waGFWMCkYRk6QiJkklD9s7cJCjM6Nx+CPU\r\nFBNDNYxyRhEjnwsSnhsAAACQo76dIPGxLr73Alm5MPDnmj/n5ysx6ork5ER65ZXJNHToELrrrrvo\r\n8ssvp6uuuoruvPNr9MMf3ku/+90wio19miZNGk8zZ06nhQvfo/j4ZbRx4zohWbt3b6cDB/ZSVtYh\r\nOzEyxSgmho/z5TKyaOCALNq6pTBi18ivoc5OjdRNI0eMDrpTo3ajulvsGamRunYpR0GVGgXtkTp3\r\naiRuGnVZ3R3vEiO7vtsnNbJ8qrt1CYNuqAt6qrv5OJ0jRlNlO525a1RpNtRNlMmRSoxMMYo5wshl\r\nZDFJyrqZko8MhRydqRxdeQXVKjEqZGQw0nmChOcGAAAA5AiAvktGxgFat241zZ07h0nRBCFHjzzy\r\nexo8+Od0770/oG9/+1tCnm677Yt04403iDG9K674jBKjaka5IUY5QoxiYg4wOcqg1MQC18FXs53O\r\nPPhq3jTy3tRypUb2OJ33rpHfrlGSKzESN43sg6/rXCN1ctfIuWskGuqaupMaqYOvRmI
k2unqdH33\r\nbM/BV/ddo2DUXSN106hivBSjaka5IUY5UoxiDsTQgIybKalAytGDDz5IQ4YMoYceeoh++9vf0i23\r\n3Exf+tLt4s/vW9/6Jg0cOIDuv/8n9Jvf/IqGD39EjFuOGfN3mj59mhDhtWtXCQEu6gPjZXyUTidG\r\nXIz2M3ZdcQWtWrWKpk6dKmr3UShz/uHP89TX4mj5soWiNAh/JwMAIEcAgN75yW0nRsUuMeKJUWri\r\nEeOmUfdSI3HbyEiNzOru0LG9PqmROU7nlqNgizNSF/SM0wWNhjozNXJuGvmN0+nUaFH0hrp61VBX\r\n+7brppGzazQjysFXKUZB0VBnpkayuttOjIrdYsQTo6QjD9m3tvgbzfnz59G8eXNFZfw777xNaWlb\r\nRVrIkz+eAH7wwQL2/W/RtGmv0dixY+i55/5Kf/rTcPrVr34hRLh//zvp+uuvp0996p/pmmuuEVL1\r\nk5/8mB57bATFxU1h4hBPOTkZl8Zr+I9/sBMjLkY7GYu/8x1KSUmhtrY2CofDhI/z/8GfZ/5879ix\r\ng6ZMniTOTuDvVwAA5AgA0AvlyJ0YDRyQR6lbSuRdo06/XaNCJkVOO11EdbeRGLlTo32qpW6vU93d\r\nvpPCdmq0rcvUKNjspEbBo+vsY68CJkfBJqe6WzfU2eN0Wo7UOJ1Vv1CmRg1ajpzq7sibRu5doyAv\r\nYqiebpcwyJE6/xIGAT/4WjEuIjEaePgWSi56WDTUWeWjKFD2PBOk58/5WB0fn+SJ4ttvz6YXXhjp\r\nGsW8+eab6Kc/vZ/9ni/T5s0beudruDCPCpggHbjyCpEYLb3nHso5dAi2chE/cnNzxesYCRIAAHIE\r\nAOiFciTFaOCAAtqaVBZx08hupzulxchdxKBH6sIqNTJLGOSh4f3ucbr23acpYTBSIyZHQXOkrnmj\r\nq7pb3zXSN414ahTyljDwPSNz
nK7+fZUaGUUMeqSuXrbUWbVGQ13NLNc4nazuNlIjQ4yCXjGqnEAB\r\nJkZCjpQYDchnUlQ8TLXTyRKGQNkLQoysspEXdOdo69ZkmjXrdXr44aF0++230ec+d6349kcffUjl\r\n5cW97rXMR+l4coGPi/+RnJgg7vHh71gAAOQIANCr6NdvO5OiSufg66lKmRqd8k+NnLtGsrpbipG8\r\naaTH6czEKKyPvRqpkX3XqC3yrpGrhEE11NmpkRqnCwnUnlGTvmmk6rsblxt3jSJTI2fXaAFZTIzE\r\nrpG6aWRFlDDwkTo5TmemRvyukV3dzUfqdEOdPU43yR6nsyrHiYOvAwuZFJXK6m5500hWd2sxCpQ+\r\nJ7iYhQy7dm2nv/3tRfrqV79Ct956qyj96E17S/xIMx/twsfF/2htaaS4uFfxdywAAHIEAOhd8Dfj\r\nXIyos5o9mmJUGnWcTpYwqJE6dfDVHqlTB19Dx9J9D746JQzb1b6RX3W3PPbqPvhqpEZH5cFXnRqF\r\nzOpuJUa+JQx6nM7eM5pv1He/a9w18pQwqF0jPU6nU6Ogd5yu0l3CIOSoYqykfAwF+MFX+66RHKez\r\njNQoUPpsj2mr43tJ3//+QFHgsXLl8l7xWualANgx6jk7SPy1fLEaPQEAAHIEADgLOapSYlTluWvk\r\nPfjqlxo51d364KvZTidKGI7pEgZn18iVGrVGjtPJ1MhoqFM3jUL2TaPV9jidc/B1uVHfvcyTGi1y\r\nNdSJg69qnM7yOfhqljAEjXY6nhpZZmpkVncbd42kGMnUyKoYw3jJSI1e9EmNniWr9K89rsp76tRX\r\nKSYmhpYtW9IrXsv46Dkf5mv5QtyCAwAAyBEA4Ny8oeSpkR6n63RSo1CUEoaQfew1x9VQx1MjMVLn\r\nTY1cu0ZKjNoNMTJTI3vPSI/TObtGQUOOQr4NdT4lDGZqpG4aWcbBVyFGuqFO1
Hf7V3e7UiMmRjI1\r\ninN2jYybRjI1GkcBIUZSjnhqFFByJHaNVGoUKBtpp0Y9UY44/NAwr37nDXl9WY6s9gYqKyqisrJq\r\nam7vOINf2UGbZo6mEbEzKa+jb8oRBwkSAAByBADoBTtHxZS6pd4YpzNSo1NmanQkakOdvmnkTY38\r\nxunCXRYxqJE6IzUK2jeNZAmD9+CrHqcLucbplBx5Dr7KsTr3wddujdOJ+m7PTaOoDXVmajSWCZGZ\r\nGo2WlI2yq7u5GFlKjAIlz/TYI7C8RpzXguflZfdBOWqnlJkjRIJmMjO9vdu/fs4g/msG0572vitH\r\nfMQOf+cCACBHAIAe3lbXyThGAwccpdTESv8SBiZGISM1EuN0J9WekdgxOqQeD0ZUdzt3jXb6ljAE\r\njeruoNozEqmRGqdz2ul0arRGjNQJOTJG6nzvGrnESKVGepxO7RnxxEiXMPiN1EXcNVLjdEG7hGGy\r\nnRoFKtwlDGKczrVnJFMjPlJnlbtH6gI9XI44Awf+N82ePbPPyVF71hwlRINpwaY02pOyieZMGE3x\r\ned2XowWD5a9Pj5ocWbRpwjD2c/rTkjzrfOZfF+j3iZSjJUvQXgcAgBwBAHq8HB1jtDGaGPVMkiqY\r\nJKnU6FSRrO42Guoi7hoZ43RhUd3tf9Mo7LdnFOWuUdDYNZJyJBvq/Mfpot00MkbqjF2jaKkRH6cT\r\n1d21s6LeNHKqu+OMxEilRlVOEUNAlzAwQdIlDHrXyJsa6XE6qzSW0bPlaPLkiTRkyIN9To6K4mOV\r\nHMVGjsV1FNGEYYNp0ODRlKV+LC9+Ag0aNIgmJBR55GgYJaQl0Ij+MUJOBo2YSdqv8pbEOqlU//40\r\neHQ8+1XtFD96GA0aNoFS9qhfN2wBtVvVtGTCCBrUX//8QRQ7M4EaTNdpzqMF5s+JGSRkzv/3uTBy\r\n1JNeywAAADkCAESRIy
1GDYwqRoW4fTRwQCGTpCOuhjq9a2SO08nqbtlOp3eNwsedIoaIu0bt7nE6\r\nu7pbNNMlGkdf1cFXTwmDefA11OTsGpmpUcgcp6s3Shh8xMhJjWaLm0ayvnuWXcTgumtk7xqZDXWT\r\nnHG6Cp0ayXY6Pk4XEFJkJEZiz+h5V0OdTo0CJU/3yDeUlQW51DTrdcp6aCi9dPtt4p/7khxZ1Zuo\r\nvzFON3rOJkdE2tNpcIx7ZC5rzmDx8wbNTPfIkWTwCCYt+t83eIGQk+q0Bfb3DRoxgebEp5PFx/GM\r\nXxfDhGvQiCXU3pFOw5jszFySQGlMtkYPkj8+Ia1BCVsWjbD//aNpwZIlNIH9nkuy2qP8PpAjAACA\r\nHAEAlBzJxMgUI34UNiYml5HFJCmDUjfn+KRG2fZInb5rFDIa6szUyClh2O4qYXBuGunUyN1Qp0fq\r\n7BKGZr8Sho98UiPvTSOdGqnq7jrPSF2dvms0y9VQ5z34Gl2M/BrqXrZH6pwShhcjShgCKjXiYhQo\r\nearHvaGs3bCWrOuuI/ZisOH/zL+/LxUytBdtUolPjD1it6mIaY0QFTUyZ8vRMClBPnI0M61a+csC\r\n+98jparD/jlzdARl/LrR8Vm+BRHV1WWUMHqQS8aKlqj9qP4TqNqnHCLy94EcAQAA5AiAS5iMjAO0\r\nbt0amjt3Dk2YMJaefPIJevjhoXT//T+he+75LvXvfyfdfvttdMMNNygxqmaUG2KUI8QoJuYAk6OD\r\nlLIpW900ynHG6U74t9NJ9tpFDGEuR23qrpEYqdsWMU4ndo1azZtGG4x2unWqgEHeNLKPvTa5ixjE\r\nwdeGJZElDEyOrNOM00WUMFTPUEUM01V191SJru723jVSu0Z6nE6UMHjFSFV3y3E6Xd3tFDHwkbqe\r\nJkc8IfKKkSlIPS1BOv9V3h2UlzLHSX1i4qjBR47yFkSTo2HOzpGVZf8
6KUeGQKU3R+wquTymo4ji\r\nBvePKIgY7JGj/rEJPqmQ3+8DOQIAAMgRAJcAhYV54lgnF6AHH3yAvv71u+jKK68Q9O/fn374w3vp\r\nd78bRi+8MJKmTJlEb701mz78cBFt2LCWUlK20K5d243EqNglRjoxkuN0h/13jU5kOKnRMaOhzr5r\r\npMToNNXdIWOczn3XSB58jdg1UuN0Qoyalrna6UJd7Bm5UiMhR3NcI3VmdTcvYQiaJQzVrzklDDo1\r\nMvaM5I6RGqkz7hrxIoauqrvN1ChQ8mSPekPJR+n8xEjDf7xvyZH2mjn2Hs+eGmesLl2YSAPNGRYT\r\nRY6cQgaraIn6dwxT4uOM0EUmR454mWN7Wn6yZsp/HjwnyyVnMf2ZvPk15yE5AgAAyBEAlwqJiRso\r\nNvZp+s53vk2f+tSnhBD99rcPUVzcFCFKPDU6s7E6d2I0cEAupWzOEyUMIbO6+0SkGIXUrlH06m7Z\r\nUCfru72pUaorNXKqu52bRlyMQmqczp0aaTHyNNR5UiNLNNQ543Q6NdI3jUR1d41MjYJmdbd508iu\r\n7zZG6nhipKq77Ya6CmfXSJcwBMpGy1E6PU7nKWEIlMS6UiOrh8lRC5PqruSI/3hfkCNeYjA4No7i\r\neVPdnk00YZhKbQbNpGYqo9F6h2dYLI0YFJnkuHaOhsVRCvt36D2hmGHxKt3poCVaqkbPpE1peWLn\r\nyF+OlPwMnkCbNjlJVv9hc4hP+lHzHuf7RvDfbw8lLJgpxwB9fx/IEQAAQI4A6EXwhIcL0c033yT4\r\nv/97lD74YAHl5+ecg50jKUYDB+RRamKBqu52t9OJ6m4xUpcld43skbqDnpG6vZEHX9v9bhr5H3wV\r\nJQwtG+27RnzXKGQXMUQ21GkxCkXbNdI3jezq7ncUaqTOc9fI3jWqkbtGdkOdGKczD77q+u4JnoOv\r\nOjFyN9Q5RQwe
OVKpkcWTo+InGX9BctQj5SjyxlH/YRMoXbUyZC0Z7Xx/7BxaEiflZdiCrIgEKHbE\r\nIOffM2wmFRnhTUP6AtfIXrM5jmdWyjXscQoXYvpT3II4+9fF7WlWO1IpFDvI/d88J6s9yu8DOQIA\r\nAMgRAL2ALVs20s9//jO6+uqr6ZFHfi9So3P9e/Trt51JUZHr4Ku7oc5/nC5kN9TpEgbvTSPj2Gu7\r\nJzVqM1IjY5xOHHxt2WCnRkGPGLlSI1diZKZGi2RDXb1/dbcVcfB1luvga/SbRjo1Mg6+VvgffJUN\r\ndaPdDXU8NSp9zkiNnnGN0wmKn+hZO0dMvrFzpMbgOtqpoaGaqqurqaG5w/fHm5u7V4rd0d5O7e3t\r\nUfeampuZFnWcLs+xqJ39fvqnWe3N1NzeEZECtbN/V7Px887894EcAQAA5AiAi0x2doaQoWuvvZZe\r\nfPEFOnIk77y+oeRiFNIHX703jXh9t50aaTE6JOQoLDjAhIjJUXtkauSM07l3jYItSXLXqFXLkRIj\r\no7pbkqDKGBw5CvHUqFGO04V0auRTwhC0R+pkamQZiZE89vqWffA1WPuG2DOyjNTIGafzlDBoMao0\r\nD746YuS6acQPv7ruGj0nShjEOJ26a2SVPm2LUU+TI7TV4QNyBAAAkCMALiorVy6nG2+8QbTL5eVl\r\nX5A3lDIxUnLUccROjfRInV3dbd81cpcw6HG6MMe8acTFqHWbMU5nHHxtSXJuGvEShmZvCcMaSdMq\r\n9zgdF6OmKHtGjYukHDEx0g11lihgYNT73DWqnaXEyChhEO10TgmDFiP3OJ1ZxKCru31KGERD3fNd\r\nVndLMfqLECOr+PGeeecoP0eM0L15042055mn+tydI3xAjgAAAHIEwEVg4cL3RFo0f/7cC/qG0hyn\r\nc5UwnPRLjZzESMrRPruhTqZGO/3vGhnjdDo1Copjr85NI7uEw
UiMIlIj864Rr+7mu0a6oa5elzAs\r\nMBrqvKmRkxjJPSM9Uve6XcQQdN01ivNJjSaqcbqxrptGAVHbPdqVGPFjr3ZqJCq8pRzpEga+a2SV\r\ncDl6nPFYj35DOXToEJo0aUKP/fwRr2WrhdFMZB2lcKCJ0ci+3cAe6yjcWcuoIeqsZo+VjAoKn+KU\r\nMUoZJRTqiBwvlejdu2xFlPFSnaDa46W7KOy3e+ctJbGPH6svFLhS1AT1xQJ1/PioUWPvLSUxd+/4\r\naKl39874QoG5dye+UFDjJKjmeGmwZpqryj4ovmDgGS9VXygwd+8gRwAAyBEA4BOTlrZVLEjHxy+7\r\noL/v+PHj2ZvAI3ZiFFZy5LdrZKdGx+TB1/BxMzXyHHz1HadTB1/Fm0FnpM6p7l5nH3x1lTA0dSM1\r\natB7Rgui7hqZqVFQpEaz7BIG166R702jScY4nTlS506N9F0j165RlNTI8qRGJwqe6NFvKGfPnkkD\r\nB/53j5YjCrbackQWl6MGIka4s449SjkKd1YZclTmyBEXo1NFzudDR4ErQQ2flF8oCB1Xu3fHvV8s\r\n2OdqbAwf0ze+drjEKOhz48tOUMUXCjbYpSTOFwsid++C5o0vJUb+Vfbz2evfKSURx49dI6bOFwtk\r\nlf0MtX833TVealfZmwlqReTxY9HWCDkCAECOAACflP3799A//dM/iQa6C/17T50aRy31GfauUciV\r\nGmX7pkY6MXLa6YxdI3XwNaxTozYlR2ZqxNvpjJtGzsFXZ5xOvBE8utI49hqvyhg8qVEXB1/lTSOd\r\nGs2x94wsVcJguRIjZ9fISY0cOQqau0YV+uCrFKOAz8FXq1ynRs85x179RuqM1Khg5ws0ceLEHvuG\r\nkrcj8nKQNWtW9lw5slrcqVFApUZCjKoVVTIx6ix35KijxFVKErZTo7yIG19hMV5q3Pg67k5QnS8U\r\nmGIUpb
FRjJducX0+mKUkUffuzARVf6HA/GJB/fvqCwULfA4gs8+JWn0A+U1XKUn0LxT4fLFA3/my\r\nU1TnxhdPUSFHAADIEQDgE/HAA7+hRx/900X5vZcu/YBSEuNd43Tyq+S5zq6RSo2kHMkRIpkaeRvq\r\n3CUMQW9qpBIj+UYw0b5rpN8MOiNEPtXdjcb4UIN6I2h+ldx+I+h8ldx5MyhTIz1Sxw++iuTIp6HO\r\nLmHgXyWv9EuNzDeC8q6R01CnW+p8UiOfm0ZajKy8EXTika9RzWWfprJPf5p2/eiHtOi9eT3yDeU7\r\n77wlEs6eKEhyrI6JkSXFyDVSZ6dGTI5OmalRqZ0amaUkEZ8PxhcKZIKqRuqOO3e+xEhdu2e8NEop\r\niWucrtUpJQmKCnstRs7ng77zJT8flkdW2Xd146vO/ELBO0aC+qZdZe+M1M0QpSQRnw8RKeokeeOr\r\nwklQRSmJceMLcgQAgBwBAM6Y3bu305VXXkmHD2ddpGa8Q+JNTM6hpIjUyK7uNr5Kbr8R1OND5jid\r\nWcTg2q0wvkruOviqx4e6GqdTbwTVboU9QuTbUOdNjZyDr/Kr5M5NI68YBe0ShqmuIgY5QmTcNfKp\r\n7vYdpyt73nXTSCdG9q6RbqgreUKIURMTjhpGOaOIkcwEqae+ofzww0VCkObOndMDkyM5TkcWl6N6\r\nMU7HxYgC3nG6cvc4nU8piRwvzZWfD3ykjo/TmbtGx9Pd43Rq10iM03nHS+1xOv/du1CLs2ukb3yZ\r\nnw8hIUfGrpF3z8j+QoH788GKsnsX9OzeBT2lJMFqnz0j/bngbWz0pEZWhfx8gBwBACBHAIAz5tln\r\nY+nPf/7jRf1vyMw8SJMnT6KtyauopXa/SIycr5KbI3XpSoz2e0oYouwaeXcrVGqkdytC6ivlYoTI\r\nO1LXtNL/zaAap7N3K4w9I6su8o2g+Cp5nTs1cnYrnBI
G567Ra85uhfFVcr1bEfApYZBy5DTUOQdf\r\nPXeNDDHiJQwnCp6igp2jRGJUq8SokJHB2HPZZT36DSVvVbztti/S978/kFavXtEj/pv69Sum1OQW\r\nsWfExYgUuohBylGVUcKgxumUHOldo5DR1ujeu8twlTA4pSTGFwtc46U7jPHSbZGfD61bIsZLQ8aN\r\nr5A9XrrKNWLqSlEbo6WoPnt3td4bX55Skmq5a2SmRkHvFwqYGA08eSsl1w33lJI446W6rRFyBACA\r\nHAEAzphvfOPrtHz50ov+38ETpMWLF1FcXJx4UwMuDHzHiI/S6cSIi9F+RpqSoyVLFvXY125RUT5N\r\nmTKJbr31VvrKV+6g0aNH0a5d2y/e/1HFdDKO0cABrZSa1GiP0zmpkRajyNRIiJF940ulRj53vkLd\r\nKWGI2k6nElR7986RI2ekbr34QkHoqDNOp1MjvXcnE9RlPqmRmaC6Gxv1SJ1fY6P4QgEXI7F3Nz16\r\nKYlKjGI6YyjmWAwNbO5HydWPOClquZMa8TtfkCMAAOQIAHDGfJq9Mb4Q94zOhLVr10S8qQHnD75j\r\nVGiI0U7GOjVWx/8sevpruLy8mD766EP67W8fos997lq6/fbbxJ2uN96YQampSRdQjo4x2hhNjHom\r\nSdWUuqXKFiPyyFHISI30OF3IM06nU9TQCW+CqktJ9DidWd9tpqjbXFX29gFks5TEGKeL3k4X7xxA\r\nbvLs3rkaGxeI6m6dolq6gMHTThdRSuI7YvqavxwxMYppYzQx6pkkVd5CyRXD7NRI791BjgAAkCMA\r\nwBlx6NB+uuqqq3rcf9fBg/shLReQRfPmUgqTod2XXSYSIy5GH6hCBv5n0dte15s3b2BvjF+mn/70\r\nfrrllpvp8ssvp7vuukvcSXr++efo7bdnM+lbRQcO7D3HcqTFqIFRxahgFNH3BxQzSSqLmhrJ2u4j\r\n
7hp7vWvkaqhzSkn07l3YLiXZ4zTUeffuXO10uro70di9c6rsg/aukdPY6FtK0mVqZCZGc31LSaLt\r\n3pmpkWu81NgzssWogVHFqGAUMUkqYpJU8rA9Xgo5AgBAjgAAZ8THH6eIvY2e+N+2bVsKxOUiw/8M\r\nLoXXeU5OBq1aFU+vvjqFHn/8/+j++39C/fvfSddccw196lP/TNdddx3deefX6Ac/GES/+tUv6E9/\r\nGk7PPfdXGjt2DE2bFica8njNPb8BtmHDWkpK2kxpaam0d+9Oysg4QFlZByk3N9NOjEwxiok5wshl\r\nZNHAAVm0dUthxK6RX0OdnRodz/K0NR50p0btRnW32DNSI3XtRmNjayp7TPGtshelJF1Wd8e7xMhV\r\nZe/bUOeu7nbt3tliNMu1Z+SI0VTZTmfuGkU0Nk60EyNTjGKOMHIZWUySsm6m5CNDIUcAAMgRAODM\r\n2LkzTXxlvaf+9/HUgo918b0XyMqFgT/X/DnvjYnRJ91b2rNnB61bt5oWLnyPpk+fRmPG/J2eeeYp\r\nGj78EXrggV8LmRo4cAB9+9vfElL15S9/ifr1u0VIFResK6+8QqRTUoyqGeWGGOUIMYqJOcDkKINS\r\nEwtcB1/Ndjrz4Kt500jf+fI2NpoNdZF3jfx2jZJciZEuJdGNjeZIndw1cu4aiVKSpu6kRqrK3kiM\r\nZFujeQB5tquUxLfKPmKcbpJ940uIUTWj3BCjHClGMQdiaEDGzZRUIOXo0UcfpSef/AuNHDmSXn75\r\nZVqwYJ5o6MTf/wAAyBEAwPcr6vxNHZ4LAM7FWJ1OjIpdYsQTo9TEI8ZNo+6lRt4bX2Z1tziAHJEa\r\nmeN0bjmy73y1miUM7oOvrnE6100jv3E6nRotit5QV68a6mrfdt00cnaNZkQ5+CrFKCga6iLvfNmJ\r\nUbFbjHhilHTkIfvGF5ejGTOm0yuvTGHfHssE6
TkaNOh/6POf/xx99rOfpR/96Ic0fvxY2rHjY7x+\r\nAQCQIwCA5LLLLutxhQwA9E45cidGAwfkUeqWEnnXqNNv16iQSZHTThdR3W0kRu7UaJ9qqdvrqrJ3\r\nDiBv6zI1CjYbVfZHnePHAl5n3+RUd+uGOnucTsuRGqezeJU9T40atBzNcx0/dt80cu8aBY0q+6BO\r\njaKUMAgq5I0vb2I08PAtlFz0sGios8pHqRtfz3c5VpeevpfefHMWPfjgA0KWvv71u+i1116hwsI8\r\nvJYBAJAjAPoy/E3BmjUr8VwAcNZyJMVo4IAC2ppUFnHTyG6nO6XFyF3EoEfqwio1MksYQl3e+IpW\r\nwmCkRkyOguZIXfNGV3W3vmukbxrx1CjkLWFQN77scbr691VqZBQx6JG6etlSZ9UaDXU+N76CNUZq\r\nZIhR0CtGlRMoII4fj7PFaEA+k6LiYa4bX4GyF4QY8QPI3d054m2Hixe/T/fe+wMxKsnr4UtLC/Ga\r\nBgBAjgDoi/D6Y97shecCgLOjX7/tTIoqnYOvpyplanTKPzVy7hrJ6m4pRvKmkR6nMxOjsD72aqRG\r\n9l2jtsi7Rq4SBtVQZ6dGapwuJFB7Rk36ppGq725cbtw1ikyNnF2jBWQxMRK7RuqmkRVRwsBH6uQ4\r\nnZka8btGdnU3H6nTDXWVxgFkNU5nVY4TB18HFjIpKh2mjh//za7u1mIUKH1O8EkKGTZtWk/f+c63\r\n6T//8xvYTQIAQI4A6Iu8/vo/6Gc/+188FwCcJfzNOBcj6qxmj6YYlUYdp5MlDGqkTh18tUfq1MHX\r\n0LF034OvTgnDdrVv5FfdLY+9ug++GqnRUXnwVadGIbO6W4mRbwmDHqez94zmG/Xd7xp3jTwlDGrX\r\nSI/T6dQo6B2nq3SXMAg5qhgrKR9DAX7w1b5rJMfpLCM1CpQ+e1ZtdU899ReK4Xe/9u/BaxsAAD
kC\r\noC/BZ+8/85nPYIwEgHMiR1VKjKo8d428B1/9UiOnulsffDXb6UQJwzFdwuDsGrlSo9bIcTqZGhkN\r\ndeqmUci+abTaHqdzDr4uN+q7l3lSo0Wuhjpx8FWN01k+B1/NEoag0U7HUyPLTI3M6m7jrpEUI5ka\r\nWRVjGC8ZqdGLPqnRs2SV/vWsq7z5F474UeFdu5AgAQAgRwD0KXg98dKli/FcAHCWciRSIz1O1+mk\r\nRqEoJQwh+9hrjquhjqdGYqTOmxq5do2UGLUbYmSmRvaekR6nc3aNgoYchXwb6nxKGMzUSN00soyD\r\nr0KMdEOdqO/2r+52pUZMjGRqFOfsGhk3jWRqNI4CQoykHPHUKKDkSOwaqdQoUDbSTo3OhRxx/vGP\r\nqaK6vaAgF69xAADkCIC+Ar/r8sADv8FzAcBZ7RwVU+qWemOczkiNTpmp0ZGoDXX6ppE3NfIbpwt3\r\nWcSgRuqM1Cho3zSSJQzeg696nC7kGqdTcuQ5+CrH6twHX7s1Tifquz03jaI21Jmp0VgmRGZqNFpS\r\nNsqu7uZiZCkxCpQ8c86OwN5zz3dp8uSJeI0DACBHAPQV+Fz9FVd8BjW2AJzN/1HFdDKO0cABRyk1\r\nsdK/hIGJUchIjcQ43Um1ZyR2jA6px4MR1d3OXaOdviUMQaO6O6j2jERqpMbpnHY6nRqtESN1Qo6M\r\nkTrfu0YuMVKpkR6nU3tGPDHSJQx+I3URd43UOF3QLmGYbKdGgQp3CYMYp3PtGcnUiI/UWeXukbrA\r\nOZaj1NQkuu66z1NxcQFe5wAAyBEAfYXvfvduevfdt/FcAPCJ5egYo43RxKhnklTBJEmlRqeKZHW3\r\n0VAXcdfIGKcLi+pu/5tGYb89oyh3jYLGrpGUI9lQ5z9OF+2mkTFSZ+waRUuN+DidqO6unRX1ppFT\r\n3R1nJEYqNapyihgCuoSBCZIuYdC7Rt7
USI/TWaWxjHMnR5w77riDVqz4CK9zAADkCIC+wuzZM8X4\r\nCJ4LAD6pHGkxamBUMSrE7aOBAwqZJB1xNdTpXSNznE5Wd8t2Or1rFD7uFDFE3DVqd4/T2dXdopku\r\n0Tj6qg6+ekoYzIOvoSZn18hMjULmOF29UcLgI0ZOajRb3DSS9d2z7CIG110je9fIbKib5IzTVejU\r\nSLbT8XG6gJAiIzESe0bPuxrqdGoUKHn6nMrRyJHP0uOP/x9e5wAAyBEAfQU+MnLNNdfQ1q3JeD4A\r\n+ERyJBMjU4z4UdiYmFxGFpOkDErdnOOTGmXbI3X6rlHIaKgzUyOnhGG7q4TBuWmkUyN3Q50eqbNL\r\nGJr9Shg+8kmNvDeNdGqkqrvrPCN1dfqu0SxXQ5334Gt0MfJrqHvZHqlzShhejChhCKjUiItRoOSp\r\ncypH/ItH//u/9+N1DgCAHAHQl+C3Pf7wh9/juQBAUV5eTPv27aZVq+Jp1qzXafToUfToo3+mX//6\r\nlzRo0P/Qf/3Xf9K///u/080336TEqJpRbohRjhCjmJgDTI4OUsqmbHXTKMcZpzvh304n2WsXMYS5\r\nHLWpu0ZipG5bxDid2DVqNW8abTDa6dapAgZ508g+9trkLmIQB18blkSWMDA5sk4zThdRwlA9QxUx\r\nTFfV3VMlurrbe9dI7RrpcTpRwuAVI1XdLcfpdHW3U8TAR+rOtRxt2LCW7rzza/icAABAjgDoS/A3\r\ngVdeeSXl5mbi+QB9Mj1dt24NjR8/lh544NfUv39/+vSnP03XX389feMbXxfHkp944jH6+99Hi4rn\r\nBQvm0Zo1KykxcQNt377NSIyKXWKkEyM5TnfYf9foRIaTGh0zGursu0ZKjE5T3R0yxuncd43kwdeI\r\nXSM1TifEqGmZq50u1MWekSs1EnI0xzVSZ1Z38xKGoFnCUP2aU8KgUyNjz0juGKmROuOu
ES9i6Kq6\r\n20yNAiVPnlM54q8LyBEAAHIEQB+Ef0V81Kjn8VyAPsHevTtp4sRxIgW6/PLLRQr08MNDadq0OFq9\r\nesUZfaHAmxgNHJBLKZvzRAlDyKzuPhEpRiG1axS9uls21Mn6bm9qlOpKjZzqbuemERejkBqnc6dG\r\nWow8DXWe1MgSDXXOOJ1OjfRNI1HdXSNTo6BZ3W3eNLLru42ROp4Yqepuu6Guwtk10iUMgbLRcpRO\r\nj9N5ShgCJbGu1Mg6D3LEZRmfMwAAyBEAfYwtWzZSv89dS3UzplHLCyOpadbrVIkDiOASoqTkCM2c\r\nOZ2+97176OqrrxYp0VtvzabDh7POcudIitHAAXmUmligqrvd7XSiuluM1GXJXSN7pO6gZ6Rub+TB\r\n13a/m0b+B19FCUPLRvuuEd81CtlFDJENdVqMQtF2jfRNI7u6+x2FGqnz3DWyd41q5K6R3VAnxunM\r\ng6+6vnuC5+CrTozcDXVOEYNHjlRqZPHkqPhJxl/OqRzxJs8f/vBefP4AACBHAPQ1ajespYZ//mdi\r\n7/JsrOuuE9+P5wf0ZkpLC2nSpAl0ww030H//9/fo7bdnU1FR/jn79/frt51JUZHr4Ku7oc5/nC5k\r\nN9TpEgbvTSPj2Gu7JzVqM1IjY5xOHHxt2WCnRkGPGLlSI1diZKZGi2RDXb1/dbcVcfB1luvga/Sb\r\nRjo1Mg6+VvgffJUNdaPdDXU8NSp9zkiNnnGN0wmKnzincsRHKf/85z/i8wgAADkCoC/BEyIuQqYY\r\nmYKEBAn0VvhCPb9Vw6Vo3brV5+X34G/GuRiF9MFX700jXt9tp0ZajA4JOQoLDjAhYnLUHpkaOeN0\r\n7l2jYEuS3DVq1XKkxMio7pYkqDIGR45CPDVqlON0IZ0a+ZQwBO2ROpkaWUZiJI+9vmUffA3WviH2\r\njCwjNXLG6TwlDFqMKs2Dr44Yu
W4a8cOvrrtGz4kSBjFOp+4aWaVP22J0ruVoyJAHacqUSfhcAgBA\r\njgDoS/AROj8x0vAfx/MEehu8YOGqq64So3Pn8/cRciTESMlRxxE7NdIjdXZ1t33XyF3CoMfpwhzz\r\nphEXo9ZtxjidcfC1Jcm5acRLGJq9JQxrJE2r3ON0XIyaouwZNS6ScsTESDfUWaKAgVHvc9eodpYS\r\nI6OEQbTTOSUMWozc43RmEYOu7vYpYRANdc93Wd0txegvQoys4sfPqRzddNONlJqahM8nAADkCIC+\r\nBN8x6kqO+I/jeQK9iZde+hvdfvttok3ufP9ejhzJcTpXCcNJv9TISYykHO2zG+pkarTT/66RMU6n\r\nU6OgOPbq3DSySxiMxCgiNTLvGvHqbr5rpBvq6nUJwwKjoc6bGjmJkdwz0iN1r9tFDEHXXaM4n9Ro\r\nohqnG+u6aRQQtd2jXYkRP/Zqp0aiwlvKkS5h4LtGVgmXo8cZj50zOeItnnw3DZ9PAADIEQBIjpAc\r\ngV4Lr9qOYa/bnTvTLlBCNZ4J0RE7MQorOfLbNbJTo2Py4Gv4uJkaeQ6++o7TqYOvYtfIGalzqrvX\r\n2QdfXSUMTd1IjRr0ntGCqLtGZmoUFKnRLLuEwbVr5HvTaJIxTmeO1LlTI33XyLVrFCU1sjyp0YmC\r\nczdWN27cy/Sb3/wKn1MAAMgRAH1u5yg/BztH4JIgLW2rGKXjFcwX6vecOjWOWuoz7F2jkCs1yvZN\r\njXRi5LTTGbtG6uBrWKdGbUqOzNSIt9MZN42cg6/OOJ0Qo6MrjWOv8aqMwZMadXHwVd400qnRHHvP\r\nyFIlDJYrMXJ2jZzUyJGjoLlrVKEPvkoxCvgcfLXKdWr0nHPs1W+kzkiNCna+QBMmTDgncvTNb/4X\r\nLVz4Hj6vAACQIwD6IryVzitIJ6++Cm11oFfx05/eTy+++MIF/T2XLv2AUhLjXe
N0orrbTo2y7dRI\r\nypHcNZKpkbehzl3CEPSmRioxkmKUaN810g11TgmDT3V3o3HTiIsRT43Mg6/2ON18sur0OJ1MjfSu\r\nkR6p4wdfRXLk01BnlzDwhrpKv9RIj9ONte8aOQ11uqXOJzXyuWmkxcjKG0EnHvka1Vz2aSr79Kdp\r\n149+SIvem/eJ5Wjfvl3iMDY/EIzPKwAA5AiAPpwg8RE6vmO0/rcP0f8b8N94XkCvge+IXHnlFWd9\r\nt+hMyc4+JEa5cg4lRaRGdnW3uGkkSxj0wVctRiFznM4sYtB3jbwlDK6DrxvUTaOuxumWK1RDXVOU\r\nkboGd3W3TI2cg6/BOvdNI68YBe0ShqmuIgZZwmDcNfKp7vYdpyt73nXTSCdG9q6RbqgreUKIUVNM\r\nDNUwyhlFjGQmSJ9Ujp588gn64x//gM8rAADkCAAg4XdgPv/5z4njsHg+QG+A3zJ64IHfXJTfOzPz\r\nIE2ePIm2Jq+iltr9IjHS43TmXSOZGu0XuEsYouwaGWIUNFKjoN4zEtXdqojBO1LXZI7ULXenRg2L\r\nKWSXMCw0EqPIEgaxZ1TnTo2EHNW6Sxicu0avqbtGZmo0yb5pFPApYZBy5DTUOQdfPXeNDDHiJQwn\r\nCp6igp2jRGJUq8SokJHB2HPZZZ9Ijvjffddccw1t25aMzysAAOQIAOAwatTz9Otf/xLPBegV3H//\r\nT2j27JkX7ffnCdLixYsoLi5OJEngwjBx4kQxSqcTIy5G+xlpSo6WLFl0Rn+Ob7wxg+6557v4nAIA\r\nQI4AAG5yczPF3D0fV8LzAXo6//EfX6WNG9f1iP+WtWvXRJQCgPMH3zEqNMRoJ2OdGqvjfxbd/XMr\r\nLy+m2277In344SJ8TgEAIEega0pKimjlypU0depUUV2Lr1heCMbT5FfiaMEHC8RXpS/Gn/vw4Y/Q\r\nU0/9BZ8DoMdz/fXX054
9O3rEf8vBg/shLReQRfPmUgqTod2XXSYSIy5GH6hCBv5n0d0/tzlz3qS7\r\n7roLn08AAMgROA2VFeLNenJKKh1taaNTVphB1ME4GSA6oTjWSdR+StLGaO0gamE0nyQ6ymhiNJ4g\r\nqj9OVHeMqJZR005UrahqI6pQlLcSlbUQlTJKmomKFUVHiY40EeU3Sg43SHIZOfVE2YwsRmYdUUYt\r\n0SHGwRqidMUBxr5qor1VRHsqiXZVSHYydpQTbWekMT4uI9rGKSVK5ZQQpTCSGUnFRFuKiBIZmwuJ\r\nNh5hsMf17HFdgSQhn2gNJ49oNWPVYaKVjBWM+Fyi5TlEHzGWZRMtZXzIWJJFtChT8kEG0cJDYZq3\r\nu41eX76DJk6aJPYaLvSf/datyWL+Hq1NoKfDX6cZGQd6zH/Ptm0pEJeLDP8zOJM/s69+9Ss0f/5c\r\nfD4BACBHoKvEqJimTJlC2dm5ZIWIOoMSLkeck5YUo+OK9k4JlyMhRh1KjE5IMWo4ruRIwQXJliNG\r\npZ8ctUgpKlRiJORIkdcoxUjIUYOUo2yPHHGEGDEp2ldlyBFjd6UhRxVSjoQgKTHaqnCJUbESI8Ym\r\nJUcbFFqO1hY4YuSSo1wpRx8ZcvRhlsQlR4yFQpCIFjBmr88VgnoxEqTvfe8emoVDsKCHc+utt/a4\r\nJXqeWvCxLr73Alm5MPDnmj/nZ5IYcV5//R/0n//5DXwuAQAgR6BrVq1aRdu376BgmIQcBUKOHOnk\r\niHO8UyZHnNYuUqMGIzmqU8lRjSFGQo5apRx5U6NCJUgF3uRICZIWo6w6KUecg0ZyxOVovyFGthxV\r\nepKjMpkccbaaqVGxJzXSclQoxWh9gWRtviTBTI7yHDGyU6McmRotVanR4kzJByo5et+Qo/mMOcvW\r\niIXvC/0amDv3Hbr77u/g8wH0aL797W9RfPwyPBfgjOENdTfeeAOtWPER
ng8AAOQIdM20adOouaWN\r\ngiFyJUccc6zOLzXSctTkkxzVq9SoxhitM1OjUiM1EuN0xkgdRwtSXqN7rC5ipK7WGacTI3VVEj1W\r\np+Vol0qOdqixOm9qpJOjLX7JUaEzVsdZW+AWo5XekTqFKUd6rG6xSo/eV3IkxOgg0XucXQ0UF/fq\r\nRXnjcMUVn0ExA+jRPPjgA+zzYwqeC3DGvPzyS3TffffiuQAAQI7A6eHlC8FQWIiRmRzZqZElxcjc\r\nN+KpUespT3Kk5EjvHHFEanTMPU7HKWuV6OTIHKvTyVGBGqnL86ZG9U5qpPeNuCDx1MhMjvaq1EiP\r\n1Xn3jT42941KZWoUkRwVqp2jQvdIXUK+s3OkUyMtRytUcrRcjdRxQTLFiKPFaKGSIw6Xo7npYTFa\r\n90lGRs7FG8+XXvobPidAj2XSpPE0ZMiDeC7AGZGevle0cn78cQqeDwAA5AicHv5mPKRH6vS+kZYj\r\nc9+o050ctap9I3vnyCxjUKlRl/tGre7kSI/VHTnqTo28+0Z2clTn7BvpsTouRvsUeyqj7xuZI3Xm\r\nWF1SceTOkd++kZaj1XkeOcp1kiO9c7Q029k3WmyUMXhH6nh6NC+dxJ/HJ102PhuWLVtC/fvfic8J\r\n0GPZtGk9felLt+O5AGfEb37zK3rssRF4LgAAkCPQfTnyjtR55Ug31R3TYnTKSY5ON1JXbYzUVSox\r\nKvckR2YZgzc1imiqq4tMjtK7Gqmr6N6+UYpPS50uY9jo2TdKMPaNeBGDt4xhuaeljmPvG2X4yJEa\r\nq/PK0ZnW1J4NpaWF9JnPfEZ8lRWfF6Cnwhvrduz4GM8F6BYJCavouuuuo7y8bDwfAADIETgDOYpS\r\nxtDh01Sn5cgvNfKWMfgmR2YZg7lv1BxZxtBlcmS01Gk52q/a6rgYeZvqdlY4Y3W6qY5XeUet8O4i\r\nORJNdZ6xuogKb
4VOjVzJUaZ7rG6+wk+OzuTA4dnys5/9r2h0wucF6KkMHTpE7I/guQCng58n+Ld/\r\n+zK99dZsPB8AAMgR+GTJUcBbxqDlqNO5beQqY/DK0XEnPfKO1VWYqZFPGYNd4300ct/ILmOo86/w\r\nTjfEyLxx5JccbY9WxlDsKWModNd4ry/w3DjyljHkesoYsp2Rug+NIoZoZQxcjOb6yBGvrb1Qr4Wx\r\nY8fQsGEP4/MC9Fg+/HARff3rOOIJTs/Ikc/Svff+AM8FAAByBM4+OTJTI/v4q09T3dFoNd7e+0Zt\r\nUe4bNfvvGxV4bhxFHn9tp2lPD6P/+fFgGrm82q7x3rEzgX7ylUH07EfVrhpvv/tGZmrUnRpvOzXK\r\nd1KjaCN15r6RFiRdxhCRGh1UqdFBfzniXKjXwpo1K/HGE/Ro+Pjnddd9npKTE/F8gKjw8oXPfvaz\r\ntGfPDjwfAADIEThzOXKN1HkqvCP2jTqMG0eeA7CmGPntG1UoMfKWMfCdI54eHTH2jQ4b+0be+0a8\r\njGHVWyMoJiaGYu6ZSam8qa6mg14dxv45ZjDNy4+yb6TKGLaZZQylcqRO1HgXuZMju8Jb7xsVuPeN\r\nvE11ZhmDuXOk943M1MgsY3jvoG6ru7hyxOfy/+Vf/gWfF6BH8+STT9Cjj/4JzwXwpby8mL75zf+i\r\nCRPG4vkAAECOwFnIkWekrsMYqdNy1N7plDH4jdTVe0bqaozUyK+pjmOO1BV47xs1yl2jiOSIlzHk\r\np9G3uBwxJu0i2ncwQXz7++PTXfeNvCN10Zrqkr37Rj7HX7vbVLfMOABrVnh7m+oWGnIUbazuQsoR\r\n51//9V8pOzsDnxugx7J370668sorKDc3E88HiICfJOAHg7kk4fkAAECOwFnLkS5jMI+/6jIGnRo1\r\n+6RGDUqQdBFDjU8ZQ7lfGcNRdfxVocXIt4zBtXNk0YxH+wsh+u
ZLCfTqyEHs24NoTq77vpGrjMG4\r\nb8TTIy1FdhlDlH0jPVbHR+rWqtRIlzF0mRpluWu8RVOdz1idTo16ghz163cL2sBAj2fw4J+zN8Gj\r\n8VwAF9u2JYubRvg7DAAAOQJnLUd+Nd4nPfeNzArvCDk6HnnjSAtSV/eNvCN13uTILmPwHn9lbE+Z\r\nI0frFP/19zR3GUOl/1idmRrZI3U++0abPMnRWt1UF22kzmyq89k3Mpvq/Ebq3u0BcvTFL36R0tJS\r\n8bkBejQbN66j66+/nkpKjuD5AIKysiKxMzlp0gQ8HwAAyBE4hztHZmrU6d43cjXVnfTcODrhjNXV\r\neIoYKv2a6prdTXWFRyNvHOX43DfiqREfq5P3jarpsa9oORpEb2ZGNtVxMdrhkxqllnZRxuBtqjti\r\npEb57tTIW8bgbarTNd6ukTqfpjrOuwcuvhzxJeaMjAP43AA9nrvv/g698cYMPBdA8MwzT9HAgQPw\r\nXAAAIEfg7OUooowhyvFX+8bRSYm5cxSRGnkEKeL4qylIxs5R/mmOv2YYyRFn5QxZzPClJ1PsG0eu\r\n1KjC//irLmNI8StjKDLKGI44x1/XRts38ozV6aa6D42dow88qZHrvlEPSY54IcNll12GWX3QK1i+\r\nfCndcsvNosEOz0ffhjdtXn311ThiDQCAHIFzJEfe+0bGvlFXNd7ekTotSFqMXE11PjXeRUd9yhia\r\nnHE6V1Od5/jrQXHjqIFG/pinRv3pH+mWTI2qot83spOj0sjkKKLC2+e+kXffaJXPjSNbjPR9I6Op\r\nrqvkqCfIUXz8MvrGN76OzwvQa/jud++madPi8Fz0YfLzc8Su5Lx57+L5AABAjsC5kaNgyFPGYCRH\r\noozBSI1aopQx1BtlDLWeMoYKVeNdbrTUFRtypEfqzDKGw94yBq8c1RAtmz5MjtQ9mkC7DTFyyVGF\r\ns2/E2Vb
mjNXpcTrfkTq/G0cFkWN13vtGfKRumUqNdHKkj79GK2PQcnSxCxl4PfKzz8bi8wL0Glas\r\n+IhuuulG7B718XKO3/72ITwXAADIETh3chQKkzgE671xJMoYTjllDOa+kff4a0OUG0dcik53/FUf\r\ngM1XgmQmRzlRxCi9poOWLEmgV99NoKVZFu2rpi6TozRPapTq3Tcqjp4cmTeO7NTII0fxuU4ZQ0Ry\r\nlOW+cWSO1JlNdRdz5+jw4SzR8rR793Z8XoBeBd8zmTJlEp6LPsi0aa/Rv/3bl+nIkcN4PgAAkCNw\r\n7uQoHGxjMHsJtlDYOspglmI1UjhQz6hjMBsJ1FK4s5pRReFTFYwyRimjhEIdRRTuKGQcodDJfAqf\r\nzGMcZuRS6EQOhU9kM7IodDyDwscPscd0Ch3bz9jH2Euh9t2MXYydFGrbzh63U7g9jX17G4VatzJS\r\nGSmMJMYWCrVspmDzRsYGCjWvp+DRtYwE9u0E9riasYpCR1dSsCmesZyxjEJNSynY+CFjMQUbFlGw\r\n/n3GQsYCsurns8f3GPPIqnuXgnXvMOZQsPYtsmpns8dZjDfIqnmdgjUzyKqezpimmEpWVRzjVcYr\r\nZFVOZkxiTGSMJ6tiLONlxhiyyv/O+JsgUPYiYxRZZS9QoHQk4zmySp+9aHL02GMj6IEHfoPPCdDr\r\n2LRpPX3uc9eKnTk8H32HrVuTRYFMcnIing8AAOQInFs5omA7EyImR1YLo5nJkCNHxOWos0aJUSVD\r\ni5Gio4Q9FjNBknIU7ihggiTlKNCeQ22Nh6mpjlGbq8gxyGZkSWoyGRmKg4LG6nT2yKg+wL69nz1y\r\n9rFv72WPnD3UWLWbmhiNVbvY405BY+UOaqrczh7T2GOaeGys/JixTVKxVZHKSJGUJym2MBINNjM2\r\nUWPZRva4nlor4ulUFZOl6n/YYhSsZmJUOYV9m4lRlRaj
iRSoGMcexwk5CpS/ZMsRFyOr3BEjq+w5\r\n9vhXJkd/vShyNGvW6/T5z3+O9u3bjc8J0Cv55S9/QbGxT+O56CMUFeXTV7/6FXr11Sl4PgAAkCNw\r\nPuTIPzUinhx11orkSMsRcUE6VS5TIy5GHcU+qVEeNdfnU3FRIfs/saJLkAJqKktgIvQaE6TXfFKj\r\nCUyIeGo0zkmNXMkRk6OyUUySnmePTI5UahQoib3gcsSXmPne1sqVy/H5AHotfBz0+is+QyWTJ1DL\r\nCyOpiQl/ZUEunptLlKFDh9DPf/4zPBcAAMgROE9jdVYrI8pIXWcNEyImRqd0alSh5Kgs6kgdF6NL\r\nU4rcNJWtVmI0RWKO1HnkKGCkRnqcjouRHqnjyVGg5JkLKkfvvfcuXXvttZSUtAmfC6BXU7thLbVc\r\nfhkx07exrrtOfD+en0uLGTP+IY5V85Y6PB8AAMgROE/JkRynIyZGXI7CgYaIkTqyd43KXeN0YXuc\r\njsHkyDqW16MSo72Jy2h6XBxNnz2fUtPPrbQVFxXQqcoZMjUScqRTo3GKsUyKdHL0kpMalevU6Hl7\r\n18gqjWVcGDniuxkPPzxUtHwhMQK9HZ4QcREyxcgUJCRIlw58v4jvGSUlbcbzAQCAHIHzKEc6NVK7\r\nRmQ1eMbp1L6RlqOO/8/emcBVWad9n/f9PM8zTc2TLTPTvDOVU9PMUE02S4s1aUPZvtBMWdZgZVOW\r\nzVRkllFaCWqRZpGmuKIiSeKGiooIKiqCchQQZN9BZJHNBT0L1/tf7/t/3+c+iMp28KLP93NYDkg3\r\nnHPzu3+/63fxIgYaqXMprpHr5CFoaei8AMlMioZA/8G8jpvhC8OGjYJFyTldIl4y40L51x08DHzJ\r\n7cTYnTB3jD+MmRXfZQKpqXy5EqkLcStikLNGQ05cCwmHnxfCSHWOxrJZIxqps5e83a3iqKAgFz78\r\n8
APmFr300otw8GAGPgYQr4dG6KyEkYR+HI+T90Mv6lx//XXMOcLjgSAIiiOk250jKo7Ag2ukNdSd\r\nVmaNWAmDHqlrF5G6hiOdE0e2lRM1QTRxbjTEroyE0IljmIgJXGnrEuESO5EKr/GQpr0vE0J8fcB3\r\nfGyXiaP6sjXgNLhGk7g4qvzM0FLnc5r8vx7zgaFHr4GEyueEazRWFDEEskidvZucoy1bNsKLL46E\r\nyy+/nOX06dv4u4/0F+iMUUfiiH4cj5P389BDD8LIkf/EY4EgCIojpCdmjnRhpJUwMGFEK7zVeSPV\r\nNXKfNXKdyOmkOEqB8b5cGM2KN7lEeTmQk9c1wiU+ZBj4+IZATjfG9upLY7lrRFvqKoLd67srJoC9\r\nLIgJI58WQgOh1geGVF4NW8ue1YoYaKTOXvJWl4gjmsVfujQCXn/9Nbj22mtYfO7dd9/BHUYIOkeI\r\nV/LRRx/Crbfeylrq8HggCILiCOkRcUQjde12EamzH9H3Gp2qNJUwqOKoSHONeH1358RRTjyPuw2b\r\neAYHJzMeJo7QY3e+IyZCfKbuAs0iHxsVGgmLJvrrLlRkMvt4XOgI/fMII0LjtM8ZMSNO+zfy0mIh\r\ncJiM9Q2D8RPHwODBYyA+p7PiaK2y10iKI2MRg738I10Y1RGqCBWEIh8YWnQ1JBQ/zSJ15yKOMjLS\r\nYfXqGAgNncq2xNM/IH70ox/BnXfewQTR5s1x+HuO9O+Zo7xsnDnqx6xYsVysGkjB44EgCIojpKdm\r\njoQwYg11qnPEI3VafbfZNTqZb6jvpruNOiOOMuNCmBgJicvs4H7JEMgEywiIjEuG5PhFMIK5TYGQ\r\nnMfFUagUNUTMLFoZCeOH8Y+n0H8jJQ5CRvmSt0eRj62EuCQbj9UNJmJJE2XJMEb8G4vikyFp5SwY\r\nJkTSysyzFUe6a8RKGMplQx1vqZOOkSqMfAoIOY
QsHxiS+UvYmv8U+3mEh8+BWbNmwrffhsH06dNg\r\n9uxZMGVKCHzwwTgYOTIAHnjgfhg0aBAMGHAp449/vBWefXY4BAd/CmvWrITCwlz83UYuKGgrnVkg\r\nHf6//xeKyB/WeHy8F+p20xnJ6OgoPB4IgqA4QnpaHNUZ6ru1WSNDfXfHkTrXiWwijnLP7ByJooTQ\r\nDsSRFFATYzOVz5PvE0KHiqFhIdpMUXwodZAGa8LGPVbHxdFgIY48/xuDIfZsxJGM1LntNpqg1Xcz\r\nYVRNKFeEUTYXRj7pRBwd+CUk5HFx9PTTTzOeeeYZGD58OFx88cVw2WUD4Oc//zlcd92viTC6BYYO\r\nHULu83d4443RTDRR8fTddzPZHxG0yYk6Svj7jVxoDhKN0Mk9R6OeG84eH3hsvBNaIHPzzTfBxIkf\r\n4/FAEATFEdLTsTp18asijk5ZNdSprlG+VsRAXaPOiqPMWC5KxndQvJApREq0TX9fXvJcoziiQidE\r\nj8jFUTHkM0wTNnEhg5k4yuxQHPlCZEqeEvk7B3FUaZ410p0jO6vvDtIdo2KjMBqS+StIyP872Ev+\r\nA/bif7Ofx8KF82H+/Hkwb95cmDt3DmzfvhXi4+MgNnY1i5jQ/UTffvs1TJ06mWXx33zzDRape+KJ\r\nx1ic7oYbfgNXXHEF/Nd//Rdcc83VcMcdtzMhRWN2YWEzIC5uHfnD4xD+/iP9GpstjTmrOGvnnfz9\r\n70/BU0/547FAEATFEdIbzlG9pWtk3G2k1HeflLuN8g3CqP3EQSKODp1RUOSlzGVzQD7+oYpwMQuo\r\niSJ6l2MSLiZxpMwtnZs4oiJNd45WhvgbvkbnxFEI2LXdRnpDnbbXqGy8m2M05NCvYGvh06yIwVHy\r\nFhNG9pI3u7StjsbrkpO3QUxMNEyfHgpvvfVv1lbn6+sLF110EQwcOBAef/xRCAoaz/YdYRwP6W8
E\r\nBr7N/sjGY+FdTJr0Kdx0043MPcLjgSAIiiOk550jpb7bUMTAInVWJQzUOdLru2mkrl0TR7mdEhXR\r\n40XRgv9EiE1Og8xMG6QkxcKMwFEQSsVPTjyMoB8fNhHi0jIhMy1OzBSNEGUJnsXRyk6Ko6K8JBjF\r\nZowGw/jQUBijFDN0Xhytca/vLp8g5o14pI7uNZLCaEje1bC1aDjYS/leI7toqaPOkaPk3z2yBJZS\r\nXl4MiYlbmJP06quvsKjeJZdcAkOG3AMTJgTBrl078PGBeD10N87PfvZT2LRpAx4PLyEqaimbM0LH\r\nD0EQFEdI7zlHBtfosL70VRYxSHF0qljfa9SWz5a+MmF0Mps5R64TWdBQc6iTNdh5EDsjkDtIBoZp\r\nS2BzkqNFCYPAdxREagti3cURnznyh9gcRSwN7kAcUWxxMHGUPwz29QX/8bMgMnSUYW6pU+LIYukr\r\nd414pI6Ko6GF18DW4ueIGHoPHGVjxW4j3lDnYJG6NwljekwcWUErwOfPnwsBAS/AlVdeyYoeJk+e\r\nxP7AxMcK4q18/vkUGDr0HjwWXkBychJ77qFuNx4PBEFQHCG96ByZl76aZ43K2OJXlzJvpM8a6a6R\r\n60TmWYgjudcoE1JSUiAtLQ3SbDmWIiozM5OR1w17ivJyjP/W3FE+psWxnRRHpqWvdkUYOco+IKJo\r\nHFv66hCLX6lz5DC5Rr0tjlTKyopg2bIl8MQTj7O5jf/8503Iytrv3b/v5Odb/8rLUE/+fw4TKsjr\r\nFbg3pd9TUlLAdn2tXPkDHo8+TE5OJvzmN9fDF19MxeOBIAiKI6T3xRFzjmSkTq3vtnKN6F6jE4c0\r\nccRdo4NEIFFxlNNtC1e7HhtMZFXg/jAmMBD8hUs1Zm7yWSyBXQ12ZemrWt9N542kOHKUvc9dIyaO\r\ndNfIrrhGfUkcqdB4y/PPP8eu6NLZJW/9
Xa8f9RI00IpnQjmhiJBHBRI+D/R7pk//EgYPvhOPRR+F\r\nXoy57z4/ePHFkXg8EARBcYT0hVid7hoZSxjK3F0jpb5bLWJwHc+E9uMZcPSIN4mjIkiJi4TQkIkQ\r\nSMRR4PgQiI63ndXn15euYq6RXanvdnONysYJ50iIo5JAvYhBcY3sxW/0SXEk2bJlI/zhDzfDO++8\r\nxWaWvE4cDbgUaoQwKiRkEGzUQcLngX5PaWkhDBx4Lfzww/d4PPogY8a8DnfdNZi5fHg8EARBcYT0\r\ncivQJHCdrtGLGE7LIoZyTRjRhjqthKHNVMRwkouj9hNZRCBlQHP9Qa8SR+dLU+lSpb57grGlrnw8\r\nEUbvE4E0jvAei9Ops0a0oY7NG5Vw5+hE/pt9WhxRiovzmbtGm6S8rd2ORumkY0SF0T5CyqWXwurV\r\nq2HatGnssUCPP9K90OM8bVoorIheDAcPHuixnz+tv6dV9/i837eYOfMbtnKAlvLg8UAQBMURHoRe\r\nh/6R0lxfoDTUVRlb6tqMkTrVNWoXJQzUNaLzRq7jB8DecgCKiwovEHGUD23ln5sidaprJMXR+/q8\r\nUck7TBw5St82Repeh/xd70NwcHCfFkcSGoEZOzbQuxykV17WHCMqjHYTlt15JyQmJkJLSwu0t7cD\r\nvnT/Cz3O9Hjv2rULpk6ZTP4o7plZNupK/L//9//Yni987u8brF+/lu1kS0jYhMcDQRAExVHfYPny\r\nZZCYsA7AzmeNeKROr+92qfXdFq4RFUd01qj9RAa0E3HkOm6Do0eyLghx1FAaoyx+1Xcb0fpuh6GI\r\nQZ01ekcrYlBb6hzFb8Di+Z/D9OnTvEIc0T80f//738OcObO85/e9MBfyiUBKH3Apc4yW3303ZB84\r\ngGqlF19ycnKYm9RTDhKtqff3fxKf+/sAe/fugV/84hdsqTUeDwRBEBRHfQb6Rwn94yQ7c
6e22whO\r\nl5t2G/GGOpd5r5EijmikznV8PxFINkI6E0j910HKF8JInzWys4a6IOYamVvqZKROzhppRQzKrFHc\r\nCh43mj9/vleII0pExAK4+eabvPL3nkbpqHOBL73/sjU+FpYti+yxRjTavpiWthuf/3uR/Pwc9txB\r\nF1Dj8UAQBEFx1OegsZYpUybDtsQN0FR7CFwsSmc1b5Tv5hq5hGskhRF1jlzH0qH92F6wt+yF5roD\r\n0FCTAQ2HJeTtw/sJNqivTocGxj7BXkEaIRXqq/ZAA6G+KoWwm7xO2QX1lTuhgVBfmcxoqNxBbinb\r\nob5iGyFJkEjYyilPIGwRxAs2EzZxyjYS4ggbBOuhvnSdIJawlrxvNTSVLYNTFaGsvtt+JtdImTWS\r\n80aqa3Qi/y3I3z0eFoZ/zgTq/Pnz3IRRXxZHFF9fX6/cSTJ9+nQW7cKX3n9pbqqH0NAveuxn/9pr\r\n/2LV9Pjc3zvQKO5DDz0Iw4c/jccDQRAExVHfdpDo1dvQ0FAcGu9BQkJC2B/qVo4RJSoqsk//3rzx\r\nxmh49913vLKIBGeM+s4MEn0srFu3Fvbv39ftP/utW+Phqqt+zhrs8Lm/53nrrX/Dbbf9he2Vw+OB\r\nIAiC4sgroH+kWP2hjvQ89GfRl39XlixZBEOHDvG633FWYY8vfeZFbWncvj2x23/+f/rTHyEqaik+\r\n3/cwYWEz2ELejIx0PB4IgiAojrwHevUWhUnfoCeupJ8rlfk5kP1xEEy74nJomPkNexvFUXe8tMGm\r\nsCAYHRgGuW2e7uOAsiwbpNqyoNHRlV+358VRT/zef/LJBBgx4jl8vu9B1qxZCZdffjlz7vB4IAiC\r\noDjyOujVWxQnvUtPXEE/V2ri1oHjqqsAfHw06Ns1XlKT3H3iqBUi/H3YLigfnwCwtaofK4PgQeJj\r\nARHQehZfM9yPfp4/pHr8pEYI9e
FfO7m1K79u74ij7nZMd+3aAT/96U+9cpmxN7Jnz052vJcujcDj\r\ngSAIguLIux0k+kcKnXtBsdIz0GPdU7MX5+MYmYWRKpC8wUHqGXHkA4GxZfpHbOHa+338womcOduv\r\n6S/ElgM2BQeQtwdBVK5Dc46yEmMhKiYRqh3n+nX7jjjqiVm73/72Bti0aQM+13czeXnZ8Lvf/Q6C\r\ngz/F44EgCILiCEH6HzRCZyWMJPTjF7Q4CtDFkY9/uHCIHBAbNMggjtj724ogOMAf/PyDIEtE23Jj\r\ngsHPzw+CY4ssRUxuVKD+dQYNAv+gGHKPNtgUGggBo0NFRK4VYoICwC8gGBJTY2E0c6wGgd/oMMht\r\ntRJH/P7+/v4QllitB++KYiFgkJ/hfT0hjnqipfG5556FyZMn4WO6GykrK4J77x0KI0f+E48HgiAI\r\niiME6Z80fTCuQ3FEP37BO0eD/MFfCJJYqitaU8GPHJtBfoOM4qjVBv4+xmhbVrg/u49fmM1SHFUn\r\nR7Cvxe4zOhjCY2xEerVCuL/6deTbHP/Ro7XP8fGXkT6z6Botvrcw4Wq1Qczonond9YY4Cg2dCs8+\r\nOxwf093IqFEvwZAh97Cl0Xg8EARBUBwhCDpHF6o4CgiHTeFcbARE5ULZpiAmMmI2hZucIxsE+Bij\r\nbVnhAVzQeBBHVLTI6F64tJvc7qPH+8KSuevTlhUhxJIuoAyf05isCagoalpVx5q+j/4ljuh+rjvu\r\nuB0f093E5MnB8JvfXA/Z2Rl4PBAEQVAcIUj/pTIvG2eOziSO/KOgrnoTDPLh7hG7DdwEdblRZxRH\r\nuRFnEkeK8LE1nuE+AWCT+smRpf1bluKIRv8CubPlFxoLMcF+5HU/SG6EfimOduxIhIEDB+Jjugtm\r\nEOkFEeoYy9bKyMglrICBFl/gMUIQBEFxhCD9HmyrO4M4IuKnjfzH2+CkkGkFR26
Ex1idjRUp1EG4\r\nmFnqSByFd9o58tfEkaMoSmvRy2qzLmRozVJKI5hISu6VQoaeEEd0184VV1yBj+cufh5ou/JK+Nul\r\nl8Lq1TF4jBAEQVAcIciF5SDRK8XTyB+YdN8R7jkyiiOqN8piZXnCaChi0bZwU1tdGQRJIRIQCKMV\r\nMdVRrC5KCqigMNiUnMtmjjy5S4MCQiExdRMEya8dEAMOj2111XrduI8fJNZBvxVHqam74Be/+AU+\r\nls/DMfLkIB8bMMCrng8QBEFQHCEI0mXQNqrFixd61ffc/bE6GZurg6zUVMgqqhPOTITbnqOsqCBN\r\nEA0KDIeoUB6rC4jIMokjfW9SnU0vZfDxCSVCy3wfXRz5B/jpblBAGBS1gcevy2N9fFZqUFBir1V5\r\n94Q42rhxPdx88034GL6AZw8R5EKgpKQIVq9eBdOmTYNJkyax51uke5lE+HJKCPwQMRsOHjyA4ghB\r\nLjTGjg2E119/DcXRebw42lqhsfFsK+HayOcQWdTm6GCHkYjQka/f2tqZr18HYf6yZc/Rr8XRrFlh\r\n8MgjD+Nj+BzpD62VCNLvHd7KCvb8mrh1K7QcPQrtp08DSE6dIueGNs7JkwAnTnCOHwc4doycRsg5\r\no6VFp7kZyEkHgHwdaGgAqK/Xqa0FOHKEU1MDcPgwp7oaoKqKU1kJ5JsCKCvjlJZySkoAiosBioo4\r\nhYUABQWc/HyAvDxObi7AoUMAOTkA2dlAVAdAVhYnMxMgI4Nz4ADA/v0ANhtAejpn3z5OWhpAaipn\r\nzx6AlBTOrl0AO3dykpMBduzgbN8OsG0bJykJIDERgBxLRkICwJYtAPHxAJs3A2zaxNm4Edo3bICW\r\nNWtg1/z5MDUkmHx7+1EcIciFBG39+v3vf4/iqE+9tEKYH4/GnU0Nd5Yog/AJjAVHD363vSGOhg9/\r\nhjWq4WMYnSME6Z+OUTFM
nToVcqiIcDg4dvvZiyMqipqauDCS4kgVSHV1HCqQpEgyiyMpjCjl5bpA\r\nosJIYhZHVBhJcUSFERVFUhh1VhxJgUSF0d691uJo926OKpCkMJLiSAojKY6oMKJQYWQhjiAuDoAI\r\nJErO0qXsHNdZBwnFEYL0E2g8KSJiAYqjvuNFQVZiLBGuidB5A6gNbJvo58RCVp2jR7/bnhZHhw5l\r\nwYABl5Jz5R58/J7HzKG3t1YiSH9m9erVsIv+oe9yATid1uKIogojKookqmNExZEUSFIcSdfILIyk\r\nc0SFkVkcUWEkxZHZOaJQYSTpyDWS4ohiFkZm50gKI7M4kq6RFEZSHFHnSLpHUiCprpEURtQ1Up0j\r\nChVGEiGOYP162LpoFixbFoniCEEuJObMmcXcI29Z9kj/GG93NBHIE73jKLTbGwjkSd5RR26PQPvp\r\nGgJ5cj9dTW4rCRXQfopSRigllICrrRja24oIheA6mQ/tJ/MEh8B1IhvaTxwUZBIywHV8P7iO2Qjp\r\nhH3gak0jt6mEPeT13YQUaGe3O8HVkkzYQdgOruYkwVZwNm0BV1M8YTM4GzeBq3EjIY68vp7criPE\r\ngvPoWsJqwipwHV0JzoYYcDWsILc/gLM+mrCc8D0465YRIglLwVm7mNxSIsjrC8F5ZAFhPnl9HrkN\r\nJ8wBZ81scNTMIswE5+FvwXH4G4bz8NfgqP6KMJ28Pp3cTgNHVSjhC3ASHFVTCVPAURkCjopgwiTC\r\nZ2Cv+ITcTiRM6HFx9OGHH8Bjjz2Kj93zJHFaKFT/n//jta2VCNKfmT59OrRQQUOFkSqOpECSzpEn\r\n14hChZFEOkcU6hqp0TqzMPIUqVOdI6tYnSfXSHWOOorVUWFkdozUSJ1EjdTJWJ0qjjxF6lSBZCWO\r\nqHNEXSPpHBFhBOvWQfPqHyA09AsURwhyIVFeXgxPPPEY3HDDb7zHOXI2a
+IIHFQc1ZGTBhFHp8kT\r\nvJ2Lo/bTVYo4KtPFERVGp4qIKCogr1Pyyeu5ujA6mU1us4ggohBxdJyLo3YGFUd7oZ3gaiXiqHUP\r\neT2FCKFd5PVdBmHkZKIoURdGzVu4MGoiwqhpIxFFcUwcuRo3EDEkxdEaIorWEDG0ikDF0QoOEUau\r\nBl0YueqXcWFUt4QLo9pFDAcVRrVEGB2ZS4RQOHmbiyNHzXdEIFGIQCLiyFkTRm6/ZjgPz+DiSAgj\r\nZzUVR58TQURF0WQOFUaVXBg5mDD6BOzlE3pcHCUkbIbLL7+cnP+24WP3PKA7jH72s5/C9/Pnuu05\r\nwuODIL0PLV9ol66R2TmSrhEVR1IYqc6ROm9kdo4oHblGZueICiOJ6hzJWJ153sgskKQ4ks4RRbpG\r\nVBhJ14hCHSOreSPpHKmROjVWp84bWblGEnXeSMbqpDBSnSMqjqgwEuKoPTaWnefWrVtLvr19KI4Q\r\n5EKhtLSQuUe3334bea7L7/viyNFkdI3swjViwqhaUMUdo9PlujhqKyG3umvUrrlGXBy1n8whwog6\r\nRlnMNXIRYdR+/AC5tREUYXQsldzuYY4RE0WaMFJco5ZtmjhyNSUQthBhtJnccnHkauKukS6M1hqE\r\nkashhjlGLuYaCWFUH8XRXCMijmojBAsJC4ggoo7RPCaQnDVzyO1sIY5mcmF0OIxgdI10x4i7Rkwc\r\nUdeICqMqKpCkOPpUwF0je/lHPSaObLY0uOiii+Dbb7/Gx+x5kJ2dwS6ETJ48CY8HgvTl85w5Umd2\r\njc7kHJlnjuSskad5IytxZI7VmeeNrMoYVOeIQoXR2ZYxWM0bmWN15nkjszg6k3N0hnkjTSAJcSTP\r\nb9u3J6I4QpALBSqKHn/8UfjDH24mzxsb+3isjggjBxdGhkid5hoRcXRKdY1KNdfIpQgjlyKMZJzO\r\npQmjA5prRMURd4
1EpE64RjxSt9voGjVvMwgjLU7XHM+EkZNF6TYQQSSFke4asUhdg4zU6a4RFUcu\r\nKY6kMKpbAg4mirhrpMXpqChizpGM033HInXUNdIjddQ1mqFH6pQ4nUEYEewyTlf5mXCMiDCirlH5\r\nx2AvC+oRcUSdIlo2ERo6FR+r5zXkXQBDhtwDo0a9hMcDQfp8QsLZeXFEhZEqjmScTnWMPEXqPDlH\r\nHUXqVHFknjeiAkmdN1IjdaprZI7UMedoD2waNwpGvzAOcndblDGorpFVpM5KHHkSRh3NGynOkVkc\r\nUTw5SCiOEKTfZp1D4corr4QRI54jz0E7+6hzxON04KDiqJbF6agwArs5TldujNMxYSTEEY3UCXHk\r\nOpHDXCMWqaNxOnXWSBNGumtEZ41YnI4Ko5adFnE6QgufNXI1J7BIneYaiVkjFxNI64gg0uN0LiaO\r\nlFkj85yRFqczRuocwjWikToHE0f6rJEhTnc4TJs1onE6Z7XFnBGL003RZ408uEaOio+JQOp+52j2\r\n7FksSjdp0qf4+DxPAgJeAD+/vzGnGI8HgniZc6RWeVuJIyvXyOwceWqqY1XeRRDxsL7MnHMjBLw3\r\nE6qLFdeoM011ZypjsBJHTCDtgvDb6L97L6Tu2Oe5qU66RlZNdWcqYzhTU506c2ThHFFoxA7FEYJc\r\nYGRl7Ye33vo3awV78sknYNmyJeT5sKhPfG8DBxZD0tYmNmdEhREIZBEDF0dVSgmDiNMJcSRnjahr\r\n5LKI07EonVLCwIWRcI2UWSMWqROzRu2siEEtYTDOGqlxOtU1osLIJeN0oohBiiNnvVrCIOJ06qyR\r\n5hoZ43R01ojPGc3WHCMHc4yEOKrms0aqa+Ss/lJ3jYQwGnry17D1yChFGPESBrt0jcqDwF72YbeJ\r\no/Xr18A99/wVfH192dJXfFye7wzDpyw6m5eXjccDQbxFHMkab/P
MUUeuUWedI4MwohXehUIc3QjB\r\nX8yA8HGvwiAhkvw+3+LZOVIdI1UcSWHkad7IHKtjkbqdEPE3Lo5sVBzt3QObRj9M3r4Bon5IcZ83\r\nstpx1NlIXUexOsU1grVr3c5zUVGRKI4Q5EIlN/cgm0344x9vZW4SvfI8f/7cXv0Dy8fnNOEYDB3S\r\nDEkJ9VqcTneNpDByd42YMKJzRm36rJGLiiPqHJ3IViJ1nShh8NhOJ+aMpGukzBrpkboN5HYdEUV6\r\nnE66RnzWSJYwRFu4RmoJgz5rJIsYOFwcuZUwUGFUPUMrYXBYxemEY+RzmpygjvnA0MaBsLX6JSaQ\r\ntEidcI0c5V0rjoqK8lh7IhVFv/zlL9kuI3Q5zp+lSyNYAUNKyk48Hgjizc7RmeaN1BpvirnGW43U\r\nue03kuLoIcgq4011qe/dyMXRZ3GaOHKkr4ewVx4QzpIvjB4/FxoVcdS4bjYEPXmn5j4NumM05O4n\r\nwsi2CYIfvw/87nsVstJ5jXfu9DfB7/bbIfibdSJWtwsi7tXFUW7I87qLdcMN4P/SVGi1Ekdnu/zV\r\nqsZbukbSMeogVufpPIfiCEEuwIarCRM+YjMLl1xyCQwadAu8+uorEBY2gzz3bGGtdz0jjo4RWggN\r\nhFoikqohaUuVJozAJI5cimsk43QuU5zOJWaN1Dhd+3FZ3b1XkGqq71Yjddv5rJGI0zlpAQMTRvGW\r\ncTrP7XQxXBxR16hBuEZ1UW6zRkwU1UWA44jqGulxOtlO5xAlDA4Rp+PtdNw1YpG6qi/J619aiyMi\r\njHxaCA2EWiKSKq+FrRUBmmvkYM7R+PMWR3Rv0XffzYRnnvkHXHHFFfDXv97Nfqe8pVq+r7N1azyL\r\nJa5ZsxKPB4J4kzhSHSOK2lKnNtWpwsgqVqfG6TqcNyrSxFHy/gKo2xYNgXdzYRK0NIW7RtnrIUCI\r\nleCv50H4
qMFcPE1Yy8VRlvLxaRGQPG8aBL34HhdHaT+Av49YcJ7Km+qyJvjxz38/ytI5qp7/CfhJ\r\n9+qp0RA+dTE4OjNvpDbVSedI3XFkdo3UOJ3qHFEsnCMURwiCuFFYmAurVq2Ajz76kJU4DBw4kDWJ\r\n0QgUjeHRSN60aV/AihXLyfNVEnnOzO1CcSSFUR2hilBBKLlq18kAAFpDSURBVIJ7hxQTkVTm0TXi\r\ntd3qnJFwjOiskaGh7oAmjmQJg3SN2qk4kg11plkjYzudrO7me424a8Qb6likTps1kpE6fa+RMU7X\r\nkWukOkbzRUNdOCticFjOGn1t2VCnVXerO40qg3VhVEeoIlQQiohIKiIiqeQFFqlznKU4ysnJJOeZ\r\nVWyu7YUXRrCYFxXa993nxxzKvXtT8PHVhWRkpMPVV/+KiU08HgjihYUMVmUMcvmrp6Y6c0udxDxv\r\n5FEcGRn9re4a5Ya9wN//wCdQlHUI6jZ+x6N3g4OhlbpHWauFAPKBwM9mQ9GuA3qkzrZCCCc/sO3J\r\nZM5R1oTH2H39PYgj2LtTOEk+EL5su3ukzkocqe6RpwWwaoW3p6Y6GatD5whBkHOloOAQeW5Zx6qW\r\nx44NZE7A4MF3wrXXXgP//d//za5e/+Y318Mdd9zO9ir985/Pw5tvvsEE1tSpk9nnLVgwD3744Xv2\r\nB/TmzXHkuW0rpKXthvT0NPI8amM1xNIxUoWRj08BIYeQBUOHZMG2LYVus0ZWDXWaayR2GunCaL/R\r\nNWpVqrvZnJGI1LVyceQUrpFTi9QZXSO206jD6u4YgzDS6rstXCOHRXW3LGGQDXVOU3U3jdPpwmga\r\nb6dTZ40q1Ya6EO4cCcdIFUY+BYQcQhYRSVnXwNaCEeykMXv2dzBz5rfwzTdfw5dfhsJXX02Djz8O\r\nYj9f+rP+85//BL/4xS/gxz/+MXMchw9/ms3ArF+/ts9Xx
3srNKJ4221/YRcq8HggiBeLI4p5v5Ea\r\nq+vINepMjbe2AFbG6u6GqOhICLpRiiN93ij3mxfcxBPnHagW80a5YW8bP3bffyArJRsg/QddHKXy\r\neaPcSUIcffC9ZawO9m7XxFHY4i2eyxg6EkZWrpFECqMOyhjQOUIQpNug4oZGfKj4oQ1kU6aEwAcf\r\njIM33hjNXATqOA0bdj/cffddbMaJulDXXXcdmz356U9/CgMGDICf/OQnQhhVE8oVYZTNhJGPTzoR\r\nRxmQFJ9vWPiqttOpC1/VnUbtIlIn9xoZXCMtTmfea2Q1a5RgcIzYTiNt4et6Q6SOzxrpe41YQ11D\r\nZ1wjsfBVcYxYO90RWd89y7Tw1bjXyOlx1kjsNKqYxIVRNaFcEUbZXBj5pPvAkIxrICGfi6ORI0fC\r\nyy+/DK+++iqMGTMGnn767/Daa69CUNB4Ipq+YS4jFbk9Fb1EStjP4JFHHsZjjiD91Tk6034jitk1\r\nsipj0Cq8iTh6SMwclVaCY9tXmsAJj8syOke+70K13HFkXv5Kyxiy0yBr2TQtYucXFAOQtkK4SveB\r\n7QAVR9sg/DEf3Tli+412GsVRGrlPZ5wj2VSnCiOreSNzrM7KOTJF6lAcIQjS59Edo2KDMKKOUVJ8\r\ngbLTqHOuEdttpLhGanW361iahWukxumM4sjZpEfqnKY4nVNpqFNdI32nkVWcTrpGkZ4b6mpFQ13N\r\nHMNOI33W6GsPC1+5MHKyhjrVNeLV3ZpjVGwURtQxSih4HhxlH4C9dFyPLYFFOg8VpTfffBP5OyUH\r\njweC9AdxZG6pk6hNdbKMQXWN1GidpyIGudtIEUep+XzHUfJ7dwmB9Hew5fCZIxmb83t+PGxavhw2\r\nzfwCAke8D7kH+cxR8HOvQ0xENBTFR0PwHcJ9+poIkINbIEh+7mMBMPp23V3SYnXpybo42r6Xxeqi\r\nRN
TP/6V3YdOc5Xzm6HzKGMxNdVaukRKpQ3GEIIgXiCOjYzR0SC4kbSnhe41OW80aFRJRpLfTuVV3\r\nK46R0TXaK1rq0vTq7tbd0K65Rts7dI2cjbpr5Dy6Xlv2yiDiyNmgV3fLhjotTifFkYjTOWoXc9eo\r\nToojvbrbfaeRcdbISYsYqmdoJQw8UmddwsCgC18rPnNzjIYeuha2Fr3AGuoc5ePBXvY+EUjvozjq\r\nYyxcOI9FGPfu3YPHA0G8vZDhbJe/SudIiiRPZQxWzlF1gRBH/wCbEEdQkgSBMh73whxoKy2Ftj0/\r\nQNADvqZY3cuQlZXPxNFoU+TO/8UpUJbJ9xtlffGq3mIXMAGiAh9lrwd8toI7R5o4ekQ4R2lQt2Si\r\nVsrg4/NvaPRUxiCLGKxidWZxZF7+ap43kgKJOkc4c4QgSN8XR1wYDR2SD9sSytx2GmntdKekMDIW\r\nMchIXbtwjdQSBhdrqNtnjNO17jlDCYPiGhFx5FQjdY0bDdXdcq+R3GlEXSOXuYSBzhmpcbraJcI1\r\nUooYZKSulrfUOWqUhrrDMw1xOl7drbhGijBymoVRZTDYiTBi4kgIoyF5RBQVB4h2Ol7CYC/7gAkj\r\nRxk6R32JhIRNrPGPznLh8UCQfiyOZKTufMsYKJpzRKiuZhXeTBhVVHA87Ddqy7RBIxE0rdm5bjuO\r\n2tLToXXfPmjdn6UvgBX7jRz7UqExOUXfb8SWv+4X4iidoy5/ZQtgd0AjETWt23ZalzGcyTnqzH4j\r\ndI4QBPFWBg7cSURRpb7w9VQld41OWbtG+l4jXt3NhRHfaSTjdKpj1C6XvSqukbbXqMV9r5GhhEE0\r\n1GmukYjTuRhizqhB7jQS9d31K5S9Ru6ukT5rFAEOIozYrJHYaeRwK2GgkToep1NdI7rXSKvuppE6\r\n2VCnxekma3E6R+VnbOHr0EIiikp5dTffacSru6U
wspe+x0Bx1Degi5tpMx2d8cLjgSD9JFZnnjWy\r\nco6s5o2s9ht5co7YjiNFHFFhJKHCSIojVSDJeSM5c9TR8lcpjKyWv1JhJMURi9UpwkiKo9RU4/JX\r\nGauTs0Zy3qgzLXVnK47QOUIQxFtOGlQYwelqcqsKo1KPcTpewiAidWLhqxapEwtfXcdslgtf9RKG\r\nnWLeyKq6my97NS58VVyjo3zhq3SNXGp1txBGliUMMk6nzRktUuq75yl7jUwlDGLWSMbppGvkNMfp\r\nKo0lDEwcVXzKKZ8IdrrwVdtrxON0DsU1speORXHUB6A7oe66azCMGfM6Hg8E6S/iqL1dnzsyzxx5\r\nco08LX81O0dSFJldo7NwjgzCSBVHZoFExZHiHDFU14gVMVi4Rqo4oqjCyMo5snKNOnKOOlr+Kl0j\r\ndI4QBPEecVQlhFGVaa+ReeGrlWukV3fLha9qOx0rYTgmSxj0WSODa9TsHqfjrpHSUCd2Grm0nUZr\r\ntDidvvB1hVLfHW1yjSINDXVs4auI0zksFr6qJQxOpZ2OukYO1TVSq7uVvUZcGHHXyFExkTBBcY0+\r\ntHCNxoKj9F0UR32AF18cyXZFlZUV4fFAkP5ynnO2EJqJQGqCdsdRAhE3jnpot9cSjhCIoLHXkPNg\r\ntSleXsrOhS6Lxef6zG22tt/PdVxvaXVpyYk09/Nf605obzUtPWcXCPXzH78oqC87Z1Fyt3ZWcVGw\r\nQUlL1IvzXq2MkNOkhKl8SJ73tIuBM0VSQp7vxLnOonhIvxAYolwEFOc67Tz3EYuO03OdLByi5zrH\r\nWVwERHGEIEjvXVGjJwMZpzutu0YuDyUMLm3Za7ahoa5dnhTMrpFh1kieGBRhpLpG2pyRjNPps0ZO\r\nRRy5LBvqLEoYVNdI7DRyKAtfmTCSDXWsvtu6utvgGhFhxF2jUH3WSNlpxF2jz8DOThb8hEFdI7s4
\r\nabBZI+Ea2cvGaa4RiqPe54svprL9YXTBLh4PBOlPsbpWIoiIOHI0ERqJGNLFEVBxxKLlaoKiTIfO\r\n3p4qJudEscaiLV9bY2FvzYaW+kPQcIRQkyPIVjhIyOIcziRkCPYz6qtt5JZQnU5e30duKXvJ62nk\r\nlpIK9VV7oIFQX5VCbncz6it3QUPlTnKbTG6T2W195Q7Cdk7FNkESIZFTniDYQohX2EzYBPVlG8nt\r\nBmiuiIFTVUQsiV1+fMH5Fzw6Ti8CVunnOzZXK+LjMh3hdp4rpec5ehHw3bM6z6E4QhCkl2aOiiFp\r\nS60Sp1Nco1Oqa1TgsaFO7jQyu0ZWcbr2DosYRKROcY2c2k4jXsJgXvgq43QuQ5xOXj0zLnzlsboI\r\n09WzTsTpWH23aaeRx4Y61TX6lJwsVNcoiFOmnjDGsStp9IRhL3kHxVEvEhMTDVdeeSUkJyfh8UCQ\r\nfieOrF0joM7R6RrmHElxBFQgyXi5tsbC7BrlQmNtHhQXFUJRUVE/JB8aymJ5SkI935nj44aExERD\r\nQoIXDr0vznPcNbKXBKI4QhCkr7fVnSYcg6FDjkJSfKV1CYNyQtDidCeztQgBb6fLsNhrtFfZa7Tb\r\nsoTBqVR3O8WcEXONRJxOb6eTrtFaFilg4kiJ1FnuNTIII+EayTidmDOijpEsYbCK1LntNRJxOqdW\r\nwqDHC+wVxhIGfqJQ54yUmEG5MVJnR3HUq+zZs5MtR46KWorHA0H6Y6zO0UzwEKmTc7daIZExXm4V\r\nqaPCqH+KIiMNZWuEMJpqmq0NcRNHajpCxul4MmKcONed3XkOxRGCIL0kjo4RWggNhFoikiqISBKu\r\n0akiXt2tNNS57TVS4nTtLGNtvdOo3WrOyMNeI6cya8TFEW+os47TedpppETqlFkjT64RjdOx6u6a\r\nmR53GunV3aGKY6TGDPiVNLssYTDFDOSVN
NU1knE6R2kgAcVRb1BQkAs33XQjBAd/iscDQfqtc8Tj\r\ndECEERVH7fY6t0gdmOdu22SCQsbpeILCcSy3HztGRoqL8uFU5ddK8ZA8132mJCTU2dqP3Pb3yVmj\r\nsz3PoThCEKSXxJEURnWEKkIF2300dEghEUkFhoY6OWukxul4dTdvp5OzRu3H9SIGt71GrcY4nVbd\r\nzZrp4pWlr2Lhq6mEQV346mrQZ41U18ilxulqlRIGC2Gku0az2E4jpxhMdRiqu82zRl+YThQhSkPd\r\nZ1o7HT1R2K0GU8UJQ4ojeTXNXvI2iqNe4IknHodnnvkHHgsE6acUFxJxY2/hrpGYNQJHnSlOJ+aN\r\npDhqK9VKiVyKa+Q6eQhaGs7VNcqEuYH+4B84F3LcPpYGoSOGwfhFm2HuGH8YMyu+zwikpvLlSlIi\r\nxK2IQW9i1WeNjM6RjI4HntV5DsURgiC9JI64Y6QKI7oU1scnh5BFRFIGJG3OtnCNDmqROq2ZR2mo\r\na/fQzqOWMOg7jaRrZGyok5E6rYSh0aqE4QcL18i800i6RqK6+4gpUndE7jWaaWioMy989SyMrBrq\r\nPtEidfpw6oduJQx24RrRE4a95C0URz3MxIkfw80338TcIzweCNI/OX38OByrr4fjDUfAcfyIpWuk\r\nNdSdVmaNWAmD+9xtw5Fzj9TFhfqTc6svRKYZ358TH0re7wMzkvZCiK8P+I6P7TPiqL5sjVI8pKyq\r\nMETI9R1++qzR+6bz3DvkdXSOEATpQTIzbbBx43qIiFgAX375OXzwwTh49dVXYPjwp+Ghhx6Eu+++\r\nCwYNugVuuOE3bMElnbHgwqiaUK4Io2wmjHx80ok42g+Jmw6KnUbZepzuhHU7nV5byl2jdiqOWsRe\r\noxZRW2qK07FZo2Z1p1Gc0k63XhQw8J1G2rLXBmMRA6swrYtyL2Eg4shxhjidWwlD9deiiG
GGqO6e\r\n5l5lqmavxayRjNOxEgazMBLV3Xprz1hDEQONGqA46lmio6PYY4DOG+HxQJD+CxVGLTU10FBSArX5\r\n+VBfcAjaGsuFMKIV3tXGBeiaa2Q9d3s+4qgoLRJ8iQjyn2F0hqIDfcHHdzyk9cFoXX1pLD/fVenn\r\nO0N9N01JlAUZVlVoFwKVIoazPc+hOEIQpFPQBZXx8XHw1VfT4M0332Ci53e/+y1cdNFFMGDApXDj\r\njb5sR8vw4c+wJZaffDIBpk8PhblzZ8P330dCXNw62Lo1Hnbt2gHp6WmKY1RsEEbSMeJxukPWs0Yn\r\n1H0OSkOdttdICKMzVHe7lDidca+RsttBnTUScTqX2O2gttO5OpgzMrhGTByFGyJ1anU3LWFwqiUM\r\n1V/qJQzyClqV2tjzqZa/Vvca0SKGjqq7VdfIXvIfFEc9xN69KfDzn/8MVqxYjscDQfo5UhjVFRRA\r\nVUYGVKSnQ9HOnVBlS4PjR/K5MDKUMKjiqEhzjXh993mKo6IcmOHvYxRCefEwQhNMmTBrxGAYMSNO\r\n/xxbHAQO82HOEnWdQqJTyOckw/hhvjBmVpL2deeOGQa+/iHa17XFhoDv4EBIzjtfcbTWGCGvdC9i\r\nsEvXqFxvqGPnuTJ+IdB+DgkJFEcIgliSlXUA5s8PZw7QrbfeCj/60Y+Y8/OPfzwF48aNhdmzZ0FC\r\nwmbIzT14jrE6o2M0dEgOJG7OZSUMhkV3J9yFkUvMGnmu7uYNdby+2+waJRlcI726W99pRIWRS8Tp\r\njK6RFEamhjqTa+RgDXV6nE66RnKnEavuPsxdI6da3a3uNNLqu01VpqK6W2uoq9BnjbT8NbuSpsTp\r\nTCUMPH+tu0YOFEc9QlFRHnssffTRh3g8EOQCQDpGqjAq2LYNcjZuhKzYWMjfuglaq7KtXSPDuZCf\r\nD89PHBVBWmQgEzqh8TlcxKwcr0T
tMiFksA/4TpSxumQYQ0URET3xaSkQGTJC3DeHiCjy/sEhkEnv\r\nl7kShgnxNDcljz3PzaUfHzEX8oq6ShzprhErYSiXDXUfu7tGym6jcz3PoThCEESDujo0EnfbbX+B\r\n//3f/4V77x3K3l69Ogby83O6eOaIC6OhQ3IhKT5fRAiM7XR8+zeN1GXxWSMtUrffFKlLc1/42mq1\r\n08h64SsrYWjaqO01orNGLq2Iwb2hTgojl6dZI7nTSKvunqtvBT8yR9kMPss4a3SYzxo5DZvB1YWv\r\npj0P2sJX6RhNsD5ZmFwjeSXNQa+mFf+H8G8URz3AyJH/ZI4rHgsE8ZaLhPshMXELc3rpBcEpU0LY\r\nOfH111+D559/Dh5//FH429/uhTvuuB3+8Iebteg4dYcHDBjAhFF1ZiaUK8IomwqjdesgPToacrds\r\ngOayDH23UQeROno+bDiSe35RtZw48CdCxjcwmr3NRMywGaKkgYujwUIcZcaFMCE1ZlYspCSnQHLc\r\nLBbLG7/SBimRY5gYis4kAksILsqoWSnkc+OYWKL3K+oKcSQjdW67jSYYlr5qs0ZlXBzJC4FSHNlR\r\nHCEI0lmo6KFzQn/8461w+eWXw6hRL0Fk5BJ29ac7/92BA3cSUVRkWPhqbKizjtO5tIY6WcJg3mmk\r\nLHttNblGLYprpMTp2MLXpjjNNXKahJHBNTI4RqprFMkb6mqtq7sdbgtfZxoWvnreaSRdI2Xha4X1\r\nwlcZLzA01JXy7LVdmTNS43SM4jdRHHUz33zzFVx33XXn7LQiCNIdMdc9bAkzjYC//fZ/WDLizjvv\r\nIOena+F//ud/4LLLLoPrr7+OiZ9HHnmYXeCgsfKgoPHw+edTYM6cWbB48UImnjZsiIVt27ayi4z0\r\n69JZ3CoijKhjVEyFUVKSJoyoY9RSmW3RUKe6RvmGBehdIo7kjJHPKIhPi2UiZkxk
itZoZyWOjPhC\r\naFwmFNmiYTB5OzA6iQmsYaErIZJ+3RFzIYm5Uf4Qn1fUNeKo0jxrpDtH+jnPyjUSRQzyXHcWFwFR\r\nHCHIBRybCwx8G6644goYNux+WLZsCZSWFvbYv8+W46mNPOadRrS+W3ONpDA6wMRROyOdCCIijlrd\r\nXSM9TmecNXI2JfBZo2YpjoQwUqq7ObGijEEXRy7qGtXzOJ1LukYWJQxOLVLHXSOH4hjxZa+ztYWv\r\nzppv2ZyRQ3GN9DidqYRBCqNKdeGrLowMO41Ea496spCDqXax78FR+rYmjFAcdS80fkr/yKIzd3g8\r\nEKR3SoPoouUJEz5i9fmDBg2CSy65BK688komfJ5++u/sfPj111+xwpQdOxKhoODQef+7BscoLo6I\r\npCRorT7EGuqMu42U+u6TcreROUVxkIijQ+ctOHLiZzCh4+vrw0RMbE6RtTiKncjuNzE207IaPJTO\r\nIvkOZveZlUzuH80dpMG08W5MZBcVMqwVMfLPjK6RaYefub7bruzwc1BxRISRveRNFEcIgnguVqBL\r\nJ6lLRMsTUlJ6pzGLiSNt6LTQNHjKTwZadbe218hYwiDjdO0UdacRFUbN25U4nbLwtSlB32lESxga\r\nzSUMazkNq41xOiqMGjzMGdVHcnFEhJFsqHOwAgZCrcVeo5qZQhgpJQysnU4vYZDCyBinU4sYzPEC\r\npYRB1Jl2VN0tr6RRYeQoHoPiqJvIy8tmV55nzJiOxwNBeoDi4nxYs2YlfPxxEDz22KMs5nbppf/L\r\nHKGXX36RJSXox+kFwm6fMxTCqHTPTjh+pADAXsPru7WGOqsSBnqxUK/vdokLhVwc5XaB6EiD8b7c\r\nCfIds8ggeFRxRIsX2MyRzwhYFJfCBGZS3EqIS+PzSkmzRgg3KRBSWHnDSuYm0feFxGV2kTha417f\r\nXT5BzBuZ9/iN09pYtRIGJ
VLnKEHnCEEQC+iV61tu+QPcdddgSE5O6tXvRRdHPE5nKGE4aeUa6Y4R\r\nF0d7tYY67hrttt5rpMTppGvkZMte9Z1GWgmD4hi5uUbqXiNa3U1njWRDXa0sYYhQGurMrpHuGPE5\r\nIxmp+0YrYnAa9hqFWrhGIRbxggliAV6QwTHiex6EayRiBvJKGjtZFPOThZ0II3vxGyiOugl//yfh\r\nueeexWOBIN1EWVkRrF27ihUFDR58J2tQpTvE/vWvURAWNgO2b9/aa9/bzjVr4EQtOc9pe40O60tf\r\n2eJXxTViEXPdNXKxi4R0AXq2uFiYBQ01h7pEdCTNGsVFTKzNszhya6szCp+8lEVsBmmYdn/hJvmM\r\ngeQuq/JeY7n01SGWnKuROn7Oe0+01OkXAh1aQmIMiiMEQYzMmzeHRehCQ6f2ie9n0qRJ5Mm/QFlw\r\nJ6+Suc8aaa7RMb7wtf246hqZFr5axunEwlc2a6RH6vTq7vXawldDCUNDJ1yjOjlnFOFx1kh1jZzM\r\nNZqplTAYZo0sdxqpNabB7gvwKox7jYzZa2vXyGFyjU7kY6yuO/jii6lw0003dvv8HoJcaBw8mMGE\r\nzxNPPMZcIbpK4rXXXmXzsocOZfWZ75NdBHRb+lppmjUqY4tfDRFz7WKh7hrRBEVXiaOzjuJlZkIm\r\nIS+vp/ccrbFc+mo1a6S7Ru9q8XHVNUJxhCCIgQUL5rEqbrprqK98T9OmhUJTbYY2a+QyuEYHLV0j\r\n6Rjp7XTKrJFY+NouXaMWIY5U14i20yk7jfSFr3qcjgmjo6uUZa8xoozB5Bp1sPCV7zSSrlG4Nmfk\r\nECUMDoNjpM8a6a6RLo6c6qxRhVz4Knc8uC98dZQrV9C0djqLSJ3iGuXv/gBCQkJQHHWxS0vnjOiA\r\nNh4PBDl/srMzWCRu6NAhcPHFF8PDDz/E3rbZ0vrs9yzFEXOOZKSOzRt14B
rReDm7SJgrLhTKiDkV\r\nRzl9blFr94qj1aZznnV9t3rOs7vFx98U5zoURwiCCKhTRK3wnTu396nva/nypZAYH2OI07GhU801\r\nOqi5Rlwc8Vkj7hqZG+qMJQxOs2skHCMujOK1vUayoU4vYbCo7q5XdhpRYURdI3XhqxanWwSOIzJO\r\nx10jOWskI3V04Stzjiwa6rQSBtpQV2nlGslowafaXiO9oc6qsUe4RhY7jaQwcuSOhhMv/QEOX/xj\r\nKPvxjyHlwQcgcuECFEfnSUFBLvz2tzfA9Olf4vFAkPOMzEVELIBHH32EFSjQ6mxaqd3VqyW6Uxyp\r\nrpGxhKHM3TVS6rvVIgbW1no8A44eudDE0Sq3lRVurhE7143TxVGJUsRQcm7xcRRHCNKPoTlsGqVL\r\nSkrog7GIA+yJKvtAgptrpFV3s51GvIRBLnyVwsilxunUIga518hcwmBY+Bondhp1FKdbIRANdQ0e\r\nInV1xupu7hrpC1+dR4w7jczCyKmVMEwzFDHwEoYppgV41g11xqHU9w07jaRjpEYM2JW0kjeZMGog\r\nwvkwoZxQRNhKBBKKo/Pjn/98ns0a4bFAkHPjwIF98O6778BVV13F1kzQi3zUOfK2/w8WHz9doxcx\r\nnJZFDOWaMKINdVoJQ5upiOFktnJOzIDm+oMXlDhqKl1qmK81trKO18536lyt5hoV/1tcDOTO0dnE\r\nx1EcIUi/vXp9CAYOHAjz58/tw/Wq+2HKlMmwbetqaKrZxxwjGadT9xpx12gfw1jC4GHWSBFGTsU1\r\ncso5I1bdLYoYzJG6BjVSt8LoGtUtA5dWwrBYcYzcSxjYnNERo2vExFGNsYRB32v0pdhrpLpGk7Wd\r\nRnaLEgZ+otAb6vSFr6a9Rqbs9Yn8tyB/93jmGNUIYVRIyCCkXnwxiqPzjLDSHSm0pQ6PB4KcHfRC\r\nHl2uSueI6E6hLVs
2evX/D42PN9cXKA11VcaWujZjpM5QTCRKGFiCQjS22lsOQHFR4QUijvKhrfxz\r\nU6ROdY2Uxa9y3kjs8TOuqqCu0euQv+t9CA4ORnGEIBcyY8cGwlNP+XvBYO0BWLYsEkJDQ9lVHaRn\r\noDNGNEonHSMqjPYRkoU4ioqKxMfRWUJnH6hTSx1bPB4I0nnWr18Dfn5/Y3uH6LkrIyO9X/x/LV++\r\nDBIT1gHY+awRj9Tp9d0ui3UWqmukzt7KFMXRI1kXhDhqKI1Rmlknus/XakUM6qyRKUIuxJGj+A1Y\r\nPP9zmD59GoojBLmQB1fpMHhq6i6v+r7XrVvr9sSFdB90xqhQEUa7CetFrI7+LPCxdHbQQfF33nkL\r\njwWCdJKEhE3w4IPDWHyOlisUFub2s1Y9ER/P3KntNoLT5abdRryhzmXea6SIIxqpkykKGjGnAqn/\r\nOkj5Qhjps0Z2scfPIbCblpyzhroSY0OdWjoUt+IzFnGcP38+iiMEuVAJCfkMnnjica/7vvfv34ei\r\npQeJXDAfEokY2nPxxcwxosJoqShkoD8LfCx1nsmTg9lsBB0gx+OBIB1Dl48/+eQTzCn65JMJ/U4U\r\nWcbHEzdAU+0hcLEondW8Ub6ba+Q6YYqXy2KiY3vB3rIXmusOQENNBjQclpC3D+8n2KC+Oh0aGPsE\r\newVphFSor9oDDYT6qhTCbvI6ZRfUV+6EBkJ9ZTKjoXIHuaVsh/qKbYQkQSJhK6c8gbBFEC/YTNjE\r\nKdtIiCNsEKyH+tJ1gljCWvK+1dBUtgxOVYSaouQeXCNl1si8x4+6RjI+vjD8cyZQ58+fZ3keRHGE\r\nIBcId9xxO2v48cbvffv2RBQuvQz9GeDjqPPs2rUDBgwY0KvLJhHEW5ocaWyOPl7ef/+9C2Y2D+Pj\r\nvRcfnz59uqVj1FF8HMURgvQzcnIy4Sc/+QmUlBR47f8DdS1orIs+
caFY6RnosabHHB2js6O8vJhd\r\njJgw4SM8HgjSAQsXzoNrrrma1XJ7W+Qb4+P9E0/xcRRHCNLPWLo0gs0+4LFAkO4nOPhTuO22vzCR\r\nhMcDQaxiZTZ44onH4Prrr4Pvv8eiF4yP9x08XQxEcYQg/YxJkz6FkSMD8FggSDdDr37T4pMdOzCG\r\niCBWzJs3h80VjR79KhQV5eExwfi4V8THURwhSD9j1KiXYOLEj/FYIEg3c//998G4cWPxWCCIiUOH\r\nstgi5Ouuuw5iY1fjMcH4uFfFx1EcIUg/Y9iw+1m2G48FgnQfs2fPgt/97rdQXJyPxwNBFOjOomuv\r\nvQYCAl5AtwjxSlAcIUg/Y+jQeyAycjEeCwTpJnJzD7K9LHhFHEGMfPxxEFuEPHfubDweCIojBEH6\r\nBrQ5a8WK5XgsEKSbGDPmdXj66b/jsUAQJUb34IMPwJ///KcLuokOQXGEIEgfhJ6c8Io2gnQPtHyB\r\n7mix2dLOfP+iPKh/5WWoH3ApHCZUkNcrMGaE9DMSEjbDr3/9axg58p9evUICQVAcIUg/5Z57/grL\r\nli3BY4Eg3VTC8MknEzp13/pRL0GDjw8cJpQTigh5VCDhcUT6CQsWzIPLL78cZsyYjscDQXGEIEjf\r\nhEYbaH0qHgsE6VpWrvwBfvWrX3Z6yJw6RjVCGBUSMgg26iDhsUS8iMq8bGiY+Q00fTCO3Vbm57D3\r\njx//Ppu927hxPR4nBMURgiB9FzoL8c03X+GxQJBuiKyezWOLRumkY0SF0T5CyqWXwurVq2HatGkw\r\nadIk+Oyzz5Buhh7nL7/8An5YvhgOHjyAv8tnQU3cOnAQAQTkd1fiuOrn8J7f32DQoFtg7949eJwQ\r\nFEcIgvRtXn/9Nfjwww/wWCBIF0Lr8W+66caz+7xXXtYcIyqMdhOW3XknJCYmQktLC7S3twO+dP8L\r\nPc70eO/at
QumTpkMmZn78Xe6M45Rfo6bMJI0XPQjKMy04XFCUBwhCNL3T2Y/PPUkrLrtL4b4A4Ig\r\n58ett94K4eHfnd3nFeZCPhFI6QMuZY7R8rvvhuwDB1Ct9OJLTk4Oc5PQQToz9BxiJYw0gUQ+jscJ\r\nQXGEIIiXxR+uYu/H44Mg587330fC9ddfB+Xlxef8NWiUjjoX+NL7L1vjY2HZskj83T4DdMaoI3FE\r\nP47HCUFxhCCI18Uf6PvRQUKQc+evf70bvv326/P6GtOnT2fRLnzp/ZfmpnoIDf0Cf7fROUIQFEcI\r\ngicxBEHOhu3bt8KVV17Z6YY6T9BSAJwx6jszSDRat27dWti/fx/+nnugMCOdzRbhRTcExRGCIBh/\r\nQBCE8a9/jYJ//3vMeX8d+sc4vvSdF/rzWLJkMWP79kT8XTdBW+hoG93Yv93L2ukwro2gOEIQBJ0j\r\nBLnAKS7Oh8suu4z8oZhyQYmjssRwGD16NIRtKjqv+5hf2lobobqsDIrKqqHV0XfEEQUdJB26t4ju\r\nL6J7jFhs28OeIwRBcYQgSN+dOSInL5w5QpCuZcmSRfCXv/y5S75Wb4qjophA8lTgQwiA1NYz398W\r\n5s/u7xdmO6/7KLIIYkb7iO9BMgiCY7LA0UfEEY3Y4e98CcyYMR0uv/xyWLBgHh4PBMUR0vcpKSmC\r\nVbg8sIeZBFM+D4WIpRF9vvoV2+oQpGsZPvxp+PTTiV4ujsogSBElo6Nyz/gZuREB7L7+HQifztxH\r\nf2mFmOAgCI9NhKzcLEiMCoZB4vuJrXb0CXEUFRV5gf99UQAjR/4Tfv3rX0NCwmZ8/CMojhAvoLKC\r\nPZknbE2EhqYWOOVoJwC0EU7aAU4Ijp0mp6FTnBZCcxtAE6HxJMBRQgOh/gRA7XGAI8cAagiHWwGq\r\nBVUtABWC8mZyWm0CKCWUNAIUC4qOAhQ0AOTVcw7VcXII2b
UABwlZhMwjABk1AAcI+w8D2ATphL3V\r\nAGlVAKmVACkVnN2EXeUAOwnJhB1lANsppQBJlBKARMJWQkIxwJYigHjC5kKAjQUEcruB3K7P58Tm\r\nAaylkL8F1hBWHwJYRVhJiMkBWJEN8AMh+iDAcsL3hKgsgMhMztIMgMUH2mHBnhb4ZsUuCJnc95cH\r\nyvjD6ttvY/uO0DFCkHOHFjF0RaSuN8VRY2oYEyGD/AYJgRRE5JLJ16lOhiB/P34//0AY7efjJnw6\r\nc5/Ov1RDoBBHoamNfUIcUS7U3/PU1F3w5z//CR588AE4dCgLH/sIiiM8CN5wRacYpk6dCgcP5oDD\r\nBXDayaHiiHLSwYXRcUHraQ4VR0wYtQlhdIILo7rjQhwJqEDSxBGh0kocNXFRVCiEERNHgtx6LoyY\r\nOKrj4uigSRxRmDAiomhvlSKOCHsqFXFUwcURE0hCGG0TGIRRsRBGhE1CHMUJpDhal68LI4M4yuHi\r\n6AdFHH2fxTGII8JiJpAAIgizNnjP8sCgoPEwevSr+PhBkHMkKSkBrr76V1329XpHHLVCVIAQRG1F\r\n1oKkLQsCxPv9AsMgJjxIc5k04dOZ+5yDYPPx8YPkOkBx1IvMnTsbrrjiCvj44yB83CMIiiPvgS4P\r\n3LlzFzjbgYkju0sXR9I5ohw/zZ0jSnMHrlGd4hwdEc7RYUUYMXHUzMWR2TUqFAIp3+wcCYEkhVHW\r\nES6OKPsV54iKo32KMNLEUaXJOSrjzhFlm+oaFZtcIymOCrkw2pDPWZfHiVWdo1xdGGmuUTZ3jZYL\r\n12hZJmepcI6WKOJoESE8eq1XLA/85puv4B//eAofPwhyjkydOhmee+5ZrxZHjrJYJkICInINUTif\r\ngChoE/epSw7l7/MLBalTssL9DcKnM/fptDDKitIidRG2XlJGKI6gsDAXAgJegGuvvQbWr1+Dj3kE\r\nQXH
kXdDlgY1NLeB0gcE5oqixOivXSIqjBgvnqFa4RoeVaJ3qGpUqrhGL0ymROooUSLn1xlidW6Su\r\nRo/TsUhdFUfG6qQ4ShHO0S4RqzO7RtI52mLlHBXqsTrKunyjMFpljtQJVHEkY3XLhHu0RIgjJoz2\r\nAyykpNR5xfLA+fPD4cEHh+HjB0HOkVdffaVLr6b3hjhKDvXTyg/8/Pw0UULfji1zGIoVfHyCFeFj\r\nnCfqzH0685IbG8y/zqBASK5u61NtdReSOIqNXQ3XX38d+Ps/iTE6BEFx5J3Q8gWnq50JI9U50lwj\r\nBxdG6rwRdY2aT5mcIyGO5MwRhblGx4xxOkpZM0c6R2qsTjpH+SJSl2t2jWp110jOG1GBRF0j1TlK\r\nE66RjNWZ5412qPNGpdw1cnOOCsXMUaExUhebp88cSddIiqOVwjlaISJ1VCCpwogihdFiIY4oVBzN\r\nt3nH8sBly5bAPff8FR8/CHKOPPDA/TBv3hzvFUdtNh6F8w+E8PBwCAsLY7eB/nz2yC80mQuWqNHC\r\nFQoDXmTngE1Bfgbh05n7nLEBL0J8jYBwaITef7kQxRFdZPzaa6+yWbqu/N1GEBRHSI9Dn8RdMlIn\r\n542kOFLnjU4bnaNmMW+kzRypZQzCNepw3qjZ6BzJWF3BUaNrZJ430pyjI/q8kYzVUWG0V5Ba6Xne\r\nSI3UqbG6hGL3mSOreSMpjtbkmsRRju4cyZmj5Qf1eaNlShmDOVJH3aMFNu9YHkivDNIBW3z8IMi5\r\nceutt3Zp3KinxZGs7w7PMjo0bVnhWq23rY1G72K0+SG/wGAIHj3IbZ6oM/fpePTJBn6aa+UPgYGj\r\n2Y6kAP/REJPbiuKoB4iKWsrcoieeeBwyM234GEcQFEfeL47MkTqzOJJNdcekMDqlO0dnitRVK5G6\r\nSiGMyk3OkVrGYHaN3Jrqjrg7RzYPkbrteY2wbk8Z
rNhTzQRPR/NGiRYtdbKMYaNp3ihWmTeiRQzm\r\nMoYVppY6ijZvlGEhjkSsziyO+urywJiYaLjjjtvx8YMg58igQbd4sThqhHA/44yQ/lIHoaJpLmgT\r\n763LitELFnz8giAsSMwThevCpzP3OaOLZUGYDcVRdzfRPfLIw3DNNVfDwoW4uwhBUBz1J3HkoYyh\r\nzaKpToojK9fIXMZg6RypZQzqvFGjexlDh86R0lInxdE+0VaXWtkGUwPclwL+a04WbFOa6miVt8cK\r\n7w6cI9ZUZ4rVuVV4C6RrZHCOMo2xukUCK3HUF5cHRkYugSFD7sHHD4KcI7fc8geI68IdYb25BLZT\r\n5Q1trdDa2Aht53QfB7S1ko9Z0Nbm6JP/v/1dHOXlZcP7778HAwZcCu+99y4rYMDHNYKgOOqXzpHd\r\nXMYgxdFpfbeRoYzBLI6O6+6ROVZXobpGFmUMWo33Ufd5I62M4Yh1hbdNEUa8xrsVpr4XBOMXJUJk\r\nUhZ8+20w/EaIpC/2OqzLGIpNZQyFxhrvDfmmHUfmMoYcUxnDQT1S971SxOCpjIEKo/k271geSK8Q\r\nDht2Pz5+EOQceeyxR2HWrLALRhydX2N4qlL2YCI4FcVRD7fQffLJBDZX9OSTT8CePTvx8YwgKI4u\r\nDOdIdY205a8WTXVHPdV4m/cbtXjYb9RoPW+U39AKYYEBcP8j/hC0qlqL1O1Li4XHbvKDD2Kq2cyR\r\nYflrtS6Q0kw13rsqquFZcTIds6bRzTXqTI235hrl6a6Rp0idOm8kBZIsY3BzjfYL12i/tTjqiydV\r\nenJ8+eUX8fGDIOfImDGvw7hxY1Ecda79AarLyqDMgurGNhRHPSSKvvzyc7jqqqtYU2lCwiZ8HCMI\r\niqP+LY4MkTpThbfbvFGbsuPItABWFUZW80YVQhiZyxjozBF1jwqUeaMN4aJ96K9hsJuJozb4aiQf\
r\nuI0s0mu89wthpM0cVRtb6mgZw6a1+lLAmTYujLQyhlIeqWM13kVG50ir8JbzRvnGeSNzU51axqDO\r\nHMl5I9U1UssYFu6XbXXecVJ98cWR5Pv8BB8/CHKOrFq1An7/+9936fN4u6OJQJ5IHUeh3d5AIE+k\r\njjpyewTaT9cQyJPk6WpyW0mogPZTlDJCKaEEXG3F0N5WRCgE18l8aD+ZJzgErhPZ0H7ioCCTkAGu\r\n4/vBdcxGSCfsA1drGrlNJewhr+8mpEA7u90JrpZkwg7CdnA1Jwm2grNpC7ia4gmbwdm4CVyNGwlx\r\n5PX15HYdIRacR9cSVhNWgevoSnA2xICrYQW5/QGc9dGE5YTvwVm3jBBJWArO2sXklhJBXl8IziML\r\nCPPJ6/PIbThhDjhrZoOjZhZhJjgPfwuOw98wnIe/Bkf1V4Tp5PXp5HYaOKpCCV+Ak+ComkqYAo7K\r\nEHBUBBMmET4De8Un5HYiYUK/EUcZGekwdmwgc4r8/P6GO4sQBMXRBSaOTJG6NiVSJ8VR62m9jMEq\r\nUldritQdVlwjq6Y6ihqpy1f3GxUmwx1y43oaEUeZfOGg32SbW1MdE0bV1vuNNm+J0iJ1QXF1Hpvq\r\ntprnjSyWv3a2qS5aWQCrVnibm+oWK+LIU6yuL55Uhw4dQr6vRfj4QZBzpLg4H37+859BUlJC1zlH\r\nzmZNHIGDiqM68sROxNFp8oRp5+Ko/XSVIo7KdHFEhdGpIiKKCsjrlHzyeq4ujE5mk9ssIogoRBwd\r\n5+KonUHF0V5oJ7haiThq3UNeTyFCaBd5fZdBGDmZKErUhVHzFi6MmogwatpIRFEcE0euxg1EDElx\r\ntIaIojVEDK0iUHG0gkOEkatBF0au+mVcGNUt4cKodhHDQYVRLRFGR+YSIRRO3ubiyFHzHRFIFCKQ\r\niDhy1oSR268ZzsMzuDgSwshZTcXR50QQUV
E0mUOFUSUXRg4mjD4Be/mEfiGOtmzZCCNH/hMuvfR/\r\n4fnnn+uy31MEQVAceaU4kmUM6vJXWcYgXaNGC9eoTggkWcRw2KKModyqjOGoWP4qkEUMufUOmPU6\r\nr3S945NYmPGBH3N+IvKNZQzSNZI13qnKfqPlC8VSwBsD4bu9bVpTnYzVSVGklTF4mDeSsToaqVsn\r\nXCNZxtCha5RlrPFmTXUWsTrpGnmDOCopKYCf/OQnkJ2dgY8fBDkPpkwJgbvvvqvrxJGjyega2YVr\r\nxIRRtaCKO0any3Vx1FZCbnXXqF1zjbg4aj+ZQ4QRdYyymGvkIsKo/fgBcmsjKMLoWCq53cMcIyaK\r\nNGGkuEYt2zRx5GpKIGwhwmgzueXiyNXEXSNdGK01CCNXQwxzjFzMNRLCqD6Ko7lGRBzVRggWEhYQ\r\nQUQdo3lMIDlr5pDb2UIczeTC6HAYwega6Y4Rd42YOKKuERVGVVQgSXH0qYC7Rvbyj7xSHNHn9NDQ\r\nqfDHP97K4nPvvvsOHDiwDx+rCILi6MIVR1Y13idN+43UCm83cXTcfceRFEgd7TcyR+rUHUf7doQb\r\nhm9vn5isV3ibxJG5xnvxVyKW9/dw2GRaAKu6RlqkzmLeaJPJOVonm+o8RerUpjqLeSO1qc4qUjfP\r\nC8TR4sUL4fbbb8PHDoKcJ/n5OfDb394AQUHjuyhWR4SRgwsjQ6ROc42IODqlukalmmvkUoSRSxFG\r\nMk7n0oTRAc01ouKIu0YiUidcIx6p2210jZq3GYSRFqdrjmfCyMmidBuIIJLCSHeNWKSuQUbqdNeI\r\niiOXFEdSGNUtAQcTRdw10uJ0VBQx50jG6b5jkTrqGumROuoazdAjdUqcziCMCHYZp6v8TDhGRBhR\r\n16j8Y7CXBXmNOKKtc999NxMef/xRuOSSS+DRRx+BiIgFUFZWhI9RBEFxhOJIrfHWXKPTxnk
jQ1Pd\r\nSdOOoxN6rO6wqYih0qqprtHYVFd41H3HUXZdNfznJh9tXmh+NneN1DIG6Rrtq+bCiImjPBv8RVkK\r\n+Oy/RsOTL4yGBx4cDZO2tvIyhtIOyhjMTXUFimuUZ3SNzGUM5qY6WeNtiNRZNNVR5qX3fXFEG4pC\r\nQj7Dxw6CdAG07Ys+T/3rX6O6wDnicTpwUHFUy+J0VBiB3RynKzfG6ZgwEuKIRuqEOHKdyGGuEYvU\r\n0TidOmukCSPdNaKzRixOR4VRy06LOB2hhc8auZoTWKROc43ErJGLCaR1RBDpcToXE0fKrJF5zkiL\r\n0xkjdQ7hGtFInYOJI33WyBCnOxymzRrROJ2z2mLOiMXppuizRh5cI0fFx0Qg9W3nKD09jTlEDz30\r\nIBNE9947lJUtYBoAQVAcIcpJ1a2MwcPyV23H0UmOOnPk5hqZBJLb8ldVICkzR3mm5a/rw7gD9Lu3\r\nE3mNt+Icae6R4hyxeaMiGzzkofr17Q2thjKGRKsyhiKljKFAX/66ztO8kSlWJ5vqvldmjpaaXCPD\r\nfiMvcY7owr/LLrsMT6II0oXs25cKP/vZT2HSpE/P+WsMHFgMSVub2JwRFUYgkEUMXBxVKSUMIk4n\r\nxJGcNaKukcsiTseidEoJAxdGwjVSZo1YpE7MGrWzIga1hME4a6TG6VTXiAojl4zTiSIGKY6c9WoJ\r\ng4jTqbNGmmtkjNPRWSM+ZzRbc4wczDES4qiazxqprpGz+kvdNRLCyHm8iHx+hCKMeAmDXbpG5UFg\r\nL/uwTz2PHzqUxXbTvfbaq3Djjb5sN9ETTzwO3377NRw8iM/lCILiCLEWR+b9Rsq8UUc13uZInRRI\r\nUhgZmuosaryLjlqUMRAOafuN6uDDh/kC128zHcqOIwcRQK2ws5CzvYCQT0QPYUexw9BUt0tE6naW\r\nK/NGpe7OkVuFt8V+I/O80WqLHUea
MJL7jZSmuo6cI28QR0895c+ai/BxgyBdy+7dyfDnP/8J7rpr\r\nMGzatOHsT7Y+pwnHYOiQZkhKqNfidLprJIWRu2vEhBGdM2rTZ41cVBxR5+hEthKp60QJg8d2OjFn\r\nJF0jZdZIj9RtILfriCjS43TSNeKzRrKEIdrCNVJLGPRZI1nEwOHiyK2EgQqj6hlaCYPDKk4nHKPT\r\nx4/Dsfp6OH7YBqfK5zCBpEXqhGvkKO9dcbR9+1YIC5vB3Mibb74JLrroIhg8+E5WHb927SqMzCEI\r\niiOkM+LI6TKVMSjOEStjUFyjJg9lDLVKGUONqYyhQtR4lystdcWKOJKROr2MgTtHa74N4I7P67Fw\r\noFZZAFuUCr/1tBTwvVSjOKrQ540oNFInY3UyTmcZqbPacZTvHqsz7zeikbpo4RpJ50guf/VUxiDF\r\nUV8uZFiwYB4MHHgtFBQcwscNgnQDpaWFrKSBDsPfd58fLFu2BMrLizspjo4RWggNhFoikqohaUuV\r\nJozAJI5cimsk43QuU5zOJWaN1Dhd+3FZ3b1XkGqq71Yjddv5rJGI0zlpAQMTRvGWcTrP7XQxXBxR\r\n16hBuEZ1UW6zRkwU1UWA44jqGulxOtlO5xAlDA4Rp+PtdNw1YpG6qi/J619aiiMqjFpqaqChpARq\r\n8/OhLjsBThR/o7lGDuYcje+R5/GsrAOwenUMi8S99NKLcMcdt7N2uauv/hVbMjxhQhCsWbOSNSPi\r\n4wtBUBwhZymOXO3AFsGadxyxMoZTehmDOm9kXv5a52HHERVFZ1r+KhfA5gmBxJ2jNoiJjoUZC2Nh\r\nVY7qGtF5ozbYvLcMNhDWC9YRYtPI+3LaLJ2jZJNrlGSeNyr27BypO44018gkjmJy9DIGN+coy7jj\r\nSI3UqU11fXXmKDk5Ca644gp21REfMwjSvdCFm9OmfcFaw2jd97PPDmdD8zZbWgfiS
AqjOkIVoYJQ\r\nBPcOKSYiqcyja8Rru9U5I+EY0VkjQ0PdAU0cyRIG6Rq1U3EkG+pMs0bGdjpZ3c33GnHXiDfUsUid\r\nNmskI3X6XiNjnK4j10h1jOaLhrpwVsTgsJw1+tqyoU6r7lZ3GlUGa8KorqAAqjIyoCI9HYp27oTK\r\nPauh9dAXLFLn6CJxRAs7qAsUHR0FX3/9Fbzzzlvwj388xUQQfT6m80K33norPPPMP2DixI/h++8j\r\nITPTho8hBEFxhHRJy5GzhUDUi7NJazzShnpZPOOw2JNRbcqty+WB7lcf9cx6tnaSNVTAyqz6sTQ9\r\nqy6vOrbuhPZW05VHdoJN0PdiNMqdGBv0nHqjGsdYxU+qrN1I2YdRLxYFsrrXxexqo8Mtoy6uNmr5\r\n9JmEb5UFgTJ+YRHB0PZghLjl0unVRR67+IidROkVRkfZB2AvHUd4DxylY/ucONqwIRauueZqNsCL\r\njxcE6Vl27drBZpEefPABNu9HxRJdxjlq1EtsEfOcObPYQlnpGKnCyMengJBDyIKhQ7Jg25ZCt1kj\r\nq4Y6zTUSO410YbTf6Bq1KtXdbM5IROpauThyiudupxapM7pG7Pm7w+ruGIMw0uq7LVwjh0V1tyxh\r\nkA11TlN1N43T6cJoGm+nU2eNKtWGuhCGdIxUYVSwbRvkbNwIWbGxkL9xATRlBrPn8fnz58HcueHk\r\nZzSbiNtZsH79WlixYjlrg6M/t88/n8KaCt988w22U+jhhx9iTaDXXXcdDBgwAH70o/+BgQMHwp13\r\n3gFPP/13Jo6mT/8SYmKi2ZwaPj4QBMUR0o3iCJytRBA1iz0ZjWxPhhRHwLarixpYt+WB+o4Ml2w6\r\nUpYH2luzoaX+EDQcIdTkCLIVDhKyOIczCRmC/Yz6ahu5JVSnk9f3kVvKXvJ6GrmlpEJ91R5oINRX\r\npZDb3Yz6yl3QULmT3CaT22
R2W1+5g7CdU7FNkERI5JQnCLYQ4hU2EzZBfdlGcrsBmiti4FQVEUvi\r\nhMqvMtITqbjCWKWfSO10OaBW9TpBE0fs6mK5LowcZe+R23eJOHq3T4mjH374nkUV6VVrfKwgSN9o\r\nt6N/XFOn4JVXXmZ/UFMngQujakK5IoyymTDy8Ukn4igDkuLzDQtf1XY6deGrutOoXUTq5EUtg2uk\r\nxenMe42sZo0SDI4R22mkLXxdb4jU6Re3+KyRS1zgOrNrJBa+Ko4Ra6c7Mke50KUufDXuNXJ6nDUS\r\nO40qJjFhVJ2ZCeWKMMqmwmjdOkiPjoZDG+bB0f2fsufxESNGwAsvvAABAQHw0ksvwS23/IH9rKi4\r\npdXZdLnq66+/Bh98MI7FKalgosKHLlzNytqPv+8IguII6V1xZO0aaW1Hdl0cARVILJ5RqlyBNLtG\r\nudBYmwfFRYVQVFTUD8mHhrJY92x6pfFEqm9On2hyjnj0wl72Prkl4ki4RvaSwD4jjqhTRKMbS5dG\r\n4OMEQfr6yVZzjIoNwog6RknxBcpOo865Rmy3keIaqdXd3O03u0ZqnM4ojpxNeqTOaYrTOZWGOtU1\r\n0ncaWcXppGsU6bmhrlY01NXMMew00meNvvaw8JU/lzvZ87nqGvHq7ioijKhjVEyFUVKSJoyoY9SY\r\nGaJd8PLGJbAIgqA4QtRYnaOZ4CFSd/owEUTq8kA1u24dqaPCqH+KIiMNZWvEyXSqiF8okTqTOLIr\r\nrpGM01FhJCN11Dmyl7zT6ydVOl909913saucW7fG42MEQbxCHBkdo6FDciFpSwl/zj5tNWtUSJ6v\r\n9XY6t+puxTEyukZ7RUudMQ7drrlG2zt0jZyNumvkPLpeW/bKIOLI2aBXd8uGOi1OJ8WRiNM5aCya\r\nukZ1Uhzp1d3uO42Ms0ZOWsRQPUMrYeCROusSBvX53OAYxcVBceIyaD44hV/
wKpcXvN5HcYQgCIoj\r\n73eOeJyOLhDkG9br3CJ15rYjGafTohkinuE4ltunHKO0+GiYERoKM2YtgiRb14q24qJ8OFX5tWl7\r\nerAQRZ+JmtdP9AWB0jVSTqJy1shRGkjoPXGUkrIThg9/Gi6//HI241BSUoCPDwTxGnHEhdHQIfmw\r\nLaHMbaeR1k53SgojYxGDjNS1C9dILWHQZ0SVOF3rnjOUMCiuERFHTjVS17jRUN0t9xrJnUbUNXKZ\r\nSxjonJEap6Mzo3VyblS4RjJSV8vnRh01SkPd4ZmGOB2v7lZcI0UYOc3CiDyn28VzuhRGJTuioSUn\r\nVLTTySTAB+w5nV70QnGEIAiKI28XR9I1ErNG4KgzxenEvJEUR228iIGebF2Ka0R3Y7Q0dF6AZCZF\r\nQ6D/YKWK2xeGDRsFi5JzukS8ZMaF8q87eBj4ktuJsTth7hh/GDMrvssEUlP5ciVSF+JWxCBnjYac\r\nuBYSDj8vhJHqHI1ls0Y0UmcvebtHT6q0OpguB7z//vuYKHr33XdYPSw+LhDEuxg4cCcRRZX6wlfN\r\n6bd2jfS9Rry6mwsjvtNIxulUx6hdK9DRXSNtr1GL+14jQwmDaKjTXCMRp3MxxJxRg9xpJOq761co\r\ne43cXSN91ogW6izks0Zip5HDrYRhlijUCTO4RnSvkVbdTSN1sqFOi9NN1uJ0cna0grbS5X6pRKR5\r\ndbcURjwF8B6KIwRBUBz1B+eIiiPw4BppVyFPK7NGrITBONRLT7QNRzonjmwrJ2qCaOLcaIhdGQmh\r\nE8cwERO40tYlwiV2IhVe4yFNe18mhPj6gO/42C4TR/Vla/iVRnXWSDmZylkjn9Pk//WYDww9eg0k\r\nVD4nTqRjRRFDIIvU2XvAOSoqymOCiLZdUUH0pz/9kdUGFxTk4uMBQbw5Hi0j0KdVYVTqMU7nEvOh\r\n7crCVy1SJxa+uo7Z
LBe+6iUMO8W8kVV1N1/2alz4qrhGR/nCV+kaudTqbiGMLEsYZJxOmzNapNR3\r\nz1P2GplKGMSskYzTSdfIaY7TmWdHtYtdhPKJ2gUvvtdIL9eRrpG9D7aOIgiC4gg565kjXRhpJQxM\r\nGNEK72rjVUjNNbJeHtg5cZQC4325MJoVb3KJ8nIgJ69rhEt8yDDw8Q2BnG6M7dWXxvKTKW2pqwj+\r\n/+2de3RV5ZnG4wURvNS1HEUBxSvS0bFrtNNJ1xjsdFK6RotRsRrroKLWchHMIBJgiAIB8QhDwaAD\r\ncnMMjojcAhwhhAQMEgwQ4BgCCSSQC/ccGxBROJe8s9/3+769v2+ffUKgQk18/3gWRYrQJD07v/M8\r\n7/PE1nfXjoRQ9XACo4RjloKWDidAUl1nWF39uF3EgJG60J6B3/tDFbcycCjw1Vdfgfvv7w6XX345\r\n/Pzn90J6+qtUE8z/H2CxWgsc7ZNgtC/mNtQcfPVyjZzqbjX4qrfTUQnDcVXC4JpeUK7R0dg4nZpe\r\nsBvq5KZR1N40WmzH6ZzB1/laffc8l2uUbTTU0eCrjNOFPQZf9RKGiNZOh65RWHeN9OpubddIvJ6P\r\nMl7P9WKdWNdo8A+udZTFYjEcsc4SjjBS1xiSkbrQIWfX6GRd7ICgDUeVrirY5sFRWa6IuyVnnMbB\r\nCeRCRqoTu+uWmgG5AccFmmr9Wh9fNszOSHFcqOxC+nW/L9X5fZZSfX7796RO8tt/RnlxDqQlq1hf\r\nMqRn9IPExH6QW9ZcOFoS02jkLmIIWQ9SG4yOWNpnqdZSZQJ0r+wMeVW9KFL318DRzp2lkJe3Et59\r\ndyq88sp/wiOPPAy33XYrtG3blsYk//jH52HGjGlQWrqNv+5bmOoswA1mTYaGoUPoR/w5f1xYMQkA\r\nvTjnlOMaReOUMETtsdftRkNdo9qjc7tGxq2R2qTTwEh3jew7IxWnc
26NIhocRT0b6jxKGHTXSG4a\r\nhbXBVwIj1VBH9d3e1d2Ga2SBkXCNfM6tkbZpJFyjURCi13L1ej7SKNexJxmwdVSLSTMcsVgshqMW\r\nf3MkwYga6nTnSETq7Pput2tk1MCKeEZz4CjgzyQYyfQHmvjvFUIaAUsqZPsLoTB3NqSS25QGheUC\r\njnwKaiyYmb0gG9KTxa8X4Z9R5IfMPt2sn/exfm0B+AtKRKwu0YIlG8oKoZ/8M2bnFkLBgqmQLCFp\r\nQeBM4chxjaiEoUY11IkHqXKMdDBK2GWpzNKXCZAU6AirKx6mz4caDpw6NQumTJlMy+fTp78LEyf6\r\nYOTIEdC374tUnoB7GT/9aTf4yU+uhEsvvRS6dr0dfvvbHjBgQD9aVM/N9XOxQgvXQf9SCHfoANYX\r\npS38Of5z/viwnJujKihYdViL02mu0ckqw+mP11CnNo3crpFXnK6xySIGGanTXKOIvWkkShjcg68q\r\nThc14nRquNscfBWxujmu4e5mxOmovtu1aRS3oU5/owtf03XXaLhQtb5VN0QW6/wwWkdZLBbDEet7\r\ngaMjRn23fWtk1Hc3HanDeEbw0M7TO0eyKMHXBBwpgMrICWi/T/0zCToIQ8mZ9k1Rrg8dpEQbbGJj\r\ndQKOEiUcxf8zEiHnTOBIRepqvSIY4h1GAqP9lmo0MNouwChhswVHWztCXrmAo169ehlSDtgFF1xA\r\nuvDCC+Giiy6CNm0uhksuuYTcocsuuwzat29PsbkrrriCgAlX1vGuCPeKrr76auhgfVONuv7666FT\r\np45www2drW+qboSbbroJbrnlZnKa7rjjDgKuO+/8e7j77n8g1+nee++h5XZcasea76Sk+6B79ySC\r\ns+Tkf4MePX5DY5QPPvgA9Oz5O3j00YfhsccehSeeeByeeupJ6N37P+jGCd0rHD1EeBs06CUqgBgy\r\nZDAMGzbUgr
7h8NprI2HMmNdpEPHNN9+gNfgpUyZZkPg2weHMme/B++/Pgrlz/xfmzfsQFiz4GJYs\r\nWQjLl+fAypV+cs7Wrl0N69athS+++JxW5AOBEigrC8CuXTtaHCiiQ+QGIx2Q2EFiOW11pywdh+5J\r\nX0FBbp13CYPH63Xjt/LOiG6Mtsoft8RUdzu7Rus9SxgiWnV3RN4ZkWsk43ROO51yjZZQpI7gSIvU\r\nee4aGWAkXSMVp5N3RugYqRIGr0hdzK6RjNNF7BIGZ4YhVDvG425UvzPSJhlqzEhdiOGIxWIxHLWW\r\nWJ0+/KrB0UmvhjrdNaqIqYJtDhwFcgSUpDdRvBCQkDKvxPln5YXTTThC0Ml0InJ+hKGEZBts/JmJ\r\nBEeBJuGoG2QXlWuRv7OAozr3rZHjHIVko5HtGFWZYJQU6AR5FY9YD9SXIFQ1wPVQnUM/YqscfmNf\r\nVVVBhQq7d++kAgX8hh9vilDl5dthx44vYfv2bRSdw4V1BIOtWzfBli0boaSkmGChuHg9bNiwDtav\r\nLySIwF0jBApcZcddo7y8FbBixXLw+5fCsmWLCT4WLpxPy+0ff/x/5GJhoQOOw86ZM5OA5b33/gem\r\nTXsH3nknC7KyJhPQINjgkCyCTmbmKHj99QwCoOHD0+n+afDgNHj55YHw0kv9yQlDcHruuWfh6ad7\r\nE1Clpj5B7lhKykO0Jo+OGILYr351P9x3379AYuI/0+0Uwttdd90J3bp1g9tvv41AD6Hvuuuug2uu\r\n+TsCQwTHtm0vIajEr5+LL76YnDaESITHa6+9Bjp27EigeOuttxAg4r8T/90IhQiECIP45yME9uz5\r\nIAHg44//nv6uzz77NP39+/fvS9CHsUYBfCOoFv2NN8aS64cfF4w9YrxRQd78+R/RTdiyZUvI6cvP\r\nX2V9TtbQ56hq7BhPMFLCiB2/hrEEHB23dMxS0NJhC5JqLUi
SrtHJSlHdrTXUxewaaXG6Rqru9t40\r\navS6M4qzaxTRbo0EHImGOu84XbxNIy1Sp90axXONME5H1d0Hs+JuGjnV3T7NMZKu0T6niCGkShi0\r\n1lF9xFt3jVSc7m89ycBisRiOWN+bc1Tv6RqZ20Zaffe3atuoImYjI3hox2mBorxoOt0BJaT4NHBx\r\nA1SGjN6VucDFBUfa3dLZwRFCmuMcLchMMf4dzYOjTHsHQ2+o0x+kbscoaUcnWL27Fz1Iw3sGEhiF\r\n9vTnh+p5EAImwiRCJMLjxo0baOcJQRHhBCEF3SgEQ4RCdKkQBhEEEQKnTp0CkyZNhLfeGk/wN2rU\r\nawR+Q4cOIegbOHAAAd8LLzwHzzzzNPzhD6nkoiHoPfDAv0OPHsk25P3iF/8E99zzjzS6i1CGcHbj\r\njTeQu5fZvn2TcDSmXTvo0OFa6Ny5E9x8880Uq0TH72c/E1D3y18muqDud+ToIXiim4cw+uKLLxCg\r\npqUNIhdvxIhh5OCNHTvadu/efvvPBtQhIOPHZfHiBQR16NohWH/2WT5B98aNRQTkWAuPt3AI8zU1\r\nVfy1d07hSIHREUv7LNXS9lH3pN0WJO0yGurUrZEepxPV3aKdTt0aNX7jFDHE7Bp9bcbp7OpuaqbL\r\n1UZf5eCrq4RBH3yNBp1bI901iupxusNaCYMHGDmu0VTaNBL13Vl2EYOxa2TfGr3p2qjL1BrqRtnt\r\ndFSqQ6/l5oi32qpTcKRco/M9ycBisRiOWOfCOdLqu40ihlO1cUoY0DnaZR722nC0s1lQMS9dFi2k\r\nZEBOYTG5HEUFOTAprQ/4EH7KciEVfz05A/zFAQgU++VNUaosS4gPRwuaCUeV5QXQhyJriZDu80E/\r\nrZih+XC0OLa+23W0iw9TBUZJ5Z1hdeXvrQep2DUKyZY6dI7CewbwQ5VlC52hpuBo7xuZBCLYOrhm\r\nzWpy
/dDxy8lZRPDy0UdzDahDVw9v0RB60M1DCEIYQihCOEJIQlhCaOrd+ymCKISphx7q6Ql1WAOP\r\nUIeuHUYyu3TpQnFNBDZ07K688gpoZwFcmzZt7FgoxkAx/nnVVVfZUU/8Pcq169q1q4x03k1xTvxz\r\nlHP361//K0U48e+Cf6devR4h9w7hE/++6OAhkOL/BnTxEFIV9GE7I/5vzcj4L3LzEP7Gjx9HNfaT\r\nJ/+3jG9OIQjEjxWC4KxZIsaJH0N0+fDjiU4ffmzR7cOPM8IhfswRqDHWiXCNnwsERXQA8XOD4I0x\r\nT4RwdG/RxUV43LZtM73uocuLoI6uL8Ikgju6wegMC+0kwESoR/cYXeTq6kpylJWUY6SDEY7CJiSU\r\nWfrSgqRtULByu4drVGpH6tSuUVRrqNNdI6eEYZ1RwuBsGinXyGyoU5E6u4ThL14lDB97uEbuTSPl\r\nGsnq7kOuSN0htWuUZTTUuQdf44ORV6nOa3akzilhGBZTwuBMMgw6J62jLBaL4Yh1vp0jwzU64Iy+\r\nqiIGBUd02Ou4RlFyjMootx6VA4LBgzuaWYNdDjmT0oSDZCjZHoEtK5wnSxikuvWBbHsgNhaOxM1R\r\nCuSUabCU2AQcoUr8kNEnBRKtb/BS0qdCtq+PcbfULDjyGH0Ny3ca1Uhg9903wOqqJyibHq4ebDxI\r\nwxSp62+pHz9UWc7NkfVNcmu6OcJv4vEbfYx/oquEkIAxT3SblGu3atWnBBtLly6iOCfCCDpVCCiz\r\nZ8+gCCcCDLpZCHro3mFsEWFHOHgjCILQxcN4I8IRQlK/fn8iaHr++T7k5iFMPfkkRjcfI8hCVw/j\r\nkghe6LIhCOI4MsIgghkCITpxCGvoyqHbhw4dwiHCHN7pYawTAQ9dPARFdADR1cPIJsY8VdQToRDh\r\nEQER7wLxPhAjnngviMLIJ94RYhQUhUCJgIlxULw1V
DeH6gYRJcBov6UaDYy2ExglJGy24GgL5K8o\r\nlZtG25043QnvdjqhYruIoRHh6JjcNaJI3dqYOB3dGh3VN438WjvdMlnAIDaN7LHXoFnEQIOvRz6M\r\nLWGw4Ch8mjhdTAnD/j/LIoZJsrp7gpCq7nbvGslbIxWnoxIGNxjJ6m4Rp1PV3U4Rw7maZGCxWAxH\r\nrPPuHLlHX923RtU0/BrV19XtWyPHNcIHbfPhSO0aBaCoqMj6Jsn6RqmkzBOiAoEAqfwc7BSVl5l/\r\n1vQ+Ca7h2GbCkWv0NaSBkcqmqwcpxS/2OttGyjViOGJxWx3r7GJ1yjGqMsBIOUYiTrfD+9boxDbH\r\nNTquNdTZu0YSjE5T3R3V4nTmrpEYfI25NZJxOgKj4DyjnS7axJ2R4RoRHE0zInV6dTeWMET0Eob9\r\nbzklDMo10u6MxJtcMlKn7RqF6LU8fnW3/mYXvp7z6ziLxWI4agVwRM6RitTp9d1erhFm1+lBu1M+\r\naNU7kQhHZedscPX7VwlkUBV4CvRLS4MU6VL1m154BiOwi+Q7jc6ukXskMKyNBAo4Mh+kyjViOGLF\r\nc5B454jVNByZjlH3pDLIX7nTNbeArlEsGEXlrVH86m7RUCfqu92uUYHhGjnV3c6mEYJRVMbpTNdI\r\ngZGroc7lGoWpoc6J0ynXSG0aUXX3AeEaRfTqbn3TyK7v1iJ1NN49zmyoq3VujVQKAEe8KUqn4nSu\r\nEgYc8dZdozDDEYvFYjhqDbE6xzWCmHV1l2uk1cHqRQyq7eirQy0JjiqhyJ8NvswMSLPgKC09E+bl\r\nlpzR76/fu1AbCtSPdzXXiB6kQxw42pPmFDForlGoqi8/VFks1lnAkQCj7kk7oSC3Qr5WV3iU5oj4\r\ns3L6RaRuiytSVxw7+Pq116aR9+ArlTA0fGrvGuGtUdQuYohtqFNgFI13a6Q2jezq7ulSMlLn2jWy\r
\nb40OiFsju6GO4nT64Os4Z6POGHxVjtFIzze63K6RerMrjG94VXm1jvLrOIvFYjhqURo9ejRETx10\r\nihhO1WlDggKMxFaGLGH4zlXE8K2AI7WVcbS+tEXB0V+rhr0feB7uinca02Wjkcqnu+IX1kOU7o32\r\nCOfoRAW31bFYrDNXly7rLCiqNAZfzYY67zhd1G6oUyUM7k0jbez1a5drdExzjbQ4HQ2+Nvht1yji\r\nAiPDNTIcI901yhYNdYe9q7vDMYOvWcbga/xNI+UaaYOvtd6Dr86bXMOMeHR47yuaa/SymQKQSQB+\r\nHWexWAxHLVgTJvgsoNmlNdTtM1vqvjMjdWZEQ7wLiQ/aqKyDDR3bClWVu38kcFQB39WMd0XqdNco\r\n3a57te+N5MM0vHeQK1L3J6j4/FUYM2YMP1RZLNaZx6Ot12njLlTfNJKNolFZ3S3AaCvBUSNpswVE\r\nFhx9HesaOXE689Yo0pAnbo2OKjiSYKRVdwvlyDIGB46i6BrVizhdVLlGHiUMETtSJ1yjsOYYibHX\r\nd+3B18jBt+nOKKy5Rk6czlXCoMCoTh98dcDIfJNruGvXyEkAqNtR8/Wc4YjFYjEctWhhPW1+3lKA\r\nkLg1EpE6p747qtd3e7hG+sNWHfV+dejLHwUcBfd+og2/ZsS0GjlFDPqtkZlNV3AUruoL788YDxMn\r\nTuCHKovFOnM48nitjmqROru62941MksYVJyuEaVvGiEYHV2rxem0wdeGPGfTCEsY/uIuYVgiFFxk\r\nxukQjIJx7ozqswUcWWCkGurCVMBg6bDHrtHBLAlGWgkDtdM5JQwKjMw4nV7EoBXquEsY5JtcTVV3\r\nqxFvfD0P8+0oi8ViOGrZKi3dSi/k2wPr7G0jOFXj2jbabRz22rtGGhyJrYwttK6O70IiILVeB6lC\r\ngpGTUQ/Jh2lYKuR6pzEkD3f1hrqQdmvknz+
KIo4zZszghyqLxTpLOBJxOsPh/9bLNXIcIwFHG+2G\r\nOuEarffeNdLidMo1itDYq7NpZJcwaI5RjGuk7xphdTfeGqmGusOqhGGO1lDndo0cx0jcGalI3WS7\r\niCFi7Br5PFyjTGOGwdmoGyFLGBzHSLj/0jXSItL263kV
<TRUNCATED>
[28/50] [abbrv] airavata git commit: Fixed AIRAVATA-1620.
Posted by sh...@apache.org.
Fixed AIRAVATA-1620.
Project: http://git-wip-us.apache.org/repos/asf/airavata/repo
Commit: http://git-wip-us.apache.org/repos/asf/airavata/commit/774b092d
Tree: http://git-wip-us.apache.org/repos/asf/airavata/tree/774b092d
Diff: http://git-wip-us.apache.org/repos/asf/airavata/diff/774b092d
Branch: refs/heads/master
Commit: 774b092d31e41919b39ca3ce9f1edd5af1c30669
Parents: 44d89ee
Author: shamrath <sh...@gmail.com>
Authored: Fri Mar 6 16:18:44 2015 -0500
Committer: shamrath <sh...@gmail.com>
Committed: Fri Mar 6 16:18:44 2015 -0500
----------------------------------------------------------------------
.../server/OrchestratorServerHandler.java | 31 +-
.../engine/SimpleWorkflowInterpreter.java | 280 ++++++++-----------
.../engine/WorkflowEnactmentService.java | 129 ++++++++-
3 files changed, 259 insertions(+), 181 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/airavata/blob/774b092d/modules/orchestrator/airavata-orchestrator-service/src/main/java/org/apache/airavata/orchestrator/server/OrchestratorServerHandler.java
----------------------------------------------------------------------
diff --git a/modules/orchestrator/airavata-orchestrator-service/src/main/java/org/apache/airavata/orchestrator/server/OrchestratorServerHandler.java b/modules/orchestrator/airavata-orchestrator-service/src/main/java/org/apache/airavata/orchestrator/server/OrchestratorServerHandler.java
index d168c26..fe306d7 100644
--- a/modules/orchestrator/airavata-orchestrator-service/src/main/java/org/apache/airavata/orchestrator/server/OrchestratorServerHandler.java
+++ b/modules/orchestrator/airavata-orchestrator-service/src/main/java/org/apache/airavata/orchestrator/server/OrchestratorServerHandler.java
@@ -52,11 +52,20 @@ import org.apache.airavata.model.messaging.event.ExperimentStatusChangeEvent;
import org.apache.airavata.model.messaging.event.MessageType;
import org.apache.airavata.model.messaging.event.ProcessSubmitEvent;
import org.apache.airavata.model.util.ExecutionType;
-import org.apache.airavata.model.workspace.experiment.*;
+import org.apache.airavata.model.workspace.experiment.Experiment;
+import org.apache.airavata.model.workspace.experiment.ExperimentState;
+import org.apache.airavata.model.workspace.experiment.ExperimentStatus;
+import org.apache.airavata.model.workspace.experiment.TaskDetails;
+import org.apache.airavata.model.workspace.experiment.TaskState;
+import org.apache.airavata.model.workspace.experiment.TaskStatus;
+import org.apache.airavata.model.workspace.experiment.WorkflowNodeDetails;
+import org.apache.airavata.model.workspace.experiment.WorkflowNodeState;
+import org.apache.airavata.model.workspace.experiment.WorkflowNodeStatus;
import org.apache.airavata.orchestrator.core.exception.OrchestratorException;
import org.apache.airavata.orchestrator.cpi.OrchestratorService;
import org.apache.airavata.orchestrator.cpi.impl.SimpleOrchestratorImpl;
import org.apache.airavata.orchestrator.cpi.orchestrator_cpi_serviceConstants;
+import org.apache.airavata.orchestrator.util.DataModelUtils;
import org.apache.airavata.orchestrator.util.OrchestratorServerThreadPoolExecutor;
import org.apache.airavata.persistance.registry.jpa.impl.RegistryFactory;
import org.apache.airavata.registry.cpi.Registry;
@@ -64,17 +73,25 @@ import org.apache.airavata.registry.cpi.RegistryException;
import org.apache.airavata.registry.cpi.RegistryModelType;
import org.apache.airavata.registry.cpi.utils.Constants.FieldConstants.TaskDetailConstants;
import org.apache.airavata.registry.cpi.utils.Constants.FieldConstants.WorkflowNodeConstants;
-import org.apache.airavata.orchestrator.util.DataModelUtils;
-import org.apache.airavata.simple.workflow.engine.SimpleWorkflowInterpreter;
import org.apache.airavata.simple.workflow.engine.WorkflowEnactmentService;
import org.apache.thrift.TBase;
import org.apache.thrift.TException;
-import org.apache.zookeeper.*;
+import org.apache.zookeeper.CreateMode;
+import org.apache.zookeeper.KeeperException;
+import org.apache.zookeeper.WatchedEvent;
+import org.apache.zookeeper.Watcher;
+import org.apache.zookeeper.ZooDefs;
+import org.apache.zookeeper.ZooKeeper;
import org.apache.zookeeper.data.Stat;
import java.io.File;
import java.io.IOException;
-import java.util.*;
+import java.util.Arrays;
+import java.util.Calendar;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Random;
public class OrchestratorServerHandler implements OrchestratorService.Iface,
Watcher {
@@ -656,10 +673,8 @@ public class OrchestratorServerHandler implements OrchestratorService.Iface,
try {
WorkflowEnactmentService.getInstance().
submitWorkflow(experimentId, airavataCredStoreToken, getGatewayName(), getRabbitMQProcessPublisher());
- } catch (RegistryException e) {
- log.error("Error while launching workflow", e);
} catch (Exception e) {
- log.error("Error while initializing rabbit mq process publisher");
+ log.error("Error while launching workflow", e);
}
}
http://git-wip-us.apache.org/repos/asf/airavata/blob/774b092d/modules/simple-workflow/src/main/java/org/apache/airavata/simple/workflow/engine/SimpleWorkflowInterpreter.java
----------------------------------------------------------------------
diff --git a/modules/simple-workflow/src/main/java/org/apache/airavata/simple/workflow/engine/SimpleWorkflowInterpreter.java b/modules/simple-workflow/src/main/java/org/apache/airavata/simple/workflow/engine/SimpleWorkflowInterpreter.java
index a052e5c..ee7ff6b 100644
--- a/modules/simple-workflow/src/main/java/org/apache/airavata/simple/workflow/engine/SimpleWorkflowInterpreter.java
+++ b/modules/simple-workflow/src/main/java/org/apache/airavata/simple/workflow/engine/SimpleWorkflowInterpreter.java
@@ -24,8 +24,6 @@ package org.apache.airavata.simple.workflow.engine;
import org.apache.airavata.common.exception.AiravataException;
import org.apache.airavata.common.utils.AiravataUtils;
import org.apache.airavata.messaging.core.MessageContext;
-import org.apache.airavata.messaging.core.MessageHandler;
-import org.apache.airavata.messaging.core.MessagingConstants;
import org.apache.airavata.messaging.core.impl.RabbitMQProcessPublisher;
import org.apache.airavata.messaging.core.impl.RabbitMQStatusConsumer;
import org.apache.airavata.model.appcatalog.appinterface.OutputDataObjectType;
@@ -66,7 +64,10 @@ import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
-public class SimpleWorkflowInterpreter implements Runnable{
+/**
+ * Package-Private class
+ */
+class SimpleWorkflowInterpreter{
private static final Logger log = LoggerFactory.getLogger(SimpleWorkflowInterpreter.class);
private List<WorkflowInputNode> workflowInputNodes;
@@ -102,8 +103,11 @@ public class SimpleWorkflowInterpreter implements Runnable{
this.publisher = publisher;
}
-
- public void launchWorkflow() throws Exception {
+ /**
+ * Package-Private method.
+ * @throws Exception
+ */
+ void launchWorkflow() throws Exception {
WorkflowFactoryImpl wfFactory = WorkflowFactoryImpl.getInstance();
WorkflowParser workflowParser = wfFactory.getWorkflowParser(experiment.getExperimentID(), credentialToken);
log.debug("Initialized workflow parser");
@@ -111,15 +115,16 @@ public class SimpleWorkflowInterpreter implements Runnable{
log.debug("Parsed the workflow and got the workflow input nodes");
// process workflow input nodes
processWorkflowInputNodes(getWorkflowInputNodes());
- // initialize the rabbitmq status consumer
- statusConsumer = new RabbitMQStatusConsumer();
- consumerId = statusConsumer.listen(new TaskMessageHandler());
-
processReadyList();
}
// try to remove synchronization tag
- private synchronized void processReadyList() throws RegistryException, AiravataException {
+ /**
+ * Package-Private method.
+ * @throws RegistryException
+ * @throws AiravataException
+ */
+ void processReadyList() throws RegistryException, AiravataException {
for (WorkflowNode readyNode : readyList.values()) {
if (readyNode instanceof WorkflowOutputNode) {
WorkflowOutputNode wfOutputNode = (WorkflowOutputNode) readyNode;
@@ -232,10 +237,11 @@ public class SimpleWorkflowInterpreter implements Runnable{
}
/**
+ * Package-Private method.
* Remove the workflow node from waiting queue and add it to the ready queue.
* @param workflowNode - Workflow Node
*/
- private synchronized void addToReadyQueue(WorkflowNode workflowNode) {
+ synchronized void addToReadyQueue(WorkflowNode workflowNode) {
waitingList.remove(workflowNode.getId());
readyList.put(workflowNode.getId(), workflowNode);
}
@@ -265,31 +271,8 @@ public class SimpleWorkflowInterpreter implements Runnable{
readyList.remove(wfOutputNode.getId());
}
- @Override
- public void run() {
- try {
- log.debug("Launching workflow");
- launchWorkflow();
- while (continueWorkflow && !(waitingList.isEmpty() && readyList.isEmpty())) {
-// processReadyList();
- Thread.sleep(1000);
- }
- if (continueWorkflow) {
- log.info("Successfully launched workflow for experiment : " + getExperiment().getExperimentID());
- } else if (!(waitingList.isEmpty() || readyList.isEmpty())) {
- log.error("Workflow couldn't execute all workflow nodes due to an error");
- }
- } catch (Exception e) {
- log.error("Error launching workflow", e);
- } finally {
- try {
- statusConsumer.stopListen(consumerId);
- log.info("Successfully un-bind status consumer for experiment " + getExperiment().getExperimentID());
- } catch (AiravataException e) {
- log.error("Error while un-binding status consumer: " + consumerId + " for experiment "
- + getExperiment().getExperimentID());
- }
- }
+ boolean isAllDone() {
+ return !continueWorkflow || (waitingList.isEmpty() && readyList.isEmpty());
}
private void setExperiment(String experimentId) throws RegistryException {
@@ -297,147 +280,108 @@ public class SimpleWorkflowInterpreter implements Runnable{
log.debug("Retrieve Experiment for experiment id : " + experimentId);
}
- class TaskMessageHandler implements MessageHandler{
-
- @Override
- public Map<String, Object> getProperties() {
- Map<String, Object> props = new HashMap<String, Object>();
- String gatewayId = "*";
- String experimentId = getExperiment().getExperimentID();
- List<String> routingKeys = new ArrayList<String>();
-// routingKeys.add(gatewayName+ "." + getExperiment().getExperimentID() + ".*");
- routingKeys.add(gatewayId);
- routingKeys.add(gatewayId + "." + experimentId);
- routingKeys.add(gatewayId + "." + experimentId+ ".*");
- routingKeys.add(gatewayId + "." + experimentId+ ".*.*");
- props.put(MessagingConstants.RABBIT_ROUTING_KEY, routingKeys);
- return props;
- }
-
- @Override
- public void onMessage(MessageContext msgCtx) {
- String message;
- if (msgCtx.getType() == MessageType.TASK) {
- TaskStatusChangeEvent event = (TaskStatusChangeEvent) msgCtx.getEvent();
- TaskIdentifier taskIdentifier = event.getTaskIdentity();
- handleTaskStatusChangeEvent(event);
- message = "Received task output change event , expId : " + taskIdentifier.getExperimentId() + ", taskId : " + taskIdentifier.getTaskId() + ", workflow node Id : " + taskIdentifier.getWorkflowNodeId();
- log.debug(message);
- }else if (msgCtx.getType() == MessageType.TASKOUTPUT) {
- TaskOutputChangeEvent event = (TaskOutputChangeEvent) msgCtx.getEvent();
- TaskIdentifier taskIdentifier = event.getTaskIdentity();
- handleTaskOutputChangeEvent(event);
- message = "Received task output change event , expId : " + taskIdentifier.getExperimentId() + ", taskId : " + taskIdentifier.getTaskId() + ", workflow node Id : " + taskIdentifier.getWorkflowNodeId();
- log.debug(message);
- } else {
- // not interesting, ignores
- }
- }
-
- private void handleTaskOutputChangeEvent(TaskOutputChangeEvent taskOutputChangeEvent) {
-
- String taskId = taskOutputChangeEvent.getTaskIdentity().getTaskId();
- log.debug("Task Output changed event received for workflow node : " +
- taskOutputChangeEvent.getTaskIdentity().getWorkflowNodeId() + ", task : " + taskId);
- ProcessContext processContext = processingQueue.get(taskId);
- Set<WorkflowNode> tempWfNodeSet = new HashSet<WorkflowNode>();
- if (processContext != null) {
- WorkflowNode workflowNode = processContext.getWorkflowNode();
- if (workflowNode instanceof ApplicationNode) {
- ApplicationNode applicationNode = (ApplicationNode) workflowNode;
- // Workflow node can have one to many output ports and each output port can have one to many links
- for (OutPort outPort : applicationNode.getOutputPorts()) {
- for (OutputDataObjectType outputDataObjectType : taskOutputChangeEvent.getOutput()) {
- if (outPort.getOutputObject().getName().equals(outputDataObjectType.getName())) {
- outPort.getOutputObject().setValue(outputDataObjectType.getValue());
- break;
- }
+ synchronized void handleTaskOutputChangeEvent(TaskOutputChangeEvent taskOutputChangeEvent) {
+
+ String taskId = taskOutputChangeEvent.getTaskIdentity().getTaskId();
+ log.debug("Task Output changed event received for workflow node : " +
+ taskOutputChangeEvent.getTaskIdentity().getWorkflowNodeId() + ", task : " + taskId);
+ ProcessContext processContext = processingQueue.get(taskId);
+ Set<WorkflowNode> tempWfNodeSet = new HashSet<WorkflowNode>();
+ if (processContext != null) {
+ WorkflowNode workflowNode = processContext.getWorkflowNode();
+ if (workflowNode instanceof ApplicationNode) {
+ ApplicationNode applicationNode = (ApplicationNode) workflowNode;
+ // Workflow node can have one to many output ports and each output port can have one to many links
+ for (OutPort outPort : applicationNode.getOutputPorts()) {
+ for (OutputDataObjectType outputDataObjectType : taskOutputChangeEvent.getOutput()) {
+ if (outPort.getOutputObject().getName().equals(outputDataObjectType.getName())) {
+ outPort.getOutputObject().setValue(outputDataObjectType.getValue());
+ break;
}
- for (Edge edge : outPort.getOutEdges()) {
- edge.getToPort().getInputObject().setValue(outPort.getOutputObject().getValue());
- if (edge.getToPort().getNode().isReady()) {
- addToReadyQueue(edge.getToPort().getNode());
- }
+ }
+ for (Edge edge : outPort.getOutEdges()) {
+ edge.getToPort().getInputObject().setValue(outPort.getOutputObject().getValue());
+ if (edge.getToPort().getNode().isReady()) {
+ addToReadyQueue(edge.getToPort().getNode());
}
}
}
- addToCompleteQueue(processContext);
- log.debug("removed task from processing queue : " + taskId);
- try {
- processReadyList();
- } catch (Exception e) {
- log.error("Error while processing ready workflow nodes", e);
- continueWorkflow = false;
- }
+ }
+ addToCompleteQueue(processContext);
+ log.debug("removed task from processing queue : " + taskId);
+ try {
+ processReadyList();
+ } catch (Exception e) {
+ log.error("Error while processing ready workflow nodes", e);
+ continueWorkflow = false;
}
}
+ }
- private void handleTaskStatusChangeEvent(TaskStatusChangeEvent taskStatusChangeEvent) {
- TaskState taskState = taskStatusChangeEvent.getState();
- TaskIdentifier taskIdentity = taskStatusChangeEvent.getTaskIdentity();
- String taskId = taskIdentity.getTaskId();
- ProcessContext processContext = processingQueue.get(taskId);
- if (processContext != null) {
- WorkflowNodeState wfNodeState = WorkflowNodeState.INVOKED;
- switch (taskState) {
- case WAITING:
- break;
- case STARTED:
- break;
- case PRE_PROCESSING:
- wfNodeState = WorkflowNodeState.INVOKED;
- processContext.getWorkflowNode().setState(NodeState.PRE_PROCESSING);
- break;
- case INPUT_DATA_STAGING:
- wfNodeState = WorkflowNodeState.INVOKED;
- processContext.getWorkflowNode().setState(NodeState.PRE_PROCESSING);
- break;
- case EXECUTING:
- wfNodeState = WorkflowNodeState.EXECUTING;
- processContext.getWorkflowNode().setState(NodeState.EXECUTING);
- break;
- case OUTPUT_DATA_STAGING:
- wfNodeState = WorkflowNodeState.COMPLETED;
- processContext.getWorkflowNode().setState(NodeState.POST_PROCESSING);
- break;
- case POST_PROCESSING:
- wfNodeState = WorkflowNodeState.COMPLETED;
- processContext.getWorkflowNode().setState(NodeState.POST_PROCESSING);
- break;
- case COMPLETED:
- wfNodeState = WorkflowNodeState.COMPLETED;
- processContext.getWorkflowNode().setState(NodeState.EXECUTED);
- break;
- case FAILED:
- wfNodeState = WorkflowNodeState.FAILED;
- processContext.getWorkflowNode().setState(NodeState.FAILED);
- break;
- case UNKNOWN:
- wfNodeState = WorkflowNodeState.UNKNOWN;
- break;
- case CONFIGURING_WORKSPACE:
- wfNodeState = WorkflowNodeState.COMPLETED;
- break;
- case CANCELED:
- case CANCELING:
- wfNodeState = WorkflowNodeState.CANCELED;
- processContext.getWorkflowNode().setState(NodeState.FAILED);
- break;
- default:
- break;
- }
- if (wfNodeState != WorkflowNodeState.UNKNOWN) {
- try {
- updateWorkflowNodeStatus(processContext.getWfNodeDetails(), wfNodeState);
- } catch (RegistryException e) {
- log.error("Error while updating workflow node status update to the registry. nodeInstanceId :"
- + processContext.getWfNodeDetails().getNodeInstanceId() + " status to: "
- + processContext.getWfNodeDetails().getWorkflowNodeStatus().toString() , e);
- }
+ void handleTaskStatusChangeEvent(TaskStatusChangeEvent taskStatusChangeEvent) {
+ TaskState taskState = taskStatusChangeEvent.getState();
+ TaskIdentifier taskIdentity = taskStatusChangeEvent.getTaskIdentity();
+ String taskId = taskIdentity.getTaskId();
+ ProcessContext processContext = processingQueue.get(taskId);
+ if (processContext != null) {
+ WorkflowNodeState wfNodeState = WorkflowNodeState.INVOKED;
+ switch (taskState) {
+ case WAITING:
+ break;
+ case STARTED:
+ break;
+ case PRE_PROCESSING:
+ wfNodeState = WorkflowNodeState.INVOKED;
+ processContext.getWorkflowNode().setState(NodeState.PRE_PROCESSING);
+ break;
+ case INPUT_DATA_STAGING:
+ wfNodeState = WorkflowNodeState.INVOKED;
+ processContext.getWorkflowNode().setState(NodeState.PRE_PROCESSING);
+ break;
+ case EXECUTING:
+ wfNodeState = WorkflowNodeState.EXECUTING;
+ processContext.getWorkflowNode().setState(NodeState.EXECUTING);
+ break;
+ case OUTPUT_DATA_STAGING:
+ wfNodeState = WorkflowNodeState.COMPLETED;
+ processContext.getWorkflowNode().setState(NodeState.POST_PROCESSING);
+ break;
+ case POST_PROCESSING:
+ wfNodeState = WorkflowNodeState.COMPLETED;
+ processContext.getWorkflowNode().setState(NodeState.POST_PROCESSING);
+ break;
+ case COMPLETED:
+ wfNodeState = WorkflowNodeState.COMPLETED;
+ processContext.getWorkflowNode().setState(NodeState.EXECUTED);
+ break;
+ case FAILED:
+ wfNodeState = WorkflowNodeState.FAILED;
+ processContext.getWorkflowNode().setState(NodeState.FAILED);
+ break;
+ case UNKNOWN:
+ wfNodeState = WorkflowNodeState.UNKNOWN;
+ break;
+ case CONFIGURING_WORKSPACE:
+ wfNodeState = WorkflowNodeState.COMPLETED;
+ break;
+ case CANCELED:
+ case CANCELING:
+ wfNodeState = WorkflowNodeState.CANCELED;
+ processContext.getWorkflowNode().setState(NodeState.FAILED);
+ break;
+ default:
+ break;
+ }
+ if (wfNodeState != WorkflowNodeState.UNKNOWN) {
+ try {
+ updateWorkflowNodeStatus(processContext.getWfNodeDetails(), wfNodeState);
+ } catch (RegistryException e) {
+ log.error("Error while updating workflow node status update to the registry. nodeInstanceId :"
+ + processContext.getWfNodeDetails().getNodeInstanceId() + " status to: "
+ + processContext.getWfNodeDetails().getWorkflowNodeStatus().toString() , e);
}
}
-
}
- }
+ }
}
http://git-wip-us.apache.org/repos/asf/airavata/blob/774b092d/modules/simple-workflow/src/main/java/org/apache/airavata/simple/workflow/engine/WorkflowEnactmentService.java
----------------------------------------------------------------------
diff --git a/modules/simple-workflow/src/main/java/org/apache/airavata/simple/workflow/engine/WorkflowEnactmentService.java b/modules/simple-workflow/src/main/java/org/apache/airavata/simple/workflow/engine/WorkflowEnactmentService.java
index ec5acfa..c7ab7b9 100644
--- a/modules/simple-workflow/src/main/java/org/apache/airavata/simple/workflow/engine/WorkflowEnactmentService.java
+++ b/modules/simple-workflow/src/main/java/org/apache/airavata/simple/workflow/engine/WorkflowEnactmentService.java
@@ -21,23 +21,46 @@
package org.apache.airavata.simple.workflow.engine;
+import org.apache.airavata.common.exception.AiravataException;
import org.apache.airavata.common.utils.ServerSettings;
+import org.apache.airavata.messaging.core.MessageContext;
+import org.apache.airavata.messaging.core.MessageHandler;
+import org.apache.airavata.messaging.core.MessagingConstants;
import org.apache.airavata.messaging.core.impl.RabbitMQProcessPublisher;
-import org.apache.airavata.registry.cpi.RegistryException;
+import org.apache.airavata.messaging.core.impl.RabbitMQStatusConsumer;
+import org.apache.airavata.model.messaging.event.MessageType;
+import org.apache.airavata.model.messaging.event.TaskIdentifier;
+import org.apache.airavata.model.messaging.event.TaskOutputChangeEvent;
+import org.apache.airavata.model.messaging.event.TaskStatusChangeEvent;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class WorkflowEnactmentService {
private static WorkflowEnactmentService workflowEnactmentService;
+ private final RabbitMQStatusConsumer statusConsumer;
+ private String consumerId;
private ExecutorService executor;
+ private Map<String,SimpleWorkflowInterpreter> workflowMap;
- private WorkflowEnactmentService () {
+ private WorkflowEnactmentService () throws AiravataException {
executor = Executors.newFixedThreadPool(getThreadPoolSize());
+ workflowMap = new ConcurrentHashMap<String, SimpleWorkflowInterpreter>();
+ statusConsumer = new RabbitMQStatusConsumer();
+ consumerId = statusConsumer.listen(new TaskMessageHandler());
+ // register the shutdown hook to un-bind status consumer.
+ Runtime.getRuntime().addShutdownHook(new EnactmentShutDownHook());
}
- public static WorkflowEnactmentService getInstance(){
+ public static WorkflowEnactmentService getInstance() throws AiravataException {
if (workflowEnactmentService == null) {
synchronized (WorkflowEnactmentService.class) {
if (workflowEnactmentService == null) {
@@ -51,14 +74,110 @@ public class WorkflowEnactmentService {
public void submitWorkflow(String experimentId,
String credentialToken,
String gatewayName,
- RabbitMQProcessPublisher publisher) throws RegistryException {
+ RabbitMQProcessPublisher publisher) throws Exception {
SimpleWorkflowInterpreter simpleWorkflowInterpreter = new SimpleWorkflowInterpreter(
experimentId, credentialToken,gatewayName, publisher);
- executor.execute(simpleWorkflowInterpreter);
+ workflowMap.put(experimentId, simpleWorkflowInterpreter);
+ simpleWorkflowInterpreter.launchWorkflow();
+
}
private int getThreadPoolSize() {
return ServerSettings.getEnactmentThreadPoolSize();
}
+
+ private class TaskMessageHandler implements MessageHandler {
+
+ @Override
+ public Map<String, Object> getProperties() {
+ Map<String, Object> props = new HashMap<String, Object>();
+ String gatewayId = "*";
+ String experimentId = "*";
+ List<String> routingKeys = new ArrayList<String>();
+ routingKeys.add(gatewayId);
+ routingKeys.add(gatewayId + "." + experimentId);
+ routingKeys.add(gatewayId + "." + experimentId+ ".*");
+ routingKeys.add(gatewayId + "." + experimentId+ ".*.*");
+ props.put(MessagingConstants.RABBIT_ROUTING_KEY, routingKeys);
+ return props;
+ }
+
+ @Override
+ public void onMessage(MessageContext msgCtx) {
+ StatusHandler statusHandler = new StatusHandler(msgCtx);
+ executor.execute(statusHandler);
+ }
+
+
+ }
+
+ private class StatusHandler implements Runnable{
+ private final Logger log = LoggerFactory.getLogger(StatusHandler.class);
+
+ private final MessageContext msgCtx;
+
+ public StatusHandler(MessageContext msgCtx) {
+ this.msgCtx = msgCtx;
+ }
+
+ @Override
+ public void run() {
+ process();
+ }
+
+ private void process() {
+ String message;
+ SimpleWorkflowInterpreter simpleWorkflowInterpreter;
+ if (msgCtx.getType() == MessageType.TASK) {
+ TaskStatusChangeEvent event = (TaskStatusChangeEvent) msgCtx.getEvent();
+ TaskIdentifier taskIdentifier = event.getTaskIdentity();
+ simpleWorkflowInterpreter = getInterpreter(taskIdentifier.getExperimentId());
+ if (simpleWorkflowInterpreter != null) {
+ simpleWorkflowInterpreter.handleTaskStatusChangeEvent(event);
+ } else {
+ // this happens when Task status messages comes after the Taskoutput messages,as we have worked on
+ // output changes it is ok to ignore this.
+ }
+ message = "Received task output change event , expId : " + taskIdentifier.getExperimentId() + ", taskId : " + taskIdentifier.getTaskId() + ", workflow node Id : " + taskIdentifier.getWorkflowNodeId();
+ log.debug(message);
+ }else if (msgCtx.getType() == MessageType.TASKOUTPUT) {
+ TaskOutputChangeEvent event = (TaskOutputChangeEvent) msgCtx.getEvent();
+ TaskIdentifier taskIdentifier = event.getTaskIdentity();
+ simpleWorkflowInterpreter = getInterpreter(taskIdentifier.getExperimentId());
+ if (simpleWorkflowInterpreter != null) {
+ simpleWorkflowInterpreter.handleTaskOutputChangeEvent(event);
+ if (simpleWorkflowInterpreter.isAllDone()) {
+ workflowMap.remove(taskIdentifier.getExperimentId());
+ }
+ } else {
+ throw new IllegalArgumentException("Error while processing TaskOutputChangeEvent, " +
+ "There is no registered workflow for experiment Id : " + taskIdentifier.getExperimentId());
+ }
+ message = "Received task output change event , expId : " + taskIdentifier.getExperimentId() + ", taskId : " + taskIdentifier.getTaskId() + ", workflow node Id : " + taskIdentifier.getWorkflowNodeId();
+ log.debug(message);
+ } else {
+ // not interested, ignores
+ }
+ }
+
+ private SimpleWorkflowInterpreter getInterpreter(String experimentId){
+ return workflowMap.get(experimentId);
+ }
+ }
+
+
+ private class EnactmentShutDownHook extends Thread {
+ private final Logger log = LoggerFactory.getLogger(EnactmentShutDownHook.class);
+ @Override
+ public void run() {
+ super.run();
+ try {
+ statusConsumer.stopListen(consumerId);
+ log.info("Successfully un-binded task status consumer");
+ } catch (AiravataException e) {
+ log.error("Error while un-bind enactment status consumer", e);
+ }
+ }
+ }
}
[37/50] [abbrv] airavata git commit: Fixed sample issue with invalid
gateway id
Posted by sh...@apache.org.
Fixed sample issue with invalid gateway id
Project: http://git-wip-us.apache.org/repos/asf/airavata/repo
Commit: http://git-wip-us.apache.org/repos/asf/airavata/commit/7d787b82
Tree: http://git-wip-us.apache.org/repos/asf/airavata/tree/7d787b82
Diff: http://git-wip-us.apache.org/repos/asf/airavata/diff/7d787b82
Branch: refs/heads/master
Commit: 7d787b829217f4fda26fb5265a0afbaaad86c833
Parents: be6aecd
Author: shamrath <sh...@gmail.com>
Authored: Wed Mar 25 11:22:10 2015 -0400
Committer: shamrath <sh...@gmail.com>
Committed: Wed Mar 25 11:22:10 2015 -0400
----------------------------------------------------------------------
.../client/samples/RegisterSampleData.java | 50 ++++++++++++--------
1 file changed, 30 insertions(+), 20 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/airavata/blob/7d787b82/airavata-api/airavata-client-sdks/java-client-samples/src/main/java/org/apache/airavata/client/samples/RegisterSampleData.java
----------------------------------------------------------------------
diff --git a/airavata-api/airavata-client-sdks/java-client-samples/src/main/java/org/apache/airavata/client/samples/RegisterSampleData.java b/airavata-api/airavata-client-sdks/java-client-samples/src/main/java/org/apache/airavata/client/samples/RegisterSampleData.java
index 8b23643..c9017c3 100644
--- a/airavata-api/airavata-client-sdks/java-client-samples/src/main/java/org/apache/airavata/client/samples/RegisterSampleData.java
+++ b/airavata-api/airavata-client-sdks/java-client-samples/src/main/java/org/apache/airavata/client/samples/RegisterSampleData.java
@@ -35,6 +35,7 @@ import org.apache.airavata.model.appcatalog.computeresource.ResourceJobManagerTy
import org.apache.airavata.model.appcatalog.gatewayprofile.ComputeResourcePreference;
import org.apache.airavata.model.appcatalog.gatewayprofile.GatewayResourceProfile;
import org.apache.airavata.model.error.AiravataClientConnectException;
+import org.apache.airavata.model.workspace.Gateway;
import org.apache.thrift.TException;
import java.io.File;
@@ -45,7 +46,6 @@ public class RegisterSampleData {
private static final String THRIFT_SERVER_HOST = "127.0.0.1";
private static final int THRIFT_SERVER_PORT = 8930;
- private static final String DEFAULT_GATEWAY = "Sample";
private Airavata.Client airavataClient;
private String localhost_ip = "127.0.0.1";
@@ -58,6 +58,8 @@ public class RegisterSampleData {
private String monteXModuleId;
private String gaussianModuleId;
+ private String gatewayId;
+
public static void main(String[] args) throws AiravataClientConnectException, TException {
RegisterSampleData registerSampleData = new RegisterSampleData();
registerSampleData.init();
@@ -77,6 +79,7 @@ public class RegisterSampleData {
public void register() throws AiravataClientConnectException, TException {
airavataClient = AiravataClientFactory.createAiravataClient(THRIFT_SERVER_HOST, THRIFT_SERVER_PORT);
+ gatewayId = registerGateway();
registerLocalhost();
registerGatewayProfile();
registerApplicationModules();
@@ -84,11 +87,18 @@ public class RegisterSampleData {
registerApplicationInterfaces();
}
+ private String registerGateway() throws TException {
+ Gateway gateway = new Gateway();
+ gateway.setGatewayName("Sample");
+ gateway.setGatewayId("sample");
+ return airavataClient.addGateway(gateway);
+ }
+
private void registerGatewayProfile() throws TException {
ComputeResourcePreference localhostResourcePreference = RegisterSampleApplicationsUtils.
createComputeResourcePreference(localhostId, "Sample", false, null, null, null, sampleScriptDir + "/..");
GatewayResourceProfile gatewayResourceProfile = new GatewayResourceProfile();
- gatewayResourceProfile.setGatewayID(DEFAULT_GATEWAY);
+ gatewayResourceProfile.setGatewayID(gatewayId);
gatewayResourceProfile.addToComputeResourcePreferences(localhostResourcePreference);
airavataClient.registerGatewayResourceProfile(gatewayResourceProfile);
}
@@ -142,7 +152,7 @@ public class RegisterSampleData {
List<OutputDataObjectType> applicationOutputs = new ArrayList<OutputDataObjectType>();
applicationOutputs.add(output1);
- String addApplicationInterfaceId = airavataClient.registerApplicationInterface(DEFAULT_GATEWAY,
+ String addApplicationInterfaceId = airavataClient.registerApplicationInterface(gatewayId,
RegisterSampleApplicationsUtils.createApplicationInterfaceDescription("Gaussian", "Gaussian application",
appModules, applicationInputs, applicationOutputs));
System.out.println("Gaussian Application Interface Id " + addApplicationInterfaceId);
@@ -190,7 +200,7 @@ public class RegisterSampleData {
List<OutputDataObjectType> applicationOutputs = new ArrayList<OutputDataObjectType>();
applicationOutputs.add(output1);
- String addApplicationInterfaceId = airavataClient.registerApplicationInterface(DEFAULT_GATEWAY,
+ String addApplicationInterfaceId = airavataClient.registerApplicationInterface(gatewayId,
RegisterSampleApplicationsUtils.createApplicationInterfaceDescription("Tinker_Monte", "Monte application",
appModules, applicationInputs, applicationOutputs));
System.out.println("Monte Application Interface Id " + addApplicationInterfaceId);
@@ -203,42 +213,42 @@ public class RegisterSampleData {
private void registerApplicationDeployments() throws TException {
System.out.println("#### Registering Application Deployments on Localhost ####");
//Register Echo
- String echoAppDeployId = airavataClient.registerApplicationDeployment(DEFAULT_GATEWAY,
+ String echoAppDeployId = airavataClient.registerApplicationDeployment(gatewayId,
RegisterSampleApplicationsUtils.createApplicationDeployment(echoModuleId, localhostId,
sampleScriptDir + "/echo.sh", ApplicationParallelismType.SERIAL, "Echo application description",
null, null, null));
System.out.println("Successfully registered Echo application on localhost, application Id = " + echoAppDeployId);
//Register Add application
- String addAppDeployId = airavataClient.registerApplicationDeployment(DEFAULT_GATEWAY,
+ String addAppDeployId = airavataClient.registerApplicationDeployment(gatewayId,
RegisterSampleApplicationsUtils.createApplicationDeployment(addModuleId, localhostId,
sampleScriptDir + "/add.sh", ApplicationParallelismType.SERIAL, "Add application description",
null, null, null));
System.out.println("Successfully registered Add application on localhost, application Id = " + addAppDeployId);
//Register Multiply application
- String multiplyAppDeployId = airavataClient.registerApplicationDeployment(DEFAULT_GATEWAY,
+ String multiplyAppDeployId = airavataClient.registerApplicationDeployment(gatewayId,
RegisterSampleApplicationsUtils.createApplicationDeployment(multiplyModuleId, localhostId,
sampleScriptDir + "/multiply.sh", ApplicationParallelismType.SERIAL, "Multiply application description",
null, null, null));
System.out.println("Successfully registered Multiply application on localhost, application Id = " + multiplyAppDeployId);
//Register Subtract application
- String subtractAppDeployId = airavataClient.registerApplicationDeployment(DEFAULT_GATEWAY,
+ String subtractAppDeployId = airavataClient.registerApplicationDeployment(gatewayId,
RegisterSampleApplicationsUtils.createApplicationDeployment(subtractModuleId, localhostId,
sampleScriptDir + "/subtract.sh", ApplicationParallelismType.SERIAL, "Subtract application description ",
null, null, null));
System.out.println("Successfully registered Subtract application on localhost, application Id = " + subtractAppDeployId);
//Register Tinker monte application
- String tinkerMonteAppDeployId = airavataClient.registerApplicationDeployment(DEFAULT_GATEWAY,
+ String tinkerMonteAppDeployId = airavataClient.registerApplicationDeployment(gatewayId,
RegisterSampleApplicationsUtils.createApplicationDeployment(monteXModuleId, localhostId,
sampleScriptDir + "/monte.x", ApplicationParallelismType.SERIAL, "Grid chem tinker monte application description ",
null, null, null));
System.out.println("Successfully registered tinker monte application on localhost, application Id = " + tinkerMonteAppDeployId);
//Register Tinker monte application
- String gaussianAppDeployId = airavataClient.registerApplicationDeployment(DEFAULT_GATEWAY,
+ String gaussianAppDeployId = airavataClient.registerApplicationDeployment(gatewayId,
RegisterSampleApplicationsUtils.createApplicationDeployment(gaussianModuleId, localhostId,
sampleScriptDir + "/gaussian.sh", ApplicationParallelismType.SERIAL, "Grid chem Gaussian application description ",
null, null, null));
@@ -247,28 +257,28 @@ public class RegisterSampleData {
private void registerApplicationModules() throws TException {
//Register Echo
- echoModuleId = airavataClient.registerApplicationModule(DEFAULT_GATEWAY,
+ echoModuleId = airavataClient.registerApplicationModule(gatewayId,
RegisterSampleApplicationsUtils.createApplicationModule(
"Echo", "1.0", "Echo application description"));
//Register Echo
- addModuleId = airavataClient.registerApplicationModule(DEFAULT_GATEWAY,
+ addModuleId = airavataClient.registerApplicationModule(gatewayId,
RegisterSampleApplicationsUtils.createApplicationModule(
"Add", "1.0", "Add application description"));
//Register Echo
- multiplyModuleId = airavataClient.registerApplicationModule(DEFAULT_GATEWAY,
+ multiplyModuleId = airavataClient.registerApplicationModule(gatewayId,
RegisterSampleApplicationsUtils.createApplicationModule(
"Multiply", "1.0", "Multiply application description"));
//Register Echo
- subtractModuleId = airavataClient.registerApplicationModule(DEFAULT_GATEWAY,
+ subtractModuleId = airavataClient.registerApplicationModule(gatewayId,
RegisterSampleApplicationsUtils.createApplicationModule(
"Subtract", "1.0", "Subtract application description"));
//Register Monte
- monteXModuleId = airavataClient.registerApplicationModule(DEFAULT_GATEWAY,
+ monteXModuleId = airavataClient.registerApplicationModule(gatewayId,
RegisterSampleApplicationsUtils.createApplicationModule(
"Tinker Monte", "1.0", "Grid chem tinker monte application description"));
// Register gaussian application
- gaussianModuleId = airavataClient.registerApplicationModule(DEFAULT_GATEWAY,
+ gaussianModuleId = airavataClient.registerApplicationModule(gatewayId,
RegisterSampleApplicationsUtils.createApplicationModule(
"Gaussian", "1.0", "Grid Chem Gaussian application description"));
@@ -294,7 +304,7 @@ public class RegisterSampleData {
List<OutputDataObjectType> applicationOutputs = new ArrayList<OutputDataObjectType>();
applicationOutputs.add(output1);
- String echoInterfaceId = airavataClient.registerApplicationInterface(DEFAULT_GATEWAY,
+ String echoInterfaceId = airavataClient.registerApplicationInterface(gatewayId,
RegisterSampleApplicationsUtils.createApplicationInterfaceDescription("Echo", "Echo application description",
appModules, applicationInputs, applicationOutputs));
System.out.println("Echo Application Interface Id " + echoInterfaceId);
@@ -326,7 +336,7 @@ public class RegisterSampleData {
List<OutputDataObjectType> applicationOutputs = new ArrayList<OutputDataObjectType>();
applicationOutputs.add(output1);
- String addApplicationInterfaceId = airavataClient.registerApplicationInterface(DEFAULT_GATEWAY,
+ String addApplicationInterfaceId = airavataClient.registerApplicationInterface(gatewayId,
RegisterSampleApplicationsUtils.createApplicationInterfaceDescription("Add", "Add two numbers",
appModules, applicationInputs, applicationOutputs));
System.out.println("Add Application Interface Id " + addApplicationInterfaceId);
@@ -358,7 +368,7 @@ public class RegisterSampleData {
List<OutputDataObjectType> applicationOutputs = new ArrayList<OutputDataObjectType>();
applicationOutputs.add(output1);
- String multiplyApplicationInterfaceId = airavataClient.registerApplicationInterface(DEFAULT_GATEWAY,
+ String multiplyApplicationInterfaceId = airavataClient.registerApplicationInterface(gatewayId,
RegisterSampleApplicationsUtils.createApplicationInterfaceDescription("Multiply", "Multiply two numbers",
appModules, applicationInputs, applicationOutputs));
System.out.println("Multiply Application Interface Id " + multiplyApplicationInterfaceId);
@@ -390,7 +400,7 @@ public class RegisterSampleData {
List<OutputDataObjectType> applicationOutputs = new ArrayList<OutputDataObjectType>();
applicationOutputs.add(output1);
- String subtractApplicationInterfaceId = airavataClient.registerApplicationInterface(DEFAULT_GATEWAY,
+ String subtractApplicationInterfaceId = airavataClient.registerApplicationInterface(gatewayId,
RegisterSampleApplicationsUtils.createApplicationInterfaceDescription("Subtract", "Subtract two numbers",
appModules, applicationInputs, applicationOutputs));
System.out.println("Subtract Application Interface Id " + subtractApplicationInterfaceId);
[32/50] [abbrv] airavata git commit: Mereged master branch
Posted by sh...@apache.org.
Mereged master branch
Project: http://git-wip-us.apache.org/repos/asf/airavata/repo
Commit: http://git-wip-us.apache.org/repos/asf/airavata/commit/0db33d2e
Tree: http://git-wip-us.apache.org/repos/asf/airavata/tree/0db33d2e
Diff: http://git-wip-us.apache.org/repos/asf/airavata/diff/0db33d2e
Branch: refs/heads/master
Commit: 0db33d2e515603f94a8fc4abd34b1b91f6a1faa4
Parents: 48192d9 73f371d
Author: shamrath <sh...@gmail.com>
Authored: Thu Mar 19 15:11:10 2015 -0400
Committer: shamrath <sh...@gmail.com>
Committed: Thu Mar 19 15:11:10 2015 -0400
----------------------------------------------------------------------
.../airavata/api/server/AiravataAPIServer.java | 38 +-
.../server/handler/AiravataServerHandler.java | 498 +-
.../api/server/util/DataModelUtils.java | 8 +-
.../java/org/apache/airavata/api/Airavata.java | 49461 ++++++++++++-----
.../airavata/api/airavataAPIConstants.java | 2 +-
.../main/resources/lib/airavata/Airavata.cpp | 15118 +++--
.../src/main/resources/lib/airavata/Airavata.h | 7404 ++-
.../lib/airavata/Airavata_server.skeleton.cpp | 115 +-
.../lib/airavata/airavataAPI_constants.cpp | 2 +-
.../lib/airavata/computeResourceModel_types.cpp | 12 +-
.../lib/airavata/computeResourceModel_types.h | 5 +-
.../lib/airavata/experimentModel_types.cpp | 62 +-
.../lib/airavata/experimentModel_types.h | 61 +-
.../gatewayResourceProfileModel_constants.cpp | 2 -
.../gatewayResourceProfileModel_constants.h | 1 -
.../gatewayResourceProfileModel_types.cpp | 72 +-
.../gatewayResourceProfileModel_types.h | 45 +-
.../lib/airavata/workspaceModel_types.cpp | 51 +-
.../lib/airavata/workspaceModel_types.h | 45 +-
.../resources/lib/Airavata/API/Airavata.php | 13160 +++--
.../main/resources/lib/Airavata/API/Types.php | 2 +-
.../Model/AppCatalog/ComputeResource/Types.php | 10 +-
.../Model/AppCatalog/GatewayProfile/Types.php | 92 +-
.../Model/Workspace/Experiment/Types.php | 60 +
.../lib/Airavata/Model/Workspace/Types.php | 58 +-
.../client/samples/CreateLaunchExperiment.java | 1007 +-
.../samples/CreateLaunchExperimentUS3.java | 20 +-
.../client/samples/RegisterSampleData.java | 37 +-
.../samples/TestCreateLaunchExperiment.java | 10 +-
.../tools/RegisterOGCEUS3Application.java | 10 +-
.../tools/RegisterSampleApplications.java | 366 +-
.../client/tools/RegisterUS3Application.java | 14 +-
.../computeresource/AuthenticationMode.java | 70 +
.../computeresource/ResourceJobManagerType.java | 42 +-
.../computeresource/UnicoreJobSubmission.java | 2 +
.../ComputeResourcePreference.java | 168 +-
.../gatewayprofile/GatewayResourceProfile.java | 226 +-
.../airavata/model/workspace/Gateway.java | 334 +-
.../ComputationalResourceScheduling.java | 109 +-
.../experiment/UserConfigurationData.java | 205 +-
.../airavataAPI.thrift | 192 +-
.../computeResourceModel.thrift | 23 +-
.../experimentModel.thrift | 11 +-
.../gatewayResourceProfileModel.thrift | 28 +-
.../workspaceModel.thrift | 6 +-
.../appcatalog/cpi/ApplicationDeployment.java | 4 +-
.../appcatalog/cpi/ApplicationInterface.java | 8 +-
.../appcatalog/cpi/ComputeResource.java | 3 +
.../appcatalog/cpi/WorkflowCatalog.java | 4 +-
.../data/impl/ApplicationDeploymentImpl.java | 6 +-
.../data/impl/ApplicationInterfaceImpl.java | 12 +-
.../catalog/data/impl/ComputeResourceImpl.java | 45 +-
.../data/impl/GwyResourceProfileImpl.java | 30 +-
.../catalog/data/impl/WorkflowCatalogImpl.java | 6 +-
.../data/model/ApplicationDeployment.java | 10 +
.../data/model/ApplicationInterface.java | 10 +
.../catalog/data/model/ApplicationModule.java | 10 +
.../data/model/ComputeResourcePreference.java | 10 +
.../catalog/data/model/GatewayProfile.java | 19 -
.../catalog/data/model/UnicoreDataMovement.java | 65 +
.../data/model/UnicoreJobSubmission.java | 5 +-
.../catalog/data/model/Workflow.java | 10 +
.../data/resources/AbstractResource.java | 13 +-
.../data/resources/AppDeploymentResource.java | 12 +
.../data/resources/AppInterfaceResource.java | 12 +
.../data/resources/AppModuleResource.java | 12 +
.../ComputeHostPreferenceResource.java | 11 +
.../data/resources/GatewayProfileResource.java | 30 +-
.../resources/UnicoreDataMovementResource.java | 255 +
.../resources/UnicoreJobSubmissionResource.java | 16 +-
.../data/resources/WorkflowResource.java | 12 +
.../catalog/data/util/AppCatalogJPAUtils.java | 26 +-
.../data/util/AppCatalogResourceType.java | 1 +
.../data/util/AppCatalogThriftConversion.java | 29 +-
.../src/main/resources/META-INF/persistence.xml | 1 +
.../src/main/resources/appcatalog-derby.sql | 219 +-
.../src/main/resources/appcatalog-mysql.sql | 218 +-
.../app/catalog/test/AppDeploymentTest.java | 11 +-
.../app/catalog/test/AppInterfaceTest.java | 12 +-
.../app/catalog/test/GatewayProfileTest.java | 5 +-
.../src/test/resources/appcatalog-derby.sql | 219 +-
modules/commons/utils/pom.xml | 4 +-
.../apache/airavata/common/utils/Constants.java | 4 +-
.../common/utils/DatabaseTestCases.java | 2 +-
.../airavata/common/utils/WSConstants.java | 10 +-
.../apache/airavata/common/utils/WSDLUtil.java | 764 +-
.../apache/airavata/common/utils/XMLUtil.java | 34 +-
.../main/resources/airavata-client.properties | 2 +-
.../server/src/main/resources/LSFTemplate.xslt | 92 +
.../server/src/main/resources/PBSTemplate.xslt | 22 +-
.../server/src/main/resources/SGETemplate.xslt | 18 +-
.../src/main/resources/SLURMTemplate.xslt | 22 +-
.../main/resources/airavata-server.properties | 6 +-
.../credential-store-webapp/pom.xml | 158 -
.../basic/BasicAccessAuthenticator.java | 226 -
.../credentialstore/local/LocalUserStore.java | 339 -
.../session/HttpAuthenticatorFilter.java | 191 -
.../session/ServletRequestHelper.java | 129 -
.../main/resources/airavata-server.properties | 241 -
.../main/resources/credential-store/client.xml | 36 -
.../credential-store/oauth-privkey.pk8 | 28 -
.../resources/credential-store/oauth-pubkey.pem | 9 -
.../src/main/webapp/WEB-INF/web.xml | 130 -
.../src/main/webapp/acs/index.jsp | 44 -
.../src/main/webapp/credential-store/error.jsp | 53 -
.../credential-store/password-credentials.jsp | 33 -
.../webapp/credential-store/show-redirect.jsp | 44 -
.../main/webapp/credential-store/success.jsp | 25 -
.../src/main/webapp/gateway/acs.jsp | 62 -
.../src/main/webapp/gateway/callback.jsp | 78 -
.../src/main/webapp/gateway/list_users.jsp | 78 -
.../src/main/webapp/gateway/logout.jsp | 35 -
.../src/main/webapp/gateway/user.jsp | 102 -
.../src/main/webapp/images/airavata-logo-2.png | Bin 4314 -> 0 bytes
.../src/main/webapp/index.jsp | 26 -
.../src/main/webapp/user-store/add.jsp | 142 -
.../src/main/webapp/user-store/index.jsp | 138 -
.../src/main/webapp/user-store/password.jsp | 157 -
.../credential-store/pom.xml | 149 -
.../scripts/credential-store-h2.sql | 42 -
.../scripts/credential-store-mysql.sql | 42 -
.../credential/store/client/TestSSLClient.java | 140 -
.../store/cpi/CredentialStoreService.java | 6888 ---
.../store/cpi/cs_cpi_serviceConstants.java | 55 -
.../credential/store/credential/AuditInfo.java | 53 -
.../store/credential/CommunityUser.java | 71 -
.../credential/store/credential/Credential.java | 62 -
.../impl/certificate/CertificateAuditInfo.java | 101 -
.../impl/certificate/CertificateCredential.java | 102 -
.../impl/password/PasswordCredential.java | 53 -
.../credential/impl/ssh/SSHCredential.java | 88 -
.../impl/ssh/SSHCredentialGenerator.java | 103 -
.../store/datamodel/CertificateCredential.java | 1104 -
.../store/datamodel/CommunityUser.java | 589 -
.../store/datamodel/PasswordCredential.java | 698 -
.../store/datamodel/SSHCredential.java | 998 -
.../store/datamodel/csDataModelConstants.java | 55 -
.../exception/CredentialStoreException.java | 397 -
.../store/notifier/CredentialStoreNotifier.java | 42 -
.../store/notifier/NotificationMessage.java | 46 -
.../store/notifier/NotifierBootstrap.java | 144 -
.../notifier/impl/EmailNotificationMessage.java | 58 -
.../store/notifier/impl/EmailNotifier.java | 71 -
.../impl/EmailNotifierConfiguration.java | 84 -
.../store/server/CredentialStoreServer.java | 158 -
.../server/CredentialStoreServerHandler.java | 201 -
.../store/servlet/CredentialBootstrapper.java | 49 -
.../servlet/CredentialStoreCallbackServlet.java | 272 -
.../servlet/CredentialStoreStartServlet.java | 183 -
.../store/store/CredentialReader.java | 112 -
.../store/store/CredentialReaderFactory.java | 54 -
.../store/store/CredentialStoreException.java | 40 -
.../store/store/CredentialWriter.java | 39 -
.../store/impl/CertificateCredentialWriter.java | 121 -
.../store/store/impl/CredentialReaderImpl.java | 162 -
.../store/store/impl/SSHCredentialWriter.java | 87 -
.../store/store/impl/db/CommunityUserDAO.java | 257 -
.../store/store/impl/db/CredentialsDAO.java | 458 -
.../store/store/impl/db/ParentDAO.java | 37 -
.../store/util/ConfigurationReader.java | 121 -
.../store/util/CredentialStoreConstants.java | 37 -
.../credential/store/util/PrivateKeyStore.java | 70 -
.../credential/store/util/TokenGenerator.java | 57 -
.../airavata/credential/store/util/Utility.java | 110 -
.../store/notifier/impl/EmailNotifierTest.java | 56 -
.../store/impl/db/CommunityUserDAOTest.java | 207 -
.../store/store/impl/db/CredentialsDAOTest.java | 421 -
.../store/util/ConfigurationReaderTest.java | 58 -
.../store/util/TokenGeneratorTest.java | 42 -
.../test/resources/credential-store/client.xml | 35 -
.../src/test/resources/keystore.jks | Bin 2230 -> 0 bytes
.../src/test/resources/mykeystore.jks | Bin 498 -> 0 bytes
.../credentialStoreErrors.thrift | 32 -
.../cs-thrift-description/cs.cpi.service.thrift | 50 -
.../cs-thrift-description/csDataModel.thrift | 61 -
.../cs-thrift-description/generate-cs-stubs.sh | 134 -
modules/credential-store-service/pom.xml | 42 -
.../credential-store-service/pom.xml | 166 +
.../scripts/credential-store-h2.sql | 42 +
.../scripts/credential-store-mysql.sql | 42 +
.../credential/store/credential/AuditInfo.java | 53 +
.../store/credential/CommunityUser.java | 71 +
.../credential/store/credential/Credential.java | 62 +
.../impl/certificate/CertificateAuditInfo.java | 101 +
.../impl/certificate/CertificateCredential.java | 102 +
.../impl/password/PasswordCredential.java | 53 +
.../credential/impl/ssh/SSHCredential.java | 88 +
.../impl/ssh/SSHCredentialGenerator.java | 103 +
.../store/notifier/CredentialStoreNotifier.java | 42 +
.../store/notifier/NotificationMessage.java | 46 +
.../store/notifier/NotifierBootstrap.java | 144 +
.../notifier/impl/EmailNotificationMessage.java | 58 +
.../store/notifier/impl/EmailNotifier.java | 71 +
.../impl/EmailNotifierConfiguration.java | 84 +
.../store/server/CredentialStoreServer.java | 158 +
.../server/CredentialStoreServerHandler.java | 202 +
.../store/servlet/CredentialBootstrapper.java | 49 +
.../servlet/CredentialStoreCallbackServlet.java | 272 +
.../servlet/CredentialStoreStartServlet.java | 183 +
.../store/store/CredentialReader.java | 112 +
.../store/store/CredentialReaderFactory.java | 54 +
.../store/store/CredentialStoreException.java | 40 +
.../store/store/CredentialWriter.java | 39 +
.../store/impl/CertificateCredentialWriter.java | 121 +
.../store/store/impl/CredentialReaderImpl.java | 162 +
.../store/store/impl/SSHCredentialWriter.java | 87 +
.../store/store/impl/db/CommunityUserDAO.java | 257 +
.../store/store/impl/db/CredentialsDAO.java | 458 +
.../store/store/impl/db/ParentDAO.java | 37 +
.../store/util/ConfigurationReader.java | 121 +
.../store/util/CredentialStoreConstants.java | 37 +
.../credential/store/util/PrivateKeyStore.java | 70 +
.../credential/store/util/TokenGenerator.java | 57 +
.../airavata/credential/store/util/Utility.java | 110 +
.../store/notifier/impl/EmailNotifierTest.java | 56 +
.../store/impl/db/CommunityUserDAOTest.java | 207 +
.../store/store/impl/db/CredentialsDAOTest.java | 421 +
.../store/store/impl/db/SSHCredentialTest.java | 92 +
.../store/util/ConfigurationReaderTest.java | 58 +
.../store/util/TokenGeneratorTest.java | 42 +
.../test/resources/airavata-server.properties | 254 +
.../test/resources/credential-store/client.xml | 35 +
.../src/test/resources/keystore.jks | Bin 0 -> 2230 bytes
.../src/test/resources/mykeystore.jks | Bin 0 -> 498 bytes
.../credential-store-stubs/pom.xml | 50 +
.../credential/store/client/TestSSLClient.java | 140 +
.../store/cpi/CredentialStoreService.java | 6888 +++
.../store/cpi/credentialStoreCPIConstants.java | 55 +
.../store/datamodel/CertificateCredential.java | 1104 +
.../store/datamodel/CommunityUser.java | 589 +
.../store/datamodel/PasswordCredential.java | 698 +
.../store/datamodel/SSHCredential.java | 998 +
.../credentialStoreDataModelConstants.java | 55 +
.../exception/CredentialStoreException.java | 397 +
.../credential-store-webapp/pom.xml | 158 +
.../basic/BasicAccessAuthenticator.java | 226 +
.../credentialstore/local/LocalUserStore.java | 339 +
.../session/HttpAuthenticatorFilter.java | 191 +
.../session/ServletRequestHelper.java | 129 +
.../main/resources/airavata-server.properties | 241 +
.../main/resources/credential-store/client.xml | 36 +
.../credential-store/oauth-privkey.pk8 | 28 +
.../resources/credential-store/oauth-pubkey.pem | 9 +
.../src/main/webapp/WEB-INF/web.xml | 130 +
.../src/main/webapp/acs/index.jsp | 44 +
.../src/main/webapp/credential-store/error.jsp | 53 +
.../credential-store/password-credentials.jsp | 33 +
.../webapp/credential-store/show-redirect.jsp | 44 +
.../main/webapp/credential-store/success.jsp | 25 +
.../src/main/webapp/gateway/acs.jsp | 62 +
.../src/main/webapp/gateway/callback.jsp | 78 +
.../src/main/webapp/gateway/list_users.jsp | 78 +
.../src/main/webapp/gateway/logout.jsp | 35 +
.../src/main/webapp/gateway/user.jsp | 102 +
.../src/main/webapp/images/airavata-logo-2.png | Bin 0 -> 4314 bytes
.../src/main/webapp/index.jsp | 26 +
.../src/main/webapp/user-store/add.jsp | 142 +
.../src/main/webapp/user-store/index.jsp | 138 +
.../src/main/webapp/user-store/password.jsp | 157 +
.../credentialStoreCPI.thrift | 61 +
.../credentialStoreDataModel.thrift | 61 +
.../credentialStoreErrors.thrift | 32 +
.../cs-thrift-descriptions/generate-cs-stubs.sh | 134 +
modules/credential-store/pom.xml | 43 +
modules/distribution/server/pom.xml | 1251 +-
.../server/src/main/assembly/bin-assembly.xml | 1 +
.../server/src/main/resources/bin/data.sql | 141 -
.../airavata/gfac/server/GfacServerHandler.java | 44 +-
.../airavata/gfac/client/util/Initialize.java | 4 +-
modules/gfac/gfac-bes/pom.xml | 9 +-
.../gfac/bes/provider/impl/BESProvider.java | 10 +-
.../org/apache/airavata/gfac/RequestData.java | 2 +
.../gfac/core/context/JobExecutionContext.java | 9 +
.../airavata/gfac/core/cpi/BetterGfacImpl.java | 26 +-
.../airavata/gfac/core/utils/GFacUtils.java | 2 +-
.../gfac/core/utils/OutHandlerWorker.java | 11 +-
modules/gfac/gfac-gsissh/pom.xml | 10 -
.../handler/GSISSHDirectorySetupHandler.java | 7 +-
.../gfac/gsissh/util/GFACGSISSHUtils.java | 10 +-
.../monitor/impl/pull/qstat/HPCPullMonitor.java | 42 +-
.../impl/pull/qstat/ResourceConnection.java | 16 +-
.../airavata/gfac/monitor/util/CommonUtils.java | 1 +
modules/gfac/gfac-ssh/pom.xml | 10 -
.../ssh/handler/SSHDirectorySetupHandler.java | 7 +-
.../gfac/ssh/provider/impl/SSHProvider.java | 1 +
.../gfac/ssh/security/TokenizedSSHAuthInfo.java | 5 +-
.../airavata/gfac/ssh/util/GFACSSHUtils.java | 98 +-
.../airavata/gfac/ssh/util/HandleOutputs.java | 5 +-
.../apache/airavata/integration/BaseCaseIT.java | 4 +-
.../airavata/integration/DataRetrievalIT.java | 8 +-
.../airavata/integration/SimpleEchoIT.java | 4 +-
.../SingleAppIntegrationTestBase.java | 6 +-
.../WorkflowIntegrationTestBase.java | 2 +-
.../integration/tools/DocumentCreatorNew.java | 75 +-
.../messaging/client/RabbitMQListener.java | 13 +
.../airavata/messaging/client/TestReader.java | 50 +
.../core/impl/RabbitMQStatusPublisher.java | 5 +-
.../messaging/core/stats/CountWriterTask.java | 35 +
.../messaging/core/stats/LatencyWriterTask.java | 37 +
.../messaging/core/stats/StatCounter.java | 38 +-
.../messaging/core/stats/WriterTask.java | 38 -
.../orchestrator/util/DataModelUtils.java | 10 +-
.../orchestrator/client/util/Initialize.java | 4 +-
.../airavata/orchestrator/cpi/Orchestrator.java | 2 +-
.../orchestrator/core/util/Initialize.java | 4 +-
.../persistance/registry/jpa/ResourceType.java | 2 -
.../persistance/registry/jpa/ResourceUtils.java | 69 +-
.../registry/jpa/impl/ExperimentRegistry.java | 16 +-
.../registry/jpa/impl/GatewayRegistry.java | 76 +
.../registry/jpa/impl/LoggingRegistryImpl.java | 35 +-
.../registry/jpa/impl/ProjectRegistry.java | 16 +-
.../registry/jpa/impl/RegistryFactory.java | 17 +
.../registry/jpa/impl/RegistryImpl.java | 28 +-
.../Computational_Resource_Scheduling.java | 10 +
.../registry/jpa/model/Experiment.java | 14 +-
.../jpa/model/ExperimentConfigData.java | 20 +
.../persistance/registry/jpa/model/Gateway.java | 32 +-
.../registry/jpa/model/Gateway_Worker.java | 14 +-
.../registry/jpa/model/Gateway_Worker_PK.java | 14 +-
.../persistance/registry/jpa/model/Project.java | 13 +-
.../registry/jpa/model/Published_Workflow.java | 124 -
.../jpa/model/Published_Workflow_PK.java | 64 -
.../registry/jpa/model/User_Workflow.java | 122 -
.../registry/jpa/model/User_Workflow_PK.java | 74 -
.../jpa/resources/AbstractResource.java | 33 +-
.../ComputationSchedulingResource.java | 10 +
.../jpa/resources/ConfigDataResource.java | 22 +
.../jpa/resources/ExperimentResource.java | 6 +-
.../registry/jpa/resources/GatewayResource.java | 159 +-
.../registry/jpa/resources/ProjectResource.java | 4 +-
.../jpa/resources/PublishWorkflowResource.java | 282 -
.../jpa/resources/UserWorkflowResource.java | 174 -
.../registry/jpa/resources/Utils.java | 72 +-
.../registry/jpa/resources/WorkerResource.java | 100 +-
.../jpa/utils/ThriftDataModelConversion.java | 22 +
.../src/main/resources/META-INF/persistence.xml | 2 -
.../src/main/resources/registry-derby.sql | 58 +-
.../src/main/resources/registry-mysql.sql | 56 +-
.../registry/jpa/GatewayResourceTest.java | 26 +-
.../jpa/PublishWorkflowResourceTest.java | 62 -
.../registry/jpa/UserWorkflowResourceTest.java | 66 -
.../registry/jpa/util/Initialize.java | 4 +-
.../src/test/resources/registry-derby.sql | 58 +-
.../airavata/registry/cpi/ParentDataType.java | 3 +-
.../apache/airavata/registry/cpi/Registry.java | 2 +-
.../registry/cpi/RegistryModelType.java | 1 +
.../airavata/registry/cpi/utils/Constants.java | 3 +-
.../src/test/resources/jdbc-authenticator.xml | 2 +-
.../test/resources/session-authenticator.xml | 2 +-
modules/test-suite/pom.xml | 116 -
.../tests/LeadCallbackHandlerTest.java | 173 -
.../tests/LeadNotificationManagerTest.java | 49 -
.../tests/MultipleSubscriptionTest.java | 105 -
.../tests/RenewSubscriptionTest.java | 155 -
.../tests/ThreadMessagePassingCallback.java | 27 -
.../tests/impl/publish/Test.java | 40 -
.../tests/impl/publish/TestWSMPublisher.java | 119 -
.../tests/messagebox/MessagePullerTest.java | 140 -
.../MultipleSubscriptionForMessageBoxTest.java | 118 -
.../tests/messagebox/RenewSubscriptionTest.java | 109 -
.../tests/messagebox/SubscriberThread.java | 96 -
.../restart/MessageBoxClientRestartTest.java | 131 -
.../restart/MessageBoxCreateThread.java | 83 -
.../tests/samples/workflow/SimpleTest.java | 202 -
.../workflow/SimpleWorkflowExecution.java | 473 -
.../workflow/WorkflowNotificationListener.java | 127 -
.../tests/util/CommonUtils.java | 26 -
.../tests/util/SubscriberThread.java | 91 -
.../tests/util/TestConfigKeys.java | 34 -
.../src/test/resources/gram.properties.template | 70 -
.../src/test/resources/unit_test.properties | 26 -
modules/workflow-model/workflow-engine/pom.xml | 5 +-
.../airavata/workflow/engine/WorkflowUtils.java | 10 +-
.../engine/gfac/GFacRegistryClient.java | 186 +-
.../workflow/engine/gfac/SimpleWSClient.java | 166 +-
.../interpretor/SystemComponentInvoker.java | 86 +-
.../engine/interpretor/WorkflowInterpreter.java | 24 +-
.../engine/invoker/AsynchronousInvoker.java | 98 +-
.../workflow/engine/invoker/DynamicInvoker.java | 48 +-
.../workflow/engine/invoker/Invoker.java | 84 +-
.../workflow/engine/invoker/SimpleInvoker.java | 411 +-
.../workflow/engine/util/InterpreterUtil.java | 112 +-
.../workflow/engine/util/XBayaUtil.java | 94 +-
.../engine/workflow/proxy/WorkflowContext.java | 4 +-
.../workflow-model-component/pom.xml | 7 +-
.../registry/JCRComponentRegistry.java | 3 +-
.../workflow-model/workflow-model-core/pom.xml | 8 +-
.../component/system/SubWorkflowComponent.java | 4 +-
.../component/url/URLComponentRegistry.java | 12 +-
.../component/ws/WSComponentApplication.java | 2 +-
.../model/component/ws/WSComponentFactory.java | 8 +-
.../model/component/ws/WSComponentRegistry.java | 32 +-
.../model/component/ws/WorkflowComponent.java | 108 +-
.../airavata/workflow/model/gpel/DSCUtil.java | 140 +-
.../workflow/model/gpel/script/BPELScript.java | 1276 +-
.../model/gpel/script/WorkflowWSDL.java | 528 +-
.../model/graph/system/StreamSourceNode.java | 7 +-
.../workflow/model/ode/ODEBPELTransformer.java | 1260 +-
.../airavata/workflow/model/ode/ODEClient.java | 200 +-
.../model/ode/ODEDeploymentDescriptor.java | 368 +-
.../workflow/model/ode/ODEWSDLTransformer.java | 872 +-
.../workflow/model/ode/WSDLCleaner.java | 196 +-
.../workflow/model/wf/TridentTransformer.java | 50 +-
.../airavata/workflow/model/wf/Workflow.java | 542 +-
modules/xbaya-gui/pom.xml | 5 +
.../xbaya/core/generators/BPELFiler.java | 38 +-
.../xbaya/core/generators/ODEScriptFiler.java | 68 +-
.../xbaya/invoker/factory/InvokerFactory.java | 16 +-
.../graph/dynamic/DynamicNodeWindow.java | 72 +-
.../dialogs/workflow/WorkflowImportWindow.java | 3 +-
.../ui/experiment/LaunchApplicationWindow.java | 8 +-
.../RegistryWorkflowPublisherWindow.java | 3 +-
.../WorkflowInterpreterLaunchWindow.java | 9 +-
pom.xml | 6 +-
tools/gsissh/pom.xml | 8 +-
.../java/com/jcraft/jsch/ExtendedSession.java | 2 -
.../illinois/ncsa/BCGSS/BCGSSContextImpl.java | 2894 +-
.../illinois/ncsa/BCGSS/CircularByteBuffer.java | 1648 +-
.../ncsa/BCGSS/GlobusTlsCipherFactory.java | 126 +-
.../illinois/ncsa/BCGSS/GlobusTlsClient.java | 494 +-
.../edu/illinois/ncsa/BCGSS/TlsHandlerUtil.java | 564 +-
.../apache/airavata/gsi/ssh/GSSContextX509.java | 43 +-
.../airavata/gsi/ssh/api/job/JobDescriptor.java | 14 +
.../ssh/api/job/JobManagerConfiguration.java | 9 +-
.../gsi/ssh/api/job/LSFJobConfiguration.java | 116 +
.../gsi/ssh/api/job/LSFOutputParser.java | 110 +
.../airavata/gsi/ssh/api/job/OutputParser.java | 14 +-
.../gsi/ssh/api/job/PBSJobConfiguration.java | 15 +
.../gsi/ssh/api/job/PBSOutputParser.java | 8 +-
.../gsi/ssh/api/job/SGEOutputParser.java | 8 +-
.../gsi/ssh/api/job/SlurmJobConfiguration.java | 15 +
.../gsi/ssh/api/job/SlurmOutputParser.java | 10 +-
.../gsi/ssh/impl/GSISSHAbstractCluster.java | 233 +-
.../apache/airavata/gsi/ssh/impl/JobStatus.java | 20 +-
.../airavata/gsi/ssh/impl/PBSCluster.java | 4 +
.../airavata/gsi/ssh/impl/RawCommandInfo.java | 8 +-
.../gsi/ssh/listener/JobSubmissionListener.java | 2 +-
.../airavata/gsi/ssh/util/CommonUtils.java | 13 +
.../apache/airavata/gsi/ssh/util/SSHUtils.java | 4 +-
.../gsissh/src/main/resources/LSFTemplate.xslt | 93 +
.../main/resources/schemas/PBSJobDescriptor.xsd | 3 +-
.../impl/DefaultSSHApiTestWithMyProxyAuth.java | 32 +-
.../gsi/ssh/impl/VanilaTestWithSSHAuth.java | 90 +-
tools/registry-tool/README | 2 +-
444 files changed, 91302 insertions(+), 58080 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/airavata/blob/0db33d2e/airavata-api/airavata-api-server/src/main/java/org/apache/airavata/api/server/handler/AiravataServerHandler.java
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/airavata/blob/0db33d2e/airavata-api/airavata-client-sdks/java-client-samples/src/main/java/org/apache/airavata/client/samples/CreateLaunchExperiment.java
----------------------------------------------------------------------
diff --cc airavata-api/airavata-client-sdks/java-client-samples/src/main/java/org/apache/airavata/client/samples/CreateLaunchExperiment.java
index dd8686d,ed141b9..812f6c4
--- a/airavata-api/airavata-client-sdks/java-client-samples/src/main/java/org/apache/airavata/client/samples/CreateLaunchExperiment.java
+++ b/airavata-api/airavata-client-sdks/java-client-samples/src/main/java/org/apache/airavata/client/samples/CreateLaunchExperiment.java
@@@ -54,16 -55,16 +55,17 @@@ public class CreateLaunchExperiment
private final static Logger logger = LoggerFactory.getLogger(CreateLaunchExperiment.class);
private static final String DEFAULT_USER = "default.registry.user";
- private static final String DEFAULT_GATEWAY = "default.registry.gateway";
+ private static final String DEFAULT_GATEWAY = "php_reference_gateway";
private static Airavata.Client airavataClient;
- private static String echoAppId = "Echo_a8fc8511-7b8e-431a-ad0f-de5eb1a9c576";
++
+ private static String echoAppId = "Echo_61988d1f-7ca9-47ba-9212-a0ac2e973cf1";
private static String mpiAppId = "HelloMPI_720e159f-198f-4daa-96ca-9f5eafee92c9";
private static String wrfAppId = "WRF_7ad5da38-c08b-417c-a9ea-da9298839762";
- private static String amberAppId = "Amber_42124128-628b-484c-829d-aff8b584eb00";
+ private static String amberAppId = "Amber_aa083c86-4680-4002-b3ef-fad93c181926";
private static String gromacsAppId = "GROMACS_05622038-9edd-4cb1-824e-0b7cb993364b";
private static String espressoAppId = "ESPRESSO_10cc2820-5d0b-4c63-9546-8a8b595593c1";
- private static String lammpsAppId = "LAMMPS_10893eb5-3840-438c-8446-d26c7ecb001f";
+ private static String lammpsAppId = "LAMMPS_2472685b-8acf-497e-aafe-cc66fe5f4cb6";
private static String nwchemAppId = "NWChem_2c8fee64-acf9-4a89-b6d3-91eb53c7640c";
private static String trinityAppId = "Trinity_e894acf5-9bca-46e8-a1bd-7e2d5155191a";
private static String autodockAppId = "AutoDock_43d9fdd0-c404-49f4-b913-3abf9080a8c9";
@@@ -89,11 -95,75 +96,76 @@@
private static String fsdResourceId;
+ public static void getAvailableAppInterfaceComputeResources(String appInterfaceId) {
+ try {
+ Map<String, String> availableAppInterfaceComputeResources = airavataClient.getAvailableAppInterfaceComputeResources(appInterfaceId);
+ for (String key : availableAppInterfaceComputeResources.keySet()){
+ System.out.println("id : " + key);
+ System.out.println("name : " + availableAppInterfaceComputeResources.get(key));
+ }
+ } catch (AiravataSystemException e) {
+ e.printStackTrace();
+ } catch (InvalidRequestException e) {
+ e.printStackTrace();
+ } catch (AiravataClientException e) {
+ e.printStackTrace();
+ } catch (TException e) {
+ e.printStackTrace();
+ }
+
+ }
+
+
+ public static void createGateway(){
+ try {
+ Gateway gateway = new Gateway();
+ gateway.setGatewayId("testGatewayId2");
+ gateway.setGatewayName("testGateway2");
+ gatewayId = airavataClient.addGateway(gateway);
+ System.out.println(gatewayId);
+ } catch (AiravataSystemException e) {
+ e.printStackTrace();
+ } catch (InvalidRequestException e) {
+ e.printStackTrace();
+ } catch (AiravataClientException e) {
+ e.printStackTrace();
+ } catch (TException e) {
+ e.printStackTrace();
+ }
+
+ }
+
+ public static void getGateway(String gatewayId){
+ try {
+ Gateway gateway = airavataClient.getGateway(gatewayId);
+ gateway.setDomain("testDomain");
+ airavataClient.updateGateway(gatewayId, gateway);
+ List<Gateway> allGateways = airavataClient.getAllGateways();
+ System.out.println(allGateways.size());
+ if (airavataClient.isGatewayExist(gatewayId)){
+ Gateway gateway1 = airavataClient.getGateway(gatewayId);
+ System.out.println(gateway1.getGatewayName());
+ }
+ boolean b = airavataClient.deleteGateway("testGatewayId2");
+ System.out.println(b);
+ } catch (AiravataSystemException e) {
+ e.printStackTrace();
+ } catch (InvalidRequestException e) {
+ e.printStackTrace();
+ } catch (AiravataClientException e) {
+ e.printStackTrace();
+ } catch (TException e) {
+ e.printStackTrace();
+ }
+
+ }
+
+
public static void createAndLaunchExp() throws TException {
// final String expId = createEchoExperimentForFSD(airavataClient);
+ List<String> experimentIds = new ArrayList<String>();
try {
- for (int i = 0; i < 100; i++) {
+ for (int i = 0; i < 1; i++) {
// final String expId = createExperimentForSSHHost(airavata);
// final String expId = createEchoExperimentForFSD(airavataClient);
// final String expId = createMPIExperimentForFSD(airavataClient);
http://git-wip-us.apache.org/repos/asf/airavata/blob/0db33d2e/modules/configuration/server/src/main/resources/airavata-server.properties
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/airavata/blob/0db33d2e/modules/credential-store/credential-store-webapp/src/main/resources/airavata-server.properties
----------------------------------------------------------------------
diff --cc modules/credential-store/credential-store-webapp/src/main/resources/airavata-server.properties
index 0000000,badf28d..fe4de5d
mode 000000,100644..100644
--- a/modules/credential-store/credential-store-webapp/src/main/resources/airavata-server.properties
+++ b/modules/credential-store/credential-store-webapp/src/main/resources/airavata-server.properties
@@@ -1,0 -1,234 +1,241 @@@
+ #
+ #
+ # 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.
+ #
+
+ ###########################################################################
+ #
+ # This properties file provides configuration for all Airavata Services:
+ # API Server, Registry, Workflow Interpreter, GFac, Orchestrator
+ #
+ ###########################################################################
+
+ ###########################################################################
+ # API Server Registry Configuration
+ ###########################################################################
+
+ #for derby [AiravataJPARegistry]
+ registry.jdbc.driver=org.apache.derby.jdbc.ClientDriver
+ registry.jdbc.url=jdbc:derby://localhost:1527/experiment_catalog;create=true;user=airavata;password=airavata
+ # MySql database configuration
+ #registry.jdbc.driver=com.mysql.jdbc.Driver
+ #registry.jdbc.url=jdbc:mysql://localhost:3306/persistent_data
+ registry.jdbc.user=airavata
+ registry.jdbc.password=airavata
+ start.derby.server.mode=true
+ validationQuery=SELECT 1 from CONFIGURATION
+ jpa.cache.size=5000
+ #jpa.connection.properties=MaxActive=10,MaxIdle=5,MinIdle=2,MaxWait=60000,testWhileIdle=true,testOnBorrow=true
+
+ # Properties for default user mode
+ default.registry.user=admin
+ default.registry.password=admin
+ default.registry.password.hash.method=SHA
+ default.registry.gateway=default
+
+ #ip=127.0.0.1
+
+ ###########################################################################
+ # Application Catalog DB Configuration
+ ###########################################################################
+ #for derby [AiravataJPARegistry]
+ appcatalog.jdbc.driver=org.apache.derby.jdbc.ClientDriver
+ appcatalog.jdbc.url=jdbc:derby://localhost:1527/app_catalog;create=true;user=airavata;password=airavata
+ # MySql database configuration
+ #appcatalog.jdbc.driver=com.mysql.jdbc.Driver
+ #appcatalog.jdbc.url=jdbc:mysql://localhost:3306/app_catalog
+ appcatalog.jdbc.user=airavata
+ appcatalog.jdbc.password=airavata
+ appcatalog.validationQuery=SELECT 1 from CONFIGURATION
+
+ ###########################################################################
+ # Server module Configuration
+ ###########################################################################
+
+ servers=apiserver,orchestrator,gfac,workflowserver
+ #shutdown.trategy=NONE
+ shutdown.trategy=SELF_TERMINATE
+
+
+ apiserver.server.host=localhost
+ apiserver.server.port=8930
+ apiserver.server.min.threads=50
+ workflow.server.host=localhost
+ workflow.server.port=8931
+ orchestrator.server.host=localhost
+ orchestrator.server.port=8940
+ gfac.server.host=localhost
+ gfac.server.port=8950
+ orchestrator.server.min.threads=50
+
+ ###########################################################################
+ # Credential Store module Configuration
+ ###########################################################################
+ credential.store.keystore.url=/Users/lahirugunathilake/Downloads/airavata_sym.jks
+ credential.store.keystore.alias=airavata
+ credential.store.keystore.password=airavata
+ credential.store.jdbc.url=jdbc:derby://localhost:1527/experiment_catalog;create=true;user=airavata;password=airavata
+ credential.store.jdbc.user=airavata
+ credential.store.jdbc.password=airavata
+ credential.store.jdbc.driver=org.apache.derby.jdbc.ClientDriver
+
+ notifier.enabled=false
+ #period in milliseconds
+ notifier.duration=5000
+
+ email.server=smtp.googlemail.com
+ email.server.port=465
+ email.user=airavata
+ email.password=xxx
+ email.ssl=true
+ email.from=airavata@apache.org
+
+ ###########################################################################
+ # Airavata GFac MyProxy GSI credentials to access Grid Resources.
+ ###########################################################################
+ #
+ # Security Configuration used by Airavata Generic Factory Service
+ # to interact with Computational Resources.
+ #
+ gfac=org.apache.airavata.gfac.server.GfacServer
+ myproxy.server=myproxy.teragrid.org
+ myproxy.username=ogce
+ myproxy.password=
+ myproxy.life=3600
+ # XSEDE Trusted certificates can be downloaded from https://software.xsede.org/security/xsede-certs.tar.gz
+ trusted.cert.location=/Users/lahirugunathilake/Downloads/certificates
+ # SSH PKI key pair or ssh password can be used SSH based authentication is used.
+ # if user specify both password authentication gets the higher preference
+
+ ################# ---------- For ssh key pair authentication ------------------- ################
+ #public.ssh.key=/path to public key for ssh
+ #ssh.username=username for ssh connection
+ #private.ssh.key=/path to private key file for ssh
+ #ssh.keypass=passphrase for the private key
+
+
+ ################# ---------- For ssh key pair authentication ------------------- ################
+ #ssh.username=username for ssh connection
+ #ssh.password=Password for ssh connection
+
+
+
+ ###########################################################################
+ # Airavata Workflow Interpreter Configurations
+ ###########################################################################
+
+ #runInThread=true
+ #provenance=true
+ #provenanceWriterThreadPoolSize=20
+ #gfac.embedded=true
+ #workflowserver=org.apache.airavata.api.server.WorkflowServer
++enactment.thread.pool.size=10
++
++#to define custom workflow parser user following property
++#workflow.parser=org.apache.airavata.simple.workflow.engine.parser.AiravataWorkflowParser
+
+
+ ###########################################################################
+ # API Server module Configuration
+ ###########################################################################
+ apiserver=org.apache.airavata.api.server.AiravataAPIServer
+
+ ###########################################################################
+ # Workflow Server module Configuration
+ ###########################################################################
+
+ workflowserver=org.apache.airavata.api.server.WorkflowServer
+
+ ###########################################################################
+ # Advance configuration to change service implementations
+ ###########################################################################
+ # If false, disables two phase commit when submitting jobs
+ TwoPhase=true
+ #
+ # Class which implemented HostScheduler interface. It will determine the which host to submit the request
+ #
+ host.scheduler=org.apache.airavata.gfac.core.scheduler.impl.SimpleHostScheduler
+
+ ###########################################################################
+ # Monitoring module Configuration
+ ###########################################################################
+
+ #This will be the primary monitoring tool which runs in airavata, in future there will be multiple monitoring
+ #mechanisms and one would be able to start a monitor
+ monitors=org.apache.airavata.gfac.monitor.impl.pull.qstat.QstatMonitor,org.apache.airavata.gfac.monitor.impl.LocalJobMonitor
+
+
+ ###########################################################################
+ # AMQP Notification Configuration
+ ###########################################################################
+
+
+ amqp.notification.enable=1
+
+ amqp.broker.host=localhost
+ amqp.broker.port=5672
+ amqp.broker.username=guest
+ amqp.broker.password=guest
+
+ amqp.sender=org.apache.airavata.wsmg.client.amqp.rabbitmq.AMQPSenderImpl
+ amqp.topic.sender=org.apache.airavata.wsmg.client.amqp.rabbitmq.AMQPTopicSenderImpl
+ amqp.broadcast.sender=org.apache.airavata.wsmg.client.amqp.rabbitmq.AMQPBroadcastSenderImpl
+
+ #,org.apache.airavata.gfac.monitor.impl.push.amqp.AMQPMonitor
+ #This is the amqp related configuration and this lists down the Rabbitmq host, this is an xsede specific configuration
+ amqp.hosts=info1.dyn.teragrid.org,info2.dyn.teragrid.org
+ proxy.file.path=/Users/lahirugunathilake/Downloads/x509up_u503876
+ connection.name=xsede
+ #publisher
+ activity.listeners=org.apache.airavata.gfac.core.monitor.AiravataJobStatusUpdator,org.apache.airavata.gfac.core.monitor.AiravataTaskStatusUpdator,org.apache.airavata.gfac.core.monitor.AiravataWorkflowNodeStatusUpdator,org.apache.airavata.api.server.listener.AiravataExperimentStatusUpdator,org.apache.airavata.gfac.core.monitor.GfacInternalStatusUpdator,org.apache.airavata.workflow.engine.util.ProxyMonitorPublisher
+ publish.rabbitmq=false
-activity.publisher=org.apache.airavata.messaging.core.impl.RabbitMQPublisher
++status.publisher=org.apache.airavata.messaging.core.impl.RabbitMQStatusPublisher
++task.launch.publisher=org.apache.airavata.messaging.core.impl.RabbitMQTaskLaunchPublisher
+ rabbitmq.broker.url=amqp://localhost:5672
-rabbitmq.exchange.name=airavata_rabbitmq_exchange
++rabbitmq.status.exchange.name=airavata_rabbitmq_exchange
++rabbitmq.task.launch.exchange.name=airavata_task_launch_rabbitmq_exchange
+
+ ###########################################################################
+ # Orchestrator module Configuration
+ ###########################################################################
+
+ #job.submitter=org.apache.airavata.orchestrator.core.impl.GFACEmbeddedJobSubmitter
-job.submitter=org.apache.airavata.orchestrator.core.impl.GFACServiceJobSubmitter
++#job.submitter=org.apache.airavata.orchestrator.core.impl.GFACPassiveJobSubmitter
++job.submitter=org.apache.airavata.orchestrator.core.impl.GFACRPCJobSubmitter
+ job.validators=org.apache.airavata.orchestrator.core.validator.impl.SimpleAppDataValidator,org.apache.airavata.orchestrator.core.validator.impl.ExperimentStatusValidator
+ submitter.interval=10000
+ threadpool.size=10
+ start.submitter=true
+ embedded.mode=true
+ enable.validation=true
+ orchestrator=org.apache.airavata.orchestrator.server.OrchestratorServer
+
+ ###########################################################################
+ # Zookeeper Server Configuration
+ ###########################################################################
+
+ embedded.zk=true
+ zookeeper.server.host=localhost
+ zookeeper.server.port=2181
+ airavata-server=/api-server
+ orchestrator-server=/orchestrator-server
+ gfac-server=/gfac-server
+ gfac-experiments=/gfac-experiments
+ gfac-server-name=gfac-node0
+ orchestrator-server-name=orch-node0
+ airavata-server-name=api-node0
http://git-wip-us.apache.org/repos/asf/airavata/blob/0db33d2e/modules/gfac/airavata-gfac-service/src/main/java/org/apache/airavata/gfac/server/GfacServerHandler.java
----------------------------------------------------------------------
diff --cc modules/gfac/airavata-gfac-service/src/main/java/org/apache/airavata/gfac/server/GfacServerHandler.java
index 1c0f095,4973a41..2fc3f16
--- a/modules/gfac/airavata-gfac-service/src/main/java/org/apache/airavata/gfac/server/GfacServerHandler.java
+++ b/modules/gfac/airavata-gfac-service/src/main/java/org/apache/airavata/gfac/server/GfacServerHandler.java
@@@ -27,7 -27,10 +27,11 @@@ import org.apache.aiaravata.application
import org.apache.airavata.common.exception.ApplicationSettingsException;
import org.apache.airavata.common.logger.AiravataLogger;
import org.apache.airavata.common.logger.AiravataLoggerFactory;
- import org.apache.airavata.common.utils.*;
+ import org.apache.airavata.common.utils.AiravataZKUtils;
+ import org.apache.airavata.common.utils.Constants;
+ import org.apache.airavata.common.utils.MonitorPublisher;
+ import org.apache.airavata.common.utils.ServerSettings;
++import org.apache.airavata.common.utils.ThriftUtils;
import org.apache.airavata.gfac.core.cpi.BetterGfacImpl;
import org.apache.airavata.gfac.core.cpi.GFac;
import org.apache.airavata.gfac.core.utils.GFacThreadPoolExecutor;
http://git-wip-us.apache.org/repos/asf/airavata/blob/0db33d2e/modules/gfac/gfac-core/src/main/java/org/apache/airavata/gfac/core/cpi/BetterGfacImpl.java
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/airavata/blob/0db33d2e/modules/gfac/gfac-core/src/main/java/org/apache/airavata/gfac/core/utils/GFacUtils.java
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/airavata/blob/0db33d2e/modules/messaging/client/src/main/java/org/apache/airavata/messaging/client/RabbitMQListener.java
----------------------------------------------------------------------
diff --cc modules/messaging/client/src/main/java/org/apache/airavata/messaging/client/RabbitMQListener.java
index c1bdc3d,53d08d3..3f876ae
--- a/modules/messaging/client/src/main/java/org/apache/airavata/messaging/client/RabbitMQListener.java
+++ b/modules/messaging/client/src/main/java/org/apache/airavata/messaging/client/RabbitMQListener.java
@@@ -55,12 -56,16 +56,16 @@@ public class RabbitMQListener
private static boolean allMessages = false;
public static void main(String[] args) {
+ File file = new File("/tmp/latency_client");
parseArguments(args);
try {
+ FileOutputStream fos = new FileOutputStream(file, false);
+ final BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(fos));
AiravataUtils.setExecutionAsServer();
String brokerUrl = ServerSettings.getSetting(RABBITMQ_BROKER_URL);
+ System.out.println("broker url " + brokerUrl);
final String exchangeName = ServerSettings.getSetting(RABBITMQ_EXCHANGE_NAME);
- RabbitMQConsumer consumer = new RabbitMQConsumer(brokerUrl, exchangeName);
+ RabbitMQStatusConsumer consumer = new RabbitMQStatusConsumer(brokerUrl, exchangeName);
consumer.listen(new MessageHandler() {
@Override
public Map<String, Object> getProperties() {
http://git-wip-us.apache.org/repos/asf/airavata/blob/0db33d2e/modules/messaging/core/src/main/java/org/apache/airavata/messaging/core/impl/RabbitMQStatusPublisher.java
----------------------------------------------------------------------
diff --cc modules/messaging/core/src/main/java/org/apache/airavata/messaging/core/impl/RabbitMQStatusPublisher.java
index a149037,0000000..2ba7a19
mode 100644,000000..100644
--- a/modules/messaging/core/src/main/java/org/apache/airavata/messaging/core/impl/RabbitMQStatusPublisher.java
+++ b/modules/messaging/core/src/main/java/org/apache/airavata/messaging/core/impl/RabbitMQStatusPublisher.java
@@@ -1,107 -1,0 +1,106 @@@
+/*
+ *
+ * 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.messaging.core.impl;
+
+import org.apache.airavata.common.exception.AiravataException;
+import org.apache.airavata.common.exception.ApplicationSettingsException;
+import org.apache.airavata.common.utils.ServerSettings;
+import org.apache.airavata.common.utils.ThriftUtils;
+import org.apache.airavata.messaging.core.MessageContext;
+import org.apache.airavata.messaging.core.MessagingConstants;
+import org.apache.airavata.messaging.core.Publisher;
- import org.apache.airavata.messaging.core.stats.StatCounter;
+import org.apache.airavata.model.messaging.event.*;
+import org.apache.thrift.TException;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class RabbitMQStatusPublisher implements Publisher {
+
+ private static Logger log = LoggerFactory.getLogger(RabbitMQStatusPublisher.class);
+
+ private RabbitMQProducer rabbitMQProducer;
+
- StatCounter statCounter = StatCounter.getInstance();
++// StatCounter statCounter = StatCounter.getInstance();
+
+ public RabbitMQStatusPublisher() throws Exception {
+ String brokerUrl;
+ String exchangeName;
+ try {
+ brokerUrl = ServerSettings.getSetting(MessagingConstants.RABBITMQ_BROKER_URL);
+ exchangeName = ServerSettings.getSetting(MessagingConstants.RABBITMQ_STATUS_EXCHANGE_NAME);
+ } catch (ApplicationSettingsException e) {
+ String message = "Failed to get read the required properties from airavata to initialize rabbitmq";
+ log.error(message, e);
+ throw new AiravataException(message, e);
+ }
+ rabbitMQProducer = new RabbitMQProducer(brokerUrl, exchangeName);
+ rabbitMQProducer.open();
+ }
+
+ public void publish(MessageContext msgCtx) throws AiravataException {
+ try {
+ log.info("Publishing status to rabbitmq...");
+ byte[] body = ThriftUtils.serializeThriftObject(msgCtx.getEvent());
+ Message message = new Message();
+ message.setEvent(body);
+ message.setMessageId(msgCtx.getMessageId());
+ message.setMessageType(msgCtx.getType());
+ message.setUpdatedTime(msgCtx.getUpdatedTime().getTime());
+ String gatewayId = msgCtx.getGatewayId();
+ String routingKey = null;
+ if (msgCtx.getType() == MessageType.EXPERIMENT) {
+ ExperimentStatusChangeEvent event = (ExperimentStatusChangeEvent) msgCtx.getEvent();
+ routingKey = gatewayId + "." + event.getExperimentId();
+ } else if (msgCtx.getType() == MessageType.TASK) {
+ TaskStatusChangeEvent event = (TaskStatusChangeEvent) msgCtx.getEvent();
+ routingKey = gatewayId + "." + event.getTaskIdentity().getExperimentId() + "." +
+ event.getTaskIdentity().getWorkflowNodeId() + "." + event.getTaskIdentity().getTaskId();
+ } else if (msgCtx.getType() == MessageType.TASKOUTPUT) {
+ TaskOutputChangeEvent event = (TaskOutputChangeEvent) msgCtx.getEvent();
+ routingKey = gatewayId + "." + event.getTaskIdentity().getExperimentId() + "." +
+ event.getTaskIdentity().getWorkflowNodeId() + "." + event.getTaskIdentity().getTaskId();
+ } else if (msgCtx.getType() == MessageType.WORKFLOWNODE) {
+ WorkflowNodeStatusChangeEvent event = (WorkflowNodeStatusChangeEvent) msgCtx.getEvent();
+ WorkflowIdentifier workflowNodeIdentity = event.getWorkflowNodeIdentity();
+ routingKey = gatewayId + "." + workflowNodeIdentity.getExperimentId() + "." + workflowNodeIdentity.getWorkflowNodeId();
+ } else if (msgCtx.getType() == MessageType.JOB) {
+ JobStatusChangeEvent event = (JobStatusChangeEvent) msgCtx.getEvent();
+ JobIdentifier identity = event.getJobIdentity();
+ routingKey = gatewayId + "." + identity.getExperimentId() + "." +
+ identity.getWorkflowNodeId() + "." +
+ identity.getTaskId() + "." +
+ identity.getJobId();
+ }
+ byte[] messageBody = ThriftUtils.serializeThriftObject(message);
+ rabbitMQProducer.send(messageBody, routingKey);
- statCounter.add();
++// statCounter.add(message);
+ } catch (TException e) {
+ String msg = "Error while deserializing the object";
+ log.error(msg, e);
+ throw new AiravataException(msg, e);
+ } catch (Exception e) {
+ String msg = "Error while sending to rabbitmq";
+ log.error(msg, e);
+ throw new AiravataException(msg, e);
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/airavata/blob/0db33d2e/modules/messaging/core/src/main/java/org/apache/airavata/messaging/core/stats/CountWriterTask.java
----------------------------------------------------------------------
diff --cc modules/messaging/core/src/main/java/org/apache/airavata/messaging/core/stats/CountWriterTask.java
index 0000000,286e059..5261512
mode 000000,100644..100644
--- a/modules/messaging/core/src/main/java/org/apache/airavata/messaging/core/stats/CountWriterTask.java
+++ b/modules/messaging/core/src/main/java/org/apache/airavata/messaging/core/stats/CountWriterTask.java
@@@ -1,0 -1,36 +1,35 @@@
+ package org.apache.airavata.messaging.core.stats;
+
+ import java.io.*;
+ import java.util.List;
+ import java.util.TimerTask;
+
+ public class CountWriterTask extends TimerTask {
+
+ private File file;
+ private FileOutputStream fos;
+ private BufferedWriter bw;
+
+ public void setFile(File file) {
+ this.file = file;
+
+ }
+
+ @Override
+ public void run() {
+ try {
- System.out.println("########### calling Write Task ############");
+ StatCounter statCounter = StatCounter.getInstance();
+ List<Long> contPer10S = statCounter.getMessageContPer10S();
+ fos = new FileOutputStream(file, false);
+ bw = new BufferedWriter(new OutputStreamWriter(fos));
+ for (int i = 0; i < contPer10S.size(); i++) {
+ bw.write(String.valueOf(i+1) + " :" + String.valueOf(contPer10S.get(i)));
+ bw.newLine();
+ }
+ bw.flush();
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+
+ }
+ }
http://git-wip-us.apache.org/repos/asf/airavata/blob/0db33d2e/modules/xbaya-gui/src/main/java/org/apache/airavata/xbaya/ui/experiment/WorkflowInterpreterLaunchWindow.java
----------------------------------------------------------------------
diff --cc modules/xbaya-gui/src/main/java/org/apache/airavata/xbaya/ui/experiment/WorkflowInterpreterLaunchWindow.java
index 3425a4f,7e7a8ba..2eece65
--- a/modules/xbaya-gui/src/main/java/org/apache/airavata/xbaya/ui/experiment/WorkflowInterpreterLaunchWindow.java
+++ b/modules/xbaya-gui/src/main/java/org/apache/airavata/xbaya/ui/experiment/WorkflowInterpreterLaunchWindow.java
@@@ -360,24 -355,9 +362,25 @@@ public class WorkflowInterpreterLaunchW
}else {
throw new RuntimeException("Resource scheduling failed, target computer resource host name is not defined");
}
+/*
+// code snippet for load test.
+ for (int i = 0; i < 20; i++) {
+ experiment.setName(instanceName + "_" + i);
+
+ experiment.setExperimentID(airavataClient.createExperiment(experiment));
+
+ try {
+ this.engine.getMonitor().subscribe(experiment.getExperimentID());
+ this.engine.getMonitor().fireStartMonitoring(workflow.getName());
+ } catch (MonitorException e) {
+ logger.error("Error while subscribing with experiment Id : " + experiment.getExperimentID(), e);
+ }
+ airavataClient.launchExperiment(experiment.getExperimentID(), "testToken");
+
+ }*/
- experiment.setExperimentID(airavataClient.createExperiment(experiment));
+ //FIXME:: use gatewayId from UI
+ experiment.setExperimentID(airavataClient.createExperiment("default", experiment));
try {
this.engine.getMonitor().subscribe(experiment.getExperimentID());
http://git-wip-us.apache.org/repos/asf/airavata/blob/0db33d2e/pom.xml
----------------------------------------------------------------------
[17/50] [abbrv] airavata git commit: Fixed AIRAVATA-1590
Posted by sh...@apache.org.
Fixed AIRAVATA-1590
Project: http://git-wip-us.apache.org/repos/asf/airavata/repo
Commit: http://git-wip-us.apache.org/repos/asf/airavata/commit/41ea9467
Tree: http://git-wip-us.apache.org/repos/asf/airavata/tree/41ea9467
Diff: http://git-wip-us.apache.org/repos/asf/airavata/diff/41ea9467
Branch: refs/heads/master
Commit: 41ea9467865dc60cecb2304a97ba9acd85ba2aac
Parents: 6bfb956
Author: shamrath <sh...@gmail.com>
Authored: Tue Feb 24 09:56:42 2015 -0500
Committer: shamrath <sh...@gmail.com>
Committed: Tue Feb 24 09:56:42 2015 -0500
----------------------------------------------------------------------
.../airavata-orchestrator-service/pom.xml | 5 ++++
.../server/OrchestratorServerHandler.java | 26 +++++++++++---------
2 files changed, 20 insertions(+), 11 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/airavata/blob/41ea9467/modules/orchestrator/airavata-orchestrator-service/pom.xml
----------------------------------------------------------------------
diff --git a/modules/orchestrator/airavata-orchestrator-service/pom.xml b/modules/orchestrator/airavata-orchestrator-service/pom.xml
index 72ecc0e..3817852 100644
--- a/modules/orchestrator/airavata-orchestrator-service/pom.xml
+++ b/modules/orchestrator/airavata-orchestrator-service/pom.xml
@@ -52,6 +52,11 @@
</dependency>
<dependency>
<groupId>org.apache.airavata</groupId>
+ <artifactId>simple-workflow</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.airavata</groupId>
<artifactId>app-catalog-data</artifactId>
<version>${project.version}</version>
</dependency>
http://git-wip-us.apache.org/repos/asf/airavata/blob/41ea9467/modules/orchestrator/airavata-orchestrator-service/src/main/java/org/apache/airavata/orchestrator/server/OrchestratorServerHandler.java
----------------------------------------------------------------------
diff --git a/modules/orchestrator/airavata-orchestrator-service/src/main/java/org/apache/airavata/orchestrator/server/OrchestratorServerHandler.java b/modules/orchestrator/airavata-orchestrator-service/src/main/java/org/apache/airavata/orchestrator/server/OrchestratorServerHandler.java
index e88945d..c93e213 100644
--- a/modules/orchestrator/airavata-orchestrator-service/src/main/java/org/apache/airavata/orchestrator/server/OrchestratorServerHandler.java
+++ b/modules/orchestrator/airavata-orchestrator-service/src/main/java/org/apache/airavata/orchestrator/server/OrchestratorServerHandler.java
@@ -34,7 +34,6 @@ import org.apache.airavata.common.utils.AiravataUtils;
import org.apache.airavata.common.utils.AiravataZKUtils;
import org.apache.airavata.common.utils.Constants;
import org.apache.airavata.common.utils.ServerSettings;
-import org.apache.airavata.credential.store.credential.impl.certificate.CertificateCredential;
import org.apache.airavata.credential.store.store.CredentialReader;
import org.apache.airavata.gfac.core.scheduler.HostScheduler;
import org.apache.airavata.gfac.core.utils.GFacUtils;
@@ -51,10 +50,8 @@ import org.apache.airavata.model.util.ExecutionType;
import org.apache.airavata.model.workspace.experiment.*;
import org.apache.airavata.orchestrator.core.exception.OrchestratorException;
import org.apache.airavata.orchestrator.cpi.OrchestratorService;
-import org.apache.airavata.orchestrator.cpi.OrchestratorService.Client;
import org.apache.airavata.orchestrator.cpi.impl.SimpleOrchestratorImpl;
import org.apache.airavata.orchestrator.cpi.orchestrator_cpi_serviceConstants;
-import org.apache.airavata.orchestrator.util.OrchestratorRecoveryHandler;
import org.apache.airavata.orchestrator.util.OrchestratorServerThreadPoolExecutor;
import org.apache.airavata.persistance.registry.jpa.impl.RegistryFactory;
import org.apache.airavata.registry.cpi.Registry;
@@ -62,10 +59,8 @@ import org.apache.airavata.registry.cpi.RegistryException;
import org.apache.airavata.registry.cpi.RegistryModelType;
import org.apache.airavata.registry.cpi.utils.Constants.FieldConstants.TaskDetailConstants;
import org.apache.airavata.registry.cpi.utils.Constants.FieldConstants.WorkflowNodeConstants;
-import org.apache.airavata.workflow.engine.WorkflowEngine;
-import org.apache.airavata.workflow.engine.WorkflowEngineException;
-import org.apache.airavata.workflow.engine.WorkflowEngineFactory;
import org.apache.airavata.orchestrator.util.DataModelUtils;
+import org.apache.airavata.simple.workflow.engine.SimpleWorkflowInterpreter;
import org.apache.thrift.TException;
import org.apache.zookeeper.*;
import org.apache.zookeeper.data.Stat;
@@ -632,11 +627,20 @@ public class OrchestratorServerHandler implements OrchestratorService.Iface,
return true;
}
private void launchWorkflowExperiment(String experimentId, String airavataCredStoreToken) throws TException {
- try {
- WorkflowEngine workflowEngine = WorkflowEngineFactory.getWorkflowEngine();
- workflowEngine.launchExperiment(experimentId, airavataCredStoreToken);
- } catch (WorkflowEngineException e) {
- log.errorId(experimentId, "Error while launching experiment.", e);
+// try {
+// WorkflowEngine workflowEngine = WorkflowEngineFactory.getWorkflowEngine();
+// workflowEngine.launchExperiment(experimentId, airavataCredStoreToken);
+// } catch (WorkflowEngineException e) {
+// log.errorId(experimentId, "Error while launching experiment.", e);
+// }
+
+ try {
+ SimpleWorkflowInterpreter simpleWorkflowInterpreter = new SimpleWorkflowInterpreter(experimentId, airavataCredStoreToken);
+ Thread thread = new Thread(simpleWorkflowInterpreter);
+ thread.start();
+// simpleWorkflowInterpreter.run();
+ } catch (RegistryException e) {
+ log.error("Error while launching workflow", e);
}
}
[36/50] [abbrv] airavata git commit: removed synchronized block in
Orchestrator Server handler
Posted by sh...@apache.org.
removed synchronized block in Orchestrator Server handler
Project: http://git-wip-us.apache.org/repos/asf/airavata/repo
Commit: http://git-wip-us.apache.org/repos/asf/airavata/commit/be6aecda
Tree: http://git-wip-us.apache.org/repos/asf/airavata/tree/be6aecda
Diff: http://git-wip-us.apache.org/repos/asf/airavata/diff/be6aecda
Branch: refs/heads/master
Commit: be6aecdaf1bdec6c0bbea9beb5d006a1f1d175db
Parents: 2b45c6d
Author: shamrath <sh...@gmail.com>
Authored: Fri Mar 20 12:58:08 2015 -0400
Committer: shamrath <sh...@gmail.com>
Committed: Fri Mar 20 12:58:08 2015 -0400
----------------------------------------------------------------------
.../server/OrchestratorServerHandler.java | 25 +++++++++-----------
1 file changed, 11 insertions(+), 14 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/airavata/blob/be6aecda/modules/orchestrator/airavata-orchestrator-service/src/main/java/org/apache/airavata/orchestrator/server/OrchestratorServerHandler.java
----------------------------------------------------------------------
diff --git a/modules/orchestrator/airavata-orchestrator-service/src/main/java/org/apache/airavata/orchestrator/server/OrchestratorServerHandler.java b/modules/orchestrator/airavata-orchestrator-service/src/main/java/org/apache/airavata/orchestrator/server/OrchestratorServerHandler.java
index 4209bb9..a0e25d7 100644
--- a/modules/orchestrator/airavata-orchestrator-service/src/main/java/org/apache/airavata/orchestrator/server/OrchestratorServerHandler.java
+++ b/modules/orchestrator/airavata-orchestrator-service/src/main/java/org/apache/airavata/orchestrator/server/OrchestratorServerHandler.java
@@ -249,24 +249,21 @@ public class OrchestratorServerHandler implements OrchestratorService.Iface,
throw new AiravataException("Couldn't identify the gateway Id using the credential token");
}
ExecutionType executionType = DataModelUtils.getExecutionType(gatewayId, experiment);
- synchronized (this) {
- if (executionType==ExecutionType.SINGLE_APP) {
- //its an single application execution experiment
- log.debugId(experimentId, "Launching single application experiment {}.", experimentId);
- OrchestratorServerThreadPoolExecutor.getFixedThreadPool().execute(new SingleAppExperimentRunner(experimentId, token));
- }
- else if (executionType == ExecutionType.WORKFLOW){
- //its a workflow execution experiment
- log.debugId(experimentId, "Launching workflow experiment {}.", experimentId);
- launchWorkflowExperiment(experimentId, token);
+ if (executionType == ExecutionType.SINGLE_APP) {
+ //its an single application execution experiment
+ log.debugId(experimentId, "Launching single application experiment {}.", experimentId);
+ OrchestratorServerThreadPoolExecutor.getFixedThreadPool().execute(new SingleAppExperimentRunner(experimentId, token));
+ } else if (executionType == ExecutionType.WORKFLOW) {
+ //its a workflow execution experiment
+ log.debugId(experimentId, "Launching workflow experiment {}.", experimentId);
+ launchWorkflowExperiment(experimentId, token);
} else {
log.errorId(experimentId, "Couldn't identify experiment type, experiment {} is neither single application nor workflow.", experimentId);
throw new TException("Experiment '" + experimentId + "' launch failed. Unable to figureout execution type for application " + experiment.getApplicationId());
}
- }
- }catch(Exception e){
- throw new TException("Experiment '" + experimentId + "' launch failed. Unable to figureout execution type for application " + experiment.getApplicationId());
- }
+ } catch (Exception e) {
+ throw new TException("Experiment '" + experimentId + "' launch failed. Unable to figureout execution type for application " + experiment.getApplicationId());
+ }
return true;
}
[30/50] [abbrv] airavata git commit: Fixed new workflow interpreter
termination issue.
Posted by sh...@apache.org.
Fixed new workflow interpreter termination issue.
Project: http://git-wip-us.apache.org/repos/asf/airavata/repo
Commit: http://git-wip-us.apache.org/repos/asf/airavata/commit/97004593
Tree: http://git-wip-us.apache.org/repos/asf/airavata/tree/97004593
Diff: http://git-wip-us.apache.org/repos/asf/airavata/diff/97004593
Branch: refs/heads/master
Commit: 970045939852e228bd7059eac8c7df30acad0c0e
Parents: ad8e482
Author: shamrath <sh...@gmail.com>
Authored: Fri Mar 13 14:40:32 2015 -0400
Committer: shamrath <sh...@gmail.com>
Committed: Fri Mar 13 14:40:32 2015 -0400
----------------------------------------------------------------------
.../workflow/engine/SimpleWorkflowInterpreter.java | 15 ++++++++++++++-
.../workflow/engine/dag/port/InputPortIml.java | 3 ++-
2 files changed, 16 insertions(+), 2 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/airavata/blob/97004593/modules/simple-workflow/src/main/java/org/apache/airavata/simple/workflow/engine/SimpleWorkflowInterpreter.java
----------------------------------------------------------------------
diff --git a/modules/simple-workflow/src/main/java/org/apache/airavata/simple/workflow/engine/SimpleWorkflowInterpreter.java b/modules/simple-workflow/src/main/java/org/apache/airavata/simple/workflow/engine/SimpleWorkflowInterpreter.java
index ee7ff6b..5504f84 100644
--- a/modules/simple-workflow/src/main/java/org/apache/airavata/simple/workflow/engine/SimpleWorkflowInterpreter.java
+++ b/modules/simple-workflow/src/main/java/org/apache/airavata/simple/workflow/engine/SimpleWorkflowInterpreter.java
@@ -115,6 +115,16 @@ class SimpleWorkflowInterpreter{
log.debug("Parsed the workflow and got the workflow input nodes");
// process workflow input nodes
processWorkflowInputNodes(getWorkflowInputNodes());
+ if (readyList.isEmpty()) {
+ StringBuilder sb = new StringBuilder();
+ for (WorkflowInputNode workflowInputNode : workflowInputNodes) {
+ sb.append(", ");
+ sb.append(workflowInputNode.getInputObject().getName());
+ sb.append("=");
+ sb.append(workflowInputNode.getInputObject().getValue());
+ }
+ throw new AiravataException("No workflow application node in ready state to run with experiment inputs" + sb.toString());
+ }
processReadyList();
}
@@ -125,6 +135,9 @@ class SimpleWorkflowInterpreter{
* @throws AiravataException
*/
void processReadyList() throws RegistryException, AiravataException {
+ if (readyList.isEmpty() && processingQueue.isEmpty() && !waitingList.isEmpty()) {
+ throw new AiravataException("No workflow application node in ready state to run");
+ }
for (WorkflowNode readyNode : readyList.values()) {
if (readyNode instanceof WorkflowOutputNode) {
WorkflowOutputNode wfOutputNode = (WorkflowOutputNode) readyNode;
@@ -272,7 +285,7 @@ class SimpleWorkflowInterpreter{
}
boolean isAllDone() {
- return !continueWorkflow || (waitingList.isEmpty() && readyList.isEmpty());
+ return !continueWorkflow || (waitingList.isEmpty() && readyList.isEmpty() && processingQueue.isEmpty());
}
private void setExperiment(String experimentId) throws RegistryException {
http://git-wip-us.apache.org/repos/asf/airavata/blob/97004593/modules/simple-workflow/src/main/java/org/apache/airavata/simple/workflow/engine/dag/port/InputPortIml.java
----------------------------------------------------------------------
diff --git a/modules/simple-workflow/src/main/java/org/apache/airavata/simple/workflow/engine/dag/port/InputPortIml.java b/modules/simple-workflow/src/main/java/org/apache/airavata/simple/workflow/engine/dag/port/InputPortIml.java
index c78dc86..076f5b6 100644
--- a/modules/simple-workflow/src/main/java/org/apache/airavata/simple/workflow/engine/dag/port/InputPortIml.java
+++ b/modules/simple-workflow/src/main/java/org/apache/airavata/simple/workflow/engine/dag/port/InputPortIml.java
@@ -69,7 +69,8 @@ public class InputPortIml implements InPort {
@Override
public boolean isReady() {
- return getInputObject() != null && inputDataObjectType.getValue() != null && !inputDataObjectType.getValue().equals("");
+ return getInputObject() != null && (!inputDataObjectType.isIsRequired() ||
+ (inputDataObjectType.getValue() != null && !inputDataObjectType.getValue().equals("")));
}
@Override
[07/50] [abbrv] airavata git commit: Make test machine independent
Posted by sh...@apache.org.
Make test machine independent
Project: http://git-wip-us.apache.org/repos/asf/airavata/repo
Commit: http://git-wip-us.apache.org/repos/asf/airavata/commit/0bc98a30
Tree: http://git-wip-us.apache.org/repos/asf/airavata/tree/0bc98a30
Diff: http://git-wip-us.apache.org/repos/asf/airavata/diff/0bc98a30
Branch: refs/heads/master
Commit: 0bc98a30df024ac3ff3f194c3079503779d32fc5
Parents: 308291f
Author: shamrath <sh...@gmail.com>
Authored: Wed Feb 18 08:36:07 2015 -0500
Committer: shamrath <sh...@gmail.com>
Committed: Wed Feb 18 08:36:07 2015 -0500
----------------------------------------------------------------------
modules/simple-workflow/pom.xml | 8 +++++++
.../workflow/engine/WorkflowFactoryImpl.java | 7 +++++-
.../engine/parser/AiravataDefaultParser.java | 23 +++++++++++---------
.../parser/AiravataDefaultParserTest.java | 18 +++++++--------
4 files changed, 35 insertions(+), 21 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/airavata/blob/0bc98a30/modules/simple-workflow/pom.xml
----------------------------------------------------------------------
diff --git a/modules/simple-workflow/pom.xml b/modules/simple-workflow/pom.xml
index 623934d..6b36335 100644
--- a/modules/simple-workflow/pom.xml
+++ b/modules/simple-workflow/pom.xml
@@ -52,6 +52,14 @@
<artifactId>guava</artifactId>
<version>18.0</version>
</dependency>
+
+ <!--test-->
+ <dependency>
+ <groupId>junit</groupId>
+ <artifactId>junit</artifactId>
+ <version>4.11</version>
+ <scope>test</scope>
+ </dependency>
</dependencies>
</project>
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/airavata/blob/0bc98a30/modules/simple-workflow/src/main/java/org/apache/ariavata/simple/workflow/engine/WorkflowFactoryImpl.java
----------------------------------------------------------------------
diff --git a/modules/simple-workflow/src/main/java/org/apache/ariavata/simple/workflow/engine/WorkflowFactoryImpl.java b/modules/simple-workflow/src/main/java/org/apache/ariavata/simple/workflow/engine/WorkflowFactoryImpl.java
index f489a12..a6173ac 100644
--- a/modules/simple-workflow/src/main/java/org/apache/ariavata/simple/workflow/engine/WorkflowFactoryImpl.java
+++ b/modules/simple-workflow/src/main/java/org/apache/ariavata/simple/workflow/engine/WorkflowFactoryImpl.java
@@ -21,6 +21,7 @@
package org.apache.ariavata.simple.workflow.engine;
+import org.apache.airavata.registry.cpi.RegistryException;
import org.apache.ariavata.simple.workflow.engine.parser.AiravataDefaultParser;
/**
@@ -51,7 +52,11 @@ public class WorkflowFactoryImpl implements WorkflowFactory {
@Override
public WorkflowParser getWorkflowParser(String experimentId, String credentialToken) {
if (workflowParser == null) {
- workflowParser = new AiravataDefaultParser(experimentId, credentialToken);
+ try {
+ workflowParser = new AiravataDefaultParser(experimentId, credentialToken);
+ } catch (RegistryException e) {
+ // TODO : handle this scenario
+ }
}
return workflowParser;
}
http://git-wip-us.apache.org/repos/asf/airavata/blob/0bc98a30/modules/simple-workflow/src/main/java/org/apache/ariavata/simple/workflow/engine/parser/AiravataDefaultParser.java
----------------------------------------------------------------------
diff --git a/modules/simple-workflow/src/main/java/org/apache/ariavata/simple/workflow/engine/parser/AiravataDefaultParser.java b/modules/simple-workflow/src/main/java/org/apache/ariavata/simple/workflow/engine/parser/AiravataDefaultParser.java
index b86e58b..39e422a 100644
--- a/modules/simple-workflow/src/main/java/org/apache/ariavata/simple/workflow/engine/parser/AiravataDefaultParser.java
+++ b/modules/simple-workflow/src/main/java/org/apache/ariavata/simple/workflow/engine/parser/AiravataDefaultParser.java
@@ -66,28 +66,28 @@ import java.util.Map;
public class AiravataDefaultParser implements WorkflowParser {
- private String experimentId;
private String credentialToken ;
private Workflow workflow;
- // TODO : remove this setter method
- public void setExperiment(Experiment experiment) {
- this.experiment = experiment;
- }
private Experiment experiment;
private Map<String, WorkflowNode> wfNodes = new HashMap<String, WorkflowNode>();
- public AiravataDefaultParser(String experimentId, String credentialToken) {
- this.experimentId = experimentId;
+ public AiravataDefaultParser(String experimentId, String credentialToken) throws RegistryException {
+ this.experiment = getExperiment(experimentId);
+ this.credentialToken = credentialToken;
+ }
+
+ public AiravataDefaultParser(Experiment experiment, String credentialToken) {
this.credentialToken = credentialToken;
+ this.experiment = experiment;
}
@Override
public List<WorkflowInputNode> parse() throws RegistryException, AppCatalogException,
ComponentException, GraphException {
- return parseWorkflow(getWorkflowFromExperiment());
+ return parseWorkflow(getWorkflowFromExperiment(experiment));
}
public List<WorkflowInputNode> parseWorkflow(Workflow workflow) {
@@ -216,9 +216,12 @@ public class AiravataDefaultParser implements WorkflowParser {
return outputDataObjectType;
}
- private Workflow getWorkflowFromExperiment() throws RegistryException, AppCatalogException, GraphException, ComponentException {
+ private Experiment getExperiment(String experimentId) throws RegistryException {
Registry registry = RegistryFactory.getDefaultRegistry();
- experiment = (Experiment)registry.get(RegistryModelType.EXPERIMENT, experimentId);
+ return (Experiment)registry.get(RegistryModelType.EXPERIMENT, experimentId);
+ }
+
+ private Workflow getWorkflowFromExperiment(Experiment experiment) throws RegistryException, AppCatalogException, GraphException, ComponentException {
WorkflowCatalog workflowCatalog = getWorkflowCatalog();
return new Workflow(workflowCatalog.getWorkflow(experiment.getApplicationId()).getGraph());
}
http://git-wip-us.apache.org/repos/asf/airavata/blob/0bc98a30/modules/simple-workflow/src/test/java/org/apache/ariavata/simple/workflow/engine/parser/AiravataDefaultParserTest.java
----------------------------------------------------------------------
diff --git a/modules/simple-workflow/src/test/java/org/apache/ariavata/simple/workflow/engine/parser/AiravataDefaultParserTest.java b/modules/simple-workflow/src/test/java/org/apache/ariavata/simple/workflow/engine/parser/AiravataDefaultParserTest.java
index 15b2864..432a1c6 100644
--- a/modules/simple-workflow/src/test/java/org/apache/ariavata/simple/workflow/engine/parser/AiravataDefaultParserTest.java
+++ b/modules/simple-workflow/src/test/java/org/apache/ariavata/simple/workflow/engine/parser/AiravataDefaultParserTest.java
@@ -21,7 +21,6 @@
package org.apache.ariavata.simple.workflow.engine.parser;
-import junit.framework.Assert;
import org.apache.airavata.model.appcatalog.appinterface.DataType;
import org.apache.airavata.model.appcatalog.appinterface.InputDataObjectType;
import org.apache.airavata.model.workspace.experiment.Experiment;
@@ -31,12 +30,12 @@ import org.apache.ariavata.simple.workflow.engine.dag.nodes.WorkflowInputNode;
import org.apache.ariavata.simple.workflow.engine.dag.nodes.WorkflowNode;
import org.apache.ariavata.simple.workflow.engine.dag.nodes.WorkflowOutputNode;
import org.junit.After;
+import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
import java.io.BufferedReader;
-import java.io.File;
-import java.io.FileReader;
+import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
@@ -55,18 +54,16 @@ public class AiravataDefaultParserTest {
@Test
public void testWorkflowParse() throws Exception {
-// File jsonWfFile = new File("modules/simple-workflow/src/test/resources/ComplexMathWorkflow.awf");
- File jsonWfFile = new File("/Users/shameera/work/source/git_airavata/modules/simple-workflow/src/test/resources/ComplexMathWorkflow.awf");
- BufferedReader br = new BufferedReader(new FileReader(jsonWfFile));
+ Assert.assertNotNull("Test file (ComplexMathWorkflow.awf) is missing", getClass().getResource("/ComplexMathWorkflow.awf"));
+ InputStreamReader isr = new InputStreamReader(this.getClass().getResourceAsStream("/ComplexMathWorkflow.awf"));
+ BufferedReader br = new BufferedReader(isr);
StringBuffer sb = new StringBuffer();
String nextLine = br.readLine();
while (nextLine != null) {
sb.append(nextLine);
nextLine = br.readLine();
}
-
Workflow workflow = new Workflow(sb.toString());
- AiravataDefaultParser parser = new AiravataDefaultParser("testExperimentId", "testCredentialId");
Experiment experiment = new Experiment();
InputDataObjectType x = new InputDataObjectType();
x.setValue("6");
@@ -88,7 +85,8 @@ public class AiravataDefaultParserTest {
inputs.add(y);
inputs.add(z);
experiment.setExperimentInputs(inputs);
- parser.setExperiment(experiment);
+ // create parser
+ AiravataDefaultParser parser = new AiravataDefaultParser(experiment, "testCredentialId");
List<WorkflowInputNode> workflowInputNodes = parser.parseWorkflow(workflow);
Assert.assertNotNull(workflowInputNodes);
Assert.assertEquals(3, workflowInputNodes.size());
@@ -111,7 +109,7 @@ public class AiravataDefaultParserTest {
Assert.assertEquals(1, node.getOutputPorts().size());
Assert.assertEquals(1, node.getOutputPorts().get(0).getOutEdges().size());
Assert.assertNotNull(node.getOutputPorts().get(0).getOutEdges().get(0));
- }else if (wfNode instanceof WorkflowOutputNode) {
+ } else if (wfNode instanceof WorkflowOutputNode) {
WorkflowOutputNode workflowOutputNode = (WorkflowOutputNode) wfNode;
Assert.assertNotNull(workflowOutputNode.getInPort());
}
[16/50] [abbrv] airavata git commit: Renamed the wrong package name
Posted by sh...@apache.org.
Renamed the wrong package name
Project: http://git-wip-us.apache.org/repos/asf/airavata/repo
Commit: http://git-wip-us.apache.org/repos/asf/airavata/commit/6bfb9563
Tree: http://git-wip-us.apache.org/repos/asf/airavata/tree/6bfb9563
Diff: http://git-wip-us.apache.org/repos/asf/airavata/diff/6bfb9563
Branch: refs/heads/master
Commit: 6bfb9563a049b943c2ab2287f468a38f8eaf9b78
Parents: 8835097
Author: shamrath <sh...@gmail.com>
Authored: Mon Feb 23 16:51:21 2015 -0500
Committer: shamrath <sh...@gmail.com>
Committed: Mon Feb 23 16:51:21 2015 -0500
----------------------------------------------------------------------
.../simple/workflow/engine/ProcessPack.java | 62 +++
.../engine/SimpleWorkflowInterpreter.java | 470 +++++++++++++++++++
.../simple/workflow/engine/WorkflowFactory.java | 31 ++
.../workflow/engine/WorkflowFactoryImpl.java | 66 +++
.../simple/workflow/engine/WorkflowParser.java | 32 ++
.../simple/workflow/engine/WorkflowUtil.java | 63 +++
.../workflow/engine/dag/edge/DirectedEdge.java | 52 ++
.../simple/workflow/engine/dag/edge/Edge.java | 43 ++
.../engine/dag/nodes/ApplicationNode.java | 41 ++
.../engine/dag/nodes/ApplicationNodeImpl.java | 113 +++++
.../workflow/engine/dag/nodes/NodeState.java | 34 ++
.../workflow/engine/dag/nodes/NodeType.java | 28 ++
.../engine/dag/nodes/WorkflowInputNode.java | 37 ++
.../engine/dag/nodes/WorkflowInputNodeImpl.java | 96 ++++
.../workflow/engine/dag/nodes/WorkflowNode.java | 38 ++
.../engine/dag/nodes/WorkflowOutputNode.java | 37 ++
.../dag/nodes/WorkflowOutputNodeImpl.java | 97 ++++
.../simple/workflow/engine/dag/port/InPort.java | 41 ++
.../workflow/engine/dag/port/InputPortIml.java | 90 ++++
.../workflow/engine/dag/port/OutPort.java | 39 ++
.../workflow/engine/dag/port/OutPortImpl.java | 83 ++++
.../simple/workflow/engine/dag/port/Port.java | 36 ++
.../engine/parser/AiravataDefaultParser.java | 293 ++++++++++++
.../workflow/engine/parser/PortContainer.java | 53 +++
.../simple/workflow/engine/ProcessPack.java | 62 ---
.../engine/SimpleWorkflowInterpreter.java | 470 -------------------
.../simple/workflow/engine/WorkflowFactory.java | 31 --
.../workflow/engine/WorkflowFactoryImpl.java | 66 ---
.../simple/workflow/engine/WorkflowParser.java | 32 --
.../simple/workflow/engine/WorkflowUtil.java | 63 ---
.../workflow/engine/dag/edge/DirectedEdge.java | 52 --
.../simple/workflow/engine/dag/edge/Edge.java | 43 --
.../engine/dag/nodes/ApplicationNode.java | 41 --
.../engine/dag/nodes/ApplicationNodeImpl.java | 113 -----
.../workflow/engine/dag/nodes/NodeState.java | 34 --
.../workflow/engine/dag/nodes/NodeType.java | 28 --
.../engine/dag/nodes/WorkflowInputNode.java | 37 --
.../engine/dag/nodes/WorkflowInputNodeImpl.java | 96 ----
.../workflow/engine/dag/nodes/WorkflowNode.java | 38 --
.../engine/dag/nodes/WorkflowOutputNode.java | 37 --
.../dag/nodes/WorkflowOutputNodeImpl.java | 97 ----
.../simple/workflow/engine/dag/port/InPort.java | 41 --
.../workflow/engine/dag/port/InputPortIml.java | 90 ----
.../workflow/engine/dag/port/OutPort.java | 39 --
.../workflow/engine/dag/port/OutPortImpl.java | 83 ----
.../simple/workflow/engine/dag/port/Port.java | 36 --
.../engine/parser/AiravataDefaultParser.java | 293 ------------
.../workflow/engine/parser/PortContainer.java | 53 ---
.../simple/workflow/engine/WorkflowDAGTest.java | 46 ++
.../parser/AiravataDefaultParserTest.java | 119 +++++
.../simple/workflow/engine/WorkflowDAGTest.java | 46 --
.../parser/AiravataDefaultParserTest.java | 119 -----
52 files changed, 2140 insertions(+), 2140 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/airavata/blob/6bfb9563/modules/simple-workflow/src/main/java/org/apache/airavata/simple/workflow/engine/ProcessPack.java
----------------------------------------------------------------------
diff --git a/modules/simple-workflow/src/main/java/org/apache/airavata/simple/workflow/engine/ProcessPack.java b/modules/simple-workflow/src/main/java/org/apache/airavata/simple/workflow/engine/ProcessPack.java
new file mode 100644
index 0000000..b58b947
--- /dev/null
+++ b/modules/simple-workflow/src/main/java/org/apache/airavata/simple/workflow/engine/ProcessPack.java
@@ -0,0 +1,62 @@
+/*
+ *
+ * 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.simple.workflow.engine;
+
+import org.apache.airavata.model.workspace.experiment.TaskDetails;
+import org.apache.airavata.model.workspace.experiment.WorkflowNodeDetails;
+import org.apache.airavata.simple.workflow.engine.dag.nodes.WorkflowNode;
+
+public class ProcessPack {
+ private WorkflowNode workflowNode;
+ private WorkflowNodeDetails wfNodeDetails;
+ private TaskDetails taskDetails;
+
+ public ProcessPack(WorkflowNode workflowNode, WorkflowNodeDetails wfNodeDetails, TaskDetails taskDetails) {
+ this.workflowNode = workflowNode;
+ this.wfNodeDetails = wfNodeDetails;
+ this.taskDetails = taskDetails;
+ }
+
+ public WorkflowNode getWorkflowNode() {
+ return workflowNode;
+ }
+
+ public void setWorkflowNode(WorkflowNode workflowNode) {
+ this.workflowNode = workflowNode;
+ }
+
+ public WorkflowNodeDetails getWfNodeDetails() {
+ return wfNodeDetails;
+ }
+
+ public void setWfNodeDetails(WorkflowNodeDetails wfNodeDetails) {
+ this.wfNodeDetails = wfNodeDetails;
+ }
+
+ public TaskDetails getTaskDetails() {
+ return taskDetails;
+ }
+
+ public void setTaskDetails(TaskDetails taskDetails) {
+ this.taskDetails = taskDetails;
+ }
+}
http://git-wip-us.apache.org/repos/asf/airavata/blob/6bfb9563/modules/simple-workflow/src/main/java/org/apache/airavata/simple/workflow/engine/SimpleWorkflowInterpreter.java
----------------------------------------------------------------------
diff --git a/modules/simple-workflow/src/main/java/org/apache/airavata/simple/workflow/engine/SimpleWorkflowInterpreter.java b/modules/simple-workflow/src/main/java/org/apache/airavata/simple/workflow/engine/SimpleWorkflowInterpreter.java
new file mode 100644
index 0000000..6dcb8bd
--- /dev/null
+++ b/modules/simple-workflow/src/main/java/org/apache/airavata/simple/workflow/engine/SimpleWorkflowInterpreter.java
@@ -0,0 +1,470 @@
+/*
+ *
+ * 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.simple.workflow.engine;
+
+import com.google.common.eventbus.EventBus;
+import com.google.common.eventbus.Subscribe;
+import org.apache.airavata.model.appcatalog.appinterface.InputDataObjectType;
+import org.apache.airavata.model.appcatalog.appinterface.OutputDataObjectType;
+import org.apache.airavata.model.messaging.event.TaskIdentifier;
+import org.apache.airavata.model.messaging.event.TaskOutputChangeEvent;
+import org.apache.airavata.model.messaging.event.TaskStatusChangeEvent;
+import org.apache.airavata.model.util.ExperimentModelUtil;
+import org.apache.airavata.model.workspace.experiment.ExecutionUnit;
+import org.apache.airavata.model.workspace.experiment.Experiment;
+import org.apache.airavata.model.workspace.experiment.TaskDetails;
+import org.apache.airavata.model.workspace.experiment.TaskState;
+import org.apache.airavata.model.workspace.experiment.WorkflowNodeDetails;
+import org.apache.airavata.model.workspace.experiment.WorkflowNodeState;
+import org.apache.airavata.model.workspace.experiment.WorkflowNodeStatus;
+import org.apache.airavata.persistance.registry.jpa.impl.RegistryFactory;
+import org.apache.airavata.registry.cpi.ChildDataType;
+import org.apache.airavata.registry.cpi.Registry;
+import org.apache.airavata.registry.cpi.RegistryException;
+import org.apache.airavata.registry.cpi.RegistryModelType;
+import org.apache.airavata.simple.workflow.engine.dag.edge.Edge;
+import org.apache.airavata.simple.workflow.engine.dag.nodes.ApplicationNode;
+import org.apache.airavata.simple.workflow.engine.dag.nodes.NodeState;
+import org.apache.airavata.simple.workflow.engine.dag.nodes.WorkflowInputNode;
+import org.apache.airavata.simple.workflow.engine.dag.nodes.WorkflowOutputNode;
+import org.apache.airavata.simple.workflow.engine.parser.AiravataDefaultParser;
+import org.apache.airavata.simple.workflow.engine.dag.nodes.WorkflowNode;
+import org.apache.airavata.simple.workflow.engine.dag.port.InPort;
+import org.apache.airavata.simple.workflow.engine.dag.port.OutPort;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+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 java.util.concurrent.ConcurrentHashMap;
+
+public class SimpleWorkflowInterpreter implements Runnable{
+
+ private static final Logger log = LoggerFactory.getLogger(SimpleWorkflowInterpreter.class);
+
+ private List<WorkflowInputNode> workflowInputNodes;
+
+ private Experiment experiment;
+
+ private String credentialToken;
+
+ private Map<String, WorkflowNode> readList = new ConcurrentHashMap<String, WorkflowNode>();
+ private Map<String, WorkflowNode> waitingList = new ConcurrentHashMap<String, WorkflowNode>();
+ private Map<String, ProcessPack> processingQueue = new ConcurrentHashMap<String, ProcessPack>();
+ private Map<String, ProcessPack> completeList = new HashMap<String, ProcessPack>();
+ private Registry registry;
+ private EventBus eventBus = new EventBus();
+ private List<WorkflowOutputNode> completeWorkflowOutputs = new ArrayList<WorkflowOutputNode>();
+
+ public SimpleWorkflowInterpreter(String experimentId, String credentialToken) throws RegistryException {
+ setExperiment(experimentId);
+ this.credentialToken = credentialToken;
+ }
+
+ public SimpleWorkflowInterpreter(Experiment experiment, String credentialStoreToken) {
+ // read the workflow file and build the topology to a DAG. Then execute that dag
+ // get workflowInputNode list and start processing
+ // next() will return ready task and block the thread if no task in ready state.
+ this.experiment = experiment;
+ this.credentialToken = credentialStoreToken;
+ }
+
+
+ public void launchWorkflow() throws Exception {
+ // process workflow input nodes
+// WorkflowFactoryImpl wfFactory = WorkflowFactoryImpl.getInstance();
+// WorkflowParser workflowParser = wfFactory.getWorkflowParser(experiment.getExperimentID(), credentialToken);
+ WorkflowParser workflowParser = new AiravataDefaultParser(experiment, credentialToken);
+ log.debug("Initialized workflow parser");
+ setWorkflowInputNodes(workflowParser.parse());
+ log.debug("Parsed the workflow and got the workflow input nodes");
+ processWorkflowInputNodes(getWorkflowInputNodes());
+ }
+
+ // try to remove synchronization tag
+ private synchronized void processReadyList() {
+ for (WorkflowNode readyNode : readList.values()) {
+ try {
+ if (readyNode instanceof WorkflowOutputNode) {
+ WorkflowOutputNode wfOutputNode = (WorkflowOutputNode) readyNode;
+ wfOutputNode.getOutputObject().setValue(wfOutputNode.getInPort().getInputObject().getValue());
+ addToCompleteOutputNodeList(wfOutputNode);
+ continue;
+ }
+ WorkflowNodeDetails workflowNodeDetails = createWorkflowNodeDetails(readyNode);
+ TaskDetails process = getProcess(workflowNodeDetails);
+ ProcessPack processPack = new ProcessPack(readyNode, workflowNodeDetails, process);
+ addToProcessingQueue(processPack);
+// publishToProcessQueue(process);
+ publishToProcessQueue(processPack);
+ } catch (RegistryException e) {
+ // FIXME : handle this exception
+ }
+ }
+ }
+
+
+ private void publishToProcessQueue(TaskDetails process) {
+ Thread thread = new Thread(new TempPublisher(process, eventBus));
+ thread.start();
+ //TODO: publish to process queue.
+ }
+
+ // TODO : remove this test method
+ private void publishToProcessQueue(ProcessPack process) {
+ WorkflowNode workflowNode = process.getWorkflowNode();
+ if (workflowNode instanceof ApplicationNode) {
+ ApplicationNode applicationNode = (ApplicationNode) workflowNode;
+ List<InPort> inputPorts = applicationNode.getInputPorts();
+ if (applicationNode.getName().equals("Add")) {
+ applicationNode.getOutputPorts().get(0).getOutputObject().setValue(String.valueOf(
+ Integer.parseInt(inputPorts.get(0).getInputObject().getValue()) + Integer.parseInt(inputPorts.get(1).getInputObject().getValue())));
+ } else if (applicationNode.getName().equals("Multiply")) {
+ applicationNode.getOutputPorts().get(0).getOutputObject().setValue(String.valueOf(
+ Integer.parseInt(inputPorts.get(0).getInputObject().getValue()) * Integer.parseInt(inputPorts.get(1).getInputObject().getValue())));
+ } else if (applicationNode.getName().equals("Subtract")) {
+ applicationNode.getOutputPorts().get(0).getOutputObject().setValue(String.valueOf(
+ Integer.parseInt(inputPorts.get(0).getInputObject().getValue()) - Integer.parseInt(inputPorts.get(1).getInputObject().getValue())));
+ } else {
+ throw new RuntimeException("Invalid Application name");
+ }
+
+ for (Edge edge : applicationNode.getOutputPorts().get(0).getOutEdges()) {
+ WorkflowUtil.copyValues(applicationNode.getOutputPorts().get(0).getOutputObject(), edge.getToPort().getInputObject());
+ if (edge.getToPort().getNode().isReady()) {
+ addToReadyQueue(edge.getToPort().getNode());
+ } else {
+ addToWaitingQueue(edge.getToPort().getNode());
+ }
+ }
+ } else if (workflowNode instanceof WorkflowOutputNode) {
+ WorkflowOutputNode wfOutputNode = (WorkflowOutputNode) workflowNode;
+ throw new RuntimeException("Workflow output node in processing queue");
+ }
+
+ processingQueue.remove(process.getTaskDetails().getTaskID());
+ }
+
+ private TaskDetails getProcess(WorkflowNodeDetails wfNodeDetails) throws RegistryException {
+ // create workflow taskDetails from workflowNodeDetails
+ TaskDetails taskDetails = ExperimentModelUtil.cloneTaskFromWorkflowNodeDetails(getExperiment(), wfNodeDetails);
+ taskDetails.setTaskID(getRegistry()
+ .add(ChildDataType.TASK_DETAIL, taskDetails, wfNodeDetails.getNodeInstanceId()).toString());
+ return taskDetails;
+ }
+
+ private WorkflowNodeDetails createWorkflowNodeDetails(WorkflowNode readyNode) throws RegistryException {
+ WorkflowNodeDetails wfNodeDetails = ExperimentModelUtil.createWorkflowNode(readyNode.getId(), null);
+ ExecutionUnit executionUnit = ExecutionUnit.APPLICATION;
+ String executionData = null;
+ if (readyNode instanceof ApplicationNode) {
+ executionUnit = ExecutionUnit.APPLICATION;
+ executionData = ((ApplicationNode) readyNode).getApplicationId();
+ } else if (readyNode instanceof WorkflowInputNode) {
+ executionUnit = ExecutionUnit.INPUT;
+ } else if (readyNode instanceof WorkflowOutputNode) {
+ executionUnit = ExecutionUnit.OUTPUT;
+ }
+ wfNodeDetails.setExecutionUnit(executionUnit);
+ wfNodeDetails.setExecutionUnitData(executionData);
+ setupNodeDetailsInput(readyNode, wfNodeDetails);
+ wfNodeDetails.setNodeInstanceId((String) getRegistry()
+ .add(ChildDataType.WORKFLOW_NODE_DETAIL, wfNodeDetails, getExperiment().getExperimentID()));
+// nodeInstanceList.put(node, wfNodeDetails);
+ return wfNodeDetails;
+ }
+
+ private void setupNodeDetailsInput(WorkflowNode readyNode, WorkflowNodeDetails wfNodeDetails) {
+ if (readyNode instanceof ApplicationNode) {
+ ApplicationNode applicationNode = (ApplicationNode) readyNode;
+ if (applicationNode.isReady()) {
+ for (InPort inPort : applicationNode.getInputPorts()) {
+ wfNodeDetails.addToNodeInputs(inPort.getInputObject());
+ }
+ } else {
+ // TODO: handle this scenario properly.
+ }
+ } else {
+ // TODO: do we support for other type of workflow nodes ?
+ }
+ }
+
+
+ private void processWorkflowInputNodes(List<WorkflowInputNode> wfInputNodes) {
+ Set<WorkflowNode> tempNodeSet = new HashSet<WorkflowNode>();
+ for (WorkflowInputNode wfInputNode : wfInputNodes) {
+ if (wfInputNode.isReady()) {
+ log.debug("Workflow node : " + wfInputNode.getId() + " is ready to execute");
+ for (Edge edge : wfInputNode.getOutPort().getOutEdges()) {
+ edge.getToPort().getInputObject().setValue(wfInputNode.getInputObject().getValue());
+ if (edge.getToPort().getNode().isReady()) {
+ addToReadyQueue(edge.getToPort().getNode());
+ log.debug("Added workflow node : " + edge.getToPort().getNode().getId() + " to the readyQueue");
+ } else {
+ addToWaitingQueue(edge.getToPort().getNode());
+ log.debug("Added workflow node " + edge.getToPort().getNode().getId() + " to the waitingQueue");
+
+ }
+ }
+ }
+ }
+ }
+
+
+ public List<WorkflowInputNode> getWorkflowInputNodes() throws Exception {
+ return workflowInputNodes;
+ }
+
+ public void setWorkflowInputNodes(List<WorkflowInputNode> workflowInputNodes) {
+ this.workflowInputNodes = workflowInputNodes;
+ }
+
+
+ private List<WorkflowInputNode> parseWorkflowDescription(){
+ return null;
+ }
+
+
+ private Registry getRegistry() throws RegistryException {
+ if (registry==null){
+ registry = RegistryFactory.getDefaultRegistry();
+ }
+ return registry;
+ }
+
+ public Experiment getExperiment() {
+ return experiment;
+ }
+
+ private void updateWorkflowNodeStatus(WorkflowNodeDetails wfNodeDetails, WorkflowNodeState state) throws RegistryException{
+ WorkflowNodeStatus status = ExperimentModelUtil.createWorkflowNodeStatus(state);
+ wfNodeDetails.setWorkflowNodeStatus(status);
+ getRegistry().update(RegistryModelType.WORKFLOW_NODE_STATUS, status, wfNodeDetails.getNodeInstanceId());
+ }
+
+ @Subscribe
+ public void taskOutputChanged(TaskOutputChangeEvent taskOutputEvent){
+ String taskId = taskOutputEvent.getTaskIdentity().getTaskId();
+ log.debug("Task Output changed event received for workflow node : " +
+ taskOutputEvent.getTaskIdentity().getWorkflowNodeId() + ", task : " + taskId);
+ ProcessPack processPack = processingQueue.get(taskId);
+ Set<WorkflowNode> tempWfNodeSet = new HashSet<WorkflowNode>();
+ if (processPack != null) {
+ WorkflowNode workflowNode = processPack.getWorkflowNode();
+ if (workflowNode instanceof ApplicationNode) {
+ ApplicationNode applicationNode = (ApplicationNode) workflowNode;
+ // Workflow node can have one to many output ports and each output port can have one to many links
+ for (OutPort outPort : applicationNode.getOutputPorts()) {
+ for (OutputDataObjectType outputDataObjectType : taskOutputEvent.getOutput()) {
+ if (outPort.getOutputObject().getName().equals(outputDataObjectType.getName())) {
+ outPort.getOutputObject().setValue(outputDataObjectType.getValue());
+ break;
+ }
+ }
+ for (Edge edge : outPort.getOutEdges()) {
+ WorkflowUtil.copyValues(outPort.getOutputObject(), edge.getToPort().getInputObject());
+ if (edge.getToPort().getNode().isReady()) {
+ addToReadyQueue(edge.getToPort().getNode());
+ }
+ }
+ }
+ }
+ processingQueue.remove(taskId);
+ log.debug("removed task from processing queue : " + taskId);
+ }
+
+ }
+
+ @Subscribe
+ public void taskStatusChanged(TaskStatusChangeEvent taskStatus){
+ String taskId = taskStatus.getTaskIdentity().getTaskId();
+ ProcessPack processPack = processingQueue.get(taskId);
+ if (processPack != null) {
+ WorkflowNodeState wfNodeState = WorkflowNodeState.UNKNOWN;
+ switch (taskStatus.getState()) {
+ case WAITING:
+ break;
+ case STARTED:
+ break;
+ case PRE_PROCESSING:
+ processPack.getWorkflowNode().setState(NodeState.PRE_PROCESSING);
+ break;
+ case INPUT_DATA_STAGING:
+ processPack.getWorkflowNode().setState(NodeState.PRE_PROCESSING);
+ break;
+ case EXECUTING:
+ processPack.getWorkflowNode().setState(NodeState.EXECUTING);
+ break;
+ case OUTPUT_DATA_STAGING:
+ processPack.getWorkflowNode().setState(NodeState.POST_PROCESSING);
+ break;
+ case POST_PROCESSING:
+ processPack.getWorkflowNode().setState(NodeState.POST_PROCESSING);
+ break;
+ case COMPLETED:
+ processPack.getWorkflowNode().setState(NodeState.EXECUTED);
+ break;
+ case FAILED:
+ processPack.getWorkflowNode().setState(NodeState.FAILED);
+ break;
+ case UNKNOWN:
+ break;
+ case CONFIGURING_WORKSPACE:
+ break;
+ case CANCELED:
+ case CANCELING:
+ processPack.getWorkflowNode().setState(NodeState.FAILED);
+ break;
+ default:
+ break;
+ }
+ if (wfNodeState != WorkflowNodeState.UNKNOWN) {
+ try {
+ updateWorkflowNodeStatus(processPack.getWfNodeDetails(), wfNodeState);
+ } catch (RegistryException e) {
+ // TODO: handle this.
+ }
+ }
+ }
+
+ }
+
+ /**
+ * Remove the workflow node from waiting queue and add it to the ready queue.
+ * @param workflowNode - Workflow Node
+ */
+ private synchronized void addToReadyQueue(WorkflowNode workflowNode) {
+ waitingList.remove(workflowNode.getId());
+ readList.put(workflowNode.getId(), workflowNode);
+ }
+
+ private void addToWaitingQueue(WorkflowNode workflowNode) {
+ waitingList.put(workflowNode.getId(), workflowNode);
+ }
+
+ /**
+ * First remove the node from ready list and then add the WfNodeContainer to the process queue.
+ * Note that underline data structure of the process queue is a Map.
+ * @param processPack - has both workflow and correspond workflowNodeDetails and TaskDetails
+ */
+ private synchronized void addToProcessingQueue(ProcessPack processPack) {
+ readList.remove(processPack.getWorkflowNode().getId());
+ processingQueue.put(processPack.getTaskDetails().getTaskID(), processPack);
+ }
+
+ private synchronized void addToCompleteQueue(ProcessPack processPack) {
+ processingQueue.remove(processPack.getTaskDetails().getTaskID());
+ completeList.put(processPack.getTaskDetails().getTaskID(), processPack);
+ }
+
+
+ private void addToCompleteOutputNodeList(WorkflowOutputNode wfOutputNode) {
+ completeWorkflowOutputs.add(wfOutputNode);
+ readList.remove(wfOutputNode.getId());
+ }
+
+ @Override
+ public void run() {
+ // TODO: Auto generated method body.
+ try {
+ log.debug("Launching workflow");
+ launchWorkflow();
+ while (!(waitingList.isEmpty() && readList.isEmpty())) {
+ processReadyList();
+ Thread.sleep(1000);
+ }
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ }
+
+ private void setExperiment(String experimentId) throws RegistryException {
+ experiment = (Experiment) getRegistry().get(RegistryModelType.EXPERIMENT, experimentId);
+ log.debug("Retrieve Experiment for experiment id : " + experimentId);
+ }
+
+
+ class TempPublisher implements Runnable {
+ private TaskDetails tempTaskDetails;
+ private EventBus tempEventBus;
+
+ public TempPublisher(TaskDetails tempTaskDetails, EventBus tempEventBus) {
+ this.tempTaskDetails = tempTaskDetails;
+ this.tempEventBus = tempEventBus;
+ }
+
+ @Override
+ public void run() {
+ try {
+ TaskIdentifier identifier = new TaskIdentifier(tempTaskDetails.getTaskID(), null, null, null);
+ TaskStatusChangeEvent statusChangeEvent = new TaskStatusChangeEvent(TaskState.PRE_PROCESSING, identifier);
+ tempEventBus.post(statusChangeEvent);
+ Thread.sleep(1000);
+ statusChangeEvent = new TaskStatusChangeEvent(TaskState.WAITING, identifier);
+ tempEventBus.post(statusChangeEvent);
+ Thread.sleep(1000);
+ statusChangeEvent = new TaskStatusChangeEvent(TaskState.INPUT_DATA_STAGING, identifier);
+ tempEventBus.post(statusChangeEvent);
+ Thread.sleep(1000);
+ statusChangeEvent = new TaskStatusChangeEvent(TaskState.STARTED, identifier);
+ tempEventBus.post(statusChangeEvent);
+ Thread.sleep(1000);
+ statusChangeEvent = new TaskStatusChangeEvent(TaskState.EXECUTING, identifier);
+ tempEventBus.post(statusChangeEvent);
+ Thread.sleep(1000);
+ statusChangeEvent = new TaskStatusChangeEvent(TaskState.POST_PROCESSING, identifier);
+ tempEventBus.post(statusChangeEvent);
+ Thread.sleep(1000);
+ statusChangeEvent = new TaskStatusChangeEvent(TaskState.OUTPUT_DATA_STAGING, identifier);
+ tempEventBus.post(statusChangeEvent);
+ Thread.sleep(1000);
+ statusChangeEvent = new TaskStatusChangeEvent(TaskState.COMPLETED, identifier);
+ tempEventBus.post(statusChangeEvent);
+ Thread.sleep(1000);
+
+ List<InputDataObjectType> applicationInputs = tempTaskDetails.getApplicationInputs();
+ List<OutputDataObjectType> applicationOutputs = tempTaskDetails.getApplicationOutputs();
+ log.info("************** Task output change event fired for application id :" + tempTaskDetails.getApplicationId());
+ if (tempTaskDetails.getApplicationId().equals("Add") || tempTaskDetails.getApplicationId().equals("Add_2")) {
+ applicationOutputs.get(0).setValue((Integer.parseInt(applicationInputs.get(0).getValue()) +
+ Integer.parseInt(applicationInputs.get(1).getValue())) + "");
+ } else if (tempTaskDetails.getApplicationId().equals("Subtract")) {
+ applicationOutputs.get(0).setValue((Integer.parseInt(applicationInputs.get(0).getValue()) -
+ Integer.parseInt(applicationInputs.get(1).getValue())) + "");
+ } else if (tempTaskDetails.getApplicationId().equals("Multiply")) {
+ applicationOutputs.get(0).setValue((Integer.parseInt(applicationInputs.get(0).getValue()) *
+ Integer.parseInt(applicationInputs.get(1).getValue())) + "");
+ }
+ TaskOutputChangeEvent taskOutputChangeEvent = new TaskOutputChangeEvent(applicationOutputs, identifier);
+ eventBus.post(taskOutputChangeEvent);
+
+ } catch (InterruptedException e) {
+ log.error("Thread was interrupted while sleeping");
+ }
+
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/airavata/blob/6bfb9563/modules/simple-workflow/src/main/java/org/apache/airavata/simple/workflow/engine/WorkflowFactory.java
----------------------------------------------------------------------
diff --git a/modules/simple-workflow/src/main/java/org/apache/airavata/simple/workflow/engine/WorkflowFactory.java b/modules/simple-workflow/src/main/java/org/apache/airavata/simple/workflow/engine/WorkflowFactory.java
new file mode 100644
index 0000000..3de90f2
--- /dev/null
+++ b/modules/simple-workflow/src/main/java/org/apache/airavata/simple/workflow/engine/WorkflowFactory.java
@@ -0,0 +1,31 @@
+/*
+ *
+ * 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.simple.workflow.engine;
+
+/**
+ * All classes implement this WorkflowFactory interface, should be abstract or singleton.
+ */
+public interface WorkflowFactory {
+
+ public WorkflowParser getWorkflowParser(String experimentId, String credentialToken);
+
+}
http://git-wip-us.apache.org/repos/asf/airavata/blob/6bfb9563/modules/simple-workflow/src/main/java/org/apache/airavata/simple/workflow/engine/WorkflowFactoryImpl.java
----------------------------------------------------------------------
diff --git a/modules/simple-workflow/src/main/java/org/apache/airavata/simple/workflow/engine/WorkflowFactoryImpl.java b/modules/simple-workflow/src/main/java/org/apache/airavata/simple/workflow/engine/WorkflowFactoryImpl.java
new file mode 100644
index 0000000..116a10d
--- /dev/null
+++ b/modules/simple-workflow/src/main/java/org/apache/airavata/simple/workflow/engine/WorkflowFactoryImpl.java
@@ -0,0 +1,66 @@
+/*
+ *
+ * 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.simple.workflow.engine;
+
+import org.apache.airavata.registry.cpi.RegistryException;
+import org.apache.airavata.simple.workflow.engine.parser.AiravataDefaultParser;
+
+/**
+ * Singleton class, only one instance can exist in runtime.
+ */
+public class WorkflowFactoryImpl implements WorkflowFactory {
+
+ private static WorkflowFactoryImpl workflowFactoryImpl;
+
+ private WorkflowParser workflowParser;
+
+ private static final String synch = "sync";
+
+ private WorkflowFactoryImpl(){
+
+ }
+
+ public static WorkflowFactoryImpl getInstance() {
+ if (workflowFactoryImpl == null) {
+ synchronized (synch) {
+ if (workflowFactoryImpl == null) {
+ workflowFactoryImpl = new WorkflowFactoryImpl();
+ }
+ }
+ }
+ return workflowFactoryImpl;
+ }
+
+
+ @Override
+ public WorkflowParser getWorkflowParser(String experimentId, String credentialToken) {
+ if (workflowParser == null) {
+ try {
+ workflowParser = new AiravataDefaultParser(experimentId, credentialToken);
+ } catch (RegistryException e) {
+ // TODO : handle this scenario
+ }
+ }
+ return workflowParser;
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/airavata/blob/6bfb9563/modules/simple-workflow/src/main/java/org/apache/airavata/simple/workflow/engine/WorkflowParser.java
----------------------------------------------------------------------
diff --git a/modules/simple-workflow/src/main/java/org/apache/airavata/simple/workflow/engine/WorkflowParser.java b/modules/simple-workflow/src/main/java/org/apache/airavata/simple/workflow/engine/WorkflowParser.java
new file mode 100644
index 0000000..6c4d6f2
--- /dev/null
+++ b/modules/simple-workflow/src/main/java/org/apache/airavata/simple/workflow/engine/WorkflowParser.java
@@ -0,0 +1,32 @@
+/*
+ *
+ * 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.simple.workflow.engine;
+
+import org.apache.airavata.simple.workflow.engine.dag.nodes.WorkflowInputNode;
+
+import java.util.List;
+
+public interface WorkflowParser {
+
+ public List<WorkflowInputNode> parse() throws Exception;
+
+}
http://git-wip-us.apache.org/repos/asf/airavata/blob/6bfb9563/modules/simple-workflow/src/main/java/org/apache/airavata/simple/workflow/engine/WorkflowUtil.java
----------------------------------------------------------------------
diff --git a/modules/simple-workflow/src/main/java/org/apache/airavata/simple/workflow/engine/WorkflowUtil.java b/modules/simple-workflow/src/main/java/org/apache/airavata/simple/workflow/engine/WorkflowUtil.java
new file mode 100644
index 0000000..a2b69ae
--- /dev/null
+++ b/modules/simple-workflow/src/main/java/org/apache/airavata/simple/workflow/engine/WorkflowUtil.java
@@ -0,0 +1,63 @@
+/*
+ *
+ * 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.simple.workflow.engine;
+
+import com.google.common.eventbus.EventBus;
+import org.apache.airavata.model.appcatalog.appinterface.InputDataObjectType;
+import org.apache.airavata.model.appcatalog.appinterface.OutputDataObjectType;
+import org.apache.airavata.model.messaging.event.TaskIdentifier;
+import org.apache.airavata.model.messaging.event.TaskStatusChangeEvent;
+import org.apache.airavata.model.workspace.experiment.TaskDetails;
+import org.apache.airavata.model.workspace.experiment.TaskState;
+import org.apache.airavata.persistance.registry.jpa.model.TaskDetail;
+
+public class WorkflowUtil {
+
+ public static InputDataObjectType copyValues(InputDataObjectType fromInputObj, InputDataObjectType toInputObj){
+ if (toInputObj == null) {
+ // TODO : throw an error
+ }
+ toInputObj.setValue(fromInputObj.getValue());
+ if (fromInputObj.getApplicationArgument() != null
+ && !fromInputObj.getApplicationArgument().trim().equals("")) {
+ toInputObj.setApplicationArgument(fromInputObj.getApplicationArgument());
+ }
+ if (toInputObj.getType() == null) {
+ toInputObj.setType(fromInputObj.getType());
+ }
+ return fromInputObj;
+ }
+
+ public static InputDataObjectType copyValues(OutputDataObjectType outputData, InputDataObjectType inputData) {
+ inputData.setValue(outputData.getValue());
+ return inputData;
+ }
+
+
+ public static OutputDataObjectType copyValues(InputDataObjectType inputObject, OutputDataObjectType outputObject) {
+ if (outputObject == null) {
+ outputObject = new OutputDataObjectType();
+ }
+ outputObject.setValue(inputObject.getValue());
+ return outputObject;
+ }
+}
http://git-wip-us.apache.org/repos/asf/airavata/blob/6bfb9563/modules/simple-workflow/src/main/java/org/apache/airavata/simple/workflow/engine/dag/edge/DirectedEdge.java
----------------------------------------------------------------------
diff --git a/modules/simple-workflow/src/main/java/org/apache/airavata/simple/workflow/engine/dag/edge/DirectedEdge.java b/modules/simple-workflow/src/main/java/org/apache/airavata/simple/workflow/engine/dag/edge/DirectedEdge.java
new file mode 100644
index 0000000..3bc380d
--- /dev/null
+++ b/modules/simple-workflow/src/main/java/org/apache/airavata/simple/workflow/engine/dag/edge/DirectedEdge.java
@@ -0,0 +1,52 @@
+/*
+ *
+ * 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.simple.workflow.engine.dag.edge;
+
+import org.apache.airavata.simple.workflow.engine.dag.port.OutPort;
+import org.apache.airavata.simple.workflow.engine.dag.port.InPort;
+
+
+public class DirectedEdge implements Edge {
+
+ private InPort inPort;
+ private OutPort outPort;
+
+ @Override
+ public InPort getToPort() {
+ return inPort;
+ }
+
+ @Override
+ public void setToPort(InPort inPort) {
+ this.inPort = inPort;
+ }
+
+ @Override
+ public OutPort getFromPort() {
+ return outPort;
+ }
+
+ @Override
+ public void setFromPort(OutPort outPort) {
+ this.outPort = outPort;
+ }
+}
http://git-wip-us.apache.org/repos/asf/airavata/blob/6bfb9563/modules/simple-workflow/src/main/java/org/apache/airavata/simple/workflow/engine/dag/edge/Edge.java
----------------------------------------------------------------------
diff --git a/modules/simple-workflow/src/main/java/org/apache/airavata/simple/workflow/engine/dag/edge/Edge.java b/modules/simple-workflow/src/main/java/org/apache/airavata/simple/workflow/engine/dag/edge/Edge.java
new file mode 100644
index 0000000..e8bce2e
--- /dev/null
+++ b/modules/simple-workflow/src/main/java/org/apache/airavata/simple/workflow/engine/dag/edge/Edge.java
@@ -0,0 +1,43 @@
+/*
+ *
+ * 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.simple.workflow.engine.dag.edge;
+
+import org.apache.airavata.simple.workflow.engine.dag.port.InPort;
+import org.apache.airavata.simple.workflow.engine.dag.port.OutPort;
+
+/**
+ * Edge is a link to one node to another, basically edge should have outPort of a workflow node ,
+ * which is starting point and inPort of a workflow node, which is end point of the edge.
+ */
+
+public interface Edge {
+
+ public InPort getToPort();
+
+ public void setToPort(InPort inPort);
+
+ public OutPort getFromPort();
+
+ public void setFromPort(OutPort outPort);
+
+
+}
http://git-wip-us.apache.org/repos/asf/airavata/blob/6bfb9563/modules/simple-workflow/src/main/java/org/apache/airavata/simple/workflow/engine/dag/nodes/ApplicationNode.java
----------------------------------------------------------------------
diff --git a/modules/simple-workflow/src/main/java/org/apache/airavata/simple/workflow/engine/dag/nodes/ApplicationNode.java b/modules/simple-workflow/src/main/java/org/apache/airavata/simple/workflow/engine/dag/nodes/ApplicationNode.java
new file mode 100644
index 0000000..37efded
--- /dev/null
+++ b/modules/simple-workflow/src/main/java/org/apache/airavata/simple/workflow/engine/dag/nodes/ApplicationNode.java
@@ -0,0 +1,41 @@
+/*
+ *
+ * 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.simple.workflow.engine.dag.nodes;
+
+import org.apache.airavata.simple.workflow.engine.dag.port.InPort;
+import org.apache.airavata.simple.workflow.engine.dag.port.OutPort;
+
+import java.util.List;
+
+public interface ApplicationNode extends WorkflowNode {
+
+ public String getApplicationId();
+
+ public void addInPort(InPort inPort);
+
+ public List<InPort> getInputPorts();
+
+ public void addOutPort(OutPort outPort);
+
+ public List<OutPort> getOutputPorts();
+
+}
http://git-wip-us.apache.org/repos/asf/airavata/blob/6bfb9563/modules/simple-workflow/src/main/java/org/apache/airavata/simple/workflow/engine/dag/nodes/ApplicationNodeImpl.java
----------------------------------------------------------------------
diff --git a/modules/simple-workflow/src/main/java/org/apache/airavata/simple/workflow/engine/dag/nodes/ApplicationNodeImpl.java b/modules/simple-workflow/src/main/java/org/apache/airavata/simple/workflow/engine/dag/nodes/ApplicationNodeImpl.java
new file mode 100644
index 0000000..52b0595
--- /dev/null
+++ b/modules/simple-workflow/src/main/java/org/apache/airavata/simple/workflow/engine/dag/nodes/ApplicationNodeImpl.java
@@ -0,0 +1,113 @@
+/*
+ *
+ * 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.simple.workflow.engine.dag.nodes;
+
+import org.apache.airavata.simple.workflow.engine.dag.port.InPort;
+import org.apache.airavata.simple.workflow.engine.dag.port.OutPort;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class ApplicationNodeImpl implements ApplicationNode {
+
+ private final String nodeId;
+ private NodeState myState = NodeState.WAITING;
+ private String applicationId;
+ private List<InPort> inPorts = new ArrayList<InPort>();
+ private List<OutPort> outPorts = new ArrayList<OutPort>();
+ private String applicationName;
+
+// public ApplicationNodeImpl(String nodeId) {
+// this(nodeId, null);
+// }
+//
+// public ApplicationNodeImpl(String nodeId, String applicationId) {
+// this(nodeId, null, applicationId);
+// }
+
+ public ApplicationNodeImpl(String nodeId, String applicationName, String applicationId) {
+ this.nodeId = nodeId;
+ this.applicationName = applicationName;
+ this.applicationId = applicationId;
+ }
+
+ @Override
+ public String getId() {
+ return this.nodeId;
+ }
+
+ @Override
+ public String getName() {
+ return applicationName;
+ }
+
+ @Override
+ public NodeType getType() {
+ return NodeType.APPLICATION;
+ }
+
+ @Override
+ public NodeState getState() {
+ return myState;
+ }
+
+ @Override
+ public void setState(NodeState newState) {
+ // TODO: node state can't be reversed , correct order WAITING --> READY --> EXECUTING --> EXECUTED --> COMPLETE
+ myState = newState;
+ }
+
+ @Override
+ public boolean isReady() {
+ for (InPort inPort : getInputPorts()) {
+ if (!inPort.isReady()) {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ @Override
+ public String getApplicationId() {
+ return this.applicationId;
+ }
+
+ @Override
+ public void addInPort(InPort inPort) {
+ this.inPorts.add(inPort);
+ }
+
+ @Override
+ public List<InPort> getInputPorts() {
+ return this.inPorts;
+ }
+
+ @Override
+ public void addOutPort(OutPort outPort) {
+ this.outPorts.add(outPort);
+ }
+
+ @Override
+ public List<OutPort> getOutputPorts() {
+ return this.outPorts;
+ }
+}
http://git-wip-us.apache.org/repos/asf/airavata/blob/6bfb9563/modules/simple-workflow/src/main/java/org/apache/airavata/simple/workflow/engine/dag/nodes/NodeState.java
----------------------------------------------------------------------
diff --git a/modules/simple-workflow/src/main/java/org/apache/airavata/simple/workflow/engine/dag/nodes/NodeState.java b/modules/simple-workflow/src/main/java/org/apache/airavata/simple/workflow/engine/dag/nodes/NodeState.java
new file mode 100644
index 0000000..333fcb2
--- /dev/null
+++ b/modules/simple-workflow/src/main/java/org/apache/airavata/simple/workflow/engine/dag/nodes/NodeState.java
@@ -0,0 +1,34 @@
+/*
+ *
+ * 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.simple.workflow.engine.dag.nodes;
+
+public enum NodeState {
+ WAITING, // waiting on inputs
+ READY, // all inputs are available and ready to execute
+ QUEUED, //
+ PRE_PROCESSING, //
+ EXECUTING, // task has been submitted , not yet finish
+ EXECUTED, // task executed
+ POST_PROCESSING, //
+ FAILED,
+ COMPLETE // all works done
+}
http://git-wip-us.apache.org/repos/asf/airavata/blob/6bfb9563/modules/simple-workflow/src/main/java/org/apache/airavata/simple/workflow/engine/dag/nodes/NodeType.java
----------------------------------------------------------------------
diff --git a/modules/simple-workflow/src/main/java/org/apache/airavata/simple/workflow/engine/dag/nodes/NodeType.java b/modules/simple-workflow/src/main/java/org/apache/airavata/simple/workflow/engine/dag/nodes/NodeType.java
new file mode 100644
index 0000000..95710fb
--- /dev/null
+++ b/modules/simple-workflow/src/main/java/org/apache/airavata/simple/workflow/engine/dag/nodes/NodeType.java
@@ -0,0 +1,28 @@
+/*
+ *
+ * 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.simple.workflow.engine.dag.nodes;
+
+public enum NodeType {
+ APPLICATION,
+ WORKFLOW_INPUT,
+ WORKFLOW_OUTPUT
+}
http://git-wip-us.apache.org/repos/asf/airavata/blob/6bfb9563/modules/simple-workflow/src/main/java/org/apache/airavata/simple/workflow/engine/dag/nodes/WorkflowInputNode.java
----------------------------------------------------------------------
diff --git a/modules/simple-workflow/src/main/java/org/apache/airavata/simple/workflow/engine/dag/nodes/WorkflowInputNode.java b/modules/simple-workflow/src/main/java/org/apache/airavata/simple/workflow/engine/dag/nodes/WorkflowInputNode.java
new file mode 100644
index 0000000..9ac800a
--- /dev/null
+++ b/modules/simple-workflow/src/main/java/org/apache/airavata/simple/workflow/engine/dag/nodes/WorkflowInputNode.java
@@ -0,0 +1,37 @@
+/*
+ *
+ * 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.simple.workflow.engine.dag.nodes;
+
+import org.apache.airavata.model.appcatalog.appinterface.InputDataObjectType;
+import org.apache.airavata.simple.workflow.engine.dag.port.OutPort;
+
+public interface WorkflowInputNode extends WorkflowNode {
+
+ public InputDataObjectType getInputObject();
+
+ public void setInputObject(InputDataObjectType inputObject);
+
+ public OutPort getOutPort();
+
+ public void setOutPort(OutPort outPort);
+
+}
http://git-wip-us.apache.org/repos/asf/airavata/blob/6bfb9563/modules/simple-workflow/src/main/java/org/apache/airavata/simple/workflow/engine/dag/nodes/WorkflowInputNodeImpl.java
----------------------------------------------------------------------
diff --git a/modules/simple-workflow/src/main/java/org/apache/airavata/simple/workflow/engine/dag/nodes/WorkflowInputNodeImpl.java b/modules/simple-workflow/src/main/java/org/apache/airavata/simple/workflow/engine/dag/nodes/WorkflowInputNodeImpl.java
new file mode 100644
index 0000000..b3dfa62
--- /dev/null
+++ b/modules/simple-workflow/src/main/java/org/apache/airavata/simple/workflow/engine/dag/nodes/WorkflowInputNodeImpl.java
@@ -0,0 +1,96 @@
+/*
+ * 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.simple.workflow.engine.dag.nodes;
+
+import org.apache.airavata.model.appcatalog.appinterface.InputDataObjectType;
+import org.apache.airavata.simple.workflow.engine.dag.port.OutPort;
+
+public class WorkflowInputNodeImpl implements WorkflowInputNode {
+
+ private NodeState myState = NodeState.READY;
+ private final String nodeId;
+ private String nodeName;
+ private OutPort outPort;
+ private InputDataObjectType inputDataObjectType;
+ private String name;
+
+ public WorkflowInputNodeImpl(String nodeId) {
+ this(nodeId, null);
+ }
+
+ public WorkflowInputNodeImpl(String nodeId, String nodeName) {
+ this.nodeId = nodeId;
+ this.nodeName = nodeName;
+ }
+
+ @Override
+ public String getId() {
+ return this.nodeId;
+ }
+
+ @Override
+ public String getName() {
+ return this.nodeName;
+ }
+
+ @Override
+ public NodeType getType() {
+ return NodeType.WORKFLOW_INPUT;
+ }
+
+ @Override
+ public NodeState getState() {
+ return myState;
+ }
+
+ @Override
+ public void setState(NodeState newState) {
+ // TODO: node state can't be reversed , correct order WAITING --> READY --> EXECUTING --> EXECUTED --> COMPLETE
+ myState = newState;
+ }
+
+ @Override
+ public boolean isReady() {
+ return (inputDataObjectType.getValue() != null && !inputDataObjectType.getValue().equals(""))
+ || !inputDataObjectType.isIsRequired();
+ }
+
+ @Override
+ public InputDataObjectType getInputObject() {
+ return this.inputDataObjectType;
+ }
+
+ @Override
+ public void setInputObject(InputDataObjectType inputObject) {
+ this.inputDataObjectType = inputObject;
+ }
+
+ @Override
+ public OutPort getOutPort() {
+ return this.outPort;
+ }
+
+ @Override
+ public void setOutPort(OutPort outPort) {
+ this.outPort = outPort;
+ }
+
+
+}
http://git-wip-us.apache.org/repos/asf/airavata/blob/6bfb9563/modules/simple-workflow/src/main/java/org/apache/airavata/simple/workflow/engine/dag/nodes/WorkflowNode.java
----------------------------------------------------------------------
diff --git a/modules/simple-workflow/src/main/java/org/apache/airavata/simple/workflow/engine/dag/nodes/WorkflowNode.java b/modules/simple-workflow/src/main/java/org/apache/airavata/simple/workflow/engine/dag/nodes/WorkflowNode.java
new file mode 100644
index 0000000..efcf9c7
--- /dev/null
+++ b/modules/simple-workflow/src/main/java/org/apache/airavata/simple/workflow/engine/dag/nodes/WorkflowNode.java
@@ -0,0 +1,38 @@
+/*
+ *
+ * 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.simple.workflow.engine.dag.nodes;
+
+public interface WorkflowNode {
+
+ public String getId();
+
+ public String getName();
+
+ public NodeType getType();
+
+ public NodeState getState();
+
+ public void setState(NodeState newState);
+
+ public boolean isReady();
+
+}
http://git-wip-us.apache.org/repos/asf/airavata/blob/6bfb9563/modules/simple-workflow/src/main/java/org/apache/airavata/simple/workflow/engine/dag/nodes/WorkflowOutputNode.java
----------------------------------------------------------------------
diff --git a/modules/simple-workflow/src/main/java/org/apache/airavata/simple/workflow/engine/dag/nodes/WorkflowOutputNode.java b/modules/simple-workflow/src/main/java/org/apache/airavata/simple/workflow/engine/dag/nodes/WorkflowOutputNode.java
new file mode 100644
index 0000000..14e4519
--- /dev/null
+++ b/modules/simple-workflow/src/main/java/org/apache/airavata/simple/workflow/engine/dag/nodes/WorkflowOutputNode.java
@@ -0,0 +1,37 @@
+/*
+ *
+ * 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.simple.workflow.engine.dag.nodes;
+
+import org.apache.airavata.model.appcatalog.appinterface.OutputDataObjectType;
+import org.apache.airavata.simple.workflow.engine.dag.port.InPort;
+
+public interface WorkflowOutputNode extends WorkflowNode {
+
+ public OutputDataObjectType getOutputObject();
+
+ public void setOutputObject(OutputDataObjectType outputObject);
+
+ public InPort getInPort();
+
+ public void setInPort(InPort inPort);
+
+}
http://git-wip-us.apache.org/repos/asf/airavata/blob/6bfb9563/modules/simple-workflow/src/main/java/org/apache/airavata/simple/workflow/engine/dag/nodes/WorkflowOutputNodeImpl.java
----------------------------------------------------------------------
diff --git a/modules/simple-workflow/src/main/java/org/apache/airavata/simple/workflow/engine/dag/nodes/WorkflowOutputNodeImpl.java b/modules/simple-workflow/src/main/java/org/apache/airavata/simple/workflow/engine/dag/nodes/WorkflowOutputNodeImpl.java
new file mode 100644
index 0000000..5924212
--- /dev/null
+++ b/modules/simple-workflow/src/main/java/org/apache/airavata/simple/workflow/engine/dag/nodes/WorkflowOutputNodeImpl.java
@@ -0,0 +1,97 @@
+/*
+ *
+ * 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.simple.workflow.engine.dag.nodes;
+
+import org.apache.airavata.model.appcatalog.appinterface.OutputDataObjectType;
+import org.apache.airavata.simple.workflow.engine.dag.port.InPort;
+
+public class WorkflowOutputNodeImpl implements WorkflowOutputNode {
+
+ private NodeState myState = NodeState.WAITING;
+ private final String nodeId;
+ private String nodeName;
+ private OutputDataObjectType outputDataObjectType;
+ private InPort inPort;
+
+ public WorkflowOutputNodeImpl(String nodeId) {
+ this(nodeId, null);
+ }
+
+ public WorkflowOutputNodeImpl(String nodeId, String nodeName) {
+ this.nodeId = nodeId;
+ this.nodeName = nodeName;
+ }
+
+ @Override
+ public String getId() {
+ return this.nodeId;
+ }
+
+ @Override
+ public String getName() {
+ return this.nodeName;
+ }
+
+ @Override
+ public NodeType getType() {
+ return NodeType.WORKFLOW_OUTPUT;
+ }
+
+ @Override
+ public NodeState getState() {
+ return myState;
+ }
+
+ @Override
+ public void setState(NodeState newState) {
+ // TODO: node state can't be reversed , correct order WAITING --> READY --> EXECUTING --> EXECUTED --> COMPLETE
+ myState = newState;
+ }
+
+ @Override
+ public boolean isReady() {
+ return !(inPort.getInputObject() == null || inPort.getInputObject().getValue() == null
+ || inPort.getInputObject().getValue().equals(""));
+ }
+
+ @Override
+ public OutputDataObjectType getOutputObject() {
+ return this.outputDataObjectType;
+ }
+
+ @Override
+ public void setOutputObject(OutputDataObjectType outputObject) {
+ this.outputDataObjectType = outputObject;
+ }
+
+ @Override
+ public InPort getInPort() {
+ return this.inPort;
+ }
+
+ @Override
+ public void setInPort(InPort inPort) {
+ this.inPort = inPort;
+ }
+
+}
+
http://git-wip-us.apache.org/repos/asf/airavata/blob/6bfb9563/modules/simple-workflow/src/main/java/org/apache/airavata/simple/workflow/engine/dag/port/InPort.java
----------------------------------------------------------------------
diff --git a/modules/simple-workflow/src/main/java/org/apache/airavata/simple/workflow/engine/dag/port/InPort.java b/modules/simple-workflow/src/main/java/org/apache/airavata/simple/workflow/engine/dag/port/InPort.java
new file mode 100644
index 0000000..bb4a112
--- /dev/null
+++ b/modules/simple-workflow/src/main/java/org/apache/airavata/simple/workflow/engine/dag/port/InPort.java
@@ -0,0 +1,41 @@
+/*
+ *
+ * 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.simple.workflow.engine.dag.port;
+
+import org.apache.airavata.model.appcatalog.appinterface.InputDataObjectType;
+import org.apache.airavata.simple.workflow.engine.dag.edge.Edge;
+
+public interface InPort extends Port {
+
+ public void setInputObject(InputDataObjectType inputObject);
+
+ public InputDataObjectType getInputObject();
+
+ public Edge getEdge();
+
+ public void addEdge(Edge edge);
+
+ public String getDefaultValue();
+
+ public void setDefaultValue(String defaultValue);
+
+}
http://git-wip-us.apache.org/repos/asf/airavata/blob/6bfb9563/modules/simple-workflow/src/main/java/org/apache/airavata/simple/workflow/engine/dag/port/InputPortIml.java
----------------------------------------------------------------------
diff --git a/modules/simple-workflow/src/main/java/org/apache/airavata/simple/workflow/engine/dag/port/InputPortIml.java b/modules/simple-workflow/src/main/java/org/apache/airavata/simple/workflow/engine/dag/port/InputPortIml.java
new file mode 100644
index 0000000..c78dc86
--- /dev/null
+++ b/modules/simple-workflow/src/main/java/org/apache/airavata/simple/workflow/engine/dag/port/InputPortIml.java
@@ -0,0 +1,90 @@
+/*
+ * 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.simple.workflow.engine.dag.port;
+
+import org.apache.airavata.model.appcatalog.appinterface.InputDataObjectType;
+import org.apache.airavata.simple.workflow.engine.dag.edge.Edge;
+import org.apache.airavata.simple.workflow.engine.dag.nodes.WorkflowNode;
+
+public class InputPortIml implements InPort {
+
+ private InputDataObjectType inputDataObjectType;
+ private boolean ready = false;
+ private String portId;
+ private Edge edge;
+ private WorkflowNode node;
+ private String defaultValue;
+
+ public InputPortIml(String portId) {
+ this.portId = portId;
+ }
+
+ @Override
+ public void setInputObject(InputDataObjectType inputObject) {
+ this.inputDataObjectType = inputObject;
+ ready = (inputDataObjectType.getValue() != null && !inputDataObjectType.getValue().equals(""))
+ || !inputDataObjectType.isIsRequired();
+ }
+
+ @Override
+ public InputDataObjectType getInputObject() {
+ return this.inputDataObjectType;
+ }
+
+ @Override
+ public Edge getEdge() {
+ return this.edge;
+ }
+
+ @Override
+ public void addEdge(Edge edge) {
+ this.edge = edge;
+ }
+
+ @Override
+ public String getDefaultValue() {
+ return defaultValue;
+ }
+
+ public void setDefaultValue(String defaultValue) {
+ this.defaultValue = defaultValue;
+ }
+
+ @Override
+ public boolean isReady() {
+ return getInputObject() != null && inputDataObjectType.getValue() != null && !inputDataObjectType.getValue().equals("");
+ }
+
+ @Override
+ public WorkflowNode getNode() {
+ return this.node;
+ }
+
+ @Override
+ public void setNode(WorkflowNode workflowNode) {
+ this.node = workflowNode;
+ }
+
+ @Override
+ public String getId() {
+ return this.portId;
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/airavata/blob/6bfb9563/modules/simple-workflow/src/main/java/org/apache/airavata/simple/workflow/engine/dag/port/OutPort.java
----------------------------------------------------------------------
diff --git a/modules/simple-workflow/src/main/java/org/apache/airavata/simple/workflow/engine/dag/port/OutPort.java b/modules/simple-workflow/src/main/java/org/apache/airavata/simple/workflow/engine/dag/port/OutPort.java
new file mode 100644
index 0000000..0332f81
--- /dev/null
+++ b/modules/simple-workflow/src/main/java/org/apache/airavata/simple/workflow/engine/dag/port/OutPort.java
@@ -0,0 +1,39 @@
+/*
+ *
+ * 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.simple.workflow.engine.dag.port;
+
+import org.apache.airavata.model.appcatalog.appinterface.OutputDataObjectType;
+import org.apache.airavata.simple.workflow.engine.dag.edge.Edge;
+
+import java.util.List;
+
+public interface OutPort extends Port {
+
+ public void setOutputObject(OutputDataObjectType outputObject);
+
+ public OutputDataObjectType getOutputObject();
+
+ public List<Edge> getOutEdges();
+
+ public void addEdge(Edge edge);
+
+}
http://git-wip-us.apache.org/repos/asf/airavata/blob/6bfb9563/modules/simple-workflow/src/main/java/org/apache/airavata/simple/workflow/engine/dag/port/OutPortImpl.java
----------------------------------------------------------------------
diff --git a/modules/simple-workflow/src/main/java/org/apache/airavata/simple/workflow/engine/dag/port/OutPortImpl.java b/modules/simple-workflow/src/main/java/org/apache/airavata/simple/workflow/engine/dag/port/OutPortImpl.java
new file mode 100644
index 0000000..4e26cb3
--- /dev/null
+++ b/modules/simple-workflow/src/main/java/org/apache/airavata/simple/workflow/engine/dag/port/OutPortImpl.java
@@ -0,0 +1,83 @@
+/*
+ *
+ * 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.simple.workflow.engine.dag.port;
+
+import org.apache.airavata.model.appcatalog.appinterface.OutputDataObjectType;
+import org.apache.airavata.simple.workflow.engine.dag.edge.Edge;
+import org.apache.airavata.simple.workflow.engine.dag.nodes.WorkflowNode;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class OutPortImpl implements OutPort {
+
+ private OutputDataObjectType outputDataObjectType;
+ private List<Edge> outEdges = new ArrayList<Edge>();
+ private boolean isSatisfy = false;
+ private String portId;
+ private WorkflowNode node;
+
+ public OutPortImpl(String portId) {
+ this.portId = portId;
+ }
+
+ @Override
+ public void setOutputObject(OutputDataObjectType outputObject) {
+ this.outputDataObjectType = outputObject;
+ }
+
+ @Override
+ public OutputDataObjectType getOutputObject() {
+ return this.outputDataObjectType;
+ }
+
+ @Override
+ public List<Edge> getOutEdges() {
+ return this.outEdges;
+ }
+
+ @Override
+ public void addEdge(Edge edge) {
+ this.outEdges.add(edge);
+ }
+
+ @Override
+ public boolean isReady() {
+ return this.outputDataObjectType.getValue() != null
+ && !this.outputDataObjectType.getValue().equals("");
+ }
+
+ @Override
+ public WorkflowNode getNode() {
+ return this.node;
+ }
+
+ @Override
+ public void setNode(WorkflowNode workflowNode) {
+ this.node = workflowNode;
+ }
+
+ @Override
+ public String getId() {
+ return portId;
+ }
+}
http://git-wip-us.apache.org/repos/asf/airavata/blob/6bfb9563/modules/simple-workflow/src/main/java/org/apache/airavata/simple/workflow/engine/dag/port/Port.java
----------------------------------------------------------------------
diff --git a/modules/simple-workflow/src/main/java/org/apache/airavata/simple/workflow/engine/dag/port/Port.java b/modules/simple-workflow/src/main/java/org/apache/airavata/simple/workflow/engine/dag/port/Port.java
new file mode 100644
index 0000000..2b27ea0
--- /dev/null
+++ b/modules/simple-workflow/src/main/java/org/apache/airavata/simple/workflow/engine/dag/port/Port.java
@@ -0,0 +1,36 @@
+/*
+ *
+ * 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.simple.workflow.engine.dag.port;
+
+import org.apache.airavata.simple.workflow.engine.dag.nodes.WorkflowNode;
+
+public interface Port {
+
+ public boolean isReady();
+
+ public WorkflowNode getNode();
+
+ public void setNode(WorkflowNode workflowNode);
+
+ public String getId();
+
+}
[21/50] [abbrv] airavata git commit: Fixed AIRAVATA-1591 ,
AIRAVATA-1592 , AIRAVATA-1593
Posted by sh...@apache.org.
Fixed AIRAVATA-1591 ,AIRAVATA-1592 , AIRAVATA-1593
Project: http://git-wip-us.apache.org/repos/asf/airavata/repo
Commit: http://git-wip-us.apache.org/repos/asf/airavata/commit/d25441a0
Tree: http://git-wip-us.apache.org/repos/asf/airavata/tree/d25441a0
Diff: http://git-wip-us.apache.org/repos/asf/airavata/diff/d25441a0
Branch: refs/heads/master
Commit: d25441a017f2e443165a22c9c5966a6d9e6aad9e
Parents: 97ff3b7
Author: shamrath <sh...@gmail.com>
Authored: Wed Feb 25 17:12:18 2015 -0500
Committer: shamrath <sh...@gmail.com>
Committed: Wed Feb 25 17:12:18 2015 -0500
----------------------------------------------------------------------
.../lib/airavata/messagingEvents_types.cpp | 88 +++-
.../lib/airavata/messagingEvents_types.h | 47 +-
.../Airavata/Model/Messaging/Event/Types.php | 94 ++++
.../model/messaging/event/MessageType.java | 5 +-
.../messaging/event/ProcessSubmitEvent.java | 492 +++++++++++++++++++
.../messagingEvents.thrift | 8 +-
.../core/monitor/AiravataTaskStatusUpdator.java | 13 +
.../core/impl/RabbitMQProcessConsumer.java | 158 ++++++
.../core/impl/RabbitMQProcessPublisher.java | 84 ++++
.../core/impl/RabbitMQStatusConsumer.java | 10 +-
.../core/impl/RabbitMQStatusPublisher.java | 20 +-
.../server/OrchestratorServerHandler.java | 76 ++-
modules/simple-workflow/pom.xml | 5 +
.../simple/workflow/engine/ProcessContext.java | 62 +++
.../simple/workflow/engine/ProcessPack.java | 62 ---
.../engine/SimpleWorkflowInterpreter.java | 378 +++++++-------
.../workflow/engine/WorkflowFactoryImpl.java | 4 +-
.../engine/parser/AiravataDefaultParser.java | 293 -----------
.../engine/parser/AiravataWorkflowParser.java | 291 +++++++++++
.../parser/AiravataDefaultParserTest.java | 119 -----
.../parser/AiravataWorkflowParserTest.java | 119 +++++
21 files changed, 1724 insertions(+), 704 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/airavata/blob/d25441a0/airavata-api/airavata-client-sdks/airavata-cpp-sdk/src/main/resources/lib/airavata/messagingEvents_types.cpp
----------------------------------------------------------------------
diff --git a/airavata-api/airavata-client-sdks/airavata-cpp-sdk/src/main/resources/lib/airavata/messagingEvents_types.cpp b/airavata-api/airavata-client-sdks/airavata-cpp-sdk/src/main/resources/lib/airavata/messagingEvents_types.cpp
index 71f45be..92f29c6 100644
--- a/airavata-api/airavata-client-sdks/airavata-cpp-sdk/src/main/resources/lib/airavata/messagingEvents_types.cpp
+++ b/airavata-api/airavata-client-sdks/airavata-cpp-sdk/src/main/resources/lib/airavata/messagingEvents_types.cpp
@@ -47,7 +47,8 @@ int _kMessageTypeValues[] = {
MessageType::WORKFLOWNODE,
MessageType::JOB,
MessageType::LAUNCHTASK,
- MessageType::TERMINATETASK
+ MessageType::TERMINATETASK,
+ MessageType::TASKOUTPUT
};
const char* _kMessageTypeNames[] = {
"EXPERIMENT",
@@ -55,9 +56,10 @@ const char* _kMessageTypeNames[] = {
"WORKFLOWNODE",
"JOB",
"LAUNCHTASK",
- "TERMINATETASK"
+ "TERMINATETASK",
+ "TASKOUTPUT"
};
-const std::map<int, const char*> _MessageType_VALUES_TO_NAMES(::apache::thrift::TEnumIterator(6, _kMessageTypeValues, _kMessageTypeNames), ::apache::thrift::TEnumIterator(-1, NULL, NULL));
+const std::map<int, const char*> _MessageType_VALUES_TO_NAMES(::apache::thrift::TEnumIterator(7, _kMessageTypeValues, _kMessageTypeNames), ::apache::thrift::TEnumIterator(-1, NULL, NULL));
const char* ExperimentStatusChangeEvent::ascii_fingerprint = "38C252E94E93B69D04EB3A6EE2F9EDFB";
const uint8_t ExperimentStatusChangeEvent::binary_fingerprint[16] = {0x38,0xC2,0x52,0xE9,0x4E,0x93,0xB6,0x9D,0x04,0xEB,0x3A,0x6E,0xE2,0xF9,0xED,0xFB};
@@ -839,6 +841,86 @@ void swap(JobIdentifier &a, JobIdentifier &b) {
swap(a.gatewayId, b.gatewayId);
}
+const char* ProcessSubmitEvent::ascii_fingerprint = "07A9615F837F7D0A952B595DD3020972";
+const uint8_t ProcessSubmitEvent::binary_fingerprint[16] = {0x07,0xA9,0x61,0x5F,0x83,0x7F,0x7D,0x0A,0x95,0x2B,0x59,0x5D,0xD3,0x02,0x09,0x72};
+
+uint32_t ProcessSubmitEvent::read(::apache::thrift::protocol::TProtocol* iprot) {
+
+ uint32_t xfer = 0;
+ std::string fname;
+ ::apache::thrift::protocol::TType ftype;
+ int16_t fid;
+
+ xfer += iprot->readStructBegin(fname);
+
+ using ::apache::thrift::protocol::TProtocolException;
+
+ bool isset_taskId = false;
+ bool isset_credentialToken = false;
+
+ while (true)
+ {
+ xfer += iprot->readFieldBegin(fname, ftype, fid);
+ if (ftype == ::apache::thrift::protocol::T_STOP) {
+ break;
+ }
+ switch (fid)
+ {
+ case 1:
+ if (ftype == ::apache::thrift::protocol::T_STRING) {
+ xfer += iprot->readString(this->taskId);
+ isset_taskId = true;
+ } else {
+ xfer += iprot->skip(ftype);
+ }
+ break;
+ case 2:
+ if (ftype == ::apache::thrift::protocol::T_STRING) {
+ xfer += iprot->readString(this->credentialToken);
+ isset_credentialToken = true;
+ } else {
+ xfer += iprot->skip(ftype);
+ }
+ break;
+ default:
+ xfer += iprot->skip(ftype);
+ break;
+ }
+ xfer += iprot->readFieldEnd();
+ }
+
+ xfer += iprot->readStructEnd();
+
+ if (!isset_taskId)
+ throw TProtocolException(TProtocolException::INVALID_DATA);
+ if (!isset_credentialToken)
+ throw TProtocolException(TProtocolException::INVALID_DATA);
+ return xfer;
+}
+
+uint32_t ProcessSubmitEvent::write(::apache::thrift::protocol::TProtocol* oprot) const {
+ uint32_t xfer = 0;
+ xfer += oprot->writeStructBegin("ProcessSubmitEvent");
+
+ xfer += oprot->writeFieldBegin("taskId", ::apache::thrift::protocol::T_STRING, 1);
+ xfer += oprot->writeString(this->taskId);
+ xfer += oprot->writeFieldEnd();
+
+ xfer += oprot->writeFieldBegin("credentialToken", ::apache::thrift::protocol::T_STRING, 2);
+ xfer += oprot->writeString(this->credentialToken);
+ xfer += oprot->writeFieldEnd();
+
+ xfer += oprot->writeFieldStop();
+ xfer += oprot->writeStructEnd();
+ return xfer;
+}
+
+void swap(ProcessSubmitEvent &a, ProcessSubmitEvent &b) {
+ using ::std::swap;
+ swap(a.taskId, b.taskId);
+ swap(a.credentialToken, b.credentialToken);
+}
+
const char* TaskSubmitEvent::ascii_fingerprint = "C93D890311F28844166CF6E571EB3AC2";
const uint8_t TaskSubmitEvent::binary_fingerprint[16] = {0xC9,0x3D,0x89,0x03,0x11,0xF2,0x88,0x44,0x16,0x6C,0xF6,0xE5,0x71,0xEB,0x3A,0xC2};
http://git-wip-us.apache.org/repos/asf/airavata/blob/d25441a0/airavata-api/airavata-client-sdks/airavata-cpp-sdk/src/main/resources/lib/airavata/messagingEvents_types.h
----------------------------------------------------------------------
diff --git a/airavata-api/airavata-client-sdks/airavata-cpp-sdk/src/main/resources/lib/airavata/messagingEvents_types.h b/airavata-api/airavata-client-sdks/airavata-cpp-sdk/src/main/resources/lib/airavata/messagingEvents_types.h
index c7e2bb5..aafcda1 100644
--- a/airavata-api/airavata-client-sdks/airavata-cpp-sdk/src/main/resources/lib/airavata/messagingEvents_types.h
+++ b/airavata-api/airavata-client-sdks/airavata-cpp-sdk/src/main/resources/lib/airavata/messagingEvents_types.h
@@ -54,7 +54,8 @@ struct MessageType {
WORKFLOWNODE = 2,
JOB = 3,
LAUNCHTASK = 4,
- TERMINATETASK = 5
+ TERMINATETASK = 5,
+ TASKOUTPUT = 6
};
};
@@ -462,6 +463,50 @@ class JobIdentifier {
void swap(JobIdentifier &a, JobIdentifier &b);
+class ProcessSubmitEvent {
+ public:
+
+ static const char* ascii_fingerprint; // = "07A9615F837F7D0A952B595DD3020972";
+ static const uint8_t binary_fingerprint[16]; // = {0x07,0xA9,0x61,0x5F,0x83,0x7F,0x7D,0x0A,0x95,0x2B,0x59,0x5D,0xD3,0x02,0x09,0x72};
+
+ ProcessSubmitEvent() : taskId(), credentialToken() {
+ }
+
+ virtual ~ProcessSubmitEvent() throw() {}
+
+ std::string taskId;
+ std::string credentialToken;
+
+ void __set_taskId(const std::string& val) {
+ taskId = val;
+ }
+
+ void __set_credentialToken(const std::string& val) {
+ credentialToken = val;
+ }
+
+ bool operator == (const ProcessSubmitEvent & rhs) const
+ {
+ if (!(taskId == rhs.taskId))
+ return false;
+ if (!(credentialToken == rhs.credentialToken))
+ return false;
+ return true;
+ }
+ bool operator != (const ProcessSubmitEvent &rhs) const {
+ return !(*this == rhs);
+ }
+
+ bool operator < (const ProcessSubmitEvent & ) const;
+
+ uint32_t read(::apache::thrift::protocol::TProtocol* iprot);
+ uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const;
+
+};
+
+void swap(ProcessSubmitEvent &a, ProcessSubmitEvent &b);
+
+
class TaskSubmitEvent {
public:
http://git-wip-us.apache.org/repos/asf/airavata/blob/d25441a0/airavata-api/airavata-client-sdks/airavata-php-sdk/src/main/resources/lib/Airavata/Model/Messaging/Event/Types.php
----------------------------------------------------------------------
diff --git a/airavata-api/airavata-client-sdks/airavata-php-sdk/src/main/resources/lib/Airavata/Model/Messaging/Event/Types.php b/airavata-api/airavata-client-sdks/airavata-php-sdk/src/main/resources/lib/Airavata/Model/Messaging/Event/Types.php
index b0d7676..4c4ec93 100644
--- a/airavata-api/airavata-client-sdks/airavata-php-sdk/src/main/resources/lib/Airavata/Model/Messaging/Event/Types.php
+++ b/airavata-api/airavata-client-sdks/airavata-php-sdk/src/main/resources/lib/Airavata/Model/Messaging/Event/Types.php
@@ -37,6 +37,7 @@ final class MessageType {
const JOB = 3;
const LAUNCHTASK = 4;
const TERMINATETASK = 5;
+ const TASKOUTPUT = 6;
static public $__names = array(
0 => 'EXPERIMENT',
1 => 'TASK',
@@ -44,6 +45,7 @@ final class MessageType {
3 => 'JOB',
4 => 'LAUNCHTASK',
5 => 'TERMINATETASK',
+ 6 => 'TASKOUTPUT',
);
}
@@ -971,6 +973,98 @@ class JobIdentifier {
}
+class ProcessSubmitEvent {
+ static $_TSPEC;
+
+ public $taskId = null;
+ public $credentialToken = null;
+
+ public function __construct($vals=null) {
+ if (!isset(self::$_TSPEC)) {
+ self::$_TSPEC = array(
+ 1 => array(
+ 'var' => 'taskId',
+ 'type' => TType::STRING,
+ ),
+ 2 => array(
+ 'var' => 'credentialToken',
+ 'type' => TType::STRING,
+ ),
+ );
+ }
+ if (is_array($vals)) {
+ if (isset($vals['taskId'])) {
+ $this->taskId = $vals['taskId'];
+ }
+ if (isset($vals['credentialToken'])) {
+ $this->credentialToken = $vals['credentialToken'];
+ }
+ }
+ }
+
+ public function getName() {
+ return 'ProcessSubmitEvent';
+ }
+
+ public function read($input)
+ {
+ $xfer = 0;
+ $fname = null;
+ $ftype = 0;
+ $fid = 0;
+ $xfer += $input->readStructBegin($fname);
+ while (true)
+ {
+ $xfer += $input->readFieldBegin($fname, $ftype, $fid);
+ if ($ftype == TType::STOP) {
+ break;
+ }
+ switch ($fid)
+ {
+ case 1:
+ if ($ftype == TType::STRING) {
+ $xfer += $input->readString($this->taskId);
+ } else {
+ $xfer += $input->skip($ftype);
+ }
+ break;
+ case 2:
+ if ($ftype == TType::STRING) {
+ $xfer += $input->readString($this->credentialToken);
+ } else {
+ $xfer += $input->skip($ftype);
+ }
+ break;
+ default:
+ $xfer += $input->skip($ftype);
+ break;
+ }
+ $xfer += $input->readFieldEnd();
+ }
+ $xfer += $input->readStructEnd();
+ return $xfer;
+ }
+
+ public function write($output) {
+ $xfer = 0;
+ $xfer += $output->writeStructBegin('ProcessSubmitEvent');
+ if ($this->taskId !== null) {
+ $xfer += $output->writeFieldBegin('taskId', TType::STRING, 1);
+ $xfer += $output->writeString($this->taskId);
+ $xfer += $output->writeFieldEnd();
+ }
+ if ($this->credentialToken !== null) {
+ $xfer += $output->writeFieldBegin('credentialToken', TType::STRING, 2);
+ $xfer += $output->writeString($this->credentialToken);
+ $xfer += $output->writeFieldEnd();
+ }
+ $xfer += $output->writeFieldStop();
+ $xfer += $output->writeStructEnd();
+ return $xfer;
+ }
+
+}
+
class TaskSubmitEvent {
static $_TSPEC;
http://git-wip-us.apache.org/repos/asf/airavata/blob/d25441a0/airavata-api/airavata-data-models/src/main/java/org/apache/airavata/model/messaging/event/MessageType.java
----------------------------------------------------------------------
diff --git a/airavata-api/airavata-data-models/src/main/java/org/apache/airavata/model/messaging/event/MessageType.java b/airavata-api/airavata-data-models/src/main/java/org/apache/airavata/model/messaging/event/MessageType.java
index 230b87b..761626f 100644
--- a/airavata-api/airavata-data-models/src/main/java/org/apache/airavata/model/messaging/event/MessageType.java
+++ b/airavata-api/airavata-data-models/src/main/java/org/apache/airavata/model/messaging/event/MessageType.java
@@ -34,7 +34,8 @@ import org.apache.thrift.TEnum;
WORKFLOWNODE(2),
JOB(3),
LAUNCHTASK(4),
- TERMINATETASK(5);
+ TERMINATETASK(5),
+ TASKOUTPUT(6);
private final int value;
@@ -67,6 +68,8 @@ import org.apache.thrift.TEnum;
return LAUNCHTASK;
case 5:
return TERMINATETASK;
+ case 6:
+ return TASKOUTPUT;
default:
return null;
}
http://git-wip-us.apache.org/repos/asf/airavata/blob/d25441a0/airavata-api/airavata-data-models/src/main/java/org/apache/airavata/model/messaging/event/ProcessSubmitEvent.java
----------------------------------------------------------------------
diff --git a/airavata-api/airavata-data-models/src/main/java/org/apache/airavata/model/messaging/event/ProcessSubmitEvent.java b/airavata-api/airavata-data-models/src/main/java/org/apache/airavata/model/messaging/event/ProcessSubmitEvent.java
new file mode 100644
index 0000000..e1d001a
--- /dev/null
+++ b/airavata-api/airavata-data-models/src/main/java/org/apache/airavata/model/messaging/event/ProcessSubmitEvent.java
@@ -0,0 +1,492 @@
+/**
+ * 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.
+ */
+
+/**
+ * Autogenerated by Thrift Compiler (0.9.1)
+ *
+ * DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING
+ * @generated
+ */
+package org.apache.airavata.model.messaging.event;
+
+import org.apache.thrift.scheme.IScheme;
+import org.apache.thrift.scheme.SchemeFactory;
+import org.apache.thrift.scheme.StandardScheme;
+
+import org.apache.thrift.scheme.TupleScheme;
+import org.apache.thrift.protocol.TTupleProtocol;
+import org.apache.thrift.protocol.TProtocolException;
+import org.apache.thrift.EncodingUtils;
+import org.apache.thrift.TException;
+import org.apache.thrift.async.AsyncMethodCallback;
+import org.apache.thrift.server.AbstractNonblockingServer.*;
+import java.util.List;
+import java.util.ArrayList;
+import java.util.Map;
+import java.util.HashMap;
+import java.util.EnumMap;
+import java.util.Set;
+import java.util.HashSet;
+import java.util.EnumSet;
+import java.util.Collections;
+import java.util.BitSet;
+import java.nio.ByteBuffer;
+import java.util.Arrays;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+@SuppressWarnings("all") public class ProcessSubmitEvent implements org.apache.thrift.TBase<ProcessSubmitEvent, ProcessSubmitEvent._Fields>, java.io.Serializable, Cloneable, Comparable<ProcessSubmitEvent> {
+ private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("ProcessSubmitEvent");
+
+ private static final org.apache.thrift.protocol.TField TASK_ID_FIELD_DESC = new org.apache.thrift.protocol.TField("taskId", org.apache.thrift.protocol.TType.STRING, (short)1);
+ private static final org.apache.thrift.protocol.TField CREDENTIAL_TOKEN_FIELD_DESC = new org.apache.thrift.protocol.TField("credentialToken", org.apache.thrift.protocol.TType.STRING, (short)2);
+
+ private static final Map<Class<? extends IScheme>, SchemeFactory> schemes = new HashMap<Class<? extends IScheme>, SchemeFactory>();
+ static {
+ schemes.put(StandardScheme.class, new ProcessSubmitEventStandardSchemeFactory());
+ schemes.put(TupleScheme.class, new ProcessSubmitEventTupleSchemeFactory());
+ }
+
+ private String taskId; // required
+ private String credentialToken; // required
+
+ /** The set of fields this struct contains, along with convenience methods for finding and manipulating them. */
+ @SuppressWarnings("all") public enum _Fields implements org.apache.thrift.TFieldIdEnum {
+ TASK_ID((short)1, "taskId"),
+ CREDENTIAL_TOKEN((short)2, "credentialToken");
+
+ private static final Map<String, _Fields> byName = new HashMap<String, _Fields>();
+
+ static {
+ for (_Fields field : EnumSet.allOf(_Fields.class)) {
+ byName.put(field.getFieldName(), field);
+ }
+ }
+
+ /**
+ * Find the _Fields constant that matches fieldId, or null if its not found.
+ */
+ public static _Fields findByThriftId(int fieldId) {
+ switch(fieldId) {
+ case 1: // TASK_ID
+ return TASK_ID;
+ case 2: // CREDENTIAL_TOKEN
+ return CREDENTIAL_TOKEN;
+ default:
+ return null;
+ }
+ }
+
+ /**
+ * Find the _Fields constant that matches fieldId, throwing an exception
+ * if it is not found.
+ */
+ public static _Fields findByThriftIdOrThrow(int fieldId) {
+ _Fields fields = findByThriftId(fieldId);
+ if (fields == null) throw new IllegalArgumentException("Field " + fieldId + " doesn't exist!");
+ return fields;
+ }
+
+ /**
+ * Find the _Fields constant that matches name, or null if its not found.
+ */
+ public static _Fields findByName(String name) {
+ return byName.get(name);
+ }
+
+ private final short _thriftId;
+ private final String _fieldName;
+
+ _Fields(short thriftId, String fieldName) {
+ _thriftId = thriftId;
+ _fieldName = fieldName;
+ }
+
+ public short getThriftFieldId() {
+ return _thriftId;
+ }
+
+ public String getFieldName() {
+ return _fieldName;
+ }
+ }
+
+ // isset id assignments
+ public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
+ static {
+ Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
+ tmpMap.put(_Fields.TASK_ID, new org.apache.thrift.meta_data.FieldMetaData("taskId", org.apache.thrift.TFieldRequirementType.REQUIRED,
+ new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING)));
+ tmpMap.put(_Fields.CREDENTIAL_TOKEN, new org.apache.thrift.meta_data.FieldMetaData("credentialToken", org.apache.thrift.TFieldRequirementType.REQUIRED,
+ new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING)));
+ metaDataMap = Collections.unmodifiableMap(tmpMap);
+ org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(ProcessSubmitEvent.class, metaDataMap);
+ }
+
+ public ProcessSubmitEvent() {
+ }
+
+ public ProcessSubmitEvent(
+ String taskId,
+ String credentialToken)
+ {
+ this();
+ this.taskId = taskId;
+ this.credentialToken = credentialToken;
+ }
+
+ /**
+ * Performs a deep copy on <i>other</i>.
+ */
+ public ProcessSubmitEvent(ProcessSubmitEvent other) {
+ if (other.isSetTaskId()) {
+ this.taskId = other.taskId;
+ }
+ if (other.isSetCredentialToken()) {
+ this.credentialToken = other.credentialToken;
+ }
+ }
+
+ public ProcessSubmitEvent deepCopy() {
+ return new ProcessSubmitEvent(this);
+ }
+
+ @Override
+ public void clear() {
+ this.taskId = null;
+ this.credentialToken = null;
+ }
+
+ public String getTaskId() {
+ return this.taskId;
+ }
+
+ public void setTaskId(String taskId) {
+ this.taskId = taskId;
+ }
+
+ public void unsetTaskId() {
+ this.taskId = null;
+ }
+
+ /** Returns true if field taskId is set (has been assigned a value) and false otherwise */
+ public boolean isSetTaskId() {
+ return this.taskId != null;
+ }
+
+ public void setTaskIdIsSet(boolean value) {
+ if (!value) {
+ this.taskId = null;
+ }
+ }
+
+ public String getCredentialToken() {
+ return this.credentialToken;
+ }
+
+ public void setCredentialToken(String credentialToken) {
+ this.credentialToken = credentialToken;
+ }
+
+ public void unsetCredentialToken() {
+ this.credentialToken = null;
+ }
+
+ /** Returns true if field credentialToken is set (has been assigned a value) and false otherwise */
+ public boolean isSetCredentialToken() {
+ return this.credentialToken != null;
+ }
+
+ public void setCredentialTokenIsSet(boolean value) {
+ if (!value) {
+ this.credentialToken = null;
+ }
+ }
+
+ public void setFieldValue(_Fields field, Object value) {
+ switch (field) {
+ case TASK_ID:
+ if (value == null) {
+ unsetTaskId();
+ } else {
+ setTaskId((String)value);
+ }
+ break;
+
+ case CREDENTIAL_TOKEN:
+ if (value == null) {
+ unsetCredentialToken();
+ } else {
+ setCredentialToken((String)value);
+ }
+ break;
+
+ }
+ }
+
+ public Object getFieldValue(_Fields field) {
+ switch (field) {
+ case TASK_ID:
+ return getTaskId();
+
+ case CREDENTIAL_TOKEN:
+ return getCredentialToken();
+
+ }
+ throw new IllegalStateException();
+ }
+
+ /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */
+ public boolean isSet(_Fields field) {
+ if (field == null) {
+ throw new IllegalArgumentException();
+ }
+
+ switch (field) {
+ case TASK_ID:
+ return isSetTaskId();
+ case CREDENTIAL_TOKEN:
+ return isSetCredentialToken();
+ }
+ throw new IllegalStateException();
+ }
+
+ @Override
+ public boolean equals(Object that) {
+ if (that == null)
+ return false;
+ if (that instanceof ProcessSubmitEvent)
+ return this.equals((ProcessSubmitEvent)that);
+ return false;
+ }
+
+ public boolean equals(ProcessSubmitEvent that) {
+ if (that == null)
+ return false;
+
+ boolean this_present_taskId = true && this.isSetTaskId();
+ boolean that_present_taskId = true && that.isSetTaskId();
+ if (this_present_taskId || that_present_taskId) {
+ if (!(this_present_taskId && that_present_taskId))
+ return false;
+ if (!this.taskId.equals(that.taskId))
+ return false;
+ }
+
+ boolean this_present_credentialToken = true && this.isSetCredentialToken();
+ boolean that_present_credentialToken = true && that.isSetCredentialToken();
+ if (this_present_credentialToken || that_present_credentialToken) {
+ if (!(this_present_credentialToken && that_present_credentialToken))
+ return false;
+ if (!this.credentialToken.equals(that.credentialToken))
+ return false;
+ }
+
+ return true;
+ }
+
+ @Override
+ public int hashCode() {
+ return 0;
+ }
+
+ @Override
+ public int compareTo(ProcessSubmitEvent other) {
+ if (!getClass().equals(other.getClass())) {
+ return getClass().getName().compareTo(other.getClass().getName());
+ }
+
+ int lastComparison = 0;
+
+ lastComparison = Boolean.valueOf(isSetTaskId()).compareTo(other.isSetTaskId());
+ if (lastComparison != 0) {
+ return lastComparison;
+ }
+ if (isSetTaskId()) {
+ lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.taskId, other.taskId);
+ if (lastComparison != 0) {
+ return lastComparison;
+ }
+ }
+ lastComparison = Boolean.valueOf(isSetCredentialToken()).compareTo(other.isSetCredentialToken());
+ if (lastComparison != 0) {
+ return lastComparison;
+ }
+ if (isSetCredentialToken()) {
+ lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.credentialToken, other.credentialToken);
+ if (lastComparison != 0) {
+ return lastComparison;
+ }
+ }
+ return 0;
+ }
+
+ public _Fields fieldForId(int fieldId) {
+ return _Fields.findByThriftId(fieldId);
+ }
+
+ public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
+ schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
+ }
+
+ public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
+ schemes.get(oprot.getScheme()).getScheme().write(oprot, this);
+ }
+
+ @Override
+ public String toString() {
+ StringBuilder sb = new StringBuilder("ProcessSubmitEvent(");
+ boolean first = true;
+
+ sb.append("taskId:");
+ if (this.taskId == null) {
+ sb.append("null");
+ } else {
+ sb.append(this.taskId);
+ }
+ first = false;
+ if (!first) sb.append(", ");
+ sb.append("credentialToken:");
+ if (this.credentialToken == null) {
+ sb.append("null");
+ } else {
+ sb.append(this.credentialToken);
+ }
+ first = false;
+ sb.append(")");
+ return sb.toString();
+ }
+
+ public void validate() throws org.apache.thrift.TException {
+ // check for required fields
+ if (!isSetTaskId()) {
+ throw new org.apache.thrift.protocol.TProtocolException("Required field 'taskId' is unset! Struct:" + toString());
+ }
+
+ if (!isSetCredentialToken()) {
+ throw new org.apache.thrift.protocol.TProtocolException("Required field 'credentialToken' is unset! Struct:" + toString());
+ }
+
+ // check for sub-struct validity
+ }
+
+ private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException {
+ try {
+ write(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(out)));
+ } catch (org.apache.thrift.TException te) {
+ throw new java.io.IOException(te);
+ }
+ }
+
+ private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, ClassNotFoundException {
+ try {
+ read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
+ } catch (org.apache.thrift.TException te) {
+ throw new java.io.IOException(te);
+ }
+ }
+
+ private static class ProcessSubmitEventStandardSchemeFactory implements SchemeFactory {
+ public ProcessSubmitEventStandardScheme getScheme() {
+ return new ProcessSubmitEventStandardScheme();
+ }
+ }
+
+ private static class ProcessSubmitEventStandardScheme extends StandardScheme<ProcessSubmitEvent> {
+
+ public void read(org.apache.thrift.protocol.TProtocol iprot, ProcessSubmitEvent struct) throws org.apache.thrift.TException {
+ org.apache.thrift.protocol.TField schemeField;
+ iprot.readStructBegin();
+ while (true)
+ {
+ schemeField = iprot.readFieldBegin();
+ if (schemeField.type == org.apache.thrift.protocol.TType.STOP) {
+ break;
+ }
+ switch (schemeField.id) {
+ case 1: // TASK_ID
+ if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
+ struct.taskId = iprot.readString();
+ struct.setTaskIdIsSet(true);
+ } else {
+ org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
+ }
+ break;
+ case 2: // CREDENTIAL_TOKEN
+ if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
+ struct.credentialToken = iprot.readString();
+ struct.setCredentialTokenIsSet(true);
+ } else {
+ org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
+ }
+ break;
+ default:
+ org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
+ }
+ iprot.readFieldEnd();
+ }
+ iprot.readStructEnd();
+ struct.validate();
+ }
+
+ public void write(org.apache.thrift.protocol.TProtocol oprot, ProcessSubmitEvent struct) throws org.apache.thrift.TException {
+ struct.validate();
+
+ oprot.writeStructBegin(STRUCT_DESC);
+ if (struct.taskId != null) {
+ oprot.writeFieldBegin(TASK_ID_FIELD_DESC);
+ oprot.writeString(struct.taskId);
+ oprot.writeFieldEnd();
+ }
+ if (struct.credentialToken != null) {
+ oprot.writeFieldBegin(CREDENTIAL_TOKEN_FIELD_DESC);
+ oprot.writeString(struct.credentialToken);
+ oprot.writeFieldEnd();
+ }
+ oprot.writeFieldStop();
+ oprot.writeStructEnd();
+ }
+
+ }
+
+ private static class ProcessSubmitEventTupleSchemeFactory implements SchemeFactory {
+ public ProcessSubmitEventTupleScheme getScheme() {
+ return new ProcessSubmitEventTupleScheme();
+ }
+ }
+
+ private static class ProcessSubmitEventTupleScheme extends TupleScheme<ProcessSubmitEvent> {
+
+ @Override
+ public void write(org.apache.thrift.protocol.TProtocol prot, ProcessSubmitEvent struct) throws org.apache.thrift.TException {
+ TTupleProtocol oprot = (TTupleProtocol) prot;
+ oprot.writeString(struct.taskId);
+ oprot.writeString(struct.credentialToken);
+ }
+
+ @Override
+ public void read(org.apache.thrift.protocol.TProtocol prot, ProcessSubmitEvent struct) throws org.apache.thrift.TException {
+ TTupleProtocol iprot = (TTupleProtocol) prot;
+ struct.taskId = iprot.readString();
+ struct.setTaskIdIsSet(true);
+ struct.credentialToken = iprot.readString();
+ struct.setCredentialTokenIsSet(true);
+ }
+ }
+
+}
+
http://git-wip-us.apache.org/repos/asf/airavata/blob/d25441a0/airavata-api/thrift-interface-descriptions/messagingEvents.thrift
----------------------------------------------------------------------
diff --git a/airavata-api/thrift-interface-descriptions/messagingEvents.thrift b/airavata-api/thrift-interface-descriptions/messagingEvents.thrift
index d9e85d4..b13b5ed 100644
--- a/airavata-api/thrift-interface-descriptions/messagingEvents.thrift
+++ b/airavata-api/thrift-interface-descriptions/messagingEvents.thrift
@@ -40,7 +40,8 @@ enum MessageType {
WORKFLOWNODE,
JOB,
LAUNCHTASK,
- TERMINATETASK
+ TERMINATETASK,
+ TASKOUTPUT
}
struct ExperimentStatusChangeEvent {
@@ -102,6 +103,11 @@ struct JobIdentifier {
// //8:
// }
+struct ProcessSubmitEvent{
+ 1: required string taskId;
+ 2: required string credentialToken;
+}
+
struct TaskSubmitEvent{
1: required string experimentId,
2: required string taskId,
http://git-wip-us.apache.org/repos/asf/airavata/blob/d25441a0/modules/gfac/gfac-core/src/main/java/org/apache/airavata/gfac/core/monitor/AiravataTaskStatusUpdator.java
----------------------------------------------------------------------
diff --git a/modules/gfac/gfac-core/src/main/java/org/apache/airavata/gfac/core/monitor/AiravataTaskStatusUpdator.java b/modules/gfac/gfac-core/src/main/java/org/apache/airavata/gfac/core/monitor/AiravataTaskStatusUpdator.java
index 837b728..5490d50 100644
--- a/modules/gfac/gfac-core/src/main/java/org/apache/airavata/gfac/core/monitor/AiravataTaskStatusUpdator.java
+++ b/modules/gfac/gfac-core/src/main/java/org/apache/airavata/gfac/core/monitor/AiravataTaskStatusUpdator.java
@@ -21,6 +21,7 @@
package org.apache.airavata.gfac.core.monitor;
import com.google.common.eventbus.Subscribe;
+import org.apache.airavata.common.exception.AiravataException;
import org.apache.airavata.common.utils.AiravataUtils;
import org.apache.airavata.common.utils.MonitorPublisher;
import org.apache.airavata.common.utils.ServerSettings;
@@ -150,4 +151,16 @@ public class AiravataTaskStatusUpdator implements AbstractActivityListener {
}
}
}
+
+
+ @Subscribe
+ public void taskOutputChanged(TaskOutputChangeEvent taskOutputEvent) throws AiravataException {
+ String taskId = taskOutputEvent.getTaskIdentity().getTaskId();
+ logger.debug("Task Output changed event received for workflow node : " +
+ taskOutputEvent.getTaskIdentity().getWorkflowNodeId() + ", task : " + taskId);
+ // TODO - do we need to update the output to the registry? , we do it in the workflowInterpreter too.
+ MessageContext messageContext = new MessageContext(taskOutputEvent, MessageType.TASKOUTPUT, taskOutputEvent.getTaskIdentity().getTaskId(), taskOutputEvent.getTaskIdentity().getGatewayId());
+ messageContext.setUpdatedTime(AiravataUtils.getCurrentTimestamp());
+ publisher.publish(messageContext);
+ }
}
http://git-wip-us.apache.org/repos/asf/airavata/blob/d25441a0/modules/messaging/core/src/main/java/org/apache/airavata/messaging/core/impl/RabbitMQProcessConsumer.java
----------------------------------------------------------------------
diff --git a/modules/messaging/core/src/main/java/org/apache/airavata/messaging/core/impl/RabbitMQProcessConsumer.java b/modules/messaging/core/src/main/java/org/apache/airavata/messaging/core/impl/RabbitMQProcessConsumer.java
new file mode 100644
index 0000000..3352893
--- /dev/null
+++ b/modules/messaging/core/src/main/java/org/apache/airavata/messaging/core/impl/RabbitMQProcessConsumer.java
@@ -0,0 +1,158 @@
+/*
+ *
+ * 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.messaging.core.impl;
+
+import com.rabbitmq.client.AMQP;
+import com.rabbitmq.client.Channel;
+import com.rabbitmq.client.Connection;
+import com.rabbitmq.client.ConnectionFactory;
+import com.rabbitmq.client.Envelope;
+import com.rabbitmq.client.QueueingConsumer;
+import com.rabbitmq.client.ShutdownListener;
+import com.rabbitmq.client.ShutdownSignalException;
+import org.apache.airavata.common.exception.AiravataException;
+import org.apache.airavata.common.exception.ApplicationSettingsException;
+import org.apache.airavata.common.utils.AiravataUtils;
+import org.apache.airavata.common.utils.ServerSettings;
+import org.apache.airavata.common.utils.ThriftUtils;
+import org.apache.airavata.messaging.core.MessageContext;
+import org.apache.airavata.messaging.core.MessageHandler;
+import org.apache.airavata.messaging.core.MessagingConstants;
+import org.apache.airavata.model.messaging.event.Message;
+import org.apache.airavata.model.messaging.event.ProcessSubmitEvent;
+import org.apache.thrift.TBase;
+import org.apache.thrift.TException;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.io.IOException;
+import java.util.Map;
+
+public class RabbitMQProcessConsumer {
+
+ private static final Logger log = LoggerFactory.getLogger(RabbitMQProcessConsumer.class);
+
+ private String url;
+ private Connection connection;
+ private Channel channel;
+
+ public RabbitMQProcessConsumer() throws AiravataException {
+ try {
+ url = ServerSettings.getSetting(MessagingConstants.RABBITMQ_BROKER_URL);
+ createConnection();
+ } catch (ApplicationSettingsException e) {
+ String message = "Failed to get read the required properties from airavata to initialize rabbitmq";
+ log.error(message, e);
+ throw new AiravataException(message, e);
+ }
+ }
+
+ private void createConnection() throws AiravataException {
+ try {
+ ConnectionFactory connectionFactory = new ConnectionFactory();
+ connectionFactory.setUri(url);
+ connection = connectionFactory.newConnection();
+ connection.addShutdownListener(new ShutdownListener() {
+ public void shutdownCompleted(ShutdownSignalException cause) {
+ }
+ });
+ log.info("connected to rabbitmq: " + connection + " for default");
+
+ channel = connection.createChannel();
+// channel.exchangeDeclare(taskLaunchExchangeName, "fanout");
+
+ } catch (Exception e) {
+ String msg = "could not open channel for exchange default";
+ log.error(msg);
+ throw new AiravataException(msg, e);
+ }
+ }
+
+
+ public String listen(final MessageHandler handler) throws AiravataException {
+ try {
+ Map<String, Object> props = handler.getProperties();
+ final Object routing = props.get(MessagingConstants.RABBIT_ROUTING_KEY);
+ if (routing == null) {
+ throw new IllegalArgumentException("The routing key must be present");
+ }
+ String queueName = (String) props.get(MessagingConstants.RABBIT_QUEUE);
+ String consumerTag = (String) props.get(MessagingConstants.RABBIT_CONSUMER_TAG);
+ if (queueName == null) {
+ if (!channel.isOpen()) {
+ channel = connection.createChannel();
+// channel.exchangeDeclare(taskLaunchExchangeName, "fanout");
+ }
+ queueName = channel.queueDeclare().getQueue();
+ } else {
+ channel.queueDeclare(queueName, true, false, false, null);
+ }
+
+ if (consumerTag == null) {
+ consumerTag = "default";
+ }
+ // autoAck=false, we will ack after task is done
+ final String finalQueueName = queueName;
+ channel.basicConsume(queueName, true, new QueueingConsumer(channel) {
+ @Override
+ public void handleDelivery(String consumerTag,
+ Envelope envelope,
+ AMQP.BasicProperties properties,
+ byte[] body) {
+ Message message = new Message();
+
+ try {
+ ThriftUtils.createThriftFromBytes(body, message);
+ TBase event = null;
+ String gatewayId = null;
+ ProcessSubmitEvent processSubmitEvent = new ProcessSubmitEvent();
+ ThriftUtils.createThriftFromBytes(message.getEvent(), processSubmitEvent);
+ log.debug("Message received with message id : " + message.getMessageId()
+ + " with task id : " + processSubmitEvent.getTaskId());
+ event = processSubmitEvent;
+ MessageContext messageContext = new MessageContext(event, message.getMessageType(), message.getMessageId(), null);
+ messageContext.setUpdatedTime(AiravataUtils.getTime(message.getUpdatedTime()));
+ handler.onMessage(messageContext);
+ } catch (TException e) {
+ String msg = "Failed to de-serialize the thrift message, from routing keys and queueName " + finalQueueName;
+ log.warn(msg, e);
+ }
+ }
+ });
+ return "";
+ } catch (Exception e) {
+ String msg = "could not open channel for exchange default";
+ log.error(msg);
+ throw new AiravataException(msg, e);
+ }
+ }
+
+ public void stopListen(final String queueName , final String exchangeName) throws AiravataException {
+ try {
+ channel.queueUnbind(queueName, exchangeName, null);
+ } catch (IOException e) {
+ String msg = "could not un-bind queue: " + queueName + " for exchange " + exchangeName;
+ log.debug(msg);
+ }
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/airavata/blob/d25441a0/modules/messaging/core/src/main/java/org/apache/airavata/messaging/core/impl/RabbitMQProcessPublisher.java
----------------------------------------------------------------------
diff --git a/modules/messaging/core/src/main/java/org/apache/airavata/messaging/core/impl/RabbitMQProcessPublisher.java b/modules/messaging/core/src/main/java/org/apache/airavata/messaging/core/impl/RabbitMQProcessPublisher.java
new file mode 100644
index 0000000..3684198
--- /dev/null
+++ b/modules/messaging/core/src/main/java/org/apache/airavata/messaging/core/impl/RabbitMQProcessPublisher.java
@@ -0,0 +1,84 @@
+/*
+ *
+ * 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.messaging.core.impl;
+
+import org.apache.airavata.common.exception.AiravataException;
+import org.apache.airavata.common.exception.ApplicationSettingsException;
+import org.apache.airavata.common.utils.ServerSettings;
+import org.apache.airavata.common.utils.ThriftUtils;
+import org.apache.airavata.messaging.core.MessageContext;
+import org.apache.airavata.messaging.core.MessagingConstants;
+import org.apache.airavata.messaging.core.Publisher;
+import org.apache.airavata.model.messaging.event.Message;
+import org.apache.airavata.model.messaging.event.MessageType;
+import org.apache.thrift.TException;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+
+public class RabbitMQProcessPublisher implements Publisher {
+
+ private static final Logger log = LoggerFactory.getLogger(RabbitMQProcessPublisher.class);
+ public static final String PROCESS = "process.queue" ;
+
+ private RabbitMQProducer rabbitMQProducer;
+
+ public RabbitMQProcessPublisher() throws Exception {
+ String brokerUrl;
+ String exchangeName;
+ try {
+ brokerUrl = ServerSettings.getSetting(MessagingConstants.RABBITMQ_BROKER_URL);
+// exchangeName = ServerSettings.getSetting(MessagingConstants.RABBITMQ_STATUS_EXCHANGE_NAME);
+ } catch (ApplicationSettingsException e) {
+ String message = "Failed to get read the required properties from airavata to initialize rabbitmq";
+ log.error(message, e);
+ throw new AiravataException(message, e);
+ }
+ rabbitMQProducer = new RabbitMQProducer(brokerUrl, null, null);
+ rabbitMQProducer.open();
+ }
+
+ @Override
+ public void publish(MessageContext msgCtx) throws AiravataException {
+ try {
+ log.info("Publishing to process queue ...");
+ byte[] body = ThriftUtils.serializeThriftObject(msgCtx.getEvent());
+ Message message = new Message();
+ message.setEvent(body);
+ message.setMessageId(msgCtx.getMessageId());
+ message.setMessageType(msgCtx.getType());
+ message.setUpdatedTime(msgCtx.getUpdatedTime().getTime());
+ String queueName = PROCESS;
+ message.setMessageType(MessageType.TASK);
+ byte[] messageBody = ThriftUtils.serializeThriftObject(message);
+ rabbitMQProducer.sendToWorkerQueue(messageBody, queueName);
+ } catch (TException e) {
+ String msg = "Error while serializing the thrift object";
+ log.error(msg, e);
+ throw new AiravataException(msg, e);
+ } catch (Exception e) {
+ String msg = "Error while sending to rabbitmq";
+ log.error(msg, e);
+ throw new AiravataException(msg, e);
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/airavata/blob/d25441a0/modules/messaging/core/src/main/java/org/apache/airavata/messaging/core/impl/RabbitMQStatusConsumer.java
----------------------------------------------------------------------
diff --git a/modules/messaging/core/src/main/java/org/apache/airavata/messaging/core/impl/RabbitMQStatusConsumer.java b/modules/messaging/core/src/main/java/org/apache/airavata/messaging/core/impl/RabbitMQStatusConsumer.java
index d5e8c72..6efa77a 100644
--- a/modules/messaging/core/src/main/java/org/apache/airavata/messaging/core/impl/RabbitMQStatusConsumer.java
+++ b/modules/messaging/core/src/main/java/org/apache/airavata/messaging/core/impl/RabbitMQStatusConsumer.java
@@ -174,6 +174,12 @@ public class RabbitMQStatusConsumer implements Consumer {
taskStatusChangeEvent.getState());
event = taskStatusChangeEvent;
gatewayId = taskStatusChangeEvent.getTaskIdentity().getGatewayId();
+ }else if (message.getMessageType() == MessageType.TASKOUTPUT) {
+ TaskOutputChangeEvent taskOutputChangeEvent = new TaskOutputChangeEvent();
+ ThriftUtils.createThriftFromBytes(message.getEvent(), taskOutputChangeEvent);
+ log.debug(" Message Received with message id '" + message.getMessageId() + "' and with message type '" + message.getMessageType());
+ event = taskOutputChangeEvent;
+ gatewayId = taskOutputChangeEvent.getTaskIdentity().getGatewayId();
} else if (message.getMessageType().equals(MessageType.JOB)) {
JobStatusChangeEvent jobStatusChangeEvent = new JobStatusChangeEvent();
ThriftUtils.createThriftFromBytes(message.getEvent(), jobStatusChangeEvent);
@@ -182,7 +188,7 @@ public class RabbitMQStatusConsumer implements Consumer {
jobStatusChangeEvent.getState());
event = jobStatusChangeEvent;
gatewayId = jobStatusChangeEvent.getJobIdentity().getGatewayId();
- }else if(message.getMessageType().equals(MessageType.LAUNCHTASK)) {
+ } else if (message.getMessageType().equals(MessageType.LAUNCHTASK)) {
TaskSubmitEvent taskSubmitEvent = new TaskSubmitEvent();
ThriftUtils.createThriftFromBytes(message.getEvent(), taskSubmitEvent);
log.debug(" Message Received with message id '" + message.getMessageId()
@@ -190,7 +196,7 @@ public class RabbitMQStatusConsumer implements Consumer {
taskSubmitEvent.getExperimentId() + "and taskId: " + taskSubmitEvent.getTaskId());
event = taskSubmitEvent;
gatewayId = taskSubmitEvent.getGatewayId();
- }else if(message.getMessageType().equals(MessageType.TERMINATETASK)) {
+ } else if (message.getMessageType().equals(MessageType.TERMINATETASK)) {
TaskTerminateEvent taskTerminateEvent = new TaskTerminateEvent();
ThriftUtils.createThriftFromBytes(message.getEvent(), taskTerminateEvent);
log.debug(" Message Received with message id '" + message.getMessageId()
http://git-wip-us.apache.org/repos/asf/airavata/blob/d25441a0/modules/messaging/core/src/main/java/org/apache/airavata/messaging/core/impl/RabbitMQStatusPublisher.java
----------------------------------------------------------------------
diff --git a/modules/messaging/core/src/main/java/org/apache/airavata/messaging/core/impl/RabbitMQStatusPublisher.java b/modules/messaging/core/src/main/java/org/apache/airavata/messaging/core/impl/RabbitMQStatusPublisher.java
index 966d44d..a149037 100644
--- a/modules/messaging/core/src/main/java/org/apache/airavata/messaging/core/impl/RabbitMQStatusPublisher.java
+++ b/modules/messaging/core/src/main/java/org/apache/airavata/messaging/core/impl/RabbitMQStatusPublisher.java
@@ -68,21 +68,25 @@ public class RabbitMQStatusPublisher implements Publisher {
message.setUpdatedTime(msgCtx.getUpdatedTime().getTime());
String gatewayId = msgCtx.getGatewayId();
String routingKey = null;
- if (msgCtx.getType().equals(MessageType.EXPERIMENT)){
+ if (msgCtx.getType() == MessageType.EXPERIMENT) {
ExperimentStatusChangeEvent event = (ExperimentStatusChangeEvent) msgCtx.getEvent();
routingKey = gatewayId + "." + event.getExperimentId();
- } else if (msgCtx.getType().equals(MessageType.TASK)) {
+ } else if (msgCtx.getType() == MessageType.TASK) {
TaskStatusChangeEvent event = (TaskStatusChangeEvent) msgCtx.getEvent();
- routingKey = gatewayId + "." + event.getTaskIdentity().getExperimentId() + "." +
+ routingKey = gatewayId + "." + event.getTaskIdentity().getExperimentId() + "." +
event.getTaskIdentity().getWorkflowNodeId() + "." + event.getTaskIdentity().getTaskId();
- }else if (msgCtx.getType().equals(MessageType.WORKFLOWNODE)){
+ } else if (msgCtx.getType() == MessageType.TASKOUTPUT) {
+ TaskOutputChangeEvent event = (TaskOutputChangeEvent) msgCtx.getEvent();
+ routingKey = gatewayId + "." + event.getTaskIdentity().getExperimentId() + "." +
+ event.getTaskIdentity().getWorkflowNodeId() + "." + event.getTaskIdentity().getTaskId();
+ } else if (msgCtx.getType() == MessageType.WORKFLOWNODE) {
WorkflowNodeStatusChangeEvent event = (WorkflowNodeStatusChangeEvent) msgCtx.getEvent();
WorkflowIdentifier workflowNodeIdentity = event.getWorkflowNodeIdentity();
- routingKey = gatewayId + "." + workflowNodeIdentity.getExperimentId() + "." + workflowNodeIdentity.getWorkflowNodeId();
- }else if (msgCtx.getType().equals(MessageType.JOB)){
- JobStatusChangeEvent event = (JobStatusChangeEvent)msgCtx.getEvent();
+ routingKey = gatewayId + "." + workflowNodeIdentity.getExperimentId() + "." + workflowNodeIdentity.getWorkflowNodeId();
+ } else if (msgCtx.getType() == MessageType.JOB) {
+ JobStatusChangeEvent event = (JobStatusChangeEvent) msgCtx.getEvent();
JobIdentifier identity = event.getJobIdentity();
- routingKey = gatewayId + "." + identity.getExperimentId() + "." +
+ routingKey = gatewayId + "." + identity.getExperimentId() + "." +
identity.getWorkflowNodeId() + "." +
identity.getTaskId() + "." +
identity.getJobId();
http://git-wip-us.apache.org/repos/asf/airavata/blob/d25441a0/modules/orchestrator/airavata-orchestrator-service/src/main/java/org/apache/airavata/orchestrator/server/OrchestratorServerHandler.java
----------------------------------------------------------------------
diff --git a/modules/orchestrator/airavata-orchestrator-service/src/main/java/org/apache/airavata/orchestrator/server/OrchestratorServerHandler.java b/modules/orchestrator/airavata-orchestrator-service/src/main/java/org/apache/airavata/orchestrator/server/OrchestratorServerHandler.java
index e873e05..a4e105e 100644
--- a/modules/orchestrator/airavata-orchestrator-service/src/main/java/org/apache/airavata/orchestrator/server/OrchestratorServerHandler.java
+++ b/modules/orchestrator/airavata-orchestrator-service/src/main/java/org/apache/airavata/orchestrator/server/OrchestratorServerHandler.java
@@ -38,14 +38,19 @@ import org.apache.airavata.credential.store.store.CredentialReader;
import org.apache.airavata.gfac.core.scheduler.HostScheduler;
import org.apache.airavata.gfac.core.utils.GFacUtils;
import org.apache.airavata.messaging.core.MessageContext;
+import org.apache.airavata.messaging.core.MessageHandler;
+import org.apache.airavata.messaging.core.MessagingConstants;
import org.apache.airavata.messaging.core.Publisher;
import org.apache.airavata.messaging.core.PublisherFactory;
+import org.apache.airavata.messaging.core.impl.RabbitMQProcessConsumer;
+import org.apache.airavata.messaging.core.impl.RabbitMQProcessPublisher;
import org.apache.airavata.model.appcatalog.appdeployment.ApplicationDeploymentDescription;
import org.apache.airavata.model.appcatalog.appinterface.ApplicationInterfaceDescription;
import org.apache.airavata.model.appcatalog.computeresource.ComputeResourceDescription;
import org.apache.airavata.model.error.LaunchValidationException;
import org.apache.airavata.model.messaging.event.ExperimentStatusChangeEvent;
import org.apache.airavata.model.messaging.event.MessageType;
+import org.apache.airavata.model.messaging.event.ProcessSubmitEvent;
import org.apache.airavata.model.util.ExecutionType;
import org.apache.airavata.model.workspace.experiment.*;
import org.apache.airavata.orchestrator.core.exception.OrchestratorException;
@@ -61,6 +66,7 @@ import org.apache.airavata.registry.cpi.utils.Constants.FieldConstants.TaskDetai
import org.apache.airavata.registry.cpi.utils.Constants.FieldConstants.WorkflowNodeConstants;
import org.apache.airavata.orchestrator.util.DataModelUtils;
import org.apache.airavata.simple.workflow.engine.SimpleWorkflowInterpreter;
+import org.apache.thrift.TBase;
import org.apache.thrift.TException;
import org.apache.zookeeper.*;
import org.apache.zookeeper.data.Stat;
@@ -86,7 +92,10 @@ public class OrchestratorServerHandler implements OrchestratorService.Iface,
private String gatewayName;
private Publisher publisher;
- /**
+ private RabbitMQProcessConsumer rabbitMQProcessConsumer;
+ private RabbitMQProcessPublisher rabbitMQProcessPublisher;
+
+ /**
* Query orchestrator server to fetch the CPI version
*/
public String getOrchestratorCPIVersion() throws TException {
@@ -152,7 +161,8 @@ public class OrchestratorServerHandler implements OrchestratorService.Iface,
orchestrator.initialize();
orchestrator.getOrchestratorContext().setZk(this.zk);
orchestrator.getOrchestratorContext().setPublisher(this.publisher);
- } catch (OrchestratorException e) {
+ startProcessConsumer();
+ } catch (OrchestratorException e) {
log.error(e.getMessage(), e);
throw new OrchestratorException("Error while initializing orchestrator service", e);
} catch (RegistryException e) {
@@ -161,6 +171,19 @@ public class OrchestratorServerHandler implements OrchestratorService.Iface,
}
}
+ private void startProcessConsumer() throws OrchestratorException {
+ try {
+ rabbitMQProcessConsumer = new RabbitMQProcessConsumer();
+ ProcessConsumer processConsumer = new ProcessConsumer();
+ Thread thread = new Thread(processConsumer);
+ thread.start();
+
+ } catch (AiravataException e) {
+ throw new OrchestratorException("Error while starting process consumer", e);
+ }
+
+ }
+
private void registerOrchestratorService(String airavataServerHostPort, String orchServer) throws KeeperException, InterruptedException {
Stat zkStat = zk.exists(orchServer, false);
if (zkStat == null) {
@@ -627,6 +650,7 @@ public class OrchestratorServerHandler implements OrchestratorService.Iface,
}
return true;
}
+
private void launchWorkflowExperiment(String experimentId, String airavataCredStoreToken) throws TException {
// try {
// WorkflowEngine workflowEngine = WorkflowEngineFactory.getWorkflowEngine();
@@ -634,15 +658,25 @@ public class OrchestratorServerHandler implements OrchestratorService.Iface,
// } catch (WorkflowEngineException e) {
// log.errorId(experimentId, "Error while launching experiment.", e);
// }
-
try {
- SimpleWorkflowInterpreter simpleWorkflowInterpreter = new SimpleWorkflowInterpreter(experimentId, airavataCredStoreToken);
+ SimpleWorkflowInterpreter simpleWorkflowInterpreter = new SimpleWorkflowInterpreter(
+ experimentId, airavataCredStoreToken,getGatewayName(), getRabbitMQProcessPublisher());
+
Thread thread = new Thread(simpleWorkflowInterpreter);
thread.start();
// simpleWorkflowInterpreter.run();
} catch (RegistryException e) {
log.error("Error while launching workflow", e);
+ } catch (Exception e) {
+ log.error("Error while initializing rabbit mq process publisher");
+ }
+ }
+
+ public synchronized RabbitMQProcessPublisher getRabbitMQProcessPublisher() throws Exception {
+ if (rabbitMQProcessPublisher == null) {
+ rabbitMQProcessPublisher = new RabbitMQProcessPublisher();
}
+ return rabbitMQProcessPublisher;
}
@@ -732,4 +766,38 @@ public class OrchestratorServerHandler implements OrchestratorService.Iface,
}
}
+ private class ProcessConsumer implements Runnable, MessageHandler{
+
+
+ @Override
+ public void run() {
+ try {
+ rabbitMQProcessConsumer.listen(this);
+ } catch (AiravataException e) {
+ log.error("Error while listen to the RabbitMQProcessConsumer");
+ }
+ }
+
+ @Override
+ public Map<String, Object> getProperties() {
+ Map<String, Object> props = new HashMap<String, Object>();
+ props.put(MessagingConstants.RABBIT_QUEUE, RabbitMQProcessPublisher.PROCESS);
+ props.put(MessagingConstants.RABBIT_ROUTING_KEY, RabbitMQProcessPublisher.PROCESS);
+ return props;
+ }
+
+ @Override
+ public void onMessage(MessageContext msgCtx) {
+ TBase event = msgCtx.getEvent();
+ if (event instanceof ProcessSubmitEvent) {
+ ProcessSubmitEvent processSubmitEvent = (ProcessSubmitEvent) event;
+ try {
+ launchTask(processSubmitEvent.getTaskId(), processSubmitEvent.getCredentialToken());
+ } catch (TException e) {
+ log.error("Error while launching task : " + processSubmitEvent.getTaskId());
+ }
+ }
+ }
+ }
+
}
http://git-wip-us.apache.org/repos/asf/airavata/blob/d25441a0/modules/simple-workflow/pom.xml
----------------------------------------------------------------------
diff --git a/modules/simple-workflow/pom.xml b/modules/simple-workflow/pom.xml
index 6b36335..5cb9dfb 100644
--- a/modules/simple-workflow/pom.xml
+++ b/modules/simple-workflow/pom.xml
@@ -48,6 +48,11 @@
</dependency>
<!-- Messaging dependency -->
<dependency>
+ <groupId>org.apache.airavata</groupId>
+ <artifactId>airavata-messaging-core</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+ <dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
<version>18.0</version>
http://git-wip-us.apache.org/repos/asf/airavata/blob/d25441a0/modules/simple-workflow/src/main/java/org/apache/airavata/simple/workflow/engine/ProcessContext.java
----------------------------------------------------------------------
diff --git a/modules/simple-workflow/src/main/java/org/apache/airavata/simple/workflow/engine/ProcessContext.java b/modules/simple-workflow/src/main/java/org/apache/airavata/simple/workflow/engine/ProcessContext.java
new file mode 100644
index 0000000..849af85
--- /dev/null
+++ b/modules/simple-workflow/src/main/java/org/apache/airavata/simple/workflow/engine/ProcessContext.java
@@ -0,0 +1,62 @@
+/*
+ *
+ * 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.simple.workflow.engine;
+
+import org.apache.airavata.model.workspace.experiment.TaskDetails;
+import org.apache.airavata.model.workspace.experiment.WorkflowNodeDetails;
+import org.apache.airavata.simple.workflow.engine.dag.nodes.WorkflowNode;
+
+public class ProcessContext {
+ private WorkflowNode workflowNode;
+ private WorkflowNodeDetails wfNodeDetails;
+ private TaskDetails taskDetails;
+
+ public ProcessContext(WorkflowNode workflowNode, WorkflowNodeDetails wfNodeDetails, TaskDetails taskDetails) {
+ this.workflowNode = workflowNode;
+ this.wfNodeDetails = wfNodeDetails;
+ this.taskDetails = taskDetails;
+ }
+
+ public WorkflowNode getWorkflowNode() {
+ return workflowNode;
+ }
+
+ public void setWorkflowNode(WorkflowNode workflowNode) {
+ this.workflowNode = workflowNode;
+ }
+
+ public WorkflowNodeDetails getWfNodeDetails() {
+ return wfNodeDetails;
+ }
+
+ public void setWfNodeDetails(WorkflowNodeDetails wfNodeDetails) {
+ this.wfNodeDetails = wfNodeDetails;
+ }
+
+ public TaskDetails getTaskDetails() {
+ return taskDetails;
+ }
+
+ public void setTaskDetails(TaskDetails taskDetails) {
+ this.taskDetails = taskDetails;
+ }
+}
http://git-wip-us.apache.org/repos/asf/airavata/blob/d25441a0/modules/simple-workflow/src/main/java/org/apache/airavata/simple/workflow/engine/ProcessPack.java
----------------------------------------------------------------------
diff --git a/modules/simple-workflow/src/main/java/org/apache/airavata/simple/workflow/engine/ProcessPack.java b/modules/simple-workflow/src/main/java/org/apache/airavata/simple/workflow/engine/ProcessPack.java
deleted file mode 100644
index b58b947..0000000
--- a/modules/simple-workflow/src/main/java/org/apache/airavata/simple/workflow/engine/ProcessPack.java
+++ /dev/null
@@ -1,62 +0,0 @@
-/*
- *
- * 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.simple.workflow.engine;
-
-import org.apache.airavata.model.workspace.experiment.TaskDetails;
-import org.apache.airavata.model.workspace.experiment.WorkflowNodeDetails;
-import org.apache.airavata.simple.workflow.engine.dag.nodes.WorkflowNode;
-
-public class ProcessPack {
- private WorkflowNode workflowNode;
- private WorkflowNodeDetails wfNodeDetails;
- private TaskDetails taskDetails;
-
- public ProcessPack(WorkflowNode workflowNode, WorkflowNodeDetails wfNodeDetails, TaskDetails taskDetails) {
- this.workflowNode = workflowNode;
- this.wfNodeDetails = wfNodeDetails;
- this.taskDetails = taskDetails;
- }
-
- public WorkflowNode getWorkflowNode() {
- return workflowNode;
- }
-
- public void setWorkflowNode(WorkflowNode workflowNode) {
- this.workflowNode = workflowNode;
- }
-
- public WorkflowNodeDetails getWfNodeDetails() {
- return wfNodeDetails;
- }
-
- public void setWfNodeDetails(WorkflowNodeDetails wfNodeDetails) {
- this.wfNodeDetails = wfNodeDetails;
- }
-
- public TaskDetails getTaskDetails() {
- return taskDetails;
- }
-
- public void setTaskDetails(TaskDetails taskDetails) {
- this.taskDetails = taskDetails;
- }
-}
[15/50] [abbrv] airavata git commit: Renamed the wrong package name
Posted by sh...@apache.org.
http://git-wip-us.apache.org/repos/asf/airavata/blob/6bfb9563/modules/simple-workflow/src/main/java/org/apache/airavata/simple/workflow/engine/parser/AiravataDefaultParser.java
----------------------------------------------------------------------
diff --git a/modules/simple-workflow/src/main/java/org/apache/airavata/simple/workflow/engine/parser/AiravataDefaultParser.java b/modules/simple-workflow/src/main/java/org/apache/airavata/simple/workflow/engine/parser/AiravataDefaultParser.java
new file mode 100644
index 0000000..644eda6
--- /dev/null
+++ b/modules/simple-workflow/src/main/java/org/apache/airavata/simple/workflow/engine/parser/AiravataDefaultParser.java
@@ -0,0 +1,293 @@
+/*
+ *
+ * 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.simple.workflow.engine.parser;
+
+import org.airavata.appcatalog.cpi.AppCatalogException;
+import org.airavata.appcatalog.cpi.WorkflowCatalog;
+import org.apache.aiaravata.application.catalog.data.impl.AppCatalogFactory;
+import org.apache.airavata.model.appcatalog.appinterface.InputDataObjectType;
+import org.apache.airavata.model.appcatalog.appinterface.OutputDataObjectType;
+import org.apache.airavata.model.workspace.experiment.Experiment;
+import org.apache.airavata.persistance.registry.jpa.impl.RegistryFactory;
+import org.apache.airavata.registry.cpi.Registry;
+import org.apache.airavata.registry.cpi.RegistryException;
+import org.apache.airavata.registry.cpi.RegistryModelType;
+import org.apache.airavata.simple.workflow.engine.dag.nodes.ApplicationNodeImpl;
+import org.apache.airavata.simple.workflow.engine.dag.nodes.WorkflowInputNode;
+import org.apache.airavata.simple.workflow.engine.dag.nodes.WorkflowInputNodeImpl;
+import org.apache.airavata.simple.workflow.engine.dag.port.OutPortImpl;
+import org.apache.airavata.workflow.model.component.ComponentException;
+import org.apache.airavata.workflow.model.component.system.ConstantComponent;
+import org.apache.airavata.workflow.model.component.system.InputComponent;
+import org.apache.airavata.workflow.model.component.system.S3InputComponent;
+import org.apache.airavata.workflow.model.graph.DataEdge;
+import org.apache.airavata.workflow.model.graph.DataPort;
+import org.apache.airavata.workflow.model.graph.GraphException;
+import org.apache.airavata.workflow.model.graph.Node;
+import org.apache.airavata.workflow.model.graph.impl.NodeImpl;
+import org.apache.airavata.workflow.model.graph.system.OutputNode;
+import org.apache.airavata.workflow.model.graph.system.SystemDataPort;
+import org.apache.airavata.workflow.model.graph.ws.WSNode;
+import org.apache.airavata.workflow.model.graph.ws.WSPort;
+import org.apache.airavata.workflow.model.wf.Workflow;
+import org.apache.airavata.simple.workflow.engine.WorkflowParser;
+import org.apache.airavata.simple.workflow.engine.dag.edge.DirectedEdge;
+import org.apache.airavata.simple.workflow.engine.dag.edge.Edge;
+import org.apache.airavata.simple.workflow.engine.dag.nodes.ApplicationNode;
+import org.apache.airavata.simple.workflow.engine.dag.nodes.WorkflowNode;
+import org.apache.airavata.simple.workflow.engine.dag.nodes.WorkflowOutputNode;
+import org.apache.airavata.simple.workflow.engine.dag.nodes.WorkflowOutputNodeImpl;
+import org.apache.airavata.simple.workflow.engine.dag.port.InPort;
+import org.apache.airavata.simple.workflow.engine.dag.port.InputPortIml;
+import org.apache.airavata.simple.workflow.engine.dag.port.OutPort;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+public class AiravataDefaultParser implements WorkflowParser {
+
+ private String credentialToken ;
+ private Workflow workflow;
+
+
+ private Experiment experiment;
+ private Map<String, WorkflowNode> wfNodes = new HashMap<String, WorkflowNode>();
+
+
+ public AiravataDefaultParser(String experimentId, String credentialToken) throws RegistryException {
+ this.experiment = getExperiment(experimentId);
+ this.credentialToken = credentialToken;
+ }
+
+ public AiravataDefaultParser(Experiment experiment, String credentialToken) {
+ this.credentialToken = credentialToken;
+ this.experiment = experiment;
+ }
+
+ @Override
+ public List<WorkflowInputNode> parse() throws RegistryException, AppCatalogException,
+ ComponentException, GraphException {
+ return parseWorkflow(getWorkflowFromExperiment(experiment));
+ }
+
+ public List<WorkflowInputNode> parseWorkflow(Workflow workflow) {
+ List<Node> gNodes = getInputNodes(workflow);
+ List<WorkflowInputNode> wfInputNodes = new ArrayList<WorkflowInputNode>();
+ List<PortContainer> portContainers = new ArrayList<PortContainer>();
+ List<InputDataObjectType> experimentInputs = experiment.getExperimentInputs();
+ Map<String,InputDataObjectType> inputDataMap=new HashMap<String, InputDataObjectType>();
+ WorkflowInputNode wfInputNode = null;
+ for (InputDataObjectType dataObjectType : experimentInputs) {
+ inputDataMap.put(dataObjectType.getName(), dataObjectType);
+ }
+ for (Node gNode : gNodes) {
+ wfInputNode = new WorkflowInputNodeImpl(gNode.getID(), gNode.getName());
+ wfInputNode.setInputObject(inputDataMap.get(wfInputNode.getName()));
+ if (wfInputNode.getInputObject() == null) {
+ // TODO: throw an error and exit.
+ }
+ portContainers.addAll(processOutPorts(gNode, wfInputNode));
+ wfInputNodes.add(wfInputNode);
+ }
+
+ // while port container is not empty iterate graph and build the workflow DAG.
+ buildModel(portContainers);
+
+ return wfInputNodes;
+ }
+
+ private void buildModel(List<PortContainer> portContainerList) {
+ // end condition of recursive call.
+ if (portContainerList == null || portContainerList.isEmpty()) {
+ return ;
+ }
+ DataPort dataPort = null;
+ InPort inPort = null;
+ ApplicationNode wfApplicationNode = null;
+ WorkflowOutputNode wfOutputNode = null;
+ List<PortContainer> nextPortContainerList = new ArrayList<PortContainer>();
+ for (PortContainer portContainer : portContainerList) {
+ dataPort = portContainer.getDataPort();
+ inPort = portContainer.getInPort();
+ Node node = dataPort.getNode();
+ if (node instanceof WSNode) {
+ WSNode wsNode = (WSNode) node;
+ WorkflowNode wfNode = wfNodes.get(wsNode.getID());
+ if (wfNode == null) {
+ wfApplicationNode = createApplicationNode(wsNode);
+ wfNodes.put(wfApplicationNode.getId(), wfApplicationNode);
+ nextPortContainerList.addAll(processOutPorts(wsNode, wfApplicationNode));
+ } else if (wfNode instanceof ApplicationNode) {
+ wfApplicationNode = (ApplicationNode) wfNode;
+ } else {
+ // TODO : handle this scenario
+ }
+ inPort.setNode(wfApplicationNode);
+ wfApplicationNode.addInPort(inPort);
+
+ }else if (node instanceof OutputNode) {
+ OutputNode oNode = (OutputNode) node;
+ wfOutputNode = createWorkflowOutputNode(oNode);
+ wfOutputNode.setInPort(inPort);
+ inPort.setNode(wfOutputNode);
+ wfNodes.put(wfOutputNode.getId(), wfOutputNode);
+ }
+ }
+ buildModel(nextPortContainerList);
+
+ }
+
+ private WorkflowOutputNode createWorkflowOutputNode(OutputNode oNode) {
+ WorkflowOutputNodeImpl workflowOutputNode = new WorkflowOutputNodeImpl(oNode.getID(), oNode.getName());
+ OutputDataObjectType outputDataObjectType = new OutputDataObjectType();
+ outputDataObjectType.setType(oNode.getParameterType());
+ workflowOutputNode.setOutputObject(outputDataObjectType);
+ return workflowOutputNode;
+ }
+
+ private ApplicationNode createApplicationNode(WSNode wsNode) {
+ ApplicationNode applicationNode = new ApplicationNodeImpl(wsNode.getID(),
+ wsNode.getComponent().getApplication().getName(),
+ wsNode.getComponent().getApplication().getApplicationId());
+ return applicationNode;
+ }
+
+ private List<PortContainer> processOutPorts(Node node, WorkflowNode wfNode) {
+ OutPort outPort ;
+ Edge edge;
+ InPort inPort = null;
+ List<PortContainer> portContainers = new ArrayList<PortContainer>();
+ for (DataPort dataPort : node.getOutputPorts()) {
+ outPort = createOutPort(dataPort);
+ for (DataEdge dataEdge : dataPort.getEdges()) {
+ edge = new DirectedEdge();
+ edge.setFromPort(outPort);
+ outPort.addEdge(edge);
+ inPort = createInPort(dataEdge.getToPort());
+ edge.setToPort(inPort);
+ inPort.addEdge(edge);
+ portContainers.add(new PortContainer(dataEdge.getToPort(), inPort));
+ }
+ outPort.setNode(wfNode);
+ if (wfNode instanceof WorkflowInputNode) {
+ WorkflowInputNode workflowInputNode = (WorkflowInputNode) wfNode;
+ workflowInputNode.setOutPort(outPort);
+ } else if (wfNode instanceof ApplicationNode) {
+ ApplicationNode applicationNode = ((ApplicationNode) wfNode);
+ applicationNode.addOutPort(outPort);
+ }
+ }
+ return portContainers;
+ }
+
+ private OutPort createOutPort(DataPort dataPort) {
+ OutPortImpl outPort = new OutPortImpl(dataPort.getID());
+ OutputDataObjectType outputDataObjectType = new OutputDataObjectType();
+ if (dataPort instanceof WSPort) {
+ WSPort wsPort = (WSPort) dataPort;
+ outputDataObjectType.setName(wsPort.getFromNode().getName());
+ outputDataObjectType.setType(wsPort.getType());
+ }else if (dataPort instanceof SystemDataPort) {
+ SystemDataPort sysPort = (SystemDataPort) dataPort;
+ outputDataObjectType.setName(sysPort.getFromNode().getName());
+ outputDataObjectType.setType(sysPort.getType());
+ }
+
+ outPort.setOutputObject(outputDataObjectType);
+ return outPort;
+ }
+
+ private InPort createInPort(DataPort toPort) {
+ InPort inPort = new InputPortIml(toPort.getID());
+ InputDataObjectType inputDataObjectType = new InputDataObjectType();
+ if (toPort instanceof WSPort) {
+ WSPort wsPort = (WSPort) toPort;
+ inputDataObjectType.setName(wsPort.getName());
+ inputDataObjectType.setType(wsPort.getType());
+ inputDataObjectType.setApplicationArgument(wsPort.getComponentPort().getApplicationArgument());
+ inputDataObjectType.setIsRequired(!wsPort.getComponentPort().isOptional());
+ inputDataObjectType.setInputOrder(wsPort.getComponentPort().getInputOrder());
+
+ inPort.setDefaultValue(wsPort.getComponentPort().getDefaultValue());
+ }else if (toPort instanceof SystemDataPort) {
+ SystemDataPort sysPort = (SystemDataPort) toPort;
+ inputDataObjectType.setName(sysPort.getName());
+ inputDataObjectType.setType(sysPort.getType());
+ }
+ inPort.setInputObject(inputDataObjectType);
+ return inPort;
+ }
+
+ private InputDataObjectType getInputDataObject(DataPort dataPort) {
+ InputDataObjectType inputDataObject = new InputDataObjectType();
+ inputDataObject.setName(dataPort.getName());
+ if (dataPort instanceof WSPort) {
+ WSPort port = (WSPort) dataPort;
+ inputDataObject.setInputOrder(port.getComponentPort().getInputOrder());
+ inputDataObject.setApplicationArgument(port.getComponentPort().getApplicationArgument() == null ?
+ "" : port.getComponentPort().getApplicationArgument());
+ inputDataObject.setType(dataPort.getType());
+ }
+ return inputDataObject;
+ }
+
+ private OutputDataObjectType getOutputDataObject(InputDataObjectType inputObject) {
+ OutputDataObjectType outputDataObjectType = new OutputDataObjectType();
+ outputDataObjectType.setApplicationArgument(inputObject.getApplicationArgument());
+ outputDataObjectType.setName(inputObject.getName());
+ outputDataObjectType.setType(inputObject.getType());
+ outputDataObjectType.setValue(inputObject.getValue());
+ return outputDataObjectType;
+ }
+
+ private Experiment getExperiment(String experimentId) throws RegistryException {
+ Registry registry = RegistryFactory.getDefaultRegistry();
+ return (Experiment)registry.get(RegistryModelType.EXPERIMENT, experimentId);
+ }
+
+ private Workflow getWorkflowFromExperiment(Experiment experiment) throws RegistryException, AppCatalogException, GraphException, ComponentException {
+ WorkflowCatalog workflowCatalog = getWorkflowCatalog();
+ return new Workflow(workflowCatalog.getWorkflow(experiment.getApplicationId()).getGraph());
+ }
+
+ private WorkflowCatalog getWorkflowCatalog() throws AppCatalogException {
+ return AppCatalogFactory.getAppCatalog().getWorkflowCatalog();
+ }
+
+ private ArrayList<Node> getInputNodes(Workflow wf) {
+ ArrayList<Node> list = new ArrayList<Node>();
+ List<NodeImpl> nodes = wf.getGraph().getNodes();
+ for (Node node : nodes) {
+ String name = node.getComponent().getName();
+ if (InputComponent.NAME.equals(name) || ConstantComponent.NAME.equals(name) || S3InputComponent.NAME.equals(name)) {
+ list.add(node);
+ }
+ }
+ return list;
+ }
+
+ public Map<String, WorkflowNode> getWfNodes() {
+ return wfNodes;
+ }
+}
http://git-wip-us.apache.org/repos/asf/airavata/blob/6bfb9563/modules/simple-workflow/src/main/java/org/apache/airavata/simple/workflow/engine/parser/PortContainer.java
----------------------------------------------------------------------
diff --git a/modules/simple-workflow/src/main/java/org/apache/airavata/simple/workflow/engine/parser/PortContainer.java b/modules/simple-workflow/src/main/java/org/apache/airavata/simple/workflow/engine/parser/PortContainer.java
new file mode 100644
index 0000000..db3dda5
--- /dev/null
+++ b/modules/simple-workflow/src/main/java/org/apache/airavata/simple/workflow/engine/parser/PortContainer.java
@@ -0,0 +1,53 @@
+/*
+ *
+ * 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.simple.workflow.engine.parser;
+
+import org.apache.airavata.workflow.model.graph.DataPort;
+import org.apache.airavata.simple.workflow.engine.dag.port.InPort;
+
+
+public class PortContainer {
+ private DataPort dataPort;
+ private InPort inPort;
+
+
+ public PortContainer(DataPort dataPort, InPort inPort) {
+ this.dataPort = dataPort;
+ this.inPort = inPort;
+ }
+
+ public DataPort getDataPort() {
+ return dataPort;
+ }
+
+ public void setDataPort(DataPort dataPort) {
+ this.dataPort = dataPort;
+ }
+
+ public InPort getInPort() {
+ return inPort;
+ }
+
+ public void setInPort(InPort inPort) {
+ this.inPort = inPort;
+ }
+}
http://git-wip-us.apache.org/repos/asf/airavata/blob/6bfb9563/modules/simple-workflow/src/main/java/org/apache/ariavata/simple/workflow/engine/ProcessPack.java
----------------------------------------------------------------------
diff --git a/modules/simple-workflow/src/main/java/org/apache/ariavata/simple/workflow/engine/ProcessPack.java b/modules/simple-workflow/src/main/java/org/apache/ariavata/simple/workflow/engine/ProcessPack.java
deleted file mode 100644
index ab8b724..0000000
--- a/modules/simple-workflow/src/main/java/org/apache/ariavata/simple/workflow/engine/ProcessPack.java
+++ /dev/null
@@ -1,62 +0,0 @@
-/*
- *
- * 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.ariavata.simple.workflow.engine;
-
-import org.apache.airavata.model.workspace.experiment.TaskDetails;
-import org.apache.airavata.model.workspace.experiment.WorkflowNodeDetails;
-import org.apache.ariavata.simple.workflow.engine.dag.nodes.WorkflowNode;
-
-public class ProcessPack {
- private WorkflowNode workflowNode;
- private WorkflowNodeDetails wfNodeDetails;
- private TaskDetails taskDetails;
-
- public ProcessPack(WorkflowNode workflowNode, WorkflowNodeDetails wfNodeDetails, TaskDetails taskDetails) {
- this.workflowNode = workflowNode;
- this.wfNodeDetails = wfNodeDetails;
- this.taskDetails = taskDetails;
- }
-
- public WorkflowNode getWorkflowNode() {
- return workflowNode;
- }
-
- public void setWorkflowNode(WorkflowNode workflowNode) {
- this.workflowNode = workflowNode;
- }
-
- public WorkflowNodeDetails getWfNodeDetails() {
- return wfNodeDetails;
- }
-
- public void setWfNodeDetails(WorkflowNodeDetails wfNodeDetails) {
- this.wfNodeDetails = wfNodeDetails;
- }
-
- public TaskDetails getTaskDetails() {
- return taskDetails;
- }
-
- public void setTaskDetails(TaskDetails taskDetails) {
- this.taskDetails = taskDetails;
- }
-}
http://git-wip-us.apache.org/repos/asf/airavata/blob/6bfb9563/modules/simple-workflow/src/main/java/org/apache/ariavata/simple/workflow/engine/SimpleWorkflowInterpreter.java
----------------------------------------------------------------------
diff --git a/modules/simple-workflow/src/main/java/org/apache/ariavata/simple/workflow/engine/SimpleWorkflowInterpreter.java b/modules/simple-workflow/src/main/java/org/apache/ariavata/simple/workflow/engine/SimpleWorkflowInterpreter.java
deleted file mode 100644
index 93b3bc0..0000000
--- a/modules/simple-workflow/src/main/java/org/apache/ariavata/simple/workflow/engine/SimpleWorkflowInterpreter.java
+++ /dev/null
@@ -1,470 +0,0 @@
-/*
- *
- * 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.ariavata.simple.workflow.engine;
-
-import com.google.common.eventbus.EventBus;
-import com.google.common.eventbus.Subscribe;
-import org.apache.airavata.model.appcatalog.appinterface.InputDataObjectType;
-import org.apache.airavata.model.appcatalog.appinterface.OutputDataObjectType;
-import org.apache.airavata.model.messaging.event.TaskIdentifier;
-import org.apache.airavata.model.messaging.event.TaskOutputChangeEvent;
-import org.apache.airavata.model.messaging.event.TaskStatusChangeEvent;
-import org.apache.airavata.model.util.ExperimentModelUtil;
-import org.apache.airavata.model.workspace.experiment.ExecutionUnit;
-import org.apache.airavata.model.workspace.experiment.Experiment;
-import org.apache.airavata.model.workspace.experiment.TaskDetails;
-import org.apache.airavata.model.workspace.experiment.TaskState;
-import org.apache.airavata.model.workspace.experiment.WorkflowNodeDetails;
-import org.apache.airavata.model.workspace.experiment.WorkflowNodeState;
-import org.apache.airavata.model.workspace.experiment.WorkflowNodeStatus;
-import org.apache.airavata.persistance.registry.jpa.impl.RegistryFactory;
-import org.apache.airavata.registry.cpi.ChildDataType;
-import org.apache.airavata.registry.cpi.Registry;
-import org.apache.airavata.registry.cpi.RegistryException;
-import org.apache.airavata.registry.cpi.RegistryModelType;
-import org.apache.ariavata.simple.workflow.engine.dag.edge.Edge;
-import org.apache.ariavata.simple.workflow.engine.dag.nodes.ApplicationNode;
-import org.apache.ariavata.simple.workflow.engine.dag.nodes.NodeState;
-import org.apache.ariavata.simple.workflow.engine.dag.nodes.WorkflowInputNode;
-import org.apache.ariavata.simple.workflow.engine.dag.nodes.WorkflowNode;
-import org.apache.ariavata.simple.workflow.engine.dag.nodes.WorkflowOutputNode;
-import org.apache.ariavata.simple.workflow.engine.dag.port.InPort;
-import org.apache.ariavata.simple.workflow.engine.dag.port.OutPort;
-import org.apache.ariavata.simple.workflow.engine.parser.AiravataDefaultParser;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-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 java.util.concurrent.ConcurrentHashMap;
-
-public class SimpleWorkflowInterpreter implements Runnable{
-
- private static final Logger log = LoggerFactory.getLogger(SimpleWorkflowInterpreter.class);
-
- private List<WorkflowInputNode> workflowInputNodes;
-
- private Experiment experiment;
-
- private String credentialToken;
-
- private Map<String, WorkflowNode> readList = new ConcurrentHashMap<String, WorkflowNode>();
- private Map<String, WorkflowNode> waitingList = new ConcurrentHashMap<String, WorkflowNode>();
- private Map<String, ProcessPack> processingQueue = new ConcurrentHashMap<String, ProcessPack>();
- private Map<String, ProcessPack> completeList = new HashMap<String, ProcessPack>();
- private Registry registry;
- private EventBus eventBus = new EventBus();
- private List<WorkflowOutputNode> completeWorkflowOutputs = new ArrayList<WorkflowOutputNode>();
-
- public SimpleWorkflowInterpreter(String experimentId, String credentialToken) throws RegistryException {
- setExperiment(experimentId);
- this.credentialToken = credentialToken;
- }
-
- public SimpleWorkflowInterpreter(Experiment experiment, String credentialStoreToken) {
- // read the workflow file and build the topology to a DAG. Then execute that dag
- // get workflowInputNode list and start processing
- // next() will return ready task and block the thread if no task in ready state.
- this.experiment = experiment;
- this.credentialToken = credentialStoreToken;
- }
-
-
- public void launchWorkflow() throws Exception {
- // process workflow input nodes
-// WorkflowFactoryImpl wfFactory = WorkflowFactoryImpl.getInstance();
-// WorkflowParser workflowParser = wfFactory.getWorkflowParser(experiment.getExperimentID(), credentialToken);
- WorkflowParser workflowParser = new AiravataDefaultParser(experiment, credentialToken);
- log.debug("Initialized workflow parser");
- setWorkflowInputNodes(workflowParser.parse());
- log.debug("Parsed the workflow and got the workflow input nodes");
- processWorkflowInputNodes(getWorkflowInputNodes());
- }
-
- // try to remove synchronization tag
- private synchronized void processReadyList() {
- for (WorkflowNode readyNode : readList.values()) {
- try {
- if (readyNode instanceof WorkflowOutputNode) {
- WorkflowOutputNode wfOutputNode = (WorkflowOutputNode) readyNode;
- wfOutputNode.getOutputObject().setValue(wfOutputNode.getInPort().getInputObject().getValue());
- addToCompleteOutputNodeList(wfOutputNode);
- continue;
- }
- WorkflowNodeDetails workflowNodeDetails = createWorkflowNodeDetails(readyNode);
- TaskDetails process = getProcess(workflowNodeDetails);
- ProcessPack processPack = new ProcessPack(readyNode, workflowNodeDetails, process);
- addToProcessingQueue(processPack);
-// publishToProcessQueue(process);
- publishToProcessQueue(processPack);
- } catch (RegistryException e) {
- // FIXME : handle this exception
- }
- }
- }
-
-
- private void publishToProcessQueue(TaskDetails process) {
- Thread thread = new Thread(new TempPublisher(process, eventBus));
- thread.start();
- //TODO: publish to process queue.
- }
-
- // TODO : remove this test method
- private void publishToProcessQueue(ProcessPack process) {
- WorkflowNode workflowNode = process.getWorkflowNode();
- if (workflowNode instanceof ApplicationNode) {
- ApplicationNode applicationNode = (ApplicationNode) workflowNode;
- List<InPort> inputPorts = applicationNode.getInputPorts();
- if (applicationNode.getName().equals("Add")) {
- applicationNode.getOutputPorts().get(0).getOutputObject().setValue(String.valueOf(
- Integer.parseInt(inputPorts.get(0).getInputObject().getValue()) + Integer.parseInt(inputPorts.get(1).getInputObject().getValue())));
- } else if (applicationNode.getName().equals("Multiply")) {
- applicationNode.getOutputPorts().get(0).getOutputObject().setValue(String.valueOf(
- Integer.parseInt(inputPorts.get(0).getInputObject().getValue()) * Integer.parseInt(inputPorts.get(1).getInputObject().getValue())));
- } else if (applicationNode.getName().equals("Subtract")) {
- applicationNode.getOutputPorts().get(0).getOutputObject().setValue(String.valueOf(
- Integer.parseInt(inputPorts.get(0).getInputObject().getValue()) - Integer.parseInt(inputPorts.get(1).getInputObject().getValue())));
- } else {
- throw new RuntimeException("Invalid Application name");
- }
-
- for (Edge edge : applicationNode.getOutputPorts().get(0).getOutEdges()) {
- WorkflowUtil.copyValues(applicationNode.getOutputPorts().get(0).getOutputObject(), edge.getToPort().getInputObject());
- if (edge.getToPort().getNode().isReady()) {
- addToReadyQueue(edge.getToPort().getNode());
- } else {
- addToWaitingQueue(edge.getToPort().getNode());
- }
- }
- } else if (workflowNode instanceof WorkflowOutputNode) {
- WorkflowOutputNode wfOutputNode = (WorkflowOutputNode) workflowNode;
- throw new RuntimeException("Workflow output node in processing queue");
- }
-
- processingQueue.remove(process.getTaskDetails().getTaskID());
- }
-
- private TaskDetails getProcess(WorkflowNodeDetails wfNodeDetails) throws RegistryException {
- // create workflow taskDetails from workflowNodeDetails
- TaskDetails taskDetails = ExperimentModelUtil.cloneTaskFromWorkflowNodeDetails(getExperiment(), wfNodeDetails);
- taskDetails.setTaskID(getRegistry()
- .add(ChildDataType.TASK_DETAIL, taskDetails, wfNodeDetails.getNodeInstanceId()).toString());
- return taskDetails;
- }
-
- private WorkflowNodeDetails createWorkflowNodeDetails(WorkflowNode readyNode) throws RegistryException {
- WorkflowNodeDetails wfNodeDetails = ExperimentModelUtil.createWorkflowNode(readyNode.getId(), null);
- ExecutionUnit executionUnit = ExecutionUnit.APPLICATION;
- String executionData = null;
- if (readyNode instanceof ApplicationNode) {
- executionUnit = ExecutionUnit.APPLICATION;
- executionData = ((ApplicationNode) readyNode).getApplicationId();
- } else if (readyNode instanceof WorkflowInputNode) {
- executionUnit = ExecutionUnit.INPUT;
- } else if (readyNode instanceof WorkflowOutputNode) {
- executionUnit = ExecutionUnit.OUTPUT;
- }
- wfNodeDetails.setExecutionUnit(executionUnit);
- wfNodeDetails.setExecutionUnitData(executionData);
- setupNodeDetailsInput(readyNode, wfNodeDetails);
- wfNodeDetails.setNodeInstanceId((String) getRegistry()
- .add(ChildDataType.WORKFLOW_NODE_DETAIL, wfNodeDetails, getExperiment().getExperimentID()));
-// nodeInstanceList.put(node, wfNodeDetails);
- return wfNodeDetails;
- }
-
- private void setupNodeDetailsInput(WorkflowNode readyNode, WorkflowNodeDetails wfNodeDetails) {
- if (readyNode instanceof ApplicationNode) {
- ApplicationNode applicationNode = (ApplicationNode) readyNode;
- if (applicationNode.isReady()) {
- for (InPort inPort : applicationNode.getInputPorts()) {
- wfNodeDetails.addToNodeInputs(inPort.getInputObject());
- }
- } else {
- // TODO: handle this scenario properly.
- }
- } else {
- // TODO: do we support for other type of workflow nodes ?
- }
- }
-
-
- private void processWorkflowInputNodes(List<WorkflowInputNode> wfInputNodes) {
- Set<WorkflowNode> tempNodeSet = new HashSet<WorkflowNode>();
- for (WorkflowInputNode wfInputNode : wfInputNodes) {
- if (wfInputNode.isReady()) {
- log.debug("Workflow node : " + wfInputNode.getId() + " is ready to execute");
- for (Edge edge : wfInputNode.getOutPort().getOutEdges()) {
- edge.getToPort().getInputObject().setValue(wfInputNode.getInputObject().getValue());
- if (edge.getToPort().getNode().isReady()) {
- addToReadyQueue(edge.getToPort().getNode());
- log.debug("Added workflow node : " + edge.getToPort().getNode().getId() + " to the readyQueue");
- } else {
- addToWaitingQueue(edge.getToPort().getNode());
- log.debug("Added workflow node " + edge.getToPort().getNode().getId() + " to the waitingQueue");
-
- }
- }
- }
- }
- }
-
-
- public List<WorkflowInputNode> getWorkflowInputNodes() throws Exception {
- return workflowInputNodes;
- }
-
- public void setWorkflowInputNodes(List<WorkflowInputNode> workflowInputNodes) {
- this.workflowInputNodes = workflowInputNodes;
- }
-
-
- private List<WorkflowInputNode> parseWorkflowDescription(){
- return null;
- }
-
-
- private Registry getRegistry() throws RegistryException {
- if (registry==null){
- registry = RegistryFactory.getDefaultRegistry();
- }
- return registry;
- }
-
- public Experiment getExperiment() {
- return experiment;
- }
-
- private void updateWorkflowNodeStatus(WorkflowNodeDetails wfNodeDetails, WorkflowNodeState state) throws RegistryException{
- WorkflowNodeStatus status = ExperimentModelUtil.createWorkflowNodeStatus(state);
- wfNodeDetails.setWorkflowNodeStatus(status);
- getRegistry().update(RegistryModelType.WORKFLOW_NODE_STATUS, status, wfNodeDetails.getNodeInstanceId());
- }
-
- @Subscribe
- public void taskOutputChanged(TaskOutputChangeEvent taskOutputEvent){
- String taskId = taskOutputEvent.getTaskIdentity().getTaskId();
- log.debug("Task Output changed event received for workflow node : " +
- taskOutputEvent.getTaskIdentity().getWorkflowNodeId() + ", task : " + taskId);
- ProcessPack processPack = processingQueue.get(taskId);
- Set<WorkflowNode> tempWfNodeSet = new HashSet<WorkflowNode>();
- if (processPack != null) {
- WorkflowNode workflowNode = processPack.getWorkflowNode();
- if (workflowNode instanceof ApplicationNode) {
- ApplicationNode applicationNode = (ApplicationNode) workflowNode;
- // Workflow node can have one to many output ports and each output port can have one to many links
- for (OutPort outPort : applicationNode.getOutputPorts()) {
- for (OutputDataObjectType outputDataObjectType : taskOutputEvent.getOutput()) {
- if (outPort.getOutputObject().getName().equals(outputDataObjectType.getName())) {
- outPort.getOutputObject().setValue(outputDataObjectType.getValue());
- break;
- }
- }
- for (Edge edge : outPort.getOutEdges()) {
- WorkflowUtil.copyValues(outPort.getOutputObject(), edge.getToPort().getInputObject());
- if (edge.getToPort().getNode().isReady()) {
- addToReadyQueue(edge.getToPort().getNode());
- }
- }
- }
- }
- processingQueue.remove(taskId);
- log.debug("removed task from processing queue : " + taskId);
- }
-
- }
-
- @Subscribe
- public void taskStatusChanged(TaskStatusChangeEvent taskStatus){
- String taskId = taskStatus.getTaskIdentity().getTaskId();
- ProcessPack processPack = processingQueue.get(taskId);
- if (processPack != null) {
- WorkflowNodeState wfNodeState = WorkflowNodeState.UNKNOWN;
- switch (taskStatus.getState()) {
- case WAITING:
- break;
- case STARTED:
- break;
- case PRE_PROCESSING:
- processPack.getWorkflowNode().setState(NodeState.PRE_PROCESSING);
- break;
- case INPUT_DATA_STAGING:
- processPack.getWorkflowNode().setState(NodeState.PRE_PROCESSING);
- break;
- case EXECUTING:
- processPack.getWorkflowNode().setState(NodeState.EXECUTING);
- break;
- case OUTPUT_DATA_STAGING:
- processPack.getWorkflowNode().setState(NodeState.POST_PROCESSING);
- break;
- case POST_PROCESSING:
- processPack.getWorkflowNode().setState(NodeState.POST_PROCESSING);
- break;
- case COMPLETED:
- processPack.getWorkflowNode().setState(NodeState.EXECUTED);
- break;
- case FAILED:
- processPack.getWorkflowNode().setState(NodeState.FAILED);
- break;
- case UNKNOWN:
- break;
- case CONFIGURING_WORKSPACE:
- break;
- case CANCELED:
- case CANCELING:
- processPack.getWorkflowNode().setState(NodeState.FAILED);
- break;
- default:
- break;
- }
- if (wfNodeState != WorkflowNodeState.UNKNOWN) {
- try {
- updateWorkflowNodeStatus(processPack.getWfNodeDetails(), wfNodeState);
- } catch (RegistryException e) {
- // TODO: handle this.
- }
- }
- }
-
- }
-
- /**
- * Remove the workflow node from waiting queue and add it to the ready queue.
- * @param workflowNode - Workflow Node
- */
- private synchronized void addToReadyQueue(WorkflowNode workflowNode) {
- waitingList.remove(workflowNode.getId());
- readList.put(workflowNode.getId(), workflowNode);
- }
-
- private void addToWaitingQueue(WorkflowNode workflowNode) {
- waitingList.put(workflowNode.getId(), workflowNode);
- }
-
- /**
- * First remove the node from ready list and then add the WfNodeContainer to the process queue.
- * Note that underline data structure of the process queue is a Map.
- * @param processPack - has both workflow and correspond workflowNodeDetails and TaskDetails
- */
- private synchronized void addToProcessingQueue(ProcessPack processPack) {
- readList.remove(processPack.getWorkflowNode().getId());
- processingQueue.put(processPack.getTaskDetails().getTaskID(), processPack);
- }
-
- private synchronized void addToCompleteQueue(ProcessPack processPack) {
- processingQueue.remove(processPack.getTaskDetails().getTaskID());
- completeList.put(processPack.getTaskDetails().getTaskID(), processPack);
- }
-
-
- private void addToCompleteOutputNodeList(WorkflowOutputNode wfOutputNode) {
- completeWorkflowOutputs.add(wfOutputNode);
- readList.remove(wfOutputNode.getId());
- }
-
- @Override
- public void run() {
- // TODO: Auto generated method body.
- try {
- log.debug("Launching workflow");
- launchWorkflow();
- while (!(waitingList.isEmpty() && readList.isEmpty())) {
- processReadyList();
- Thread.sleep(1000);
- }
- } catch (Exception e) {
- e.printStackTrace();
- }
- }
-
- private void setExperiment(String experimentId) throws RegistryException {
- experiment = (Experiment) getRegistry().get(RegistryModelType.EXPERIMENT, experimentId);
- log.debug("Retrieve Experiment for experiment id : " + experimentId);
- }
-
-
- class TempPublisher implements Runnable {
- private TaskDetails tempTaskDetails;
- private EventBus tempEventBus;
-
- public TempPublisher(TaskDetails tempTaskDetails, EventBus tempEventBus) {
- this.tempTaskDetails = tempTaskDetails;
- this.tempEventBus = tempEventBus;
- }
-
- @Override
- public void run() {
- try {
- TaskIdentifier identifier = new TaskIdentifier(tempTaskDetails.getTaskID(), null, null, null);
- TaskStatusChangeEvent statusChangeEvent = new TaskStatusChangeEvent(TaskState.PRE_PROCESSING, identifier);
- tempEventBus.post(statusChangeEvent);
- Thread.sleep(1000);
- statusChangeEvent = new TaskStatusChangeEvent(TaskState.WAITING, identifier);
- tempEventBus.post(statusChangeEvent);
- Thread.sleep(1000);
- statusChangeEvent = new TaskStatusChangeEvent(TaskState.INPUT_DATA_STAGING, identifier);
- tempEventBus.post(statusChangeEvent);
- Thread.sleep(1000);
- statusChangeEvent = new TaskStatusChangeEvent(TaskState.STARTED, identifier);
- tempEventBus.post(statusChangeEvent);
- Thread.sleep(1000);
- statusChangeEvent = new TaskStatusChangeEvent(TaskState.EXECUTING, identifier);
- tempEventBus.post(statusChangeEvent);
- Thread.sleep(1000);
- statusChangeEvent = new TaskStatusChangeEvent(TaskState.POST_PROCESSING, identifier);
- tempEventBus.post(statusChangeEvent);
- Thread.sleep(1000);
- statusChangeEvent = new TaskStatusChangeEvent(TaskState.OUTPUT_DATA_STAGING, identifier);
- tempEventBus.post(statusChangeEvent);
- Thread.sleep(1000);
- statusChangeEvent = new TaskStatusChangeEvent(TaskState.COMPLETED, identifier);
- tempEventBus.post(statusChangeEvent);
- Thread.sleep(1000);
-
- List<InputDataObjectType> applicationInputs = tempTaskDetails.getApplicationInputs();
- List<OutputDataObjectType> applicationOutputs = tempTaskDetails.getApplicationOutputs();
- log.info("************** Task output change event fired for application id :" + tempTaskDetails.getApplicationId());
- if (tempTaskDetails.getApplicationId().equals("Add") || tempTaskDetails.getApplicationId().equals("Add_2")) {
- applicationOutputs.get(0).setValue((Integer.parseInt(applicationInputs.get(0).getValue()) +
- Integer.parseInt(applicationInputs.get(1).getValue())) + "");
- } else if (tempTaskDetails.getApplicationId().equals("Subtract")) {
- applicationOutputs.get(0).setValue((Integer.parseInt(applicationInputs.get(0).getValue()) -
- Integer.parseInt(applicationInputs.get(1).getValue())) + "");
- } else if (tempTaskDetails.getApplicationId().equals("Multiply")) {
- applicationOutputs.get(0).setValue((Integer.parseInt(applicationInputs.get(0).getValue()) *
- Integer.parseInt(applicationInputs.get(1).getValue())) + "");
- }
- TaskOutputChangeEvent taskOutputChangeEvent = new TaskOutputChangeEvent(applicationOutputs, identifier);
- eventBus.post(taskOutputChangeEvent);
-
- } catch (InterruptedException e) {
- log.error("Thread was interrupted while sleeping");
- }
-
- }
- }
-}
http://git-wip-us.apache.org/repos/asf/airavata/blob/6bfb9563/modules/simple-workflow/src/main/java/org/apache/ariavata/simple/workflow/engine/WorkflowFactory.java
----------------------------------------------------------------------
diff --git a/modules/simple-workflow/src/main/java/org/apache/ariavata/simple/workflow/engine/WorkflowFactory.java b/modules/simple-workflow/src/main/java/org/apache/ariavata/simple/workflow/engine/WorkflowFactory.java
deleted file mode 100644
index b0ee4a1..0000000
--- a/modules/simple-workflow/src/main/java/org/apache/ariavata/simple/workflow/engine/WorkflowFactory.java
+++ /dev/null
@@ -1,31 +0,0 @@
-/*
- *
- * 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.ariavata.simple.workflow.engine;
-
-/**
- * All classes implement this WorkflowFactory interface, should be abstract or singleton.
- */
-public interface WorkflowFactory {
-
- public WorkflowParser getWorkflowParser(String experimentId, String credentialToken);
-
-}
http://git-wip-us.apache.org/repos/asf/airavata/blob/6bfb9563/modules/simple-workflow/src/main/java/org/apache/ariavata/simple/workflow/engine/WorkflowFactoryImpl.java
----------------------------------------------------------------------
diff --git a/modules/simple-workflow/src/main/java/org/apache/ariavata/simple/workflow/engine/WorkflowFactoryImpl.java b/modules/simple-workflow/src/main/java/org/apache/ariavata/simple/workflow/engine/WorkflowFactoryImpl.java
deleted file mode 100644
index dd84df0..0000000
--- a/modules/simple-workflow/src/main/java/org/apache/ariavata/simple/workflow/engine/WorkflowFactoryImpl.java
+++ /dev/null
@@ -1,66 +0,0 @@
-/*
- *
- * 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.ariavata.simple.workflow.engine;
-
-import org.apache.airavata.registry.cpi.RegistryException;
-import org.apache.ariavata.simple.workflow.engine.parser.AiravataDefaultParser;
-
-/**
- * Singleton class, only one instance can exist in runtime.
- */
-public class WorkflowFactoryImpl implements WorkflowFactory {
-
- private static WorkflowFactoryImpl workflowFactoryImpl;
-
- private WorkflowParser workflowParser;
-
- private static final String synch = "sync";
-
- private WorkflowFactoryImpl(){
-
- }
-
- public static WorkflowFactoryImpl getInstance() {
- if (workflowFactoryImpl == null) {
- synchronized (synch) {
- if (workflowFactoryImpl == null) {
- workflowFactoryImpl = new WorkflowFactoryImpl();
- }
- }
- }
- return workflowFactoryImpl;
- }
-
-
- @Override
- public WorkflowParser getWorkflowParser(String experimentId, String credentialToken) {
- if (workflowParser == null) {
- try {
- workflowParser = new AiravataDefaultParser(experimentId, credentialToken);
- } catch (RegistryException e) {
- // TODO : handle this scenario
- }
- }
- return workflowParser;
- }
-
-}
http://git-wip-us.apache.org/repos/asf/airavata/blob/6bfb9563/modules/simple-workflow/src/main/java/org/apache/ariavata/simple/workflow/engine/WorkflowParser.java
----------------------------------------------------------------------
diff --git a/modules/simple-workflow/src/main/java/org/apache/ariavata/simple/workflow/engine/WorkflowParser.java b/modules/simple-workflow/src/main/java/org/apache/ariavata/simple/workflow/engine/WorkflowParser.java
deleted file mode 100644
index adf0447..0000000
--- a/modules/simple-workflow/src/main/java/org/apache/ariavata/simple/workflow/engine/WorkflowParser.java
+++ /dev/null
@@ -1,32 +0,0 @@
-/*
- *
- * 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.ariavata.simple.workflow.engine;
-
-import org.apache.ariavata.simple.workflow.engine.dag.nodes.WorkflowInputNode;
-
-import java.util.List;
-
-public interface WorkflowParser {
-
- public List<WorkflowInputNode> parse() throws Exception;
-
-}
http://git-wip-us.apache.org/repos/asf/airavata/blob/6bfb9563/modules/simple-workflow/src/main/java/org/apache/ariavata/simple/workflow/engine/WorkflowUtil.java
----------------------------------------------------------------------
diff --git a/modules/simple-workflow/src/main/java/org/apache/ariavata/simple/workflow/engine/WorkflowUtil.java b/modules/simple-workflow/src/main/java/org/apache/ariavata/simple/workflow/engine/WorkflowUtil.java
deleted file mode 100644
index 688b170..0000000
--- a/modules/simple-workflow/src/main/java/org/apache/ariavata/simple/workflow/engine/WorkflowUtil.java
+++ /dev/null
@@ -1,63 +0,0 @@
-/*
- *
- * 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.ariavata.simple.workflow.engine;
-
-import com.google.common.eventbus.EventBus;
-import org.apache.airavata.model.appcatalog.appinterface.InputDataObjectType;
-import org.apache.airavata.model.appcatalog.appinterface.OutputDataObjectType;
-import org.apache.airavata.model.messaging.event.TaskIdentifier;
-import org.apache.airavata.model.messaging.event.TaskStatusChangeEvent;
-import org.apache.airavata.model.workspace.experiment.TaskDetails;
-import org.apache.airavata.model.workspace.experiment.TaskState;
-import org.apache.airavata.persistance.registry.jpa.model.TaskDetail;
-
-public class WorkflowUtil {
-
- public static InputDataObjectType copyValues(InputDataObjectType fromInputObj, InputDataObjectType toInputObj){
- if (toInputObj == null) {
- // TODO : throw an error
- }
- toInputObj.setValue(fromInputObj.getValue());
- if (fromInputObj.getApplicationArgument() != null
- && !fromInputObj.getApplicationArgument().trim().equals("")) {
- toInputObj.setApplicationArgument(fromInputObj.getApplicationArgument());
- }
- if (toInputObj.getType() == null) {
- toInputObj.setType(fromInputObj.getType());
- }
- return fromInputObj;
- }
-
- public static InputDataObjectType copyValues(OutputDataObjectType outputData, InputDataObjectType inputData) {
- inputData.setValue(outputData.getValue());
- return inputData;
- }
-
-
- public static OutputDataObjectType copyValues(InputDataObjectType inputObject, OutputDataObjectType outputObject) {
- if (outputObject == null) {
- outputObject = new OutputDataObjectType();
- }
- outputObject.setValue(inputObject.getValue());
- return outputObject;
- }
-}
http://git-wip-us.apache.org/repos/asf/airavata/blob/6bfb9563/modules/simple-workflow/src/main/java/org/apache/ariavata/simple/workflow/engine/dag/edge/DirectedEdge.java
----------------------------------------------------------------------
diff --git a/modules/simple-workflow/src/main/java/org/apache/ariavata/simple/workflow/engine/dag/edge/DirectedEdge.java b/modules/simple-workflow/src/main/java/org/apache/ariavata/simple/workflow/engine/dag/edge/DirectedEdge.java
deleted file mode 100644
index 9e1544e..0000000
--- a/modules/simple-workflow/src/main/java/org/apache/ariavata/simple/workflow/engine/dag/edge/DirectedEdge.java
+++ /dev/null
@@ -1,52 +0,0 @@
-/*
- *
- * 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.ariavata.simple.workflow.engine.dag.edge;
-
-import org.apache.ariavata.simple.workflow.engine.dag.port.InPort;
-import org.apache.ariavata.simple.workflow.engine.dag.port.OutPort;
-
-
-public class DirectedEdge implements Edge {
-
- private InPort inPort;
- private OutPort outPort;
-
- @Override
- public InPort getToPort() {
- return inPort;
- }
-
- @Override
- public void setToPort(InPort inPort) {
- this.inPort = inPort;
- }
-
- @Override
- public OutPort getFromPort() {
- return outPort;
- }
-
- @Override
- public void setFromPort(OutPort outPort) {
- this.outPort = outPort;
- }
-}
http://git-wip-us.apache.org/repos/asf/airavata/blob/6bfb9563/modules/simple-workflow/src/main/java/org/apache/ariavata/simple/workflow/engine/dag/edge/Edge.java
----------------------------------------------------------------------
diff --git a/modules/simple-workflow/src/main/java/org/apache/ariavata/simple/workflow/engine/dag/edge/Edge.java b/modules/simple-workflow/src/main/java/org/apache/ariavata/simple/workflow/engine/dag/edge/Edge.java
deleted file mode 100644
index cc8116a..0000000
--- a/modules/simple-workflow/src/main/java/org/apache/ariavata/simple/workflow/engine/dag/edge/Edge.java
+++ /dev/null
@@ -1,43 +0,0 @@
-/*
- *
- * 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.ariavata.simple.workflow.engine.dag.edge;
-
-import org.apache.ariavata.simple.workflow.engine.dag.port.InPort;
-import org.apache.ariavata.simple.workflow.engine.dag.port.OutPort;
-
-/**
- * Edge is a link to one node to another, basically edge should have outPort of a workflow node ,
- * which is starting point and inPort of a workflow node, which is end point of the edge.
- */
-
-public interface Edge {
-
- public InPort getToPort();
-
- public void setToPort(InPort inPort);
-
- public OutPort getFromPort();
-
- public void setFromPort(OutPort outPort);
-
-
-}
http://git-wip-us.apache.org/repos/asf/airavata/blob/6bfb9563/modules/simple-workflow/src/main/java/org/apache/ariavata/simple/workflow/engine/dag/nodes/ApplicationNode.java
----------------------------------------------------------------------
diff --git a/modules/simple-workflow/src/main/java/org/apache/ariavata/simple/workflow/engine/dag/nodes/ApplicationNode.java b/modules/simple-workflow/src/main/java/org/apache/ariavata/simple/workflow/engine/dag/nodes/ApplicationNode.java
deleted file mode 100644
index 6ab5754..0000000
--- a/modules/simple-workflow/src/main/java/org/apache/ariavata/simple/workflow/engine/dag/nodes/ApplicationNode.java
+++ /dev/null
@@ -1,41 +0,0 @@
-/*
- *
- * 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.ariavata.simple.workflow.engine.dag.nodes;
-
-import org.apache.ariavata.simple.workflow.engine.dag.port.InPort;
-import org.apache.ariavata.simple.workflow.engine.dag.port.OutPort;
-
-import java.util.List;
-
-public interface ApplicationNode extends WorkflowNode {
-
- public String getApplicationId();
-
- public void addInPort(InPort inPort);
-
- public List<InPort> getInputPorts();
-
- public void addOutPort(OutPort outPort);
-
- public List<OutPort> getOutputPorts();
-
-}
http://git-wip-us.apache.org/repos/asf/airavata/blob/6bfb9563/modules/simple-workflow/src/main/java/org/apache/ariavata/simple/workflow/engine/dag/nodes/ApplicationNodeImpl.java
----------------------------------------------------------------------
diff --git a/modules/simple-workflow/src/main/java/org/apache/ariavata/simple/workflow/engine/dag/nodes/ApplicationNodeImpl.java b/modules/simple-workflow/src/main/java/org/apache/ariavata/simple/workflow/engine/dag/nodes/ApplicationNodeImpl.java
deleted file mode 100644
index 1282dd0..0000000
--- a/modules/simple-workflow/src/main/java/org/apache/ariavata/simple/workflow/engine/dag/nodes/ApplicationNodeImpl.java
+++ /dev/null
@@ -1,113 +0,0 @@
-/*
- *
- * 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.ariavata.simple.workflow.engine.dag.nodes;
-
-import org.apache.ariavata.simple.workflow.engine.dag.port.InPort;
-import org.apache.ariavata.simple.workflow.engine.dag.port.OutPort;
-
-import java.util.ArrayList;
-import java.util.List;
-
-public class ApplicationNodeImpl implements ApplicationNode {
-
- private final String nodeId;
- private NodeState myState = NodeState.WAITING;
- private String applicationId;
- private List<InPort> inPorts = new ArrayList<InPort>();
- private List<OutPort> outPorts = new ArrayList<OutPort>();
- private String applicationName;
-
-// public ApplicationNodeImpl(String nodeId) {
-// this(nodeId, null);
-// }
-//
-// public ApplicationNodeImpl(String nodeId, String applicationId) {
-// this(nodeId, null, applicationId);
-// }
-
- public ApplicationNodeImpl(String nodeId, String applicationName, String applicationId) {
- this.nodeId = nodeId;
- this.applicationName = applicationName;
- this.applicationId = applicationId;
- }
-
- @Override
- public String getId() {
- return this.nodeId;
- }
-
- @Override
- public String getName() {
- return applicationName;
- }
-
- @Override
- public NodeType getType() {
- return NodeType.APPLICATION;
- }
-
- @Override
- public NodeState getState() {
- return myState;
- }
-
- @Override
- public void setState(NodeState newState) {
- // TODO: node state can't be reversed , correct order WAITING --> READY --> EXECUTING --> EXECUTED --> COMPLETE
- myState = newState;
- }
-
- @Override
- public boolean isReady() {
- for (InPort inPort : getInputPorts()) {
- if (!inPort.isReady()) {
- return false;
- }
- }
- return true;
- }
-
- @Override
- public String getApplicationId() {
- return this.applicationId;
- }
-
- @Override
- public void addInPort(InPort inPort) {
- this.inPorts.add(inPort);
- }
-
- @Override
- public List<InPort> getInputPorts() {
- return this.inPorts;
- }
-
- @Override
- public void addOutPort(OutPort outPort) {
- this.outPorts.add(outPort);
- }
-
- @Override
- public List<OutPort> getOutputPorts() {
- return this.outPorts;
- }
-}
http://git-wip-us.apache.org/repos/asf/airavata/blob/6bfb9563/modules/simple-workflow/src/main/java/org/apache/ariavata/simple/workflow/engine/dag/nodes/NodeState.java
----------------------------------------------------------------------
diff --git a/modules/simple-workflow/src/main/java/org/apache/ariavata/simple/workflow/engine/dag/nodes/NodeState.java b/modules/simple-workflow/src/main/java/org/apache/ariavata/simple/workflow/engine/dag/nodes/NodeState.java
deleted file mode 100644
index 088336b..0000000
--- a/modules/simple-workflow/src/main/java/org/apache/ariavata/simple/workflow/engine/dag/nodes/NodeState.java
+++ /dev/null
@@ -1,34 +0,0 @@
-/*
- *
- * 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.ariavata.simple.workflow.engine.dag.nodes;
-
-public enum NodeState {
- WAITING, // waiting on inputs
- READY, // all inputs are available and ready to execute
- QUEUED, //
- PRE_PROCESSING, //
- EXECUTING, // task has been submitted , not yet finish
- EXECUTED, // task executed
- POST_PROCESSING, //
- FAILED,
- COMPLETE // all works done
-}
http://git-wip-us.apache.org/repos/asf/airavata/blob/6bfb9563/modules/simple-workflow/src/main/java/org/apache/ariavata/simple/workflow/engine/dag/nodes/NodeType.java
----------------------------------------------------------------------
diff --git a/modules/simple-workflow/src/main/java/org/apache/ariavata/simple/workflow/engine/dag/nodes/NodeType.java b/modules/simple-workflow/src/main/java/org/apache/ariavata/simple/workflow/engine/dag/nodes/NodeType.java
deleted file mode 100644
index 9cef6ab..0000000
--- a/modules/simple-workflow/src/main/java/org/apache/ariavata/simple/workflow/engine/dag/nodes/NodeType.java
+++ /dev/null
@@ -1,28 +0,0 @@
-/*
- *
- * 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.ariavata.simple.workflow.engine.dag.nodes;
-
-public enum NodeType {
- APPLICATION,
- WORKFLOW_INPUT,
- WORKFLOW_OUTPUT
-}
http://git-wip-us.apache.org/repos/asf/airavata/blob/6bfb9563/modules/simple-workflow/src/main/java/org/apache/ariavata/simple/workflow/engine/dag/nodes/WorkflowInputNode.java
----------------------------------------------------------------------
diff --git a/modules/simple-workflow/src/main/java/org/apache/ariavata/simple/workflow/engine/dag/nodes/WorkflowInputNode.java b/modules/simple-workflow/src/main/java/org/apache/ariavata/simple/workflow/engine/dag/nodes/WorkflowInputNode.java
deleted file mode 100644
index 0c1d0b4..0000000
--- a/modules/simple-workflow/src/main/java/org/apache/ariavata/simple/workflow/engine/dag/nodes/WorkflowInputNode.java
+++ /dev/null
@@ -1,37 +0,0 @@
-/*
- *
- * 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.ariavata.simple.workflow.engine.dag.nodes;
-
-import org.apache.airavata.model.appcatalog.appinterface.InputDataObjectType;
-import org.apache.ariavata.simple.workflow.engine.dag.port.OutPort;
-
-public interface WorkflowInputNode extends WorkflowNode {
-
- public InputDataObjectType getInputObject();
-
- public void setInputObject(InputDataObjectType inputObject);
-
- public OutPort getOutPort();
-
- public void setOutPort(OutPort outPort);
-
-}
http://git-wip-us.apache.org/repos/asf/airavata/blob/6bfb9563/modules/simple-workflow/src/main/java/org/apache/ariavata/simple/workflow/engine/dag/nodes/WorkflowInputNodeImpl.java
----------------------------------------------------------------------
diff --git a/modules/simple-workflow/src/main/java/org/apache/ariavata/simple/workflow/engine/dag/nodes/WorkflowInputNodeImpl.java b/modules/simple-workflow/src/main/java/org/apache/ariavata/simple/workflow/engine/dag/nodes/WorkflowInputNodeImpl.java
deleted file mode 100644
index a015909..0000000
--- a/modules/simple-workflow/src/main/java/org/apache/ariavata/simple/workflow/engine/dag/nodes/WorkflowInputNodeImpl.java
+++ /dev/null
@@ -1,96 +0,0 @@
-/*
- * 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.ariavata.simple.workflow.engine.dag.nodes;
-
-import org.apache.airavata.model.appcatalog.appinterface.InputDataObjectType;
-import org.apache.ariavata.simple.workflow.engine.dag.port.OutPort;
-
-public class WorkflowInputNodeImpl implements WorkflowInputNode {
-
- private NodeState myState = NodeState.READY;
- private final String nodeId;
- private String nodeName;
- private OutPort outPort;
- private InputDataObjectType inputDataObjectType;
- private String name;
-
- public WorkflowInputNodeImpl(String nodeId) {
- this(nodeId, null);
- }
-
- public WorkflowInputNodeImpl(String nodeId, String nodeName) {
- this.nodeId = nodeId;
- this.nodeName = nodeName;
- }
-
- @Override
- public String getId() {
- return this.nodeId;
- }
-
- @Override
- public String getName() {
- return this.nodeName;
- }
-
- @Override
- public NodeType getType() {
- return NodeType.WORKFLOW_INPUT;
- }
-
- @Override
- public NodeState getState() {
- return myState;
- }
-
- @Override
- public void setState(NodeState newState) {
- // TODO: node state can't be reversed , correct order WAITING --> READY --> EXECUTING --> EXECUTED --> COMPLETE
- myState = newState;
- }
-
- @Override
- public boolean isReady() {
- return (inputDataObjectType.getValue() != null && !inputDataObjectType.getValue().equals(""))
- || !inputDataObjectType.isIsRequired();
- }
-
- @Override
- public InputDataObjectType getInputObject() {
- return this.inputDataObjectType;
- }
-
- @Override
- public void setInputObject(InputDataObjectType inputObject) {
- this.inputDataObjectType = inputObject;
- }
-
- @Override
- public OutPort getOutPort() {
- return this.outPort;
- }
-
- @Override
- public void setOutPort(OutPort outPort) {
- this.outPort = outPort;
- }
-
-
-}
http://git-wip-us.apache.org/repos/asf/airavata/blob/6bfb9563/modules/simple-workflow/src/main/java/org/apache/ariavata/simple/workflow/engine/dag/nodes/WorkflowNode.java
----------------------------------------------------------------------
diff --git a/modules/simple-workflow/src/main/java/org/apache/ariavata/simple/workflow/engine/dag/nodes/WorkflowNode.java b/modules/simple-workflow/src/main/java/org/apache/ariavata/simple/workflow/engine/dag/nodes/WorkflowNode.java
deleted file mode 100644
index f875674..0000000
--- a/modules/simple-workflow/src/main/java/org/apache/ariavata/simple/workflow/engine/dag/nodes/WorkflowNode.java
+++ /dev/null
@@ -1,38 +0,0 @@
-/*
- *
- * 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.ariavata.simple.workflow.engine.dag.nodes;
-
-public interface WorkflowNode {
-
- public String getId();
-
- public String getName();
-
- public NodeType getType();
-
- public NodeState getState();
-
- public void setState(NodeState newState);
-
- public boolean isReady();
-
-}
http://git-wip-us.apache.org/repos/asf/airavata/blob/6bfb9563/modules/simple-workflow/src/main/java/org/apache/ariavata/simple/workflow/engine/dag/nodes/WorkflowOutputNode.java
----------------------------------------------------------------------
diff --git a/modules/simple-workflow/src/main/java/org/apache/ariavata/simple/workflow/engine/dag/nodes/WorkflowOutputNode.java b/modules/simple-workflow/src/main/java/org/apache/ariavata/simple/workflow/engine/dag/nodes/WorkflowOutputNode.java
deleted file mode 100644
index 63a52a3..0000000
--- a/modules/simple-workflow/src/main/java/org/apache/ariavata/simple/workflow/engine/dag/nodes/WorkflowOutputNode.java
+++ /dev/null
@@ -1,37 +0,0 @@
-/*
- *
- * 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.ariavata.simple.workflow.engine.dag.nodes;
-
-import org.apache.airavata.model.appcatalog.appinterface.OutputDataObjectType;
-import org.apache.ariavata.simple.workflow.engine.dag.port.InPort;
-
-public interface WorkflowOutputNode extends WorkflowNode {
-
- public OutputDataObjectType getOutputObject();
-
- public void setOutputObject(OutputDataObjectType outputObject);
-
- public InPort getInPort();
-
- public void setInPort(InPort inPort);
-
-}
http://git-wip-us.apache.org/repos/asf/airavata/blob/6bfb9563/modules/simple-workflow/src/main/java/org/apache/ariavata/simple/workflow/engine/dag/nodes/WorkflowOutputNodeImpl.java
----------------------------------------------------------------------
diff --git a/modules/simple-workflow/src/main/java/org/apache/ariavata/simple/workflow/engine/dag/nodes/WorkflowOutputNodeImpl.java b/modules/simple-workflow/src/main/java/org/apache/ariavata/simple/workflow/engine/dag/nodes/WorkflowOutputNodeImpl.java
deleted file mode 100644
index a44c05f..0000000
--- a/modules/simple-workflow/src/main/java/org/apache/ariavata/simple/workflow/engine/dag/nodes/WorkflowOutputNodeImpl.java
+++ /dev/null
@@ -1,97 +0,0 @@
-/*
- *
- * 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.ariavata.simple.workflow.engine.dag.nodes;
-
-import org.apache.airavata.model.appcatalog.appinterface.OutputDataObjectType;
-import org.apache.ariavata.simple.workflow.engine.dag.port.InPort;
-
-public class WorkflowOutputNodeImpl implements WorkflowOutputNode {
-
- private NodeState myState = NodeState.WAITING;
- private final String nodeId;
- private String nodeName;
- private OutputDataObjectType outputDataObjectType;
- private InPort inPort;
-
- public WorkflowOutputNodeImpl(String nodeId) {
- this(nodeId, null);
- }
-
- public WorkflowOutputNodeImpl(String nodeId, String nodeName) {
- this.nodeId = nodeId;
- this.nodeName = nodeName;
- }
-
- @Override
- public String getId() {
- return this.nodeId;
- }
-
- @Override
- public String getName() {
- return this.nodeName;
- }
-
- @Override
- public NodeType getType() {
- return NodeType.WORKFLOW_OUTPUT;
- }
-
- @Override
- public NodeState getState() {
- return myState;
- }
-
- @Override
- public void setState(NodeState newState) {
- // TODO: node state can't be reversed , correct order WAITING --> READY --> EXECUTING --> EXECUTED --> COMPLETE
- myState = newState;
- }
-
- @Override
- public boolean isReady() {
- return !(inPort.getInputObject() == null || inPort.getInputObject().getValue() == null
- || inPort.getInputObject().getValue().equals(""));
- }
-
- @Override
- public OutputDataObjectType getOutputObject() {
- return this.outputDataObjectType;
- }
-
- @Override
- public void setOutputObject(OutputDataObjectType outputObject) {
- this.outputDataObjectType = outputObject;
- }
-
- @Override
- public InPort getInPort() {
- return this.inPort;
- }
-
- @Override
- public void setInPort(InPort inPort) {
- this.inPort = inPort;
- }
-
-}
-
http://git-wip-us.apache.org/repos/asf/airavata/blob/6bfb9563/modules/simple-workflow/src/main/java/org/apache/ariavata/simple/workflow/engine/dag/port/InPort.java
----------------------------------------------------------------------
diff --git a/modules/simple-workflow/src/main/java/org/apache/ariavata/simple/workflow/engine/dag/port/InPort.java b/modules/simple-workflow/src/main/java/org/apache/ariavata/simple/workflow/engine/dag/port/InPort.java
deleted file mode 100644
index bac10ee..0000000
--- a/modules/simple-workflow/src/main/java/org/apache/ariavata/simple/workflow/engine/dag/port/InPort.java
+++ /dev/null
@@ -1,41 +0,0 @@
-/*
- *
- * 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.ariavata.simple.workflow.engine.dag.port;
-
-import org.apache.airavata.model.appcatalog.appinterface.InputDataObjectType;
-import org.apache.ariavata.simple.workflow.engine.dag.edge.Edge;
-
-public interface InPort extends Port {
-
- public void setInputObject(InputDataObjectType inputObject);
-
- public InputDataObjectType getInputObject();
-
- public Edge getEdge();
-
- public void addEdge(Edge edge);
-
- public String getDefaultValue();
-
- public void setDefaultValue(String defaultValue);
-
-}
http://git-wip-us.apache.org/repos/asf/airavata/blob/6bfb9563/modules/simple-workflow/src/main/java/org/apache/ariavata/simple/workflow/engine/dag/port/InputPortIml.java
----------------------------------------------------------------------
diff --git a/modules/simple-workflow/src/main/java/org/apache/ariavata/simple/workflow/engine/dag/port/InputPortIml.java b/modules/simple-workflow/src/main/java/org/apache/ariavata/simple/workflow/engine/dag/port/InputPortIml.java
deleted file mode 100644
index 82160a9..0000000
--- a/modules/simple-workflow/src/main/java/org/apache/ariavata/simple/workflow/engine/dag/port/InputPortIml.java
+++ /dev/null
@@ -1,90 +0,0 @@
-/*
- * 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.ariavata.simple.workflow.engine.dag.port;
-
-import org.apache.airavata.model.appcatalog.appinterface.InputDataObjectType;
-import org.apache.ariavata.simple.workflow.engine.dag.edge.Edge;
-import org.apache.ariavata.simple.workflow.engine.dag.nodes.WorkflowNode;
-
-public class InputPortIml implements InPort {
-
- private InputDataObjectType inputDataObjectType;
- private boolean ready = false;
- private String portId;
- private Edge edge;
- private WorkflowNode node;
- private String defaultValue;
-
- public InputPortIml(String portId) {
- this.portId = portId;
- }
-
- @Override
- public void setInputObject(InputDataObjectType inputObject) {
- this.inputDataObjectType = inputObject;
- ready = (inputDataObjectType.getValue() != null && !inputDataObjectType.getValue().equals(""))
- || !inputDataObjectType.isIsRequired();
- }
-
- @Override
- public InputDataObjectType getInputObject() {
- return this.inputDataObjectType;
- }
-
- @Override
- public Edge getEdge() {
- return this.edge;
- }
-
- @Override
- public void addEdge(Edge edge) {
- this.edge = edge;
- }
-
- @Override
- public String getDefaultValue() {
- return defaultValue;
- }
-
- public void setDefaultValue(String defaultValue) {
- this.defaultValue = defaultValue;
- }
-
- @Override
- public boolean isReady() {
- return getInputObject() != null && inputDataObjectType.getValue() != null && !inputDataObjectType.getValue().equals("");
- }
-
- @Override
- public WorkflowNode getNode() {
- return this.node;
- }
-
- @Override
- public void setNode(WorkflowNode workflowNode) {
- this.node = workflowNode;
- }
-
- @Override
- public String getId() {
- return this.portId;
- }
-
-}
http://git-wip-us.apache.org/repos/asf/airavata/blob/6bfb9563/modules/simple-workflow/src/main/java/org/apache/ariavata/simple/workflow/engine/dag/port/OutPort.java
----------------------------------------------------------------------
diff --git a/modules/simple-workflow/src/main/java/org/apache/ariavata/simple/workflow/engine/dag/port/OutPort.java b/modules/simple-workflow/src/main/java/org/apache/ariavata/simple/workflow/engine/dag/port/OutPort.java
deleted file mode 100644
index 04a7e1e..0000000
--- a/modules/simple-workflow/src/main/java/org/apache/ariavata/simple/workflow/engine/dag/port/OutPort.java
+++ /dev/null
@@ -1,39 +0,0 @@
-/*
- *
- * 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.ariavata.simple.workflow.engine.dag.port;
-
-import org.apache.airavata.model.appcatalog.appinterface.OutputDataObjectType;
-import org.apache.ariavata.simple.workflow.engine.dag.edge.Edge;
-
-import java.util.List;
-
-public interface OutPort extends Port {
-
- public void setOutputObject(OutputDataObjectType outputObject);
-
- public OutputDataObjectType getOutputObject();
-
- public List<Edge> getOutEdges();
-
- public void addEdge(Edge edge);
-
-}
[34/50] [abbrv] airavata git commit: Used user provide gateway id
instead of default gateway Id
Posted by sh...@apache.org.
Used user provide gateway id instead of default gateway Id
Project: http://git-wip-us.apache.org/repos/asf/airavata/repo
Commit: http://git-wip-us.apache.org/repos/asf/airavata/commit/d3f67fd8
Tree: http://git-wip-us.apache.org/repos/asf/airavata/tree/d3f67fd8
Diff: http://git-wip-us.apache.org/repos/asf/airavata/diff/d3f67fd8
Branch: refs/heads/master
Commit: d3f67fd85197078e4cd13f70ff184fa38f53ea58
Parents: 29a0e4b
Author: shamrath <sh...@gmail.com>
Authored: Thu Mar 19 15:59:03 2015 -0400
Committer: shamrath <sh...@gmail.com>
Committed: Thu Mar 19 15:59:03 2015 -0400
----------------------------------------------------------------------
.../airavata-orchestrator-service/pom.xml | 11 ++++++---
.../registry/JCRComponentRegistry.java | 7 +++---
.../airavata/xbaya/XBayaConfiguration.java | 2 +-
.../ui/dialogs/registry/RegistryWindow.java | 26 ++++++++++----------
.../dialogs/workflow/WorkflowImportWindow.java | 2 +-
.../ui/experiment/LaunchApplicationWindow.java | 7 +++---
.../RegistryWorkflowPublisherWindow.java | 3 +--
.../WorkflowInterpreterLaunchWindow.java | 23 ++++-------------
8 files changed, 36 insertions(+), 45 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/airavata/blob/d3f67fd8/modules/orchestrator/airavata-orchestrator-service/pom.xml
----------------------------------------------------------------------
diff --git a/modules/orchestrator/airavata-orchestrator-service/pom.xml b/modules/orchestrator/airavata-orchestrator-service/pom.xml
index 3817852..b441023 100644
--- a/modules/orchestrator/airavata-orchestrator-service/pom.xml
+++ b/modules/orchestrator/airavata-orchestrator-service/pom.xml
@@ -26,6 +26,11 @@
<dependencies>
<dependency>
+ <groupId>org.apache.airavata</groupId>
+ <artifactId>airavata-credential-store</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+ <dependency>
<groupId>org.apache.thrift</groupId>
<artifactId>libthrift</artifactId>
<version>${thrift.version}</version>
@@ -45,7 +50,7 @@
<artifactId>airavata-orchestrator-stubs</artifactId>
<version>${project.version}</version>
</dependency>
- <dependency>
+ <dependency>
<groupId>org.apache.airavata</groupId>
<artifactId>airavata-workflow-engine</artifactId>
<version>${project.version}</version>
@@ -65,12 +70,12 @@
<artifactId>app-catalog-cpi</artifactId>
<version>${project.version}</version>
</dependency>
- <dependency>
+ <dependency>
<groupId>org.apache.airavata</groupId>
<artifactId>airavata-model-utils</artifactId>
<version>${project.version}</version>
</dependency>
- <dependency>
+ <dependency>
<groupId>org.apache.airavata</groupId>
<artifactId>airavata-server-configuration</artifactId>
<scope>test</scope>
http://git-wip-us.apache.org/repos/asf/airavata/blob/d3f67fd8/modules/workflow-model/workflow-model-component/src/main/java/org/apache/airavata/workflow/model/component/registry/JCRComponentRegistry.java
----------------------------------------------------------------------
diff --git a/modules/workflow-model/workflow-model-component/src/main/java/org/apache/airavata/workflow/model/component/registry/JCRComponentRegistry.java b/modules/workflow-model/workflow-model-component/src/main/java/org/apache/airavata/workflow/model/component/registry/JCRComponentRegistry.java
index ccaae5e..bf844bc 100644
--- a/modules/workflow-model/workflow-model-component/src/main/java/org/apache/airavata/workflow/model/component/registry/JCRComponentRegistry.java
+++ b/modules/workflow-model/workflow-model-component/src/main/java/org/apache/airavata/workflow/model/component/registry/JCRComponentRegistry.java
@@ -35,10 +35,12 @@ public class JCRComponentRegistry extends ComponentRegistry {
private static final Logger log = LoggerFactory.getLogger(JCRComponentRegistry.class);
private static final String NAME = "Applications";
+ private final String gatewayId;
private Airavata.Client client;
- public JCRComponentRegistry(Airavata.Client client) {
+ public JCRComponentRegistry(String gatewayId, Airavata.Client client) {
setClient(client);
+ this.gatewayId = gatewayId;
}
/**
@@ -48,8 +50,7 @@ public class JCRComponentRegistry extends ComponentRegistry {
public List<ComponentReference> getComponentReferenceList() {
List<ComponentReference> tree = new ArrayList<ComponentReference>();
try {
- //FIXME: Pass Gateway ID to the UI and use it to fetch the applications
- List<ApplicationInterfaceDescription> allApplicationInterfaces = client.getAllApplicationInterfaces("default");
+ List<ApplicationInterfaceDescription> allApplicationInterfaces = client.getAllApplicationInterfaces(gatewayId);
for (ApplicationInterfaceDescription interfaceDescription : allApplicationInterfaces) {
JCRComponentReference jcr = new JCRComponentReference(interfaceDescription.getApplicationName(),interfaceDescription);
tree.add(jcr);
http://git-wip-us.apache.org/repos/asf/airavata/blob/d3f67fd8/modules/xbaya-gui/src/main/java/org/apache/airavata/xbaya/XBayaConfiguration.java
----------------------------------------------------------------------
diff --git a/modules/xbaya-gui/src/main/java/org/apache/airavata/xbaya/XBayaConfiguration.java b/modules/xbaya-gui/src/main/java/org/apache/airavata/xbaya/XBayaConfiguration.java
index 77a0aa0..aab86a4 100644
--- a/modules/xbaya-gui/src/main/java/org/apache/airavata/xbaya/XBayaConfiguration.java
+++ b/modules/xbaya-gui/src/main/java/org/apache/airavata/xbaya/XBayaConfiguration.java
@@ -767,7 +767,7 @@ public class XBayaConfiguration extends Observable implements Observer {
try {
Client airavataClient = XBayaUtil.getAiravataClient(getThriftClientData(ThriftServiceType.API_SERVICE));
if (getJcrComponentRegistry() == null) {
- setJcrComponentRegistry(new JCRComponentRegistry(airavataClient));
+ setJcrComponentRegistry(new JCRComponentRegistry(getThriftClientData(ThriftServiceType.API_SERVICE).getGatewayId(),airavataClient));
} else {
getJcrComponentRegistry().setClient(airavataClient);
}
http://git-wip-us.apache.org/repos/asf/airavata/blob/d3f67fd8/modules/xbaya-gui/src/main/java/org/apache/airavata/xbaya/ui/dialogs/registry/RegistryWindow.java
----------------------------------------------------------------------
diff --git a/modules/xbaya-gui/src/main/java/org/apache/airavata/xbaya/ui/dialogs/registry/RegistryWindow.java b/modules/xbaya-gui/src/main/java/org/apache/airavata/xbaya/ui/dialogs/registry/RegistryWindow.java
index 9275fe5..0b5f2c1 100644
--- a/modules/xbaya-gui/src/main/java/org/apache/airavata/xbaya/ui/dialogs/registry/RegistryWindow.java
+++ b/modules/xbaya-gui/src/main/java/org/apache/airavata/xbaya/ui/dialogs/registry/RegistryWindow.java
@@ -55,14 +55,14 @@ public class RegistryWindow {
private XBayaTextField portTextField;
- private XBayaTextField gatewayNameTextField;
+ private XBayaTextField gatewayIdTextField;
private XBayaTextField usernameTextField;
private XBayaComboBox serviceTypeCombo;
- private String gatewayName;
+ private String gatewayId;
private String username;
@@ -100,14 +100,14 @@ public class RegistryWindow {
private void ok() {
setServerName(this.serverTextField.getText());
setPreviousServerName(this.serverTextField.getText());
- setGatewayName(this.gatewayNameTextField.getText());
+ setGatewayId(this.gatewayIdTextField.getText());
setUsername(new String(this.usernameTextField.getText()));
setServerPort(this.portTextField.getText());
setServiceType((ThriftServiceType)serviceTypeModel.getSelectedItem());
try {
validateData();
XBayaConfiguration configuration = this.engine.getConfiguration();
- configuration.addThriftClientData(new ThriftClientData(getServiceType(),serverName, Integer.parseInt(serverPort),gatewayName, username));
+ configuration.addThriftClientData(new ThriftClientData(getServiceType(),serverName, Integer.parseInt(serverPort), gatewayId, username));
hide();
} catch (Exception e) {
this.engine.getGUI().getErrorWindow().error(e.getMessage());
@@ -120,16 +120,16 @@ public class RegistryWindow {
private void initGUI() {
this.serverTextField = new XBayaTextField();
this.portTextField = new XBayaTextField();
- this.gatewayNameTextField = new XBayaTextField();
+ this.gatewayIdTextField = new XBayaTextField();
this.usernameTextField = new XBayaTextField();
this.serverTextField.setText("localhost");
this.portTextField.setText("8930");
- this.gatewayNameTextField.setText("airavata");
+ this.gatewayIdTextField.setText("airavata");
this.usernameTextField.setText("airavata");
ThriftClientData thriftClientData = engine.getConfiguration().getThriftClientData(ThriftServiceType.API_SERVICE);
if (thriftClientData!=null){
this.serverTextField.setText(thriftClientData.getServerAddress());
- this.gatewayNameTextField.setText(thriftClientData.getGatewayId());
+ this.gatewayIdTextField.setText(thriftClientData.getGatewayId());
this.portTextField.setText(String.valueOf(thriftClientData.getServerPort()));
this.usernameTextField.setText(thriftClientData.getUsername());
}
@@ -142,7 +142,7 @@ public class RegistryWindow {
XBayaLabel serverAddressLabel = new XBayaLabel("Server Address", this.serverTextField);
XBayaLabel serverPortLabel = new XBayaLabel("Server Port", this.portTextField);
- XBayaLabel gatewayNameLabel = new XBayaLabel("Gateway Name", this.gatewayNameTextField);
+ XBayaLabel gatewayNameLabel = new XBayaLabel("Gateway ID", this.gatewayIdTextField);
XBayaLabel gatewayUserLabel = new XBayaLabel("Gateway User", this.usernameTextField);
serviceTypeModel = new DefaultComboBoxModel(ThriftServiceType.values());
serviceTypeModel.setSelectedItem(getServiceType());
@@ -163,7 +163,7 @@ public class RegistryWindow {
infoPanel.add(serverPortLabel);
infoPanel.add(this.portTextField);
infoPanel.add(gatewayNameLabel);
- infoPanel.add(this.gatewayNameTextField);
+ infoPanel.add(this.gatewayIdTextField);
infoPanel.add(gatewayUserLabel);
infoPanel.add(this.usernameTextField);
infoPanel.layout(5, 2, GridPanel.WEIGHT_NONE, 1);
@@ -210,16 +210,16 @@ public class RegistryWindow {
return serverName;
}
- public String getGatewayName() {
- return gatewayName;
+ public String getGatewayId() {
+ return gatewayId;
}
public void setServerName(String serverName) {
this.serverName = serverName;
}
- public void setGatewayName(String gateway) {
- this.gatewayName = gateway;
+ public void setGatewayId(String gateway) {
+ this.gatewayId = gateway;
}
public void setUsername(String username) {
http://git-wip-us.apache.org/repos/asf/airavata/blob/d3f67fd8/modules/xbaya-gui/src/main/java/org/apache/airavata/xbaya/ui/dialogs/workflow/WorkflowImportWindow.java
----------------------------------------------------------------------
diff --git a/modules/xbaya-gui/src/main/java/org/apache/airavata/xbaya/ui/dialogs/workflow/WorkflowImportWindow.java b/modules/xbaya-gui/src/main/java/org/apache/airavata/xbaya/ui/dialogs/workflow/WorkflowImportWindow.java
index 0931ebc..07d2f46 100644
--- a/modules/xbaya-gui/src/main/java/org/apache/airavata/xbaya/ui/dialogs/workflow/WorkflowImportWindow.java
+++ b/modules/xbaya-gui/src/main/java/org/apache/airavata/xbaya/ui/dialogs/workflow/WorkflowImportWindow.java
@@ -111,7 +111,7 @@ public class WorkflowImportWindow {
public void run() {
try {
//FIXME: Update the gateway id fetched from UI
- List<String> resultList = getClient().getAllWorkflows("default");
+ List<String> resultList = getClient().getAllWorkflows(engine.getConfiguration().getThriftClientData(ThriftServiceType.API_SERVICE).getGatewayId());
if (resultList == null || resultList.size() == 0) {
/*
* OGCEXRegistryLoaderWindow.this.list.getList(). setListData( new
http://git-wip-us.apache.org/repos/asf/airavata/blob/d3f67fd8/modules/xbaya-gui/src/main/java/org/apache/airavata/xbaya/ui/experiment/LaunchApplicationWindow.java
----------------------------------------------------------------------
diff --git a/modules/xbaya-gui/src/main/java/org/apache/airavata/xbaya/ui/experiment/LaunchApplicationWindow.java b/modules/xbaya-gui/src/main/java/org/apache/airavata/xbaya/ui/experiment/LaunchApplicationWindow.java
index adfa726..450dde5 100644
--- a/modules/xbaya-gui/src/main/java/org/apache/airavata/xbaya/ui/experiment/LaunchApplicationWindow.java
+++ b/modules/xbaya-gui/src/main/java/org/apache/airavata/xbaya/ui/experiment/LaunchApplicationWindow.java
@@ -264,6 +264,7 @@ public class LaunchApplicationWindow {
private void execute() throws AiravataClientConnectException, InvalidRequestException, AiravataClientException, AiravataSystemException, TException {
List<NodeImpl> nodes = workflow.getGraph().getNodes();
+ String gatewayId = engine.getConfiguration().getThriftClientData(ThriftServiceType.API_SERVICE).getGatewayId();
String appId = null;
NodeImpl node = null;
for(int i=0; i<nodes.size(); i++){
@@ -298,8 +299,7 @@ public class LaunchApplicationWindow {
String owner = this.thriftClientData.getUsername();
if(owner.equals(""))owner="NotKnown";
project.setOwner(owner);
- //FIXME:: use gatewayId from UI
- project.setProjectID(airavataClient.createProject("default", project));
+ project.setProjectID(airavataClient.createProject(gatewayId, project));
// final List<InputNode> inputNodes = GraphUtil.getInputNodes(this.workflow.getGraph());
final List<DataPort> inputPorts = node.getInputPorts();
final Experiment experiment = new Experiment();
@@ -368,8 +368,7 @@ public class LaunchApplicationWindow {
experiment.addToExperimentOutputs(elem );
}
- //FIXME:: use gatewayId from UI
- experiment.setExperimentID(airavataClient.createExperiment("default", experiment));
+ experiment.setExperimentID(airavataClient.createExperiment(gatewayId, experiment));
airavataClient.launchExperiment(experiment.getExperimentID(), "testToken");
hide();
JOptionPane.showMessageDialog(null, "Experiment Launched. You will be alerted on completion.");
http://git-wip-us.apache.org/repos/asf/airavata/blob/d3f67fd8/modules/xbaya-gui/src/main/java/org/apache/airavata/xbaya/ui/experiment/RegistryWorkflowPublisherWindow.java
----------------------------------------------------------------------
diff --git a/modules/xbaya-gui/src/main/java/org/apache/airavata/xbaya/ui/experiment/RegistryWorkflowPublisherWindow.java b/modules/xbaya-gui/src/main/java/org/apache/airavata/xbaya/ui/experiment/RegistryWorkflowPublisherWindow.java
index e8ea5d8..1b4c383 100644
--- a/modules/xbaya-gui/src/main/java/org/apache/airavata/xbaya/ui/experiment/RegistryWorkflowPublisherWindow.java
+++ b/modules/xbaya-gui/src/main/java/org/apache/airavata/xbaya/ui/experiment/RegistryWorkflowPublisherWindow.java
@@ -102,8 +102,7 @@ public class RegistryWorkflowPublisherWindow {
org.apache.airavata.model.Workflow workflowData = new org.apache.airavata.model.Workflow();
workflowData.setName(workflowTemplateName);
workflowData.setGraph(workflowAsString);
- //FIXME: Use the gatewayId from the UI
- client.registerWorkflow("default", workflowData);
+ client.registerWorkflow(engine.getConfiguration().getThriftClientData(ThriftServiceType.API_SERVICE).getGatewayId(), workflowData);
hide();
}
} catch (Exception e) {
http://git-wip-us.apache.org/repos/asf/airavata/blob/d3f67fd8/modules/xbaya-gui/src/main/java/org/apache/airavata/xbaya/ui/experiment/WorkflowInterpreterLaunchWindow.java
----------------------------------------------------------------------
diff --git a/modules/xbaya-gui/src/main/java/org/apache/airavata/xbaya/ui/experiment/WorkflowInterpreterLaunchWindow.java b/modules/xbaya-gui/src/main/java/org/apache/airavata/xbaya/ui/experiment/WorkflowInterpreterLaunchWindow.java
index 2eece65..df27269 100644
--- a/modules/xbaya-gui/src/main/java/org/apache/airavata/xbaya/ui/experiment/WorkflowInterpreterLaunchWindow.java
+++ b/modules/xbaya-gui/src/main/java/org/apache/airavata/xbaya/ui/experiment/WorkflowInterpreterLaunchWindow.java
@@ -265,20 +265,17 @@ public class WorkflowInterpreterLaunchWindow {
this.dialog.setDefaultButton(okButton);
}
- private void execute() throws AiravataClientConnectException, InvalidRequestException, AiravataClientException, AiravataSystemException, TException {
-
-
+ private void execute() throws AiravataClientConnectException, TException {
ThriftClientData thriftClientData = engine.getConfiguration().getThriftClientData(ThriftServiceType.API_SERVICE);
Client airavataClient = XBayaUtil.getAiravataClient(thriftClientData);
+ String gatewayId = engine.getConfiguration().getThriftClientData(ThriftServiceType.API_SERVICE).getGatewayId();
-
Workflow workflowClone = workflow.clone();
workflowClone.setName(workflowClone.getName()+UUID.randomUUID().toString());
org.apache.airavata.model.Workflow w = new org.apache.airavata.model.Workflow();
w.setName(workflowClone.getName());
w.setGraph(JSONUtil.jsonElementToString(workflowClone.toJSON()));
- //FIXME:: use gatewayId from UI
- w.setTemplateId(airavataClient.registerWorkflow("default", w));
+ w.setTemplateId(airavataClient.registerWorkflow(gatewayId, w));
String instanceName = this.instanceNameTextField.getText();
if (instanceName.trim().equals("")){
JOptionPane.showMessageDialog(engine.getGUI().getFrame(),
@@ -287,20 +284,16 @@ public class WorkflowInterpreterLaunchWindow {
JOptionPane.ERROR_MESSAGE);
return;
}
-
//previous instance name
if (!instanceNameTextField.getText().equals("")){
this.instanceNameTextField.setText("");
}
-
// Use topic as a base of workflow instance ID so that the monitor can
// find it.
-
Project project = new Project();
project.setName("project1");
project.setOwner(thriftClientData.getUsername());
- //FIXME:: use gatewayId from UI
- project.setProjectID(airavataClient.createProject("default", project));
+ project.setProjectID(airavataClient.createProject(gatewayId, project));
final List<InputNode> inputNodes = GraphUtil.getInputNodes(this.workflow.getGraph());
final Experiment experiment = new Experiment();
experiment.setApplicationId(w.getTemplateId());
@@ -322,7 +315,6 @@ public class WorkflowInterpreterLaunchWindow {
experiment.addToExperimentInputs(elem );
}
-
final List<OutputNode> outputNodes = GraphUtil.getOutputNodes(this.workflow.getGraph());
OutputDataObjectType outputDataObjectType = null;
for (OutputNode outputNode : outputNodes) {
@@ -331,7 +323,6 @@ public class WorkflowInterpreterLaunchWindow {
outputDataObjectType.setType(DataType.STRING);
experiment.addToExperimentOutputs(outputDataObjectType);
}
-
// Add scheduling configurations
if (host != null && host.getSelectedIndex() >= 0) {
String selectedHostName = host.getSelectedItem().toString();
@@ -378,10 +369,7 @@ public class WorkflowInterpreterLaunchWindow {
airavataClient.launchExperiment(experiment.getExperimentID(), "testToken");
}*/
-
- //FIXME:: use gatewayId from UI
- experiment.setExperimentID(airavataClient.createExperiment("default", experiment));
-
+ experiment.setExperimentID(airavataClient.createExperiment(gatewayId, experiment));
try {
this.engine.getMonitor().subscribe(experiment.getExperimentID());
this.engine.getMonitor().fireStartMonitoring(workflow.getName());
@@ -389,7 +377,6 @@ public class WorkflowInterpreterLaunchWindow {
logger.error("Error while subscribing with experiment Id : " + experiment.getExperimentID(), e);
}
airavataClient.launchExperiment(experiment.getExperimentID(), "testToken");
-
hide();
}
[39/50] [abbrv] airavata git commit: Merge new-workfow-design
Posted by sh...@apache.org.
Merge new-workfow-design
Project: http://git-wip-us.apache.org/repos/asf/airavata/repo
Commit: http://git-wip-us.apache.org/repos/asf/airavata/commit/1014cd98
Tree: http://git-wip-us.apache.org/repos/asf/airavata/tree/1014cd98
Diff: http://git-wip-us.apache.org/repos/asf/airavata/diff/1014cd98
Branch: refs/heads/master
Commit: 1014cd9830ae8a4d5ac1df836d357e8964db79ce
Parents: b27dc19 5e5630d
Author: shamrath <sh...@gmail.com>
Authored: Wed Mar 25 13:25:13 2015 -0400
Committer: shamrath <sh...@gmail.com>
Committed: Wed Mar 25 13:25:13 2015 -0400
----------------------------------------------------------------------
.../lib/airavata/messagingEvents_types.cpp | 88 +++-
.../lib/airavata/messagingEvents_types.h | 47 +-
.../Airavata/Model/Messaging/Event/Types.php | 94 ++++
.../client/samples/CreateLaunchExperiment.java | 2 +-
.../client/samples/RegisterSampleData.java | 50 +-
.../model/messaging/event/MessageType.java | 5 +-
.../messaging/event/ProcessSubmitEvent.java | 492 +++++++++++++++++++
.../messagingEvents.thrift | 8 +-
.../airavata/common/utils/ServerSettings.java | 20 +
.../main/resources/airavata-server.properties | 6 +-
.../main/resources/airavata-server.properties | 4 +
modules/credential-store/pom.xml | 19 +-
.../airavata/gfac/server/GfacServerHandler.java | 1 +
.../core/monitor/AiravataTaskStatusUpdator.java | 13 +
.../core/impl/RabbitMQProcessConsumer.java | 158 ++++++
.../core/impl/RabbitMQProcessPublisher.java | 84 ++++
.../core/impl/RabbitMQStatusConsumer.java | 10 +-
.../core/impl/RabbitMQStatusPublisher.java | 20 +-
.../messaging/core/stats/CountWriterTask.java | 1 -
.../airavata-orchestrator-service/pom.xml | 16 +-
.../server/OrchestratorServerHandler.java | 159 ++++--
.../orchestrator/util/DataModelUtils.java | 8 +-
modules/simple-workflow/pom.xml | 70 +++
.../simple/workflow/engine/ProcessContext.java | 62 +++
.../engine/SimpleWorkflowInterpreter.java | 400 +++++++++++++++
.../engine/WorkflowEnactmentService.java | 183 +++++++
.../simple/workflow/engine/WorkflowFactory.java | 31 ++
.../workflow/engine/WorkflowFactoryImpl.java | 74 +++
.../simple/workflow/engine/WorkflowParser.java | 32 ++
.../workflow/engine/dag/edge/DirectedEdge.java | 52 ++
.../simple/workflow/engine/dag/edge/Edge.java | 43 ++
.../engine/dag/nodes/ApplicationNode.java | 41 ++
.../engine/dag/nodes/ApplicationNodeImpl.java | 116 +++++
.../workflow/engine/dag/nodes/NodeState.java | 44 ++
.../workflow/engine/dag/nodes/NodeType.java | 28 ++
.../engine/dag/nodes/WorkflowInputNode.java | 37 ++
.../engine/dag/nodes/WorkflowInputNodeImpl.java | 99 ++++
.../workflow/engine/dag/nodes/WorkflowNode.java | 38 ++
.../engine/dag/nodes/WorkflowOutputNode.java | 37 ++
.../dag/nodes/WorkflowOutputNodeImpl.java | 100 ++++
.../simple/workflow/engine/dag/port/InPort.java | 41 ++
.../workflow/engine/dag/port/InputPortIml.java | 91 ++++
.../workflow/engine/dag/port/OutPort.java | 39 ++
.../workflow/engine/dag/port/OutPortImpl.java | 83 ++++
.../simple/workflow/engine/dag/port/Port.java | 36 ++
.../engine/parser/AiravataWorkflowParser.java | 291 +++++++++++
.../workflow/engine/parser/PortContainer.java | 53 ++
.../simple/workflow/engine/WorkflowDAGTest.java | 46 ++
.../parser/AiravataWorkflowParserTest.java | 119 +++++
.../src/test/resources/ComplexMathWorkflow.awf | 465 ++++++++++++++++++
.../registry/JCRComponentRegistry.java | 7 +-
.../airavata/xbaya/XBayaConfiguration.java | 2 +-
.../ui/dialogs/registry/RegistryWindow.java | 26 +-
.../dialogs/workflow/WorkflowImportWindow.java | 2 +-
.../ui/experiment/LaunchApplicationWindow.java | 7 +-
.../RegistryWorkflowPublisherWindow.java | 3 +-
.../WorkflowInterpreterLaunchWindow.java | 58 ++-
pom.xml | 1 +
58 files changed, 4018 insertions(+), 144 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/airavata/blob/1014cd98/airavata-api/airavata-client-sdks/java-client-samples/src/main/java/org/apache/airavata/client/samples/CreateLaunchExperiment.java
----------------------------------------------------------------------
diff --cc airavata-api/airavata-client-sdks/java-client-samples/src/main/java/org/apache/airavata/client/samples/CreateLaunchExperiment.java
index e65acb4,812f6c4..1af3450
--- a/airavata-api/airavata-client-sdks/java-client-samples/src/main/java/org/apache/airavata/client/samples/CreateLaunchExperiment.java
+++ b/airavata-api/airavata-client-sdks/java-client-samples/src/main/java/org/apache/airavata/client/samples/CreateLaunchExperiment.java
@@@ -160,9 -162,10 +160,9 @@@ public class CreateLaunchExperiment
public static void createAndLaunchExp() throws TException {
-// final String expId = createEchoExperimentForFSD(airavataClient);
List<String> experimentIds = new ArrayList<String>();
try {
- for (int i = 0; i < 100; i++) {
+ for (int i = 0; i < 1; i++) {
// final String expId = createExperimentForSSHHost(airavata);
// final String expId = createEchoExperimentForFSD(airavataClient);
// final String expId = createMPIExperimentForFSD(airavataClient);
http://git-wip-us.apache.org/repos/asf/airavata/blob/1014cd98/airavata-api/thrift-interface-descriptions/messagingEvents.thrift
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/airavata/blob/1014cd98/modules/configuration/server/src/main/resources/airavata-server.properties
----------------------------------------------------------------------
diff --cc modules/configuration/server/src/main/resources/airavata-server.properties
index 61ee3c5,8442472..0b7a000
--- a/modules/configuration/server/src/main/resources/airavata-server.properties
+++ b/modules/configuration/server/src/main/resources/airavata-server.properties
@@@ -223,10 -225,7 +227,8 @@@ task.launch.publisher=org.apache.airava
rabbitmq.status.exchange.name=airavata_rabbitmq_exchange
rabbitmq.task.launch.exchange.name=airavata_task_launch_rabbitmq_exchange
-
-
+activity.publisher=org.apache.airavata.messaging.core.impl.RabbitMQPublisher
+rabbitmq.exchange.name=airavata_rabbitmq_exchange
###########################################################################
# Orchestrator module Configuration
http://git-wip-us.apache.org/repos/asf/airavata/blob/1014cd98/modules/credential-store/credential-store-webapp/src/main/resources/airavata-server.properties
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/airavata/blob/1014cd98/modules/gfac/airavata-gfac-service/src/main/java/org/apache/airavata/gfac/server/GfacServerHandler.java
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/airavata/blob/1014cd98/modules/orchestrator/airavata-orchestrator-service/src/main/java/org/apache/airavata/orchestrator/server/OrchestratorServerHandler.java
----------------------------------------------------------------------
[29/50] [abbrv] airavata git commit: Show error message when there is
no compute resources found.
Posted by sh...@apache.org.
Show error message when there is no compute resources found.
Project: http://git-wip-us.apache.org/repos/asf/airavata/repo
Commit: http://git-wip-us.apache.org/repos/asf/airavata/commit/ad8e4826
Tree: http://git-wip-us.apache.org/repos/asf/airavata/tree/ad8e4826
Diff: http://git-wip-us.apache.org/repos/asf/airavata/diff/ad8e4826
Branch: refs/heads/master
Commit: ad8e482674b7c3523eed16b99b5d448dfb83f63c
Parents: 774b092
Author: shamrath <sh...@gmail.com>
Authored: Mon Mar 9 20:44:35 2015 -0400
Committer: shamrath <sh...@gmail.com>
Committed: Mon Mar 9 20:44:35 2015 -0400
----------------------------------------------------------------------
.../xbaya/ui/experiment/WorkflowInterpreterLaunchWindow.java | 7 +++++++
1 file changed, 7 insertions(+)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/airavata/blob/ad8e4826/modules/xbaya-gui/src/main/java/org/apache/airavata/xbaya/ui/experiment/WorkflowInterpreterLaunchWindow.java
----------------------------------------------------------------------
diff --git a/modules/xbaya-gui/src/main/java/org/apache/airavata/xbaya/ui/experiment/WorkflowInterpreterLaunchWindow.java b/modules/xbaya-gui/src/main/java/org/apache/airavata/xbaya/ui/experiment/WorkflowInterpreterLaunchWindow.java
index c0c6b45..3425a4f 100644
--- a/modules/xbaya-gui/src/main/java/org/apache/airavata/xbaya/ui/experiment/WorkflowInterpreterLaunchWindow.java
+++ b/modules/xbaya-gui/src/main/java/org/apache/airavata/xbaya/ui/experiment/WorkflowInterpreterLaunchWindow.java
@@ -151,6 +151,13 @@ public class WorkflowInterpreterLaunchWindow {
try {
hosts = airavataClient.getAllComputeResourceNames();
+ if (hosts.isEmpty()) {
+ JOptionPane.showMessageDialog(engine.getGUI().getFrame(),
+ "No Compute Resources found",
+ "Compute Resources",
+ JOptionPane.ERROR_MESSAGE);
+ return;
+ }
} catch (InvalidRequestException e2) {
// TODO Auto-generated catch block
e2.printStackTrace();
[35/50] [abbrv] airavata git commit: Reade gateway Id from credential
token and identify the experiment execution type
Posted by sh...@apache.org.
Reade gateway Id from credential token and identify the experiment execution type
Project: http://git-wip-us.apache.org/repos/asf/airavata/repo
Commit: http://git-wip-us.apache.org/repos/asf/airavata/commit/2b45c6d9
Tree: http://git-wip-us.apache.org/repos/asf/airavata/tree/2b45c6d9
Diff: http://git-wip-us.apache.org/repos/asf/airavata/diff/2b45c6d9
Branch: refs/heads/master
Commit: 2b45c6d95f083fc5a3964c9e64e2daea55e25b86
Parents: d3f67fd
Author: shamrath <sh...@gmail.com>
Authored: Thu Mar 19 17:03:44 2015 -0400
Committer: shamrath <sh...@gmail.com>
Committed: Thu Mar 19 17:03:44 2015 -0400
----------------------------------------------------------------------
modules/credential-store/pom.xml | 19 ++++++-----------
.../server/OrchestratorServerHandler.java | 22 +++++++++++++++-----
.../orchestrator/util/DataModelUtils.java | 8 +++----
3 files changed, 26 insertions(+), 23 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/airavata/blob/2b45c6d9/modules/credential-store/pom.xml
----------------------------------------------------------------------
diff --git a/modules/credential-store/pom.xml b/modules/credential-store/pom.xml
index 370cc9b..af4bc58 100644
--- a/modules/credential-store/pom.xml
+++ b/modules/credential-store/pom.xml
@@ -23,19 +23,12 @@
<name>Airavata Credential Store</name>
<url>http://airavata.apache.org/</url>
- <profiles>
- <profile>
- <id>default</id>
- <activation>
- <activeByDefault>true</activeByDefault>
- </activation>
- <modules>
- <module>credential-store-service</module>
- <module>credential-store-stubs</module>
- <module>credential-store-webapp</module>
- </modules>
- </profile>
- </profiles>
+ <modules>
+ <module>credential-store-service</module>
+ <module>credential-store-stubs</module>
+ <module>credential-store-webapp</module>
+ </modules>
+
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
http://git-wip-us.apache.org/repos/asf/airavata/blob/2b45c6d9/modules/orchestrator/airavata-orchestrator-service/src/main/java/org/apache/airavata/orchestrator/server/OrchestratorServerHandler.java
----------------------------------------------------------------------
diff --git a/modules/orchestrator/airavata-orchestrator-service/src/main/java/org/apache/airavata/orchestrator/server/OrchestratorServerHandler.java b/modules/orchestrator/airavata-orchestrator-service/src/main/java/org/apache/airavata/orchestrator/server/OrchestratorServerHandler.java
index fe306d7..4209bb9 100644
--- a/modules/orchestrator/airavata-orchestrator-service/src/main/java/org/apache/airavata/orchestrator/server/OrchestratorServerHandler.java
+++ b/modules/orchestrator/airavata-orchestrator-service/src/main/java/org/apache/airavata/orchestrator/server/OrchestratorServerHandler.java
@@ -236,7 +236,19 @@ public class OrchestratorServerHandler implements OrchestratorService.Iface,
log.errorId(experimentId, "Error retrieving the Experiment by the given experimentID: {} ", experimentId);
return false;
}
- ExecutionType executionType = DataModelUtils.getExecutionType(experiment);
+ CredentialReader credentialReader = GFacUtils.getCredentialReader();
+ String gatewayId = null;
+ if (credentialReader != null) {
+ try {
+ gatewayId = credentialReader.getGatewayID(token);
+ } catch (Exception e) {
+ log.error(e.getLocalizedMessage());
+ }
+ }
+ if (gatewayId == null) {
+ throw new AiravataException("Couldn't identify the gateway Id using the credential token");
+ }
+ ExecutionType executionType = DataModelUtils.getExecutionType(gatewayId, experiment);
synchronized (this) {
if (executionType==ExecutionType.SINGLE_APP) {
//its an single application execution experiment
@@ -247,10 +259,10 @@ public class OrchestratorServerHandler implements OrchestratorService.Iface,
//its a workflow execution experiment
log.debugId(experimentId, "Launching workflow experiment {}.", experimentId);
launchWorkflowExperiment(experimentId, token);
- } else {
- log.errorId(experimentId, "Couldn't identify experiment type, experiment {} is neither single application nor workflow.", experimentId);
- throw new TException("Experiment '" + experimentId + "' launch failed. Unable to figureout execution type for application " + experiment.getApplicationId());
- }
+ } else {
+ log.errorId(experimentId, "Couldn't identify experiment type, experiment {} is neither single application nor workflow.", experimentId);
+ throw new TException("Experiment '" + experimentId + "' launch failed. Unable to figureout execution type for application " + experiment.getApplicationId());
+ }
}
}catch(Exception e){
throw new TException("Experiment '" + experimentId + "' launch failed. Unable to figureout execution type for application " + experiment.getApplicationId());
http://git-wip-us.apache.org/repos/asf/airavata/blob/2b45c6d9/modules/orchestrator/airavata-orchestrator-service/src/main/java/org/apache/airavata/orchestrator/util/DataModelUtils.java
----------------------------------------------------------------------
diff --git a/modules/orchestrator/airavata-orchestrator-service/src/main/java/org/apache/airavata/orchestrator/util/DataModelUtils.java b/modules/orchestrator/airavata-orchestrator-service/src/main/java/org/apache/airavata/orchestrator/util/DataModelUtils.java
index 3243eb8..b6f8387 100644
--- a/modules/orchestrator/airavata-orchestrator-service/src/main/java/org/apache/airavata/orchestrator/util/DataModelUtils.java
+++ b/modules/orchestrator/airavata-orchestrator-service/src/main/java/org/apache/airavata/orchestrator/util/DataModelUtils.java
@@ -37,7 +37,7 @@ import org.slf4j.LoggerFactory;
public class DataModelUtils {
private final static Logger logger = LoggerFactory.getLogger(DataModelUtils.class);
- public static ExecutionType getExecutionType(Experiment experiment){
+ public static ExecutionType getExecutionType(String gatewayId, Experiment experiment){
try {
ApplicationInterface applicationInterface = AppCatalogFactory.getAppCatalog().getApplicationInterface();
List<String> allApplicationInterfaceIds = applicationInterface.getAllApplicationInterfaceIds();
@@ -45,16 +45,14 @@ public class DataModelUtils {
if (allApplicationInterfaceIds.contains(applicationId)){
return ExecutionType.SINGLE_APP;
} else {
- List<String> allWorkflows = WorkflowCatalogFactory.getWorkflowCatalog().getAllWorkflows(ServerSettings.getDefaultUserGateway());
+ List<String> allWorkflows = WorkflowCatalogFactory.getWorkflowCatalog().getAllWorkflows(gatewayId);
if (allWorkflows.contains(applicationId)){
return ExecutionType.WORKFLOW;
}
}
} catch (AppCatalogException e) {
logger.error(e.getMessage(), e);
- } catch (ApplicationSettingsException e) {
- logger.error(e.getMessage(), e);
- }
+ }
return ExecutionType.UNKNOWN;
}
}
[46/50] [abbrv] airavata git commit: Renamed simple-workflow module
to workflow and created a new workflow-core module which will keep all the
core code
Posted by sh...@apache.org.
http://git-wip-us.apache.org/repos/asf/airavata/blob/509f2037/modules/simple-workflow/src/main/java/org/apache/airavata/simple/workflow/engine/dag/port/InputPortIml.java
----------------------------------------------------------------------
diff --git a/modules/simple-workflow/src/main/java/org/apache/airavata/simple/workflow/engine/dag/port/InputPortIml.java b/modules/simple-workflow/src/main/java/org/apache/airavata/simple/workflow/engine/dag/port/InputPortIml.java
deleted file mode 100644
index 076f5b6..0000000
--- a/modules/simple-workflow/src/main/java/org/apache/airavata/simple/workflow/engine/dag/port/InputPortIml.java
+++ /dev/null
@@ -1,91 +0,0 @@
-/*
- * 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.simple.workflow.engine.dag.port;
-
-import org.apache.airavata.model.appcatalog.appinterface.InputDataObjectType;
-import org.apache.airavata.simple.workflow.engine.dag.edge.Edge;
-import org.apache.airavata.simple.workflow.engine.dag.nodes.WorkflowNode;
-
-public class InputPortIml implements InPort {
-
- private InputDataObjectType inputDataObjectType;
- private boolean ready = false;
- private String portId;
- private Edge edge;
- private WorkflowNode node;
- private String defaultValue;
-
- public InputPortIml(String portId) {
- this.portId = portId;
- }
-
- @Override
- public void setInputObject(InputDataObjectType inputObject) {
- this.inputDataObjectType = inputObject;
- ready = (inputDataObjectType.getValue() != null && !inputDataObjectType.getValue().equals(""))
- || !inputDataObjectType.isIsRequired();
- }
-
- @Override
- public InputDataObjectType getInputObject() {
- return this.inputDataObjectType;
- }
-
- @Override
- public Edge getEdge() {
- return this.edge;
- }
-
- @Override
- public void addEdge(Edge edge) {
- this.edge = edge;
- }
-
- @Override
- public String getDefaultValue() {
- return defaultValue;
- }
-
- public void setDefaultValue(String defaultValue) {
- this.defaultValue = defaultValue;
- }
-
- @Override
- public boolean isReady() {
- return getInputObject() != null && (!inputDataObjectType.isIsRequired() ||
- (inputDataObjectType.getValue() != null && !inputDataObjectType.getValue().equals("")));
- }
-
- @Override
- public WorkflowNode getNode() {
- return this.node;
- }
-
- @Override
- public void setNode(WorkflowNode workflowNode) {
- this.node = workflowNode;
- }
-
- @Override
- public String getId() {
- return this.portId;
- }
-
-}
http://git-wip-us.apache.org/repos/asf/airavata/blob/509f2037/modules/simple-workflow/src/main/java/org/apache/airavata/simple/workflow/engine/dag/port/OutPort.java
----------------------------------------------------------------------
diff --git a/modules/simple-workflow/src/main/java/org/apache/airavata/simple/workflow/engine/dag/port/OutPort.java b/modules/simple-workflow/src/main/java/org/apache/airavata/simple/workflow/engine/dag/port/OutPort.java
deleted file mode 100644
index 0332f81..0000000
--- a/modules/simple-workflow/src/main/java/org/apache/airavata/simple/workflow/engine/dag/port/OutPort.java
+++ /dev/null
@@ -1,39 +0,0 @@
-/*
- *
- * 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.simple.workflow.engine.dag.port;
-
-import org.apache.airavata.model.appcatalog.appinterface.OutputDataObjectType;
-import org.apache.airavata.simple.workflow.engine.dag.edge.Edge;
-
-import java.util.List;
-
-public interface OutPort extends Port {
-
- public void setOutputObject(OutputDataObjectType outputObject);
-
- public OutputDataObjectType getOutputObject();
-
- public List<Edge> getOutEdges();
-
- public void addEdge(Edge edge);
-
-}
http://git-wip-us.apache.org/repos/asf/airavata/blob/509f2037/modules/simple-workflow/src/main/java/org/apache/airavata/simple/workflow/engine/dag/port/OutPortImpl.java
----------------------------------------------------------------------
diff --git a/modules/simple-workflow/src/main/java/org/apache/airavata/simple/workflow/engine/dag/port/OutPortImpl.java b/modules/simple-workflow/src/main/java/org/apache/airavata/simple/workflow/engine/dag/port/OutPortImpl.java
deleted file mode 100644
index 4e26cb3..0000000
--- a/modules/simple-workflow/src/main/java/org/apache/airavata/simple/workflow/engine/dag/port/OutPortImpl.java
+++ /dev/null
@@ -1,83 +0,0 @@
-/*
- *
- * 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.simple.workflow.engine.dag.port;
-
-import org.apache.airavata.model.appcatalog.appinterface.OutputDataObjectType;
-import org.apache.airavata.simple.workflow.engine.dag.edge.Edge;
-import org.apache.airavata.simple.workflow.engine.dag.nodes.WorkflowNode;
-
-import java.util.ArrayList;
-import java.util.List;
-
-public class OutPortImpl implements OutPort {
-
- private OutputDataObjectType outputDataObjectType;
- private List<Edge> outEdges = new ArrayList<Edge>();
- private boolean isSatisfy = false;
- private String portId;
- private WorkflowNode node;
-
- public OutPortImpl(String portId) {
- this.portId = portId;
- }
-
- @Override
- public void setOutputObject(OutputDataObjectType outputObject) {
- this.outputDataObjectType = outputObject;
- }
-
- @Override
- public OutputDataObjectType getOutputObject() {
- return this.outputDataObjectType;
- }
-
- @Override
- public List<Edge> getOutEdges() {
- return this.outEdges;
- }
-
- @Override
- public void addEdge(Edge edge) {
- this.outEdges.add(edge);
- }
-
- @Override
- public boolean isReady() {
- return this.outputDataObjectType.getValue() != null
- && !this.outputDataObjectType.getValue().equals("");
- }
-
- @Override
- public WorkflowNode getNode() {
- return this.node;
- }
-
- @Override
- public void setNode(WorkflowNode workflowNode) {
- this.node = workflowNode;
- }
-
- @Override
- public String getId() {
- return portId;
- }
-}
http://git-wip-us.apache.org/repos/asf/airavata/blob/509f2037/modules/simple-workflow/src/main/java/org/apache/airavata/simple/workflow/engine/dag/port/Port.java
----------------------------------------------------------------------
diff --git a/modules/simple-workflow/src/main/java/org/apache/airavata/simple/workflow/engine/dag/port/Port.java b/modules/simple-workflow/src/main/java/org/apache/airavata/simple/workflow/engine/dag/port/Port.java
deleted file mode 100644
index 2b27ea0..0000000
--- a/modules/simple-workflow/src/main/java/org/apache/airavata/simple/workflow/engine/dag/port/Port.java
+++ /dev/null
@@ -1,36 +0,0 @@
-/*
- *
- * 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.simple.workflow.engine.dag.port;
-
-import org.apache.airavata.simple.workflow.engine.dag.nodes.WorkflowNode;
-
-public interface Port {
-
- public boolean isReady();
-
- public WorkflowNode getNode();
-
- public void setNode(WorkflowNode workflowNode);
-
- public String getId();
-
-}
http://git-wip-us.apache.org/repos/asf/airavata/blob/509f2037/modules/simple-workflow/src/main/java/org/apache/airavata/simple/workflow/engine/parser/AiravataWorkflowParser.java
----------------------------------------------------------------------
diff --git a/modules/simple-workflow/src/main/java/org/apache/airavata/simple/workflow/engine/parser/AiravataWorkflowParser.java b/modules/simple-workflow/src/main/java/org/apache/airavata/simple/workflow/engine/parser/AiravataWorkflowParser.java
deleted file mode 100644
index f7d53be..0000000
--- a/modules/simple-workflow/src/main/java/org/apache/airavata/simple/workflow/engine/parser/AiravataWorkflowParser.java
+++ /dev/null
@@ -1,291 +0,0 @@
-/*
- *
- * 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.simple.workflow.engine.parser;
-
-import org.airavata.appcatalog.cpi.AppCatalogException;
-import org.airavata.appcatalog.cpi.WorkflowCatalog;
-import org.apache.aiaravata.application.catalog.data.impl.AppCatalogFactory;
-import org.apache.airavata.model.appcatalog.appinterface.InputDataObjectType;
-import org.apache.airavata.model.appcatalog.appinterface.OutputDataObjectType;
-import org.apache.airavata.model.workspace.experiment.Experiment;
-import org.apache.airavata.persistance.registry.jpa.impl.RegistryFactory;
-import org.apache.airavata.registry.cpi.Registry;
-import org.apache.airavata.registry.cpi.RegistryException;
-import org.apache.airavata.registry.cpi.RegistryModelType;
-import org.apache.airavata.simple.workflow.engine.WorkflowParser;
-import org.apache.airavata.simple.workflow.engine.dag.edge.DirectedEdge;
-import org.apache.airavata.simple.workflow.engine.dag.edge.Edge;
-import org.apache.airavata.simple.workflow.engine.dag.nodes.ApplicationNode;
-import org.apache.airavata.simple.workflow.engine.dag.nodes.ApplicationNodeImpl;
-import org.apache.airavata.simple.workflow.engine.dag.nodes.WorkflowInputNode;
-import org.apache.airavata.simple.workflow.engine.dag.nodes.WorkflowInputNodeImpl;
-import org.apache.airavata.simple.workflow.engine.dag.nodes.WorkflowNode;
-import org.apache.airavata.simple.workflow.engine.dag.nodes.WorkflowOutputNode;
-import org.apache.airavata.simple.workflow.engine.dag.nodes.WorkflowOutputNodeImpl;
-import org.apache.airavata.simple.workflow.engine.dag.port.InPort;
-import org.apache.airavata.simple.workflow.engine.dag.port.InputPortIml;
-import org.apache.airavata.simple.workflow.engine.dag.port.OutPort;
-import org.apache.airavata.simple.workflow.engine.dag.port.OutPortImpl;
-import org.apache.airavata.workflow.model.component.ComponentException;
-import org.apache.airavata.workflow.model.component.system.ConstantComponent;
-import org.apache.airavata.workflow.model.component.system.InputComponent;
-import org.apache.airavata.workflow.model.component.system.S3InputComponent;
-import org.apache.airavata.workflow.model.graph.DataEdge;
-import org.apache.airavata.workflow.model.graph.DataPort;
-import org.apache.airavata.workflow.model.graph.GraphException;
-import org.apache.airavata.workflow.model.graph.Node;
-import org.apache.airavata.workflow.model.graph.impl.NodeImpl;
-import org.apache.airavata.workflow.model.graph.system.OutputNode;
-import org.apache.airavata.workflow.model.graph.system.SystemDataPort;
-import org.apache.airavata.workflow.model.graph.ws.WSNode;
-import org.apache.airavata.workflow.model.graph.ws.WSPort;
-import org.apache.airavata.workflow.model.wf.Workflow;
-
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-
-public class AiravataWorkflowParser implements WorkflowParser {
-
- private String credentialToken ;
-
- private Experiment experiment;
- private Map<String, WorkflowNode> wfNodes = new HashMap<String, WorkflowNode>();
-
-
- public AiravataWorkflowParser(String experimentId, String credentialToken) throws RegistryException {
- this.experiment = getExperiment(experimentId);
- this.credentialToken = credentialToken;
- }
-
- public AiravataWorkflowParser(Experiment experiment, String credentialToken) {
- this.credentialToken = credentialToken;
- this.experiment = experiment;
- }
-
- @Override
- public List<WorkflowInputNode> parse() throws RegistryException, AppCatalogException,
- ComponentException, GraphException {
- return parseWorkflow(getWorkflowFromExperiment(experiment));
- }
-
- public List<WorkflowInputNode> parseWorkflow(Workflow workflow) {
- List<Node> gNodes = getInputNodes(workflow);
- List<WorkflowInputNode> wfInputNodes = new ArrayList<WorkflowInputNode>();
- List<PortContainer> portContainers = new ArrayList<PortContainer>();
- List<InputDataObjectType> experimentInputs = experiment.getExperimentInputs();
- Map<String,InputDataObjectType> inputDataMap=new HashMap<String, InputDataObjectType>();
- WorkflowInputNode wfInputNode = null;
- for (InputDataObjectType dataObjectType : experimentInputs) {
- inputDataMap.put(dataObjectType.getName(), dataObjectType);
- }
- for (Node gNode : gNodes) {
- wfInputNode = new WorkflowInputNodeImpl(gNode.getID(), gNode.getName());
- wfInputNode.setInputObject(inputDataMap.get(wfInputNode.getId()));
- if (wfInputNode.getInputObject() == null) {
- throw new RuntimeException("Workflow Input object is not set, workflow node id: " + wfInputNode.getId());
- }
- portContainers.addAll(processOutPorts(gNode, wfInputNode));
- wfInputNodes.add(wfInputNode);
- }
-
- // while port container is not empty iterate graph and build the workflow DAG.
- buildModel(portContainers);
-
- return wfInputNodes;
- }
-
- private void buildModel(List<PortContainer> portContainerList) {
- // end condition of recursive call.
- if (portContainerList == null || portContainerList.isEmpty()) {
- return ;
- }
- DataPort dataPort = null;
- InPort inPort = null;
- ApplicationNode wfApplicationNode = null;
- WorkflowOutputNode wfOutputNode = null;
- List<PortContainer> nextPortContainerList = new ArrayList<PortContainer>();
- for (PortContainer portContainer : portContainerList) {
- dataPort = portContainer.getDataPort();
- inPort = portContainer.getInPort();
- Node node = dataPort.getNode();
- if (node instanceof WSNode) {
- WSNode wsNode = (WSNode) node;
- WorkflowNode wfNode = wfNodes.get(wsNode.getID());
- if (wfNode == null) {
- wfApplicationNode = createApplicationNode(wsNode);
- wfNodes.put(wfApplicationNode.getId(), wfApplicationNode);
- nextPortContainerList.addAll(processOutPorts(wsNode, wfApplicationNode));
- } else if (wfNode instanceof ApplicationNode) {
- wfApplicationNode = (ApplicationNode) wfNode;
- } else {
- throw new IllegalArgumentException("Only support for ApplicationNode implementation, but found other type for node implementation");
- }
- inPort.setNode(wfApplicationNode);
- wfApplicationNode.addInPort(inPort);
-
- }else if (node instanceof OutputNode) {
- OutputNode oNode = (OutputNode) node;
- wfOutputNode = createWorkflowOutputNode(oNode);
- wfOutputNode.setInPort(inPort);
- inPort.setNode(wfOutputNode);
- wfNodes.put(wfOutputNode.getId(), wfOutputNode);
- }
- }
- buildModel(nextPortContainerList);
-
- }
-
- private WorkflowOutputNode createWorkflowOutputNode(OutputNode oNode) {
- WorkflowOutputNodeImpl workflowOutputNode = new WorkflowOutputNodeImpl(oNode.getID(), oNode.getName());
- OutputDataObjectType outputDataObjectType = new OutputDataObjectType();
- outputDataObjectType.setType(oNode.getParameterType());
- workflowOutputNode.setOutputObject(outputDataObjectType);
- return workflowOutputNode;
- }
-
- private ApplicationNode createApplicationNode(WSNode wsNode) {
- ApplicationNode applicationNode = new ApplicationNodeImpl(wsNode.getID(),
- wsNode.getComponent().getApplication().getName(),
- wsNode.getComponent().getApplication().getApplicationId());
- return applicationNode;
- }
-
- private List<PortContainer> processOutPorts(Node node, WorkflowNode wfNode) {
- OutPort outPort ;
- Edge edge;
- InPort inPort = null;
- List<PortContainer> portContainers = new ArrayList<PortContainer>();
- for (DataPort dataPort : node.getOutputPorts()) {
- outPort = createOutPort(dataPort);
- for (DataEdge dataEdge : dataPort.getEdges()) {
- edge = new DirectedEdge();
- edge.setFromPort(outPort);
- outPort.addEdge(edge);
- inPort = createInPort(dataEdge.getToPort());
- edge.setToPort(inPort);
- inPort.addEdge(edge);
- portContainers.add(new PortContainer(dataEdge.getToPort(), inPort));
- }
- outPort.setNode(wfNode);
- if (wfNode instanceof WorkflowInputNode) {
- WorkflowInputNode workflowInputNode = (WorkflowInputNode) wfNode;
- workflowInputNode.setOutPort(outPort);
- } else if (wfNode instanceof ApplicationNode) {
- ApplicationNode applicationNode = ((ApplicationNode) wfNode);
- applicationNode.addOutPort(outPort);
- }
- }
- return portContainers;
- }
-
- private OutPort createOutPort(DataPort dataPort) {
- OutPortImpl outPort = new OutPortImpl(dataPort.getID());
- OutputDataObjectType outputDataObjectType = new OutputDataObjectType();
- if (dataPort instanceof WSPort) {
- WSPort wsPort = (WSPort) dataPort;
- outputDataObjectType.setName(wsPort.getComponentPort().getName());
- outputDataObjectType.setType(wsPort.getType());
- }else if (dataPort instanceof SystemDataPort) {
- SystemDataPort sysPort = (SystemDataPort) dataPort;
- outputDataObjectType.setName(sysPort.getFromNode().getName());
- outputDataObjectType.setType(sysPort.getType());
- }
-
- outPort.setOutputObject(outputDataObjectType);
- return outPort;
- }
-
- private InPort createInPort(DataPort toPort) {
- InPort inPort = new InputPortIml(toPort.getID());
- InputDataObjectType inputDataObjectType = new InputDataObjectType();
- if (toPort instanceof WSPort) {
- WSPort wsPort = (WSPort) toPort;
- inputDataObjectType.setName(wsPort.getName());
- inputDataObjectType.setType(wsPort.getType());
- inputDataObjectType.setApplicationArgument(wsPort.getComponentPort().getApplicationArgument());
- inputDataObjectType.setIsRequired(!wsPort.getComponentPort().isOptional());
- inputDataObjectType.setInputOrder(wsPort.getComponentPort().getInputOrder());
-
- inPort.setDefaultValue(wsPort.getComponentPort().getDefaultValue());
- }else if (toPort instanceof SystemDataPort) {
- SystemDataPort sysPort = (SystemDataPort) toPort;
- inputDataObjectType.setName(sysPort.getName());
- inputDataObjectType.setType(sysPort.getType());
- }
- inPort.setInputObject(inputDataObjectType);
- return inPort;
- }
-
- private InputDataObjectType getInputDataObject(DataPort dataPort) {
- InputDataObjectType inputDataObject = new InputDataObjectType();
- inputDataObject.setName(dataPort.getName());
- if (dataPort instanceof WSPort) {
- WSPort port = (WSPort) dataPort;
- inputDataObject.setInputOrder(port.getComponentPort().getInputOrder());
- inputDataObject.setApplicationArgument(port.getComponentPort().getApplicationArgument() == null ?
- "" : port.getComponentPort().getApplicationArgument());
- inputDataObject.setType(dataPort.getType());
- }
- return inputDataObject;
- }
-
- private OutputDataObjectType getOutputDataObject(InputDataObjectType inputObject) {
- OutputDataObjectType outputDataObjectType = new OutputDataObjectType();
- outputDataObjectType.setApplicationArgument(inputObject.getApplicationArgument());
- outputDataObjectType.setName(inputObject.getName());
- outputDataObjectType.setType(inputObject.getType());
- outputDataObjectType.setValue(inputObject.getValue());
- return outputDataObjectType;
- }
-
- private Experiment getExperiment(String experimentId) throws RegistryException {
- Registry registry = RegistryFactory.getDefaultRegistry();
- return (Experiment)registry.get(RegistryModelType.EXPERIMENT, experimentId);
- }
-
- private Workflow getWorkflowFromExperiment(Experiment experiment) throws RegistryException, AppCatalogException, GraphException, ComponentException {
- WorkflowCatalog workflowCatalog = getWorkflowCatalog();
- return new Workflow(workflowCatalog.getWorkflow(experiment.getApplicationId()).getGraph());
- }
-
- private WorkflowCatalog getWorkflowCatalog() throws AppCatalogException {
- return AppCatalogFactory.getAppCatalog().getWorkflowCatalog();
- }
-
- private ArrayList<Node> getInputNodes(Workflow wf) {
- ArrayList<Node> list = new ArrayList<Node>();
- List<NodeImpl> nodes = wf.getGraph().getNodes();
- for (Node node : nodes) {
- String name = node.getComponent().getName();
- if (InputComponent.NAME.equals(name) || ConstantComponent.NAME.equals(name) || S3InputComponent.NAME.equals(name)) {
- list.add(node);
- }
- }
- return list;
- }
-
- public Map<String, WorkflowNode> getWfNodes() {
- return wfNodes;
- }
-}
http://git-wip-us.apache.org/repos/asf/airavata/blob/509f2037/modules/simple-workflow/src/main/java/org/apache/airavata/simple/workflow/engine/parser/PortContainer.java
----------------------------------------------------------------------
diff --git a/modules/simple-workflow/src/main/java/org/apache/airavata/simple/workflow/engine/parser/PortContainer.java b/modules/simple-workflow/src/main/java/org/apache/airavata/simple/workflow/engine/parser/PortContainer.java
deleted file mode 100644
index 4ddb8b9..0000000
--- a/modules/simple-workflow/src/main/java/org/apache/airavata/simple/workflow/engine/parser/PortContainer.java
+++ /dev/null
@@ -1,53 +0,0 @@
-/*
- *
- * 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.simple.workflow.engine.parser;
-
-import org.apache.airavata.simple.workflow.engine.dag.port.InPort;
-import org.apache.airavata.workflow.model.graph.DataPort;
-
-
-public class PortContainer {
- private DataPort dataPort;
- private InPort inPort;
-
-
- public PortContainer(DataPort dataPort, InPort inPort) {
- this.dataPort = dataPort;
- this.inPort = inPort;
- }
-
- public DataPort getDataPort() {
- return dataPort;
- }
-
- public void setDataPort(DataPort dataPort) {
- this.dataPort = dataPort;
- }
-
- public InPort getInPort() {
- return inPort;
- }
-
- public void setInPort(InPort inPort) {
- this.inPort = inPort;
- }
-}
http://git-wip-us.apache.org/repos/asf/airavata/blob/509f2037/modules/simple-workflow/src/test/java/org/apache/airavata/simple/workflow/engine/WorkflowDAGTest.java
----------------------------------------------------------------------
diff --git a/modules/simple-workflow/src/test/java/org/apache/airavata/simple/workflow/engine/WorkflowDAGTest.java b/modules/simple-workflow/src/test/java/org/apache/airavata/simple/workflow/engine/WorkflowDAGTest.java
deleted file mode 100644
index 9ec95df..0000000
--- a/modules/simple-workflow/src/test/java/org/apache/airavata/simple/workflow/engine/WorkflowDAGTest.java
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
- *
- * 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.simple.workflow.engine;
-
-import org.junit.After;
-import org.junit.Before;
-import org.junit.Test;
-
-public class WorkflowDAGTest {
-
- @Before
- public void setUp() throws Exception {
-
- }
-
- @After
- public void tearDown() throws Exception {
-
- }
-
- @Test
- public void testWorkflowDAG() throws Exception {
-
-
-
- }
-}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/airavata/blob/509f2037/modules/simple-workflow/src/test/java/org/apache/airavata/simple/workflow/engine/parser/AiravataWorkflowParserTest.java
----------------------------------------------------------------------
diff --git a/modules/simple-workflow/src/test/java/org/apache/airavata/simple/workflow/engine/parser/AiravataWorkflowParserTest.java b/modules/simple-workflow/src/test/java/org/apache/airavata/simple/workflow/engine/parser/AiravataWorkflowParserTest.java
deleted file mode 100644
index d843abe..0000000
--- a/modules/simple-workflow/src/test/java/org/apache/airavata/simple/workflow/engine/parser/AiravataWorkflowParserTest.java
+++ /dev/null
@@ -1,119 +0,0 @@
-/*
- *
- * 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.simple.workflow.engine.parser;
-
-import org.apache.airavata.model.appcatalog.appinterface.DataType;
-import org.apache.airavata.model.appcatalog.appinterface.InputDataObjectType;
-import org.apache.airavata.model.workspace.experiment.Experiment;
-import org.apache.airavata.simple.workflow.engine.dag.nodes.ApplicationNode;
-import org.apache.airavata.simple.workflow.engine.dag.nodes.WorkflowInputNode;
-import org.apache.airavata.simple.workflow.engine.dag.nodes.WorkflowNode;
-import org.apache.airavata.simple.workflow.engine.dag.nodes.WorkflowOutputNode;
-import org.apache.airavata.workflow.model.wf.Workflow;
-import org.junit.After;
-import org.junit.Assert;
-import org.junit.Before;
-import org.junit.Test;
-
-import java.io.BufferedReader;
-import java.io.InputStreamReader;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Map;
-
-public class AiravataWorkflowParserTest {
-
- @Before
- public void setUp() throws Exception {
-
- }
-
- @After
- public void tearDown() throws Exception {
-
- }
-
- @Test
- public void testWorkflowParse() throws Exception {
- Assert.assertNotNull("Test file (ComplexMathWorkflow.awf) is missing", getClass().getResource("/ComplexMathWorkflow.awf"));
- InputStreamReader isr = new InputStreamReader(this.getClass().getResourceAsStream("/ComplexMathWorkflow.awf"));
- BufferedReader br = new BufferedReader(isr);
- StringBuffer sb = new StringBuffer();
- String nextLine = br.readLine();
- while (nextLine != null) {
- sb.append(nextLine);
- nextLine = br.readLine();
- }
- Workflow workflow = new Workflow(sb.toString());
- Experiment experiment = new Experiment();
- InputDataObjectType x = new InputDataObjectType();
- x.setValue("6");
- x.setType(DataType.STRING);
- x.setName("x");
-
- InputDataObjectType y = new InputDataObjectType();
- y.setValue("8");
- y.setType(DataType.STRING);
- y.setName("y");
-
- InputDataObjectType z = new InputDataObjectType();
- z.setValue("10");
- z.setType(DataType.STRING);
- z.setName("y_2");
-
- List<InputDataObjectType> inputs = new ArrayList<InputDataObjectType>();
- inputs.add(x);
- inputs.add(y);
- inputs.add(z);
- experiment.setExperimentInputs(inputs);
- // create parser
- AiravataWorkflowParser parser = new AiravataWorkflowParser(experiment, "testCredentialId");
- List<WorkflowInputNode> workflowInputNodes = parser.parseWorkflow(workflow);
- Assert.assertNotNull(workflowInputNodes);
- Assert.assertEquals(3, workflowInputNodes.size());
- for (WorkflowInputNode workflowInputNode : workflowInputNodes) {
- Assert.assertNotNull(workflowInputNode.getOutPort());
- Assert.assertNotNull(workflowInputNode.getInputObject());
- }
-
- Map<String, WorkflowNode> wfNodes = parser.getWfNodes();
- for (String wfId : wfNodes.keySet()) {
- WorkflowNode wfNode = wfNodes.get(wfId);
- if (wfNode instanceof ApplicationNode) {
- ApplicationNode node = (ApplicationNode) wfNode;
- Assert.assertEquals(2, node.getInputPorts().size());
- Assert.assertNotNull(node.getInputPorts().get(0).getInputObject());
- Assert.assertNotNull(node.getInputPorts().get(1).getInputObject());
- Assert.assertNotNull(node.getInputPorts().get(0).getEdge());
- Assert.assertNotNull(node.getInputPorts().get(1).getEdge());
-
- Assert.assertEquals(1, node.getOutputPorts().size());
- Assert.assertEquals(1, node.getOutputPorts().get(0).getOutEdges().size());
- Assert.assertNotNull(node.getOutputPorts().get(0).getOutEdges().get(0));
- } else if (wfNode instanceof WorkflowOutputNode) {
- WorkflowOutputNode workflowOutputNode = (WorkflowOutputNode) wfNode;
- Assert.assertNotNull(workflowOutputNode.getInPort());
- }
- }
-
- }
-}
\ No newline at end of file
[48/50] [abbrv] airavata git commit: Merge branch 'master' of
https://git-wip-us.apache.org/repos/asf/airavata
Posted by sh...@apache.org.
Merge branch 'master' of https://git-wip-us.apache.org/repos/asf/airavata
Project: http://git-wip-us.apache.org/repos/asf/airavata/repo
Commit: http://git-wip-us.apache.org/repos/asf/airavata/commit/4031e502
Tree: http://git-wip-us.apache.org/repos/asf/airavata/tree/4031e502
Diff: http://git-wip-us.apache.org/repos/asf/airavata/diff/4031e502
Branch: refs/heads/master
Commit: 4031e502df7d812cee88df68dcd3b8c1cb6714d5
Parents: 1014cd9 80d9df5
Author: shamrath <sh...@gmail.com>
Authored: Wed Mar 25 16:25:36 2015 -0400
Committer: shamrath <sh...@gmail.com>
Committed: Wed Mar 25 16:25:36 2015 -0400
----------------------------------------------------------------------
.../client/samples/CreateLaunchExperiment.java | 12 ++-
.../gfac/bes/handlers/AbstractSMSHandler.java | 2 +-
.../gfac/bes/provider/impl/BESProvider.java | 18 ++--
.../bes/security/UNICORESecurityContext.java | 58 +++++++++++-
.../gfac/bes/security/X509SecurityContext.java | 93 +++++++++++++++++++-
.../airavata/gfac/bes/utils/BESConstants.java | 7 ++
6 files changed, 176 insertions(+), 14 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/airavata/blob/4031e502/airavata-api/airavata-client-sdks/java-client-samples/src/main/java/org/apache/airavata/client/samples/CreateLaunchExperiment.java
----------------------------------------------------------------------
diff --cc airavata-api/airavata-client-sdks/java-client-samples/src/main/java/org/apache/airavata/client/samples/CreateLaunchExperiment.java
index 1af3450,925528c..4274fbe
--- a/airavata-api/airavata-client-sdks/java-client-samples/src/main/java/org/apache/airavata/client/samples/CreateLaunchExperiment.java
+++ b/airavata-api/airavata-client-sdks/java-client-samples/src/main/java/org/apache/airavata/client/samples/CreateLaunchExperiment.java
@@@ -162,13 -162,13 +162,13 @@@ public class CreateLaunchExperiment
public static void createAndLaunchExp() throws TException {
List<String> experimentIds = new ArrayList<String>();
try {
- for (int i = 0; i < 100; i++) {
+ for (int i = 0; i < 1; i++) {
// final String expId = createExperimentForSSHHost(airavata);
// final String expId = createEchoExperimentForFSD(airavataClient);
- // final String expId = createMPIExperimentForFSD(airavataClient);
+ final String expId = createMPIExperimentForFSD(airavataClient);
// final String expId = createEchoExperimentForStampede(airavataClient);
// final String expId = createEchoExperimentForTrestles(airavataClient);
- final String expId = createExperimentEchoForLocalHost(airavataClient);
+ // final String expId = createExperimentEchoForLocalHost(airavataClient);
experimentIds.add(expId);
// final String expId = createExperimentWRFTrestles(airavataClient);
// final String expId = createExperimentForBR2(airavataClient);
[18/50] [abbrv] airavata git commit: Merged queue-gfac-rabbitmq
Posted by sh...@apache.org.
Merged queue-gfac-rabbitmq
Project: http://git-wip-us.apache.org/repos/asf/airavata/repo
Commit: http://git-wip-us.apache.org/repos/asf/airavata/commit/249b4401
Tree: http://git-wip-us.apache.org/repos/asf/airavata/tree/249b4401
Diff: http://git-wip-us.apache.org/repos/asf/airavata/diff/249b4401
Branch: refs/heads/master
Commit: 249b4401f0bfc821482dfbcb1d02eaf6832b9da1
Parents: 41ea946 840e627
Author: shamrath <sh...@gmail.com>
Authored: Tue Feb 24 10:37:29 2015 -0500
Committer: shamrath <sh...@gmail.com>
Committed: Tue Feb 24 10:37:29 2015 -0500
----------------------------------------------------------------------
.../server/handler/AiravataServerHandler.java | 2 +-
.../lib/airavata/messagingEvents_types.cpp | 202 +++++-
.../lib/airavata/messagingEvents_types.h | 106 ++-
.../Airavata/Model/Messaging/Event/Types.php | 228 +++++++
.../client/samples/CreateLaunchExperiment.java | 19 +-
.../model/messaging/event/MessageType.java | 8 +-
.../model/messaging/event/TaskSubmitEvent.java | 684 +++++++++++++++++++
.../messaging/event/TaskTerminateEvent.java | 492 +++++++++++++
airavata-api/generate-thrift-files.sh | 22 +-
.../messagingEvents.thrift | 16 +-
.../airavata/common/utils/AiravataZKUtils.java | 22 +
.../airavata/common/utils/ServerSettings.java | 24 +-
.../main/resources/airavata-server.properties | 11 +-
.../main/resources/airavata-server.properties | 9 +-
modules/gfac/airavata-gfac-service/pom.xml | 10 +
.../airavata/gfac/server/GfacServerHandler.java | 122 +++-
modules/gfac/gfac-core/pom.xml | 1 +
.../airavata/gfac/core/cpi/BetterGfacImpl.java | 2 +-
.../airavata/gfac/core/utils/GFacUtils.java | 116 +++-
.../messaging/core/MessagingConstants.java | 3 +-
.../messaging/core/PublisherFactory.java | 23 +-
.../airavata/messaging/core/TestClient.java | 5 +-
.../messaging/core/impl/RabbitMQConsumer.java | 258 -------
.../messaging/core/impl/RabbitMQProducer.java | 27 +-
.../messaging/core/impl/RabbitMQPublisher.java | 103 ---
.../core/impl/RabbitMQStatusConsumer.java | 274 ++++++++
.../core/impl/RabbitMQStatusPublisher.java | 103 +++
.../core/impl/RabbitMQTaskLaunchConsumer.java | 244 +++++++
.../core/impl/RabbitMQTaskLaunchPublisher.java | 85 +++
.../server/OrchestratorServerHandler.java | 3 +-
modules/orchestrator/orchestrator-core/pom.xml | 4 +-
.../core/context/OrchestratorContext.java | 11 +
.../core/impl/GFACPassiveJobSubmitter.java | 232 +++++++
.../core/impl/GFACRPCJobSubmitter.java | 212 ++++++
.../core/impl/GFACServiceJobSubmitter.java | 212 ------
.../core/utils/OrchestratorConstants.java | 1 -
.../workflow/engine/WorkflowEngineImpl.java | 4 +-
.../airavata/xbaya/messaging/Monitor.java | 5 +-
pom.xml | 7 +
39 files changed, 3255 insertions(+), 657 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/airavata/blob/249b4401/airavata-api/airavata-client-sdks/java-client-samples/src/main/java/org/apache/airavata/client/samples/CreateLaunchExperiment.java
----------------------------------------------------------------------
diff --cc airavata-api/airavata-client-sdks/java-client-samples/src/main/java/org/apache/airavata/client/samples/CreateLaunchExperiment.java
index 7fbb18b,1e9d983..dd8686d
--- a/airavata-api/airavata-client-sdks/java-client-samples/src/main/java/org/apache/airavata/client/samples/CreateLaunchExperiment.java
+++ b/airavata-api/airavata-client-sdks/java-client-samples/src/main/java/org/apache/airavata/client/samples/CreateLaunchExperiment.java
@@@ -57,10 -60,10 +57,10 @@@ public class CreateLaunchExperiment
private static final String DEFAULT_GATEWAY = "default.registry.gateway";
private static Airavata.Client airavataClient;
- private static String echoAppId = "Echo_7d2a5cde-5b2a-4cad-ae50-f71668f4876d";
+ private static String echoAppId = "Echo_a8fc8511-7b8e-431a-ad0f-de5eb1a9c576";
private static String mpiAppId = "HelloMPI_720e159f-198f-4daa-96ca-9f5eafee92c9";
private static String wrfAppId = "WRF_7ad5da38-c08b-417c-a9ea-da9298839762";
- private static String amberAppId = "Amber_eda074ea-223d-49d7-a942-6c8742249f36";
+ private static String amberAppId = "Amber_42124128-628b-484c-829d-aff8b584eb00";
private static String gromacsAppId = "GROMACS_05622038-9edd-4cb1-824e-0b7cb993364b";
private static String espressoAppId = "ESPRESSO_10cc2820-5d0b-4c63-9546-8a8b595593c1";
private static String lammpsAppId = "LAMMPS_10893eb5-3840-438c-8446-d26c7ecb001f";
http://git-wip-us.apache.org/repos/asf/airavata/blob/249b4401/modules/messaging/core/src/main/java/org/apache/airavata/messaging/core/impl/RabbitMQStatusPublisher.java
----------------------------------------------------------------------
diff --cc modules/messaging/core/src/main/java/org/apache/airavata/messaging/core/impl/RabbitMQStatusPublisher.java
index 0000000,fe06ed7..966d44d
mode 000000,100644..100644
--- a/modules/messaging/core/src/main/java/org/apache/airavata/messaging/core/impl/RabbitMQStatusPublisher.java
+++ b/modules/messaging/core/src/main/java/org/apache/airavata/messaging/core/impl/RabbitMQStatusPublisher.java
@@@ -1,0 -1,99 +1,103 @@@
+ /*
+ *
+ * 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.messaging.core.impl;
+
+ import org.apache.airavata.common.exception.AiravataException;
+ import org.apache.airavata.common.exception.ApplicationSettingsException;
+ import org.apache.airavata.common.utils.ServerSettings;
+ import org.apache.airavata.common.utils.ThriftUtils;
+ import org.apache.airavata.messaging.core.MessageContext;
+ import org.apache.airavata.messaging.core.MessagingConstants;
+ import org.apache.airavata.messaging.core.Publisher;
++import org.apache.airavata.messaging.core.stats.StatCounter;
+ import org.apache.airavata.model.messaging.event.*;
+ import org.apache.thrift.TException;
+ import org.slf4j.Logger;
+ import org.slf4j.LoggerFactory;
+
+ public class RabbitMQStatusPublisher implements Publisher {
+
+ private static Logger log = LoggerFactory.getLogger(RabbitMQStatusPublisher.class);
+
+ private RabbitMQProducer rabbitMQProducer;
+
++ StatCounter statCounter = StatCounter.getInstance();
+
+ public RabbitMQStatusPublisher() throws Exception {
+ String brokerUrl;
+ String exchangeName;
+ try {
+ brokerUrl = ServerSettings.getSetting(MessagingConstants.RABBITMQ_BROKER_URL);
+ exchangeName = ServerSettings.getSetting(MessagingConstants.RABBITMQ_STATUS_EXCHANGE_NAME);
+ } catch (ApplicationSettingsException e) {
+ String message = "Failed to get read the required properties from airavata to initialize rabbitmq";
+ log.error(message, e);
+ throw new AiravataException(message, e);
+ }
+ rabbitMQProducer = new RabbitMQProducer(brokerUrl, exchangeName);
+ rabbitMQProducer.open();
+ }
+
+ public void publish(MessageContext msgCtx) throws AiravataException {
+ try {
+ log.info("Publishing status to rabbitmq...");
+ byte[] body = ThriftUtils.serializeThriftObject(msgCtx.getEvent());
+ Message message = new Message();
+ message.setEvent(body);
+ message.setMessageId(msgCtx.getMessageId());
+ message.setMessageType(msgCtx.getType());
+ message.setUpdatedTime(msgCtx.getUpdatedTime().getTime());
++ String gatewayId = msgCtx.getGatewayId();
+ String routingKey = null;
+ if (msgCtx.getType().equals(MessageType.EXPERIMENT)){
+ ExperimentStatusChangeEvent event = (ExperimentStatusChangeEvent) msgCtx.getEvent();
- routingKey = event.getExperimentId();
++ routingKey = gatewayId + "." + event.getExperimentId();
+ } else if (msgCtx.getType().equals(MessageType.TASK)) {
+ TaskStatusChangeEvent event = (TaskStatusChangeEvent) msgCtx.getEvent();
- routingKey = event.getTaskIdentity().getExperimentId() + "." +
++ routingKey = gatewayId + "." + event.getTaskIdentity().getExperimentId() + "." +
+ event.getTaskIdentity().getWorkflowNodeId() + "." + event.getTaskIdentity().getTaskId();
+ }else if (msgCtx.getType().equals(MessageType.WORKFLOWNODE)){
+ WorkflowNodeStatusChangeEvent event = (WorkflowNodeStatusChangeEvent) msgCtx.getEvent();
+ WorkflowIdentifier workflowNodeIdentity = event.getWorkflowNodeIdentity();
- routingKey = workflowNodeIdentity.getExperimentId() + "." + workflowNodeIdentity.getWorkflowNodeId();
++ routingKey = gatewayId + "." + workflowNodeIdentity.getExperimentId() + "." + workflowNodeIdentity.getWorkflowNodeId();
+ }else if (msgCtx.getType().equals(MessageType.JOB)){
+ JobStatusChangeEvent event = (JobStatusChangeEvent)msgCtx.getEvent();
+ JobIdentifier identity = event.getJobIdentity();
- routingKey = identity.getExperimentId() + "." +
++ routingKey = gatewayId + "." + identity.getExperimentId() + "." +
+ identity.getWorkflowNodeId() + "." +
+ identity.getTaskId() + "." +
+ identity.getJobId();
+ }
+ byte[] messageBody = ThriftUtils.serializeThriftObject(message);
+ rabbitMQProducer.send(messageBody, routingKey);
++ statCounter.add();
+ } catch (TException e) {
+ String msg = "Error while deserializing the object";
+ log.error(msg, e);
+ throw new AiravataException(msg, e);
+ } catch (Exception e) {
+ String msg = "Error while sending to rabbitmq";
+ log.error(msg, e);
+ throw new AiravataException(msg, e);
+ }
+ }
+ }
http://git-wip-us.apache.org/repos/asf/airavata/blob/249b4401/modules/orchestrator/airavata-orchestrator-service/src/main/java/org/apache/airavata/orchestrator/server/OrchestratorServerHandler.java
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/airavata/blob/249b4401/pom.xml
----------------------------------------------------------------------
[10/50] [abbrv] airavata git commit: Refactored Port's isSatisfy api
method to isReady
Posted by sh...@apache.org.
Refactored Port's isSatisfy api method to isReady
Project: http://git-wip-us.apache.org/repos/asf/airavata/repo
Commit: http://git-wip-us.apache.org/repos/asf/airavata/commit/20d6817c
Tree: http://git-wip-us.apache.org/repos/asf/airavata/tree/20d6817c
Diff: http://git-wip-us.apache.org/repos/asf/airavata/diff/20d6817c
Branch: refs/heads/master
Commit: 20d6817c80148483a6e76a443a7b151d333f31ac
Parents: 1a5daae
Author: shamrath <sh...@gmail.com>
Authored: Wed Feb 18 17:11:41 2015 -0500
Committer: shamrath <sh...@gmail.com>
Committed: Wed Feb 18 17:11:41 2015 -0500
----------------------------------------------------------------------
.../simple/workflow/engine/dag/nodes/ApplicationNodeImpl.java | 2 +-
.../ariavata/simple/workflow/engine/dag/port/InputPortIml.java | 2 +-
.../ariavata/simple/workflow/engine/dag/port/OutPortImpl.java | 2 +-
.../org/apache/ariavata/simple/workflow/engine/dag/port/Port.java | 2 +-
4 files changed, 4 insertions(+), 4 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/airavata/blob/20d6817c/modules/simple-workflow/src/main/java/org/apache/ariavata/simple/workflow/engine/dag/nodes/ApplicationNodeImpl.java
----------------------------------------------------------------------
diff --git a/modules/simple-workflow/src/main/java/org/apache/ariavata/simple/workflow/engine/dag/nodes/ApplicationNodeImpl.java b/modules/simple-workflow/src/main/java/org/apache/ariavata/simple/workflow/engine/dag/nodes/ApplicationNodeImpl.java
index cfcd3fb..dd4415a 100644
--- a/modules/simple-workflow/src/main/java/org/apache/ariavata/simple/workflow/engine/dag/nodes/ApplicationNodeImpl.java
+++ b/modules/simple-workflow/src/main/java/org/apache/ariavata/simple/workflow/engine/dag/nodes/ApplicationNodeImpl.java
@@ -73,7 +73,7 @@ public class ApplicationNodeImpl implements ApplicationNode {
@Override
public boolean isReady() {
for (InPort inPort : getInputPorts()) {
- if (!inPort.isSatisfy()) {
+ if (!inPort.isReady()) {
return false;
}
}
http://git-wip-us.apache.org/repos/asf/airavata/blob/20d6817c/modules/simple-workflow/src/main/java/org/apache/ariavata/simple/workflow/engine/dag/port/InputPortIml.java
----------------------------------------------------------------------
diff --git a/modules/simple-workflow/src/main/java/org/apache/ariavata/simple/workflow/engine/dag/port/InputPortIml.java b/modules/simple-workflow/src/main/java/org/apache/ariavata/simple/workflow/engine/dag/port/InputPortIml.java
index b42c11b..1971a1d 100644
--- a/modules/simple-workflow/src/main/java/org/apache/ariavata/simple/workflow/engine/dag/port/InputPortIml.java
+++ b/modules/simple-workflow/src/main/java/org/apache/ariavata/simple/workflow/engine/dag/port/InputPortIml.java
@@ -56,7 +56,7 @@ public class InputPortIml implements InPort {
}
@Override
- public boolean isSatisfy() {
+ public boolean isReady() {
return inputDataObjectType.getValue() != null && !inputDataObjectType.getValue().equals("");
}
http://git-wip-us.apache.org/repos/asf/airavata/blob/20d6817c/modules/simple-workflow/src/main/java/org/apache/ariavata/simple/workflow/engine/dag/port/OutPortImpl.java
----------------------------------------------------------------------
diff --git a/modules/simple-workflow/src/main/java/org/apache/ariavata/simple/workflow/engine/dag/port/OutPortImpl.java b/modules/simple-workflow/src/main/java/org/apache/ariavata/simple/workflow/engine/dag/port/OutPortImpl.java
index f4a690b..a3591ef 100644
--- a/modules/simple-workflow/src/main/java/org/apache/ariavata/simple/workflow/engine/dag/port/OutPortImpl.java
+++ b/modules/simple-workflow/src/main/java/org/apache/ariavata/simple/workflow/engine/dag/port/OutPortImpl.java
@@ -61,7 +61,7 @@ public class OutPortImpl implements OutPort {
}
@Override
- public boolean isSatisfy() {
+ public boolean isReady() {
return this.outputDataObjectType.getValue() != null
&& !this.outputDataObjectType.getValue().equals("");
}
http://git-wip-us.apache.org/repos/asf/airavata/blob/20d6817c/modules/simple-workflow/src/main/java/org/apache/ariavata/simple/workflow/engine/dag/port/Port.java
----------------------------------------------------------------------
diff --git a/modules/simple-workflow/src/main/java/org/apache/ariavata/simple/workflow/engine/dag/port/Port.java b/modules/simple-workflow/src/main/java/org/apache/ariavata/simple/workflow/engine/dag/port/Port.java
index bcd7936..ad8a644 100644
--- a/modules/simple-workflow/src/main/java/org/apache/ariavata/simple/workflow/engine/dag/port/Port.java
+++ b/modules/simple-workflow/src/main/java/org/apache/ariavata/simple/workflow/engine/dag/port/Port.java
@@ -25,7 +25,7 @@ import org.apache.ariavata.simple.workflow.engine.dag.nodes.WorkflowNode;
public interface Port {
- public boolean isSatisfy();
+ public boolean isReady();
public WorkflowNode getNode();
[44/50] [abbrv] airavata git commit: Renamed simple-workflow module
to workflow and created a new workflow-core module which will keep all the
core code
Posted by sh...@apache.org.
http://git-wip-us.apache.org/repos/asf/airavata/blob/509f2037/modules/workflow/pom.xml
----------------------------------------------------------------------
diff --git a/modules/workflow/pom.xml b/modules/workflow/pom.xml
new file mode 100644
index 0000000..4fb8e09
--- /dev/null
+++ b/modules/workflow/pom.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+
+ <parent>
+ <groupId>org.apache.airavata</groupId>
+ <artifactId>airavata</artifactId>
+ <version>0.15-SNAPSHOT</version>
+ <relativePath>../../pom.xml</relativePath>
+ </parent>
+
+ <artifactId>workflow</artifactId>
+ <packaging>pom</packaging>
+ <version>0.15-SNAPSHOT</version>
+ <name>Airavata Workflow</name>
+ <modules>
+ <module>workflow-core</module>
+ </modules>
+
+</project>
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/airavata/blob/509f2037/modules/workflow/workflow-core/pom.xml
----------------------------------------------------------------------
diff --git a/modules/workflow/workflow-core/pom.xml b/modules/workflow/workflow-core/pom.xml
new file mode 100644
index 0000000..1cb8e0d
--- /dev/null
+++ b/modules/workflow/workflow-core/pom.xml
@@ -0,0 +1,74 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+ <parent>
+ <artifactId>workflow</artifactId>
+ <groupId>org.apache.airavata</groupId>
+ <version>0.15-SNAPSHOT</version>
+ </parent>
+ <modelVersion>4.0.0</modelVersion>
+
+ <artifactId>workflow-core</artifactId>
+ <name>Airavata Workflow Core</name>
+
+ <dependencies>
+ <dependency>
+ <groupId>org.apache.airavata</groupId>
+ <artifactId>airavata-data-models</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.airavata</groupId>
+ <artifactId>airavata-registry-cpi</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.airavata</groupId>
+ <artifactId>airavata-model-utils</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.airavata</groupId>
+ <artifactId>airavata-jpa-registry</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+
+ <!-- Airavata default parser dependency -->
+ <dependency>
+ <groupId>org.apache.airavata</groupId>
+ <artifactId>airavata-workflow-model-core</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.airavata</groupId>
+ <artifactId>app-catalog-data</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.airavata</groupId>
+ <artifactId>app-catalog-cpi</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+ <!-- Messaging dependency -->
+ <dependency>
+ <groupId>org.apache.airavata</groupId>
+ <artifactId>airavata-messaging-core</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>com.google.guava</groupId>
+ <artifactId>guava</artifactId>
+ <version>18.0</version>
+ </dependency>
+
+ <!--test-->
+ <dependency>
+ <groupId>junit</groupId>
+ <artifactId>junit</artifactId>
+ <version>4.11</version>
+ <scope>test</scope>
+ </dependency>
+ </dependencies>
+
+</project>
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/airavata/blob/509f2037/modules/workflow/workflow-core/src/main/java/org/apache/airavata/workflow/core/ProcessContext.java
----------------------------------------------------------------------
diff --git a/modules/workflow/workflow-core/src/main/java/org/apache/airavata/workflow/core/ProcessContext.java b/modules/workflow/workflow-core/src/main/java/org/apache/airavata/workflow/core/ProcessContext.java
new file mode 100644
index 0000000..e0c2651
--- /dev/null
+++ b/modules/workflow/workflow-core/src/main/java/org/apache/airavata/workflow/core/ProcessContext.java
@@ -0,0 +1,62 @@
+/*
+ *
+ * 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.workflow.core;
+
+import org.apache.airavata.model.workspace.experiment.TaskDetails;
+import org.apache.airavata.model.workspace.experiment.WorkflowNodeDetails;
+import org.apache.airavata.workflow.core.dag.nodes.WorkflowNode;
+
+public class ProcessContext {
+ private WorkflowNode workflowNode;
+ private WorkflowNodeDetails wfNodeDetails;
+ private TaskDetails taskDetails;
+
+ public ProcessContext(WorkflowNode workflowNode, WorkflowNodeDetails wfNodeDetails, TaskDetails taskDetails) {
+ this.workflowNode = workflowNode;
+ this.wfNodeDetails = wfNodeDetails;
+ this.taskDetails = taskDetails;
+ }
+
+ public WorkflowNode getWorkflowNode() {
+ return workflowNode;
+ }
+
+ public void setWorkflowNode(WorkflowNode workflowNode) {
+ this.workflowNode = workflowNode;
+ }
+
+ public WorkflowNodeDetails getWfNodeDetails() {
+ return wfNodeDetails;
+ }
+
+ public void setWfNodeDetails(WorkflowNodeDetails wfNodeDetails) {
+ this.wfNodeDetails = wfNodeDetails;
+ }
+
+ public TaskDetails getTaskDetails() {
+ return taskDetails;
+ }
+
+ public void setTaskDetails(TaskDetails taskDetails) {
+ this.taskDetails = taskDetails;
+ }
+}
http://git-wip-us.apache.org/repos/asf/airavata/blob/509f2037/modules/workflow/workflow-core/src/main/java/org/apache/airavata/workflow/core/SimpleWorkflowInterpreter.java
----------------------------------------------------------------------
diff --git a/modules/workflow/workflow-core/src/main/java/org/apache/airavata/workflow/core/SimpleWorkflowInterpreter.java b/modules/workflow/workflow-core/src/main/java/org/apache/airavata/workflow/core/SimpleWorkflowInterpreter.java
new file mode 100644
index 0000000..a674aad
--- /dev/null
+++ b/modules/workflow/workflow-core/src/main/java/org/apache/airavata/workflow/core/SimpleWorkflowInterpreter.java
@@ -0,0 +1,400 @@
+/*
+ *
+ * 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.workflow.core;
+
+import org.apache.airavata.common.exception.AiravataException;
+import org.apache.airavata.common.utils.AiravataUtils;
+import org.apache.airavata.messaging.core.MessageContext;
+import org.apache.airavata.messaging.core.impl.RabbitMQProcessPublisher;
+import org.apache.airavata.messaging.core.impl.RabbitMQStatusConsumer;
+import org.apache.airavata.model.appcatalog.appinterface.OutputDataObjectType;
+import org.apache.airavata.model.messaging.event.MessageType;
+import org.apache.airavata.model.messaging.event.ProcessSubmitEvent;
+import org.apache.airavata.model.messaging.event.TaskIdentifier;
+import org.apache.airavata.model.messaging.event.TaskOutputChangeEvent;
+import org.apache.airavata.model.messaging.event.TaskStatusChangeEvent;
+import org.apache.airavata.model.util.ExperimentModelUtil;
+import org.apache.airavata.model.workspace.experiment.ExecutionUnit;
+import org.apache.airavata.model.workspace.experiment.Experiment;
+import org.apache.airavata.model.workspace.experiment.TaskDetails;
+import org.apache.airavata.model.workspace.experiment.TaskState;
+import org.apache.airavata.model.workspace.experiment.WorkflowNodeDetails;
+import org.apache.airavata.model.workspace.experiment.WorkflowNodeState;
+import org.apache.airavata.model.workspace.experiment.WorkflowNodeStatus;
+import org.apache.airavata.persistance.registry.jpa.impl.RegistryFactory;
+import org.apache.airavata.registry.cpi.ChildDataType;
+import org.apache.airavata.registry.cpi.Registry;
+import org.apache.airavata.registry.cpi.RegistryException;
+import org.apache.airavata.registry.cpi.RegistryModelType;
+import org.apache.airavata.workflow.core.dag.edge.Edge;
+import org.apache.airavata.workflow.core.dag.nodes.ApplicationNode;
+import org.apache.airavata.workflow.core.dag.nodes.NodeState;
+import org.apache.airavata.workflow.core.dag.nodes.WorkflowInputNode;
+import org.apache.airavata.workflow.core.dag.nodes.WorkflowNode;
+import org.apache.airavata.workflow.core.dag.nodes.WorkflowOutputNode;
+import org.apache.airavata.workflow.core.dag.port.InPort;
+import org.apache.airavata.workflow.core.dag.port.OutPort;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+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 java.util.concurrent.ConcurrentHashMap;
+
+/**
+ * Package-Private class
+ */
+class SimpleWorkflowInterpreter{
+
+ private static final Logger log = LoggerFactory.getLogger(SimpleWorkflowInterpreter.class);
+ private List<WorkflowInputNode> workflowInputNodes;
+
+ private Experiment experiment;
+
+ private String credentialToken;
+
+ private String gatewayName;
+
+ private Map<String, WorkflowNode> readyList = new ConcurrentHashMap<String, WorkflowNode>();
+ private Map<String, WorkflowNode> waitingList = new ConcurrentHashMap<String, WorkflowNode>();
+ private Map<String, ProcessContext> processingQueue = new ConcurrentHashMap<String, ProcessContext>();
+ private Map<String, ProcessContext> completeList = new HashMap<String, ProcessContext>();
+ private Registry registry;
+ private List<WorkflowOutputNode> completeWorkflowOutputs = new ArrayList<WorkflowOutputNode>();
+ private RabbitMQProcessPublisher publisher;
+ private RabbitMQStatusConsumer statusConsumer;
+ private String consumerId;
+ private boolean continueWorkflow = true;
+
+ public SimpleWorkflowInterpreter(String experimentId, String credentialToken, String gatewayName, RabbitMQProcessPublisher publisher) throws RegistryException {
+ this.gatewayName = gatewayName;
+ setExperiment(experimentId);
+ this.credentialToken = credentialToken;
+ this.publisher = publisher;
+ }
+
+ public SimpleWorkflowInterpreter(Experiment experiment, String credentialStoreToken, String gatewayName, RabbitMQProcessPublisher publisher) {
+ this.gatewayName = gatewayName;
+ this.experiment = experiment;
+ this.credentialToken = credentialStoreToken;
+ this.publisher = publisher;
+ }
+
+ /**
+ * Package-Private method.
+ * @throws Exception
+ */
+ void launchWorkflow() throws Exception {
+ WorkflowFactoryImpl wfFactory = WorkflowFactoryImpl.getInstance();
+ WorkflowParser workflowParser = wfFactory.getWorkflowParser(experiment.getExperimentID(), credentialToken);
+ log.debug("Initialized workflow parser");
+ setWorkflowInputNodes(workflowParser.parse());
+ log.debug("Parsed the workflow and got the workflow input nodes");
+ // process workflow input nodes
+ processWorkflowInputNodes(getWorkflowInputNodes());
+ if (readyList.isEmpty()) {
+ StringBuilder sb = new StringBuilder();
+ for (WorkflowInputNode workflowInputNode : workflowInputNodes) {
+ sb.append(", ");
+ sb.append(workflowInputNode.getInputObject().getName());
+ sb.append("=");
+ sb.append(workflowInputNode.getInputObject().getValue());
+ }
+ throw new AiravataException("No workflow application node is in ready state to run with experiment inputs" + sb.toString());
+ }
+ processReadyList();
+ }
+
+ // try to remove synchronization tag
+ /**
+ * Package-Private method.
+ * @throws RegistryException
+ * @throws AiravataException
+ */
+ void processReadyList() throws RegistryException, AiravataException {
+ if (readyList.isEmpty() && processingQueue.isEmpty() && !waitingList.isEmpty()) {
+ throw new AiravataException("No workflow application node is in ready state to run");
+ }
+ for (WorkflowNode readyNode : readyList.values()) {
+ if (readyNode instanceof WorkflowOutputNode) {
+ WorkflowOutputNode wfOutputNode = (WorkflowOutputNode) readyNode;
+ wfOutputNode.getOutputObject().setValue(wfOutputNode.getInPort().getInputObject().getValue());
+ addToCompleteOutputNodeList(wfOutputNode);
+ continue;
+ }
+ WorkflowNodeDetails workflowNodeDetails = createWorkflowNodeDetails(readyNode);
+ TaskDetails process = getProcess(workflowNodeDetails);
+ ProcessContext processContext = new ProcessContext(readyNode, workflowNodeDetails, process);
+ addToProcessingQueue(processContext);
+ publishToProcessQueue(process);
+ }
+ }
+
+
+ private void publishToProcessQueue(TaskDetails process) throws AiravataException {
+ ProcessSubmitEvent processSubmitEvent = new ProcessSubmitEvent();
+ processSubmitEvent.setCredentialToken(credentialToken);
+ processSubmitEvent.setTaskId(process.getTaskID());
+ MessageContext messageContext = new MessageContext(processSubmitEvent, MessageType.TASK, process.getTaskID(), null);
+ messageContext.setUpdatedTime(AiravataUtils.getCurrentTimestamp());
+ publisher.publish(messageContext);
+ }
+
+ private TaskDetails getProcess(WorkflowNodeDetails wfNodeDetails) throws RegistryException {
+ // create workflow taskDetails from workflowNodeDetails
+ TaskDetails taskDetails = ExperimentModelUtil.cloneTaskFromWorkflowNodeDetails(getExperiment(), wfNodeDetails);
+ taskDetails.setTaskID(getRegistry()
+ .add(ChildDataType.TASK_DETAIL, taskDetails, wfNodeDetails.getNodeInstanceId()).toString());
+ return taskDetails;
+ }
+
+ private WorkflowNodeDetails createWorkflowNodeDetails(WorkflowNode readyNode) throws RegistryException {
+ WorkflowNodeDetails wfNodeDetails = ExperimentModelUtil.createWorkflowNode(readyNode.getId(), null);
+ ExecutionUnit executionUnit = ExecutionUnit.APPLICATION;
+ String executionData = null;
+ if (readyNode instanceof ApplicationNode) {
+ executionUnit = ExecutionUnit.APPLICATION;
+ executionData = ((ApplicationNode) readyNode).getApplicationId();
+ setupNodeDetailsInput(((ApplicationNode) readyNode), wfNodeDetails);
+ } else if (readyNode instanceof WorkflowInputNode) {
+ executionUnit = ExecutionUnit.INPUT;
+ } else if (readyNode instanceof WorkflowOutputNode) {
+ executionUnit = ExecutionUnit.OUTPUT;
+ }
+ wfNodeDetails.setExecutionUnit(executionUnit);
+ wfNodeDetails.setExecutionUnitData(executionData);
+ wfNodeDetails.setNodeInstanceId((String) getRegistry()
+ .add(ChildDataType.WORKFLOW_NODE_DETAIL, wfNodeDetails, getExperiment().getExperimentID()));
+ return wfNodeDetails;
+ }
+
+ private void setupNodeDetailsInput(ApplicationNode readyAppNode, WorkflowNodeDetails wfNodeDetails) {
+ if (readyAppNode.isReady()) {
+ for (InPort inPort : readyAppNode.getInputPorts()) {
+ wfNodeDetails.addToNodeInputs(inPort.getInputObject());
+ }
+ } else {
+ throw new IllegalArgumentException("Application node should be in ready state to set inputs to the " +
+ "workflow node details, nodeId = " + readyAppNode.getId());
+ }
+ }
+
+
+ private void processWorkflowInputNodes(List<WorkflowInputNode> wfInputNodes) {
+ Set<WorkflowNode> tempNodeSet = new HashSet<WorkflowNode>();
+ for (WorkflowInputNode wfInputNode : wfInputNodes) {
+ if (wfInputNode.isReady()) {
+ log.debug("Workflow node : " + wfInputNode.getId() + " is ready to execute");
+ for (Edge edge : wfInputNode.getOutPort().getOutEdges()) {
+ edge.getToPort().getInputObject().setValue(wfInputNode.getInputObject().getValue());
+ if (edge.getToPort().getNode().isReady()) {
+ addToReadyQueue(edge.getToPort().getNode());
+ log.debug("Added workflow node : " + edge.getToPort().getNode().getId() + " to the readyQueue");
+ } else {
+ addToWaitingQueue(edge.getToPort().getNode());
+ log.debug("Added workflow node " + edge.getToPort().getNode().getId() + " to the waitingQueue");
+
+ }
+ }
+ }
+ }
+ }
+
+
+ public List<WorkflowInputNode> getWorkflowInputNodes() throws Exception {
+ return workflowInputNodes;
+ }
+
+ public void setWorkflowInputNodes(List<WorkflowInputNode> workflowInputNodes) {
+ this.workflowInputNodes = workflowInputNodes;
+ }
+
+ private Registry getRegistry() throws RegistryException {
+ if (registry==null){
+ registry = RegistryFactory.getDefaultRegistry();
+ }
+ return registry;
+ }
+
+ public Experiment getExperiment() {
+ return experiment;
+ }
+
+ private void updateWorkflowNodeStatus(WorkflowNodeDetails wfNodeDetails, WorkflowNodeState state) throws RegistryException{
+ WorkflowNodeStatus status = ExperimentModelUtil.createWorkflowNodeStatus(state);
+ wfNodeDetails.setWorkflowNodeStatus(status);
+ getRegistry().update(RegistryModelType.WORKFLOW_NODE_STATUS, status, wfNodeDetails.getNodeInstanceId());
+ }
+
+ /**
+ * Package-Private method.
+ * Remove the workflow node from waiting queue and add it to the ready queue.
+ * @param workflowNode - Workflow Node
+ */
+ synchronized void addToReadyQueue(WorkflowNode workflowNode) {
+ waitingList.remove(workflowNode.getId());
+ readyList.put(workflowNode.getId(), workflowNode);
+ }
+
+ private void addToWaitingQueue(WorkflowNode workflowNode) {
+ waitingList.put(workflowNode.getId(), workflowNode);
+ }
+
+ /**
+ * First remove the node from ready list and then add the WfNodeContainer to the process queue.
+ * Note that underline data structure of the process queue is a Map.
+ * @param processContext - has both workflow and correspond workflowNodeDetails and TaskDetails
+ */
+ private synchronized void addToProcessingQueue(ProcessContext processContext) {
+ readyList.remove(processContext.getWorkflowNode().getId());
+ processingQueue.put(processContext.getTaskDetails().getTaskID(), processContext);
+ }
+
+ private synchronized void addToCompleteQueue(ProcessContext processContext) {
+ processingQueue.remove(processContext.getTaskDetails().getTaskID());
+ completeList.put(processContext.getTaskDetails().getTaskID(), processContext);
+ }
+
+
+ private void addToCompleteOutputNodeList(WorkflowOutputNode wfOutputNode) {
+ completeWorkflowOutputs.add(wfOutputNode);
+ readyList.remove(wfOutputNode.getId());
+ }
+
+ boolean isAllDone() {
+ return !continueWorkflow || (waitingList.isEmpty() && readyList.isEmpty() && processingQueue.isEmpty());
+ }
+
+ private void setExperiment(String experimentId) throws RegistryException {
+ experiment = (Experiment) getRegistry().get(RegistryModelType.EXPERIMENT, experimentId);
+ log.debug("Retrieve Experiment for experiment id : " + experimentId);
+ }
+
+ synchronized void handleTaskOutputChangeEvent(TaskOutputChangeEvent taskOutputChangeEvent) {
+
+ String taskId = taskOutputChangeEvent.getTaskIdentity().getTaskId();
+ log.debug("Task Output changed event received for workflow node : " +
+ taskOutputChangeEvent.getTaskIdentity().getWorkflowNodeId() + ", task : " + taskId);
+ ProcessContext processContext = processingQueue.get(taskId);
+ Set<WorkflowNode> tempWfNodeSet = new HashSet<WorkflowNode>();
+ if (processContext != null) {
+ WorkflowNode workflowNode = processContext.getWorkflowNode();
+ if (workflowNode instanceof ApplicationNode) {
+ ApplicationNode applicationNode = (ApplicationNode) workflowNode;
+ // Workflow node can have one to many output ports and each output port can have one to many links
+ for (OutPort outPort : applicationNode.getOutputPorts()) {
+ for (OutputDataObjectType outputDataObjectType : taskOutputChangeEvent.getOutput()) {
+ if (outPort.getOutputObject().getName().equals(outputDataObjectType.getName())) {
+ outPort.getOutputObject().setValue(outputDataObjectType.getValue());
+ break;
+ }
+ }
+ for (Edge edge : outPort.getOutEdges()) {
+ edge.getToPort().getInputObject().setValue(outPort.getOutputObject().getValue());
+ if (edge.getToPort().getNode().isReady()) {
+ addToReadyQueue(edge.getToPort().getNode());
+ }
+ }
+ }
+ }
+ addToCompleteQueue(processContext);
+ log.debug("removed task from processing queue : " + taskId);
+ try {
+ processReadyList();
+ } catch (Exception e) {
+ log.error("Error while processing ready workflow nodes", e);
+ continueWorkflow = false;
+ }
+ }
+ }
+
+ void handleTaskStatusChangeEvent(TaskStatusChangeEvent taskStatusChangeEvent) {
+ TaskState taskState = taskStatusChangeEvent.getState();
+ TaskIdentifier taskIdentity = taskStatusChangeEvent.getTaskIdentity();
+ String taskId = taskIdentity.getTaskId();
+ ProcessContext processContext = processingQueue.get(taskId);
+ if (processContext != null) {
+ WorkflowNodeState wfNodeState = WorkflowNodeState.INVOKED;
+ switch (taskState) {
+ case WAITING:
+ break;
+ case STARTED:
+ break;
+ case PRE_PROCESSING:
+ wfNodeState = WorkflowNodeState.INVOKED;
+ processContext.getWorkflowNode().setState(NodeState.PRE_PROCESSING);
+ break;
+ case INPUT_DATA_STAGING:
+ wfNodeState = WorkflowNodeState.INVOKED;
+ processContext.getWorkflowNode().setState(NodeState.PRE_PROCESSING);
+ break;
+ case EXECUTING:
+ wfNodeState = WorkflowNodeState.EXECUTING;
+ processContext.getWorkflowNode().setState(NodeState.EXECUTING);
+ break;
+ case OUTPUT_DATA_STAGING:
+ wfNodeState = WorkflowNodeState.COMPLETED;
+ processContext.getWorkflowNode().setState(NodeState.POST_PROCESSING);
+ break;
+ case POST_PROCESSING:
+ wfNodeState = WorkflowNodeState.COMPLETED;
+ processContext.getWorkflowNode().setState(NodeState.POST_PROCESSING);
+ break;
+ case COMPLETED:
+ wfNodeState = WorkflowNodeState.COMPLETED;
+ processContext.getWorkflowNode().setState(NodeState.EXECUTED);
+ break;
+ case FAILED:
+ wfNodeState = WorkflowNodeState.FAILED;
+ processContext.getWorkflowNode().setState(NodeState.FAILED);
+ break;
+ case UNKNOWN:
+ wfNodeState = WorkflowNodeState.UNKNOWN;
+ break;
+ case CONFIGURING_WORKSPACE:
+ wfNodeState = WorkflowNodeState.COMPLETED;
+ break;
+ case CANCELED:
+ case CANCELING:
+ wfNodeState = WorkflowNodeState.CANCELED;
+ processContext.getWorkflowNode().setState(NodeState.FAILED);
+ break;
+ default:
+ break;
+ }
+ if (wfNodeState != WorkflowNodeState.UNKNOWN) {
+ try {
+ updateWorkflowNodeStatus(processContext.getWfNodeDetails(), wfNodeState);
+ } catch (RegistryException e) {
+ log.error("Error while updating workflow node status update to the registry. nodeInstanceId :"
+ + processContext.getWfNodeDetails().getNodeInstanceId() + " status to: "
+ + processContext.getWfNodeDetails().getWorkflowNodeStatus().toString() , e);
+ }
+ }
+ }
+
+ }
+}
http://git-wip-us.apache.org/repos/asf/airavata/blob/509f2037/modules/workflow/workflow-core/src/main/java/org/apache/airavata/workflow/core/WorkflowEnactmentService.java
----------------------------------------------------------------------
diff --git a/modules/workflow/workflow-core/src/main/java/org/apache/airavata/workflow/core/WorkflowEnactmentService.java b/modules/workflow/workflow-core/src/main/java/org/apache/airavata/workflow/core/WorkflowEnactmentService.java
new file mode 100644
index 0000000..7795296
--- /dev/null
+++ b/modules/workflow/workflow-core/src/main/java/org/apache/airavata/workflow/core/WorkflowEnactmentService.java
@@ -0,0 +1,183 @@
+/*
+ *
+ * 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.workflow.core;
+
+import org.apache.airavata.common.exception.AiravataException;
+import org.apache.airavata.common.utils.ServerSettings;
+import org.apache.airavata.messaging.core.MessageContext;
+import org.apache.airavata.messaging.core.MessageHandler;
+import org.apache.airavata.messaging.core.MessagingConstants;
+import org.apache.airavata.messaging.core.impl.RabbitMQProcessPublisher;
+import org.apache.airavata.messaging.core.impl.RabbitMQStatusConsumer;
+import org.apache.airavata.model.messaging.event.MessageType;
+import org.apache.airavata.model.messaging.event.TaskIdentifier;
+import org.apache.airavata.model.messaging.event.TaskOutputChangeEvent;
+import org.apache.airavata.model.messaging.event.TaskStatusChangeEvent;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+
+public class WorkflowEnactmentService {
+
+ private static WorkflowEnactmentService workflowEnactmentService;
+ private final RabbitMQStatusConsumer statusConsumer;
+ private String consumerId;
+ private ExecutorService executor;
+ private Map<String,SimpleWorkflowInterpreter> workflowMap;
+
+ private WorkflowEnactmentService () throws AiravataException {
+ executor = Executors.newFixedThreadPool(getThreadPoolSize());
+ workflowMap = new ConcurrentHashMap<String, SimpleWorkflowInterpreter>();
+ statusConsumer = new RabbitMQStatusConsumer();
+ consumerId = statusConsumer.listen(new TaskMessageHandler());
+ // register the shutdown hook to un-bind status consumer.
+ Runtime.getRuntime().addShutdownHook(new EnactmentShutDownHook());
+ }
+
+ public static WorkflowEnactmentService getInstance() throws AiravataException {
+ if (workflowEnactmentService == null) {
+ synchronized (WorkflowEnactmentService.class) {
+ if (workflowEnactmentService == null) {
+ workflowEnactmentService = new WorkflowEnactmentService();
+ }
+ }
+ }
+ return workflowEnactmentService;
+ }
+
+ public void submitWorkflow(String experimentId,
+ String credentialToken,
+ String gatewayName,
+ RabbitMQProcessPublisher publisher) throws Exception {
+
+ SimpleWorkflowInterpreter simpleWorkflowInterpreter = new SimpleWorkflowInterpreter(
+ experimentId, credentialToken,gatewayName, publisher);
+ workflowMap.put(experimentId, simpleWorkflowInterpreter);
+ simpleWorkflowInterpreter.launchWorkflow();
+
+ }
+
+ private int getThreadPoolSize() {
+ return ServerSettings.getEnactmentThreadPoolSize();
+ }
+
+ private class TaskMessageHandler implements MessageHandler {
+
+ @Override
+ public Map<String, Object> getProperties() {
+ Map<String, Object> props = new HashMap<String, Object>();
+ String gatewayId = "*";
+ String experimentId = "*";
+ List<String> routingKeys = new ArrayList<String>();
+ routingKeys.add(gatewayId);
+ routingKeys.add(gatewayId + "." + experimentId);
+ routingKeys.add(gatewayId + "." + experimentId+ ".*");
+ routingKeys.add(gatewayId + "." + experimentId+ ".*.*");
+ props.put(MessagingConstants.RABBIT_ROUTING_KEY, routingKeys);
+ return props;
+ }
+
+ @Override
+ public void onMessage(MessageContext msgCtx) {
+ StatusHandler statusHandler = new StatusHandler(msgCtx);
+ executor.execute(statusHandler);
+ }
+
+
+ }
+
+ private class StatusHandler implements Runnable{
+ private final Logger log = LoggerFactory.getLogger(StatusHandler.class);
+
+ private final MessageContext msgCtx;
+
+ public StatusHandler(MessageContext msgCtx) {
+ this.msgCtx = msgCtx;
+ }
+
+ @Override
+ public void run() {
+ process();
+ }
+
+ private void process() {
+ String message;
+ SimpleWorkflowInterpreter simpleWorkflowInterpreter;
+ if (msgCtx.getType() == MessageType.TASK) {
+ TaskStatusChangeEvent event = (TaskStatusChangeEvent) msgCtx.getEvent();
+ TaskIdentifier taskIdentifier = event.getTaskIdentity();
+ simpleWorkflowInterpreter = getInterpreter(taskIdentifier.getExperimentId());
+ if (simpleWorkflowInterpreter != null) {
+ simpleWorkflowInterpreter.handleTaskStatusChangeEvent(event);
+ } else {
+ // this happens when Task status messages comes after the Taskoutput messages,as we have worked on
+ // output changes it is ok to ignore this.
+ }
+ message = "Received task output change event , expId : " + taskIdentifier.getExperimentId() + ", taskId : " + taskIdentifier.getTaskId() + ", workflow node Id : " + taskIdentifier.getWorkflowNodeId();
+ log.debug(message);
+ }else if (msgCtx.getType() == MessageType.TASKOUTPUT) {
+ TaskOutputChangeEvent event = (TaskOutputChangeEvent) msgCtx.getEvent();
+ TaskIdentifier taskIdentifier = event.getTaskIdentity();
+ simpleWorkflowInterpreter = getInterpreter(taskIdentifier.getExperimentId());
+ if (simpleWorkflowInterpreter != null) {
+ simpleWorkflowInterpreter.handleTaskOutputChangeEvent(event);
+ if (simpleWorkflowInterpreter.isAllDone()) {
+ workflowMap.remove(taskIdentifier.getExperimentId());
+ }
+ } else {
+ throw new IllegalArgumentException("Error while processing TaskOutputChangeEvent, " +
+ "There is no registered workflow for experiment Id : " + taskIdentifier.getExperimentId());
+ }
+ message = "Received task output change event , expId : " + taskIdentifier.getExperimentId() + ", taskId : " + taskIdentifier.getTaskId() + ", workflow node Id : " + taskIdentifier.getWorkflowNodeId();
+ log.debug(message);
+ } else {
+ // not interested, ignores
+ }
+ }
+
+ private SimpleWorkflowInterpreter getInterpreter(String experimentId){
+ return workflowMap.get(experimentId);
+ }
+ }
+
+
+ private class EnactmentShutDownHook extends Thread {
+ private final Logger log = LoggerFactory.getLogger(EnactmentShutDownHook.class);
+ @Override
+ public void run() {
+ super.run();
+ try {
+ statusConsumer.stopListen(consumerId);
+ log.info("Successfully un-binded task status consumer");
+ } catch (AiravataException e) {
+ log.error("Error while un-bind enactment status consumer", e);
+ }
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/airavata/blob/509f2037/modules/workflow/workflow-core/src/main/java/org/apache/airavata/workflow/core/WorkflowFactory.java
----------------------------------------------------------------------
diff --git a/modules/workflow/workflow-core/src/main/java/org/apache/airavata/workflow/core/WorkflowFactory.java b/modules/workflow/workflow-core/src/main/java/org/apache/airavata/workflow/core/WorkflowFactory.java
new file mode 100644
index 0000000..ee89dd9
--- /dev/null
+++ b/modules/workflow/workflow-core/src/main/java/org/apache/airavata/workflow/core/WorkflowFactory.java
@@ -0,0 +1,31 @@
+/*
+ *
+ * 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.workflow.core;
+
+/**
+ * All classes implement this WorkflowFactory interface, should be abstract or singleton.
+ */
+public interface WorkflowFactory {
+
+ public WorkflowParser getWorkflowParser(String experimentId, String credentialToken) throws Exception;
+
+}
http://git-wip-us.apache.org/repos/asf/airavata/blob/509f2037/modules/workflow/workflow-core/src/main/java/org/apache/airavata/workflow/core/WorkflowFactoryImpl.java
----------------------------------------------------------------------
diff --git a/modules/workflow/workflow-core/src/main/java/org/apache/airavata/workflow/core/WorkflowFactoryImpl.java b/modules/workflow/workflow-core/src/main/java/org/apache/airavata/workflow/core/WorkflowFactoryImpl.java
new file mode 100644
index 0000000..1df2084
--- /dev/null
+++ b/modules/workflow/workflow-core/src/main/java/org/apache/airavata/workflow/core/WorkflowFactoryImpl.java
@@ -0,0 +1,74 @@
+/*
+ *
+ * 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.workflow.core;
+
+import org.apache.airavata.common.exception.ApplicationSettingsException;
+import org.apache.airavata.common.utils.ServerSettings;
+import org.apache.airavata.workflow.core.parser.AiravataWorkflowParser;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.lang.reflect.Constructor;
+
+/**
+ * Singleton class, only one instance can exist in runtime.
+ */
+public class WorkflowFactoryImpl implements WorkflowFactory {
+
+ private static final Logger log = LoggerFactory.getLogger(WorkflowFactoryImpl.class);
+
+ private static WorkflowFactoryImpl workflowFactoryImpl;
+
+ private WorkflowFactoryImpl(){
+
+ }
+
+ public static WorkflowFactoryImpl getInstance() {
+ if (workflowFactoryImpl == null) {
+ synchronized (WorkflowFactory.class) {
+ if (workflowFactoryImpl == null) {
+ workflowFactoryImpl = new WorkflowFactoryImpl();
+ }
+ }
+ }
+ return workflowFactoryImpl;
+ }
+
+
+ @Override
+ public WorkflowParser getWorkflowParser(String experimentId, String credentialToken) throws Exception {
+ WorkflowParser workflowParser = null;
+ try {
+ String wfParserClassName = ServerSettings.getWorkflowParser();
+ Class<?> aClass = Class.forName(wfParserClassName);
+ Constructor<?> constructor = aClass.getConstructor(String.class, String.class);
+ workflowParser = (WorkflowParser) constructor.newInstance(experimentId, credentialToken);
+ } catch (ApplicationSettingsException e) {
+ log.info("A custom workflow parser is not defined, Use default Airavata workflow parser");
+ }
+ if (workflowParser == null) {
+ workflowParser = new AiravataWorkflowParser(experimentId, credentialToken);
+ }
+ return workflowParser;
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/airavata/blob/509f2037/modules/workflow/workflow-core/src/main/java/org/apache/airavata/workflow/core/WorkflowParser.java
----------------------------------------------------------------------
diff --git a/modules/workflow/workflow-core/src/main/java/org/apache/airavata/workflow/core/WorkflowParser.java b/modules/workflow/workflow-core/src/main/java/org/apache/airavata/workflow/core/WorkflowParser.java
new file mode 100644
index 0000000..8d284dd
--- /dev/null
+++ b/modules/workflow/workflow-core/src/main/java/org/apache/airavata/workflow/core/WorkflowParser.java
@@ -0,0 +1,32 @@
+/*
+ *
+ * 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.workflow.core;
+
+import org.apache.airavata.workflow.core.dag.nodes.WorkflowInputNode;
+
+import java.util.List;
+
+public interface WorkflowParser {
+
+ public List<WorkflowInputNode> parse() throws Exception;
+
+}
http://git-wip-us.apache.org/repos/asf/airavata/blob/509f2037/modules/workflow/workflow-core/src/main/java/org/apache/airavata/workflow/core/dag/edge/DirectedEdge.java
----------------------------------------------------------------------
diff --git a/modules/workflow/workflow-core/src/main/java/org/apache/airavata/workflow/core/dag/edge/DirectedEdge.java b/modules/workflow/workflow-core/src/main/java/org/apache/airavata/workflow/core/dag/edge/DirectedEdge.java
new file mode 100644
index 0000000..91118cc
--- /dev/null
+++ b/modules/workflow/workflow-core/src/main/java/org/apache/airavata/workflow/core/dag/edge/DirectedEdge.java
@@ -0,0 +1,52 @@
+/*
+ *
+ * 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.workflow.core.dag.edge;
+
+import org.apache.airavata.workflow.core.dag.port.InPort;
+import org.apache.airavata.workflow.core.dag.port.OutPort;
+
+
+public class DirectedEdge implements Edge {
+
+ private InPort inPort;
+ private OutPort outPort;
+
+ @Override
+ public InPort getToPort() {
+ return inPort;
+ }
+
+ @Override
+ public void setToPort(InPort inPort) {
+ this.inPort = inPort;
+ }
+
+ @Override
+ public OutPort getFromPort() {
+ return outPort;
+ }
+
+ @Override
+ public void setFromPort(OutPort outPort) {
+ this.outPort = outPort;
+ }
+}
http://git-wip-us.apache.org/repos/asf/airavata/blob/509f2037/modules/workflow/workflow-core/src/main/java/org/apache/airavata/workflow/core/dag/edge/Edge.java
----------------------------------------------------------------------
diff --git a/modules/workflow/workflow-core/src/main/java/org/apache/airavata/workflow/core/dag/edge/Edge.java b/modules/workflow/workflow-core/src/main/java/org/apache/airavata/workflow/core/dag/edge/Edge.java
new file mode 100644
index 0000000..ee11371
--- /dev/null
+++ b/modules/workflow/workflow-core/src/main/java/org/apache/airavata/workflow/core/dag/edge/Edge.java
@@ -0,0 +1,43 @@
+/*
+ *
+ * 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.workflow.core.dag.edge;
+
+import org.apache.airavata.workflow.core.dag.port.InPort;
+import org.apache.airavata.workflow.core.dag.port.OutPort;
+
+/**
+ * Edge is a link to one node to another, basically edge should have outPort of a workflow node ,
+ * which is starting point and inPort of a workflow node, which is end point of the edge.
+ */
+
+public interface Edge {
+
+ public InPort getToPort();
+
+ public void setToPort(InPort inPort);
+
+ public OutPort getFromPort();
+
+ public void setFromPort(OutPort outPort);
+
+
+}
http://git-wip-us.apache.org/repos/asf/airavata/blob/509f2037/modules/workflow/workflow-core/src/main/java/org/apache/airavata/workflow/core/dag/nodes/ApplicationNode.java
----------------------------------------------------------------------
diff --git a/modules/workflow/workflow-core/src/main/java/org/apache/airavata/workflow/core/dag/nodes/ApplicationNode.java b/modules/workflow/workflow-core/src/main/java/org/apache/airavata/workflow/core/dag/nodes/ApplicationNode.java
new file mode 100644
index 0000000..d775bf4
--- /dev/null
+++ b/modules/workflow/workflow-core/src/main/java/org/apache/airavata/workflow/core/dag/nodes/ApplicationNode.java
@@ -0,0 +1,41 @@
+/*
+ *
+ * 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.workflow.core.dag.nodes;
+
+import org.apache.airavata.workflow.core.dag.port.InPort;
+import org.apache.airavata.workflow.core.dag.port.OutPort;
+
+import java.util.List;
+
+public interface ApplicationNode extends WorkflowNode {
+
+ public String getApplicationId();
+
+ public void addInPort(InPort inPort);
+
+ public List<InPort> getInputPorts();
+
+ public void addOutPort(OutPort outPort);
+
+ public List<OutPort> getOutputPorts();
+
+}
http://git-wip-us.apache.org/repos/asf/airavata/blob/509f2037/modules/workflow/workflow-core/src/main/java/org/apache/airavata/workflow/core/dag/nodes/ApplicationNodeImpl.java
----------------------------------------------------------------------
diff --git a/modules/workflow/workflow-core/src/main/java/org/apache/airavata/workflow/core/dag/nodes/ApplicationNodeImpl.java b/modules/workflow/workflow-core/src/main/java/org/apache/airavata/workflow/core/dag/nodes/ApplicationNodeImpl.java
new file mode 100644
index 0000000..ad7bd63
--- /dev/null
+++ b/modules/workflow/workflow-core/src/main/java/org/apache/airavata/workflow/core/dag/nodes/ApplicationNodeImpl.java
@@ -0,0 +1,116 @@
+/*
+ *
+ * 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.workflow.core.dag.nodes;
+
+import org.apache.airavata.workflow.core.dag.port.InPort;
+import org.apache.airavata.workflow.core.dag.port.OutPort;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class ApplicationNodeImpl implements ApplicationNode {
+
+ private final String nodeId;
+ private NodeState myState = NodeState.WAITING;
+ private String applicationId;
+ private List<InPort> inPorts = new ArrayList<InPort>();
+ private List<OutPort> outPorts = new ArrayList<OutPort>();
+ private String applicationName;
+
+// public ApplicationNodeImpl(String nodeId) {
+// this(nodeId, null);
+// }
+//
+// public ApplicationNodeImpl(String nodeId, String applicationId) {
+// this(nodeId, null, applicationId);
+// }
+
+ public ApplicationNodeImpl(String nodeId, String applicationName, String applicationId) {
+ this.nodeId = nodeId;
+ this.applicationName = applicationName;
+ this.applicationId = applicationId;
+ }
+
+ @Override
+ public String getId() {
+ return this.nodeId;
+ }
+
+ @Override
+ public String getName() {
+ return applicationName;
+ }
+
+ @Override
+ public NodeType getType() {
+ return NodeType.APPLICATION;
+ }
+
+ @Override
+ public NodeState getState() {
+ return myState;
+ }
+
+ @Override
+ public void setState(NodeState newState) {
+ if (newState.getLevel() > myState.getLevel()) {
+ myState = newState;
+ } else {
+ throw new IllegalStateException("Node state can't be reversed. currentState : " + myState.toString() + " , newState " + newState.toString());
+ }
+ }
+
+ @Override
+ public boolean isReady() {
+ for (InPort inPort : getInputPorts()) {
+ if (!inPort.isReady()) {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ @Override
+ public String getApplicationId() {
+ return this.applicationId;
+ }
+
+ @Override
+ public void addInPort(InPort inPort) {
+ this.inPorts.add(inPort);
+ }
+
+ @Override
+ public List<InPort> getInputPorts() {
+ return this.inPorts;
+ }
+
+ @Override
+ public void addOutPort(OutPort outPort) {
+ this.outPorts.add(outPort);
+ }
+
+ @Override
+ public List<OutPort> getOutputPorts() {
+ return this.outPorts;
+ }
+}
http://git-wip-us.apache.org/repos/asf/airavata/blob/509f2037/modules/workflow/workflow-core/src/main/java/org/apache/airavata/workflow/core/dag/nodes/NodeState.java
----------------------------------------------------------------------
diff --git a/modules/workflow/workflow-core/src/main/java/org/apache/airavata/workflow/core/dag/nodes/NodeState.java b/modules/workflow/workflow-core/src/main/java/org/apache/airavata/workflow/core/dag/nodes/NodeState.java
new file mode 100644
index 0000000..df2c87a
--- /dev/null
+++ b/modules/workflow/workflow-core/src/main/java/org/apache/airavata/workflow/core/dag/nodes/NodeState.java
@@ -0,0 +1,44 @@
+/*
+ *
+ * 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.workflow.core.dag.nodes;
+
+public enum NodeState {
+ WAITING(0), // waiting on inputs
+ READY(1), // all inputs are available and ready to execute
+ QUEUED(2), //
+ PRE_PROCESSING(3), //
+ EXECUTING(4), // task has been submitted , not yet finish
+ EXECUTED(5), // task executed
+ POST_PROCESSING(6), //
+ FAILED(7),
+ COMPLETE(8); // all works done
+
+ private int level;
+
+ NodeState(int level) {
+ this.level = level;
+ }
+
+ public int getLevel() {
+ return level;
+ }
+}
http://git-wip-us.apache.org/repos/asf/airavata/blob/509f2037/modules/workflow/workflow-core/src/main/java/org/apache/airavata/workflow/core/dag/nodes/NodeType.java
----------------------------------------------------------------------
diff --git a/modules/workflow/workflow-core/src/main/java/org/apache/airavata/workflow/core/dag/nodes/NodeType.java b/modules/workflow/workflow-core/src/main/java/org/apache/airavata/workflow/core/dag/nodes/NodeType.java
new file mode 100644
index 0000000..04e4c07
--- /dev/null
+++ b/modules/workflow/workflow-core/src/main/java/org/apache/airavata/workflow/core/dag/nodes/NodeType.java
@@ -0,0 +1,28 @@
+/*
+ *
+ * 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.workflow.core.dag.nodes;
+
+public enum NodeType {
+ APPLICATION,
+ WORKFLOW_INPUT,
+ WORKFLOW_OUTPUT
+}
http://git-wip-us.apache.org/repos/asf/airavata/blob/509f2037/modules/workflow/workflow-core/src/main/java/org/apache/airavata/workflow/core/dag/nodes/WorkflowInputNode.java
----------------------------------------------------------------------
diff --git a/modules/workflow/workflow-core/src/main/java/org/apache/airavata/workflow/core/dag/nodes/WorkflowInputNode.java b/modules/workflow/workflow-core/src/main/java/org/apache/airavata/workflow/core/dag/nodes/WorkflowInputNode.java
new file mode 100644
index 0000000..83bcacf
--- /dev/null
+++ b/modules/workflow/workflow-core/src/main/java/org/apache/airavata/workflow/core/dag/nodes/WorkflowInputNode.java
@@ -0,0 +1,37 @@
+/*
+ *
+ * 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.workflow.core.dag.nodes;
+
+import org.apache.airavata.model.appcatalog.appinterface.InputDataObjectType;
+import org.apache.airavata.workflow.core.dag.port.OutPort;
+
+public interface WorkflowInputNode extends WorkflowNode {
+
+ public InputDataObjectType getInputObject();
+
+ public void setInputObject(InputDataObjectType inputObject);
+
+ public OutPort getOutPort();
+
+ public void setOutPort(OutPort outPort);
+
+}
http://git-wip-us.apache.org/repos/asf/airavata/blob/509f2037/modules/workflow/workflow-core/src/main/java/org/apache/airavata/workflow/core/dag/nodes/WorkflowInputNodeImpl.java
----------------------------------------------------------------------
diff --git a/modules/workflow/workflow-core/src/main/java/org/apache/airavata/workflow/core/dag/nodes/WorkflowInputNodeImpl.java b/modules/workflow/workflow-core/src/main/java/org/apache/airavata/workflow/core/dag/nodes/WorkflowInputNodeImpl.java
new file mode 100644
index 0000000..2364b03
--- /dev/null
+++ b/modules/workflow/workflow-core/src/main/java/org/apache/airavata/workflow/core/dag/nodes/WorkflowInputNodeImpl.java
@@ -0,0 +1,99 @@
+/*
+ * 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.workflow.core.dag.nodes;
+
+import org.apache.airavata.model.appcatalog.appinterface.InputDataObjectType;
+import org.apache.airavata.workflow.core.dag.port.OutPort;
+
+public class WorkflowInputNodeImpl implements WorkflowInputNode {
+
+ private NodeState myState = NodeState.READY;
+ private final String nodeId;
+ private String nodeName;
+ private OutPort outPort;
+ private InputDataObjectType inputDataObjectType;
+ private String name;
+
+ public WorkflowInputNodeImpl(String nodeId) {
+ this(nodeId, null);
+ }
+
+ public WorkflowInputNodeImpl(String nodeId, String nodeName) {
+ this.nodeId = nodeId;
+ this.nodeName = nodeName;
+ }
+
+ @Override
+ public String getId() {
+ return this.nodeId;
+ }
+
+ @Override
+ public String getName() {
+ return this.nodeName;
+ }
+
+ @Override
+ public NodeType getType() {
+ return NodeType.WORKFLOW_INPUT;
+ }
+
+ @Override
+ public NodeState getState() {
+ return myState;
+ }
+
+ @Override
+ public void setState(NodeState newState) {
+ if (newState.getLevel() > myState.getLevel()) {
+ myState = newState;
+ } else {
+ throw new IllegalStateException("Node state can't be reversed. currentState : " + myState.toString() + " , newState " + newState.toString());
+ }
+ }
+
+ @Override
+ public boolean isReady() {
+ return (inputDataObjectType.getValue() != null && !inputDataObjectType.getValue().equals(""))
+ || !inputDataObjectType.isIsRequired();
+ }
+
+ @Override
+ public InputDataObjectType getInputObject() {
+ return this.inputDataObjectType;
+ }
+
+ @Override
+ public void setInputObject(InputDataObjectType inputObject) {
+ this.inputDataObjectType = inputObject;
+ }
+
+ @Override
+ public OutPort getOutPort() {
+ return this.outPort;
+ }
+
+ @Override
+ public void setOutPort(OutPort outPort) {
+ this.outPort = outPort;
+ }
+
+
+}
http://git-wip-us.apache.org/repos/asf/airavata/blob/509f2037/modules/workflow/workflow-core/src/main/java/org/apache/airavata/workflow/core/dag/nodes/WorkflowNode.java
----------------------------------------------------------------------
diff --git a/modules/workflow/workflow-core/src/main/java/org/apache/airavata/workflow/core/dag/nodes/WorkflowNode.java b/modules/workflow/workflow-core/src/main/java/org/apache/airavata/workflow/core/dag/nodes/WorkflowNode.java
new file mode 100644
index 0000000..e86a740
--- /dev/null
+++ b/modules/workflow/workflow-core/src/main/java/org/apache/airavata/workflow/core/dag/nodes/WorkflowNode.java
@@ -0,0 +1,38 @@
+/*
+ *
+ * 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.workflow.core.dag.nodes;
+
+public interface WorkflowNode {
+
+ public String getId();
+
+ public String getName();
+
+ public NodeType getType();
+
+ public NodeState getState();
+
+ public void setState(NodeState newState);
+
+ public boolean isReady();
+
+}
http://git-wip-us.apache.org/repos/asf/airavata/blob/509f2037/modules/workflow/workflow-core/src/main/java/org/apache/airavata/workflow/core/dag/nodes/WorkflowOutputNode.java
----------------------------------------------------------------------
diff --git a/modules/workflow/workflow-core/src/main/java/org/apache/airavata/workflow/core/dag/nodes/WorkflowOutputNode.java b/modules/workflow/workflow-core/src/main/java/org/apache/airavata/workflow/core/dag/nodes/WorkflowOutputNode.java
new file mode 100644
index 0000000..340ac30
--- /dev/null
+++ b/modules/workflow/workflow-core/src/main/java/org/apache/airavata/workflow/core/dag/nodes/WorkflowOutputNode.java
@@ -0,0 +1,37 @@
+/*
+ *
+ * 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.workflow.core.dag.nodes;
+
+import org.apache.airavata.model.appcatalog.appinterface.OutputDataObjectType;
+import org.apache.airavata.workflow.core.dag.port.InPort;
+
+public interface WorkflowOutputNode extends WorkflowNode {
+
+ public OutputDataObjectType getOutputObject();
+
+ public void setOutputObject(OutputDataObjectType outputObject);
+
+ public InPort getInPort();
+
+ public void setInPort(InPort inPort);
+
+}
http://git-wip-us.apache.org/repos/asf/airavata/blob/509f2037/modules/workflow/workflow-core/src/main/java/org/apache/airavata/workflow/core/dag/nodes/WorkflowOutputNodeImpl.java
----------------------------------------------------------------------
diff --git a/modules/workflow/workflow-core/src/main/java/org/apache/airavata/workflow/core/dag/nodes/WorkflowOutputNodeImpl.java b/modules/workflow/workflow-core/src/main/java/org/apache/airavata/workflow/core/dag/nodes/WorkflowOutputNodeImpl.java
new file mode 100644
index 0000000..294109f
--- /dev/null
+++ b/modules/workflow/workflow-core/src/main/java/org/apache/airavata/workflow/core/dag/nodes/WorkflowOutputNodeImpl.java
@@ -0,0 +1,100 @@
+/*
+ *
+ * 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.workflow.core.dag.nodes;
+
+import org.apache.airavata.model.appcatalog.appinterface.OutputDataObjectType;
+import org.apache.airavata.workflow.core.dag.port.InPort;
+
+public class WorkflowOutputNodeImpl implements WorkflowOutputNode {
+
+ private NodeState myState = NodeState.WAITING;
+ private final String nodeId;
+ private String nodeName;
+ private OutputDataObjectType outputDataObjectType;
+ private InPort inPort;
+
+ public WorkflowOutputNodeImpl(String nodeId) {
+ this(nodeId, null);
+ }
+
+ public WorkflowOutputNodeImpl(String nodeId, String nodeName) {
+ this.nodeId = nodeId;
+ this.nodeName = nodeName;
+ }
+
+ @Override
+ public String getId() {
+ return this.nodeId;
+ }
+
+ @Override
+ public String getName() {
+ return this.nodeName;
+ }
+
+ @Override
+ public NodeType getType() {
+ return NodeType.WORKFLOW_OUTPUT;
+ }
+
+ @Override
+ public NodeState getState() {
+ return myState;
+ }
+
+ @Override
+ public void setState(NodeState newState) {
+ if (newState.getLevel() > myState.getLevel()) {
+ myState = newState;
+ } else {
+ throw new IllegalStateException("Node state can't be reversed. currentState : " + myState.toString() + " , newState " + newState.toString());
+ }
+ }
+
+ @Override
+ public boolean isReady() {
+ return !(inPort.getInputObject() == null || inPort.getInputObject().getValue() == null
+ || inPort.getInputObject().getValue().equals(""));
+ }
+
+ @Override
+ public OutputDataObjectType getOutputObject() {
+ return this.outputDataObjectType;
+ }
+
+ @Override
+ public void setOutputObject(OutputDataObjectType outputObject) {
+ this.outputDataObjectType = outputObject;
+ }
+
+ @Override
+ public InPort getInPort() {
+ return this.inPort;
+ }
+
+ @Override
+ public void setInPort(InPort inPort) {
+ this.inPort = inPort;
+ }
+
+}
+
http://git-wip-us.apache.org/repos/asf/airavata/blob/509f2037/modules/workflow/workflow-core/src/main/java/org/apache/airavata/workflow/core/dag/port/InPort.java
----------------------------------------------------------------------
diff --git a/modules/workflow/workflow-core/src/main/java/org/apache/airavata/workflow/core/dag/port/InPort.java b/modules/workflow/workflow-core/src/main/java/org/apache/airavata/workflow/core/dag/port/InPort.java
new file mode 100644
index 0000000..fb8dfa7
--- /dev/null
+++ b/modules/workflow/workflow-core/src/main/java/org/apache/airavata/workflow/core/dag/port/InPort.java
@@ -0,0 +1,41 @@
+/*
+ *
+ * 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.workflow.core.dag.port;
+
+import org.apache.airavata.model.appcatalog.appinterface.InputDataObjectType;
+import org.apache.airavata.workflow.core.dag.edge.Edge;
+
+public interface InPort extends Port {
+
+ public void setInputObject(InputDataObjectType inputObject);
+
+ public InputDataObjectType getInputObject();
+
+ public Edge getEdge();
+
+ public void addEdge(Edge edge);
+
+ public String getDefaultValue();
+
+ public void setDefaultValue(String defaultValue);
+
+}
http://git-wip-us.apache.org/repos/asf/airavata/blob/509f2037/modules/workflow/workflow-core/src/main/java/org/apache/airavata/workflow/core/dag/port/InputPortIml.java
----------------------------------------------------------------------
diff --git a/modules/workflow/workflow-core/src/main/java/org/apache/airavata/workflow/core/dag/port/InputPortIml.java b/modules/workflow/workflow-core/src/main/java/org/apache/airavata/workflow/core/dag/port/InputPortIml.java
new file mode 100644
index 0000000..43a41be
--- /dev/null
+++ b/modules/workflow/workflow-core/src/main/java/org/apache/airavata/workflow/core/dag/port/InputPortIml.java
@@ -0,0 +1,91 @@
+/*
+ * 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.workflow.core.dag.port;
+
+import org.apache.airavata.model.appcatalog.appinterface.InputDataObjectType;
+import org.apache.airavata.workflow.core.dag.edge.Edge;
+import org.apache.airavata.workflow.core.dag.nodes.WorkflowNode;
+
+public class InputPortIml implements InPort {
+
+ private InputDataObjectType inputDataObjectType;
+ private boolean ready = false;
+ private String portId;
+ private Edge edge;
+ private WorkflowNode node;
+ private String defaultValue;
+
+ public InputPortIml(String portId) {
+ this.portId = portId;
+ }
+
+ @Override
+ public void setInputObject(InputDataObjectType inputObject) {
+ this.inputDataObjectType = inputObject;
+ ready = (inputDataObjectType.getValue() != null && !inputDataObjectType.getValue().equals(""))
+ || !inputDataObjectType.isIsRequired();
+ }
+
+ @Override
+ public InputDataObjectType getInputObject() {
+ return this.inputDataObjectType;
+ }
+
+ @Override
+ public Edge getEdge() {
+ return this.edge;
+ }
+
+ @Override
+ public void addEdge(Edge edge) {
+ this.edge = edge;
+ }
+
+ @Override
+ public String getDefaultValue() {
+ return defaultValue;
+ }
+
+ public void setDefaultValue(String defaultValue) {
+ this.defaultValue = defaultValue;
+ }
+
+ @Override
+ public boolean isReady() {
+ return getInputObject() != null && (!inputDataObjectType.isIsRequired() ||
+ (inputDataObjectType.getValue() != null && !inputDataObjectType.getValue().equals("")));
+ }
+
+ @Override
+ public WorkflowNode getNode() {
+ return this.node;
+ }
+
+ @Override
+ public void setNode(WorkflowNode workflowNode) {
+ this.node = workflowNode;
+ }
+
+ @Override
+ public String getId() {
+ return this.portId;
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/airavata/blob/509f2037/modules/workflow/workflow-core/src/main/java/org/apache/airavata/workflow/core/dag/port/OutPort.java
----------------------------------------------------------------------
diff --git a/modules/workflow/workflow-core/src/main/java/org/apache/airavata/workflow/core/dag/port/OutPort.java b/modules/workflow/workflow-core/src/main/java/org/apache/airavata/workflow/core/dag/port/OutPort.java
new file mode 100644
index 0000000..d9aa004
--- /dev/null
+++ b/modules/workflow/workflow-core/src/main/java/org/apache/airavata/workflow/core/dag/port/OutPort.java
@@ -0,0 +1,39 @@
+/*
+ *
+ * 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.workflow.core.dag.port;
+
+import org.apache.airavata.model.appcatalog.appinterface.OutputDataObjectType;
+import org.apache.airavata.workflow.core.dag.edge.Edge;
+
+import java.util.List;
+
+public interface OutPort extends Port {
+
+ public void setOutputObject(OutputDataObjectType outputObject);
+
+ public OutputDataObjectType getOutputObject();
+
+ public List<Edge> getOutEdges();
+
+ public void addEdge(Edge edge);
+
+}
http://git-wip-us.apache.org/repos/asf/airavata/blob/509f2037/modules/workflow/workflow-core/src/main/java/org/apache/airavata/workflow/core/dag/port/OutPortImpl.java
----------------------------------------------------------------------
diff --git a/modules/workflow/workflow-core/src/main/java/org/apache/airavata/workflow/core/dag/port/OutPortImpl.java b/modules/workflow/workflow-core/src/main/java/org/apache/airavata/workflow/core/dag/port/OutPortImpl.java
new file mode 100644
index 0000000..9c3f86a
--- /dev/null
+++ b/modules/workflow/workflow-core/src/main/java/org/apache/airavata/workflow/core/dag/port/OutPortImpl.java
@@ -0,0 +1,83 @@
+/*
+ *
+ * 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.workflow.core.dag.port;
+
+import org.apache.airavata.model.appcatalog.appinterface.OutputDataObjectType;
+import org.apache.airavata.workflow.core.dag.edge.Edge;
+import org.apache.airavata.workflow.core.dag.nodes.WorkflowNode;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class OutPortImpl implements OutPort {
+
+ private OutputDataObjectType outputDataObjectType;
+ private List<Edge> outEdges = new ArrayList<Edge>();
+ private boolean isSatisfy = false;
+ private String portId;
+ private WorkflowNode node;
+
+ public OutPortImpl(String portId) {
+ this.portId = portId;
+ }
+
+ @Override
+ public void setOutputObject(OutputDataObjectType outputObject) {
+ this.outputDataObjectType = outputObject;
+ }
+
+ @Override
+ public OutputDataObjectType getOutputObject() {
+ return this.outputDataObjectType;
+ }
+
+ @Override
+ public List<Edge> getOutEdges() {
+ return this.outEdges;
+ }
+
+ @Override
+ public void addEdge(Edge edge) {
+ this.outEdges.add(edge);
+ }
+
+ @Override
+ public boolean isReady() {
+ return this.outputDataObjectType.getValue() != null
+ && !this.outputDataObjectType.getValue().equals("");
+ }
+
+ @Override
+ public WorkflowNode getNode() {
+ return this.node;
+ }
+
+ @Override
+ public void setNode(WorkflowNode workflowNode) {
+ this.node = workflowNode;
+ }
+
+ @Override
+ public String getId() {
+ return portId;
+ }
+}
http://git-wip-us.apache.org/repos/asf/airavata/blob/509f2037/modules/workflow/workflow-core/src/main/java/org/apache/airavata/workflow/core/dag/port/Port.java
----------------------------------------------------------------------
diff --git a/modules/workflow/workflow-core/src/main/java/org/apache/airavata/workflow/core/dag/port/Port.java b/modules/workflow/workflow-core/src/main/java/org/apache/airavata/workflow/core/dag/port/Port.java
new file mode 100644
index 0000000..e3756cf
--- /dev/null
+++ b/modules/workflow/workflow-core/src/main/java/org/apache/airavata/workflow/core/dag/port/Port.java
@@ -0,0 +1,36 @@
+/*
+ *
+ * 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.workflow.core.dag.port;
+
+import org.apache.airavata.workflow.core.dag.nodes.WorkflowNode;
+
+public interface Port {
+
+ public boolean isReady();
+
+ public WorkflowNode getNode();
+
+ public void setNode(WorkflowNode workflowNode);
+
+ public String getId();
+
+}
[50/50] [abbrv] airavata git commit: Use default gateway Id if
credential reader fail to retrieve the gateway id using token.
Posted by sh...@apache.org.
Use default gateway Id if credential reader fail to retrieve the gateway id using token.
Project: http://git-wip-us.apache.org/repos/asf/airavata/repo
Commit: http://git-wip-us.apache.org/repos/asf/airavata/commit/a6c483cd
Tree: http://git-wip-us.apache.org/repos/asf/airavata/tree/a6c483cd
Diff: http://git-wip-us.apache.org/repos/asf/airavata/diff/a6c483cd
Branch: refs/heads/master
Commit: a6c483cdb07da24f5c9875c2a321c516b9723d78
Parents: 220e041
Author: shamrath <sh...@gmail.com>
Authored: Thu Mar 26 13:05:12 2015 -0400
Committer: shamrath <sh...@gmail.com>
Committed: Thu Mar 26 13:05:12 2015 -0400
----------------------------------------------------------------------
.../server/src/main/resources/airavata-server.properties | 2 +-
.../orchestrator/server/OrchestratorServerHandler.java | 6 ++++--
2 files changed, 5 insertions(+), 3 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/airavata/blob/a6c483cd/modules/configuration/server/src/main/resources/airavata-server.properties
----------------------------------------------------------------------
diff --git a/modules/configuration/server/src/main/resources/airavata-server.properties b/modules/configuration/server/src/main/resources/airavata-server.properties
index b957922..38a6fdd 100644
--- a/modules/configuration/server/src/main/resources/airavata-server.properties
+++ b/modules/configuration/server/src/main/resources/airavata-server.properties
@@ -220,7 +220,7 @@ connection.name=xsede
#publisher
rabbitmq.broker.url=amqp://localhost:5672
-activity.listeners=org.apache.airavata.gfac.core.monitor.AiravataJobStatusUpdator,org.apache.airavata.gfac.core.monitor.AiravataTaskStatusUpdator,org.apache.airavata.gfac.core.monitor.AiravataWorkflowNodeStatusUpdator,org.apache.airavata.api.server.listener.AiravataExperimentStatusUpdator,org.apache.airavata.gfac.core.monitor.GfacInternalStatusUpdator,org.apache.airavata.workflow.engine.util.ProxyMonitorPublisher
+activity.listeners=org.apache.airavata.gfac.core.monitor.AiravataJobStatusUpdator,org.apache.airavata.gfac.core.monitor.AiravataTaskStatusUpdator,org.apache.airavata.gfac.core.monitor.AiravataWorkflowNodeStatusUpdator,org.apache.airavata.api.server.listener.AiravataExperimentStatusUpdator,org.apache.airavata.gfac.core.monitor.GfacInternalStatusUpdator
publish.rabbitmq=false
status.publisher=org.apache.airavata.messaging.core.impl.RabbitMQStatusPublisher
task.launch.publisher=org.apache.airavata.messaging.core.impl.RabbitMQTaskLaunchPublisher
http://git-wip-us.apache.org/repos/asf/airavata/blob/a6c483cd/modules/orchestrator/airavata-orchestrator-service/src/main/java/org/apache/airavata/orchestrator/server/OrchestratorServerHandler.java
----------------------------------------------------------------------
diff --git a/modules/orchestrator/airavata-orchestrator-service/src/main/java/org/apache/airavata/orchestrator/server/OrchestratorServerHandler.java b/modules/orchestrator/airavata-orchestrator-service/src/main/java/org/apache/airavata/orchestrator/server/OrchestratorServerHandler.java
index 9cf44a9..0297cb6 100644
--- a/modules/orchestrator/airavata-orchestrator-service/src/main/java/org/apache/airavata/orchestrator/server/OrchestratorServerHandler.java
+++ b/modules/orchestrator/airavata-orchestrator-service/src/main/java/org/apache/airavata/orchestrator/server/OrchestratorServerHandler.java
@@ -246,7 +246,9 @@ public class OrchestratorServerHandler implements OrchestratorService.Iface,
}
}
if (gatewayId == null) {
- throw new AiravataException("Couldn't identify the gateway Id using the credential token");
+ gatewayId = ServerSettings.getDefaultUserGateway();
+ log.info("Couldn't identify the gateway Id using the credential token, Use default gateway Id");
+// throw new AiravataException("Couldn't identify the gateway Id using the credential token");
}
ExecutionType executionType = DataModelUtils.getExecutionType(gatewayId, experiment);
if (executionType == ExecutionType.SINGLE_APP) {
@@ -262,7 +264,7 @@ public class OrchestratorServerHandler implements OrchestratorService.Iface,
throw new TException("Experiment '" + experimentId + "' launch failed. Unable to figureout execution type for application " + experiment.getApplicationId());
}
} catch (Exception e) {
- throw new TException("Experiment '" + experimentId + "' launch failed. Unable to figureout execution type for application " + experiment.getApplicationId());
+ throw new TException("Experiment '" + experimentId + "' launch failed. Unable to figureout execution type for application " + experiment.getApplicationId(), e);
}
return true;
}
[38/50] [abbrv] airavata git commit: Added token field to workflow
launch window to provide valid token when launching an experiment.
Posted by sh...@apache.org.
Added token field to workflow launch window to provide valid token when launching an experiment.
Project: http://git-wip-us.apache.org/repos/asf/airavata/repo
Commit: http://git-wip-us.apache.org/repos/asf/airavata/commit/5e5630d3
Tree: http://git-wip-us.apache.org/repos/asf/airavata/tree/5e5630d3
Diff: http://git-wip-us.apache.org/repos/asf/airavata/diff/5e5630d3
Branch: refs/heads/master
Commit: 5e5630d32ccf267260ada711a5b0d3b65bd6b081
Parents: 7d787b8
Author: shamrath <sh...@gmail.com>
Authored: Wed Mar 25 11:35:01 2015 -0400
Committer: shamrath <sh...@gmail.com>
Committed: Wed Mar 25 11:35:01 2015 -0400
----------------------------------------------------------------------
.../experiment/WorkflowInterpreterLaunchWindow.java | 16 +++++++++-------
1 file changed, 9 insertions(+), 7 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/airavata/blob/5e5630d3/modules/xbaya-gui/src/main/java/org/apache/airavata/xbaya/ui/experiment/WorkflowInterpreterLaunchWindow.java
----------------------------------------------------------------------
diff --git a/modules/xbaya-gui/src/main/java/org/apache/airavata/xbaya/ui/experiment/WorkflowInterpreterLaunchWindow.java b/modules/xbaya-gui/src/main/java/org/apache/airavata/xbaya/ui/experiment/WorkflowInterpreterLaunchWindow.java
index df27269..1678f19 100644
--- a/modules/xbaya-gui/src/main/java/org/apache/airavata/xbaya/ui/experiment/WorkflowInterpreterLaunchWindow.java
+++ b/modules/xbaya-gui/src/main/java/org/apache/airavata/xbaya/ui/experiment/WorkflowInterpreterLaunchWindow.java
@@ -99,6 +99,7 @@ public class WorkflowInterpreterLaunchWindow {
private JComboBox host;
private HashMap<String, String> hostNames;
+ private XBayaTextField token;
/**
* Constructs a WorkflowInterpreterLaunchWindow.
@@ -172,9 +173,7 @@ public class WorkflowInterpreterLaunchWindow {
e2.printStackTrace();
}
-
hostNames = new HashMap<String, String>();
-
Iterator it=hosts.entrySet().iterator();
while(it.hasNext()){
Map.Entry pairs=(Map.Entry)it.next();
@@ -192,7 +191,6 @@ public class WorkflowInterpreterLaunchWindow {
host.addItem(key);
}
host.setSelectedIndex(0);
-
XBayaLabel hostLabel = new XBayaLabel("Host", host);
this.parameterPanel.add(hostLabel);
this.parameterPanel.add(host);
@@ -212,14 +210,18 @@ public class WorkflowInterpreterLaunchWindow {
private void initGUI() {
this.parameterPanel = new GridPanel(true);
+ GridPanel infoPanel = new GridPanel();
this.instanceNameTextField = new XBayaTextField();
XBayaLabel instanceNameLabel = new XBayaLabel("Experiment name", this.instanceNameTextField);
-
- GridPanel infoPanel = new GridPanel();
infoPanel.add(instanceNameLabel);
infoPanel.add(this.instanceNameTextField);
- infoPanel.layout(1, 2, GridPanel.WEIGHT_NONE, 1);
+
+ token = new XBayaTextField("");
+ JLabel tokenLabel = new JLabel("Token Id: ");
+ infoPanel.add(tokenLabel);
+ infoPanel.add(token);
+ infoPanel.layout(2, 2, GridPanel.WEIGHT_NONE, 1);
GridPanel mainPanel = new GridPanel();
mainPanel.getContentPanel().setBorder(BorderFactory.createEtchedBorder(EtchedBorder.LOWERED));
@@ -376,7 +378,7 @@ public class WorkflowInterpreterLaunchWindow {
} catch (MonitorException e) {
logger.error("Error while subscribing with experiment Id : " + experiment.getExperimentID(), e);
}
- airavataClient.launchExperiment(experiment.getExperimentID(), "testToken");
+ airavataClient.launchExperiment(experiment.getExperimentID(), token.getText());
hide();
}