Supports dpdk-based vm creation in OpenstackNetworking service.

Change-Id: I39c30cde5b455952a4c7ed0147903324c6598880
diff --git a/apps/openstacknetworking/api/src/main/java/org/onosproject/openstacknetworking/api/Constants.java b/apps/openstacknetworking/api/src/main/java/org/onosproject/openstacknetworking/api/Constants.java
index d890e5c..e966db1 100644
--- a/apps/openstacknetworking/api/src/main/java/org/onosproject/openstacknetworking/api/Constants.java
+++ b/apps/openstacknetworking/api/src/main/java/org/onosproject/openstacknetworking/api/Constants.java
@@ -28,6 +28,17 @@
     private Constants() {
     }
 
+    /**
+     * List of valid openstack port types.
+     */
+    public enum VnicType {
+        NORMAL,
+        DIRECT,
+        UNSUPPORTED
+    }
+    public static final String PORT_NAME_PREFIX_VM = "tap";
+    public static final String PORT_NAME_VHOST_USER_PREFIX_VM = "vhu";
+
     public static final String OPENSTACK_NETWORKING_APP_ID = "org.onosproject.openstacknetworking";
 
     public static final String ARP_BROADCAST_MODE = "broadcast";
diff --git a/apps/openstacknetworking/app/src/main/java/org/onosproject/openstacknetworking/impl/OpenstackNetworkManager.java b/apps/openstacknetworking/app/src/main/java/org/onosproject/openstacknetworking/impl/OpenstackNetworkManager.java
index 2418745..92257fd 100644
--- a/apps/openstacknetworking/app/src/main/java/org/onosproject/openstacknetworking/impl/OpenstackNetworkManager.java
+++ b/apps/openstacknetworking/app/src/main/java/org/onosproject/openstacknetworking/impl/OpenstackNetworkManager.java
@@ -75,8 +75,8 @@
 import static org.onosproject.net.AnnotationKeys.PORT_NAME;
 import static org.onosproject.openstacknetworking.api.Constants.DIRECT;
 import static org.onosproject.openstacknetworking.api.Constants.PCISLOT;
-import static org.onosproject.openstacknetworking.api.Constants.portNamePrefixMap;
 import static org.onosproject.openstacknetworking.util.OpenstackNetworkingUtil.getIntfNameFromPciAddress;
+import static org.onosproject.openstacknetworking.util.OpenstackNetworkingUtil.vnicType;
 import static org.slf4j.LoggerFactory.getLogger;
 
 /**
@@ -113,7 +113,6 @@
     private static final String ERR_NOT_FOUND = " does not exist";
     private static final String ERR_IN_USE = " still in use";
     private static final String ERR_DUPLICATE = " already exists";
-    private static final String PORT_NAME_PREFIX_VM = "tap";
 
     private static final int PREFIX_LENGTH = 32;
 
@@ -325,29 +324,34 @@
             return null;
         }
 
-        if (port.annotations().value(PORT_NAME).startsWith(PORT_NAME_PREFIX_VM)) {
-            Optional<Port> osPort = osNetworkStore.ports()
-                    .stream()
-                    .filter(p -> p.getId().contains(portName.substring(3)))
-                    .findFirst();
-            return osPort.orElse(null);
-        } else if (isDirectPort(portName)) {
-            //Additional prefixes will be added
-            Optional<Port> osPort = osNetworkStore.ports()
-                    .stream()
-                    .filter(p -> p.getvNicType().equals(DIRECT) && p.getProfile().get(PCISLOT) != null)
-                    .filter(p -> getIntfNameFromPciAddress(p).equals(portName))
-                    .findFirst();
-            return osPort.orElse(null);
-        } else {
+        try {
+            Optional<Port> osPort;
+            switch (vnicType(portName)) {
+                case NORMAL:
+                    osPort = osNetworkStore.ports()
+                            .stream()
+                            .filter(p -> p.getId().contains(portName.substring(3)))
+                            .findFirst();
+                    return osPort.orElse(null);
+
+                case DIRECT:
+                    //Additional prefixes will be added
+                    osPort = osNetworkStore.ports()
+                            .stream()
+                            .filter(p -> p.getvNicType().equals(DIRECT) && p.getProfile().get(PCISLOT) != null)
+                            .filter(p -> getIntfNameFromPciAddress(p).equals(portName))
+                            .findFirst();
+                    return osPort.orElse(null);
+
+                default:
+                    return null;
+            }
+        } catch (IllegalArgumentException e) {
+            log.error("IllegalArgumentException occurred because of {}", e);
             return null;
         }
     }
 
-    private boolean isDirectPort(String portName) {
-        return portNamePrefixMap().values().stream().filter(p -> portName.startsWith(p)).findAny().isPresent();
-    }
-
     @Override
     public Set<Port> ports() {
         return ImmutableSet.copyOf(osNetworkStore.ports());
diff --git a/apps/openstacknetworking/app/src/main/java/org/onosproject/openstacknetworking/impl/OpenstackSwitchingHostProvider.java b/apps/openstacknetworking/app/src/main/java/org/onosproject/openstacknetworking/impl/OpenstackSwitchingHostProvider.java
index 01e1099..40413d7 100644
--- a/apps/openstacknetworking/app/src/main/java/org/onosproject/openstacknetworking/impl/OpenstackSwitchingHostProvider.java
+++ b/apps/openstacknetworking/app/src/main/java/org/onosproject/openstacknetworking/impl/OpenstackSwitchingHostProvider.java
@@ -46,6 +46,7 @@
 import org.onosproject.net.host.HostService;
 import org.onosproject.net.provider.AbstractProvider;
 import org.onosproject.net.provider.ProviderId;
+import org.onosproject.openstacknetworking.api.Constants;
 import org.onosproject.openstacknetworking.api.OpenstackNetworkService;
 import org.onosproject.openstacknode.api.OpenstackNode;
 import org.onosproject.openstacknode.api.OpenstackNodeEvent;
@@ -69,7 +70,10 @@
 import static org.onosproject.openstacknetworking.api.Constants.ANNOTATION_PORT_ID;
 import static org.onosproject.openstacknetworking.api.Constants.ANNOTATION_SEGMENT_ID;
 import static org.onosproject.openstacknetworking.api.Constants.OPENSTACK_NETWORKING_APP_ID;
+import static org.onosproject.openstacknetworking.api.Constants.PORT_NAME_PREFIX_VM;
+import static org.onosproject.openstacknetworking.api.Constants.PORT_NAME_VHOST_USER_PREFIX_VM;
 import static org.onosproject.openstacknetworking.api.Constants.portNamePrefixMap;
+import static org.onosproject.openstacknetworking.util.OpenstackNetworkingUtil.vnicType;
 import static org.onosproject.openstacknode.api.OpenstackNode.NodeType.CONTROLLER;
 
 @Service
@@ -79,7 +83,6 @@
 
     private final Logger log = LoggerFactory.getLogger(getClass());
 
-    private static final String PORT_NAME_PREFIX_VM = "tap";
     private static final String ERR_ADD_HOST = "Failed to add host: ";
     private static final String SONA_HOST_SCHEME = "sona";
 
@@ -315,7 +318,9 @@
             String portName = port.annotations().value(PORT_NAME);
 
             return !Strings.isNullOrEmpty(portName) &&
-                    (portName.startsWith(PORT_NAME_PREFIX_VM) || isDirectPort(portName));
+                    (portName.startsWith(PORT_NAME_PREFIX_VM) ||
+                            isDirectPort(portName) ||
+                            portName.startsWith(PORT_NAME_VHOST_USER_PREFIX_VM));
         }
 
         private boolean isDirectPort(String portName) {
@@ -385,9 +390,9 @@
 
         private void processCompleteNode(OpenstackNode osNode) {
             deviceService.getPorts(osNode.intgBridge()).stream()
-                    .filter(port -> port.annotations().value(PORT_NAME)
-                            .startsWith(PORT_NAME_PREFIX_VM) &&
-                            port.isEnabled())
+                    .filter(port -> vnicType(port.annotations().value(PORT_NAME)).equals(Constants.VnicType.NORMAL) ||
+                            vnicType(port.annotations().value(PORT_NAME)).equals(Constants.VnicType.DIRECT))
+                    .filter(Port::isEnabled)
                     .forEach(port -> {
                         log.debug("Instance port {} is detected from {}",
                                 port.annotations().value(PORT_NAME),
@@ -395,18 +400,6 @@
                         processPortAdded(port);
                     });
 
-            portNamePrefixMap().values().forEach(portNamePrefix ->
-                    deviceService.getPorts(osNode.intgBridge()).stream()
-                    .filter(port -> port.annotations().value(PORT_NAME)
-                            .startsWith(portNamePrefix) &&
-                            port.isEnabled())
-                    .forEach(port -> {
-                        log.debug("Instance port {} is detected from {}",
-                                port.annotations().value(portNamePrefix),
-                                osNode.hostname());
-                        processPortAdded(port);
-                    }));
-
             Tools.stream(hostService.getHosts())
                     .filter(host -> deviceService.getPort(
                             host.location().deviceId(),
diff --git a/apps/openstacknetworking/app/src/main/java/org/onosproject/openstacknetworking/util/OpenstackNetworkingUtil.java b/apps/openstacknetworking/app/src/main/java/org/onosproject/openstacknetworking/util/OpenstackNetworkingUtil.java
index ca9647f..32f4fdf 100644
--- a/apps/openstacknetworking/app/src/main/java/org/onosproject/openstacknetworking/util/OpenstackNetworkingUtil.java
+++ b/apps/openstacknetworking/app/src/main/java/org/onosproject/openstacknetworking/util/OpenstackNetworkingUtil.java
@@ -25,6 +25,7 @@
 import org.onosproject.cfg.ConfigProperty;
 import org.onosproject.net.DeviceId;
 import org.onosproject.net.device.DeviceService;
+import org.onosproject.openstacknetworking.api.Constants.VnicType;
 import org.onosproject.openstacknetworking.api.InstancePort;
 import org.onosproject.openstacknetworking.api.OpenstackNetworkService;
 import org.onosproject.openstacknetworking.api.OpenstackRouterAdminService;
@@ -71,6 +72,8 @@
 import static org.onosproject.net.AnnotationKeys.PORT_NAME;
 import static org.onosproject.openstacknetworking.api.Constants.PCISLOT;
 import static org.onosproject.openstacknetworking.api.Constants.PCI_VENDOR_INFO;
+import static org.onosproject.openstacknetworking.api.Constants.PORT_NAME_PREFIX_VM;
+import static org.onosproject.openstacknetworking.api.Constants.PORT_NAME_VHOST_USER_PREFIX_VM;
 import static org.onosproject.openstacknetworking.api.Constants.portNamePrefixMap;
 import static org.openstack4j.core.transport.ObjectMapperSingleton.getContext;
 
@@ -467,6 +470,21 @@
                 Objects.equals(routerInterface1.getTenantId(), routerInterface2.getTenantId());
     }
 
+    public static VnicType vnicType(String portName) {
+        if (portName.startsWith(PORT_NAME_PREFIX_VM) ||
+                portName.startsWith(PORT_NAME_VHOST_USER_PREFIX_VM)) {
+            return VnicType.NORMAL;
+        } else if (isDirectPort(portName)) {
+            return VnicType.DIRECT;
+        } else {
+            return VnicType.UNSUPPORTED;
+        }
+    }
+
+    private static boolean isDirectPort(String portName) {
+        return portNamePrefixMap().values().stream().filter(p -> portName.startsWith(p)).findAny().isPresent();
+    }
+
     /**
      * Builds up and a complete endpoint URL from gateway node.
      *
diff --git a/apps/openstacknetworking/app/src/main/java/org/onosproject/openstacknetworking/web/OpenstackPortWebResource.java b/apps/openstacknetworking/app/src/main/java/org/onosproject/openstacknetworking/web/OpenstackPortWebResource.java
index 94c30e7..d5b2e2d 100644
--- a/apps/openstacknetworking/app/src/main/java/org/onosproject/openstacknetworking/web/OpenstackPortWebResource.java
+++ b/apps/openstacknetworking/app/src/main/java/org/onosproject/openstacknetworking/web/OpenstackPortWebResource.java
@@ -15,7 +15,11 @@
  */
 package org.onosproject.openstacknetworking.web;
 
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.fasterxml.jackson.databind.node.ObjectNode;
 import org.onosproject.openstacknetworking.api.OpenstackNetworkAdminService;
+import org.onosproject.openstacknode.api.OpenstackNode;
+import org.onosproject.openstacknode.api.OpenstackNodeService;
 import org.onosproject.rest.AbstractWebResource;
 import org.openstack4j.openstack.networking.domain.NeutronPort;
 import org.slf4j.Logger;
@@ -49,9 +53,12 @@
 
     private static final String MESSAGE = "Received ports %s request";
     private static final String PORTS = "ports";
+    private static final String VIF_TYPE = "vif_type";
+    private static final String VHOSTUSER = "vhostuser";
+    private static final String SOCKET_DIR = "socket_dir";
 
-    private final OpenstackNetworkAdminService adminService =
-                                        get(OpenstackNetworkAdminService.class);
+    private final OpenstackNetworkAdminService adminService = get(OpenstackNetworkAdminService.class);
+    private final OpenstackNodeService nodeService = get(OpenstackNodeService.class);
 
     @Context
     private UriInfo uriInfo;
@@ -101,8 +108,25 @@
                                  jsonToModelEntity(input, NeutronPort.class);
 
         adminService.updatePort(port);
+        ObjectMapper mapper = new ObjectMapper();
+        ObjectNode jsonNode = mapper.createObjectNode();
 
-        return status(Response.Status.OK).build();
+        OpenstackNode node = nodeService.node(port.getHostId());
+        if (node == null) {
+            return status(Response.Status.OK).build();
+        } else if (node.datapathType().equals(OpenstackNode.DatapathType.NETDEV)) {
+            log.debug("UpdatePort for port {} called in netdev device {} " +
+                            "so sends vif type as a payload of the response",
+                    port.getId(), node.hostname());
+            jsonNode.put(VIF_TYPE, VHOSTUSER);
+
+            if (node.socketDir() != null) {
+                jsonNode.put(SOCKET_DIR, node.socketDir());
+            }
+            return status(Response.Status.OK).entity(jsonNode.toString()).build();
+        } else {
+            return status(Response.Status.OK).build();
+        }
     }
 
     /**
diff --git a/apps/openstacknetworking/app/src/test/java/org/onosproject/openstacknetworking/util/OpenstackNetworkingUtilTest.java b/apps/openstacknetworking/app/src/test/java/org/onosproject/openstacknetworking/util/OpenstackNetworkingUtilTest.java
index 0e291f8..daf0a9a 100644
--- a/apps/openstacknetworking/app/src/test/java/org/onosproject/openstacknetworking/util/OpenstackNetworkingUtilTest.java
+++ b/apps/openstacknetworking/app/src/test/java/org/onosproject/openstacknetworking/util/OpenstackNetworkingUtilTest.java
@@ -36,6 +36,7 @@
 import org.onosproject.net.PortNumber;
 import org.onosproject.net.device.DeviceService;
 import org.onosproject.net.device.DeviceServiceAdapter;
+import org.onosproject.openstacknetworking.api.Constants;
 import org.onosproject.openstacknetworking.api.InstancePort;
 import org.onosproject.openstacknetworking.api.OpenstackNetworkService;
 import org.onosproject.openstacknetworking.api.OpenstackRouterAdminService;
@@ -84,6 +85,7 @@
 import static org.onosproject.openstacknetworking.util.OpenstackNetworkingUtil.prettyJson;
 import static org.onosproject.openstacknetworking.util.OpenstackNetworkingUtil.routerInterfacesEquals;
 import static org.onosproject.openstacknetworking.util.OpenstackNetworkingUtil.swapStaleLocation;
+import static org.onosproject.openstacknetworking.util.OpenstackNetworkingUtil.vnicType;
 
 public final class OpenstackNetworkingUtilTest {
 
@@ -438,6 +440,22 @@
 
     }
 
+    /**
+     * Tests the vnicType method.
+     */
+    @Test
+    public void testVnicType() {
+        String portNameNormalTap = "tap123456789ab";
+        String portNameNormalVhu = "tap123456789ab";
+        String portNameNormalCavium = "enp1f2s3";
+        String portNameUnsupported = "123456789ab";
+
+        assertEquals(vnicType(portNameNormalTap), Constants.VnicType.NORMAL);
+        assertEquals(vnicType(portNameNormalVhu), Constants.VnicType.NORMAL);
+        assertEquals(vnicType(portNameNormalCavium), Constants.VnicType.DIRECT);
+        assertEquals(vnicType(portNameUnsupported), Constants.VnicType.UNSUPPORTED);
+    }
+
     private DeviceId genDeviceId(int index) {
         return DeviceId.deviceId("of:compute-" + index);
     }
diff --git a/apps/openstacknetworking/app/src/test/java/org/onosproject/openstacknetworking/web/OpenstackPortWebResourceTest.java b/apps/openstacknetworking/app/src/test/java/org/onosproject/openstacknetworking/web/OpenstackPortWebResourceTest.java
index e3f4bf0..7d7a603 100644
--- a/apps/openstacknetworking/app/src/test/java/org/onosproject/openstacknetworking/web/OpenstackPortWebResourceTest.java
+++ b/apps/openstacknetworking/app/src/test/java/org/onosproject/openstacknetworking/web/OpenstackPortWebResourceTest.java
@@ -21,6 +21,7 @@
 import org.onlab.osgi.ServiceDirectory;
 import org.onlab.osgi.TestServiceDirectory;
 import org.onosproject.openstacknetworking.api.OpenstackNetworkAdminService;
+import org.onosproject.openstacknode.api.OpenstackNodeService;
 import org.onosproject.rest.resources.ResourceTest;
 
 import javax.ws.rs.client.Entity;
@@ -45,6 +46,8 @@
 
     final OpenstackNetworkAdminService mockOpenstackNetworkAdminService =
             createMock(OpenstackNetworkAdminService.class);
+    final OpenstackNodeService mockOpenstackNodeService =
+            createMock(OpenstackNodeService.class);
     private static final String PATH = "ports";
 
     /**
@@ -59,10 +62,9 @@
      */
     @Before
     public void setUpTest() {
-        ServiceDirectory testDirectory =
-                new TestServiceDirectory()
-                        .add(OpenstackNetworkAdminService.class,
-                                mockOpenstackNetworkAdminService);
+        ServiceDirectory testDirectory = new TestServiceDirectory()
+                .add(OpenstackNetworkAdminService.class, mockOpenstackNetworkAdminService)
+                .add(OpenstackNodeService.class, mockOpenstackNodeService);
         setServiceDirectory(testDirectory);
 
     }
diff --git a/apps/openstacknode/api/src/main/java/org/onosproject/openstacknode/api/DefaultOpenstackNode.java b/apps/openstacknode/api/src/main/java/org/onosproject/openstacknode/api/DefaultOpenstackNode.java
index 43a4535..e45d61b 100644
--- a/apps/openstacknode/api/src/main/java/org/onosproject/openstacknode/api/DefaultOpenstackNode.java
+++ b/apps/openstacknode/api/src/main/java/org/onosproject/openstacknode/api/DefaultOpenstackNode.java
@@ -59,6 +59,7 @@
     private final String endpoint;
     private final OpenstackSshAuth sshAuth;
     private final DatapathType datapathType;
+    private final String socketDir;
 
     private static final String NOT_NULL_MSG = "Node % cannot be null";
 
@@ -81,6 +82,7 @@
      * @param endpoint      openstack endpoint URL
      * @param sshAuth       ssh authentication info
      * @param datapathType  data path type
+     * @param socketDir     socket directory
      */
     protected DefaultOpenstackNode(String hostname, NodeType type,
                                    DeviceId intgBridge,
@@ -94,7 +96,8 @@
                                    OpenstackAuth auth,
                                    String endpoint,
                                    OpenstackSshAuth sshAuth,
-                                   DatapathType datapathType) {
+                                   DatapathType datapathType,
+                                   String socketDir) {
         this.hostname = hostname;
         this.type = type;
         this.intgBridge = intgBridge;
@@ -109,6 +112,7 @@
         this.endpoint = endpoint;
         this.sshAuth = sshAuth;
         this.datapathType = datapathType;
+        this.socketDir = socketDir;
     }
 
     @Override
@@ -157,6 +161,11 @@
     }
 
     @Override
+    public String socketDir() {
+        return socketDir;
+    }
+
+    @Override
     public NodeState state() {
         return state;
     }
@@ -257,7 +266,8 @@
                     Objects.equals(auth, that.auth) &&
                     Objects.equals(endpoint, that.endpoint) &&
                     Objects.equals(sshAuth, that.sshAuth) &&
-                    Objects.equals(datapathType, that.datapathType);
+                    Objects.equals(datapathType, that.datapathType) &&
+                    Objects.equals(socketDir, that.socketDir);
         }
         return false;
     }
@@ -276,7 +286,8 @@
                 auth,
                 endpoint,
                 sshAuth,
-                datapathType);
+                datapathType,
+                socketDir);
     }
 
     @Override
@@ -296,6 +307,7 @@
                 .add("endpoint", endpoint)
                 .add("sshAuth", sshAuth)
                 .add("datapathType", datapathType)
+                .add("socketDir", socketDir)
                 .toString();
     }
 
@@ -336,12 +348,12 @@
                 .endpoint(endpoint)
                 .sshAuthInfo(sshAuth)
                 .datapathType(datapathType)
+                .socketDir(socketDir)
                 .build();
     }
 
     @Override
     public Collection<OpenstackPhyInterface> phyIntfs() {
-
         if (phyIntfs == null) {
             return new ArrayList<>();
         }
@@ -423,7 +435,8 @@
                 .authentication(osNode.authentication())
                 .endpoint(osNode.endpoint())
                 .sshAuthInfo(osNode.sshAuthInfo())
-                .datapathType(osNode.datapathType());
+                .datapathType(osNode.datapathType())
+                .socketDir(osNode.socketDir());
     }
 
     /**
@@ -445,6 +458,7 @@
         private String endpoint;
         private OpenstackSshAuth sshAuth;
         private DatapathType datapathType = DatapathType.NORMAL;
+        private String socketDir;
 
         // private constructor not intended to use from external
         private Builder() {
@@ -482,7 +496,8 @@
                     auth,
                     endpoint,
                     sshAuth,
-                    datapathType);
+                    datapathType,
+                    socketDir);
         }
 
         @Override
@@ -570,6 +585,12 @@
             this.datapathType = datapathType;
             return this;
         }
+
+        @Override
+        public Builder socketDir(String socketDir) {
+            this.socketDir = socketDir;
+            return this;
+        }
     }
 }
 
diff --git a/apps/openstacknode/api/src/main/java/org/onosproject/openstacknode/api/OpenstackNode.java b/apps/openstacknode/api/src/main/java/org/onosproject/openstacknode/api/OpenstackNode.java
index 7fbbf9a..9760286 100644
--- a/apps/openstacknode/api/src/main/java/org/onosproject/openstacknode/api/OpenstackNode.java
+++ b/apps/openstacknode/api/src/main/java/org/onosproject/openstacknode/api/OpenstackNode.java
@@ -172,6 +172,13 @@
     DatapathType datapathType();
 
     /**
+     * Returns socket directory which dpdk port bound to.
+     *
+     * @return socket directory
+     */
+    String socketDir();
+
+    /**
      * Returns the uplink port number.
      *
      * @return uplink port number
@@ -360,6 +367,14 @@
          * @return openstack node builder
          */
         Builder datapathType(DatapathType datapathType);
+
+        /**
+         * Returns openstack node builder with supplied socket directory.
+         *
+         * @param socketDir socket directory
+         * @return openstack node builder
+         */
+        Builder socketDir(String socketDir);
     }
 }
 
diff --git a/apps/openstacknode/api/src/test/java/org/onosproject/openstacknode/api/OpenstackNodeAdapter.java b/apps/openstacknode/api/src/test/java/org/onosproject/openstacknode/api/OpenstackNodeAdapter.java
index 333edb0..dac6774 100644
--- a/apps/openstacknode/api/src/test/java/org/onosproject/openstacknode/api/OpenstackNodeAdapter.java
+++ b/apps/openstacknode/api/src/test/java/org/onosproject/openstacknode/api/OpenstackNodeAdapter.java
@@ -110,6 +110,11 @@
     }
 
     @Override
+    public String socketDir() {
+        return null;
+    }
+
+    @Override
     public PortNumber uplinkPortNum() {
         return null;
     }
diff --git a/apps/openstacknode/app/src/main/java/org/onosproject/openstacknode/codec/OpenstackNodeCodec.java b/apps/openstacknode/app/src/main/java/org/onosproject/openstacknode/codec/OpenstackNodeCodec.java
index 66a3f8b..5d16199 100644
--- a/apps/openstacknode/app/src/main/java/org/onosproject/openstacknode/codec/OpenstackNodeCodec.java
+++ b/apps/openstacknode/app/src/main/java/org/onosproject/openstacknode/codec/OpenstackNodeCodec.java
@@ -62,6 +62,7 @@
     private static final String END_POINT = "endpoint";
     private static final String SSH_AUTH = "sshAuth";
     private static final String DATA_PATH_TYPE = "datapathType";
+    private static final String SOCKET_DIR = "socketDir";
 
     private static final String MISSING_MESSAGE = " is required in OpenstackNode";
     private static final String UNSUPPORTED_DATAPATH_TYPE = "Unsupported datapath type";
@@ -127,6 +128,10 @@
             result.set(SSH_AUTH, sshAuthJson);
         }
 
+        if (node.socketDir() != null) {
+            result.put(SOCKET_DIR, node.socketDir());
+        }
+
         return result;
     }
 
@@ -181,6 +186,12 @@
             throw new IllegalArgumentException(UNSUPPORTED_DATAPATH_TYPE + datapathTypeJson.asText());
         }
 
+        JsonNode socketDir = json.get(SOCKET_DIR);
+
+        if (socketDir != null) {
+            nodeBuilder.socketDir(socketDir.asText());
+        }
+
         // parse physical interfaces
         List<OpenstackPhyInterface> phyIntfs = new ArrayList<>();
         JsonNode phyIntfsJson = json.get(PHYSICAL_INTERFACES);
diff --git a/apps/openstacknode/app/src/test/java/org/onosproject/openstacknode/codec/OpenstackNodeCodecTest.java b/apps/openstacknode/app/src/test/java/org/onosproject/openstacknode/codec/OpenstackNodeCodecTest.java
index 49b67a5..4268d6c 100644
--- a/apps/openstacknode/app/src/test/java/org/onosproject/openstacknode/codec/OpenstackNodeCodecTest.java
+++ b/apps/openstacknode/app/src/test/java/org/onosproject/openstacknode/codec/OpenstackNodeCodecTest.java
@@ -124,6 +124,7 @@
                                 .phyIntfs(ImmutableList.of(phyIntf1, phyIntf2))
                                 .controllers(ImmutableList.of(controller1, controller2))
                                 .sshAuthInfo(sshAuth)
+                                .socketDir("/var/lib/libvirt/qemu")
                                 .build();
 
         ObjectNode nodeJson = openstackNodeCodec.encode(node, context);
@@ -150,6 +151,8 @@
         assertThat(node.sshAuthInfo().id(), is("sdn"));
         assertThat(node.sshAuthInfo().password(), is("sdn"));
         assertThat(node.datapathType(), is(OpenstackNode.DatapathType.NORMAL));
+        assertThat(node.socketDir(), is("/var/lib/libvirt/qemu"));
+
 
         node.phyIntfs().forEach(intf -> {
             if (intf.network().equals("mgmtnetwork")) {
diff --git a/apps/openstacknode/app/src/test/java/org/onosproject/openstacknode/codec/OpenstackNodeJsonMatcher.java b/apps/openstacknode/app/src/test/java/org/onosproject/openstacknode/codec/OpenstackNodeJsonMatcher.java
index b53c31c..49c08c6 100644
--- a/apps/openstacknode/app/src/test/java/org/onosproject/openstacknode/codec/OpenstackNodeJsonMatcher.java
+++ b/apps/openstacknode/app/src/test/java/org/onosproject/openstacknode/codec/OpenstackNodeJsonMatcher.java
@@ -43,6 +43,7 @@
     private static final String END_POINT = "endpoint";
     private static final String SSH_AUTH = "sshAuth";
     private static final String DATA_PATH_TYPE = "datapathType";
+    private static final String SOCKET_DIR = "socketDir";
 
     private OpenstackNodeJsonMatcher(OpenstackNode node) {
         this.node = node;
@@ -154,6 +155,16 @@
             }
         }
 
+        // check socket directory
+        JsonNode jsonSocketDir = jsonNode.get(SOCKET_DIR);
+        if (jsonSocketDir != null) {
+            String socketDir = node.socketDir();
+            if (!jsonSocketDir.asText().equals(socketDir)) {
+                description.appendText("socketDir was " + jsonSocketDir);
+                return false;
+            }
+        }
+
         // check physical interfaces
         JsonNode jsonPhyIntfs = jsonNode.get(PHYSICAL_INTERFACES);
         if (jsonPhyIntfs != null) {
diff --git a/apps/openstacknode/app/src/test/java/org/onosproject/openstacknode/impl/DefaultOpenstackNodeHandlerTest.java b/apps/openstacknode/app/src/test/java/org/onosproject/openstacknode/impl/DefaultOpenstackNodeHandlerTest.java
index 9ed0a3a..06d29d7b 100644
--- a/apps/openstacknode/app/src/test/java/org/onosproject/openstacknode/impl/DefaultOpenstackNodeHandlerTest.java
+++ b/apps/openstacknode/app/src/test/java/org/onosproject/openstacknode/impl/DefaultOpenstackNodeHandlerTest.java
@@ -424,7 +424,7 @@
                 ipAddr,
                 ipAddr,
                 null, null, state, phyIntfs, controllers,
-                null, null, null, OpenstackNode.DatapathType.NORMAL);
+                null, null, null, OpenstackNode.DatapathType.NORMAL, null);
     }
 
     private static OpenstackNode createGatewayNode(String hostname,
@@ -440,7 +440,7 @@
                 ipAddr,
                 ipAddr,
                 null, uplinkPort, state, null, null, null, null, null,
-                OpenstackNode.DatapathType.NORMAL);
+                OpenstackNode.DatapathType.NORMAL, null);
     }
 
     private static final class TestDevice extends DefaultDevice {
@@ -503,7 +503,8 @@
                                   OpenstackAuth auth,
                                   String endpoint,
                                   OpenstackSshAuth sshAuth,
-                                  DatapathType datapathType) {
+                                  DatapathType datapathType,
+                                  String socketDir) {
             super(hostname,
                     type,
                     intgBridge,
@@ -517,7 +518,8 @@
                     auth,
                     endpoint,
                     sshAuth,
-                    datapathType);
+                    datapathType,
+                    socketDir);
         }
 
         @Override
diff --git a/apps/openstacknode/app/src/test/resources/org/onosproject/openstacknode/codec/OpenstackComputeNode.json b/apps/openstacknode/app/src/test/resources/org/onosproject/openstacknode/codec/OpenstackComputeNode.json
index 0c07798..0c0f949 100644
--- a/apps/openstacknode/app/src/test/resources/org/onosproject/openstacknode/codec/OpenstackComputeNode.json
+++ b/apps/openstacknode/app/src/test/resources/org/onosproject/openstacknode/codec/OpenstackComputeNode.json
@@ -28,5 +28,6 @@
       "ip": "10.10.10.3",
       "port": 6663
     }
-  ]
+  ],
+  "socketDir": "/var/lib/libvirt/qemu"
 }
\ No newline at end of file
diff --git a/apps/openstacknode/network-cfg.json b/apps/openstacknode/network-cfg.json
index b173147..eea2fc1 100644
--- a/apps/openstacknode/network-cfg.json
+++ b/apps/openstacknode/network-cfg.json
@@ -25,6 +25,7 @@
               "password" : "password"
             },
             "datapathType" : "netdev",
+            "socketDir" : "/var/lib/libvirt/qemu",
             "controllers": [
               {
                 "ip": "10.10.10.2",