[ONOS-7732] Automating switch workflow: api, app, and sample workflows
Change-Id: Iee87d4fe6cf61c1f8904d1d77df5f913a712b64a
diff --git a/apps/workflow/api/BUCK b/apps/workflow/api/BUCK
new file mode 100644
index 0000000..f9461af
--- /dev/null
+++ b/apps/workflow/api/BUCK
@@ -0,0 +1,11 @@
+COMPILE_DEPS = [
+ '//lib:CORE_DEPS',
+ '//lib:jackson-core',
+ '//lib:jackson-annotations',
+ '//lib:jackson-databind',
+ '//core/store/serializers:onos-core-serializers',
+]
+
+osgi_jar_with_tests (
+ deps = COMPILE_DEPS,
+)
diff --git a/apps/workflow/api/BUILD b/apps/workflow/api/BUILD
new file mode 100644
index 0000000..721e4b9
--- /dev/null
+++ b/apps/workflow/api/BUILD
@@ -0,0 +1,7 @@
+COMPILE_DEPS = CORE_DEPS + KRYO + JACKSON + [
+ "//core/store/serializers:onos-core-serializers",
+]
+
+osgi_jar_with_tests(
+ deps = COMPILE_DEPS,
+)
diff --git a/apps/workflow/api/src/main/java/org/onosproject/workflow/api/AbstractWorkflow.java b/apps/workflow/api/src/main/java/org/onosproject/workflow/api/AbstractWorkflow.java
new file mode 100644
index 0000000..8a5f2b8
--- /dev/null
+++ b/apps/workflow/api/src/main/java/org/onosproject/workflow/api/AbstractWorkflow.java
@@ -0,0 +1,52 @@
+/*
+ * Copyright 2018-present Open Networking Foundation
+ *
+ * Licensed 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.onosproject.workflow.api;
+
+import java.net.URI;
+
+/**
+ * Abstract class for workflow.
+ */
+public abstract class AbstractWorkflow implements Workflow {
+
+ /**
+ * ID of workflow.
+ */
+ private URI id;
+
+ /**
+ * Constructor for AbstractWorkflow.
+ * @param id ID of workflow
+ */
+ protected AbstractWorkflow(URI id) {
+ this.id = id;
+ }
+
+ @Override
+ public URI id() {
+ return id;
+ }
+
+ @Override
+ public WorkflowContext buildContext(Workplace workplace, DataModelTree data) throws WorkflowException {
+ return new DefaultWorkflowContext(id, workplace.name(), data);
+ }
+
+ @Override
+ public WorkflowContext buildSystemContext(Workplace workplace, DataModelTree data) throws WorkflowException {
+ return new SystemWorkflowContext(id, workplace.name(), data);
+ }
+}
diff --git a/apps/workflow/api/src/main/java/org/onosproject/workflow/api/AbstractWorklet.java b/apps/workflow/api/src/main/java/org/onosproject/workflow/api/AbstractWorklet.java
new file mode 100644
index 0000000..b9fb133
--- /dev/null
+++ b/apps/workflow/api/src/main/java/org/onosproject/workflow/api/AbstractWorklet.java
@@ -0,0 +1,46 @@
+/*
+ * Copyright 2018-present Open Networking Foundation
+ *
+ * Licensed 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.onosproject.workflow.api;
+
+
+import org.onosproject.event.Event;
+
+/**
+ * Abstract class for worklet.
+ */
+public abstract class AbstractWorklet implements Worklet {
+
+ @Override
+ public String tag() {
+ return this.getClass().getName();
+ }
+
+ @Override
+ public boolean isCompleted(WorkflowContext context, Event event)throws WorkflowException {
+ throw new WorkflowException("(" + tag() + ").isCompleted should not be called");
+ }
+
+ @Override
+ public boolean isNext(WorkflowContext context) throws WorkflowException {
+ throw new WorkflowException("(" + tag() + ").isNext should not be called");
+ }
+
+ @Override
+ public void timeout(WorkflowContext context) throws WorkflowException {
+ throw new WorkflowException("Timeout happened");
+ }
+}
+
diff --git a/apps/workflow/api/src/main/java/org/onosproject/workflow/api/BranchWorklet.java b/apps/workflow/api/src/main/java/org/onosproject/workflow/api/BranchWorklet.java
new file mode 100644
index 0000000..4f91bba
--- /dev/null
+++ b/apps/workflow/api/src/main/java/org/onosproject/workflow/api/BranchWorklet.java
@@ -0,0 +1,41 @@
+/*
+ * Copyright 2018-present Open Networking Foundation
+ *
+ * Licensed 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.onosproject.workflow.api;
+
+/**
+ * An interface representing branch worklet. Branch worklet is used for branching workflow execution.
+ */
+public interface BranchWorklet extends Worklet {
+
+ @Override
+ default void process(WorkflowContext context) throws WorkflowException {
+ throw new WorkflowException("This workletType.process should not be called");
+ }
+
+ @Override
+ default boolean isNext(WorkflowContext context) throws WorkflowException {
+ throw new WorkflowException("This workletType.isNext should not be called");
+ }
+
+ /**
+ * Returns next worklet class for branching.
+ * @param context workflow context
+ * @return next worklet class
+ * @throws WorkflowException workflow exception
+ */
+ Class<? extends Worklet> next(WorkflowContext context) throws WorkflowException;
+}
+
diff --git a/apps/workflow/api/src/main/java/org/onosproject/workflow/api/ContextEventMapStore.java b/apps/workflow/api/src/main/java/org/onosproject/workflow/api/ContextEventMapStore.java
new file mode 100644
index 0000000..c26b3be
--- /dev/null
+++ b/apps/workflow/api/src/main/java/org/onosproject/workflow/api/ContextEventMapStore.java
@@ -0,0 +1,83 @@
+/*
+ * Copyright 2018-present Open Networking Foundation
+ *
+ * Licensed 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.onosproject.workflow.api;
+
+
+import com.fasterxml.jackson.databind.node.ObjectNode;
+import org.onosproject.store.service.DocumentPath;
+import org.onosproject.store.service.Versioned;
+
+import java.util.Map;
+
+/**
+ * WorkflowContext Event Map Store.
+ */
+public interface ContextEventMapStore {
+
+ /**
+ * Registers workflow context event mapping.
+ * @param eventType the class name of event
+ * @param eventHint event hint string value of the event
+ * @param contextName workflow context name
+ * @param workletType the class name of worklet
+ * @throws WorkflowException workflow exception
+ */
+ void registerEventMap(String eventType, String eventHint,
+ String contextName, String workletType) throws WorkflowException;
+
+ /**
+ * Unregisters workflow context event mapping.
+ * @param eventType the class name of event
+ * @param eventHint event hint string value of the event
+ * @param contextName workflow context name
+ * @throws WorkflowException workflow exception
+ */
+ void unregisterEventMap(String eventType, String eventHint,
+ String contextName) throws WorkflowException;
+
+ /**
+ * Returns workflow context event mapping.
+ * @param eventType the class name of event
+ * @param eventHint event hint string value of the event
+ * @return workflow context event mapping
+ * @throws WorkflowException workflow exception
+ */
+ Map<String, String> getEventMap(String eventType, String eventHint) throws WorkflowException;
+
+ /**
+ * Returns child nodes on document tree path.
+ * @param path document tree path
+ * @return children under document tree path
+ * @throws WorkflowException workflow exception
+ */
+ Map<String, Versioned<String>> getChildren(String path) throws WorkflowException;
+
+ /**
+ * Returns document path.
+ * @param path document path string
+ * @return document tree
+ * @throws WorkflowException workflow exception
+ */
+ DocumentPath getDocumentPath(String path) throws WorkflowException;
+
+ /**
+ * Transforms document tree to json tree.
+ * @return json tree
+ * @throws WorkflowException workflow exception
+ */
+ ObjectNode asJsonTree() throws WorkflowException;
+}
+
diff --git a/apps/workflow/api/src/main/java/org/onosproject/workflow/api/DataModelPointer.java b/apps/workflow/api/src/main/java/org/onosproject/workflow/api/DataModelPointer.java
new file mode 100644
index 0000000..271ce4f
--- /dev/null
+++ b/apps/workflow/api/src/main/java/org/onosproject/workflow/api/DataModelPointer.java
@@ -0,0 +1,64 @@
+/*
+ * Copyright 2018-present Open Networking Foundation
+ *
+ * Licensed 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.onosproject.workflow.api;
+
+/**
+ * Common data model tree path.
+ */
+public interface DataModelPointer {
+
+ /**
+ * Workplace array pointer.
+ */
+ String WORKPLACES_PTR = "/workplaces";
+
+ /**
+ * Workplace name pointer.
+ */
+ String WORKPLACE_NAME_PTR = "/name";
+
+ /**
+ * Workplace data pointer.
+ */
+ String WORKPLACE_DATA_PTR = "/data";
+
+ /**
+ * Workplace workflow pointer.
+ */
+ String WORKPLACE_WORKFLOWS_PTR = "/workflows";
+
+ /**
+ * Workflow op pointer.
+ */
+ String WORKFLOW_OP_PTR = "/op";
+
+ /**
+ * Workflow id pointer.
+ */
+ String WORKFLOW_ID_PTR = "/id";
+
+ /**
+ * Workflow data pointer.
+ */
+ String WORKFLOW_DATA_PTR = "/data";
+
+ /**
+ * Gets path string.
+ * @return path string
+ */
+ String getPath();
+}
+
diff --git a/apps/workflow/api/src/main/java/org/onosproject/workflow/api/DataModelTree.java b/apps/workflow/api/src/main/java/org/onosproject/workflow/api/DataModelTree.java
new file mode 100644
index 0000000..3236164
--- /dev/null
+++ b/apps/workflow/api/src/main/java/org/onosproject/workflow/api/DataModelTree.java
@@ -0,0 +1,63 @@
+/*
+ * Copyright 2018-present Open Networking Foundation
+ *
+ * Licensed 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.onosproject.workflow.api;
+
+/**
+ * Interface for data model tree.
+ */
+public interface DataModelTree {
+
+ /**
+ * Data model tree node type (map or array).
+ */
+ enum Nodetype {
+
+ /**
+ * Map type data model tree node.
+ */
+ MAP,
+
+ /**
+ * Array type data model tree node.
+ */
+ ARRAY
+ }
+
+ /**
+ * Returns subtree on the path.
+ * @param path data model tree path
+ * @return subtree on the path
+ */
+ DataModelTree subtree(String path);
+
+ /**
+ * Attaches subtree on the path.
+ * @param path data model tree path where subtree will be attached
+ * @param tree subtree to be attached
+ * @throws WorkflowException workflow exception
+ */
+ void attach(String path, DataModelTree tree) throws WorkflowException;
+
+ /**
+ * Allocates leaf node on the path.
+ * @param path data model tree path where new leaf node will be allocated
+ * @param leaftype leaf node type
+ * @return data model tree
+ * @throws WorkflowException workflow exception
+ */
+ DataModelTree alloc(String path, Nodetype leaftype) throws WorkflowException;
+}
+
diff --git a/apps/workflow/api/src/main/java/org/onosproject/workflow/api/DefaultRpcDescription.java b/apps/workflow/api/src/main/java/org/onosproject/workflow/api/DefaultRpcDescription.java
new file mode 100644
index 0000000..4a4715e
--- /dev/null
+++ b/apps/workflow/api/src/main/java/org/onosproject/workflow/api/DefaultRpcDescription.java
@@ -0,0 +1,177 @@
+/*
+ * Copyright 2018-present Open Networking Foundation
+ *
+ * Licensed 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.onosproject.workflow.api;
+
+import com.fasterxml.jackson.databind.JsonNode;
+import com.fasterxml.jackson.databind.node.MissingNode;
+import com.fasterxml.jackson.databind.node.TextNode;
+import com.google.common.base.MoreObjects;
+
+/**
+ * Class of workflow RPC description.
+ */
+public final class DefaultRpcDescription implements RpcDescription {
+
+ /**
+ * Workflow RPC operation.
+ */
+ private final String op;
+
+ /**
+ * Parameters.
+ */
+ private final JsonNode params;
+
+ /**
+ * Invocation ID.
+ */
+ private final String id;
+
+ /**
+ * Constructor of workplace description.
+ * @param builder workplace builder
+ */
+ private DefaultRpcDescription(Builder builder) {
+ this.op = builder.op;
+ this.params = builder.params;
+ this.id = builder.id;
+ }
+
+ @Override
+ public String op() {
+ return this.op;
+ }
+
+ @Override
+ public JsonNode params() {
+ return this.params;
+ }
+
+ @Override
+ public String id() {
+ return this.id;
+ }
+
+ /**
+ * Creating workflow RPC description from json tree.
+ * @param root root node for workflow RPC description
+ * @return workflow RPC description
+ * @throws WorkflowException workflow exception
+ */
+ public static DefaultRpcDescription valueOf(JsonNode root) throws WorkflowException {
+
+ JsonNode node = root.at(RPC_OP_PTR);
+ if (!(node instanceof TextNode)) {
+ throw new WorkflowException("invalid RPC operation for " + root);
+ }
+ String rpcOp = node.asText();
+
+ node = root.at(RPC_PARAMS_PTR);
+ if (node instanceof MissingNode) {
+ throw new WorkflowException("invalid RPC parameters for " + root);
+ }
+ JsonNode rpcParams = node;
+
+ node = root.at(RPC_ID_PTR);
+ if (!(node instanceof TextNode)) {
+ throw new WorkflowException("invalid RPC invocation ID for " + root);
+ }
+ String rpcId = node.asText();
+
+
+ return builder()
+ .setOp(rpcOp)
+ .setParams(rpcParams)
+ .setId(rpcId)
+ .build();
+ }
+
+ @Override
+ public String toString() {
+ return MoreObjects.toStringHelper(getClass())
+ .add("op", op())
+ .add("params", params())
+ .add("id", id())
+ .toString();
+ }
+
+ /**
+ * Gets builder instance.
+ * @return builder instance
+ */
+ public static Builder builder() {
+ return new Builder();
+ }
+
+ /**
+ * Builder for workplace RPC description.
+ */
+ public static class Builder {
+
+ /**
+ * Workflow RPC operation.
+ */
+ private String op;
+
+ /**
+ * Parameters.
+ */
+ private JsonNode params;
+
+ /**
+ * Invocation ID.
+ */
+ private String id;
+
+ /**
+ * Sets workflow RPC operation.
+ * @param op workflow RPC operation
+ * @return builder
+ */
+ public Builder setOp(String op) {
+ this.op = op;
+ return this;
+ }
+
+ /**
+ * Sets workflow RPC parameters.
+ * @param params workflow RPC parameters
+ * @return builder
+ */
+ public Builder setParams(JsonNode params) {
+ this.params = params;
+ return this;
+ }
+
+ /**
+ * Sets workflow RPC invocation ID.
+ * @param id workflow invocation ID
+ * @return builder
+ */
+ public Builder setId(String id) {
+ this.id = id;
+ return this;
+ }
+
+ /**
+ * Builds workplace RPC description from builder.
+ * @return instance of workflow RPC description
+ */
+ public DefaultRpcDescription build() {
+ return new DefaultRpcDescription(this);
+ }
+ }
+}
diff --git a/apps/workflow/api/src/main/java/org/onosproject/workflow/api/DefaultWorkflowContext.java b/apps/workflow/api/src/main/java/org/onosproject/workflow/api/DefaultWorkflowContext.java
new file mode 100644
index 0000000..e16376f
--- /dev/null
+++ b/apps/workflow/api/src/main/java/org/onosproject/workflow/api/DefaultWorkflowContext.java
@@ -0,0 +1,242 @@
+/*
+ * Copyright 2018-present Open Networking Foundation
+ *
+ * Licensed 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.onosproject.workflow.api;
+
+import com.google.common.base.MoreObjects;
+import org.onosproject.event.Event;
+
+import java.net.URI;
+
+/**
+ * Default implementation of WorkflowContext.
+ */
+public class DefaultWorkflowContext extends WorkflowContext {
+
+ /**
+ * ID of workflow.
+ */
+ private URI workflowId;
+
+ /**
+ * Workplace name of the workflow.
+ */
+ private String workplaceName;
+
+ /**
+ * State of workflow.
+ */
+ private WorkflowState state;
+
+ /**
+ * Current worklet of the workflow.
+ */
+ private String current;
+
+ /**
+ * Cause of workflow exception.
+ */
+ private String cause;
+
+ /**
+ * Completion event type.
+ */
+ private transient Class<? extends Event> completionEventType;
+
+ /**
+ * Completion event hint.
+ */
+ private transient String completionEventHint;
+
+ /**
+ * Completion event generator method reference.
+ */
+ private transient WorkExecutor completionEventGenerator;
+
+ /**
+ * Completion event timeout milliseconds.
+ */
+ private transient long completionEventTimeoutMs;
+
+ /**
+ * Service reference for workflow service.
+ */
+ private transient WorkflowExecutionService workflowExecutionService;
+
+ /**
+ * Service reference for workflow store.
+ */
+ private transient WorkflowStore workflowStore;
+
+ /**
+ * Service reference for workplace store.
+ */
+ private transient WorkplaceStore workplaceStore;
+
+ /**
+ * Constructor of DefaultWorkflowContext.
+ * @param workflowId ID of workflow
+ * @param workplaceName name of workplace
+ * @param data data model tree
+ */
+ public DefaultWorkflowContext(URI workflowId, String workplaceName, DataModelTree data) {
+ super(data);
+ this.workflowId = workflowId;
+ this.workplaceName = workplaceName;
+ this.state = WorkflowState.IDLE;
+ this.current = Worklet.Common.INIT.name();
+ }
+
+ /**
+ * DefaultWorkflowContext name builder.
+ * @param workflowid workflow id
+ * @param workplacename workplace name
+ * @return DefaultWorkflowContext name
+ */
+ public static String nameBuilder(URI workflowid, String workplacename) {
+ return workflowid.toString() + "@" + workplacename;
+ }
+
+ @Override
+ public String name() {
+ return nameBuilder(workflowId, workplaceName);
+ }
+
+ @Override
+ public String distributor() {
+ return workplaceName();
+ }
+
+ @Override
+ public URI workflowId() {
+ return this.workflowId;
+ }
+
+ @Override
+ public String workplaceName() {
+ return workplaceName;
+ }
+
+ @Override
+ public WorkflowState state() {
+ return state;
+ }
+
+ @Override
+ public void setState(WorkflowState state) {
+ this.state = state;
+ }
+
+ @Override
+ public String current() {
+ return this.current;
+ }
+
+ @Override
+ public void setCurrent(Worklet worklet) {
+ this.current = worklet.tag();
+ }
+
+ @Override
+ public String cause() {
+ return this.cause;
+ }
+
+ @Override
+ public void setCause(String cause) {
+ this.cause = cause;
+ }
+
+ @Override
+ public void completed() {
+ setTriggerNext(true);
+ }
+
+ @Override
+ public void waitCompletion(Class<? extends Event> eventType, String eventHint,
+ WorkExecutor eventGenerator, long timeoutMs) {
+ this.completionEventType = eventType;
+ this.completionEventHint = eventHint;
+ this.completionEventGenerator = eventGenerator;
+ this.completionEventTimeoutMs = timeoutMs;
+ }
+
+ @Override
+ public void waitFor(long timeoutMs) {
+ this.completionEventTimeoutMs = timeoutMs;
+ }
+
+ @Override
+ public Class<? extends Event> completionEventType() {
+ return completionEventType;
+ }
+
+ @Override
+ public String completionEventHint() {
+ return completionEventHint;
+ }
+
+ @Override
+ public WorkExecutor completionEventGenerator() {
+ return completionEventGenerator;
+ }
+
+ @Override
+ public long completionEventTimeout() {
+ return completionEventTimeoutMs;
+ }
+
+ @Override
+ public void setWorkflowExecutionService(WorkflowExecutionService workflowExecutionService) {
+ this.workflowExecutionService = workflowExecutionService;
+ }
+
+ @Override
+ public WorkflowExecutionService workflowService() {
+ return workflowExecutionService;
+ }
+
+ @Override
+ public void setWorkflowStore(WorkflowStore workflowStore) {
+ this.workflowStore = workflowStore;
+ }
+
+ @Override
+ public WorkflowStore workflowStore() {
+ return workflowStore;
+ }
+
+ @Override
+ public void setWorkplaceStore(WorkplaceStore workplaceStore) {
+ this.workplaceStore = workplaceStore;
+ }
+
+ @Override
+ public WorkplaceStore workplaceStore() {
+ return workplaceStore;
+ }
+
+ @Override
+ public String toString() {
+ return MoreObjects.toStringHelper(getClass())
+ .add("name", name())
+ .add("triggernext", triggerNext())
+ .add("data", data())
+ .add("current", current)
+ .add("state", state())
+ .add("cause", cause())
+ .toString();
+ }
+}
diff --git a/apps/workflow/api/src/main/java/org/onosproject/workflow/api/DefaultWorkflowDescription.java b/apps/workflow/api/src/main/java/org/onosproject/workflow/api/DefaultWorkflowDescription.java
new file mode 100644
index 0000000..c9ded60
--- /dev/null
+++ b/apps/workflow/api/src/main/java/org/onosproject/workflow/api/DefaultWorkflowDescription.java
@@ -0,0 +1,209 @@
+/*
+ * Copyright 2018-present Open Networking Foundation
+ *
+ * Licensed 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.onosproject.workflow.api;
+
+import com.fasterxml.jackson.databind.JsonNode;
+import com.fasterxml.jackson.databind.node.JsonNodeFactory;
+import com.fasterxml.jackson.databind.node.MissingNode;
+import com.fasterxml.jackson.databind.node.ObjectNode;
+import com.fasterxml.jackson.databind.node.TextNode;
+import com.google.common.base.MoreObjects;
+
+import java.net.URI;
+
+
+/**
+ * Class for default workflow description.
+ */
+public final class DefaultWorkflowDescription implements WorkflowDescription {
+
+ /**
+ * Workplace Name.
+ */
+ private String workplaceName;
+
+ /**
+ * Workflow ID.
+ */
+ private URI id;
+
+ /**
+ * Workflow data model.
+ */
+ private JsonNode data;
+
+ /**
+ * Constructor of workflow description.
+ * @param builder workflow description builder
+ */
+ private DefaultWorkflowDescription(Builder builder) {
+ this.workplaceName = builder.workplaceName;
+ this.id = builder.id;
+ this.data = builder.data;
+ }
+
+ @Override
+ public String workplaceName() {
+ return this.workplaceName;
+ }
+
+ @Override
+ public URI id() {
+ return this.id;
+ }
+
+ @Override
+ public String workflowContextName() {
+ return DefaultWorkflowContext.nameBuilder(id(), workplaceName());
+ }
+
+ @Override
+ public JsonNode data() {
+ return this.data;
+ }
+
+ /**
+ * Creating workflow description from json tree.
+ * @param root root node for workflow description
+ * @return workflow description
+ * @throws WorkflowException workflow exception
+ */
+ public static DefaultWorkflowDescription valueOf(JsonNode root) throws WorkflowException {
+
+ JsonNode node = root.at(ptr(WF_WORKPLACE));
+ if (!(node instanceof TextNode)) {
+ throw new WorkflowException("invalid workflow workplace for " + root);
+ }
+ String wfWorkplaceName = node.asText();
+
+ node = root.at(ptr(WF_ID));
+ if (!(node instanceof TextNode)) {
+ throw new WorkflowException("invalid workflow id for " + root);
+ }
+ URI wfId = URI.create(node.asText());
+
+ node = root.at(ptr(WF_DATA));
+ if (node instanceof MissingNode) {
+ throw new WorkflowException("invalid workflow data for " + root);
+ }
+ JsonNode wfData = node;
+
+ return builder()
+ .workplaceName(wfWorkplaceName)
+ .id(wfId)
+ .data(wfData)
+ .build();
+ }
+
+ private static String ptr(String field) {
+ return "/" + field;
+ }
+
+ @Override
+ public JsonNode toJson() {
+ ObjectNode root = JsonNodeFactory.instance.objectNode();
+ root.put(WF_WORKPLACE, workplaceName());
+ root.put(WF_ID, id().toString());
+ root.put(WF_DATA, data());
+ return root;
+ }
+
+ @Override
+ public String toString() {
+ return MoreObjects.toStringHelper(getClass())
+ .add("workplace", workplaceName())
+ .add("id", id())
+ .add("data", data())
+ .toString();
+ }
+
+ /**
+ * Gets builder instance.
+ * @return builder instance
+ */
+ public static Builder builder() {
+ return new Builder();
+ }
+
+ /**
+ * Builder for workflow description.
+ */
+ public static class Builder {
+
+ /**
+ * Workplace name.
+ */
+ private String workplaceName;
+
+ /**
+ * Workflow ID.
+ */
+ private URI id;
+
+ /**
+ * Workflow data model.
+ */
+ private JsonNode data;
+
+ /**
+ * Sets workplace name.
+ * @param workplaceName workplace name
+ * @return builder
+ */
+ public Builder workplaceName(String workplaceName) {
+ this.workplaceName = workplaceName;
+ return this;
+ }
+
+ /**
+ * Sets workflow id.
+ * @param id workflow ID
+ * @return builder
+ */
+ public Builder id(URI id) {
+ this.id = id;
+ return this;
+ }
+
+ /**
+ * Sets workflow id.
+ * @param id workflow ID string
+ * @return builder
+ */
+ public Builder id(String id) {
+ this.id = URI.create(id);
+ return this;
+ }
+
+ /**
+ * Sets workflow data model.
+ * @param data workflow data model
+ * @return builder
+ */
+ public Builder data(JsonNode data) {
+ this.data = data;
+ return this;
+ }
+
+ /**
+ * Builds workflow description from builder.
+ * @return instance of workflow description
+ */
+ public DefaultWorkflowDescription build() {
+ return new DefaultWorkflowDescription(this);
+ }
+ }
+}
diff --git a/apps/workflow/api/src/main/java/org/onosproject/workflow/api/DefaultWorkplace.java b/apps/workflow/api/src/main/java/org/onosproject/workflow/api/DefaultWorkplace.java
new file mode 100644
index 0000000..1c60eaf
--- /dev/null
+++ b/apps/workflow/api/src/main/java/org/onosproject/workflow/api/DefaultWorkplace.java
@@ -0,0 +1,92 @@
+/*
+ * Copyright 2018-present Open Networking Foundation
+ *
+ * Licensed 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.onosproject.workflow.api;
+
+import com.google.common.base.MoreObjects;
+import org.onlab.osgi.DefaultServiceDirectory;
+import org.onlab.osgi.ServiceNotFoundException;
+
+import java.util.Collection;
+import java.util.Collections;
+import java.util.stream.Collectors;
+
+/**
+ * Default implementation of workplace.
+ */
+public class DefaultWorkplace extends Workplace {
+
+ /**
+ * Name of workplace.
+ */
+ private String name;
+
+ /**
+ * Constructor of DefaultWorkplace.
+ * @param name name of workplace
+ * @param data data model tree
+ */
+ public DefaultWorkplace(String name, DataModelTree data) {
+ super(data);
+ this.name = name;
+ }
+
+ @Override
+ public String name() {
+ return this.name;
+ }
+
+ @Override
+ public String distributor() {
+ return name();
+ }
+
+ @Override
+ public Collection<WorkflowContext> getContexts() throws WorkflowException {
+ WorkplaceStore workplaceStore;
+ try {
+ workplaceStore = DefaultServiceDirectory.getService(WorkplaceStore.class);
+ } catch (ServiceNotFoundException e) {
+ throw new WorkflowException(e);
+ }
+
+ return workplaceStore.getWorkplaceContexts(name());
+ }
+
+ /**
+ * Returns collection of context names.
+ * @return collection of context names
+ */
+ private Collection<String> getContextNames() {
+ Collection<WorkflowContext> ctx;
+ try {
+ ctx = getContexts();
+ } catch (WorkflowException e) {
+ ctx = Collections.emptyList();
+ }
+
+ return ctx.stream().map(x -> x.name()).collect(Collectors.toList());
+ }
+
+ @Override
+ public String toString() {
+ return MoreObjects.toStringHelper(getClass())
+ .add("name", name())
+ .add("triggernext", triggerNext())
+ .add("context", data())
+ .add("contexts", getContextNames())
+ .toString();
+ }
+}
diff --git a/apps/workflow/api/src/main/java/org/onosproject/workflow/api/DefaultWorkplaceDescription.java b/apps/workflow/api/src/main/java/org/onosproject/workflow/api/DefaultWorkplaceDescription.java
new file mode 100644
index 0000000..95da550
--- /dev/null
+++ b/apps/workflow/api/src/main/java/org/onosproject/workflow/api/DefaultWorkplaceDescription.java
@@ -0,0 +1,169 @@
+/*
+ * Copyright 2018-present Open Networking Foundation
+ *
+ * Licensed 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.onosproject.workflow.api;
+
+import com.fasterxml.jackson.databind.JsonNode;
+import com.fasterxml.jackson.databind.node.ArrayNode;
+import com.fasterxml.jackson.databind.node.JsonNodeFactory;
+import com.fasterxml.jackson.databind.node.MissingNode;
+import com.fasterxml.jackson.databind.node.ObjectNode;
+import com.fasterxml.jackson.databind.node.TextNode;
+import com.google.common.base.MoreObjects;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Optional;
+
+/**
+ * Class for default workplace description.
+ */
+public final class DefaultWorkplaceDescription implements WorkplaceDescription {
+
+ /**
+ * Name of workplace.
+ */
+ private final String name;
+
+ /**
+ * Data model of workplace(Optional).
+ */
+ private final Optional<JsonNode> optData;
+
+ /**
+ * Constructor of workplace description.
+ * @param builder workplace builder
+ */
+ private DefaultWorkplaceDescription(Builder builder) {
+ this.name = builder.name;
+ this.optData = builder.optData;
+ }
+
+ @Override
+ public String name() {
+ return this.name;
+ }
+
+ @Override
+ public Optional<JsonNode> data() {
+ return this.optData;
+ }
+
+ /**
+ * Creating workplace description from json tree.
+ * @param root root node for workplace description
+ * @return workplace description
+ * @throws WorkflowException workflow exception
+ */
+ public static DefaultWorkplaceDescription valueOf(JsonNode root) throws WorkflowException {
+
+ JsonNode node = root.at(ptr(WP_NAME));
+ if (!(node instanceof TextNode)) {
+ throw new WorkflowException("invalid workplace name for " + root);
+ }
+
+ Builder builder = builder()
+ .name(node.asText());
+
+ node = root.at(ptr(WP_DATA));
+ if (node != null && !(node instanceof MissingNode)) {
+ if (!(node instanceof ObjectNode) && !(node instanceof ArrayNode)) {
+ throw new WorkflowException("invalid workplace data for " + root);
+ }
+ builder.data(node);
+ }
+
+ return builder.build();
+ }
+
+ private static String ptr(String field) {
+ return "/" + field;
+ }
+
+ @Override
+ public JsonNode toJson() {
+ ObjectNode root = JsonNodeFactory.instance.objectNode();
+ root.put(WP_NAME, name());
+ if (data().isPresent()) {
+ root.put(WP_DATA, data().get());
+ }
+ return root;
+ }
+
+ @Override
+ public String toString() {
+ return MoreObjects.toStringHelper(getClass())
+ .add("name", name())
+ .add("optData", data())
+ .toString();
+ }
+
+ /**
+ * Gets builder instance.
+ * @return builder instance
+ */
+ public static Builder builder() {
+ return new Builder();
+ }
+
+ /**
+ * Builder for workplace description.
+ */
+ public static class Builder {
+
+ /**
+ * Workplace name.
+ */
+ private String name;
+
+ /**
+ * Workplace optData model.
+ */
+ private Optional<JsonNode> optData = Optional.empty();
+
+ /**
+ * List of workflow.
+ */
+ private List<DefaultWorkflowDescription> workflowDescs = new ArrayList<DefaultWorkflowDescription>();
+
+ /**
+ * Sets workplace name.
+ * @param name workplace name
+ * @return builder
+ */
+ public Builder name(String name) {
+ this.name = name;
+ return this;
+ }
+
+ /**
+ * Sets optData model.
+ * @param data workplace optData model
+ * @return builder
+ */
+ public Builder data(JsonNode data) {
+ this.optData = Optional.of(data);
+ return this;
+ }
+
+ /**
+ * Builds workplace description from builder.
+ * @return instance of workflow description
+ */
+ public DefaultWorkplaceDescription build() {
+ return new DefaultWorkplaceDescription(this);
+ }
+ }
+}
diff --git a/apps/workflow/api/src/main/java/org/onosproject/workflow/api/EventHintSupplier.java b/apps/workflow/api/src/main/java/org/onosproject/workflow/api/EventHintSupplier.java
new file mode 100644
index 0000000..076bfc0
--- /dev/null
+++ b/apps/workflow/api/src/main/java/org/onosproject/workflow/api/EventHintSupplier.java
@@ -0,0 +1,26 @@
+/*
+ * Copyright 2018-present Open Networking Foundation
+ *
+ * Licensed 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.onosproject.workflow.api;
+
+import org.onosproject.event.Event;
+
+/**
+ * Functional interface for delivering event hint supplier.
+ */
+@FunctionalInterface
+public interface EventHintSupplier {
+ String apply(Event event) throws Throwable;
+}
diff --git a/apps/workflow/api/src/main/java/org/onosproject/workflow/api/EventTask.java b/apps/workflow/api/src/main/java/org/onosproject/workflow/api/EventTask.java
new file mode 100644
index 0000000..3b2b30a
--- /dev/null
+++ b/apps/workflow/api/src/main/java/org/onosproject/workflow/api/EventTask.java
@@ -0,0 +1,163 @@
+/*
+ * Copyright 2018-present Open Networking Foundation
+ *
+ * Licensed 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.onosproject.workflow.api;
+
+import com.google.common.base.MoreObjects;
+import org.onosproject.event.Event;
+
+import java.util.Objects;
+
+/**
+ * Class for event task.
+ */
+public final class EventTask extends HandlerTask {
+
+ /**
+ * Event triggering event task.
+ */
+ private final Event event;
+
+ /**
+ * Event hint value for finding target event.
+ */
+ private final String eventHint;
+
+ /**
+ * Constructor of event task.
+ * @param builder builder of event task
+ */
+ private EventTask(Builder builder) {
+ super(builder);
+ this.event = builder.event;
+ this.eventHint = builder.eventHint;
+ }
+
+ /**
+ * Gets event of event task.
+ * @return event triggering event task
+ */
+ public Event event() {
+ return event;
+ }
+
+ /**
+ * Gets event type (class name of event) of event task.
+ * @return event type
+ */
+ public String eventType() {
+ return event.getClass().getName();
+ }
+
+ /**
+ * Gets event hint of event task.
+ * @return event hint string
+ */
+ public String eventHint() {
+ return eventHint;
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(this.toString());
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (obj == this) {
+ return true;
+ }
+ if (!(obj instanceof EventTask)) {
+ return false;
+ }
+ return Objects.equals(this.event(), ((EventTask) obj).event())
+ && Objects.equals(this.eventType(), ((EventTask) obj).eventType())
+ && Objects.equals(this.eventHint(), ((EventTask) obj).eventHint());
+ }
+
+ @Override
+ public String toString() {
+ return MoreObjects.toStringHelper(getClass())
+ .add("context", context())
+ .add("workletType", workletType())
+ .add("event", event())
+ .add("eventHint", eventHint())
+ .toString();
+ }
+
+ /**
+ * Gets a instance of builder.
+ * @return instance of builder
+ */
+ public static Builder builder() {
+ return new Builder();
+ }
+
+ /**
+ * Builder of EventTask.
+ */
+ public static class Builder extends HandlerTask.Builder {
+
+ /**
+ * Event triggering event task.
+ */
+ private Event event;
+
+ /**
+ * Event hint value for finding target event.
+ */
+ private String eventHint;
+
+ /**
+ * Sets event.
+ * @param event event triggering event task
+ * @return Builder of EventTask
+ */
+ public Builder event(Event event) {
+ this.event = event;
+ return this;
+ }
+
+ /**
+ * Sets event hint.
+ * @param eventHint event hint value for finding target event
+ * @return Builder of EventTask
+ */
+ public Builder eventHint(String eventHint) {
+ this.eventHint = eventHint;
+ return this;
+ }
+
+ @Override
+ public Builder context(WorkflowContext context) {
+ super.context(context);
+ return this;
+ }
+
+ @Override
+ public Builder workletType(String workletType) {
+ super.workletType(workletType);
+ return this;
+ }
+
+ /**
+ * Builds EventTask.
+ * @return instance of EventTask
+ */
+ public EventTask build() {
+ return new EventTask(this);
+ }
+ }
+}
diff --git a/apps/workflow/api/src/main/java/org/onosproject/workflow/api/EventTimeoutTask.java b/apps/workflow/api/src/main/java/org/onosproject/workflow/api/EventTimeoutTask.java
new file mode 100644
index 0000000..92516d4
--- /dev/null
+++ b/apps/workflow/api/src/main/java/org/onosproject/workflow/api/EventTimeoutTask.java
@@ -0,0 +1,152 @@
+/*
+ * Copyright 2018-present Open Networking Foundation
+ *
+ * Licensed 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.onosproject.workflow.api;
+
+import com.google.common.base.MoreObjects;
+
+import java.util.Objects;
+
+/**
+ * Class for event timeout task.
+ */
+public final class EventTimeoutTask extends HandlerTask {
+
+ /**
+ * Event type (Class name of event).
+ */
+ private final String eventType;
+
+ /**
+ * Event hint value for finding target event.
+ */
+ private final String eventHint;
+
+ /**
+ * Constructor of EventTimeoutTask.
+ * @param builder builder of EventTimeoutTask
+ */
+ private EventTimeoutTask(Builder builder) {
+ super(builder);
+ this.eventType = builder.eventType;
+ this.eventHint = builder.eventHint;
+ }
+
+ /**
+ * Gets event type (Class name of event).
+ * @return event type
+ */
+ public String eventType() {
+ return eventType;
+ }
+
+ /**
+ * Gets event hint value for finding target event.
+ * @return event hint string
+ */
+ public String eventHint() {
+ return eventHint;
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(this.toString());
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (obj == this) {
+ return true;
+ }
+ if (!(obj instanceof EventTask)) {
+ return false;
+ }
+ return Objects.equals(this.eventType(), ((EventTask) obj).eventType())
+ && Objects.equals(this.eventHint(), ((EventTask) obj).eventHint());
+ }
+
+ @Override
+ public String toString() {
+ return MoreObjects.toStringHelper(getClass())
+ .add("context", context())
+ .add("workletType", workletType())
+ .add("eventType", eventType())
+ .add("eventHint", eventHint())
+ .toString();
+ }
+
+ /**
+ * Gets a instance of builder.
+ * @return instance of builder
+ */
+ public static Builder builder() {
+ return new Builder();
+ }
+
+ /**
+ * Builder of EventTimeoutTask.
+ */
+ public static class Builder extends HandlerTask.Builder {
+ /**
+ * Event type (Class name of event).
+ */
+ private String eventType;
+
+ /**
+ * Event hint value for finding target event.
+ */
+ private String eventHint;
+
+ /**
+ * Sets Event type (Class name of event).
+ * @param eventType event type
+ * @return builder of EventTimeoutTask
+ */
+ public Builder eventType(String eventType) {
+ this.eventType = eventType;
+ return this;
+ }
+
+ /**
+ * Sets event hint string for finding target event.
+ * @param eventHint event hint string
+ * @return builder of EventTimeoutTask
+ */
+ public Builder eventHint(String eventHint) {
+ this.eventHint = eventHint;
+ return this;
+ }
+
+ @Override
+ public Builder context(WorkflowContext context) {
+ super.context(context);
+ return this;
+ }
+
+ @Override
+ public Builder workletType(String workletType) {
+ super.workletType(workletType);
+ return this;
+ }
+
+ /**
+ * Builds EventTimeoutTask.
+ * @return instance of EventTimeoutTask
+ */
+ public EventTimeoutTask build() {
+ return new EventTimeoutTask(this);
+ }
+ }
+}
diff --git a/apps/workflow/api/src/main/java/org/onosproject/workflow/api/HandlerTask.java b/apps/workflow/api/src/main/java/org/onosproject/workflow/api/HandlerTask.java
new file mode 100644
index 0000000..106466b
--- /dev/null
+++ b/apps/workflow/api/src/main/java/org/onosproject/workflow/api/HandlerTask.java
@@ -0,0 +1,95 @@
+/*
+ * Copyright 2018-present Open Networking Foundation
+ *
+ * Licensed 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.onosproject.workflow.api;
+
+import com.google.common.base.MoreObjects;
+
+/**
+ * Abstract class for handler task.
+ */
+public abstract class HandlerTask {
+
+ /**
+ * Workflow context of handler task.
+ */
+ private final WorkflowContext context;
+
+ /**
+ * Worklet type of handler task.
+ */
+ private final String workletType;
+
+ /**
+ * Constructor for handler task.
+ * @param builder handler task builder
+ */
+ protected HandlerTask(Builder builder) {
+ this.context = builder.context;
+ this.workletType = builder.workletType;
+ }
+
+ /**
+ * Returns workflow context of this handler task.
+ * @return workflow context
+ */
+ public WorkflowContext context() {
+ return context;
+ }
+
+ /**
+ * Returns worklet type name of this handler task.
+ * @return worklet type
+ */
+ public String workletType() {
+ return workletType;
+ }
+
+ @Override
+ public String toString() {
+ return MoreObjects.toStringHelper(getClass())
+ .add("context", context())
+ .add("workletType", workletType())
+ .toString();
+ }
+
+ /**
+ * Builder of HandlerTask.
+ */
+ public static class Builder {
+ protected WorkflowContext context;
+ protected String workletType;
+
+ /**
+ * Sets workflow context of handler task.
+ * @param context workflow context
+ * @return builder of handler task
+ */
+ public Builder context(WorkflowContext context) {
+ this.context = context;
+ return this;
+ }
+
+ /**
+ * Sets worklet type of handler task.
+ * @param workletType worklet type
+ * @return builder of handler task
+ */
+ public Builder workletType(String workletType) {
+ this.workletType = workletType;
+ return this;
+ }
+ }
+}
diff --git a/apps/workflow/api/src/main/java/org/onosproject/workflow/api/HandlerTaskBatchDelegate.java b/apps/workflow/api/src/main/java/org/onosproject/workflow/api/HandlerTaskBatchDelegate.java
new file mode 100644
index 0000000..c5859f2
--- /dev/null
+++ b/apps/workflow/api/src/main/java/org/onosproject/workflow/api/HandlerTaskBatchDelegate.java
@@ -0,0 +1,32 @@
+/*
+ * Copyright 2018-present Open Networking Foundation
+ *
+ * Licensed 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.onosproject.workflow.api;
+
+import java.util.Collection;
+
+/**
+ * Facade for receiving notifications from the handler task batch service.
+ */
+public interface HandlerTaskBatchDelegate {
+
+ /**
+ * Submits the specified batch of handler task operations for processing.
+ *
+ * @param operations batch of operations
+ */
+ void execute(Collection<Collection<HandlerTask>> operations);
+
+}
diff --git a/apps/workflow/api/src/main/java/org/onosproject/workflow/api/ImmutableListWorkflow.java b/apps/workflow/api/src/main/java/org/onosproject/workflow/api/ImmutableListWorkflow.java
new file mode 100644
index 0000000..b5ea456
--- /dev/null
+++ b/apps/workflow/api/src/main/java/org/onosproject/workflow/api/ImmutableListWorkflow.java
@@ -0,0 +1,288 @@
+/*
+ * Copyright 2018-present Open Networking Foundation
+ *
+ * Licensed 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.onosproject.workflow.api;
+
+import com.google.common.base.MoreObjects;
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableSet;
+import com.google.common.collect.Lists;
+import com.google.common.collect.Sets;
+import org.onlab.osgi.DefaultServiceDirectory;
+import org.onlab.osgi.ServiceNotFoundException;
+
+import java.lang.reflect.Modifier;
+import java.net.URI;
+import java.util.List;
+import java.util.Objects;
+import java.util.Set;
+
+/**
+ * Class for immutable list workflow.
+ */
+public final class ImmutableListWorkflow extends AbstractWorkflow {
+
+ /**
+ * Init worklet type(class name of init worklet type).
+ */
+ private String initWorkletType;
+
+ /**
+ * List of worklet.
+ */
+ private List<String> workletTypeList;
+
+ /**
+ * Set of workflow attributes.
+ */
+ private Set<WorkflowAttribute> attributes;
+
+ /**
+ * Constructor of ImmutableListWorkflow.
+ * @param builder builder of ImmutableListWorkflow
+ */
+ private ImmutableListWorkflow(Builder builder) {
+ super(builder.id);
+ this.initWorkletType = builder.initWorkletType;
+ workletTypeList = ImmutableList.copyOf(builder.workletTypeList);
+ attributes = ImmutableSet.copyOf(builder.attributes);
+ }
+
+ @Override
+ public Worklet init(WorkflowContext context) throws WorkflowException {
+ if (Objects.isNull(initWorkletType)) {
+ return null;
+ }
+
+ return getWorkletInstance(initWorkletType);
+ }
+
+
+ @Override
+ public Worklet next(WorkflowContext context) throws WorkflowException {
+
+ int cnt = 0;
+ for (int i = 0; i < workletTypeList.size(); i++) {
+
+ if (cnt++ > Worklet.MAX_WORKS) {
+ throw new WorkflowException("Maximum worklet execution exceeded");
+ }
+
+ String workletType = workletTypeList.get(i);
+
+ if (Worklet.Common.COMPLETED.tag().equals(workletType)) {
+ return Worklet.Common.COMPLETED;
+ }
+
+ if (Worklet.Common.INIT.tag().equals(workletType)) {
+ continue;
+ }
+
+ Worklet worklet = getWorkletInstance(workletType);
+ Class workClass = worklet.getClass();
+
+ if (BranchWorklet.class.isAssignableFrom(workClass)) {
+ Class nextClass = ((BranchWorklet) worklet).next(context);
+ if (nextClass == null) {
+ throw new WorkflowException("Invalid next Worklet for " + workClass);
+ }
+
+ // TODO : it does not support duplicated use of WorkType. It needs to consider label concept
+ int nextIdx = getClassIndex(nextClass);
+ if (nextIdx == -1) {
+ throw new WorkflowException("Failed to find next " + nextClass + " for " + workClass);
+ }
+
+ i = nextIdx;
+ continue;
+
+ } else {
+ if (worklet.isNext(context)) {
+ return worklet;
+ }
+ }
+ }
+ return Worklet.Common.COMPLETED;
+ }
+
+ @Override
+ public Worklet getWorkletInstance(String workletType) throws WorkflowException {
+
+ WorkflowStore store;
+ try {
+ store = DefaultServiceDirectory.getService(WorkflowStore.class);
+ } catch (ServiceNotFoundException e) {
+ throw new WorkflowException(e);
+ }
+
+ Class workClass;
+ try {
+ workClass = store.getClass(workletType);
+ } catch (ClassNotFoundException e) {
+ throw new WorkflowException(e);
+ }
+
+ if (!isAllowed(workClass)) {
+ throw new WorkflowException("Not allowed class(" + workClass.getSimpleName() + ")");
+ }
+
+ Worklet worklet;
+ try {
+ worklet = (Worklet) workClass.newInstance();
+ } catch (Exception e) {
+ throw new WorkflowException(e);
+ }
+
+ return worklet;
+ }
+
+ @Override
+ public Set<WorkflowAttribute> attributes() {
+ return ImmutableSet.copyOf(attributes);
+ }
+
+ /**
+ * Gets index of class in worklet type list.
+ * @param aClass class to get index
+ * @return index of class in worklet type list
+ */
+ private int getClassIndex(Class aClass) {
+ for (int i = 0; i < workletTypeList.size(); i++) {
+ if (Objects.equals(aClass.getName(), workletTypeList.get(i))) {
+ return i;
+ }
+ }
+ return -1;
+ }
+
+ /**
+ * Checks whether class is allowed class or not.
+ * @param clazz class to check
+ * @return Check result
+ */
+ private boolean isAllowed(Class clazz) {
+ // non static inner class is not allowed
+ if (clazz.isMemberClass() && !Modifier.isStatic(clazz.getModifiers())) {
+ return false;
+ }
+ // enum is not allowed
+ if (clazz.isEnum()) {
+ return false;
+ }
+ // class should be subclass of Work
+ if (!Worklet.class.isAssignableFrom(clazz)) {
+ return false;
+ }
+ return true;
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(this.toString());
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (obj == this) {
+ return true;
+ }
+ if (!(obj instanceof EventTask)) {
+ return false;
+ }
+ return Objects.equals(this.id(), ((ImmutableListWorkflow) obj).id())
+ && Objects.equals(this.initWorkletType, ((ImmutableListWorkflow) obj).initWorkletType)
+ && Objects.equals(this.workletTypeList, ((ImmutableListWorkflow) obj).workletTypeList)
+ && Objects.equals(this.attributes, ((ImmutableListWorkflow) obj).attributes);
+ }
+
+ @Override
+ public String toString() {
+ return MoreObjects.toStringHelper(getClass())
+ .add("id", id())
+ .add("initWorklet", initWorkletType)
+ .add("workList", workletTypeList)
+ .add("attributes", attributes)
+ .toString();
+ }
+
+ /**
+ * Gets a instance of builder.
+ * @return instance of builder
+ */
+ public static Builder builder() {
+ return new Builder();
+ }
+
+ /**
+ * Builder of ImmutableListWorkflow.
+ */
+ public static class Builder {
+
+ private URI id;
+ private String initWorkletType;
+ private final List<String> workletTypeList = Lists.newArrayList();
+ private final Set<WorkflowAttribute> attributes = Sets.newHashSet();
+
+ /**
+ * Sets id of immutable list workflow.
+ * @param uri id of immutable list workflow
+ * @return builder
+ */
+ public Builder id(URI uri) {
+ this.id = uri;
+ workletTypeList.add(Worklet.Common.INIT.tag());
+ return this;
+ }
+
+ /**
+ * Sets init worklet class name of immutable list workflow.
+ * @param workletClassName class name of worklet
+ * @return builder
+ */
+ public Builder init(String workletClassName) {
+ this.initWorkletType = workletClassName;
+ return this;
+ }
+
+ /**
+ * Chains worklet class name of immutable list workflow.
+ * @param workletClassName class name of worklet
+ * @return builder
+ */
+ public Builder chain(String workletClassName) {
+ workletTypeList.add(workletClassName);
+ return this;
+ }
+
+ /**
+ * Adds workflow attribute.
+ * @param attribute workflow attribute to be added
+ * @return builder
+ */
+ public Builder attribute(WorkflowAttribute attribute) {
+ attributes.add(attribute);
+ return this;
+ }
+
+ /**
+ * Builds ImmutableListWorkflow.
+ * @return instance of ImmutableListWorkflow
+ */
+ public ImmutableListWorkflow build() {
+ workletTypeList.add(Worklet.Common.COMPLETED.tag());
+ return new ImmutableListWorkflow(this);
+ }
+ }
+}
diff --git a/apps/workflow/api/src/main/java/org/onosproject/workflow/api/JsonDataModelTree.java b/apps/workflow/api/src/main/java/org/onosproject/workflow/api/JsonDataModelTree.java
new file mode 100644
index 0000000..3a74bd2
--- /dev/null
+++ b/apps/workflow/api/src/main/java/org/onosproject/workflow/api/JsonDataModelTree.java
@@ -0,0 +1,319 @@
+/*
+ * Copyright 2018-present Open Networking Foundation
+ *
+ * Licensed 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.onosproject.workflow.api;
+
+
+import com.fasterxml.jackson.core.JsonPointer;
+import com.fasterxml.jackson.core.JsonProcessingException;
+import com.fasterxml.jackson.databind.JsonNode;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.fasterxml.jackson.databind.node.ArrayNode;
+import com.fasterxml.jackson.databind.node.JsonNodeFactory;
+import com.fasterxml.jackson.databind.node.JsonNodeType;
+import com.fasterxml.jackson.databind.node.MissingNode;
+import com.fasterxml.jackson.databind.node.ObjectNode;
+import com.google.common.base.MoreObjects;
+
+import java.util.Objects;
+
+/**
+ * Class for json data model tree.
+ */
+public final class JsonDataModelTree implements DataModelTree {
+
+ /**
+ * Root node of json data model tree.
+ */
+ private JsonNode root;
+
+ /**
+ * Constructor of JsonDataModelTree.
+ */
+ public JsonDataModelTree() {
+ this.root = JsonNodeFactory.instance.objectNode();
+ }
+
+ /**
+ * Constructor of JsonDataModelTree.
+ * @param root root node of json data model tree
+ */
+ public JsonDataModelTree(JsonNode root) {
+ this.root = root;
+ }
+
+ @Override
+ public DataModelTree subtree(String path) {
+ JsonNode node = root.at(path);
+ if (Objects.isNull(node) || node.isMissingNode()) {
+ return null;
+ }
+ return new JsonDataModelTree(node);
+ }
+
+ @Override
+ public void attach(String path, DataModelTree tree) throws WorkflowException {
+ if (root == null || root instanceof MissingNode) {
+ throw new WorkflowException("Invalid root node");
+ }
+
+ JsonPointer ptr = JsonPointer.compile(path);
+ JsonNode node = root.at(ptr);
+ if (!(node instanceof MissingNode)) {
+ throw new WorkflowException("Path(" + path + ") has already subtree(" + node + ")");
+ }
+
+ if (!(tree instanceof JsonDataModelTree)) {
+ throw new WorkflowException("Invalid subTree(" + tree + ")");
+ }
+ JsonNode attachingNode = ((JsonDataModelTree) tree).root();
+
+ alloc(ptr.head(), Nodetype.MAP);
+ JsonNode parentNode = root.at(ptr.head());
+
+ if (!parentNode.isObject()) {
+ throw new WorkflowException("Invalid parentNode type(" + parentNode.getNodeType() + ")");
+ }
+
+ String key = ptr.last().getMatchingProperty();
+ ((ObjectNode) parentNode).put(key, attachingNode);
+ }
+
+ @Override
+ public JsonDataModelTree alloc(String path, Nodetype leaftype) throws WorkflowException {
+ if (root == null || root instanceof MissingNode) {
+ throw new WorkflowException("Invalid root node");
+ }
+
+ JsonPointer ptr = JsonPointer.compile(path);
+ return alloc(ptr, leaftype);
+ }
+
+ /**
+ * Allocates json data model tree on json pointer path with specific leaf type.
+ * @param ptr json pointer to allocate
+ * @param leaftype type of leaf node
+ * @return json data model tree
+ * @throws WorkflowException workflow exception
+ */
+ private JsonDataModelTree alloc(JsonPointer ptr, Nodetype leaftype) throws WorkflowException {
+ if (root == null || root instanceof MissingNode) {
+ throw new WorkflowException("Invalid root node");
+ }
+
+ switch (leaftype) {
+ case MAP:
+ alloc(root, ptr, JsonNodeType.OBJECT);
+ break;
+ case ARRAY:
+ alloc(root, ptr, JsonNodeType.ARRAY);
+ break;
+ default:
+ throw new WorkflowException("Not supported leaftype(" + leaftype + ")");
+ }
+ return this;
+ }
+
+ /**
+ * Gets root json node.
+ * @return root json node
+ * @throws WorkflowException workflow exception
+ */
+ public JsonNode root() throws WorkflowException {
+ return nodeAt("");
+ }
+
+ /**
+ * Gets root json node as ObjectNode (MAP type).
+ * @return root json node as ObjectNode
+ * @throws WorkflowException workflow exception
+ */
+ public ObjectNode rootObject() throws WorkflowException {
+ return objectAt("");
+ }
+
+ /**
+ * Gets root json node as ArrayNode (Array type).
+ * @return root json node as ArrayNode
+ * @throws WorkflowException workflow exception
+ */
+ public ArrayNode rootArray() throws WorkflowException {
+ return arrayAt("");
+ }
+
+ /**
+ * Gets json node on specific path.
+ * @param path path of json node
+ * @return json node on specific path
+ * @throws WorkflowException workflow exception
+ */
+ public JsonNode nodeAt(String path) throws WorkflowException {
+ JsonPointer ptr = JsonPointer.compile(path);
+ return nodeAt(ptr);
+ }
+
+ /**
+ * Gets json node on specific json pointer.
+ * @param ptr json pointer
+ * @return json node on specific json pointer.
+ * @throws WorkflowException workflow exception
+ */
+ public JsonNode nodeAt(JsonPointer ptr) throws WorkflowException {
+ if (root == null || root instanceof MissingNode) {
+ throw new WorkflowException("Invalid root node");
+ }
+ JsonNode node = root.at(ptr);
+ return node;
+ }
+
+ /**
+ * Gets json node on specific path as ObjectNode.
+ * @param path path of json node
+ * @return ObjectNode type json node on specific path
+ * @throws WorkflowException workflow exception
+ */
+ public ObjectNode objectAt(String path) throws WorkflowException {
+ JsonPointer ptr = JsonPointer.compile(path);
+ return objectAt(ptr);
+ }
+
+ /**
+ * Gets json node on specific json pointer as ObjectNode.
+ * @param ptr json pointer
+ * @return ObjectNode type json node on specific json pointer.
+ * @throws WorkflowException workflow exception
+ */
+ public ObjectNode objectAt(JsonPointer ptr) throws WorkflowException {
+ if (root == null || root instanceof MissingNode) {
+ throw new WorkflowException("Invalid root node");
+ }
+ JsonNode node = root.at(ptr);
+ if (!(node instanceof ObjectNode)) {
+ throw new WorkflowException("Invalid node(" + node + ") at " + ptr);
+ }
+ return (ObjectNode) node;
+ }
+
+ /**
+ * Gets json node on specific path as ArrayNode.
+ * @param path path of json node
+ * @return ArrayNode type json node on specific path
+ * @throws WorkflowException workflow exception
+ */
+ public ArrayNode arrayAt(String path) throws WorkflowException {
+ JsonPointer ptr = JsonPointer.compile(path);
+ return arrayAt(ptr);
+ }
+
+ /**
+ * Gets json node on specific json pointer as ArrayNode.
+ * @param ptr json pointer
+ * @return ArrayNode type json node on specific json pointer.
+ * @throws WorkflowException workflow exception
+ */
+ public ArrayNode arrayAt(JsonPointer ptr) throws WorkflowException {
+ if (root == null || root instanceof MissingNode) {
+ throw new WorkflowException("Invalid root node");
+ }
+ JsonNode node = root.at(ptr);
+ if (!(node instanceof ArrayNode)) {
+ throw new WorkflowException("Invalid node(" + node + ") at " + ptr);
+ }
+ return (ArrayNode) node;
+ }
+
+ /**
+ * Allocates json data model tree on json pointer path with specific leaf type.
+ * @param node current json node in the json tree path
+ * @param ptr json pointer
+ * @param leaftype leaf type to be allocated
+ * @return allocated json node
+ * @throws WorkflowException workflow exception
+ */
+ private JsonNode alloc(JsonNode node, JsonPointer ptr, JsonNodeType leaftype) throws WorkflowException {
+
+ if (ptr.matches()) {
+ if (node instanceof MissingNode) {
+ node = createEmpty(leaftype);
+ } else {
+ //TODO: checking existing node type is matched with leaftype
+ if (Objects.equals(node.getNodeType(), leaftype)) {
+ throw new WorkflowException("Requesting leaftype(" + leaftype + ") is not matched with "
+ + "existing nodetype(" + node.getNodeType() + ") for " + ptr);
+ }
+ }
+ return node;
+ }
+
+ if (ptr.getMatchingIndex() != -1) {
+ if (node instanceof MissingNode) {
+ node = createEmpty(JsonNodeType.ARRAY);
+ }
+ JsonNode child = alloc(node.get(ptr.getMatchingIndex()), ptr.tail(), leaftype);
+ if (!node.has(ptr.getMatchingIndex())) {
+ ((ArrayNode) node).insert(ptr.getMatchingIndex(), child);
+ }
+ } else if (ptr.getMatchingProperty() != null) {
+ if (node instanceof MissingNode) {
+ node = createEmpty(JsonNodeType.OBJECT);
+ }
+ JsonNode child = alloc(node.get(ptr.getMatchingProperty()), ptr.tail(), leaftype);
+ if (!node.has(ptr.getMatchingProperty())) {
+ ((ObjectNode) node).put(ptr.getMatchingProperty(), child);
+ }
+ }
+ return node;
+ }
+
+ /**
+ * Creating empty json node.
+ * @param type json node type to create
+ * @return created json node
+ * @throws WorkflowException workflow exception
+ */
+ private JsonNode createEmpty(JsonNodeType type) throws WorkflowException {
+ if (type == JsonNodeType.OBJECT) {
+ return JsonNodeFactory.instance.objectNode();
+ } else if (type == JsonNodeType.ARRAY) {
+ return JsonNodeFactory.instance.arrayNode();
+ } else if (type == JsonNodeType.STRING) {
+ return JsonNodeFactory.instance.textNode("");
+ } else {
+ throw new WorkflowException("Not supported JsonNodetype(" + type + ")");
+ }
+ }
+
+ /**
+ * Gets the pretty json formatted string of this json data model tree.
+ * @return pretty json formatted string of this json data model tree
+ */
+ public String formattedRootString() {
+ String str = "";
+ try {
+ str = (new ObjectMapper()).writerWithDefaultPrettyPrinter().writeValueAsString(root);
+ } catch (JsonProcessingException e) {
+ e.printStackTrace();
+ }
+ return str;
+ }
+
+ @Override
+ public String toString() {
+ return MoreObjects.toStringHelper(getClass())
+ .add("json", formattedRootString())
+ .toString();
+ }
+}
+
diff --git a/apps/workflow/api/src/main/java/org/onosproject/workflow/api/RpcDescription.java b/apps/workflow/api/src/main/java/org/onosproject/workflow/api/RpcDescription.java
new file mode 100644
index 0000000..5b067b4
--- /dev/null
+++ b/apps/workflow/api/src/main/java/org/onosproject/workflow/api/RpcDescription.java
@@ -0,0 +1,57 @@
+/*
+ * Copyright 2018-present Open Networking Foundation
+ *
+ * Licensed 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.onosproject.workflow.api;
+
+import com.fasterxml.jackson.databind.JsonNode;
+
+/**
+ * Interface for workflow RPC description.
+ */
+public interface RpcDescription {
+
+ /**
+ * Workflow RPC operation pointer.
+ */
+ String RPC_OP_PTR = "/op";
+
+ /**
+ * Workflow RPC parameters pointer.
+ */
+ String RPC_PARAMS_PTR = "/params";
+
+ /**
+ * Workflow RPC invocation ID pointer.
+ */
+ String RPC_ID_PTR = "/id";
+
+ /**
+ * Returns workflow RPC operation.
+ * @return workflow RPC operation
+ */
+ String op();
+
+ /**
+ * Returns workflow RPC parameters.
+ * @return workflow RPC parameters
+ */
+ JsonNode params();
+
+ /**
+ * Returns workflow RPC invocation ID.
+ * @return workflow RPC invocation ID
+ */
+ String id();
+}
diff --git a/apps/workflow/api/src/main/java/org/onosproject/workflow/api/SystemWorkflowContext.java b/apps/workflow/api/src/main/java/org/onosproject/workflow/api/SystemWorkflowContext.java
new file mode 100644
index 0000000..5642c97
--- /dev/null
+++ b/apps/workflow/api/src/main/java/org/onosproject/workflow/api/SystemWorkflowContext.java
@@ -0,0 +1,81 @@
+/*
+ * Copyright 2018-present Open Networking Foundation
+ *
+ * Licensed 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.onosproject.workflow.api;
+
+import com.google.common.base.MoreObjects;
+
+import java.net.URI;
+
+/**
+ * WorkflowContext for system workflow.
+ */
+public class SystemWorkflowContext extends DefaultWorkflowContext {
+
+ /**
+ * Timestamp when this system workflow context was created.
+ */
+ private final long timestamp;
+
+ /**
+ * Distributor string for designating which onos node executes this workflow context with work partition.
+ */
+ private String distributor;
+
+ /**
+ * The constructor of SystemWorkflowContext.
+ * @param workflowId id of workflow
+ * @param workplaceName workplace name
+ * @param data data model tree
+ */
+ public SystemWorkflowContext(URI workflowId, String workplaceName, DataModelTree data) {
+ super(workflowId, workplaceName, data);
+ timestamp = System.currentTimeMillis();
+ //initial distributor(It can be changed)
+ distributor = name();
+ }
+
+ @Override
+ public String distributor() {
+ return distributor;
+ }
+
+ /**
+ * Sets distributor string of this workflow context.
+ * @param distributor distributor string
+ */
+ public void setDistributor(String distributor) {
+ this.distributor = distributor;
+ }
+
+ @Override
+ public String name() {
+ return workflowId().toString()
+ + ":" + timestamp
+ + "@" + workplaceName();
+ }
+
+ @Override
+ public String toString() {
+ return MoreObjects.toStringHelper(getClass())
+ .add("name", name())
+ .add("triggernext", triggerNext())
+ .add("data", data())
+ .add("current", current())
+ .add("state", state())
+ .add("cause", cause())
+ .toString();
+ }
+}
diff --git a/apps/workflow/api/src/main/java/org/onosproject/workflow/api/TimeoutTask.java b/apps/workflow/api/src/main/java/org/onosproject/workflow/api/TimeoutTask.java
new file mode 100644
index 0000000..5b98bd1
--- /dev/null
+++ b/apps/workflow/api/src/main/java/org/onosproject/workflow/api/TimeoutTask.java
@@ -0,0 +1,67 @@
+/*
+ * Copyright 2018-present Open Networking Foundation
+ *
+ * Licensed 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.onosproject.workflow.api;
+
+import com.google.common.base.MoreObjects;
+
+
+public final class TimeoutTask extends HandlerTask {
+
+ private TimeoutTask(Builder builder) {
+ super(builder);
+ }
+
+ @Override
+ public String toString() {
+ return MoreObjects.toStringHelper(getClass())
+ .add("context", context())
+ .add("workletType", workletType())
+ .toString();
+ }
+
+ /**
+ * Gets a instance of builder.
+ * @return instance of builder
+ */
+ public static Builder builder() {
+ return new Builder();
+ }
+
+ /**
+ * Builder of TimeoutTask.
+ */
+ public static class Builder extends HandlerTask.Builder {
+ @Override
+ public Builder context(WorkflowContext context) {
+ super.context(context);
+ return this;
+ }
+
+ @Override
+ public Builder workletType(String workletType) {
+ super.workletType(workletType);
+ return this;
+ }
+
+ /**
+ * Builds TimeoutTask.
+ * @return instance of TimeoutTask
+ */
+ public TimeoutTask build() {
+ return new TimeoutTask(this);
+ }
+ }
+}
diff --git a/apps/workflow/api/src/main/java/org/onosproject/workflow/api/TimerChain.java b/apps/workflow/api/src/main/java/org/onosproject/workflow/api/TimerChain.java
new file mode 100644
index 0000000..33c6aa3
--- /dev/null
+++ b/apps/workflow/api/src/main/java/org/onosproject/workflow/api/TimerChain.java
@@ -0,0 +1,223 @@
+/*
+ * Copyright 2018-present Open Networking Foundation
+ *
+ * Licensed 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.onosproject.workflow.api;
+
+import java.util.Date;
+import java.util.PriorityQueue;
+import java.util.Timer;
+import java.util.TimerTask;
+
+/**
+ * Class for time chain timer.
+ */
+public class TimerChain {
+
+ private PriorityQueue<TimerChainTask> taskQueue = new PriorityQueue<>();
+
+ private Timer impendingTimer;
+ private TimerChainTask impendingTask;
+
+ /**
+ * Schedules timer event.
+ * @param afterMs millisecond which time event happens.
+ * @param runnable runnable to be executed after 'afterMs'
+ */
+ public void schedule(long afterMs, Runnable runnable) {
+ schedule(new Date((new Date()).getTime() + afterMs), runnable);
+ }
+
+ /**
+ * Schedules timer event.
+ * @param date date which timer event happens.
+ * @param runnable runnable to be executed on 'date'
+ */
+ public void schedule(Date date, Runnable runnable) {
+ schedule(new TimerChainTask(this, date, runnable));
+ }
+
+ /**
+ * Schedule timer chain task.
+ * @param task task to be scheduled.
+ */
+ private void schedule(TimerChainTask task) {
+ synchronized (this) {
+ if (taskQueue.size() == 0) {
+ scheduleImpending(task);
+ return;
+ }
+
+ if (task.date().getTime() < head().date().getTime()) {
+ impendingTimer.cancel();
+ impendingTask.cancel();
+ TimerChainTask prevImpendingTask = pop().copy();
+ taskQueue.offer(prevImpendingTask);
+
+ scheduleImpending(task);
+ } else {
+ taskQueue.offer(task);
+ }
+ }
+ }
+
+ /**
+ * Schedule impending timer task.
+ * @param task impending timer chain task
+ * @return timer chain task
+ */
+ private TimerChainTask scheduleImpending(TimerChainTask task) {
+ taskQueue.offer(task);
+ Timer timer = new Timer();
+ this.setImpendingTask(task);
+ this.setImpendingTimer(timer);
+ timer.schedule(task, task.date());
+ return task;
+ }
+
+ /**
+ * Gets impending timer.
+ * @return impending timer
+ */
+ public Timer implendingTimer() {
+ return impendingTimer;
+ }
+
+ /**
+ * Sets impending timer.
+ * @param impendingTimer impending timer
+ */
+ public void setImpendingTimer(Timer impendingTimer) {
+ this.impendingTimer = impendingTimer;
+ }
+
+ /**
+ * Gets impending timer task.
+ * @return impending timer task
+ */
+ public TimerTask impendingTask() {
+ return impendingTask;
+ }
+
+ /**
+ * Sets impending timer task.
+ * @param impendingTask impending timer task
+ */
+ public void setImpendingTask(TimerChainTask impendingTask) {
+ this.impendingTask = impendingTask;
+ }
+
+ /**
+ * Gets head of timer chain task queue.
+ * @return timer chain task
+ */
+ public TimerChainTask head() {
+ if (taskQueue.size() > 0) {
+ return taskQueue.peek();
+ } else {
+ return null;
+ }
+ }
+
+ /**
+ * Pops head of timer chain task queue.
+ * @return timer chain task
+ */
+ public TimerChainTask pop() {
+ if (taskQueue.size() > 0) {
+ return taskQueue.poll();
+ } else {
+ return null;
+ }
+ }
+
+ /**
+ * Class for timer chain task.
+ */
+ public static class TimerChainTask extends TimerTask implements Comparable<TimerChainTask> {
+
+ private final TimerChain timerchain;
+ private final Date date;
+ private final Runnable runnable;
+
+ /**
+ * Constructor of timer chain task.
+ * @param timerchain timer chain
+ * @param date date to be scheduled
+ * @param runnable runnable to be executed by timer
+ */
+ public TimerChainTask(TimerChain timerchain, Date date, Runnable runnable) {
+ this.timerchain = timerchain;
+ this.date = date;
+ this.runnable = runnable;
+ }
+
+ /**
+ * Gets date.
+ * @return date of timer chain task
+ */
+ public Date date() {
+ return this.date;
+ }
+
+ /**
+ * Gets runnable.
+ * @return runnable of timer chain task
+ */
+ public Runnable runnable() {
+ return this.runnable;
+ }
+
+ @Override
+ public void run() {
+
+ TimerChainTask nextTask;
+ synchronized (timerchain) {
+ if (timerchain.impendingTask() != this) {
+ System.out.println("Invalid impendingTask");
+ runnable().run();
+ return;
+ }
+
+ timerchain.implendingTimer().cancel();
+ timerchain.pop();
+
+ nextTask = timerchain.head();
+
+ if (nextTask != null) {
+ Timer nextTimer = new Timer();
+ this.timerchain.setImpendingTask(nextTask);
+ this.timerchain.setImpendingTimer(nextTimer);
+ nextTimer.schedule(nextTask, nextTask.date());
+ }
+ }
+
+ runnable().run();
+
+ }
+
+ @Override
+ public int compareTo(TimerChainTask target) {
+ return date().compareTo(target.date());
+ }
+
+ /**
+ * Copies timer chain task.
+ * @return timer chain task
+ */
+ public TimerChainTask copy() {
+ return new TimerChainTask(timerchain, date, runnable);
+ }
+ }
+}
diff --git a/apps/workflow/api/src/main/java/org/onosproject/workflow/api/WorkExecutor.java b/apps/workflow/api/src/main/java/org/onosproject/workflow/api/WorkExecutor.java
new file mode 100644
index 0000000..e834e81
--- /dev/null
+++ b/apps/workflow/api/src/main/java/org/onosproject/workflow/api/WorkExecutor.java
@@ -0,0 +1,29 @@
+/*
+ * Copyright 2018-present Open Networking Foundation
+ *
+ * Licensed 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.onosproject.workflow.api;
+
+/**
+ * Functional interface for delivering method reference of worklet completion event generator.
+ */
+@FunctionalInterface
+public interface WorkExecutor {
+
+ /**
+ * Applies this method reference.
+ * @throws WorkflowException workflow exception
+ */
+ void apply() throws WorkflowException;
+}
diff --git a/apps/workflow/api/src/main/java/org/onosproject/workflow/api/Workflow.java b/apps/workflow/api/src/main/java/org/onosproject/workflow/api/Workflow.java
new file mode 100644
index 0000000..95e6e08
--- /dev/null
+++ b/apps/workflow/api/src/main/java/org/onosproject/workflow/api/Workflow.java
@@ -0,0 +1,79 @@
+/*
+ * Copyright 2018-present Open Networking Foundation
+ *
+ * Licensed 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.onosproject.workflow.api;
+
+import java.net.URI;
+import java.util.Set;
+
+/**
+ * An interface representing workflow.
+ */
+public interface Workflow {
+
+ /**
+ * Id of workflow.
+ * @return id
+ */
+ URI id();
+
+ /**
+ * Returns init worklet.
+ * @param context workflow context
+ * @return init worklet
+ * @throws WorkflowException workflow exception
+ */
+ Worklet init(WorkflowContext context) throws WorkflowException;
+
+ /**
+ * Returns next worklet.
+ * @param context workflow context
+ * @return next worklet
+ * @throws WorkflowException workflow exception
+ */
+ Worklet next(WorkflowContext context) throws WorkflowException;
+
+ /**
+ * Returns instance of worklet.
+ * @param workletType class name of worklet
+ * @return instance of worklet
+ * @throws WorkflowException workflow exception
+ */
+ Worklet getWorkletInstance(String workletType) throws WorkflowException;
+
+ /**
+ * Builds workflow context.
+ * @param workplace workplace of system workflow
+ * @param data data model of system workflow context
+ * @return workflow context
+ * @throws WorkflowException workflow exception
+ */
+ WorkflowContext buildContext(Workplace workplace, DataModelTree data) throws WorkflowException;
+
+ /**
+ * Builds system workflow context.
+ * @param workplace workplace of system workflow
+ * @param data data model of system workflow context
+ * @return system workflow context
+ * @throws WorkflowException workflow exception
+ */
+ WorkflowContext buildSystemContext(Workplace workplace, DataModelTree data) throws WorkflowException;
+
+ /**
+ * Returns workflow attributes.
+ * @return attributes
+ */
+ Set<WorkflowAttribute> attributes();
+}
diff --git a/apps/workflow/api/src/main/java/org/onosproject/workflow/api/WorkflowAttribute.java b/apps/workflow/api/src/main/java/org/onosproject/workflow/api/WorkflowAttribute.java
new file mode 100644
index 0000000..18ed701
--- /dev/null
+++ b/apps/workflow/api/src/main/java/org/onosproject/workflow/api/WorkflowAttribute.java
@@ -0,0 +1,27 @@
+/*
+ * Copyright 2018-present Open Networking Foundation
+ *
+ * Licensed 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.onosproject.workflow.api;
+
+/**
+ * Attributes of workflow.
+ */
+public enum WorkflowAttribute {
+
+ /**
+ * Removes workflow context after completion of workflow.
+ */
+ REMOVE_AFTER_COMPLETE,
+}
diff --git a/apps/workflow/api/src/main/java/org/onosproject/workflow/api/WorkflowBatchDelegate.java b/apps/workflow/api/src/main/java/org/onosproject/workflow/api/WorkflowBatchDelegate.java
new file mode 100644
index 0000000..d54a92a
--- /dev/null
+++ b/apps/workflow/api/src/main/java/org/onosproject/workflow/api/WorkflowBatchDelegate.java
@@ -0,0 +1,35 @@
+/*
+ * Copyright 2018-present Open Networking Foundation
+ *
+ * Licensed 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.onosproject.workflow.api;
+
+import com.google.common.annotations.Beta;
+
+import java.util.Collection;
+
+/**
+ * Facade for receiving notifications from the workflow batch service.
+ */
+@Beta
+public interface WorkflowBatchDelegate {
+
+ /**
+ * Submits the specified batch of workflow operations for processing.
+ *
+ * @param operations batch of operations
+ */
+ void execute(Collection<WorkflowData> operations);
+
+}
diff --git a/apps/workflow/api/src/main/java/org/onosproject/workflow/api/WorkflowContext.java b/apps/workflow/api/src/main/java/org/onosproject/workflow/api/WorkflowContext.java
new file mode 100644
index 0000000..12d4673
--- /dev/null
+++ b/apps/workflow/api/src/main/java/org/onosproject/workflow/api/WorkflowContext.java
@@ -0,0 +1,166 @@
+/*
+ * Copyright 2018-present Open Networking Foundation
+ *
+ * Licensed 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.onosproject.workflow.api;
+
+import org.onosproject.event.Event;
+
+import java.net.URI;
+
+/**
+ * An abstract class representing WorkflowContext.
+ */
+public abstract class WorkflowContext extends WorkflowData {
+
+ /**
+ * Constructor of workflow context.
+ * @param data data model tree
+ */
+ public WorkflowContext(DataModelTree data) {
+ super(data);
+ }
+
+ /**
+ * Returns workflow id of this workflow context.
+ * @return workflow id
+ */
+ public abstract URI workflowId();
+
+ /**
+ * Returns workplace name.
+ * @return workplace name
+ */
+ public abstract String workplaceName();
+
+ /**
+ * Returns the current state of workflow context.
+ * @return current state of workflow context
+ */
+ public abstract WorkflowState state();
+
+ /**
+ * Sets the current state of workflow context.
+ * @param state current state of workflow context
+ */
+ public abstract void setState(WorkflowState state);
+
+ /**
+ * Sets the current worklet of workflow context.
+ * @param worklet current worklet
+ */
+ public abstract void setCurrent(Worklet worklet);
+
+ /**
+ * Returns the class name of current worklet.
+ * @return the class name of current worklet
+ */
+ public abstract String current();
+
+ /**
+ * Returns the cause string of exception state.
+ * @return cause string
+ */
+ public abstract String cause();
+
+ /**
+ * Sets the cause string of exception state.
+ * @param cause cause string
+ */
+ public abstract void setCause(String cause);
+
+ /**
+ * Indicates the worklet process become completed.
+ * By calling this, workflow triggers the next worklet selection
+ */
+ public abstract void completed();
+
+ /**
+ * Waits an event which have 'eventHint' after executing executor.
+ * If the event happens, Worklet.isCompleted will be called.
+ * If the event does not happen for timeoutMs, Worklet.timeout will be called.
+ * @param eventType the class of event to wait
+ * @param eventHint the event of the event to wait
+ * @param eventGenerator a method reference to be executed after executing executor
+ * @param timeoutMs timeout millisecond
+ */
+ public abstract void waitCompletion(Class<? extends Event> eventType, String eventHint,
+ WorkExecutor eventGenerator, long timeoutMs);
+
+ /**
+ * Waits timeout milliseconds. After timeoutMs Worklet.timeout will be called.
+ * @param timeoutMs timeout millisecond
+ */
+ public abstract void waitFor(long timeoutMs);
+
+ /**
+ * Returns the class of a completion event to wait.
+ * @return the class of a completion event
+ */
+ public abstract Class<? extends Event> completionEventType();
+
+ /**
+ * Returns the event hint string to wait.
+ * @return the event hint string
+ */
+ public abstract String completionEventHint();
+
+ /**
+ * Returns method reference for generating completion event.
+ * @return a method reference
+ */
+ public abstract WorkExecutor completionEventGenerator();
+
+ /**
+ * Returns completion event timeout.
+ * @return completion event timeout
+ */
+ public abstract long completionEventTimeout();
+
+ /**
+ * Sets workflow service.
+ * @param workflowExecutionService workflow service
+ */
+ public abstract void setWorkflowExecutionService(WorkflowExecutionService workflowExecutionService);
+
+ /**
+ * Gets workflow service.
+ * @return workflow service
+ */
+ public abstract WorkflowExecutionService workflowService();
+
+ /**
+ * Sets workflow store.
+ * @param workflowStore workflow store.
+ */
+ public abstract void setWorkflowStore(WorkflowStore workflowStore);
+
+ /**
+ * Gets worklow store.
+ * @return workflow store
+ */
+ public abstract WorkflowStore workflowStore();
+
+ /**
+ * Sets workplace store.
+ * @param workplaceStore work place store.
+ */
+ public abstract void setWorkplaceStore(WorkplaceStore workplaceStore);
+
+ /**
+ * Gets workplace store.
+ * @return workplace store
+ */
+ public abstract WorkplaceStore workplaceStore();
+}
diff --git a/apps/workflow/api/src/main/java/org/onosproject/workflow/api/WorkflowData.java b/apps/workflow/api/src/main/java/org/onosproject/workflow/api/WorkflowData.java
new file mode 100644
index 0000000..6a8590c
--- /dev/null
+++ b/apps/workflow/api/src/main/java/org/onosproject/workflow/api/WorkflowData.java
@@ -0,0 +1,71 @@
+/*
+ * Copyright 2018-present Open Networking Foundation
+ *
+ * Licensed 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.onosproject.workflow.api;
+
+
+/**
+ * An abstract class representing workflow data.
+ */
+public abstract class WorkflowData {
+
+ private DataModelTree data;
+ private boolean triggerNext = true; // default is true
+
+ /**
+ * Constructor of workflow data.
+ * @param data data model tree
+ */
+ public WorkflowData(DataModelTree data) {
+ this.data = data;
+ }
+
+ /**
+ * Returns name.
+ * @return name
+ */
+ public abstract String name();
+
+ /**
+ * Returns work-partition distributor.
+ * @return work-partition distributor
+ */
+ public abstract String distributor();
+
+ /**
+ * Returns context model tree.
+ * @return context model tree
+ */
+ public DataModelTree data() {
+ return data;
+ }
+
+ /**
+ * Returns whether to trigger next worklet selection.
+ * @return whether to trigger next worklet selection
+ */
+ public boolean triggerNext() {
+ return triggerNext;
+ }
+
+ /**
+ * Sets whether to handle update event.
+ * @param triggerNext whether to handle update event
+ */
+ public void setTriggerNext(boolean triggerNext) {
+ this.triggerNext = triggerNext;
+ }
+
+}
diff --git a/apps/workflow/api/src/main/java/org/onosproject/workflow/api/WorkflowDataEvent.java b/apps/workflow/api/src/main/java/org/onosproject/workflow/api/WorkflowDataEvent.java
new file mode 100644
index 0000000..4833251
--- /dev/null
+++ b/apps/workflow/api/src/main/java/org/onosproject/workflow/api/WorkflowDataEvent.java
@@ -0,0 +1,54 @@
+/*
+ * Copyright 2018-present Open Networking Foundation
+ *
+ * Licensed 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.onosproject.workflow.api;
+
+import org.onosproject.event.AbstractEvent;
+
+/**
+ * Workflow data event class.
+ */
+public class WorkflowDataEvent extends AbstractEvent<WorkflowDataEvent.Type, WorkflowData> {
+
+ /**
+ * Workflow data event types.
+ */
+ public enum Type {
+
+ /**
+ * Insertion of workflow data.
+ */
+ INSERT,
+
+ /**
+ * Updation of workflow data.
+ */
+ UPDATE,
+
+ /**
+ * Removal of workflow data.
+ */
+ REMOVE
+ }
+
+ /**
+ * Constructor for workflow data event.
+ * @param type workflow data event type
+ * @param data workflow data
+ */
+ public WorkflowDataEvent(Type type, WorkflowData data) {
+ super(type, data);
+ }
+}
diff --git a/apps/workflow/api/src/main/java/org/onosproject/workflow/api/WorkflowDataListener.java b/apps/workflow/api/src/main/java/org/onosproject/workflow/api/WorkflowDataListener.java
new file mode 100644
index 0000000..b777e74
--- /dev/null
+++ b/apps/workflow/api/src/main/java/org/onosproject/workflow/api/WorkflowDataListener.java
@@ -0,0 +1,25 @@
+/*
+ * Copyright 2018-present Open Networking Foundation
+ *
+ * Licensed 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.onosproject.workflow.api;
+
+import org.onosproject.event.EventListener;
+
+/**
+ * Interface for workflow data listener.
+ */
+public interface WorkflowDataListener extends EventListener<WorkflowDataEvent> {
+
+}
diff --git a/apps/workflow/api/src/main/java/org/onosproject/workflow/api/WorkflowDescription.java b/apps/workflow/api/src/main/java/org/onosproject/workflow/api/WorkflowDescription.java
new file mode 100644
index 0000000..ca483f0
--- /dev/null
+++ b/apps/workflow/api/src/main/java/org/onosproject/workflow/api/WorkflowDescription.java
@@ -0,0 +1,71 @@
+/*
+ * Copyright 2018-present Open Networking Foundation
+ *
+ * Licensed 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.onosproject.workflow.api;
+
+import com.fasterxml.jackson.databind.JsonNode;
+import java.net.URI;
+
+
+/**
+ * interface for workflow description.
+ */
+public interface WorkflowDescription {
+
+ /**
+ * Workflow workplace field name.
+ */
+ String WF_WORKPLACE = "workplace";
+
+ /**
+ * Workflow ID field name.
+ */
+ String WF_ID = "id";
+
+ /**
+ * Workflow data field name.
+ */
+ String WF_DATA = "data";
+
+ /**
+ * Gets workplace name.
+ * @return workplace name
+ */
+ String workplaceName();
+
+ /**
+ * Gets workflow ID.
+ * @return workflow ID
+ */
+ URI id();
+
+ /**
+ * Gets workflow context name.
+ * @return workflow context name
+ */
+ String workflowContextName();
+
+ /**
+ * Gets workflow data model.
+ * @return workflow data model
+ */
+ JsonNode data();
+
+ /**
+ * Gets json of workflow description.
+ * @return json of workflow description
+ */
+ JsonNode toJson();
+}
diff --git a/apps/workflow/api/src/main/java/org/onosproject/workflow/api/WorkflowException.java b/apps/workflow/api/src/main/java/org/onosproject/workflow/api/WorkflowException.java
new file mode 100644
index 0000000..09506bd
--- /dev/null
+++ b/apps/workflow/api/src/main/java/org/onosproject/workflow/api/WorkflowException.java
@@ -0,0 +1,50 @@
+/*
+ * Copyright 2018-present Open Networking Foundation
+ *
+ * Licensed 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.onosproject.workflow.api;
+
+/**
+ * Workflow exception class.
+ */
+public class WorkflowException extends Exception {
+
+ private static final long serialVersionUID = 1L;
+
+ /**
+ * Constructor for workflow exception.
+ * @param msg exception message
+ */
+ public WorkflowException(String msg) {
+ super(msg);
+ }
+
+ /**
+ * Constructor for workflow exception.
+ * @param e throwable to deliver
+ */
+ public WorkflowException(Throwable e) {
+ super(e);
+ }
+
+ /**
+ * Constructor for workflow exception.
+ * @param msg exception message
+ * @param e throwable to deliver
+ */
+ public WorkflowException(String msg, Throwable e) {
+ super(msg, e);
+ }
+
+}
diff --git a/apps/workflow/api/src/main/java/org/onosproject/workflow/api/WorkflowExecutionService.java b/apps/workflow/api/src/main/java/org/onosproject/workflow/api/WorkflowExecutionService.java
new file mode 100644
index 0000000..ad9f731
--- /dev/null
+++ b/apps/workflow/api/src/main/java/org/onosproject/workflow/api/WorkflowExecutionService.java
@@ -0,0 +1,50 @@
+/*
+ * Copyright 2018-present Open Networking Foundation
+ *
+ * Licensed 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.onosproject.workflow.api;
+
+import org.onosproject.event.Event;
+import org.onosproject.event.ListenerService;
+
+/**
+ * Interface for workflow execution service.
+ */
+public interface WorkflowExecutionService extends ListenerService<WorkflowDataEvent, WorkflowDataListener> {
+
+ /**
+ * Executes init worklet.
+ * @param context workflow context
+ */
+ void execInitWorklet(WorkflowContext context);
+
+ /**
+ * Triggers workflow event map.
+ * @param event triggering event
+ * @param generator event hint generation method reference
+ */
+ void eventMapTrigger(Event event, EventHintSupplier generator);
+
+ /**
+ * Registers workflow event map.
+ * @param eventType event type (class name of event)
+ * @param eventHint event hint value
+ * @param contextName workflow context name to be called by this event map
+ * @param workletType worklet type to be called by this event map
+ * @throws WorkflowException workflow exception
+ */
+ void registerEventMap(Class<? extends Event> eventType, String eventHint,
+ String contextName, String workletType) throws WorkflowException;
+
+}
diff --git a/apps/workflow/api/src/main/java/org/onosproject/workflow/api/WorkflowService.java b/apps/workflow/api/src/main/java/org/onosproject/workflow/api/WorkflowService.java
new file mode 100644
index 0000000..b11e835
--- /dev/null
+++ b/apps/workflow/api/src/main/java/org/onosproject/workflow/api/WorkflowService.java
@@ -0,0 +1,66 @@
+/*
+ * Copyright 2018-present Open Networking Foundation
+ *
+ * Licensed 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.onosproject.workflow.api;
+
+
+import com.fasterxml.jackson.databind.JsonNode;
+
+/**
+ * Interface for workflow service.
+ */
+public interface WorkflowService {
+
+ /**
+ * Creates workplace.
+ * @param wpDesc workplace description
+ * @throws WorkflowException workflow exception
+ */
+ void createWorkplace(WorkplaceDescription wpDesc) throws WorkflowException;
+
+ /**
+ * Removes workplace.
+ * @param wpDesc workplace description
+ * @throws WorkflowException workflow exception
+ */
+ void removeWorkplace(WorkplaceDescription wpDesc) throws WorkflowException;
+
+ /**
+ * Clears all workplaces.
+ * @throws WorkflowException workflow exception
+ */
+ void clearWorkplace() throws WorkflowException;
+
+ /**
+ * Invokes workflow.
+ * @param wfDesc workflow description
+ * @throws WorkflowException workflow exception
+ */
+ void invokeWorkflow(WorkflowDescription wfDesc) throws WorkflowException;
+
+ /**
+ * Invokes workflow.
+ * @param worklowDescJson workflow description json
+ * @throws WorkflowException workflow exception
+ */
+ void invokeWorkflow(JsonNode worklowDescJson) throws WorkflowException;
+
+ /**
+ * Terminates workflow.
+ * @param wfDesc workflow description
+ * @throws WorkflowException workflow exception
+ */
+ void terminateWorkflow(WorkflowDescription wfDesc) throws WorkflowException;
+}
\ No newline at end of file
diff --git a/apps/workflow/api/src/main/java/org/onosproject/workflow/api/WorkflowState.java b/apps/workflow/api/src/main/java/org/onosproject/workflow/api/WorkflowState.java
new file mode 100644
index 0000000..0f92624
--- /dev/null
+++ b/apps/workflow/api/src/main/java/org/onosproject/workflow/api/WorkflowState.java
@@ -0,0 +1,38 @@
+/*
+ * Copyright 2018-present Open Networking Foundation
+ *
+ * Licensed 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.onosproject.workflow.api;
+
+/**
+ * State of workflow.
+ */
+public enum WorkflowState {
+
+ /**
+ * Workflow is idle state.
+ */
+ IDLE,
+
+ /**
+ * Workflow is running state.
+ */
+ RUNNING,
+
+ /**
+ * Workflow is exception state.
+ */
+ EXCEPTION
+
+}
diff --git a/apps/workflow/api/src/main/java/org/onosproject/workflow/api/WorkflowStore.java b/apps/workflow/api/src/main/java/org/onosproject/workflow/api/WorkflowStore.java
new file mode 100644
index 0000000..ac0de4d
--- /dev/null
+++ b/apps/workflow/api/src/main/java/org/onosproject/workflow/api/WorkflowStore.java
@@ -0,0 +1,70 @@
+/*
+ * Copyright 2018-present Open Networking Foundation
+ *
+ * Licensed 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.onosproject.workflow.api;
+
+import java.net.URI;
+import java.util.Collection;
+
+/**
+ * Store for managing workflow.
+ */
+public interface WorkflowStore {
+
+ /**
+ * Registers workflow.
+ * @param workflow registering workflow
+ */
+ void register(Workflow workflow);
+
+ /**
+ * Unregisters workflow.
+ * @param id id of workflow
+ */
+ void unregister(URI id);
+
+ /**
+ * Gets workflow.
+ * @param id id of workflow
+ * @return workflow
+ */
+ Workflow get(URI id);
+
+ /**
+ * Gets all workflow.
+ * @return collection of workflow
+ */
+ Collection<Workflow> getAll();
+
+ /**
+ * Registers local class loader.
+ * @param loader class loader
+ */
+ void registerLocal(ClassLoader loader);
+
+ /**
+ * Unregisters local class loader.
+ * @param loader class loader
+ */
+ void unregisterLocal(ClassLoader loader);
+
+ /**
+ * Gets class from registered class loaders.
+ * @param name name of class
+ * @return class
+ * @throws ClassNotFoundException class not found exception
+ */
+ Class getClass(String name) throws ClassNotFoundException;
+}
diff --git a/apps/workflow/api/src/main/java/org/onosproject/workflow/api/Worklet.java b/apps/workflow/api/src/main/java/org/onosproject/workflow/api/Worklet.java
new file mode 100644
index 0000000..386fa38
--- /dev/null
+++ b/apps/workflow/api/src/main/java/org/onosproject/workflow/api/Worklet.java
@@ -0,0 +1,161 @@
+/*
+ * Copyright 2018-present Open Networking Foundation
+ *
+ * Licensed 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.onosproject.workflow.api;
+
+
+import org.onosproject.event.Event;
+
+/**
+ * An interface representing worklet. A workflow is composed of worklets.
+ */
+public interface Worklet {
+
+ int MAX_WORKS = 1000;
+
+ /**
+ * Returns tag name of worklet. class name is usually used.
+ * @return tag name
+ */
+ String tag();
+
+ /**
+ * Processes tasks of the worklet under the workflow context.
+ * @param context workflow context
+ * @throws WorkflowException workflow exception
+ */
+ void process(WorkflowContext context) throws WorkflowException;
+
+ /**
+ * Checks whether is this worklet next worklet to be done under the workflow context.
+ * @param context workflow context
+ * @return true means this worklet is the next worklet to be processed
+ * @throws WorkflowException workflow exception
+ */
+ boolean isNext(WorkflowContext context) throws WorkflowException;
+
+ /**
+ * Checks whether is this worklet completed or not. 'isCompleted' checking is triggered by an event task.
+ * @param context workflow context
+ * @param event an event triggering this 'isCompleted' checking
+ * @return completed or not
+ * @throws WorkflowException workflow exception
+ */
+ boolean isCompleted(WorkflowContext context, Event event) throws WorkflowException;
+
+ /**
+ * Completion event timeout handler.
+ * @param context workflow context
+ * @throws WorkflowException workflow exception
+ */
+ void timeout(WorkflowContext context) throws WorkflowException;
+
+ /**
+ * Common worklet enum.
+ */
+ enum Common implements Worklet {
+
+ /**
+ * Init worklet.
+ */
+ INIT {
+ @Override
+ public String tag() {
+ return INIT.name();
+ }
+
+ @Override
+ public void process(WorkflowContext context) throws WorkflowException {
+ throw new WorkflowException("(" + tag() + ").process should not be called");
+ }
+
+ @Override
+ public boolean isNext(WorkflowContext context) throws WorkflowException {
+ throw new WorkflowException("(" + tag() + ").isNext should not be called");
+ }
+
+ @Override
+ public boolean isCompleted(WorkflowContext context, Event event)throws WorkflowException {
+ throw new WorkflowException("(" + tag() + ").isCompleted should not be called");
+ }
+
+ @Override
+ public void timeout(WorkflowContext context) throws WorkflowException {
+ throw new WorkflowException("(" + tag() + ").timeout should not be called");
+ }
+ },
+
+ /**
+ * Completed worklet.
+ */
+ COMPLETED {
+ @Override
+ public String tag() {
+ return COMPLETED.name();
+ }
+
+ @Override
+ public void process(WorkflowContext context) throws WorkflowException {
+ throw new WorkflowException("(" + tag() + ").process should not be called");
+ }
+
+ @Override
+ public boolean isNext(WorkflowContext context) throws WorkflowException {
+ throw new WorkflowException("(" + tag() + ").isNext should not be called");
+ }
+
+ @Override
+ public boolean isCompleted(WorkflowContext context, Event event)throws WorkflowException {
+ throw new WorkflowException("(" + tag() + ").isCompleted should not be called");
+ }
+
+ @Override
+ public void timeout(WorkflowContext context) throws WorkflowException {
+ throw new WorkflowException("(" + tag() + ").timeout should not be called");
+ }
+ },
+
+ /**
+ * Interrupted worklet.
+ */
+ INTERRUPTED {
+ @Override
+ public String tag() {
+ return INTERRUPTED.name();
+ }
+
+ @Override
+ public void process(WorkflowContext context) throws WorkflowException {
+ throw new WorkflowException("(" + tag() + ").process should not be called");
+ }
+
+ @Override
+ public boolean isNext(WorkflowContext context) throws WorkflowException {
+ throw new WorkflowException("(" + tag() + ").isNext should not be called");
+ }
+
+ @Override
+ public boolean isCompleted(WorkflowContext context, Event event)throws WorkflowException {
+ throw new WorkflowException("(" + tag() + ").isCompleted should not be called");
+ }
+
+ @Override
+ public void timeout(WorkflowContext context) throws WorkflowException {
+ throw new WorkflowException("(" + tag() + ").timeout should not be called");
+ }
+ }
+ }
+}
+
diff --git a/apps/workflow/api/src/main/java/org/onosproject/workflow/api/Workplace.java b/apps/workflow/api/src/main/java/org/onosproject/workflow/api/Workplace.java
new file mode 100644
index 0000000..a7439d6
--- /dev/null
+++ b/apps/workflow/api/src/main/java/org/onosproject/workflow/api/Workplace.java
@@ -0,0 +1,42 @@
+/*
+ * Copyright 2018-present Open Networking Foundation
+ *
+ * Licensed 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.onosproject.workflow.api;
+
+import java.util.Collection;
+
+/**
+ * Abstract class for workplace. A common workflow data container for multiple work-flows.
+ */
+public abstract class Workplace extends WorkflowData {
+
+ public static final String SYSTEM_WORKPLACE = "system-workplace";
+
+ /**
+ * Constructor of workplace.
+ * @param data data model tree
+ */
+ public Workplace(DataModelTree data) {
+ super(data);
+ }
+
+ /**
+ * Gets workflow contexts of workplace.
+ * @return collection of workflow context
+ * @throws WorkflowException workflow exception
+ */
+ abstract Collection<WorkflowContext> getContexts() throws WorkflowException;
+
+}
diff --git a/apps/workflow/api/src/main/java/org/onosproject/workflow/api/WorkplaceDescription.java b/apps/workflow/api/src/main/java/org/onosproject/workflow/api/WorkplaceDescription.java
new file mode 100644
index 0000000..16515eb
--- /dev/null
+++ b/apps/workflow/api/src/main/java/org/onosproject/workflow/api/WorkplaceDescription.java
@@ -0,0 +1,53 @@
+/*
+ * Copyright 2018-present Open Networking Foundation
+ *
+ * Licensed 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.onosproject.workflow.api;
+
+import com.fasterxml.jackson.databind.JsonNode;
+import java.util.Optional;
+
+/**
+ * Interface for workplace description.
+ */
+public interface WorkplaceDescription {
+
+ /**
+ * Workplace name field name.
+ */
+ String WP_NAME = "name";
+
+ /**
+ * Workplace data field name.
+ */
+ String WP_DATA = "data";
+
+ /**
+ * Gets workplace name.
+ * @return workplace name
+ */
+ String name();
+
+ /**
+ * Gets optional workplace data model.
+ * @return workplace optData model
+ */
+ Optional<JsonNode> data();
+
+ /**
+ * Gets json of workflow description.
+ * @return json of workflow description
+ */
+ JsonNode toJson();
+}
diff --git a/apps/workflow/api/src/main/java/org/onosproject/workflow/api/WorkplaceStore.java b/apps/workflow/api/src/main/java/org/onosproject/workflow/api/WorkplaceStore.java
new file mode 100644
index 0000000..b73cd4f
--- /dev/null
+++ b/apps/workflow/api/src/main/java/org/onosproject/workflow/api/WorkplaceStore.java
@@ -0,0 +1,118 @@
+/*
+ * Copyright 2018-present Open Networking Foundation
+ *
+ * Licensed 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.onosproject.workflow.api;
+
+import org.onosproject.store.Store;
+import org.onosproject.store.service.StorageException;
+
+import java.util.Collection;
+
+/**
+ * Interface for workplace store.
+ */
+public interface WorkplaceStore extends Store<WorkflowDataEvent, WorkplaceStoreDelegate> {
+
+ /**
+ * Registers workplace on workplace store.
+ * @param name workplace name to register
+ * @param workplace workplace
+ * @throws StorageException storage exception
+ */
+ void registerWorkplace(String name, Workplace workplace) throws StorageException;
+
+ /**
+ * Removes workplace from workplace store.
+ * @param name workplace name to remove
+ * @throws StorageException storage exception
+ */
+ void removeWorkplace(String name) throws StorageException;
+
+ /**
+ * Gets workplace on workplace store.
+ * @param name workplace name to get
+ * @return workplace
+ * @throws StorageException storage exception
+ */
+ Workplace getWorkplace(String name) throws StorageException;
+
+ /**
+ * Commits workplace on workplace store.
+ * @param name workplace name to commit
+ * @param workplace workplace to commit
+ * @param handleEvent whether or not to handle workplace(workflow data) event
+ * @throws StorageException storage exception
+ */
+ void commitWorkplace(String name, Workplace workplace, boolean handleEvent) throws StorageException;
+
+ /**
+ * Gets all workplaces from workplace store.
+ * @return collection of workplace
+ * @throws StorageException storage exception
+ */
+ Collection<Workplace> getWorkplaces() throws StorageException;
+
+ /**
+ * Registers workflow context on workplace store.
+ * @param name workflow context name to register
+ * @param context workflow context to register
+ * @throws StorageException storage exception
+ */
+ void registerContext(String name, WorkflowContext context) throws StorageException;
+
+ /**
+ * Removes workflow context from workplace store.
+ * @param name workflow context name
+ * @throws StorageException storage exception
+ */
+ void removeContext(String name) throws StorageException;
+
+ /**
+ * Gets workflow context with name.
+ * @param name workflow context name to get
+ * @return workflow context
+ * @throws StorageException storage exception
+ */
+ WorkflowContext getContext(String name) throws StorageException;
+
+ /**
+ * Commits workflow context on workplace store.
+ * @param name workflow context name to commit
+ * @param context workflow context to commit
+ * @param handleEvent whether or not to handle workflow context(workflow data) event
+ * @throws StorageException storage exception
+ */
+ void commitContext(String name, WorkflowContext context, boolean handleEvent) throws StorageException;
+
+ /**
+ * Gets all workflow context from workplace store.
+ * @return collection of workflow context
+ * @throws StorageException storage exception
+ */
+ Collection<WorkflowContext> getContexts() throws StorageException;
+
+ /**
+ * Gets workflow contexts belonging to a workplace.
+ * @param workplaceName workplace name
+ * @return collection of workflow contexts belonging to a workplace
+ */
+ Collection<WorkflowContext> getWorkplaceContexts(String workplaceName);
+
+ /**
+ * Removes all workflow contexts beloinging to a workplace.
+ * @param workplaceName workplace name
+ */
+ void removeWorkplaceContexts(String workplaceName);
+}
diff --git a/apps/workflow/api/src/main/java/org/onosproject/workflow/api/WorkplaceStoreDelegate.java b/apps/workflow/api/src/main/java/org/onosproject/workflow/api/WorkplaceStoreDelegate.java
new file mode 100644
index 0000000..9e7ba14
--- /dev/null
+++ b/apps/workflow/api/src/main/java/org/onosproject/workflow/api/WorkplaceStoreDelegate.java
@@ -0,0 +1,24 @@
+/*
+ * Copyright 2018-present Open Networking Foundation
+ *
+ * Licensed 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.onosproject.workflow.api;
+
+import org.onosproject.store.StoreDelegate;
+
+/**
+ * Workplace store delegate.
+ */
+public interface WorkplaceStoreDelegate extends StoreDelegate<WorkflowDataEvent> {
+}
diff --git a/apps/workflow/api/src/main/java/org/onosproject/workflow/api/package-info.java b/apps/workflow/api/src/main/java/org/onosproject/workflow/api/package-info.java
new file mode 100644
index 0000000..7e68f8f
--- /dev/null
+++ b/apps/workflow/api/src/main/java/org/onosproject/workflow/api/package-info.java
@@ -0,0 +1,20 @@
+/*
+ * Copyright 2018-present Open Networking Foundation
+ *
+ * Licensed 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 for workflow APIs.
+ */
+package org.onosproject.workflow.api;
\ No newline at end of file