diff --git a/apps/workflow/ofoverlay/app/BUCK b/apps/workflow/ofoverlay/app/BUCK
new file mode 100644
index 0000000..ba31441d
--- /dev/null
+++ b/apps/workflow/ofoverlay/app/BUCK
@@ -0,0 +1,20 @@
+COMPILE_DEPS = [
+    '//lib:CORE_DEPS',
+    '//lib:KRYO',
+    '//lib:jsch',
+    '//lib:org.apache.karaf.shell.console',
+    '//lib:jackson-core',
+    '//lib:jackson-annotations',
+    '//lib:jackson-databind',
+    '//cli:onos-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',
+    '//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/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..8ba91be
--- /dev/null
+++ b/apps/workflow/ofoverlay/app/src/main/java/org/onosproject/ofoverlay/impl/OfOverlayWorkflow.java
@@ -0,0 +1,184 @@
+/*
+ * 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.apache.felix.scr.annotations.Activate;
+import org.apache.felix.scr.annotations.Component;
+import org.apache.felix.scr.annotations.Deactivate;
+import org.apache.felix.scr.annotations.Reference;
+import org.apache.felix.scr.annotations.ReferenceCardinality;
+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.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_UNARY)
+    protected WorkflowStore workflowStore;
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected WorkplaceStore workplaceStore;
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected WorkflowExecutionService workflowExecutionService;
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    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);
+
+        // registering new workflow definition based on multi-event handling
+        uri = URI.create("of-overlay.workflow-nova-multiEvent-test");
+        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.CreateOverlayBridgeMultiEvent.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.clean-workflow-nova-waitAll-Bridge-Del");
+        workflow = ImmutableListWorkflow.builder()
+                .id(uri)
+                //.attribute(WorkflowAttribute.REMOVE_AFTER_COMPLETE)
+                .chain(Ovs.DeleteOverlayBridgeConfig.class.getName())
+                .chain(Ovs.DeleteUnderlayBridgeConfig.class.getName())
+                .chain(Ovs.RemoveBridgeOfDevice.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..ad56d52
--- /dev/null
+++ b/apps/workflow/ofoverlay/app/src/main/java/org/onosproject/ofoverlay/impl/Ovs.java
@@ -0,0 +1,1418 @@
+/*
+ * 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.JsonNodeFactory;
+import com.fasterxml.jackson.databind.node.ObjectNode;
+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.Set;
+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_OF_DEVID_FOR_OVERLAY_UNDERLAY_BRIDGE = "/ofDevIdBrIntBrPhy";
+    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 creating overlay openflow bridge.
+     */
+    public static class CreateOverlayBridgeMultiEvent 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()) {
+
+                Set<String> eventHints = Sets.newHashSet(ofDeviceId.toString());
+
+                context.waitAnyCompletion(DeviceEvent.class, eventHints,
+                        () -> 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.
+                Set<String> eventHints = Sets.newHashSet(ofDeviceId.toString());
+
+                context.waitAnyCompletion(DeviceEvent.class, eventHints,
+                                       () -> 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, optional = true)
+        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);
+            }
+        }
+    }
+
+    /**
+     * Work-let class for removing underlay bridge and overlay openflow device.
+     */
+    public static class RemoveBridgeOfDevice extends AbstractWorklet {
+
+        @JsonDataModel(path = MODEL_MGMT_IP)
+        String strMgmtIp;
+
+        @JsonDataModel(path = MODEL_OF_DEVID_FOR_OVERLAY_UNDERLAY_BRIDGE, optional = true)
+        ObjectNode ofDevId;
+
+        @Override
+        public boolean isNext(WorkflowContext context) throws WorkflowException {
+
+            boolean isOfDevicePresent = true;
+
+            if (ofDevId == null) {
+                ofDevId = JsonNodeFactory.instance.objectNode();
+                ofDevId.put(String.valueOf(DEVID_IDX_BRIDGE_OVERLAY), OvsUtil.buildOfDeviceId(
+                        IpAddress.valueOf(strMgmtIp), DEVID_IDX_BRIDGE_OVERLAY).toString());
+                ofDevId.put(String.valueOf(DEVID_IDX_BRIDGE_UNDERLAY_NOVA), OvsUtil.buildOfDeviceId(
+                        IpAddress.valueOf(strMgmtIp), DEVID_IDX_BRIDGE_UNDERLAY_NOVA).toString());
+            }
+
+            if (context.getService(DeviceService.class).
+                    getDevice(DeviceId.deviceId(
+                            ofDevId.get(String.valueOf(DEVID_IDX_BRIDGE_OVERLAY)).asText())) == null) {
+                isOfDevicePresent = false;
+            }
+            if (context.getService(DeviceService.class).
+                    getDevice(DeviceId.deviceId(
+                            ofDevId.get(String.valueOf(DEVID_IDX_BRIDGE_UNDERLAY_NOVA)).asText())) == null) {
+                isOfDevicePresent = false;
+            }
+
+            return isOfDevicePresent;
+        }
+
+        @Override
+        public void process(WorkflowContext context) throws WorkflowException {
+
+            DeviceAdminService adminService = context.getService(DeviceAdminService.class);
+            String ofDevIdOverlay;
+            String ofDevIdUnderlay;
+
+            if (ofDevId == null) {
+                ofDevId = JsonNodeFactory.instance.objectNode();
+                ofDevId.put(String.valueOf(DEVID_IDX_BRIDGE_OVERLAY), OvsUtil.buildOfDeviceId(
+                        IpAddress.valueOf(strMgmtIp), DEVID_IDX_BRIDGE_OVERLAY).toString());
+                ofDevId.put(String.valueOf(DEVID_IDX_BRIDGE_UNDERLAY_NOVA), OvsUtil.buildOfDeviceId(
+                        IpAddress.valueOf(strMgmtIp), DEVID_IDX_BRIDGE_UNDERLAY_NOVA).toString());
+            }
+
+            ofDevIdOverlay = ofDevId.get(String.valueOf(DEVID_IDX_BRIDGE_OVERLAY)).asText();
+            ofDevIdUnderlay = ofDevId.get(String.valueOf(DEVID_IDX_BRIDGE_UNDERLAY_NOVA)).asText();
+
+            Set<String> eventHints = Sets.newHashSet(ofDevIdOverlay, ofDevIdUnderlay);
+
+            context.waitAnyCompletion(DeviceEvent.class, eventHints,
+                                      () -> {
+                                                adminService.removeDevice(DeviceId.deviceId(ofDevIdOverlay));
+                                                adminService.removeDevice(DeviceId.deviceId(ofDevIdUnderlay));
+                                            },
+                                   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:
+                    log.trace("GOT DEVICE REMOVED EVENT FOR DEVICE {}", event.subject());
+                    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
