Implemented JsonWorkflowParser and added unit tests
Project: http://git-wip-us.apache.org/repos/asf/airavata/repo Commit: http://git-wip-us.apache.org/repos/asf/airavata/commit/11ea5014 Tree: http://git-wip-us.apache.org/repos/asf/airavata/tree/11ea5014 Diff: http://git-wip-us.apache.org/repos/asf/airavata/diff/11ea5014 Branch: refs/heads/master Commit: 11ea5014aaf16eadb02614aaa75cc2a18191d3e8 Parents: 54bb719 Author: Shameera Rathnayaka <[email protected]> Authored: Mon Feb 8 17:18:20 2016 -0500 Committer: Shameera Rathnayaka <[email protected]> Committed: Mon Feb 8 17:18:20 2016 -0500 ---------------------------------------------------------------------- modules/workflow/workflow-core/pom.xml | 5 + .../airavata/workflow/core/WorkflowInfo.java | 87 ++++ .../workflow/core/dag/edge/DirectedEdge.java | 4 + .../core/dag/nodes/ApplicationNode.java | 5 + .../core/dag/nodes/ApplicationNodeImpl.java | 11 + .../core/parser/JsonWorkflowParser.java | 519 ++++++++++++++++++- .../workflow/core/parser/ParserException.java | 40 ++ .../workflow/core/parser/WorkflowParser.java | 3 +- .../airavata/workflow/core/WorkflowDAGTest.java | 46 -- .../core/parser/JsonWorkflowParserTest.java | 83 ++- .../src/test/resources/TestWorkflow.json | 8 +- 11 files changed, 738 insertions(+), 73 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/airavata/blob/11ea5014/modules/workflow/workflow-core/pom.xml ---------------------------------------------------------------------- diff --git a/modules/workflow/workflow-core/pom.xml b/modules/workflow/workflow-core/pom.xml index 72990c8..51d7735 100644 --- a/modules/workflow/workflow-core/pom.xml +++ b/modules/workflow/workflow-core/pom.xml @@ -37,6 +37,11 @@ <artifactId>airavata-gfac-core</artifactId> <version>${project.version}</version> </dependency> + <dependency> + <groupId>com.google.code.gson</groupId> + <artifactId>gson</artifactId> + <version>2.4</version> + </dependency> <!-- Airavata default parser dependency --> <dependency> <groupId>org.apache.airavata</groupId> http://git-wip-us.apache.org/repos/asf/airavata/blob/11ea5014/modules/workflow/workflow-core/src/main/java/org/apache/airavata/workflow/core/WorkflowInfo.java ---------------------------------------------------------------------- diff --git a/modules/workflow/workflow-core/src/main/java/org/apache/airavata/workflow/core/WorkflowInfo.java b/modules/workflow/workflow-core/src/main/java/org/apache/airavata/workflow/core/WorkflowInfo.java new file mode 100644 index 0000000..a0dd859 --- /dev/null +++ b/modules/workflow/workflow-core/src/main/java/org/apache/airavata/workflow/core/WorkflowInfo.java @@ -0,0 +1,87 @@ +/* + * + * 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; + +public class WorkflowInfo { + private String name; + private String id; + private String description; + private String version; + private int applicationCount; + private int inputCount; + private int outputCount; + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public String getDescription() { + return description; + } + + public void setDescription(String description) { + this.description = description; + } + + public String getVersion() { + return version; + } + + public void setVersion(String version) { + this.version = version; + } + + public int getApplicationCount() { + return applicationCount; + } + + public void setApplicationCount(int applicationCount) { + this.applicationCount = applicationCount; + } + + public int getInputCount() { + return inputCount; + } + + public void setInputCount(int inputCount) { + this.inputCount = inputCount; + } + + public int getOutputCount() { + return outputCount; + } + + public void setOutputCount(int outputCount) { + this.outputCount = outputCount; + } +} http://git-wip-us.apache.org/repos/asf/airavata/blob/11ea5014/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 index 3ad7afa..e8b7f07 100644 --- 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 @@ -32,6 +32,10 @@ public class DirectedEdge implements Edge { private OutPort outPort; private EdgeModel edgeModel; + public DirectedEdge(EdgeModel edgeModel) { + this.edgeModel = edgeModel; + } + @Override public String getId() { return getEdgeModel().getEdgeId(); http://git-wip-us.apache.org/repos/asf/airavata/blob/11ea5014/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 index ab876cc..00eccb0 100644 --- 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 @@ -24,6 +24,7 @@ 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.Collection; import java.util.List; public interface ApplicationNode extends WorkflowNode { @@ -40,4 +41,8 @@ public interface ApplicationNode extends WorkflowNode { public List<OutPort> getOutputPorts(); + public void addInputPorts(Collection<? extends InPort> inPorts); + + public void addOutPorts(Collection<? extends OutPort> outPorts); + } http://git-wip-us.apache.org/repos/asf/airavata/blob/11ea5014/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 index adc865f..cedf657 100644 --- 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 @@ -28,6 +28,7 @@ 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.Collection; import java.util.List; public class ApplicationNodeImpl implements ApplicationNode { @@ -119,4 +120,14 @@ public class ApplicationNodeImpl implements ApplicationNode { public List<OutPort> getOutputPorts() { return this.outPorts; } + + @Override + public void addInputPorts(Collection<? extends InPort> inPorts) { + this.inPorts.addAll(inPorts); + } + + @Override + public void addOutPorts(Collection<? extends OutPort> outPorts) { + this.outPorts.addAll(outPorts); + } } http://git-wip-us.apache.org/repos/asf/airavata/blob/11ea5014/modules/workflow/workflow-core/src/main/java/org/apache/airavata/workflow/core/parser/JsonWorkflowParser.java ---------------------------------------------------------------------- diff --git a/modules/workflow/workflow-core/src/main/java/org/apache/airavata/workflow/core/parser/JsonWorkflowParser.java b/modules/workflow/workflow-core/src/main/java/org/apache/airavata/workflow/core/parser/JsonWorkflowParser.java index f6bb084..7484f7e 100644 --- a/modules/workflow/workflow-core/src/main/java/org/apache/airavata/workflow/core/parser/JsonWorkflowParser.java +++ b/modules/workflow/workflow-core/src/main/java/org/apache/airavata/workflow/core/parser/JsonWorkflowParser.java @@ -22,63 +22,485 @@ package org.apache.airavata.workflow.core.parser; import com.google.gson.JsonObject; +import com.google.gson.stream.JsonReader; +import com.google.gson.stream.JsonToken; +import org.apache.airavata.model.EdgeModel; +import org.apache.airavata.model.NodeModel; +import org.apache.airavata.model.PortModel; +import org.apache.airavata.workflow.core.WorkflowInfo; +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.InputNode; +import org.apache.airavata.workflow.core.dag.nodes.InputNodeImpl; import org.apache.airavata.workflow.core.dag.nodes.OutputNode; +import org.apache.airavata.workflow.core.dag.nodes.OutputNodeImpl; +import org.apache.airavata.workflow.core.dag.nodes.WorkflowNode; +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.core.dag.port.Port; +import java.io.ByteArrayInputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; import java.util.ArrayList; +import java.util.HashMap; import java.util.List; +import java.util.Map; public class JsonWorkflowParser implements WorkflowParser { - private final String workflow; + private final JsonReader jsonReader; + private List<InputNode> inputs; private List<OutputNode> outputs; private List<ApplicationNode> applications; + private Map<String, WorkflowNode> nodeMap; private List<Port> ports; private List<Edge> edges; + private List<Link> links; + private WorkflowInfo workflowInfo; public JsonWorkflowParser(String jsonWorkflowString) { - workflow = jsonWorkflowString; + this(new ByteArrayInputStream(jsonWorkflowString.getBytes())); + } + public JsonWorkflowParser(InputStream inputStream) { + this(new InputStreamReader(inputStream)); + } + + public JsonWorkflowParser(InputStreamReader inputStreamReader) { + this(new JsonReader(inputStreamReader)); + } + + public JsonWorkflowParser(JsonReader jsonReader) { + this.jsonReader = jsonReader; + init(); + } + + private void init() { + applications = new ArrayList<>(); + nodeMap = new HashMap<>(); inputs = new ArrayList<>(); outputs = new ArrayList<>(); - applications = new ArrayList<>(); - ports = new ArrayList<>(); - edges = new ArrayList<>(); + links = new ArrayList<>(); + workflowInfo = new WorkflowInfo(); + } @Override - public void parse() throws Exception { + public WorkflowInfo parse() throws Exception { // TODO parse json string and construct components + if (jsonReader.peek() != JsonToken.BEGIN_OBJECT) { + throw new Exception("Invalid Json data expected beginObject but found " + getTokenString(jsonReader.peek())); + } + jsonReader.beginObject(); + while (jsonReader.hasNext()) { + String name = jsonReader.nextName(); // workflow + if (name.equals(WORKFLOW)) { + readWorkflowInfo(jsonReader); + } else { + jsonReader.skipValue(); + } + } + jsonReader.endObject(); + + buildWorkflowDAG(); + return workflowInfo; + } + + private void buildWorkflowDAG() { + // TODO construct runtime model + + } + + private void readWorkflowInfo(JsonReader jsonReader) throws IOException, ParserException { + jsonReader.beginObject(); + String name; + while (jsonReader.hasNext()) { + name = jsonReader.nextName(); + if (name.equals(NAME)) { + workflowInfo.setName(jsonReader.nextString()); + } else if (name.equals(ID)) { + workflowInfo.setId(jsonReader.nextString()); + } else if (name.equals(DESCRIPTION)) { + workflowInfo.setDescription(jsonReader.nextString()); + } else if (name.equals(VERSION)) { + workflowInfo.setVersion(jsonReader.nextString()); + } else if (name.equals(APPLICATIONS)) { + readApplications(jsonReader); + } else if (name.equals(WORKFLOW_INPUTS)) { + readWorkflowInputs(jsonReader); + } else if (name.equals(WORKFLOW_OUTPUTS)) { + readWorkflowOutputs(jsonReader); + } else if (name.equals(LINKS)) { + readWorkflowLinks(jsonReader); + } else { + jsonReader.skipValue(); + } + } + jsonReader.endObject(); + //TODO: set count properties of workflow info object + } + + private void readApplications(JsonReader jsonReader) throws IOException, ParserException { + jsonReader.beginArray(); + ApplicationNode appNode = null; + while (jsonReader.hasNext()) { + appNode = readApplication(jsonReader); + applications.add(appNode); + } + jsonReader.endArray(); + } + + private void readWorkflowInputs(JsonReader jsonReader) throws ParserException, IOException { + JsonToken peek = jsonReader.peek(); + InputNode inputNode; + NodeModel nodeModel; + String name; + if (peek == JsonToken.NULL) { + throw new ParserException("Error! workflow inputs can't be null"); + } else if (peek == JsonToken.BEGIN_ARRAY) { + jsonReader.beginArray(); + while (jsonReader.hasNext()) { + jsonReader.beginObject(); + nodeModel = new NodeModel(); + inputNode = new InputNodeImpl(nodeModel); + while (jsonReader.hasNext()) { + name = jsonReader.nextName(); + if (name.equals(NAME)) { + nodeModel.setName(jsonReader.nextString()); + } else if (name.equals(ID)) { + nodeModel.setNodeId(jsonReader.nextString()); + } else if (name.equals(DATATYPE)) { + jsonReader.skipValue(); + } else if (name.equals(DESCRIPTION)) { + nodeModel.setDescription(jsonReader.nextString()); + } else if (name.equals(POSITION)) { + readPosition(jsonReader); + } else if (name.equals(NODE_ID)) { + nodeModel.setNodeId(jsonReader.nextString()); + } else { + jsonReader.skipValue(); + } + } + jsonReader.endObject(); + inputs.add(inputNode); + } + jsonReader.endArray(); + } else { + throw new ParserException("Error! Unsupported value for Workflow Inputs, exptected " + + getTokenString(JsonToken.BEGIN_OBJECT) + " but found" + getTokenString(peek)); + } + } + + private void readWorkflowOutputs(JsonReader jsonReader) throws IOException, ParserException { + JsonToken peek = jsonReader.peek(); + OutputNode outputNode; + NodeModel nodeModel; + String name; + if (peek == JsonToken.NULL) { + throw new ParserException("Error! workflow outputs can't be null"); + } else if (peek == JsonToken.BEGIN_ARRAY) { + jsonReader.beginArray(); + while (jsonReader.hasNext()) { + jsonReader.beginObject(); + nodeModel = new NodeModel(); + outputNode = new OutputNodeImpl(nodeModel); + while (jsonReader.hasNext()) { + name = jsonReader.nextName(); + if (name.equals(NAME)) { + nodeModel.setName(jsonReader.nextString()); + } else if (name.equals(ID)) { + nodeModel.setNodeId(jsonReader.nextString()); + } else if (name.equals(DATATYPE)) { + jsonReader.skipValue(); + } else if (name.equals(DESCRIPTION)) { + nodeModel.setDescription(jsonReader.nextString()); + } else if (name.equals(POSITION)) { + readPosition(jsonReader); + } else if (name.equals(NODE_ID)) { + nodeModel.setNodeId(jsonReader.nextString()); + } else if (name.equals(DEFAULT_VALUE)) { + jsonReader.skipValue(); + } else { + jsonReader.skipValue(); + } + + } + jsonReader.endObject(); + outputs.add(outputNode); + } + jsonReader.endArray(); + } else { + throw new ParserException("Error! Unsupported value for Workflow Outputs, exptected " + + getTokenString(JsonToken.BEGIN_OBJECT) + " but found" + getTokenString(peek)); + } + } + + private void readWorkflowLinks(JsonReader jsonReader) throws IOException, ParserException { + JsonToken peek = jsonReader.peek(); + if (peek == JsonToken.NULL) { + throw new ParserException("Error! Workflow should have connecting links, found " + getTokenString(peek)); + } else if (peek == JsonToken.BEGIN_ARRAY) { + jsonReader.beginArray(); + while (jsonReader.hasNext()) { + links.add(readLink(jsonReader)); + } + jsonReader.endArray(); + } else { + throw new ParserException("Error! Unsupported value for workflow links, expected " + + getTokenString(JsonToken.BEGIN_ARRAY) + " but found" + getTokenString(peek)); + + } + } + + private Link readLink(JsonReader jsonReader) throws IOException { + jsonReader.beginObject(); + String name = null; + Link link = new Link(null, null); + while (jsonReader.hasNext()) { + name = jsonReader.nextName(); + if (name.equals(DESCRIPTION)) { + link.setDescription(jsonReader.nextString()); + } else if (name.equals(FROM)) { + link.setFrom(readLinkHelper(jsonReader)); + } else if (name.equals(TO)) { + link.setTo(readLinkHelper(jsonReader)); + } else { + jsonReader.skipValue(); + } + } + jsonReader.endObject(); + return link; + } + + private LinkHelper readLinkHelper(JsonReader jsonReader) throws IOException { + jsonReader.beginObject(); + String name; + LinkHelper helper = new LinkHelper(); + while (jsonReader.hasNext()) { + name = jsonReader.nextName(); + if (name.equals(NODE_ID)) { + helper.setNodeId(jsonReader.nextString()); + } else if (name.equals(OUTPUT_ID)) { + helper.setOutputId(jsonReader.nextString()); + } else { + jsonReader.skipValue(); + } + } + jsonReader.endObject(); + return helper; + } + + private ApplicationNode readApplication(JsonReader jsonReader) throws IOException, ParserException { + jsonReader.beginObject(); + NodeModel nodeModel = new NodeModel(); + ApplicationNode applicationNode = new ApplicationNodeImpl(nodeModel); + String name; + while (jsonReader.hasNext()) { + name = jsonReader.nextName(); + if (name.equals(APPLICATION_ID)) { + nodeModel.setApplicationId(jsonReader.nextString()); + } else if (name.equals(NAME)) { + nodeModel.setName(jsonReader.nextString()); + } else if (name.equals(DESCRIPTION)) { + nodeModel.setDescription(jsonReader.nextString()); + } else if (name.equals(APPTYPE)) { + jsonReader.skipValue(); + } else if (name.equals(INPUTS)) { + applicationNode.addInputPorts(readApplicationInputs(jsonReader)); + } else if (name.equals(OUTPUTS)) { + applicationNode.addOutPorts(readApplicationOutputs(jsonReader)); + } else if (name.equals(POSITION)) { + readPosition(jsonReader); + } else if (name.equals(NODE_ID)) { + nodeModel.setNodeId(jsonReader.nextString()); + } else if (name.equals(PARALLEL_EXECUTION)) { + jsonReader.skipValue(); + } else if (name.equals(PROPERTIES)) { + readProperties(jsonReader); + } + } + jsonReader.endObject(); + return applicationNode; + } + + private List<InPort> readApplicationInputs(JsonReader jsonReader) throws IOException, ParserException { + List<InPort> inPorts = new ArrayList<>(); + JsonToken peek = jsonReader.peek(); + PortModel portModel; + InPort inPort; + String name; + if (peek == JsonToken.NULL) { + jsonReader.nextNull(); + } else if (peek == JsonToken.BEGIN_ARRAY) { + jsonReader.beginArray(); + while (jsonReader.hasNext()) { + portModel = new PortModel(); + inPort = new InputPortIml(portModel); + jsonReader.beginObject(); + while (jsonReader.hasNext()) { + name = jsonReader.nextName(); + if (name.equals(NAME)) { + portModel.setName(jsonReader.nextString()); + } else if (name.equals(ID)) { + portModel.setPortId(jsonReader.nextString()); + } else if (name.equals(DATATYPE)) { + jsonReader.skipValue(); + } else if (name.equals(DEFAULT_VALUE)) { + inPort.setDefaultValue(jsonReader.nextString()); + } else if (name.equals(DESCRIPTION)) { + portModel.setDescription(jsonReader.nextString()); + } else { + jsonReader.skipValue(); + } + } + jsonReader.endObject(); + inPorts.add(inPort); + } + jsonReader.endArray(); + } else { + throw new ParserException("Error! reading application inputs, expected " + getTokenString(JsonToken.NULL) + + " or " + getTokenString(JsonToken.BEGIN_ARRAY) + " but found " + getTokenString(peek)); + } + + return inPorts; + } + + private List<OutPort> readApplicationOutputs(JsonReader jsonReader) throws IOException, ParserException { + List<OutPort> outPorts = new ArrayList<>(); + PortModel portModel; + OutPort outPort; + String name; + JsonToken peek = jsonReader.peek(); + if (peek == JsonToken.NULL) { + jsonReader.nextNull(); + } else if (peek == JsonToken.BEGIN_ARRAY) { + jsonReader.beginArray(); + while (jsonReader.hasNext()) { + portModel = new PortModel(); + outPort = new OutPortImpl(portModel); + jsonReader.beginObject(); + while (jsonReader.hasNext()) { + name = jsonReader.nextName(); + if (name.equals(NAME)) { + portModel.setName(jsonReader.nextString()); + } else if (name.equals(ID)) { + portModel.setPortId(jsonReader.nextString()); + } else if (name.equals(DATATYPE)) { + jsonReader.skipValue(); + } else if (name.equals(DEFAULT_VALUE)) { + jsonReader.skipValue(); // can output has default values? + } else if (name.equals(DESCRIPTION)) { + portModel.setDescription(jsonReader.nextString()); + } else { + jsonReader.skipValue(); + } + } + jsonReader.endObject(); + outPorts.add(outPort); + } + jsonReader.endArray(); + } else { + throw new ParserException("Error! reading application outputs, expected " + getTokenString(JsonToken.NULL) + + " or " + getTokenString(JsonToken.BEGIN_ARRAY) + " but found " + getTokenString(peek)); + + } + return outPorts; } + private void readPosition(JsonReader jsonReader) throws IOException { + JsonToken peek = jsonReader.peek(); + if (peek == JsonToken.NULL) { + jsonReader.nextNull(); + } else if (peek == JsonToken.BEGIN_OBJECT) { + jsonReader.beginObject(); + while (jsonReader.hasNext()) { + // skip position data. + jsonReader.nextName(); + jsonReader.skipValue(); + } + jsonReader.endObject(); + } else { + jsonReader.skipValue(); + } + } + + private void readProperties(JsonReader jsonReader) throws IOException { + JsonToken peek = jsonReader.peek(); + if (peek == JsonToken.NULL) { + jsonReader.nextNull(); + } else if (peek == JsonToken.BEGIN_OBJECT) { + jsonReader.beginObject(); + while (jsonReader.hasNext()) { + // TODO: Read and use proprety values + String name = jsonReader.nextName(); + jsonReader.skipValue(); + } + jsonReader.endObject(); + } else { + jsonReader.skipValue(); + } + + } + + private String getTokenString(JsonToken peek) { + switch (peek) { + case BEGIN_OBJECT: + return "Begin Object"; + case BEGIN_ARRAY: + return "Begin Array"; + case END_OBJECT: + return "End Object"; + case END_ARRAY: + return "End Array"; + case NAME: + return "Name"; + case STRING: + return "String"; + case NUMBER: + return "Number"; + case BOOLEAN: + return "Boolean"; + case NULL: + return "Null"; + case END_DOCUMENT: + return "End Document"; + default: + return "<Coudn't find token type>"; + } + } + + @Override public List<InputNode> getInputNodes() throws Exception { - return null; + return inputs; } @Override public List<OutputNode> getOutputNodes() throws Exception { - return null; + return outputs; } @Override public List<ApplicationNode> getApplicationNodes() throws Exception { - return null; + return applications; } @Override public List<Port> getPorts() throws Exception { - return null; + return ports; } @Override public List<Edge> getEdges() throws Exception { - return null; + return edges; } @@ -102,4 +524,79 @@ public class JsonWorkflowParser implements WorkflowParser { private Edge createEdge(JsonObject jEdge) { return null; } + + public static final String WORKFLOW = "workflow"; + private static final String NAME = "name"; + public static final String ID = "id"; + public static final String DESCRIPTION = "description"; + public static final String VERSION = "version"; + public static final String APPLICATIONS = "applications"; + public static final String APPLICATION_ID = "applicationId"; + public static final String APPTYPE = "appType"; + public static final String INPUTS = "inputs"; + public static final String DATATYPE = "dataType"; + public static final String DEFAULT_VALUE = "defaultValue"; + public static final String OUTPUTS = "outputs"; + public static final String POSITION = "position"; + public static final String X = "x"; + public static final String Y = "y"; + public static final String NODE_ID = "nodeId"; + public static final String PARALLEL_EXECUTION = "parallelExecution"; + public static final String PROPERTIES = "properties"; + public static final String WORKFLOW_INPUTS = "workflowInputs"; + public static final String WORKFLOW_OUTPUTS = "workflowOutputs"; + public static final String LINKS = "links"; + public static final String FROM = "from"; + public static final String TO = "to"; + public static final String OUTPUT_ID = "outputId"; + + + class Link { + private LinkHelper from; + private LinkHelper to; + private String description; + + public Link(LinkHelper from, LinkHelper to) { + this.from = from; + this.to = to; + } + + public String getDescription() { + return description; + } + + public void setDescription(String description) { + this.description = description; + } + + public void setFrom(LinkHelper from) { + this.from = from; + } + + public void setTo(LinkHelper to) { + this.to = to; + } + } + + class LinkHelper { + private String nodeId; + private String outputId; + + public String getNodeId() { + return nodeId; + } + + public void setNodeId(String nodeId) { + this.nodeId = nodeId; + } + + public String getOutputId() { + return outputId; + } + + public void setOutputId(String outputId) { + this.outputId = outputId; + } + } } + http://git-wip-us.apache.org/repos/asf/airavata/blob/11ea5014/modules/workflow/workflow-core/src/main/java/org/apache/airavata/workflow/core/parser/ParserException.java ---------------------------------------------------------------------- diff --git a/modules/workflow/workflow-core/src/main/java/org/apache/airavata/workflow/core/parser/ParserException.java b/modules/workflow/workflow-core/src/main/java/org/apache/airavata/workflow/core/parser/ParserException.java new file mode 100644 index 0000000..173f485 --- /dev/null +++ b/modules/workflow/workflow-core/src/main/java/org/apache/airavata/workflow/core/parser/ParserException.java @@ -0,0 +1,40 @@ +/* + * + * 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; + +public class ParserException extends Exception { + + public ParserException(String message) { + super(message); + } + + public ParserException(String message, Throwable cause) { + super(message, cause); + } + + public ParserException(Throwable cause) { + super(cause); + } + + protected ParserException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) { + super(message, cause, enableSuppression, writableStackTrace); + } +} http://git-wip-us.apache.org/repos/asf/airavata/blob/11ea5014/modules/workflow/workflow-core/src/main/java/org/apache/airavata/workflow/core/parser/WorkflowParser.java ---------------------------------------------------------------------- diff --git a/modules/workflow/workflow-core/src/main/java/org/apache/airavata/workflow/core/parser/WorkflowParser.java b/modules/workflow/workflow-core/src/main/java/org/apache/airavata/workflow/core/parser/WorkflowParser.java index dc18c9e..36e8fb0 100644 --- a/modules/workflow/workflow-core/src/main/java/org/apache/airavata/workflow/core/parser/WorkflowParser.java +++ b/modules/workflow/workflow-core/src/main/java/org/apache/airavata/workflow/core/parser/WorkflowParser.java @@ -21,6 +21,7 @@ package org.apache.airavata.workflow.core.parser; +import org.apache.airavata.workflow.core.WorkflowInfo; 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.InputNode; @@ -31,7 +32,7 @@ import java.util.List; public interface WorkflowParser { - public void parse() throws Exception; + public WorkflowInfo parse() throws Exception; public List<InputNode> getInputNodes() throws Exception; http://git-wip-us.apache.org/repos/asf/airavata/blob/11ea5014/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 deleted file mode 100644 index 09c1416..0000000 --- a/modules/workflow/workflow-core/src/test/java/org/apache/airavata/workflow/core/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.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/11ea5014/modules/workflow/workflow-core/src/test/java/org/apache/airavata/workflow/core/parser/JsonWorkflowParserTest.java ---------------------------------------------------------------------- diff --git a/modules/workflow/workflow-core/src/test/java/org/apache/airavata/workflow/core/parser/JsonWorkflowParserTest.java b/modules/workflow/workflow-core/src/test/java/org/apache/airavata/workflow/core/parser/JsonWorkflowParserTest.java index 3fedc9c..86e2f7e 100644 --- a/modules/workflow/workflow-core/src/test/java/org/apache/airavata/workflow/core/parser/JsonWorkflowParserTest.java +++ b/modules/workflow/workflow-core/src/test/java/org/apache/airavata/workflow/core/parser/JsonWorkflowParserTest.java @@ -1,34 +1,95 @@ +/* + * + * 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.WorkflowInfo; +import org.apache.airavata.workflow.core.dag.nodes.ApplicationNode; +import org.apache.airavata.workflow.core.dag.nodes.InputNode; +import org.apache.airavata.workflow.core.dag.nodes.OutputNode; import org.junit.After; +import org.junit.Assert; import org.junit.Before; import org.junit.Test; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; -import java.io.File; import java.io.InputStream; +import java.util.List; -import static org.junit.Assert.*; - -/** - * Created by syodage on 2/8/16. - */ public class JsonWorkflowParserTest { - private String workflowString; - - + private InputStream inputStream; @Before public void setUp() throws Exception { - InputStream inputStream = Thread.currentThread().getContextClassLoader().getResourceAsStream("TestWorkflow.json"); + inputStream = Thread.currentThread().getContextClassLoader().getResourceAsStream("TestWorkflow.json"); + if (inputStream == null) { + throw new Exception("Couldn't find TestWorkflow File"); + } } @After public void tearDown() throws Exception { - + if (inputStream != null) { + inputStream.close(); + } } @Test public void testParse() throws Exception { + JsonWorkflowParser jwp = new JsonWorkflowParser(inputStream); + + WorkflowInfo workflowInfo = jwp.parse(); + Assert.assertNotNull(workflowInfo); + Assert.assertEquals("name", workflowInfo.getName()); + Assert.assertEquals("default_id", workflowInfo.getId()); + Assert.assertEquals("default description", workflowInfo.getDescription()); + Assert.assertEquals("version", workflowInfo.getVersion()); + testApplications(jwp); + testWorkflowInputs(jwp); + testWorkflowOutputs(jwp); } + + private void testApplications(JsonWorkflowParser jwp) throws Exception { + List<ApplicationNode> applicationNodes = jwp.getApplicationNodes(); + Assert.assertNotNull(applicationNodes); + Assert.assertEquals(1, applicationNodes.size()); + + ApplicationNode node = applicationNodes.get(0); + Assert.assertEquals("App Name", node.getName()); + Assert.assertEquals("appId_1", node.getApplicationId()); + + } + + private void testWorkflowInputs(JsonWorkflowParser jwp) throws Exception { + List<InputNode> inputNodes = jwp.getInputNodes(); + Assert.assertEquals(2, inputNodes.size()); + + } + + private void testWorkflowOutputs(JsonWorkflowParser jwp) throws Exception { + List<OutputNode> outputNodes = jwp.getOutputNodes(); + Assert.assertEquals(2, outputNodes.size()); + + } + } \ No newline at end of file http://git-wip-us.apache.org/repos/asf/airavata/blob/11ea5014/modules/workflow/workflow-core/src/test/resources/TestWorkflow.json ---------------------------------------------------------------------- diff --git a/modules/workflow/workflow-core/src/test/resources/TestWorkflow.json b/modules/workflow/workflow-core/src/test/resources/TestWorkflow.json index 5b64172..0dd4b35 100644 --- a/modules/workflow/workflow-core/src/test/resources/TestWorkflow.json +++ b/modules/workflow/workflow-core/src/test/resources/TestWorkflow.json @@ -69,16 +69,16 @@ ], "links" : [ { "description" : "link desc", - "from" : { "nodeId" : "" , "ouputId" : "" }, + "from" : { "nodeId" : "" , "outputId" : "" }, "to" : { "nodeId" : "" , "outputId" : "" }}, { "description" : "link desc", - "from" : { "nodeId" : "" , "ouputId" : "" }, + "from" : { "nodeId" : "" , "outputId" : "" }, "to" : { "nodeId" : "" , "outputId" : "" }}, { "description" : "link desc", - "from" : { "nodeId" : "" , "ouputId" : "" }, + "from" : { "nodeId" : "" , "outputId" : "" }, "to" : { "nodeId" : "" , "outputId" : "" }}, { "description" : "link desc", - "from" : { "nodeId" : "" , "ouputId" : "" }, + "from" : { "nodeId" : "" , "outputId" : "" }, "to" : { "nodeId" : "" , "outputId" : "" }} ] }
