Supports update/remove of physical/vlan/dpdk interfaces in OpenstackNode app.

Change-Id: I7c3ab11ee90778fb2c842cb2805947f5a1d2c841
diff --git a/apps/openstacknode/app/src/main/java/org/onosproject/openstacknode/impl/DefaultOpenstackNodeHandler.java b/apps/openstacknode/app/src/main/java/org/onosproject/openstacknode/impl/DefaultOpenstackNodeHandler.java
index 0cf78fa..924cb7c 100644
--- a/apps/openstacknode/app/src/main/java/org/onosproject/openstacknode/impl/DefaultOpenstackNodeHandler.java
+++ b/apps/openstacknode/app/src/main/java/org/onosproject/openstacknode/impl/DefaultOpenstackNodeHandler.java
@@ -15,7 +15,7 @@
  */
 package org.onosproject.openstacknode.impl;
 
-import com.google.common.collect.Maps;
+import com.google.common.collect.Lists;
 import org.apache.felix.scr.annotations.Activate;
 import org.apache.felix.scr.annotations.Component;
 import org.apache.felix.scr.annotations.Deactivate;
@@ -37,7 +37,6 @@
 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.ControllerInfo;
 import org.onosproject.net.behaviour.DefaultBridgeDescription;
 import org.onosproject.net.behaviour.DefaultTunnelDescription;
@@ -60,7 +59,6 @@
 import org.onosproject.openstacknode.api.OpenstackPhyInterface;
 import org.onosproject.ovsdb.controller.OvsdbClientService;
 import org.onosproject.ovsdb.controller.OvsdbController;
-import org.onosproject.ovsdb.controller.OvsdbInterface;
 import org.onosproject.ovsdb.controller.OvsdbPort;
 import org.onosproject.ovsdb.rfc.notation.OvsdbMap;
 import org.onosproject.ovsdb.rfc.notation.OvsdbSet;
@@ -72,7 +70,6 @@
 import java.util.Collection;
 import java.util.Dictionary;
 import java.util.List;
-import java.util.Map;
 import java.util.Objects;
 import java.util.Optional;
 import java.util.Set;
@@ -94,6 +91,8 @@
 import static org.onosproject.openstacknode.api.OpenstackNode.NodeType.CONTROLLER;
 import static org.onosproject.openstacknode.api.OpenstackNode.NodeType.GATEWAY;
 import static org.onosproject.openstacknode.api.OpenstackNodeService.APP_ID;
+import static org.onosproject.openstacknode.util.OpenstackNodeUtil.addOrRemoveDpdkInterface;
+import static org.onosproject.openstacknode.util.OpenstackNodeUtil.addOrRemoveSystemInterface;
 import static org.onosproject.openstacknode.util.OpenstackNodeUtil.getBooleanProperty;
 import static org.onosproject.openstacknode.util.OpenstackNodeUtil.getConnectedClient;
 import static org.onosproject.openstacknode.util.OpenstackNodeUtil.getOvsdbClient;
@@ -111,7 +110,6 @@
     private static final String OVSDB_PORT = "ovsdbPortNum";
     private static final String AUTO_RECOVERY = "autoRecovery";
     private static final String DEFAULT_OF_PROTO = "tcp";
-    private static final String DPDK_DEVARGS = "dpdk-devargs";
     private static final int DEFAULT_OVSDB_PORT = 6640;
     private static final int DEFAULT_OFPORT = 6653;
     private static final boolean DEFAULT_AUTO_RECOVERY = true;
@@ -220,7 +218,7 @@
 
             if (osNode.type() == GATEWAY) {
                 addOrRemoveSystemInterface(osNode, INTEGRATION_BRIDGE,
-                                        osNode.uplinkPort(), true);
+                                        osNode.uplinkPort(), deviceService, true);
             }
 
             if (osNode.dataIp() != null &&
@@ -228,24 +226,30 @@
                 createTunnelInterface(osNode);
             }
 
-            if (osNode.vlanIntf() != null &&
-                    !isIntfEnabled(osNode, osNode.vlanIntf())) {
-                addOrRemoveSystemInterface(osNode, INTEGRATION_BRIDGE,
-                                        osNode.vlanIntf(), true);
-            }
-
             if (osNode.dpdkConfig() != null && osNode.dpdkConfig().dpdkIntfs() != null) {
-                osNode.dpdkConfig().dpdkIntfs().forEach(dpdkInterface ->
-                        addOrRemoveDpdkInterface(osNode, dpdkInterface, true));
+                osNode.dpdkConfig().dpdkIntfs().stream()
+                        .filter(dpdkInterface -> dpdkInterface.deviceName().equals(TUNNEL_BRIDGE))
+                        .forEach(dpdkInterface -> addOrRemoveDpdkInterface(
+                                osNode, dpdkInterface, ovsdbPort, ovsdbController, true));
+
+                osNode.dpdkConfig().dpdkIntfs().stream()
+                        .filter(dpdkInterface -> dpdkInterface.deviceName().equals(INTEGRATION_BRIDGE))
+                        .forEach(dpdkInterface -> addOrRemoveDpdkInterface(
+                                osNode, dpdkInterface, ovsdbPort, ovsdbController, true));
             }
 
             osNode.phyIntfs().forEach(i -> {
                 if (!isIntfEnabled(osNode, i.intf())) {
                     addOrRemoveSystemInterface(osNode, INTEGRATION_BRIDGE,
-                                        i.intf(), true);
+                            i.intf(), deviceService, true);
                 }
             });
 
+            if (osNode.vlanIntf() != null &&
+                    !isIntfEnabled(osNode, osNode.vlanIntf())) {
+                addOrRemoveSystemInterface(osNode, INTEGRATION_BRIDGE,
+                                        osNode.vlanIntf(), deviceService, true);
+            }
         } catch (Exception e) {
             log.error("Exception occurred because of {}", e.toString());
         }
@@ -334,59 +338,6 @@
     }
 
     /**
-     * Adds or removes a network interface (aka port) into a given bridge of openstack node.
-     *
-     * @param osNode openstack node
-     * @param bridgeName bridge name
-     * @param intfName interface name
-     * @param addOrRemove add port is true, remove it otherwise
-     */
-    private void addOrRemoveSystemInterface(OpenstackNode osNode,
-                                            String bridgeName,
-                                            String intfName,
-                                            boolean addOrRemove) {
-        Device device = deviceService.getDevice(osNode.ovsdb());
-        if (device == null || !device.is(BridgeConfig.class)) {
-            log.info("device is null or this device if not ovsdb device");
-            return;
-        }
-        BridgeConfig bridgeConfig =  device.as(BridgeConfig.class);
-
-        if (addOrRemove) {
-            bridgeConfig.addPort(BridgeName.bridgeName(bridgeName), intfName);
-        } else {
-            bridgeConfig.deletePort(BridgeName.bridgeName(bridgeName), intfName);
-        }
-    }
-
-    private void addOrRemoveDpdkInterface(OpenstackNode osNode,
-                                          DpdkInterface dpdkInterface,
-                                          boolean addOrRemove) {
-
-        OvsdbClientService client = getOvsdbClient(osNode, ovsdbPort, ovsdbController);
-        if (client == null) {
-            log.info("Failed to get ovsdb client");
-            return;
-        }
-
-        if (addOrRemove) {
-            Map<String, String> options = Maps.newHashMap();
-            options.put(DPDK_DEVARGS, dpdkInterface.pciAddress());
-
-            OvsdbInterface.Builder builder = OvsdbInterface.builder()
-                    .name(dpdkInterface.intf())
-                    .type(OvsdbInterface.Type.DPDK)
-                    .mtu(dpdkInterface.mtu())
-                    .options(options);
-
-
-            client.createInterface(dpdkInterface.deviceName(), builder.build());
-        } else {
-            client.dropInterface(dpdkInterface.intf());
-        }
-    }
-
-    /**
      * Creates a tunnel interface in a given openstack node.
      *
      * @param osNode openstack node
@@ -460,8 +411,10 @@
                         !isIntfEnabled(osNode, osNode.uplinkPort())) {
                     return false;
                 }
-                if (osNode.dpdkConfig() != null && osNode.dpdkConfig().dpdkIntfs() != null) {
-                    return isDpdkIntfsCreated(osNode, osNode.dpdkConfig().dpdkIntfs());
+                if (osNode.dpdkConfig() != null &&
+                        osNode.dpdkConfig().dpdkIntfs() != null &&
+                        !isDpdkIntfsCreated(osNode, osNode.dpdkConfig().dpdkIntfs())) {
+                    return false;
                 }
 
                 for (OpenstackPhyInterface intf : osNode.phyIntfs()) {
@@ -558,6 +511,58 @@
         }
     }
 
+    private void removeVlanInterface(OpenstackNode osNode) {
+        if (osNode.vlanIntf() != null) {
+            Optional<DpdkInterface> dpdkInterface = dpdkInterfaceByIntfName(osNode, osNode.vlanIntf());
+
+            removeInterfaceOnIntegrationBridge(osNode, osNode.vlanIntf(), dpdkInterface);
+        }
+    }
+
+    private void removePhysicalInterface(OpenstackNode osNode) {
+        osNode.phyIntfs().forEach(phyIntf -> {
+            Optional<DpdkInterface> dpdkInterface = dpdkInterfaceByIntfName(osNode, phyIntf.intf());
+
+            removeInterfaceOnIntegrationBridge(osNode, phyIntf.intf(), dpdkInterface);
+        });
+    }
+
+    private Optional<DpdkInterface> dpdkInterfaceByIntfName(OpenstackNode osNode, String intf) {
+        return osNode.dpdkConfig() == null ? Optional.empty() :
+                osNode.dpdkConfig().dpdkIntfs().stream()
+                        .filter(dpdkIntf -> dpdkIntf.intf().equals(intf))
+                        .findAny();
+    }
+
+    private void removeInterfaceOnIntegrationBridge(OpenstackNode osNode,
+                                      String intfName,
+                                      Optional<DpdkInterface> dpdkInterface) {
+        if (dpdkInterface.isPresent()) {
+            addOrRemoveDpdkInterface(osNode, dpdkInterface.get(), ovsdbPort,
+                    ovsdbController, false);
+        } else {
+            addOrRemoveSystemInterface(osNode, INTEGRATION_BRIDGE, intfName, deviceService,
+                    false);
+        }
+    }
+
+    private void processOpenstackNodeRemoved(OpenstackNode osNode) {
+        //delete physical interfaces from the node
+        removePhysicalInterface(osNode);
+
+        //delete vlan interface from the node
+        removeVlanInterface(osNode);
+
+        //delete dpdk interfaces from the node
+        if (osNode.dpdkConfig() != null) {
+            osNode.dpdkConfig().dpdkIntfs().forEach(dpdkInterface -> {
+                if (isDpdkIntfsCreated(osNode, Lists.newArrayList(dpdkInterface))) {
+                    addOrRemoveDpdkInterface(osNode, dpdkInterface, ovsdbPort, ovsdbController, false);
+                }
+            });
+        }
+    }
+
     /**
      * Checks the validity of the given endpoint.
      *
@@ -694,6 +699,7 @@
                         }
                     });
                     break;
+                case PORT_UPDATED:
                 case PORT_ADDED:
                     eventExecutor.execute(() -> {
                         Port port = event.port();
@@ -702,9 +708,10 @@
                                 Objects.equals(portName, DEFAULT_TUNNEL) ||
                                 Objects.equals(portName, osNode.vlanIntf()) ||
                                 Objects.equals(portName, osNode.uplinkPort()) ||
-                                        containsPhyIntf(osNode, portName))) {
-                            log.debug("Interface {} added to {}",
-                                                portName, event.subject().id());
+                                        containsPhyIntf(osNode, portName)) ||
+                                containsDpdkIntfs(osNode, portName)) {
+                            log.info("Interface {} added or updated to {}",
+                                                portName, device.id());
                             bootstrapNode(osNode);
                         }
                     });
@@ -717,14 +724,14 @@
                                 Objects.equals(portName, DEFAULT_TUNNEL) ||
                                 Objects.equals(portName, osNode.vlanIntf()) ||
                                 Objects.equals(portName, osNode.uplinkPort()) ||
-                                        containsPhyIntf(osNode, portName))) {
+                                        containsPhyIntf(osNode, portName)) ||
+                                containsDpdkIntfs(osNode, portName)) {
                             log.warn("Interface {} removed from {}",
                                                 portName, event.subject().id());
                             setState(osNode, INCOMPLETE);
                         }
                     });
                     break;
-                case PORT_UPDATED:
                 case DEVICE_REMOVED:
                 default:
                     // do nothing
@@ -742,13 +749,24 @@
      *          false otherwise
      */
     private boolean containsPhyIntf(OpenstackNode osNode, String portName) {
-        for (OpenstackPhyInterface phyIntf : osNode.phyIntfs()) {
-            if (Objects.equals(portName, phyIntf.intf())) {
-                return true;
-            }
-        }
+        return osNode.phyIntfs().stream()
+                .anyMatch(phyInterface -> phyInterface.intf().equals(portName));
+    }
 
-        return false;
+    /**
+     * Checks whether the openstack node contains the given dpdk interface.
+     *
+     * @param osNode openstack node
+     * @param portName dpdk interface
+     * @return true if openstack node contains the given dpdk interface,
+     *          false otherwise
+     */
+    private boolean containsDpdkIntfs(OpenstackNode osNode, String portName) {
+        if (osNode.dpdkConfig() == null) {
+            return false;
+        }
+        return osNode.dpdkConfig().dpdkIntfs().stream()
+                .anyMatch(dpdkInterface -> dpdkInterface.intf().equals(portName));
     }
 
     /**
@@ -773,6 +791,7 @@
                 case OPENSTACK_NODE_COMPLETE:
                     break;
                 case OPENSTACK_NODE_REMOVED:
+                    eventExecutor.execute(() -> processOpenstackNodeRemoved(event.subject()));
                     break;
                 default:
                     break;
diff --git a/apps/openstacknode/app/src/main/java/org/onosproject/openstacknode/impl/OpenstackNodeManager.java b/apps/openstacknode/app/src/main/java/org/onosproject/openstacknode/impl/OpenstackNodeManager.java
index ff10a2c..c2f8bc1 100644
--- a/apps/openstacknode/app/src/main/java/org/onosproject/openstacknode/impl/OpenstackNodeManager.java
+++ b/apps/openstacknode/app/src/main/java/org/onosproject/openstacknode/impl/OpenstackNodeManager.java
@@ -31,10 +31,7 @@
 import org.onosproject.core.ApplicationId;
 import org.onosproject.core.CoreService;
 import org.onosproject.event.ListenerRegistry;
-import org.onosproject.net.Device;
 import org.onosproject.net.DeviceId;
-import org.onosproject.net.behaviour.BridgeConfig;
-import org.onosproject.net.behaviour.BridgeName;
 import org.onosproject.net.device.DeviceService;
 import org.onosproject.openstacknode.api.OpenstackNode;
 import org.onosproject.openstacknode.api.OpenstackNodeAdminService;
@@ -54,6 +51,7 @@
 import java.util.Optional;
 import java.util.Set;
 import java.util.concurrent.ExecutorService;
+import java.util.concurrent.TimeUnit;
 import java.util.stream.Collectors;
 
 import static com.google.common.base.Preconditions.checkArgument;
@@ -61,9 +59,11 @@
 import static java.util.concurrent.Executors.newSingleThreadExecutor;
 import static org.onlab.packet.TpPort.tpPort;
 import static org.onlab.util.Tools.groupedThreads;
+import static org.onosproject.net.AnnotationKeys.PORT_NAME;
 import static org.onosproject.openstacknode.api.Constants.INTEGRATION_BRIDGE;
 import static org.onosproject.openstacknode.api.NodeState.COMPLETE;
 import static org.onosproject.openstacknode.api.OpenstackNode.NodeType.CONTROLLER;
+import static org.onosproject.openstacknode.util.OpenstackNodeUtil.addOrRemoveSystemInterface;
 import static org.onosproject.openstacknode.util.OpenstackNodeUtil.genDpid;
 import static org.onosproject.openstacknode.util.OpenstackNodeUtil.isOvsdbConnected;
 import static org.slf4j.LoggerFactory.getLogger;
@@ -189,11 +189,34 @@
 
         OpenstackNode updatedNode;
 
-        OpenstackNode existNode = osNodeStore.node(osNode.hostname());
-        checkNotNull(existNode, ERR_NULL_NODE);
+        OpenstackNode existingNode = osNodeStore.node(osNode.hostname());
+        checkNotNull(existingNode, ERR_NULL_NODE);
 
         DeviceId existDeviceId = osNodeStore.node(osNode.hostname()).intgBridge();
 
+        if (vlanIntfChanged(existingNode, osNode) ||
+                physicalIntfChanged(existingNode, osNode) ||
+                dpdkIntfChanged(existingNode, osNode)) {
+
+            removeNode(osNode.hostname());
+
+            //we wait 1 second for ovsdb client completely to do removal job
+            try {
+                TimeUnit.MILLISECONDS.sleep(1000);
+            } catch (InterruptedException e) {
+                log.error("Exception occurred because of {}", e);
+            }
+
+            if (!intfsRemovedFromExistNode(existingNode)) {
+                log.error("Updated node failed because intfs of existingNode {} are not removed properly",
+                        existingNode.toString());
+                return;
+            }
+
+            createNode(osNode);
+            return;
+        }
+
         if (osNode.intgBridge() == null && osNode.type() != CONTROLLER) {
             updatedNode = osNode.updateIntbridge(existDeviceId);
             checkArgument(!hasIntgBridge(updatedNode.intgBridge(), updatedNode.hostname()),
@@ -266,7 +289,7 @@
 
         connectSwitch(osNode);
 
-        addOrRemoveSystemInterface(osNode, INTEGRATION_BRIDGE, portName, true);
+        addOrRemoveSystemInterface(osNode, INTEGRATION_BRIDGE, portName, deviceService, true);
     }
 
     @Override
@@ -275,7 +298,44 @@
 
         connectSwitch(osNode);
 
-        addOrRemoveSystemInterface(osNode, INTEGRATION_BRIDGE, portName, false);
+        addOrRemoveSystemInterface(osNode, INTEGRATION_BRIDGE, portName, deviceService, false);
+    }
+
+    private boolean intfsRemovedFromExistNode(OpenstackNode osNode) {
+        if (osNode.vlanIntf() != null &&
+                !intfRemoved(osNode.vlanIntf(), osNode.intgBridge())) {
+            return false;
+        }
+
+        if (osNode.phyIntfs().stream().anyMatch(phyInterface ->
+                !intfRemoved(phyInterface.intf(), osNode.intgBridge()))) {
+            return false;
+        }
+
+        if (osNode.dpdkConfig() != null &&
+                osNode.dpdkConfig().dpdkIntfs().stream().anyMatch(dpdkInterface ->
+                        !intfRemoved(dpdkInterface.intf(), osNode.intgBridge()))) {
+            return false;
+        }
+
+        return true;
+    }
+
+    private boolean intfRemoved(String intf, DeviceId deviceId) {
+        return !deviceService.getPorts(deviceId).stream()
+                .anyMatch(port -> port.annotations().value(PORT_NAME).equals(intf));
+    }
+
+    private boolean vlanIntfChanged(OpenstackNode oldNode, OpenstackNode newNode) {
+        return !Objects.equals(oldNode.vlanIntf(), newNode.vlanIntf());
+    }
+
+    private boolean physicalIntfChanged(OpenstackNode oldNode, OpenstackNode newNode) {
+        return !Objects.equals(oldNode.phyIntfs(), newNode.phyIntfs());
+    }
+
+    private boolean dpdkIntfChanged(OpenstackNode oldNode, OpenstackNode newNode) {
+        return !Objects.equals(oldNode.dpdkConfig(), newNode.dpdkConfig());
     }
 
     private void connectSwitch(OpenstackNode osNode) {
@@ -291,21 +351,6 @@
         }
     }
 
-    private void addOrRemoveSystemInterface(OpenstackNode osNode, String bridgeName, String intfName,
-                                            boolean addOrRemove) {
-        Device device = deviceService.getDevice(osNode.ovsdb());
-        if (device == null || !device.is(BridgeConfig.class)) {
-            log.info("device is null or this device if not ovsdb device");
-            return;
-        }
-        BridgeConfig bridgeConfig =  device.as(BridgeConfig.class);
-        if (addOrRemove) {
-            bridgeConfig.addPort(BridgeName.bridgeName(bridgeName), intfName);
-        } else {
-            bridgeConfig.deletePort(BridgeName.bridgeName(bridgeName), intfName);
-        }
-    }
-
     private boolean hasIntgBridge(DeviceId deviceId, String hostname) {
         Optional<OpenstackNode> existNode = osNodeStore.nodes().stream()
                 .filter(n -> n.type() != CONTROLLER)
diff --git a/apps/openstacknode/app/src/main/java/org/onosproject/openstacknode/util/OpenstackNodeUtil.java b/apps/openstacknode/app/src/main/java/org/onosproject/openstacknode/util/OpenstackNodeUtil.java
index 311eba4..f19b8d5 100644
--- a/apps/openstacknode/app/src/main/java/org/onosproject/openstacknode/util/OpenstackNodeUtil.java
+++ b/apps/openstacknode/app/src/main/java/org/onosproject/openstacknode/util/OpenstackNodeUtil.java
@@ -17,12 +17,18 @@
 
 import com.fasterxml.jackson.databind.ObjectMapper;
 import com.google.common.base.Strings;
+import com.google.common.collect.ImmutableMap;
+import org.onosproject.net.Device;
+import org.onosproject.net.behaviour.BridgeConfig;
+import org.onosproject.net.behaviour.BridgeName;
 import org.onosproject.net.device.DeviceService;
+import org.onosproject.openstacknode.api.DpdkInterface;
 import org.onosproject.openstacknode.api.OpenstackAuth;
 import org.onosproject.openstacknode.api.OpenstackAuth.Perspective;
 import org.onosproject.openstacknode.api.OpenstackNode;
 import org.onosproject.ovsdb.controller.OvsdbClientService;
 import org.onosproject.ovsdb.controller.OvsdbController;
+import org.onosproject.ovsdb.controller.OvsdbInterface;
 import org.onosproject.ovsdb.controller.OvsdbNodeId;
 import org.openstack4j.api.OSClient;
 import org.openstack4j.api.client.IOSClientBuilder;
@@ -42,6 +48,7 @@
 import java.io.IOException;
 import java.security.cert.X509Certificate;
 import java.util.Dictionary;
+import java.util.Map;
 
 import static org.onlab.util.Tools.get;
 
@@ -61,6 +68,8 @@
     private static final String OF_PREFIX = "of:";
     private static final String ZERO = "0";
 
+    private static final String DPDK_DEVARGS = "dpdk-devargs";
+
     /**
      * Prevents object installation from external.
      */
@@ -212,6 +221,74 @@
         return OF_PREFIX + zeroPadding.toString() + hexStr;
     }
 
+
+    /**
+     * Adds or removes a network interface (aka port) into a given bridge of openstack node.
+     *
+     * @param osNode openstack node
+     * @param bridgeName bridge name
+     * @param intfName interface name
+     * @param deviceService device service
+     * @param addOrRemove add port is true, remove it otherwise
+     */
+    public static synchronized void addOrRemoveSystemInterface(OpenstackNode osNode,
+                                                               String bridgeName,
+                                                               String intfName,
+                                                               DeviceService deviceService,
+                                                               boolean addOrRemove) {
+
+
+        Device device = deviceService.getDevice(osNode.ovsdb());
+        if (device == null || !device.is(BridgeConfig.class)) {
+            log.info("device is null or this device if not ovsdb device");
+            return;
+        }
+        BridgeConfig bridgeConfig =  device.as(BridgeConfig.class);
+
+        if (addOrRemove) {
+            bridgeConfig.addPort(BridgeName.bridgeName(bridgeName), intfName);
+        } else {
+            bridgeConfig.deletePort(BridgeName.bridgeName(bridgeName), intfName);
+        }
+    }
+
+    /**
+     * Adds or removes a dpdk interface into a given openstack node.
+     *
+     * @param osNode openstack node
+     * @param dpdkInterface dpdk interface
+     * @param ovsdbPort ovsdb port
+     * @param ovsdbController ovsdb controller
+     * @param addOrRemove add port is true, remove it otherwise
+     */
+    public static synchronized void addOrRemoveDpdkInterface(OpenstackNode osNode,
+                                                             DpdkInterface dpdkInterface,
+                                                             int ovsdbPort,
+                                                             OvsdbController ovsdbController,
+                                                             boolean addOrRemove) {
+
+        OvsdbClientService client = getOvsdbClient(osNode, ovsdbPort, ovsdbController);
+        if (client == null) {
+            log.info("Failed to get ovsdb client");
+            return;
+        }
+
+        if (addOrRemove) {
+            Map<String, String> options = ImmutableMap.of(DPDK_DEVARGS, dpdkInterface.pciAddress());
+
+            OvsdbInterface.Builder builder = OvsdbInterface.builder()
+                    .name(dpdkInterface.intf())
+                    .type(OvsdbInterface.Type.DPDK)
+                    .mtu(dpdkInterface.mtu())
+                    .options(options);
+
+
+            client.createInterface(dpdkInterface.deviceName(), builder.build());
+        } else {
+            client.dropInterface(dpdkInterface.intf());
+        }
+    }
+
     /**
      * Builds up and a complete endpoint URL from gateway node.
      *
diff --git a/apps/openstacknode/app/src/main/java/org/onosproject/openstacknode/web/OpenstackNodeWebResource.java b/apps/openstacknode/app/src/main/java/org/onosproject/openstacknode/web/OpenstackNodeWebResource.java
index 3c1a263..1b69f30 100644
--- a/apps/openstacknode/app/src/main/java/org/onosproject/openstacknode/web/OpenstackNodeWebResource.java
+++ b/apps/openstacknode/app/src/main/java/org/onosproject/openstacknode/web/OpenstackNodeWebResource.java
@@ -169,7 +169,7 @@
 
                      nodeSet.add(openstackNode);
                  } catch (Exception e) {
-                     log.error(e.toString());
+                     log.error("Exception occurred due to {}", e);
                      throw new IllegalArgumentException();
                  }
              });