diff --git a/apps/workflow/BUILD b/apps/workflow/BUILD
index 118458e..e8b6a91 100644
--- a/apps/workflow/BUILD
+++ b/apps/workflow/BUILD
@@ -1,5 +1,6 @@
 BUNDLES = [
     "//apps/workflow/api:onos-apps-workflow-api",
+    "//apps/workflow/model:onos-apps-workflow-model",
     "//apps/workflow/app:onos-apps-workflow-app",
 ]
 
diff --git a/apps/workflow/app/BUILD b/apps/workflow/app/BUILD
index 87df2e1..d5af5a2 100644
--- a/apps/workflow/app/BUILD
+++ b/apps/workflow/app/BUILD
@@ -1,5 +1,6 @@
 COMPILE_DEPS = CORE_DEPS + KRYO + JACKSON + CLI + [
     "//core/store/serializers:onos-core-serializers",
+    "//core/store/primitives:onos-core-primitives",
     "//apps/workflow/api:onos-apps-workflow-api",
 ]
 
diff --git a/apps/workflow/model/BUILD b/apps/workflow/model/BUILD
new file mode 100644
index 0000000..016e14a
--- /dev/null
+++ b/apps/workflow/model/BUILD
@@ -0,0 +1,8 @@
+COMPILE_DEPS = CORE_DEPS + KRYO + JACKSON + [
+    "//core/store/serializers:onos-core-serializers",
+    "//apps/workflow/api:onos-apps-workflow-api",
+]
+
+osgi_jar_with_tests(
+    deps = COMPILE_DEPS,
+)
diff --git a/apps/workflow/model/src/main/java/org/onosproject/workflow/model/accessinfo/NetconfAccessInfo.java b/apps/workflow/model/src/main/java/org/onosproject/workflow/model/accessinfo/NetconfAccessInfo.java
new file mode 100644
index 0000000..8e428e3
--- /dev/null
+++ b/apps/workflow/model/src/main/java/org/onosproject/workflow/model/accessinfo/NetconfAccessInfo.java
@@ -0,0 +1,165 @@
+/*
+ * Copyright 2019-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.model.accessinfo;
+
+import com.fasterxml.jackson.databind.JsonNode;
+import com.fasterxml.jackson.databind.node.NumericNode;
+import com.fasterxml.jackson.databind.node.TextNode;
+import com.google.common.base.MoreObjects;
+import org.onlab.packet.IpAddress;
+import org.onlab.packet.TpPort;
+import org.onosproject.workflow.api.WorkflowException;
+
+import java.util.Objects;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+
+/**
+ * Class for NETCONF access information.
+ */
+public final class NetconfAccessInfo {
+
+    private static final String REMOTE_IP = "remoteIp";
+    private static final String PORT = "port";
+    private static final String USER = "user";
+    private static final String PASSWORD = "password";
+
+    private final IpAddress remoteIp;
+    private final TpPort port;
+    private final String user;
+    private final String password;
+
+    /**
+     * Constructor for a given NETCONF access information.
+     *
+     * @param remoteIp remote ip address
+     * @param port port number
+     * @param user user name
+     * @param password password
+     */
+    public NetconfAccessInfo(IpAddress remoteIp,
+                             TpPort port,
+                             String user,
+                             String password) {
+        this.remoteIp = checkNotNull(remoteIp);
+        this.port = checkNotNull(port);
+        this.user = checkNotNull(user);
+        this.password = checkNotNull(password);
+    }
+
+    /**
+     * Builds NetconfAccessInfo from json.
+     * @param root json root node for NetconfAccessinfo
+     * @return NETCONF access information
+     * @throws WorkflowException workflow exception
+     */
+    public static NetconfAccessInfo valueOf(JsonNode root) throws WorkflowException {
+
+        JsonNode node = root.at(ptr(REMOTE_IP));
+        if (node == null || !(node instanceof TextNode)) {
+            throw new WorkflowException("invalid remoteIp for " + root);
+        }
+        IpAddress remoteIp = IpAddress.valueOf(node.asText());
+
+        node = root.at(ptr(PORT));
+        if (node == null || !(node instanceof NumericNode)) {
+            throw new WorkflowException("invalid port for " + root);
+        }
+        TpPort tpPort = TpPort.tpPort(node.asInt());
+
+        node = root.at(ptr(USER));
+        if (node == null || !(node instanceof TextNode)) {
+            throw new WorkflowException("invalid user for " + root);
+        }
+        String strUser = node.asText();
+
+        node = root.at(ptr(PASSWORD));
+        if (node == null || !(node instanceof TextNode)) {
+            throw new WorkflowException("invalid password for " + root);
+        }
+        String strPassword = node.asText();
+
+        return new NetconfAccessInfo(remoteIp, tpPort, strUser, strPassword);
+    }
+
+    private static String ptr(String field) {
+        return "/" + field;
+    }
+
+    /**
+     * Returns the remote IP address.
+     *
+     * @return ip address
+     */
+    public IpAddress remoteIp() {
+        return this.remoteIp;
+    }
+
+    /**
+     * Returns the port number.
+     *
+     * @return port
+     */
+    public TpPort port() {
+        return this.port;
+    }
+
+    /**
+     * Returns the user name.
+     *
+     * @return user name
+     */
+    public String user() {
+        return this.user;
+    }
+
+    /**
+     * Returns the password.
+     * @return password
+     */
+    public String password() {
+        return this.password;
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (this == obj) {
+            return true;
+        }
+
+        if (obj instanceof NetconfAccessInfo) {
+            NetconfAccessInfo that = (NetconfAccessInfo) obj;
+            return Objects.equals(remoteIp, that.remoteIp) &&
+                    Objects.equals(port, that.port) &&
+                    Objects.equals(user, that.user);
+        }
+        return false;
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(remoteIp, port, user);
+    }
+
+    @Override
+    public String toString() {
+        return MoreObjects.toStringHelper(getClass())
+                .add("remoteIp", remoteIp)
+                .add("port", port)
+                .add("user", user)
+                .toString();
+    }
+}
\ No newline at end of file
diff --git a/apps/workflow/model/src/main/java/org/onosproject/workflow/model/accessinfo/RestAccessInfo.java b/apps/workflow/model/src/main/java/org/onosproject/workflow/model/accessinfo/RestAccessInfo.java
new file mode 100644
index 0000000..c13270d
--- /dev/null
+++ b/apps/workflow/model/src/main/java/org/onosproject/workflow/model/accessinfo/RestAccessInfo.java
@@ -0,0 +1,167 @@
+/*
+ * Copyright 2019-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.model.accessinfo;
+
+import com.fasterxml.jackson.databind.JsonNode;
+import com.fasterxml.jackson.databind.node.NumericNode;
+import com.fasterxml.jackson.databind.node.TextNode;
+import com.google.common.base.MoreObjects;
+import org.onlab.packet.IpAddress;
+import org.onlab.packet.TpPort;
+import org.onosproject.workflow.api.WorkflowException;
+
+import java.util.Objects;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+
+/**
+ * Class for REST access information.
+ */
+public final class RestAccessInfo {
+
+    private static final String REMOTE_IP = "remoteIp";
+    private static final String PORT = "port";
+    private static final String USER = "user";
+    private static final String PASSWORD = "password";
+
+    private final IpAddress remoteIp;
+    private final TpPort port;
+    private final String user;
+    private String password;
+
+    /**
+     * Creates a new REST access information.
+     *
+     * @param remoteIp remote ip address
+     * @param port port number
+     * @param user user name
+     * @param password password
+     */
+    private RestAccessInfo(IpAddress remoteIp,
+                          TpPort port,
+                          String user,
+                          String password) {
+        this.remoteIp = checkNotNull(remoteIp);
+        this.port = checkNotNull(port);
+        this.user = checkNotNull(user);
+        this.password = checkNotNull(password);
+    }
+
+    /**
+     * Builds RestAccessInfo from json.
+     * @param root json root node for RestAccessinfo
+     * @return REST access information
+     * @throws WorkflowException workflow exception
+     */
+    public static RestAccessInfo valueOf(JsonNode root) throws WorkflowException {
+
+        JsonNode node = root.at(ptr(REMOTE_IP));
+        if (node == null || !(node instanceof TextNode)) {
+            throw new WorkflowException("invalid remoteIp for " + root);
+        }
+        IpAddress remoteIp = IpAddress.valueOf(node.asText());
+
+        node = root.at(ptr(PORT));
+        if (node == null || !(node instanceof NumericNode)) {
+            throw new WorkflowException("invalid port for " + root);
+        }
+        TpPort tpPort = TpPort.tpPort(node.asInt());
+
+        node = root.at(ptr(USER));
+        if (node == null || !(node instanceof TextNode)) {
+            throw new WorkflowException("invalid user for " + root);
+        }
+        String strUser = node.asText();
+
+        node = root.at(ptr(PASSWORD));
+        if (node == null || !(node instanceof TextNode)) {
+            throw new WorkflowException("invalid password for " + root);
+        }
+        String strPassword = node.asText();
+
+        return new RestAccessInfo(remoteIp, tpPort, strUser, strPassword);
+    }
+
+    private static String ptr(String field) {
+        return "/" + field;
+    }
+
+    /**
+     * Returns the remote IP address.
+     *
+     * @return ip address
+     */
+    public IpAddress remoteIp() {
+        return this.remoteIp;
+    }
+
+    /**
+     * Returns the port number.
+     *
+     * @return REST port
+     */
+    public TpPort port() {
+        return this.port;
+    }
+
+    /**
+     * Returns the user name.
+     *
+     * @return user name
+     */
+    public String user() {
+        return this.user;
+    }
+
+    /**
+     * Returns the password.
+     *
+     * @return password
+     */
+    public String password() {
+        return this.password;
+    }
+
+
+    @Override
+    public boolean equals(Object obj) {
+        if (this == obj) {
+            return true;
+        }
+
+        if (obj instanceof RestAccessInfo) {
+            RestAccessInfo that = (RestAccessInfo) obj;
+            return Objects.equals(remoteIp, that.remoteIp) &&
+                    Objects.equals(port, that.port) &&
+                    Objects.equals(user, that.user);
+        }
+        return false;
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(remoteIp, port, user);
+    }
+
+    @Override
+    public String toString() {
+        return MoreObjects.toStringHelper(getClass())
+                .add("remoteIp", remoteIp)
+                .add("port", port)
+                .add("user", user)
+                .toString();
+    }
+}
\ No newline at end of file
diff --git a/apps/workflow/model/src/main/java/org/onosproject/workflow/model/accessinfo/SshAccessInfo.java b/apps/workflow/model/src/main/java/org/onosproject/workflow/model/accessinfo/SshAccessInfo.java
new file mode 100644
index 0000000..aec224a
--- /dev/null
+++ b/apps/workflow/model/src/main/java/org/onosproject/workflow/model/accessinfo/SshAccessInfo.java
@@ -0,0 +1,183 @@
+/*
+ * Copyright 2019-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.model.accessinfo;
+
+import com.fasterxml.jackson.databind.JsonNode;
+import com.fasterxml.jackson.databind.node.NumericNode;
+import com.fasterxml.jackson.databind.node.TextNode;
+import com.google.common.base.MoreObjects;
+import org.onlab.packet.IpAddress;
+import org.onlab.packet.TpPort;
+import org.onosproject.workflow.api.WorkflowException;
+
+import java.util.Objects;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+
+/**
+ * Class for SSH access information.
+ */
+public final class SshAccessInfo {
+
+    private static final String REMOTE_IP = "remoteIp";
+    private static final String PORT = "port";
+    private static final String USER = "user";
+    private static final String PASSWORD = "password";
+    private static final String KEYFILE = "keyfile";
+
+    private final IpAddress remoteIp;
+    private final TpPort port;
+    private final String user;
+    private String password;
+    private final String privateKey;
+
+    /**
+     * Constructor for SSH access information.
+     *
+     * @param remoteIp ssh remote ip address
+     * @param port ssh port number
+     * @param user user name
+     * @param password password
+     * @param privateKey path of ssh private key
+     */
+    private SshAccessInfo(IpAddress remoteIp, TpPort port, String user, String password, String privateKey) {
+        this.remoteIp = checkNotNull(remoteIp);
+        this.port = checkNotNull(port);
+        this.user = checkNotNull(user);
+        this.password = password;
+        this.privateKey = checkNotNull(privateKey);
+    }
+
+    /**
+     * Builds SshAccessInfo from json.
+     * @param root json root node for SshAccessinfo
+     * @return SSH access information
+     * @throws WorkflowException workflow exception
+     */
+    public static SshAccessInfo valueOf(JsonNode root) throws WorkflowException {
+
+        JsonNode node = root.at(ptr(REMOTE_IP));
+        if (node == null || !(node instanceof TextNode)) {
+            throw new WorkflowException("invalid remoteIp for " + root);
+        }
+        IpAddress sshIp = IpAddress.valueOf(node.asText());
+
+        node = root.at(ptr(PORT));
+        if (node == null || !(node instanceof NumericNode)) {
+            throw new WorkflowException("invalid port for " + root);
+        }
+        TpPort sshPort = TpPort.tpPort(node.asInt());
+
+        node = root.at(ptr(USER));
+        if (node == null || !(node instanceof TextNode)) {
+            throw new WorkflowException("invalid user for " + root);
+        }
+        String sshUser = node.asText();
+
+        node = root.at(ptr(PASSWORD));
+        if (node == null || !(node instanceof TextNode)) {
+            throw new WorkflowException("invalid password for " + root);
+        }
+        String sshPassword = node.asText();
+
+        node = root.at(ptr(KEYFILE));
+        if (node == null || !(node instanceof TextNode)) {
+            throw new WorkflowException("invalid keyfile for " + root);
+        }
+        String sshKeyfile = node.asText();
+
+        return new SshAccessInfo(sshIp, sshPort, sshUser, sshPassword, sshKeyfile);
+    }
+
+    private static String ptr(String field) {
+        return "/" + field;
+    }
+
+    /**
+     * Returns the remote IP address.
+     *
+     * @return ip address
+     */
+    public IpAddress remoteIp() {
+        return this.remoteIp;
+    }
+
+    /**
+     * Returns the port number.
+     *
+     * @return ssh port
+     */
+    public TpPort port() {
+        return this.port;
+    }
+
+    /**
+     * Returns the user name.
+     *
+     * @return user name
+     */
+    public String user() {
+        return this.user;
+    }
+
+    /**
+     * Returns the password.
+     * @return password
+     */
+    public String password() {
+        return this.password;
+    }
+
+    /**
+     * Returns the private key path.
+     *
+     * @return privateKey
+     */
+    public String privateKey() {
+        return privateKey;
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (this == obj) {
+            return true;
+        }
+
+        if (obj instanceof SshAccessInfo) {
+            SshAccessInfo that = (SshAccessInfo) obj;
+            return Objects.equals(remoteIp, that.remoteIp) &&
+                    Objects.equals(port, that.port) &&
+                    Objects.equals(user, that.user) &&
+                    Objects.equals(privateKey, that.privateKey);
+        }
+        return false;
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(remoteIp, port, user, privateKey);
+    }
+
+    @Override
+    public String toString() {
+        return MoreObjects.toStringHelper(getClass())
+                .add("remoteIp", remoteIp)
+                .add("port", port)
+                .add("user", user)
+                .add("privateKey", privateKey)
+                .toString();
+    }
+}
diff --git a/apps/workflow/model/src/main/java/org/onosproject/workflow/model/accessinfo/package-info.java b/apps/workflow/model/src/main/java/org/onosproject/workflow/model/accessinfo/package-info.java
new file mode 100644
index 0000000..bc88e3b
--- /dev/null
+++ b/apps/workflow/model/src/main/java/org/onosproject/workflow/model/accessinfo/package-info.java
@@ -0,0 +1,20 @@
+/*
+ * Copyright 2019-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 common data model - access info.
+ */
+package org.onosproject.workflow.model.accessinfo;
diff --git a/apps/workflow/ofoverlay/BUILD b/apps/workflow/ofoverlay/BUILD
new file mode 100644
index 0000000..cc75d82
--- /dev/null
+++ b/apps/workflow/ofoverlay/BUILD
@@ -0,0 +1,21 @@
+BUNDLES = [
+    "@jsch//jar",
+    "//protocols/ovsdb/api:onos-protocols-ovsdb-api",
+    "//protocols/ovsdb/rfc:onos-protocols-ovsdb-rfc",
+    "//apps/workflow/ofoverlay/app:onos-apps-workflow-ofoverlay-app",
+]
+
+onos_app(
+    app_name = "org.onosproject.workflow.ofoverlay",
+    category = "Utility",
+    description = "Openflow overaly application",
+    included_bundles = BUNDLES,
+    required_apps = [
+        "org.onosproject.openflow",
+        "org.onosproject.ovsdb",
+        "org.onosproject.drivers.ovsdb",
+        "org.onosproject.workflow",
+    ],
+    title = "Openflow overlay",
+    url = "http://onosproject.org",
+)
diff --git a/apps/workflow/ofoverlay/app/BUILD b/apps/workflow/ofoverlay/app/BUILD
new file mode 100644
index 0000000..d8a5fa0
--- /dev/null
+++ b/apps/workflow/ofoverlay/app/BUILD
@@ -0,0 +1,13 @@
+COMPILE_DEPS = CORE_DEPS + KRYO + JACKSON + CLI + [
+    "//core/store/serializers:onos-core-serializers",
+    "//core/store/primitives:onos-core-primitives",
+    "//apps/workflow/api:onos-apps-workflow-api",
+    "//apps/workflow/model:onos-apps-workflow-model",
+    "@jsch//jar",
+    "//protocols/ovsdb/api:onos-protocols-ovsdb-api",
+    "//protocols/ovsdb/rfc:onos-protocols-ovsdb-rfc",
+]
+
+osgi_jar_with_tests(
+    deps = COMPILE_DEPS,
+)
diff --git a/apps/workflow/ofoverlay/app/src/main/java/org/onosproject/ofoverlay/impl/OfOverlayWorkflow.java b/apps/workflow/ofoverlay/app/src/main/java/org/onosproject/ofoverlay/impl/OfOverlayWorkflow.java
new file mode 100644
index 0000000..5fb8cd2
--- /dev/null
+++ b/apps/workflow/ofoverlay/app/src/main/java/org/onosproject/ofoverlay/impl/OfOverlayWorkflow.java
@@ -0,0 +1,156 @@
+/*
+ * Copyright 2019-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.ofoverlay.impl;
+
+import org.onosproject.net.device.DeviceService;
+import org.onosproject.workflow.api.ImmutableListWorkflow;
+import org.onosproject.workflow.api.Workflow;
+import org.onosproject.workflow.api.WorkflowExecutionService;
+import org.onosproject.workflow.api.WorkflowStore;
+import org.onosproject.workflow.api.WorkplaceStore;
+import org.osgi.service.component.annotations.Activate;
+import org.osgi.service.component.annotations.Component;
+import org.osgi.service.component.annotations.Deactivate;
+import org.osgi.service.component.annotations.Reference;
+import org.osgi.service.component.annotations.ReferenceCardinality;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.net.URI;
+import java.util.concurrent.ScheduledExecutorService;
+
+import static java.util.concurrent.Executors.newSingleThreadScheduledExecutor;
+import static org.onlab.util.Tools.groupedThreads;
+
+/**
+ * Class for Open-flow overlay configuration workflow.
+ */
+@Component(immediate = true)
+public class OfOverlayWorkflow {
+
+    private static final Logger log = LoggerFactory.getLogger(OfOverlayWorkflow.class);
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY)
+    protected WorkflowStore workflowStore;
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY)
+    protected WorkplaceStore workplaceStore;
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY)
+    protected WorkflowExecutionService workflowExecutionService;
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY)
+    protected DeviceService deviceService;
+
+    private ScheduledExecutorService eventMapTriggerExecutor;
+
+    @Activate
+    public void activate() {
+        log.info("Activated");
+
+        eventMapTriggerExecutor = newSingleThreadScheduledExecutor(
+                groupedThreads("onos/of-overlay", "eventmap-trigger-executor"));
+
+        registerWorkflows();
+
+    }
+
+    @Deactivate
+    public void deactivate() {
+        log.info("Deactivated");
+    }
+
+    /**
+     * Registers workflows.
+     */
+    private void registerWorkflows() {
+        // registering class-loader
+        workflowStore.registerLocal(this.getClass().getClassLoader());
+
+        // registering new workflow definition
+        URI uri = URI.create("of-overlay.workflow-nova");
+        Workflow workflow = ImmutableListWorkflow.builder()
+                .id(uri)
+                //.attribute(WorkflowAttribute.REMOVE_AFTER_COMPLETE)
+                .chain(Ovs.CreateOvsdbDevice.class.getName())
+                .chain(Ovs.UpdateOvsVersion.class.getName())
+                .chain(Ovs.UpdateOverlayBridgeId.class.getName())
+                .chain(Ovs.CreateOverlayBridge.class.getName())
+                .chain(Ovs.UpdateUnderlayBridgeId.class.getName())
+                .chain(Ovs.CreateUnderlayBridge.class.getName())
+                .chain(Ovs.CreateOverlayBridgeVxlanPort.class.getName())
+                .chain(Ovs.AddPhysicalPortsOnUnderlayBridge.class.getName())
+                .chain(Ovs.ConfigureUnderlayBridgeLocalIp.class.getName())
+                .build();
+        workflowStore.register(workflow);
+
+        uri = URI.create("of-overlay.clean-workflow-nova");
+        workflow = ImmutableListWorkflow.builder()
+                .id(uri)
+                //.attribute(WorkflowAttribute.REMOVE_AFTER_COMPLETE)
+                .chain(Ovs.DeleteOverlayBridgeConfig.class.getName())
+                .chain(Ovs.RemoveOverlayBridgeOfDevice.class.getName())
+                .chain(Ovs.DeleteUnderlayBridgeConfig.class.getName())
+                .chain(Ovs.RemoveUnderlayBridgeOfDevice.class.getName())
+                .chain(Ovs.RemoveOvsdbDevice.class.getName())
+                .build();
+        workflowStore.register(workflow);
+
+        uri = URI.create("of-overlay.workflow-ovs-leaf");
+        workflow = ImmutableListWorkflow.builder()
+                .id(uri)
+                .chain(Ovs.CreateOvsdbDevice.class.getName())
+                .chain(Ovs.UpdateOvsVersion.class.getName())
+                .chain(Ovs.UpdateUnderlayBridgeId.class.getName())
+                .chain(Ovs.CreateUnderlayBridge.class.getName())
+                .chain(Ovs.AddPhysicalPortsOnUnderlayBridge.class.getName())
+                .build();
+        workflowStore.register(workflow);
+
+        uri = URI.create("of-overlay.workflow-ovs-spine");
+        workflow = ImmutableListWorkflow.builder()
+                .id(uri)
+                .chain(Ovs.CreateOvsdbDevice.class.getName())
+                .chain(Ovs.UpdateOvsVersion.class.getName())
+                .chain(Ovs.UpdateUnderlayBridgeId.class.getName())
+                .chain(Ovs.CreateUnderlayBridge.class.getName())
+                .chain(Ovs.AddPhysicalPortsOnUnderlayBridge.class.getName())
+                .build();
+        workflowStore.register(workflow);
+
+        deviceService.addListener(
+                event -> {
+                    // trigger EventTask for DeviceEvent
+                    eventMapTriggerExecutor.submit(
+                            () -> workflowExecutionService.eventMapTrigger(
+                                    event,
+                                    // event hint supplier
+                                    (ev) -> {
+                                        if (ev == null || ev.subject() == null) {
+                                            return null;
+                                        }
+                                        String hint = event.subject().id().toString();
+                                        log.debug("hint: {}", hint);
+                                        return hint;
+                                    }
+                            )
+                    );
+                }
+        );
+
+    }
+
+}
diff --git a/apps/workflow/ofoverlay/app/src/main/java/org/onosproject/ofoverlay/impl/Ovs.java b/apps/workflow/ofoverlay/app/src/main/java/org/onosproject/ofoverlay/impl/Ovs.java
new file mode 100644
index 0000000..428688b
--- /dev/null
+++ b/apps/workflow/ofoverlay/app/src/main/java/org/onosproject/ofoverlay/impl/Ovs.java
@@ -0,0 +1,1220 @@
+/*
+ * Copyright 2019-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.ofoverlay.impl;
+
+import com.fasterxml.jackson.databind.JsonNode;
+import com.fasterxml.jackson.databind.node.ArrayNode;
+import com.fasterxml.jackson.databind.node.TextNode;
+import com.google.common.collect.Lists;
+import com.google.common.collect.Sets;
+import org.onlab.packet.Ip4Address;
+import org.onlab.packet.Ip6Address;
+import org.onlab.packet.IpAddress;
+import org.onlab.packet.TpPort;
+import org.onosproject.cluster.ClusterService;
+import org.onosproject.event.Event;
+import org.onosproject.net.Device;
+import org.onosproject.net.DeviceId;
+import org.onosproject.net.Port;
+import org.onosproject.net.behaviour.BridgeConfig;
+import org.onosproject.net.behaviour.BridgeDescription;
+import org.onosproject.net.behaviour.BridgeName;
+import org.onosproject.net.behaviour.ControlProtocolVersion;
+import org.onosproject.net.behaviour.ControllerInfo;
+import org.onosproject.net.behaviour.DefaultBridgeDescription;
+import org.onosproject.net.behaviour.DefaultTunnelDescription;
+import org.onosproject.net.behaviour.InterfaceConfig;
+import org.onosproject.net.behaviour.TunnelDescription;
+import org.onosproject.net.behaviour.TunnelEndPoints;
+import org.onosproject.net.behaviour.TunnelKeys;
+import org.onosproject.net.device.DeviceAdminService;
+import org.onosproject.net.device.DeviceEvent;
+import org.onosproject.net.device.DeviceService;
+import org.onosproject.net.driver.Behaviour;
+import org.onosproject.net.driver.DriverHandler;
+import org.onosproject.net.driver.DriverService;
+import org.onosproject.ofoverlay.impl.util.NetworkAddress;
+import org.onosproject.ofoverlay.impl.util.OvsDatapathType;
+import org.onosproject.ofoverlay.impl.util.OvsVersion;
+import org.onosproject.ofoverlay.impl.util.SshUtil;
+import org.onosproject.ovsdb.controller.OvsdbClientService;
+import org.onosproject.ovsdb.controller.OvsdbController;
+import org.onosproject.ovsdb.controller.OvsdbNodeId;
+import org.onosproject.workflow.api.AbstractWorklet;
+import org.onosproject.workflow.api.JsonDataModel;
+import org.onosproject.workflow.api.WorkflowContext;
+import org.onosproject.workflow.api.WorkflowException;
+import org.onosproject.workflow.model.accessinfo.SshAccessInfo;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.List;
+import java.util.Objects;
+import java.util.Optional;
+import java.util.stream.Collectors;
+
+import static org.onosproject.net.AnnotationKeys.PORT_NAME;
+import static org.onosproject.workflow.api.CheckCondition.check;
+
+/**
+ * Class for defining OVS workflows.
+ */
+public final class Ovs {
+
+    private static final Logger log = LoggerFactory.getLogger(Ovs.class);
+
+    private static final String MODEL_MGMT_IP = "/mgmtIp";
+    private static final String MODEL_OVSDB_PORT = "/ovsdbPort";
+    private static final String MODEL_OVS_VERSION = "/ovsVersion";
+    private static final String MODEL_OVS_DATAPATH_TYPE = "/ovsDatapathType";
+    private static final String MODEL_SSH_ACCESSINFO = "/sshAccessInfo";
+    private static final String MODEL_OF_DEVID_OVERLAY_BRIDGE = "/ofDevIdBrInt";
+    private static final String MODEL_OF_DEVID_UNDERLAY_BRIDGE = "/ofDevIdBrPhy";
+    private static final String MODEL_PHY_PORTS = "/physicalPorts";
+    private static final String MODEL_VTEP_IP = "/vtepIp";
+
+    private static final String BRIDGE_OVERLAY = "br-int";
+    private static final String BRIDGE_UNDERLAY = "br-phy";
+
+    private static final int DEVID_IDX_BRIDGE_OVERLAY = 0;
+    private static final int DEVID_IDX_BRIDGE_UNDERLAY_NOVA = 1;
+
+    private static final ControlProtocolVersion BRIDGE_DEFAULT_OF_VERSION = ControlProtocolVersion.OF_1_3;
+    private static final int    OPENFLOW_PORT = 6653;
+    private static final String OPENFLOW_CHANNEL_PROTO = "tcp";
+    private static final String OVSDB_DEVICE_PREFIX = "ovsdb:";
+
+    private static final long TIMEOUT_DEVICE_CREATION_MS = 60000L;
+    private static final long TIMEOUT_PORT_ADDITION_MS = 120000L;
+
+
+    /**
+     * Utility class for OVS workflow.
+     */
+    public static final class OvsUtil {
+
+        private OvsUtil() {
+
+        }
+
+        private static final String OPENFLOW_DEVID_FORMAT = "of:%08x%08x";
+
+        /**
+         * Builds Open-flow device id with ip address, and index.
+         * @param addr ip address
+         * @param index index
+         * @return created device id
+         */
+        public static DeviceId buildOfDeviceId(IpAddress addr, int index) {
+            if (addr.isIp4()) {
+                Ip4Address v4Addr = addr.getIp4Address();
+                return DeviceId.deviceId(String.format(OPENFLOW_DEVID_FORMAT, v4Addr.toInt(), index));
+            } else if (addr.isIp6()) {
+                Ip6Address v6Addr = addr.getIp6Address();
+                return DeviceId.deviceId(String.format(OPENFLOW_DEVID_FORMAT, v6Addr.hashCode(), index));
+            } else {
+                return DeviceId.deviceId(String.format(OPENFLOW_DEVID_FORMAT, addr.hashCode(), index));
+            }
+        }
+
+        /**
+         * Builds OVS data path type.
+         * @param strOvsDatapathType string ovs data path type
+         * @return ovs data path type
+         * @throws WorkflowException workflow exception
+         */
+        public static final OvsDatapathType buildOvsDatapathType(String strOvsDatapathType) throws WorkflowException {
+            try {
+                return OvsDatapathType.valueOf(strOvsDatapathType.toUpperCase());
+            } catch (IllegalArgumentException e) {
+                throw new WorkflowException(e);
+            }
+        }
+
+        /**
+         * Gets OVSDB behavior.
+         * @param context workflow context
+         * @param mgmtIp management ip
+         * @param behaviourClass behavior class
+         * @param <T> behavior class
+         * @return OVSDB behavior
+         * @throws WorkflowException workflow exception
+         */
+        public static final <T extends Behaviour> T getOvsdbBehaviour(WorkflowContext context, String mgmtIp,
+                                                                    Class<T> behaviourClass) throws WorkflowException {
+
+            DriverService driverService = context.getService(DriverService.class);
+
+            DeviceId devId = ovsdbDeviceId(mgmtIp);
+            DriverHandler handler = driverService.createHandler(devId);
+            if (Objects.isNull(handler)) {
+                throw new WorkflowException("Failed to get DriverHandler for " + devId);
+            }
+            T behaviour;
+            try {
+                behaviour =  handler.behaviour(behaviourClass);
+                if (Objects.isNull(behaviour)) {
+                    throw new WorkflowException("Failed to get " + behaviourClass + " for " + devId + "-" + handler);
+                }
+            } catch (IllegalArgumentException e) {
+                throw new WorkflowException("Failed to get " + behaviourClass + " for " + devId + "-" + handler);
+            }
+            return behaviour;
+        }
+
+        /**
+         * Gets bridge description.
+         * @param bridgeConfig bridge config
+         * @param bridgeName bridge name
+         * @return bridge description optional
+         */
+        public static final Optional<BridgeDescription> getBridgeDescription(BridgeConfig bridgeConfig,
+                                                                             String bridgeName) {
+            try {
+                Collection<BridgeDescription> bridges = bridgeConfig.getBridges();
+                for (BridgeDescription br: bridges) {
+                    if (Objects.equals(bridgeName, br.name())) {
+                        return Optional.of(br);
+                    }
+                }
+            } catch (Exception e) {
+                log.error("Exception : ", e);
+            }
+            return Optional.empty();
+        }
+
+        /**
+         * Builds OVSDB device id.
+         * @param mgmtIp management ip address string
+         * @return OVSDB device id
+         */
+        public static final DeviceId ovsdbDeviceId(String mgmtIp) {
+            return DeviceId.deviceId(OVSDB_DEVICE_PREFIX.concat(mgmtIp));
+        }
+
+        /**
+         * Returns {@code true} if this bridge is available;
+         * returns {@code false} otherwise.
+         * @param context workflow context
+         * @param devId device id
+         * @return {@code true} if this bridge is available; {@code false} otherwise.
+         * @throws WorkflowException workflow exception
+         */
+        public static final boolean isAvailableBridge(WorkflowContext context, DeviceId devId)
+                throws WorkflowException {
+
+            if (Objects.isNull(devId)) {
+                throw new WorkflowException("Invalid device id in data model");
+            }
+
+            DeviceService deviceService = context.getService(DeviceService.class);
+            Device dev = deviceService.getDevice(devId);
+            if (Objects.isNull(dev)) {
+                return false;
+            }
+
+            return deviceService.isAvailable(devId);
+        }
+
+        /**
+         * Gets openflow controller information list.
+         * @param context workflow context
+         * @return openflow controller information list
+         * @throws WorkflowException workflow exception
+         */
+        public static final List<ControllerInfo> getOpenflowControllerInfoList(WorkflowContext context)
+                throws WorkflowException {
+            ClusterService clusterService = context.getService(ClusterService.class);
+            java.util.List<org.onosproject.net.behaviour.ControllerInfo> controllers = new ArrayList<>();
+            Sets.newHashSet(clusterService.getNodes()).forEach(
+                    controller -> {
+                        org.onosproject.net.behaviour.ControllerInfo ctrlInfo =
+                                new org.onosproject.net.behaviour.ControllerInfo(controller.ip(),
+                                        OPENFLOW_PORT,
+                                        OPENFLOW_CHANNEL_PROTO);
+                        controllers.add(ctrlInfo);
+                    }
+            );
+            return controllers;
+        }
+
+        /**
+         * Creates bridge.
+         * @param bridgeConfig bridge config
+         * @param name bridge name to create
+         * @param dpid openflow data path id of bridge to create
+         * @param ofControllers openflow controller information list
+         * @param datapathType OVS data path type
+         */
+        public static final void createBridge(BridgeConfig bridgeConfig, String name, String dpid,
+                                              List<ControllerInfo> ofControllers, OvsDatapathType datapathType) {
+            BridgeDescription.Builder bridgeDescBuilder = DefaultBridgeDescription.builder()
+                    .name(name)
+                    .failMode(BridgeDescription.FailMode.SECURE)
+                    .datapathId(dpid)
+                    .disableInBand()
+                    .controlProtocols(Collections.singletonList(BRIDGE_DEFAULT_OF_VERSION))
+                    .controllers(ofControllers);
+
+            if (datapathType != null && !(datapathType.equals(OvsDatapathType.EMPTY))) {
+                bridgeDescBuilder.datapathType(datapathType.toString());
+                log.info("create {} with dataPathType {}", name, datapathType);
+            }
+
+            BridgeDescription bridgeDesc = bridgeDescBuilder.build();
+            bridgeConfig.addBridge(bridgeDesc);
+        }
+
+        /**
+         * Index of data path id in openflow device id.
+         */
+        private static final int DPID_BEGIN_INDEX = 3;
+
+        /**
+         * Gets bridge data path id.
+         * @param devId device id
+         * @return bridge data path id
+         */
+        public static final String bridgeDatapathId(DeviceId devId) {
+            return devId.toString().substring(DPID_BEGIN_INDEX);
+        }
+
+        /**
+         * Gets OVSDB client.
+         * @param context workflow context
+         * @param strMgmtIp management ip address
+         * @param intOvsdbPort OVSDB port
+         * @return ovsdb client
+         * @throws WorkflowException workflow exception
+         */
+        public static final OvsdbClientService getOvsdbClient(
+                WorkflowContext context, String strMgmtIp, int intOvsdbPort) throws WorkflowException {
+            IpAddress mgmtIp = IpAddress.valueOf(strMgmtIp);
+            TpPort ovsdbPort = TpPort.tpPort(intOvsdbPort);
+            OvsdbController ovsdbController = context.getService(OvsdbController.class);
+            return ovsdbController.getOvsdbClient(new OvsdbNodeId(mgmtIp, ovsdbPort.toInt()));
+        }
+
+        /**
+         * Checks whether 2 controller informations include same controller information.
+         * @param a controller information list
+         * @param b controller information list
+         * @return {@code true} if 2 controller informations include same controller information
+         */
+        public static boolean isEqual(List<ControllerInfo> a, List<ControllerInfo> b) {
+            if (a == b) {
+                return true;
+            } else if (a == null) {
+                // equivalent to (a == null && b != null)
+                return false;
+            } else if (b == null) {
+                // equivalent to (a != null && b == null)
+                return false;
+            } else if (a.size() != b.size()) {
+                return false;
+            }
+
+            return a.containsAll(b);
+        }
+
+        /**
+         * Gets the name of the port.
+         * @param port port
+         * @return the name of the port
+         */
+        public static final String portName(Port port) {
+            return port.annotations().value(PORT_NAME);
+        }
+    }
+
+    /**
+     * Work-let class for creating OVSDB device.
+     */
+    public static class CreateOvsdbDevice extends AbstractWorklet {
+
+        @JsonDataModel(path = MODEL_MGMT_IP)
+        String strMgmtIp;
+
+        @JsonDataModel(path = MODEL_OVSDB_PORT)
+        Integer intOvsdbPort;
+
+        @Override
+        public boolean isNext(WorkflowContext context) throws WorkflowException {
+
+            OvsdbClientService ovsdbClient = OvsUtil.getOvsdbClient(context, strMgmtIp, intOvsdbPort);
+            return ovsdbClient == null || !ovsdbClient.isConnected();
+        }
+
+        @Override
+        public void process(WorkflowContext context) throws WorkflowException {
+            IpAddress mgmtIp = IpAddress.valueOf(strMgmtIp);
+            TpPort ovsdbPort = TpPort.tpPort(intOvsdbPort);
+            OvsdbController ovsdbController = context.getService(OvsdbController.class);
+            context.waitCompletion(DeviceEvent.class, OVSDB_DEVICE_PREFIX.concat(strMgmtIp),
+                    () -> ovsdbController.connect(mgmtIp, ovsdbPort),
+                    TIMEOUT_DEVICE_CREATION_MS
+            );
+        }
+
+        @Override
+        public boolean isCompleted(WorkflowContext context, Event event)throws WorkflowException {
+            if (!(event instanceof DeviceEvent)) {
+                return false;
+            }
+            DeviceEvent deviceEvent = (DeviceEvent) event;
+            Device device = deviceEvent.subject();
+            switch (deviceEvent.type()) {
+                case DEVICE_ADDED:
+                case DEVICE_AVAILABILITY_CHANGED:
+                case DEVICE_UPDATED:
+                    return context.getService(DeviceService.class).isAvailable(device.id());
+                default:
+                    return false;
+            }
+        }
+
+        @Override
+        public void timeout(WorkflowContext context) throws WorkflowException {
+            if (!isNext(context)) {
+                context.completed(); //Complete the job of worklet by timeout
+            } else {
+                super.timeout(context);
+            }
+        }
+    }
+
+
+    /**
+     * Work-let class for removing OVSDB device.
+     */
+    public static class RemoveOvsdbDevice extends AbstractWorklet {
+
+        @JsonDataModel(path = MODEL_MGMT_IP)
+        String strMgmtIp;
+
+        @Override
+        public boolean isNext(WorkflowContext context) throws WorkflowException {
+
+            DeviceId devId = DeviceId.deviceId(OVSDB_DEVICE_PREFIX.concat(strMgmtIp));
+
+            Device dev = context.getService(DeviceService.class).getDevice(devId);
+            return dev != null;
+        }
+
+        @Override
+        public void process(WorkflowContext context) throws WorkflowException {
+            IpAddress mgmtIp = IpAddress.valueOf(strMgmtIp);
+            check(mgmtIp != null, "mgmt ip is invalid");
+            DeviceId devId = DeviceId.deviceId(OVSDB_DEVICE_PREFIX.concat(strMgmtIp));
+            DeviceAdminService adminService = context.getService(DeviceAdminService.class);
+
+            context.waitCompletion(DeviceEvent.class, devId.toString(),
+                    () -> adminService.removeDevice(devId),
+                    TIMEOUT_DEVICE_CREATION_MS
+            );
+        }
+
+        @Override
+        public boolean isCompleted(WorkflowContext context, Event event)throws WorkflowException {
+            if (!(event instanceof DeviceEvent)) {
+                return false;
+            }
+            DeviceEvent deviceEvent = (DeviceEvent) event;
+            switch (deviceEvent.type()) {
+                case DEVICE_REMOVED:
+                    return !isNext(context);
+                default:
+                    return false;
+            }
+        }
+
+        @Override
+        public void timeout(WorkflowContext context) throws WorkflowException {
+            if (!isNext(context)) {
+                context.completed(); //Complete worklet by timeout
+            } else {
+                super.timeout(context);
+            }
+        }
+    }
+
+    /**
+     * Work-let class for updating OVS version.
+     */
+    public static class UpdateOvsVersion extends AbstractWorklet {
+
+        @JsonDataModel(path = MODEL_OVS_VERSION, optional = true)
+        String strOvsVersion;
+
+        @JsonDataModel(path = MODEL_SSH_ACCESSINFO)
+        JsonNode strSshAccessInfo;
+
+        @Override
+        public boolean isNext(WorkflowContext context) throws WorkflowException {
+
+            return strOvsVersion == null;
+        }
+
+        @Override
+        public void process(WorkflowContext context) throws WorkflowException {
+
+            SshAccessInfo sshAccessInfo = SshAccessInfo.valueOf(strSshAccessInfo);
+            check(Objects.nonNull(sshAccessInfo), "Invalid ssh access info " + context.data());
+
+            OvsVersion ovsVersion = SshUtil.exec(sshAccessInfo,
+                    session -> SshUtil.fetchOvsVersion(session));
+
+            check(Objects.nonNull(ovsVersion), "Failed to fetch ovs version " + context.data());
+            strOvsVersion = ovsVersion.toString();
+
+            context.completed();
+        }
+    }
+
+    /**
+     * Work-let class for updating overlay bridge device id.
+     */
+    public static class UpdateOverlayBridgeId extends AbstractWorklet {
+
+        @JsonDataModel(path = MODEL_MGMT_IP)
+        String strMgmtIp;
+
+        @JsonDataModel(path = MODEL_OF_DEVID_OVERLAY_BRIDGE, optional = true)
+        String strOfDevIdOverlay;
+
+        @Override
+        public boolean isNext(WorkflowContext context) throws WorkflowException {
+
+            return strOfDevIdOverlay == null;
+        }
+
+        @Override
+        public void process(WorkflowContext context) throws WorkflowException {
+
+            BridgeConfig bridgeConfig = OvsUtil.getOvsdbBehaviour(context, strMgmtIp, BridgeConfig.class);
+            Optional<BridgeDescription> optBd = OvsUtil.getBridgeDescription(bridgeConfig, BRIDGE_OVERLAY);
+            if (optBd.isPresent()) {
+                Optional<DeviceId> optDevId = optBd.get().deviceId();
+                if (optDevId.isPresent()) {
+                    log.info("Updates {} of device id with existing device id {}", BRIDGE_OVERLAY, optDevId.get());
+                    strOfDevIdOverlay = optDevId.get().toString();
+                } else {
+                    DeviceId newDevId = OvsUtil.buildOfDeviceId(IpAddress.valueOf(strMgmtIp), DEVID_IDX_BRIDGE_OVERLAY);
+                    log.info("Failed to find devId. Updates {} of device id with new device id {}",
+                            BRIDGE_OVERLAY, newDevId);
+                    strOfDevIdOverlay = newDevId.toString();
+                }
+            } else {
+                DeviceId newDevId = OvsUtil.buildOfDeviceId(IpAddress.valueOf(strMgmtIp), DEVID_IDX_BRIDGE_OVERLAY);
+                log.info("Failed to find description. Updates {} of device id with new device id {}",
+                        BRIDGE_OVERLAY, newDevId);
+                strOfDevIdOverlay = newDevId.toString();
+            }
+
+            context.completed();
+        }
+    }
+
+    /**
+     * Work-let class for creating overlay openflow bridge.
+     */
+    public static class CreateOverlayBridge extends AbstractWorklet {
+
+        @JsonDataModel(path = MODEL_MGMT_IP)
+        String strMgmtIp;
+
+        @JsonDataModel(path = MODEL_OVSDB_PORT)
+        Integer intOvsdbPort;
+
+        @JsonDataModel(path = MODEL_OVS_DATAPATH_TYPE)
+        String strOvsDatapath;
+
+        @JsonDataModel(path = MODEL_OF_DEVID_OVERLAY_BRIDGE, optional = true)
+        String strOfDevIdOverlay;
+
+        @Override
+        public boolean isNext(WorkflowContext context) throws WorkflowException {
+
+            check(strOfDevIdOverlay != null, "invalid strOfDevIdOverlay");
+            return !OvsUtil.isAvailableBridge(context, DeviceId.deviceId(strOfDevIdOverlay));
+        }
+
+        @Override
+        public void process(WorkflowContext context) throws WorkflowException {
+
+            check(strOfDevIdOverlay != null, "invalid strOfDevIdOverlay");
+            BridgeConfig bridgeConfig = OvsUtil.getOvsdbBehaviour(context, strMgmtIp, BridgeConfig.class);
+            List<ControllerInfo> ofControllers = OvsUtil.getOpenflowControllerInfoList(context);
+            DeviceId ofDeviceId = DeviceId.deviceId(strOfDevIdOverlay);
+
+            if (ofControllers == null || ofControllers.size() == 0) {
+                throw new WorkflowException("Invalid of controllers");
+            }
+
+            Optional<BridgeDescription> optBd = OvsUtil.getBridgeDescription(bridgeConfig, BRIDGE_OVERLAY);
+            if (!optBd.isPresent()) {
+
+                // If bridge does not exist, just creates a new bridge.
+                context.waitCompletion(DeviceEvent.class, ofDeviceId.toString(),
+                        () -> OvsUtil.createBridge(bridgeConfig,
+                                BRIDGE_OVERLAY,
+                                OvsUtil.bridgeDatapathId(ofDeviceId),
+                                ofControllers,
+                                OvsUtil.buildOvsDatapathType(strOvsDatapath)),
+                        TIMEOUT_DEVICE_CREATION_MS
+                );
+                return;
+
+            } else {
+                BridgeDescription bd = optBd.get();
+                if (OvsUtil.isEqual(ofControllers, bd.controllers())) {
+                    log.error("{} has valid controller setting({})", BRIDGE_OVERLAY, bd.controllers());
+                    context.completed();
+                    return;
+                }
+
+                OvsdbClientService ovsdbClient = OvsUtil.getOvsdbClient(context, strMgmtIp, intOvsdbPort);
+                if (ovsdbClient == null || !ovsdbClient.isConnected()) {
+                    throw new WorkflowException("Invalid ovsdb client for " + strMgmtIp);
+                }
+
+                // If controller settings are not matched, set controller with valid controller information.
+                context.waitCompletion(DeviceEvent.class, ofDeviceId.toString(),
+                        () -> ovsdbClient.setControllersWithDeviceId(bd.deviceId().get(), ofControllers),
+                        TIMEOUT_DEVICE_CREATION_MS
+                );
+                return;
+            }
+        }
+
+        @Override
+        public boolean isCompleted(WorkflowContext context, Event event)throws WorkflowException {
+            if (!(event instanceof DeviceEvent)) {
+                return false;
+            }
+            DeviceEvent deviceEvent = (DeviceEvent) event;
+            Device device = deviceEvent.subject();
+            switch (deviceEvent.type()) {
+                case DEVICE_ADDED:
+                case DEVICE_AVAILABILITY_CHANGED:
+                case DEVICE_UPDATED:
+                    return context.getService(DeviceService.class).isAvailable(device.id());
+                default:
+                    return false;
+            }
+        }
+
+        @Override
+        public void timeout(WorkflowContext context) throws WorkflowException {
+            if (!isNext(context)) {
+                context.completed(); //Complete the job of worklet by timeout
+            } else {
+                super.timeout(context);
+            }
+        }
+    }
+
+    /**
+     * Work-let class for updating underlay bridge device id.
+     */
+    public static class UpdateUnderlayBridgeId extends AbstractWorklet {
+
+        @JsonDataModel(path = MODEL_MGMT_IP)
+        String strMgmtIp;
+
+        @JsonDataModel(path = MODEL_OF_DEVID_UNDERLAY_BRIDGE, optional = true)
+        String strOfDevIdUnderlay;
+
+        @Override
+        public boolean isNext(WorkflowContext context) throws WorkflowException {
+
+            return strOfDevIdUnderlay == null;
+        }
+
+        @Override
+        public void process(WorkflowContext context) throws WorkflowException {
+
+            BridgeConfig bridgeConfig = OvsUtil.getOvsdbBehaviour(context, strMgmtIp, BridgeConfig.class);
+            Optional<BridgeDescription> optBd = OvsUtil.getBridgeDescription(bridgeConfig, BRIDGE_UNDERLAY);
+            if (optBd.isPresent()) {
+                Optional<DeviceId> optDevId = optBd.get().deviceId();
+                if (optDevId.isPresent()) {
+                    log.info("Updates {} of device id with existing device id {}", BRIDGE_UNDERLAY, optDevId.get());
+                    strOfDevIdUnderlay = optDevId.get().toString();
+                } else {
+                    DeviceId devId = OvsUtil.buildOfDeviceId(IpAddress.valueOf(strMgmtIp),
+                            DEVID_IDX_BRIDGE_UNDERLAY_NOVA);
+                    log.info("Failed to find devId. Updates {} of device id with new device id {}",
+                            BRIDGE_UNDERLAY, devId);
+                    strOfDevIdUnderlay = devId.toString();
+                }
+            } else {
+                DeviceId devId = OvsUtil.buildOfDeviceId(IpAddress.valueOf(strMgmtIp), DEVID_IDX_BRIDGE_UNDERLAY_NOVA);
+                log.info("Failed to find description. Updates {} of device id with new device id {}",
+                        BRIDGE_UNDERLAY, devId);
+                strOfDevIdUnderlay = devId.toString();
+            }
+
+            context.completed();
+        }
+    }
+
+    /**
+     * Work-let class for creating underlay openflow bridge.
+     */
+    public static class CreateUnderlayBridge extends AbstractWorklet {
+
+        @JsonDataModel(path = MODEL_MGMT_IP)
+        String strMgmtIp;
+
+        @JsonDataModel(path = MODEL_OVSDB_PORT)
+        Integer intOvsdbPort;
+
+        @JsonDataModel(path = MODEL_OVS_DATAPATH_TYPE)
+        String strOvsDatapath;
+
+        @JsonDataModel(path = MODEL_OF_DEVID_UNDERLAY_BRIDGE)
+        String strOfDevIdUnderlay;
+
+        @Override
+        public boolean isNext(WorkflowContext context) throws WorkflowException {
+
+            check(strOfDevIdUnderlay != null, "invalid strOfDevIdUnderlay");
+            return !OvsUtil.isAvailableBridge(context, DeviceId.deviceId(strOfDevIdUnderlay));
+        }
+
+        @Override
+        public void process(WorkflowContext context) throws WorkflowException {
+
+            check(strOfDevIdUnderlay != null, "invalid strOfDevIdUnderlay");
+            BridgeConfig bridgeConfig = OvsUtil.getOvsdbBehaviour(context, strMgmtIp, BridgeConfig.class);
+            List<ControllerInfo> ofControllers = OvsUtil.getOpenflowControllerInfoList(context);
+            DeviceId ofDeviceId = DeviceId.deviceId(strOfDevIdUnderlay);
+
+            if (ofControllers == null || ofControllers.size() == 0) {
+                throw new WorkflowException("Invalid of controllers");
+            }
+
+            Optional<BridgeDescription> optBd = OvsUtil.getBridgeDescription(bridgeConfig, BRIDGE_UNDERLAY);
+            if (!optBd.isPresent()) {
+
+                // If bridge does not exist, just creates a new bridge.
+                context.waitCompletion(DeviceEvent.class, ofDeviceId.toString(),
+                        () -> OvsUtil.createBridge(bridgeConfig,
+                                BRIDGE_UNDERLAY,
+                                OvsUtil.bridgeDatapathId(ofDeviceId),
+                                ofControllers,
+                                OvsUtil.buildOvsDatapathType(strOvsDatapath)),
+                        TIMEOUT_DEVICE_CREATION_MS
+                );
+                return;
+
+            } else {
+                BridgeDescription bd = optBd.get();
+                if (OvsUtil.isEqual(ofControllers, bd.controllers())) {
+                    log.error("{} has valid controller setting({})", BRIDGE_UNDERLAY, bd.controllers());
+                    context.completed();
+                    return;
+                }
+
+                OvsdbClientService ovsdbClient = OvsUtil.getOvsdbClient(context, strMgmtIp, intOvsdbPort);
+                if (ovsdbClient == null || !ovsdbClient.isConnected()) {
+                    throw new WorkflowException("Invalid ovsdb client for " + strMgmtIp);
+                }
+
+                // If controller settings are not matched, set controller with valid controller information.
+                context.waitCompletion(DeviceEvent.class, ofDeviceId.toString(),
+                        () -> ovsdbClient.setControllersWithDeviceId(bd.deviceId().get(), ofControllers),
+                        TIMEOUT_DEVICE_CREATION_MS
+                );
+                return;
+            }
+        }
+
+        @Override
+        public boolean isCompleted(WorkflowContext context, Event event)throws WorkflowException {
+            if (!(event instanceof DeviceEvent)) {
+                return false;
+            }
+            DeviceEvent deviceEvent = (DeviceEvent) event;
+            Device device = deviceEvent.subject();
+            switch (deviceEvent.type()) {
+                case DEVICE_ADDED:
+                case DEVICE_AVAILABILITY_CHANGED:
+                case DEVICE_UPDATED:
+                    return context.getService(DeviceService.class).isAvailable(device.id());
+                default:
+                    return false;
+            }
+        }
+
+        @Override
+        public void timeout(WorkflowContext context) throws WorkflowException {
+            if (!isNext(context)) {
+                context.completed(); //Complete the job of worklet by timeout
+            } else {
+                super.timeout(context);
+            }
+        }
+
+    }
+
+    /**
+     * Work-let class for creating vxlan port on the overlay bridge.
+     */
+    public static class CreateOverlayBridgeVxlanPort extends AbstractWorklet {
+
+        @JsonDataModel(path = MODEL_MGMT_IP)
+        String strMgmtIp;
+
+        @JsonDataModel(path = MODEL_OF_DEVID_OVERLAY_BRIDGE, optional = true)
+        String strOfDevIdOverlay;
+
+        private static final String OVS_VXLAN_PORTNAME = "vxlan";
+
+        @Override
+        public boolean isNext(WorkflowContext context) throws WorkflowException {
+
+            check(strOfDevIdOverlay != null, "invalid strOfDevIdOverlay");
+            DeviceId deviceId = DeviceId.deviceId(strOfDevIdOverlay);
+            if (Objects.isNull(deviceId)) {
+                throw new WorkflowException("Invalid br-int bridge, before creating VXLAN port");
+            }
+
+            DeviceService deviceService = context.getService(DeviceService.class);
+            return !deviceService.getPorts(deviceId)
+                    .stream()
+                    .filter(port -> OvsUtil.portName(port).contains(OVS_VXLAN_PORTNAME) && port.isEnabled())
+                    .findAny().isPresent();
+        }
+
+
+        @Override
+        public void process(WorkflowContext context) throws WorkflowException {
+
+            check(strOfDevIdOverlay != null, "invalid strOfDevIdOverlay");
+            TunnelDescription description = DefaultTunnelDescription.builder()
+                    .deviceId(BRIDGE_OVERLAY)
+                    .ifaceName(OVS_VXLAN_PORTNAME)
+                    .type(TunnelDescription.Type.VXLAN)
+                    .remote(TunnelEndPoints.flowTunnelEndpoint())
+                    .key(TunnelKeys.flowTunnelKey())
+                    .build();
+
+            DeviceId ofDeviceId = DeviceId.deviceId(strOfDevIdOverlay);
+            InterfaceConfig interfaceConfig = OvsUtil.getOvsdbBehaviour(context, strMgmtIp, InterfaceConfig.class);
+
+            context.waitCompletion(DeviceEvent.class, ofDeviceId.toString(),
+                    () -> interfaceConfig.addTunnelMode(BRIDGE_OVERLAY, description),
+                    TIMEOUT_DEVICE_CREATION_MS
+            );
+        }
+
+        @Override
+        public boolean isCompleted(WorkflowContext context, Event event)throws WorkflowException {
+            if (!(event instanceof DeviceEvent)) {
+                return false;
+            }
+            DeviceEvent deviceEvent = (DeviceEvent) event;
+            switch (deviceEvent.type()) {
+                case PORT_ADDED:
+                    return !isNext(context);
+                default:
+                    return false;
+            }
+        }
+
+        @Override
+        public void timeout(WorkflowContext context) throws WorkflowException {
+            if (!isNext(context)) {
+                context.completed(); //Complete the job of worklet by timeout
+            } else {
+                super.timeout(context);
+            }
+        }
+    }
+
+    /**
+     * Work-let class for adding physical ports on the underlay openflow bridge.
+     */
+    public static class AddPhysicalPortsOnUnderlayBridge extends AbstractWorklet {
+
+        @JsonDataModel(path = MODEL_MGMT_IP)
+        String strMgmtIp;
+
+        @JsonDataModel(path = MODEL_OVSDB_PORT)
+        Integer intOvsdbPort;
+
+        @JsonDataModel(path = MODEL_OF_DEVID_UNDERLAY_BRIDGE, optional = true)
+        String strOfDevIdUnderlay;
+
+        @JsonDataModel(path = MODEL_OVS_DATAPATH_TYPE)
+        String strOvsDatapath;
+
+        @JsonDataModel(path = MODEL_PHY_PORTS)
+        ArrayNode arrNodePhysicalPorts;
+
+        @Override
+        public boolean isNext(WorkflowContext context) throws WorkflowException {
+            check(strOfDevIdUnderlay != null, "invalid strOfDevIdUnderlay");
+            DeviceId brphyDevId = DeviceId.deviceId(strOfDevIdUnderlay);
+            return !hasAllPhysicalPorts(context, brphyDevId);
+        }
+
+        @Override
+        public void process(WorkflowContext context) throws WorkflowException {
+            check(strOfDevIdUnderlay != null, "invalid strOfDevIdUnderlay");
+            DeviceId brphyDevId = DeviceId.deviceId(strOfDevIdUnderlay);
+
+            context.waitCompletion(DeviceEvent.class, brphyDevId.toString(),
+                    () -> addPhysicalPorts(context, brphyDevId, BRIDGE_UNDERLAY, strOvsDatapath),
+                    TIMEOUT_PORT_ADDITION_MS
+            );
+        }
+
+        @Override
+        public boolean isCompleted(WorkflowContext context, Event event)throws WorkflowException {
+            if (!(event instanceof DeviceEvent)) {
+                return false;
+            }
+            DeviceEvent deviceEvent = (DeviceEvent) event;
+            switch (deviceEvent.type()) {
+                case PORT_ADDED:
+                    return !isNext(context);
+                default:
+                    return false;
+            }
+        }
+
+        @Override
+        public void timeout(WorkflowContext context) throws WorkflowException {
+            if (!isNext(context)) {
+                context.completed(); //Complete the job of worklet by timeout
+            } else {
+                super.timeout(context);
+            }
+        }
+
+        private final List<String> getPhysicalPorts(WorkflowContext context) throws WorkflowException {
+            List<String> ports = Lists.newArrayList();
+            for (JsonNode jsonNode : arrNodePhysicalPorts) {
+                check(jsonNode instanceof TextNode, "Invalid physical ports " + arrNodePhysicalPorts);
+                ports.add(jsonNode.asText());
+            }
+            return ports;
+        }
+
+        private final boolean hasAllPhysicalPorts(WorkflowContext context, DeviceId devId) throws WorkflowException {
+
+            List<Port> devPorts = context.getService(DeviceService.class).getPorts(devId);
+            check(devPorts != null, "Invalid device ports for " + devId);
+            List<String> physicalPorts = getPhysicalPorts(context);
+            check(physicalPorts != null, "Invalid physical ports" + context);
+
+            log.info("physicalPorts: {} for {}", physicalPorts, devId);
+            for (String port: physicalPorts) {
+                if (devPorts.stream().noneMatch(p -> OvsUtil.portName(p).contains(port))) {
+                    return false;
+                }
+            }
+            return true;
+        }
+
+        private final boolean hasPort(WorkflowContext context, DeviceId devId, String portName)
+                throws WorkflowException {
+
+            List<Port> devPorts = context.getService(DeviceService.class).getPorts(devId);
+            check(devPorts != null, "Invalid device ports for " + devId);
+            return devPorts.stream().anyMatch(p -> OvsUtil.portName(p).contains(portName));
+        }
+
+        private final void addPhysicalPorts(WorkflowContext context, DeviceId devId, String bridgeName,
+                                            String strOvsDatapathType)
+                throws WorkflowException {
+            OvsdbClientService ovsdbClient = OvsUtil.getOvsdbClient(context, strMgmtIp, intOvsdbPort);
+            check(ovsdbClient != null, "Invalid ovsdb client");
+
+            List<String> physicalPorts = getPhysicalPorts(context);
+            check(physicalPorts != null, "Invalid physical ports");
+
+            OvsDatapathType datapathType = OvsUtil.buildOvsDatapathType(strOvsDatapathType);
+            check(datapathType != null, "Invalid data path type");
+
+            List<String> sortedPhyPorts = physicalPorts.stream().sorted().collect(Collectors.toList());
+
+            for (String port: sortedPhyPorts) {
+                if (hasPort(context, devId, port)) {
+                    continue;
+                }
+                log.info("adding port {} on {}", port, devId);
+                switch (datapathType) {
+                    case NETDEV:
+                        throw new WorkflowException("NETDEV datapathType are not supported");
+                        //break;
+                    case SYSTEM:
+                    default:
+                        ovsdbClient.createPort(BridgeName.bridgeName(bridgeName).name(), port);
+                }
+            }
+        }
+    }
+
+    /**
+     * Work-let class for configure local ip of underlay openflow bridge.
+     */
+    public static class ConfigureUnderlayBridgeLocalIp extends AbstractWorklet {
+
+        @JsonDataModel(path = MODEL_SSH_ACCESSINFO)
+        JsonNode strSshAccessInfo;
+
+        @JsonDataModel(path = MODEL_VTEP_IP)
+        String strVtepIp;
+
+        @Override
+        public boolean isNext(WorkflowContext context) throws WorkflowException {
+
+            SshAccessInfo sshAccessInfo = SshAccessInfo.valueOf(strSshAccessInfo);
+            check(Objects.nonNull(sshAccessInfo), "Invalid ssh access info " + context.data());
+
+            NetworkAddress vtepIp = NetworkAddress.valueOf(strVtepIp);
+            check(Objects.nonNull(vtepIp), "Invalid vtep ip " + context.data());
+
+            return !SshUtil.exec(sshAccessInfo,
+                    session ->
+                            SshUtil.hasIpAddrOnInterface(session, BRIDGE_UNDERLAY, vtepIp)
+                                    && SshUtil.isIpLinkUpOnInterface(session, BRIDGE_UNDERLAY)
+            );
+        }
+
+        @Override
+        public void process(WorkflowContext context) throws WorkflowException {
+
+            SshAccessInfo sshAccessInfo = SshAccessInfo.valueOf(strSshAccessInfo);
+            check(Objects.nonNull(sshAccessInfo), "Invalid ssh access info " + context.data());
+
+            NetworkAddress vtepIp = NetworkAddress.valueOf(strVtepIp);
+            check(Objects.nonNull(vtepIp), "Invalid vtep ip " + context.data());
+
+            SshUtil.exec(sshAccessInfo,
+                    session -> {
+                        SshUtil.addIpAddrOnInterface(session, BRIDGE_UNDERLAY, vtepIp);
+                        SshUtil.setIpLinkUpOnInterface(session, BRIDGE_UNDERLAY);
+                        return "";
+                    });
+
+            context.completed();
+        }
+    }
+
+    /**
+     * Work-let class for deleting overlay bridge config.
+     */
+    public static class DeleteOverlayBridgeConfig extends AbstractWorklet {
+
+        @JsonDataModel(path = MODEL_MGMT_IP)
+        String strMgmtIp;
+
+        @Override
+        public boolean isNext(WorkflowContext context) throws WorkflowException {
+
+            BridgeConfig bridgeConfig = OvsUtil.getOvsdbBehaviour(context, strMgmtIp, BridgeConfig.class);
+
+            Collection<BridgeDescription> bridges = bridgeConfig.getBridges();
+            return bridges.stream()
+                    .anyMatch(bd -> Objects.equals(bd.name(), BRIDGE_OVERLAY));
+        }
+
+        @Override
+        public void process(WorkflowContext context) throws WorkflowException {
+
+            BridgeConfig bridgeConfig = OvsUtil.getOvsdbBehaviour(context, strMgmtIp, BridgeConfig.class);
+
+            bridgeConfig.deleteBridge(BridgeName.bridgeName(BRIDGE_OVERLAY));
+
+            for (int i = 0; i < 10; i++) {
+                if (!isNext(context)) {
+                    context.completed();
+                    return;
+                }
+                sleep(50);
+            }
+            throw new WorkflowException("Timeout happened for removing config");
+        }
+
+        protected void sleep(long ms) {
+            try {
+                Thread.sleep(ms);
+            } catch (InterruptedException e) {
+                e.printStackTrace();
+            }
+        }
+    }
+
+    /**
+     * Work-let class for removing overlay bridge openflow device.
+     */
+    public static class RemoveOverlayBridgeOfDevice extends AbstractWorklet {
+
+        @JsonDataModel(path = MODEL_MGMT_IP)
+        String strMgmtIp;
+
+        @Override
+        public boolean isNext(WorkflowContext context) throws WorkflowException {
+
+            DeviceId devId = OvsUtil.buildOfDeviceId(IpAddress.valueOf(strMgmtIp), DEVID_IDX_BRIDGE_OVERLAY);
+
+            Device dev = context.getService(DeviceService.class).getDevice(devId);
+            return dev != null;
+        }
+
+        @Override
+        public void process(WorkflowContext context) throws WorkflowException {
+
+            DeviceId devId = OvsUtil.buildOfDeviceId(IpAddress.valueOf(strMgmtIp), DEVID_IDX_BRIDGE_OVERLAY);
+
+            DeviceAdminService adminService = context.getService(DeviceAdminService.class);
+
+            context.waitCompletion(DeviceEvent.class, devId.toString(),
+                    () -> adminService.removeDevice(devId),
+                    TIMEOUT_DEVICE_CREATION_MS
+            );
+        }
+
+        @Override
+        public boolean isCompleted(WorkflowContext context, Event event)throws WorkflowException {
+            if (!(event instanceof DeviceEvent)) {
+                return false;
+            }
+            DeviceEvent deviceEvent = (DeviceEvent) event;
+            switch (deviceEvent.type()) {
+                case DEVICE_REMOVED:
+                    return !isNext(context);
+                default:
+                    return false;
+            }
+        }
+
+        @Override
+        public void timeout(WorkflowContext context) throws WorkflowException {
+            if (!isNext(context)) {
+                context.completed(); //Complete the job of worklet by timeout
+            } else {
+                super.timeout(context);
+            }
+        }
+    }
+
+    /**
+     * Work-let class for deleting underlay bridge config.
+     */
+    public static class DeleteUnderlayBridgeConfig extends AbstractWorklet {
+
+        @JsonDataModel(path = MODEL_MGMT_IP)
+        String strMgmtIp;
+
+        @Override
+        public boolean isNext(WorkflowContext context) throws WorkflowException {
+
+            BridgeConfig bridgeConfig = OvsUtil.getOvsdbBehaviour(context, strMgmtIp, BridgeConfig.class);
+
+            Collection<BridgeDescription> bridges = bridgeConfig.getBridges();
+            return bridges.stream()
+                    .anyMatch(bd -> Objects.equals(bd.name(), BRIDGE_UNDERLAY));
+        }
+
+        @Override
+        public void process(WorkflowContext context) throws WorkflowException {
+
+            BridgeConfig bridgeConfig = OvsUtil.getOvsdbBehaviour(context, strMgmtIp, BridgeConfig.class);
+
+            bridgeConfig.deleteBridge(BridgeName.bridgeName(BRIDGE_UNDERLAY));
+
+            for (int i = 0; i < 10; i++) {
+                if (!isNext(context)) {
+                    context.completed();
+                    return;
+                }
+                sleep(50);
+            }
+            throw new WorkflowException("Timeout happened for removing config");
+        }
+
+        protected void sleep(long ms) {
+            try {
+                Thread.sleep(ms);
+            } catch (InterruptedException e) {
+                e.printStackTrace();
+            }
+        }
+    }
+
+    /**
+     * Work-let class for removing underlay bridge openflow device.
+     */
+    public static class RemoveUnderlayBridgeOfDevice extends AbstractWorklet {
+
+        @JsonDataModel(path = MODEL_MGMT_IP)
+        String strMgmtIp;
+
+        @Override
+        public boolean isNext(WorkflowContext context) throws WorkflowException {
+
+            DeviceId devId = OvsUtil.buildOfDeviceId(IpAddress.valueOf(strMgmtIp), DEVID_IDX_BRIDGE_UNDERLAY_NOVA);
+
+            Device dev = context.getService(DeviceService.class).getDevice(devId);
+            return dev != null;
+        }
+
+        @Override
+        public void process(WorkflowContext context) throws WorkflowException {
+
+            DeviceId devId = OvsUtil.buildOfDeviceId(IpAddress.valueOf(strMgmtIp), DEVID_IDX_BRIDGE_UNDERLAY_NOVA);
+
+            DeviceAdminService adminService = context.getService(DeviceAdminService.class);
+
+            context.waitCompletion(DeviceEvent.class, devId.toString(),
+                    () -> adminService.removeDevice(devId),
+                    TIMEOUT_DEVICE_CREATION_MS
+            );
+        }
+
+        @Override
+        public boolean isCompleted(WorkflowContext context, Event event)throws WorkflowException {
+            if (!(event instanceof DeviceEvent)) {
+                return false;
+            }
+            DeviceEvent deviceEvent = (DeviceEvent) event;
+            switch (deviceEvent.type()) {
+                case DEVICE_REMOVED:
+                    return !isNext(context);
+                default:
+                    return false;
+            }
+        }
+
+        @Override
+        public void timeout(WorkflowContext context) throws WorkflowException {
+            if (!isNext(context)) {
+                context.completed(); //Complete the job of worklet by timeout
+            } else {
+                super.timeout(context);
+            }
+        }
+    }
+}
diff --git a/apps/workflow/ofoverlay/app/src/main/java/org/onosproject/ofoverlay/impl/package-info.java b/apps/workflow/ofoverlay/app/src/main/java/org/onosproject/ofoverlay/impl/package-info.java
new file mode 100644
index 0000000..42214bc
--- /dev/null
+++ b/apps/workflow/ofoverlay/app/src/main/java/org/onosproject/ofoverlay/impl/package-info.java
@@ -0,0 +1,20 @@
+/*
+ * Copyright 2019-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.
+ */
+
+/**
+ * Open-flow overlay implementation package.
+ */
+package org.onosproject.ofoverlay.impl;
diff --git a/apps/workflow/ofoverlay/app/src/main/java/org/onosproject/ofoverlay/impl/util/NetworkAddress.java b/apps/workflow/ofoverlay/app/src/main/java/org/onosproject/ofoverlay/impl/util/NetworkAddress.java
new file mode 100644
index 0000000..c8a8829
--- /dev/null
+++ b/apps/workflow/ofoverlay/app/src/main/java/org/onosproject/ofoverlay/impl/util/NetworkAddress.java
@@ -0,0 +1,112 @@
+/*
+ * Copyright 2019-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.ofoverlay.impl.util;
+
+import com.google.common.base.MoreObjects;
+import org.onlab.packet.IpAddress;
+import org.onlab.packet.IpPrefix;
+
+import java.util.Objects;
+
+import static com.google.common.base.Preconditions.checkArgument;
+
+/**
+ * Representation of a network address, which consists of IP address and prefix.
+ */
+public final class NetworkAddress {
+    private final IpAddress ip;
+    private final IpPrefix prefix;
+
+    /**
+     * Constructor for a given IP address and prefix.
+     *
+     * @param ip ip address
+     * @param prefix ip prefix
+     */
+    private NetworkAddress(IpAddress ip, IpPrefix prefix) {
+        this.ip = ip;
+        this.prefix = prefix;
+    }
+
+    /**
+     * Converts a CIDR notation string into a network address.
+     *
+     * @param cidr cidr
+     * @return network address
+     * @throws IllegalArgumentException if the cidr is not valid
+     */
+    public static NetworkAddress valueOf(String cidr) {
+        checkArgument(cidr.contains("/"));
+
+        IpAddress ipAddress = IpAddress.valueOf(cidr.split("/")[0]);
+        IpPrefix ipPrefix = IpPrefix.valueOf(cidr);
+
+        return new NetworkAddress(ipAddress, ipPrefix);
+    }
+
+    /**
+     * Returns the IP address value of the network address.
+     *
+     * @return ip address
+     */
+    public IpAddress ip() {
+        return this.ip;
+    }
+
+    /**
+     * Returns the IP prefix value of the network address.
+     *
+     * @return ip prefix
+     */
+    public IpPrefix prefix() {
+        return this.prefix;
+    }
+
+    /**
+     * Converts a network address to a CIDR notation.
+     *
+     * @return cidr notation string
+     */
+    public String cidr() {
+        return ip.toString() + "/" + prefix.prefixLength();
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (this == obj) {
+            return true;
+        }
+
+        if (obj instanceof NetworkAddress) {
+            NetworkAddress that = (NetworkAddress) obj;
+            return Objects.equals(ip, that.ip) && Objects.equals(prefix, that.prefix);
+        }
+        return false;
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(ip, prefix);
+    }
+
+    @Override
+    public String toString() {
+        return MoreObjects.toStringHelper(getClass())
+                .add("IpAddress", ip)
+                .add("IpPrefix", prefix)
+                .toString();
+    }
+}
\ No newline at end of file
diff --git a/apps/workflow/ofoverlay/app/src/main/java/org/onosproject/ofoverlay/impl/util/OvsDatapathType.java b/apps/workflow/ofoverlay/app/src/main/java/org/onosproject/ofoverlay/impl/util/OvsDatapathType.java
new file mode 100644
index 0000000..0a64e93
--- /dev/null
+++ b/apps/workflow/ofoverlay/app/src/main/java/org/onosproject/ofoverlay/impl/util/OvsDatapathType.java
@@ -0,0 +1,41 @@
+/*
+ * Copyright 2019-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.ofoverlay.impl.util;
+
+/**
+ * Enumeration for OVS data path type.
+ */
+public enum OvsDatapathType {
+    EMPTY(""),
+    NETDEV("netdev"),
+    SYSTEM("system");
+
+    private final String value;
+
+    /**
+     * Constructor for OvsDatapathType enumeration.
+     *
+     * @param value string OvsDatapathType
+     */
+    OvsDatapathType(String value) {
+        this.value = value;
+    }
+
+    @Override
+    public String toString() {
+        return value;
+    }
+}
diff --git a/apps/workflow/ofoverlay/app/src/main/java/org/onosproject/ofoverlay/impl/util/OvsVersion.java b/apps/workflow/ofoverlay/app/src/main/java/org/onosproject/ofoverlay/impl/util/OvsVersion.java
new file mode 100644
index 0000000..015ac73
--- /dev/null
+++ b/apps/workflow/ofoverlay/app/src/main/java/org/onosproject/ofoverlay/impl/util/OvsVersion.java
@@ -0,0 +1,154 @@
+/*
+ * Copyright 2019-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.ofoverlay.impl.util;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+/**
+ * Class for OVS Version.
+ */
+public final class OvsVersion {
+    protected static final Logger log = LoggerFactory.getLogger(OvsVersion.class);
+
+    private int[] versionElements = new int[] {0, 0, 0, Integer.MAX_VALUE};
+    private int depth = 0;
+
+    /**
+     * Constructor for OvsVersion.
+     * @param ovsVerStr OVS version string
+     */
+    private OvsVersion(String ovsVerStr) {
+
+        // Supporting
+        // 1.2.3 (depth = 3, public release)
+        // 1.2.3.4 (depth = 4, beta release)
+        Matcher m = Pattern.compile("(\\d+)\\.(\\d+)\\.(\\d+)(\\.(\\d+))?").matcher(ovsVerStr);
+
+        if (!m.matches()) {
+            throw new IllegalArgumentException("Malformed OVS version");
+        }
+
+        versionElements[0] = Integer.parseInt(m.group(1));
+        versionElements[1] = Integer.parseInt(m.group(2));
+        versionElements[2] = Integer.parseInt(m.group(3));
+
+        if (m.group(4) == null) {
+            depth = 3;
+            return;
+        }
+
+        versionElements[3] = Integer.parseInt(m.group(5));
+        depth = 4;
+    }
+
+    /**
+     * Builder for OvsVersion.
+     * @param ovsVersionStr OVS version string
+     * @return ovs version
+     */
+    public static OvsVersion build(String ovsVersionStr) {
+        try {
+            return new OvsVersion(ovsVersionStr);
+        } catch (IllegalArgumentException e) {
+            log.error("Exception Occurred {}", e);
+            return null;
+        }
+    }
+
+    private int get(int level) {
+        return versionElements[level];
+    }
+
+    private int compare(OvsVersion tgt) {
+        //Comparison example
+        // 2.7.0 < 2.7.2
+        // 2.7.0 > 2.6.9.12
+        // 2.7.0 > 2.7.0.0 (because 2.7.0 is public release)
+        for (int i = 0; i < versionElements.length; i++) {
+            if (versionElements[i] == tgt.get(i)) {
+                continue;
+            } else if (versionElements[i] < tgt.get(i)) {
+                return (i + 1) * -1;
+            } else {
+                return (i + 1);
+            }
+        }
+        return 0;
+    }
+
+    /**
+     * Returns whether this OVS version is equal to the target OVS version.
+     * @param tgt taret OVS version
+     * @return whether this OVS version is equal to the target OVS version
+     */
+    public boolean isEqOf(OvsVersion tgt) {
+        return (compare(tgt) == 0);
+    }
+
+    /**
+     * Returns whether this OVS version is prior to the target OVS version.
+     * @param tgt taret OVS version
+     * @return whether this OVS version is prior to the target OVS version
+     */
+    public boolean isPriorOf(OvsVersion tgt) {
+        return (compare(tgt) < 0);
+    }
+
+    /**
+     * Returns whether this OVS version is prior or equal to the target OVS version.
+     * @param tgt taret OVS version
+     * @return whether this OVS version is prior or equal to the target OVS version
+     */
+    public boolean isPriorOrEqOf(OvsVersion tgt) {
+        return (compare(tgt) <= 0);
+    }
+
+    /**
+     * Returns whether this OVS version is later to the target OVS version.
+     * @param tgt taret OVS version
+     * @return whether this OVS version is later to the target OVS version
+     */
+    public boolean isLaterOf(OvsVersion tgt) {
+        return (compare(tgt) > 0);
+    }
+
+    /**
+     * Returns whether this OVS version is later or equal to the target OVS version.
+     * @param tgt taret OVS version
+     * @return whether this OVS version is later or equal to the target OVS version
+     */
+    public boolean isLaterOrEqOf(OvsVersion tgt) {
+        return (compare(tgt) >= 0);
+    }
+
+    @Override
+    public String toString() {
+
+        StringBuilder strbuild = new StringBuilder();
+        strbuild.append(versionElements[0]);
+
+        for (int i = 1; i < depth; i++) {
+            strbuild.append(".");
+            strbuild.append(versionElements[i]);
+        }
+        return strbuild.toString();
+    }
+
+}
\ No newline at end of file
diff --git a/apps/workflow/ofoverlay/app/src/main/java/org/onosproject/ofoverlay/impl/util/SshBehavior.java b/apps/workflow/ofoverlay/app/src/main/java/org/onosproject/ofoverlay/impl/util/SshBehavior.java
new file mode 100644
index 0000000..6189837
--- /dev/null
+++ b/apps/workflow/ofoverlay/app/src/main/java/org/onosproject/ofoverlay/impl/util/SshBehavior.java
@@ -0,0 +1,30 @@
+/*
+ * Copyright 2019-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.ofoverlay.impl.util;
+
+import com.jcraft.jsch.Session;
+import org.onosproject.workflow.api.WorkflowException;
+
+/**
+ * Functional interface for ssh behavior.
+ * @param <R> return value of ssh behavior
+ */
+@FunctionalInterface
+public interface SshBehavior<R> {
+
+    R apply(Session session) throws WorkflowException;
+
+}
diff --git a/apps/workflow/ofoverlay/app/src/main/java/org/onosproject/ofoverlay/impl/util/SshUtil.java b/apps/workflow/ofoverlay/app/src/main/java/org/onosproject/ofoverlay/impl/util/SshUtil.java
new file mode 100644
index 0000000..0c6caff
--- /dev/null
+++ b/apps/workflow/ofoverlay/app/src/main/java/org/onosproject/ofoverlay/impl/util/SshUtil.java
@@ -0,0 +1,366 @@
+/*
+ * Copyright 2019-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.ofoverlay.impl.util;
+
+import com.google.common.io.CharStreams;
+import com.jcraft.jsch.Channel;
+import com.jcraft.jsch.ChannelExec;
+import com.jcraft.jsch.JSch;
+import com.jcraft.jsch.JSchException;
+import com.jcraft.jsch.Session;
+import org.onlab.packet.IpAddress;
+import org.onosproject.workflow.api.WorkflowException;
+import org.onosproject.workflow.model.accessinfo.SshAccessInfo;
+import org.slf4j.Logger;
+
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.nio.charset.StandardCharsets;
+import java.util.Collections;
+import java.util.Set;
+import java.util.regex.Pattern;
+import java.util.stream.Collectors;
+
+import static org.onosproject.workflow.api.CheckCondition.check;
+import static org.slf4j.LoggerFactory.getLogger;
+
+/**
+ * Class for SSH utilities.
+ */
+public final class SshUtil {
+
+    protected static final Logger log = getLogger(SshUtil.class);
+
+    private static final String STRICT_HOST_CHECKING = "StrictHostKeyChecking";
+    private static final String DEFAULT_STRICT_HOST_CHECKING = "no";
+    private static final int DEFAULT_SESSION_TIMEOUT = 30000; // milliseconds
+
+    private static final String SPACESEPERATOR = " ";
+
+    /**
+     * Default constructor.
+     */
+    private SshUtil() {
+    }
+
+    /**
+     * Creates a new session with a given ssh access information.
+     *
+     * @param sshInfo information to ssh to the remote server
+     * @return ssh session, or null
+     */
+    public static Session connect(SshAccessInfo sshInfo) {
+        Session session;
+
+        try {
+            JSch jsch = new JSch();
+            jsch.addIdentity(sshInfo.privateKey());
+
+            session = jsch.getSession(sshInfo.user(),
+                    sshInfo.remoteIp().toString(),
+                    sshInfo.port().toInt());
+            session.setConfig(STRICT_HOST_CHECKING, DEFAULT_STRICT_HOST_CHECKING);
+            session.connect(DEFAULT_SESSION_TIMEOUT);
+
+        } catch (JSchException e) {
+            log.warn("Failed to connect to {}", sshInfo.toString(), e);
+            session = authUserPwd(sshInfo);
+        }
+        return session;
+    }
+
+    /**
+     * Creates a new session with ssh access info.
+     *
+     * @param sshInfo information to ssh to the remote server
+     * @return ssh session, or null
+     */
+    public static Session authUserPwd(SshAccessInfo sshInfo) {
+        log.info("Retrying Session with {}", sshInfo);
+        try {
+            JSch jsch = new JSch();
+
+            Session session = jsch.getSession(sshInfo.user(),
+                    sshInfo.remoteIp().toString(),
+                    sshInfo.port().toInt());
+            session.setPassword(sshInfo.password());
+            session.setConfig(STRICT_HOST_CHECKING, DEFAULT_STRICT_HOST_CHECKING);
+            session.connect(DEFAULT_SESSION_TIMEOUT);
+
+            return session;
+        } catch (JSchException e) {
+            log.warn("Failed to connect to {} due to {}", sshInfo.toString(), e);
+            return null;
+        }
+    }
+
+    /**
+     * Closes a connection.
+     *
+     * @param session session ssh session
+     */
+    public static void disconnect(Session session) {
+        if (session.isConnected()) {
+            session.disconnect();
+        }
+    }
+
+    /**
+     * Fetches last term after executing command.
+     * @param session  ssh session
+     * @param command command to execute
+     * @return last term, or null
+     */
+    public static String fetchLastTerm(Session session, String command) {
+         if (session == null || !session.isConnected()) {
+             log.error("Invalid session({})", session);
+             return null;
+         }
+
+         log.info("fetchLastTerm: ssh command {} to {}", command, session.getHost());
+
+         try {
+             Channel channel = session.openChannel("exec");
+             if (channel == null) {
+                 log.error("Invalid channel of session({}) for command({})", session, command);
+                 return null;
+             }
+
+             ((ChannelExec) channel).setCommand(command);
+             channel.setInputStream(null);
+             InputStream output = channel.getInputStream();
+             channel.connect();
+             String[] lineList = null;
+
+             try (BufferedReader reader = new BufferedReader(new InputStreamReader(output, StandardCharsets.UTF_8))) {
+                 lineList = reader.lines().findFirst().get().split(SPACESEPERATOR);
+             } catch (IOException e) {
+                 log.error("Exception in fetchLastTerm", e);
+             } finally {
+                 channel.disconnect();
+                 output.close();
+             }
+
+             if (lineList.length > 0) {
+                 return lineList[lineList.length - 1];
+             } else {
+                 return null;
+             }
+
+         } catch (JSchException | IOException e) {
+             log.error("Exception in fetchLastTerm", e);
+             return null;
+         }
+    }
+
+    /**
+     * Executes a given command. It opens exec channel for the command and closes
+     * the channel when it's done.
+     *
+     * @param session ssh connection to a remote server
+     * @param command command to execute
+     * @return command output string if the command succeeds, or null
+     */
+    public static String executeCommand(Session session, String command) {
+        if (session == null || !session.isConnected()) {
+            log.error("Invalid session({})", session);
+            return null;
+        }
+
+        log.info("executeCommand: ssh command {} to {}", command, session.getHost());
+
+        try {
+            Channel channel = session.openChannel("exec");
+
+            if (channel == null) {
+                log.debug("Invalid channel of session({}) for command({})", session, command);
+                return null;
+            }
+
+            ((ChannelExec) channel).setCommand(command);
+            channel.setInputStream(null);
+            InputStream output = channel.getInputStream();
+
+            channel.connect();
+            String result = CharStreams.toString(new InputStreamReader(output, StandardCharsets.UTF_8));
+            log.trace("SSH result(on {}): {}", session.getHost(), result);
+            channel.disconnect();
+
+            return result;
+        } catch (JSchException | IOException e) {
+            log.debug("Failed to execute command {} due to {}", command, e);
+            return null;
+        }
+    }
+
+    /**
+     * Fetches OVS version information.
+     * @param session Jsch session
+     * @return OVS version
+     * @throws WorkflowException workflow exception
+     */
+    public static OvsVersion fetchOvsVersion(Session session) throws WorkflowException {
+
+        OvsVersion devOvsVersion;
+
+        String ovsVersionStr = fetchLastTerm(session, "ovs-vswitchd --version");
+        if (ovsVersionStr == null) {
+            log.error("Failed to get ovs Version String for ssh session:{}", session);
+            throw new WorkflowException("Failed to get ovs Version String");
+        }
+
+        devOvsVersion = OvsVersion.build(ovsVersionStr);
+        if (devOvsVersion == null) {
+            log.error("Failed to build OVS version for {}", ovsVersionStr);
+            throw new WorkflowException("Failed to build OVS version");
+        }
+
+        return devOvsVersion;
+    }
+
+    private static final String IP_PATTERN = "^([01]?\\d\\d?|2[0-4]\\d|25[0-5])\\." +
+            "([01]?\\d\\d?|2[0-4]\\d|25[0-5])\\." +
+            "([01]?\\d\\d?|2[0-4]\\d|25[0-5])\\." +
+            "([01]?\\d\\d?|2[0-4]\\d|25[0-5])$";
+
+    private static boolean isIPv6(String address) {
+        boolean isCorrect = true;
+        try {
+            IpAddress.valueOf(address);
+        } catch (IllegalArgumentException e) {
+            log.debug("Exception Occurred {}", e.toString());
+            isCorrect = false;
+        }
+        return isCorrect;
+    }
+
+    private static boolean isCidr(String s) {
+        String[] splits = s.split("/");
+        return splits.length == 2 &&
+                (splits[0].matches(IP_PATTERN) || isIPv6(splits[0]));
+    }
+
+    /**
+     * Adds IP address on the interface.
+     * @param session SSH session
+     * @param ifname interface name
+     * @param address network address
+     * @throws WorkflowException workflow exception
+     */
+    public static void addIpAddrOnInterface(Session session, String ifname, NetworkAddress address)
+            throws WorkflowException {
+
+        executeCommand(session, String.format("ip addr add %s dev %s", address.cidr(), ifname));
+
+        Set<NetworkAddress> result = getIpAddrOfInterface(session, ifname);
+        if (!result.contains(address)) {
+            throw new WorkflowException("Failed to set ip(" + address + ") on " + ifname + ",  result: " + result);
+        }
+    }
+
+    /**
+     * Gets IP addresses of interface.
+     * @param session SSH session
+     * @param ifname interface name
+     * @return IP addresses of interface
+     */
+    public static Set<NetworkAddress> getIpAddrOfInterface(Session session, String ifname) {
+
+        String output = executeCommand(session, String.format("ip addr show %s", ifname));
+
+        if (output == null) {
+            return Collections.emptySet();
+        }
+
+        Set<NetworkAddress> result = Pattern.compile(" ")
+                .splitAsStream(output)
+                .filter(SshUtil::isCidr)
+                .map(NetworkAddress::valueOf)
+                .collect(Collectors.toSet());
+        return result;
+    }
+
+    /**
+     * Returns whether the interface has IP address.
+     * @param session SSH session
+     * @param ifname interface name
+     * @param addr network address
+     * @return whether the interface has IP address
+     */
+    public static boolean hasIpAddrOnInterface(Session session, String ifname, NetworkAddress addr) {
+
+        Set<NetworkAddress> phyBrIps = getIpAddrOfInterface(session, ifname);
+
+        return phyBrIps.stream()
+                .anyMatch(ip -> addr.ip().equals(ip.ip()));
+    }
+
+    /**
+     * Sets IP link UP on the interface.
+     * @param session SSH session
+     * @param ifname interface name
+     * @throws WorkflowException workflow exception
+     */
+    public static void setIpLinkUpOnInterface(Session session, String ifname)
+            throws WorkflowException {
+
+        executeCommand(session, String.format("ip link set %s up", ifname));
+
+        if (!isIpLinkUpOnInterface(session, ifname)) {
+            throw new WorkflowException("Failed to set UP on " + ifname);
+        }
+    }
+
+    /**
+     * Returns whether the link of the interface is up.
+     * @param session SSH session
+     * @param ifname interface name
+     * @return whether the link of the interface is up
+     */
+    public static boolean isIpLinkUpOnInterface(Session session, String ifname) {
+        String output = executeCommand(session, String.format("ip link show %s", ifname));
+
+        return output != null && output.contains("UP");
+    }
+
+    /**
+     * Executes SSH behavior.
+     * @param sshAccessInfo SSH Access information
+     * @param behavior SSH behavior
+     * @param <R> Return type of SSH behavior
+     * @return return of SSH behavior
+     * @throws WorkflowException workflow exception
+     */
+    public static <R> R exec(SshAccessInfo sshAccessInfo, SshBehavior<R> behavior)
+            throws WorkflowException {
+
+        check(sshAccessInfo != null, "Invalid sshAccessInfo");
+        Session session = connect(sshAccessInfo);
+        if (session == null || !session.isConnected()) {
+            log.error("Failed to get session for ssh:{}", sshAccessInfo);
+            throw new WorkflowException("Failed to get session for ssh:" + sshAccessInfo);
+        }
+
+        try {
+            return behavior.apply(session);
+        } finally {
+            disconnect(session);
+        }
+    }
+
+}
diff --git a/apps/workflow/ofoverlay/app/src/main/java/org/onosproject/ofoverlay/impl/util/SshkeyExchange.java b/apps/workflow/ofoverlay/app/src/main/java/org/onosproject/ofoverlay/impl/util/SshkeyExchange.java
new file mode 100644
index 0000000..5615112
--- /dev/null
+++ b/apps/workflow/ofoverlay/app/src/main/java/org/onosproject/ofoverlay/impl/util/SshkeyExchange.java
@@ -0,0 +1,198 @@
+/*
+ * Copyright 2019-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.ofoverlay.impl.util;
+
+import com.jcraft.jsch.Channel;
+import com.jcraft.jsch.ChannelSftp;
+import com.jcraft.jsch.JSch;
+import com.jcraft.jsch.JSchException;
+import com.jcraft.jsch.KeyPair;
+import com.jcraft.jsch.Session;
+import com.jcraft.jsch.SftpATTRS;
+import com.jcraft.jsch.SftpException;
+import org.onlab.packet.IpAddress;
+import org.slf4j.Logger;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.nio.file.Files;
+import java.nio.file.Paths;
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
+
+import static org.slf4j.LoggerFactory.getLogger;
+
+/**
+ * Class for SSH key exchange.
+ */
+public class SshkeyExchange {
+
+    protected static final Logger log = getLogger(SshkeyExchange.class);
+    private static final String HOME_ENV = System.getProperty("user.home");
+    private static final String USER_ENV = System.getProperty("user.name");
+    private static final String PUBLIC_KEY = "/.ssh/id_rsa.pub";
+    private static final String PRIVATE_KEY = "/.ssh/id_rsa";
+    private static final String SFTP_CHANNEL = "sftp";
+    private static final String SSH_HOME = "/.ssh/";
+    private static final String SSH_AUTH_KEY = "/.ssh/authorized_keys";
+    private static final int SFTPPORT = 22;
+    private static final int DIR_PER = 448;
+    private static final int FILE_PER = 384;
+    private static final int KEY_SIZE = 2048;
+    private static final int DEFAULT_SESSION_TIMEOUT = 30000; // milliseconds
+
+    private Session getJschSession(String user, String host, String password) {
+        java.util.Properties config = new java.util.Properties();
+        config.put("StrictHostKeyChecking", "no");
+        Session session;
+        try {
+            session = new JSch().getSession(user, host, SFTPPORT);
+            session.setPassword(password);
+            session.setConfig(config);
+        } catch (JSchException e) {
+            log.error("Exception in getJschSession", e);
+            return null;
+        }
+
+        return session;
+    }
+
+    private boolean generateKeyPair() {
+        KeyPair kpair;
+        StringBuilder command = new StringBuilder()
+                .append("chmod 600 ")
+                .append(HOME_ENV)
+                .append(PRIVATE_KEY);
+        try {
+            kpair = KeyPair.genKeyPair(new JSch(), KeyPair.RSA, KEY_SIZE);
+            kpair.writePrivateKey(HOME_ENV + PRIVATE_KEY);
+            kpair.writePublicKey(HOME_ENV + PUBLIC_KEY, USER_ENV);
+            Runtime.getRuntime().exec(command.toString());
+            kpair.dispose();
+        } catch (JSchException | IOException e) {
+            log.error("Exception in generateKeyPair", e);
+            return false;
+        }
+        return true;
+    }
+
+    /**
+     * Exchanges SSH key.
+     * @param host SSH server host
+     * @param user user
+     * @param password password
+     * @return SSH key exchange success or not
+     */
+    public boolean sshAutoKeyExchange(IpAddress host, String user, String password) {
+
+        Session session = getJschSession(user, host.toString(), password);
+        boolean returnFlag;
+        File publickeyPath = new File(HOME_ENV + PUBLIC_KEY);
+        if (session == null) {
+            log.error("Error While establishing SFTP connection with {}", host.toString());
+            return false;
+        }
+        Channel channel;
+        String remoteHome;
+        ChannelSftp sftp;
+        FileInputStream fis = null;
+        SftpATTRS attrs = null;
+        try {
+            session.connect(DEFAULT_SESSION_TIMEOUT);
+            channel = session.openChannel(SFTP_CHANNEL);
+            if (channel == null) {
+                log.error("SFTP channel open failed for {}", host.toString());
+                return false;
+            }
+            channel.connect();
+            sftp = (ChannelSftp) channel;
+            remoteHome = sftp.getHome();
+            // checking key pair existance
+
+            if (!publickeyPath.exists()) {
+                File dirs = new File(HOME_ENV + SSH_HOME);
+                if (!dirs.exists() && !dirs.mkdirs()) {
+                    log.error("{} not exists and unable to create ", dirs.getPath());
+                    return false;
+                } else if (!generateKeyPair()) {
+                    log.error("SSH Key pair generation failed");
+                    return false;
+                }
+            }
+
+            // checking for authenticate_keys file existance
+            fis = new FileInputStream(publickeyPath);
+            try {
+                sftp.lstat(remoteHome + SSH_HOME);
+            } catch (SftpException e) {
+                sftp.mkdir(remoteHome + SSH_HOME);
+                sftp.chmod(700, remoteHome + SSH_HOME);
+            }
+            try {
+                attrs = sftp.lstat(remoteHome + SSH_AUTH_KEY);
+            } catch (SftpException e) {
+                log.info("authorized_keys file does not exist at remote device ,"
+                        + "a new file will be created");
+            }
+
+            if (attrs != null) {
+                sftp.get(remoteHome + SSH_AUTH_KEY, HOME_ENV + "/tempauthorized_keys");
+
+                String pubKey;
+                try (Stream<String> st = Files.lines(Paths.get(HOME_ENV + PUBLIC_KEY))) {
+                    pubKey = st.collect(Collectors.joining());
+                }
+
+                String authKey;
+                try (Stream<String> st = Files.lines(Paths.get(HOME_ENV + "/tempauthorized_keys"))) {
+                    authKey = st.collect(Collectors.joining());
+                }
+
+                if (authKey.contains(pubKey)) {
+                    log.info("Skipping key append to server as Key is already added");
+                } else {
+                    sftp.put(fis, remoteHome + SSH_AUTH_KEY, ChannelSftp.APPEND);
+                    log.info("Public key appended to server");
+                }
+            } else {
+
+                sftp.put(fis, remoteHome + SSH_AUTH_KEY, ChannelSftp.APPEND);
+                // Give proper permission to file and directory.
+                sftp.chmod(DIR_PER, remoteHome + SSH_HOME);
+                sftp.chmod(FILE_PER, remoteHome + SSH_AUTH_KEY);
+                log.info("Public key appended to server");
+            }
+
+            sftp.exit();
+            session.disconnect();
+            returnFlag = true;
+        } catch (JSchException | SftpException | IOException e) {
+            log.error("Exception occured because of {} ", e);
+            returnFlag = false;
+        } finally {
+            if (fis != null) {
+                try {
+                    fis.close();
+                } catch (IOException e) {
+                    log.info("Error closing public key file");
+                }
+            }
+        }
+        return returnFlag;
+
+    }
+}
diff --git a/apps/workflow/ofoverlay/app/src/main/java/org/onosproject/ofoverlay/impl/util/package-info.java b/apps/workflow/ofoverlay/app/src/main/java/org/onosproject/ofoverlay/impl/util/package-info.java
new file mode 100644
index 0000000..c76ba58
--- /dev/null
+++ b/apps/workflow/ofoverlay/app/src/main/java/org/onosproject/ofoverlay/impl/util/package-info.java
@@ -0,0 +1,20 @@
+/*
+ * Copyright 2019-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.
+ */
+
+/**
+ * Utility classes of ofoverlay.
+ */
+package org.onosproject.ofoverlay.impl.util;
\ No newline at end of file
diff --git a/apps/workflow/ofoverlay/test-cfg/empty.json b/apps/workflow/ofoverlay/test-cfg/empty.json
new file mode 100755
index 0000000..2691a31
--- /dev/null
+++ b/apps/workflow/ofoverlay/test-cfg/empty.json
@@ -0,0 +1,12 @@
+{
+    "apps": {
+        "org.onosproject.workflow": {
+          "workflow" : {
+            "rpc" : [
+            ]
+
+          }
+
+        }
+    }
+}
diff --git a/apps/workflow/ofoverlay/test-cfg/network-cfg-cr-wf.json b/apps/workflow/ofoverlay/test-cfg/network-cfg-cr-wf.json
new file mode 100755
index 0000000..19e2669
--- /dev/null
+++ b/apps/workflow/ofoverlay/test-cfg/network-cfg-cr-wf.json
@@ -0,0 +1,317 @@
+{
+    "apps": {
+        "org.onosproject.workflow": {
+          "workflow" : {
+            "rpc" : [
+              {
+                "op"   : "workflow.invoke",
+                "params" : {
+                  "workplace" : "Nova-000",
+                  "id"        : "of-overlay.workflow-nova",
+                  "data"      : {
+
+                    "mgmtIp" : "192.168.10.8",
+                    "ovsdbPort" : 6641,
+
+                    "sshAccessInfo" : {
+                      "remoteIp" : "192.168.10.8",
+                      "port"     : 22,
+                      "user"     : "root",
+                      "password" : "iloveyou",
+                      "keyfile"  : "~/.ssh/id_rsa"
+                    },
+
+                    "ovsDatapathType" : "system",
+                    "physicalPorts" : [ "nova0_1" ],
+                    "vtepIp" : "120.0.0.200/24",
+
+                    "annotations" : {
+                      "rackId" : 1,
+                      "rackPosition" : 3
+                    }
+
+                  }
+                },
+                "id" : "00001@10.0.0.1"
+              },
+              {
+                "op"   : "workflow.invoke",
+                "params" : {
+                  "workplace" : "Nova-001",
+                  "id"        : "of-overlay.workflow-nova",
+                  "data"      : {
+
+                    "mgmtIp" : "192.168.10.9",
+                    "ovsdbPort" : 6641,
+
+                    "sshAccessInfo" : {
+                      "remoteIp" : "192.168.10.9",
+                      "port"     : 22,
+                      "user"     : "root",
+                      "password" : "iloveyou",
+                      "keyfile"  : "~/.ssh/id_rsa"
+                    },
+
+                    "ovsDatapathType" : "system",
+                    "physicalPorts" : [ "nova1_1" ],
+                    "vtepIp" : "120.0.0.201/24",
+
+                    "annotations" : {
+                      "rackId" : 1,
+                      "rackPosition" : 3
+                    }
+
+                  }
+                },
+                "id" : "00001@10.0.0.1"
+              },
+              {
+                "op"   : "workflow.invoke",
+                "params" : {
+                  "workplace" : "Nova-002",
+                  "id"        : "of-overlay.workflow-nova",
+                  "data"      : {
+
+                    "mgmtIp" : "192.168.10.10",
+                    "ovsdbPort" : 6641,
+
+                    "sshAccessInfo" : {
+                      "remoteIp" : "192.168.10.10",
+                      "port"     : 22,
+                      "user"     : "root",
+                      "password" : "iloveyou",
+                      "keyfile"  : "~/.ssh/id_rsa"
+                    },
+
+                    "ovsDatapathType" : "system",
+                    "physicalPorts" : [ "nova2_1" ],
+                    "vtepIp" : "120.0.0.202/24",
+
+                    "annotations" : {
+                      "rackId" : 1,
+                      "rackPosition" : 3
+                    }
+
+                  }
+                },
+                "id" : "00001@10.0.0.1"
+              },
+              {
+                "op"   : "workflow.invoke",
+                "params" : {
+                  "workplace" : "Nova-003",
+                  "id"        : "of-overlay.workflow-nova",
+                  "data"      : {
+
+                    "mgmtIp" : "192.168.10.11",
+                    "ovsdbPort" : 6641,
+
+                    "sshAccessInfo" : {
+                      "remoteIp" : "192.168.10.11",
+                      "port"     : 22,
+                      "user"     : "root",
+                      "password" : "iloveyou",
+                      "keyfile"  : "~/.ssh/id_rsa"
+                    },
+
+                    "ovsDatapathType" : "system",
+                    "physicalPorts" : [ "nova3_1" ],
+                    "vtepIp" : "120.0.0.203/24",
+
+                    "annotations" : {
+                      "rackId" : 1,
+                      "rackPosition" : 3
+                    }
+
+                  }
+                },
+                "id" : "00001@10.0.0.1"
+              },
+
+              {
+                "op"   : "workflow.invoke",
+                "params" : {
+                  "workplace" : "Leaf-000",
+                  "id"        : "of-overlay.workflow-ovs-leaf",
+                  "data"      : {
+
+                    "mgmtIp" : "192.168.10.4",
+                    "ovsdbPort" : 6641,
+
+                    "sshAccessInfo" : {
+                      "remoteIp" : "192.168.10.4",
+                      "port"     : 22,
+                      "user"     : "root",
+                      "password" : "iloveyou",
+                      "keyfile"  : "~/.ssh/id_rsa"
+                    },
+
+                    "ovsDatapathType" : "system",
+                    "physicalPorts" : [ "leaf0_0", "leaf0_1", "leaf0_nova00" ],
+
+                    "annotations" : {
+                      "rackId" : 1,
+                      "rackPosition" : 3
+                    }
+
+                  }
+                },
+                "id" : "00001@10.0.0.1"
+              },
+              {
+                "op"   : "workflow.invoke",
+                "params" : {
+                  "workplace" : "Leaf-001",
+                  "id"        : "of-overlay.workflow-ovs-leaf",
+                  "data"      : {
+
+                    "mgmtIp" : "192.168.10.5",
+                    "ovsdbPort" : 6641,
+
+                    "sshAccessInfo" : {
+                      "remoteIp" : "192.168.10.5",
+                      "port"     : 22,
+                      "user"     : "root",
+                      "password" : "iloveyou",
+                      "keyfile"  : "~/.ssh/id_rsa"
+                    },
+
+                    "ovsDatapathType" : "system",
+                    "physicalPorts" : [ "leaf1_0", "leaf1_1", "leaf1_nova10" ],
+
+                    "annotations" : {
+                      "rackId" : 1,
+                      "rackPosition" : 3
+                    }
+
+                  }
+                },
+                "id" : "00001@10.0.0.1"
+              },
+              {
+                "op"   : "workflow.invoke",
+                "params" : {
+                  "workplace" : "Leaf-002",
+                  "id"        : "of-overlay.workflow-ovs-leaf",
+                  "data"      : {
+
+                    "mgmtIp" : "192.168.10.6",
+                    "ovsdbPort" : 6641,
+
+                    "sshAccessInfo" : {
+                      "remoteIp" : "192.168.10.6",
+                      "port"     : 22,
+                      "user"     : "root",
+                      "password" : "iloveyou",
+                      "keyfile"  : "~/.ssh/id_rsa"
+                    },
+
+                    "ovsDatapathType" : "system",
+                    "physicalPorts" : [ "leaf2_0", "leaf2_1", "leaf2_nova20" ],
+
+                    "annotations" : {
+                      "rackId" : 1,
+                      "rackPosition" : 3
+                    }
+
+                  }
+                },
+                "id" : "00001@10.0.0.1"
+              },
+
+              {
+                "op"   : "workflow.invoke",
+                "params" : {
+                  "workplace" : "Leaf-003",
+                  "id"        : "of-overlay.workflow-ovs-leaf",
+                  "data"      : {
+
+                    "mgmtIp" : "192.168.10.7",
+                    "ovsdbPort" : 6641,
+
+                    "sshAccessInfo" : {
+                      "remoteIp" : "192.168.10.7",
+                      "port"     : 22,
+                      "user"     : "root",
+                      "password" : "iloveyou",
+                      "keyfile"  : "~/.ssh/id_rsa"
+                    },
+
+                    "ovsDatapathType" : "system",
+                    "physicalPorts" : [ "leaf3_0", "leaf3_1", "leaf3_nova30" ],
+
+                    "annotations" : {
+                      "rackId" : 1,
+                      "rackPosition" : 3
+                    }
+
+                  }
+                },
+                "id" : "00001@10.0.0.1"
+              },
+              {
+                "op"   : "workflow.invoke",
+                "params" : {
+                  "workplace" : "Spine-000",
+                  "id"        : "of-overlay.workflow-ovs-spine",
+                  "data"      : {
+
+                    "mgmtIp" : "192.168.10.2",
+                    "ovsdbPort" : 6641,
+
+                    "sshAccessInfo" : {
+                      "remoteIp" : "192.168.10.2",
+                      "port"     : 22,
+                      "user"     : "root",
+                      "password" : "iloveyou",
+                      "keyfile"  : "~/.ssh/id_rsa"
+                    },
+
+                    "ovsDatapathType" : "system",
+                    "physicalPorts" : [ "spine0_0", "spine0_1", "spine0_2", "spine0_3" ],
+
+                    "annotations" : {
+                      "rackId" : 1,
+                      "rackPosition" : 3
+                    }
+
+                  }
+                },
+                "id" : "00001@10.0.0.1"
+              },
+              {
+                "op"   : "workflow.invoke",
+                "params" : {
+                  "workplace" : "Spine-001",
+                  "id"        : "of-overlay.workflow-ovs-spine",
+                  "data"      : {
+
+                    "mgmtIp" : "192.168.10.3",
+                    "ovsdbPort" : 6641,
+
+                    "sshAccessInfo" : {
+                      "remoteIp" : "192.168.10.3",
+                      "port"     : 22,
+                      "user"     : "root",
+                      "password" : "iloveyou",
+                      "keyfile"  : "~/.ssh/id_rsa"
+                    },
+
+                    "ovsDatapathType" : "system",
+                    "physicalPorts" : [ "spine1_0", "spine1_1", "spine1_2", "spine1_3" ],
+
+                    "annotations" : {
+                      "rackId" : 1,
+                      "rackPosition" : 3
+                    }
+
+                  }
+                },
+                "id" : "00001@10.0.0.1"
+              }
+
+            ]
+          }
+        }
+    }
+}
diff --git a/apps/workflow/ofoverlay/test-cfg/network-cfg-rm-wf.json b/apps/workflow/ofoverlay/test-cfg/network-cfg-rm-wf.json
new file mode 100755
index 0000000..be554a9
--- /dev/null
+++ b/apps/workflow/ofoverlay/test-cfg/network-cfg-rm-wf.json
@@ -0,0 +1,98 @@
+{
+    "apps": {
+        "org.onosproject.workflow": {
+          "workflow" : {
+            "rpc" : [
+              {
+                "op"   : "workflow.invoke",
+                "params" : {
+                  "workplace" : "Nova-000",
+                  "id"        : "of-overlay.clean-workflow-nova",
+                  "data"      : {
+
+                    "mgmtIp" : "192.168.10.8",
+                    "ovsdbPort" : 6641,
+
+                    "sshAccessInfo" : {
+                      "remoteIp" : "192.168.10.8",
+                      "port"     : 22,
+                      "user"     : "root",
+                      "password" : "iloveyou",
+                      "keyfile"  : "~/.ssh/id_rsa"
+                    }
+                  }
+                },
+                "id" : "00001@10.0.0.1"
+              },
+              {
+                "op"   : "workflow.invoke",
+                "params" : {
+                  "workplace" : "Nova-001",
+                  "id"        : "of-overlay.clean-workflow-nova",
+                  "data"      : {
+
+                    "mgmtIp" : "192.168.10.9",
+                    "ovsdbPort" : 6641,
+
+                    "sshAccessInfo" : {
+                      "remoteIp" : "192.168.10.9",
+                      "port"     : 22,
+                      "user"     : "root",
+                      "password" : "iloveyou",
+                      "keyfile"  : "~/.ssh/id_rsa"
+                    }
+                  }
+                },
+                "id" : "00001@10.0.0.1"
+              },
+              {
+                "op"   : "workflow.invoke",
+                "params" : {
+                  "workplace" : "Nova-002",
+                  "id"        : "of-overlay.clean-workflow-nova",
+                  "data"      : {
+
+                    "mgmtIp" : "192.168.10.10",
+                    "ovsdbPort" : 6641,
+
+                    "sshAccessInfo" : {
+                      "remoteIp" : "192.168.10.10",
+                      "port"     : 22,
+                      "user"     : "root",
+                      "password" : "iloveyou",
+                      "keyfile"  : "~/.ssh/id_rsa"
+                    }
+                  }
+                },
+                "id" : "00001@10.0.0.1"
+              },
+              {
+                "op"   : "workflow.invoke",
+                "params" : {
+                  "workplace" : "Nova-003",
+                  "id"        : "of-overlay.clean-workflow-nova",
+                  "data"      : {
+
+                    "mgmtIp" : "192.168.10.11",
+                    "ovsdbPort" : 6641,
+
+                    "sshAccessInfo" : {
+                      "remoteIp" : "192.168.10.11",
+                      "port"     : 22,
+                      "user"     : "root",
+                      "password" : "iloveyou",
+                      "keyfile"  : "~/.ssh/id_rsa"
+                    }
+                  }
+                },
+                "id" : "00001@10.0.0.1"
+              }
+
+
+            ]
+
+          }
+
+        }
+    }
+}
