TSC-101: Fixup Augmentable and Identifiable methods change
[ovsdb.git] / utils / southbound-utils / src / main / java / org / opendaylight / ovsdb / utils / southbound / utils / SouthboundUtils.java
index 9f2a202491048a81a2ba2eaa0ab5caf53bc67716..1811a24564c4f53cb278b9149cd129393ad9fceb 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015 Red Hat, Inc. and others.  All rights reserved.
+ * Copyright (c) 2015 - 2017 Red Hat, Inc. and others.  All rights reserved.
  *
  * This program and the accompanying materials are made available under the
  * terms of the Eclipse Public License v1.0 which accompanies this distribution,
@@ -14,29 +14,78 @@ import java.net.Inet4Address;
 import java.net.Inet6Address;
 import java.net.InetAddress;
 import java.net.NetworkInterface;
+import java.net.SocketException;
 import java.net.UnknownHostException;
+import java.security.InvalidParameterException;
 import java.util.ArrayList;
-
+import java.util.Collections;
 import java.util.Enumeration;
+import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+import java.util.stream.Collectors;
 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
 import org.opendaylight.ovsdb.utils.config.ConfigProperties;
 import org.opendaylight.ovsdb.utils.mdsal.utils.MdsalUtils;
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.IetfInetUtil;
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.IpAddress;
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Ipv6Address;
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.PortNumber;
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Uri;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.*;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IetfInetUtil;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpAddress;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv6Address;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.PortNumber;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Uri;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.DatapathId;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.DatapathTypeBase;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.DatapathTypeNetdev;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.InterfaceTypeBase;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.InterfaceTypeDpdk;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.InterfaceTypeDpdkr;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.InterfaceTypeDpdkvhost;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.InterfaceTypeDpdkvhostuser;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.InterfaceTypeDpdkvhostuserclient;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.InterfaceTypeGeneve;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.InterfaceTypeGre;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.InterfaceTypeGre64;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.InterfaceTypeInternal;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.InterfaceTypeIpsecGre;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.InterfaceTypeIpsecGre64;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.InterfaceTypeLisp;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.InterfaceTypePatch;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.InterfaceTypeSystem;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.InterfaceTypeTap;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.InterfaceTypeVxlan;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.InterfaceTypeVxlanGpe;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.OvsdbBridgeAugmentation;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.OvsdbBridgeAugmentationBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.OvsdbBridgeName;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.OvsdbBridgeProtocolBase;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.OvsdbBridgeProtocolOpenflow10;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.OvsdbBridgeProtocolOpenflow11;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.OvsdbBridgeProtocolOpenflow12;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.OvsdbBridgeProtocolOpenflow13;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.OvsdbBridgeProtocolOpenflow14;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.OvsdbBridgeProtocolOpenflow15;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.OvsdbFailModeBase;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.OvsdbFailModeSecure;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.OvsdbFailModeStandalone;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.OvsdbNodeAugmentation;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.OvsdbNodeAugmentationBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.OvsdbNodeRef;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.OvsdbTerminationPointAugmentation;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.OvsdbTerminationPointAugmentationBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.bridge.attributes.BridgeExternalIds;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.bridge.attributes.BridgeOtherConfigs;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.bridge.attributes.ControllerEntry;import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.bridge.attributes.ControllerEntryBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.bridge.attributes.BridgeOtherConfigsBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.bridge.attributes.ControllerEntry;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.bridge.attributes.ControllerEntryBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.bridge.attributes.ProtocolEntry;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.bridge.attributes.ProtocolEntryBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.node.attributes.ConnectionInfo;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.node.attributes.ConnectionInfoBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.node.attributes.InterfaceTypeEntry;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.node.attributes.ManagedNodeEntry;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.node.attributes.ManagerEntry;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.node.attributes.OpenvswitchOtherConfigs;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.port._interface.attributes.InterfaceExternalIds;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.port._interface.attributes.InterfaceExternalIdsBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.port._interface.attributes.InterfaceExternalIdsKey;
@@ -65,9 +114,18 @@ public class SouthboundUtils {
     public static final TopologyId OVSDB_TOPOLOGY_ID = new TopologyId(new Uri("ovsdb:1"));
     private final MdsalUtils mdsalUtils;
     public static final String OPENFLOW_CONNECTION_PROTOCOL = "tcp";
-    public static short OPENFLOW_PORT = 6653;
+    public static final String OPENFLOW_SECURE_PROTOCOL = "ssl";
+    public static final short OPENFLOW_PORT = 6653;
     public static final String OVSDB_URI_PREFIX = "ovsdb";
     public static final String BRIDGE_URI_PREFIX = "bridge";
+    private static final String DISABLE_IN_BAND = "disable-in-band";
+    private static final String PATCH_PORT_TYPE = "patch";
+    // External ID key used for mapping between an OVSDB port and an interface name
+    private static final String EXTERNAL_INTERFACE_ID_KEY = "iface-id";
+
+    private static final String FORMAT = "(\\d+)\\.(\\d+)\\.(\\d+)";
+    private static final Pattern PATTERN = Pattern.compile(FORMAT);
+
 
     public SouthboundUtils(MdsalUtils mdsalUtils) {
         this.mdsalUtils = mdsalUtils;
@@ -91,6 +149,7 @@ public class SouthboundUtils {
             .put("dpdkr", InterfaceTypeDpdkr.class)
             .put("dpdkvhost", InterfaceTypeDpdkvhost.class)
             .put("dpdkvhostuser", InterfaceTypeDpdkvhostuser.class)
+            .put("dpdkvhostuserclient", InterfaceTypeDpdkvhostuserclient.class)
             .build();
 
     public static final ImmutableBiMap<Class<? extends OvsdbBridgeProtocolBase>,String> OVSDB_PROTOCOL_MAP
@@ -103,6 +162,12 @@ public class SouthboundUtils {
             .put(OvsdbBridgeProtocolOpenflow15.class,"OpenFlow15")
             .build();
 
+    private static final ImmutableBiMap<Class<? extends OvsdbFailModeBase>,String> OVSDB_FAIL_MODE_MAP
+            = new ImmutableBiMap.Builder<Class<? extends OvsdbFailModeBase>,String>()
+            .put(OvsdbFailModeStandalone.class,"standalone")
+            .put(OvsdbFailModeSecure.class,"secure")
+            .build();
+
     public static NodeId createNodeId(IpAddress ip, PortNumber port) {
         String uriString = OVSDB_URI_PREFIX + "://"
                 + String.valueOf(ip.getValue()) + ":" + port.getValue();
@@ -134,11 +199,6 @@ public class SouthboundUtils {
         return createInstanceIdentifier(createManagedNodeId(ovsdbNodeKey.getNodeId(), bridgeName));
     }
 
-    public static NodeId createManagedNodeId(NodeId ovsdbNodeId, String bridgeName) {
-        return new NodeId(ovsdbNodeId.getValue()
-                + "/" + BRIDGE_URI_PREFIX + "/" + bridgeName);
-    }
-
     public static InstanceIdentifier<Node> createInstanceIdentifier(ConnectionInfo key) {
         return createInstanceIdentifier(key.getRemoteIp(), key.getRemotePort());
     }
@@ -152,7 +212,7 @@ public class SouthboundUtils {
         return path;
     }
 
-    public static InstanceIdentifier<Node> createInstanceIdentifier(ConnectionInfo key,OvsdbBridgeName bridgeName) {
+    public static InstanceIdentifier<Node> createInstanceIdentifier(ConnectionInfo key, OvsdbBridgeName bridgeName) {
         return createInstanceIdentifier(createManagedNodeId(key, bridgeName));
     }
 
@@ -160,12 +220,12 @@ public class SouthboundUtils {
         return createInstanceIdentifier(key, new OvsdbBridgeName(bridgeName));
     }
 
-    public InstanceIdentifier<TerminationPoint> createTerminationPointInstanceIdentifier(Node node, String portName){
+    public InstanceIdentifier<TerminationPoint> createTerminationPointInstanceIdentifier(Node node, String portName) {
 
         InstanceIdentifier<TerminationPoint> terminationPointPath = InstanceIdentifier
                 .create(NetworkTopology.class)
                 .child(Topology.class, new TopologyKey(OVSDB_TOPOLOGY_ID))
-                .child(Node.class,node.getKey())
+                .child(Node.class,node.key())
                 .child(TerminationPoint.class, new TerminationPointKey(new TpId(portName)));
 
         LOG.debug("Termination point InstanceIdentifier generated : {}",terminationPointPath);
@@ -176,6 +236,11 @@ public class SouthboundUtils {
         return new NodeKey(createNodeId(ip, port));
     }
 
+    public static NodeId createManagedNodeId(NodeId ovsdbNodeId, String bridgeName) {
+        return new NodeId(ovsdbNodeId.getValue()
+                + "/" + BRIDGE_URI_PREFIX + "/" + bridgeName);
+    }
+
     public static NodeId createManagedNodeId(ConnectionInfo key, OvsdbBridgeName bridgeName) {
         return createManagedNodeId(key.getRemoteIp(), key.getRemotePort(), bridgeName);
     }
@@ -190,17 +255,8 @@ public class SouthboundUtils {
         return nodeKey.getNodeId();
     }
 
-    public ConnectionInfo getConnectionInfo(Node ovsdbNode) {
-        ConnectionInfo connectionInfo = null;
-        OvsdbNodeAugmentation ovsdbNodeAugmentation = extractOvsdbNode(ovsdbNode);
-        if (ovsdbNodeAugmentation != null) {
-            connectionInfo = ovsdbNodeAugmentation.getConnectionInfo();
-        }
-        return connectionInfo;
-    }
-
     public OvsdbNodeAugmentation extractOvsdbNode(Node node) {
-        return node.getAugmentation(OvsdbNodeAugmentation.class);
+        return node.augmentation(OvsdbNodeAugmentation.class);
     }
 
     public static IpAddress createIpAddress(InetAddress address) {
@@ -222,6 +278,15 @@ public class SouthboundUtils {
         return new IpAddress(ipv6);
     }
 
+    public ConnectionInfo getConnectionInfo(Node ovsdbNode) {
+        ConnectionInfo connectionInfo = null;
+        OvsdbNodeAugmentation ovsdbNodeAugmentation = extractOvsdbNode(ovsdbNode);
+        if (ovsdbNodeAugmentation != null) {
+            connectionInfo = ovsdbNodeAugmentation.getConnectionInfo();
+        }
+        return connectionInfo;
+    }
+
     public static ConnectionInfo getConnectionInfo(final String addressStr, final String portStr) {
         InetAddress inetAddress = null;
         try {
@@ -333,14 +398,14 @@ public class SouthboundUtils {
         OvsdbBridgeAugmentation ovsdbBridgeAugmentation = null;
         Node bridgeNode = getBridgeNode(connectionInfo, bridgeName, store);
         if (bridgeNode != null) {
-            ovsdbBridgeAugmentation = bridgeNode.getAugmentation(OvsdbBridgeAugmentation.class);
+            ovsdbBridgeAugmentation = bridgeNode.augmentation(OvsdbBridgeAugmentation.class);
         }
         return ovsdbBridgeAugmentation;
     }
 
     /**
-     * extract the <code>LogicalDataStoreType.OPERATIONAL</code> type data store contents for the particular bridge
-     * identified by <code>bridgeName</code>
+     * Extract the <code>LogicalDataStoreType.OPERATIONAL</code> type data store contents for the particular bridge
+     * identified by <code>bridgeName</code>.
      *
      * @param connectionInfo address for the node
      * @param bridgeName name of the bridge
@@ -386,21 +451,21 @@ public class SouthboundUtils {
         ConnectionInfo connectionInfo = getConnectionInfo(ovsdbNode);
         if (connectionInfo != null) {
             InstanceIdentifier<Node> bridgeIid =
-                    createInstanceIdentifier(node.getKey(), name);
+                    createInstanceIdentifier(node.key(), name);
             bridgeNode = mdsalUtils.read(LogicalDatastoreType.OPERATIONAL, bridgeIid);
         }
         return bridgeNode;
     }
 
     public OvsdbNodeAugmentation extractNodeAugmentation(Node node) {
-        return node.getAugmentation(OvsdbNodeAugmentation.class);
+        return node.augmentation(OvsdbNodeAugmentation.class);
     }
 
     public OvsdbBridgeAugmentation extractBridgeAugmentation(Node node) {
         if (node == null) {
             return null;
         }
-        return node.getAugmentation(OvsdbBridgeAugmentation.class);
+        return node.augmentation(OvsdbBridgeAugmentation.class);
     }
 
     public Node readOvsdbNode(Node bridgeNode) {
@@ -410,7 +475,7 @@ public class SouthboundUtils {
             InstanceIdentifier<Node> ovsdbNodeIid =
                     (InstanceIdentifier<Node>) bridgeAugmentation.getManagedBy().getValue();
             ovsdbNode = mdsalUtils.read(LogicalDatastoreType.OPERATIONAL, ovsdbNodeIid);
-        }else{
+        } else {
             LOG.debug("readOvsdbNode: Provided node is not a bridge node : {}",bridgeNode);
         }
         return ovsdbNode;
@@ -441,18 +506,6 @@ public class SouthboundUtils {
         return protocolList;
     }
 
-    public boolean addBridge(final ConnectionInfo connectionInfo, InstanceIdentifier<Node> bridgeIid,
-                             final String bridgeName, NodeId bridgeNodeId, final boolean setProtocolEntries,
-                             final Class<? extends OvsdbFailModeBase> failMode, final boolean setManagedBy,
-                             final Class<? extends DatapathTypeBase> dpType,
-                             final List<BridgeExternalIds> externalIds,
-                             final List<ControllerEntry> controllerEntries,
-                             final List<BridgeOtherConfigs> otherConfigs,
-                             final String dpid) throws InterruptedException {
-        return addBridge(connectionInfo, bridgeIid, bridgeName, bridgeNodeId, setProtocolEntries, failMode,
-                setManagedBy, dpType, externalIds, controllerEntries, otherConfigs, dpid);
-    }
-
     /*
      * base method for adding test bridges.  Other helper methods used to create bridges should utilize this method.
      *
@@ -524,6 +577,139 @@ public class SouthboundUtils {
         return result;
     }
 
+    public boolean addBridge(Node ovsdbNode, String bridgeName, List<String> controllersStr,
+            final Class<? extends DatapathTypeBase> dpType, String mac) {
+        return addBridge(ovsdbNode, bridgeName, controllersStr, dpType, mac, null, null);
+    }
+
+    public boolean addBridge(Node ovsdbNode, String bridgeName, List<String> controllersStr,
+                             final Class<? extends DatapathTypeBase> dpType, String mac,
+                             Long maxBackoff, Long inactivityProbe) {
+        List<BridgeOtherConfigs> otherConfigs = new ArrayList<>();
+        if (mac != null) {
+            BridgeOtherConfigsBuilder macOtherConfigBuilder = new BridgeOtherConfigsBuilder();
+            macOtherConfigBuilder.setBridgeOtherConfigKey("hwaddr");
+            macOtherConfigBuilder.setBridgeOtherConfigValue(mac);
+            otherConfigs.add(macOtherConfigBuilder.build());
+        }
+
+        return addBridge(ovsdbNode, bridgeName, controllersStr, dpType, otherConfigs, null, null);
+    }
+
+    public boolean addBridge(Node ovsdbNode, String bridgeName, List<String> controllersStr,
+            final Class<? extends DatapathTypeBase> dpType,
+            List<BridgeOtherConfigs> otherConfigs,
+            Long maxBackoff, Long inactivityProbe) {
+        boolean result;
+
+        LOG.info("addBridge: node: {}, bridgeName: {}, controller(s): {}", ovsdbNode, bridgeName, controllersStr);
+        ConnectionInfo connectionInfo = getConnectionInfo(ovsdbNode);
+        if (connectionInfo != null) {
+            NodeBuilder bridgeNodeBuilder = new NodeBuilder();
+            InstanceIdentifier<Node> bridgeIid = createInstanceIdentifier(ovsdbNode.key(), bridgeName);
+            NodeId bridgeNodeId = createManagedNodeId(bridgeIid);
+            bridgeNodeBuilder.setNodeId(bridgeNodeId);
+            OvsdbBridgeAugmentationBuilder ovsdbBridgeAugmentationBuilder = new OvsdbBridgeAugmentationBuilder();
+            ovsdbBridgeAugmentationBuilder.setControllerEntry(createControllerEntries(
+                    controllersStr, maxBackoff, inactivityProbe));
+            ovsdbBridgeAugmentationBuilder.setBridgeName(new OvsdbBridgeName(bridgeName));
+            ovsdbBridgeAugmentationBuilder.setProtocolEntry(createMdsalProtocols());
+            ovsdbBridgeAugmentationBuilder.setFailMode(OVSDB_FAIL_MODE_MAP.inverse().get("secure"));
+            // TODO: Currently netvirt relies on this function to set disabled-in-band=true. However,
+            // TODO (cont): a better design would be to have netvirt pass that in. That way this function
+            // TODO (cont): can take a null otherConfigs to erase other_configs.
+            if (otherConfigs == null) {
+                otherConfigs = new ArrayList<>();
+            }
+            BridgeOtherConfigsBuilder bridgeOtherConfigsBuilder = new BridgeOtherConfigsBuilder();
+            bridgeOtherConfigsBuilder.setBridgeOtherConfigKey(DISABLE_IN_BAND);
+            bridgeOtherConfigsBuilder.setBridgeOtherConfigValue("true");
+            otherConfigs.add(bridgeOtherConfigsBuilder.build());
+            ovsdbBridgeAugmentationBuilder.setBridgeOtherConfigs(otherConfigs);
+            setManagedByForBridge(ovsdbBridgeAugmentationBuilder, ovsdbNode.key());
+            if (dpType != null) {
+                ovsdbBridgeAugmentationBuilder.setDatapathType(dpType);
+            }
+            if (isOvsdbNodeDpdk(ovsdbNode)) {
+                ovsdbBridgeAugmentationBuilder.setDatapathType(DatapathTypeNetdev.class);
+            }
+            bridgeNodeBuilder.addAugmentation(OvsdbBridgeAugmentation.class, ovsdbBridgeAugmentationBuilder.build());
+
+            Node node = bridgeNodeBuilder.build();
+            result = mdsalUtils.put(LogicalDatastoreType.CONFIGURATION, bridgeIid, node);
+            LOG.info("addBridge: result: {}", result);
+        } else {
+            throw new InvalidParameterException("Could not find ConnectionInfo");
+        }
+        return result;
+    }
+
+    /**
+     * Set the controllers of an existing bridge node.
+     *
+     * @param ovsdbNode where the bridge is
+     * @param bridgeName Name of the bridge
+     * @param controllers controller strings
+     * @return success if the write to md-sal was successful
+     */
+    public boolean setBridgeController(Node ovsdbNode, String bridgeName, List<String> controllers) {
+        return setBridgeController(ovsdbNode, bridgeName, controllers, null, null);
+    }
+
+    /**
+     * Set the controllers of an existing bridge node.
+     *
+     * @param ovsdbNode where the bridge is
+     * @param bridgeName Name of the bridge
+     * @param controllers controller strings
+     * @param maxBackoff Max backoff in milliseconds
+     * @param inactivityProbe inactivity probe in milliseconds
+     * @return success if the write to md-sal was successful
+     */
+    public boolean setBridgeController(Node ovsdbNode, String bridgeName, List<String> controllers,
+            Long maxBackoff, Long inactivityProbe) {
+        LOG.debug("setBridgeController: ovsdbNode: {}, bridgeNode: {}, controller(s): {}",
+                ovsdbNode, bridgeName, controllers);
+
+        InstanceIdentifier<Node> bridgeNodeIid = createInstanceIdentifier(ovsdbNode.key(), bridgeName);
+        Node bridgeNode = mdsalUtils.read(LogicalDatastoreType.CONFIGURATION, bridgeNodeIid);
+        if (bridgeNode == null) {
+            LOG.info("setBridgeController could not find bridge in configuration {}", bridgeNodeIid);
+            return false;
+        }
+
+        OvsdbBridgeAugmentation bridgeAug = extractBridgeAugmentation(bridgeNode);
+
+        //Only add controller entries that do not already exist on this bridge
+        List<ControllerEntry> existingControllerEntries = bridgeAug.getControllerEntry();
+        List<ControllerEntry> newControllerEntries = new ArrayList<>();
+        if (existingControllerEntries != null) {
+            NEW_ENTRY_LOOP:
+            for (ControllerEntry newEntry : createControllerEntries(controllers, maxBackoff, inactivityProbe)) {
+                for (ControllerEntry existingEntry : existingControllerEntries) {
+                    if (newEntry.getTarget().equals(existingEntry.getTarget())) {
+                        continue NEW_ENTRY_LOOP;
+                    }
+                }
+                newControllerEntries.add(newEntry);
+            }
+        } else {
+            newControllerEntries = createControllerEntries(controllers,maxBackoff, inactivityProbe);
+        }
+
+        if (newControllerEntries.isEmpty()) {
+            return true;
+        }
+
+        NodeBuilder nodeBuilder = new NodeBuilder(bridgeNode);
+        OvsdbBridgeAugmentationBuilder augBuilder = new OvsdbBridgeAugmentationBuilder(bridgeAug);
+
+        augBuilder.setControllerEntry(newControllerEntries);
+        nodeBuilder.addAugmentation(OvsdbBridgeAugmentation.class, augBuilder.build());
+        InstanceIdentifier<Node> bridgeIid = createInstanceIdentifier(ovsdbNode.key(), bridgeName);
+        return mdsalUtils.merge(LogicalDatastoreType.CONFIGURATION, bridgeIid, nodeBuilder.build());
+    }
+
     private void setManagedBy(final OvsdbBridgeAugmentationBuilder ovsdbBridgeAugmentationBuilder,
                               final ConnectionInfo connectionInfo) {
         InstanceIdentifier<Node> connectionNodePath = createInstanceIdentifier(connectionInfo);
@@ -539,7 +725,6 @@ public class SouthboundUtils {
     public boolean addTerminationPoint(
             Node bridgeNode, String portName, String type, Map<String, String> options, Map<String, String> externalIds,
             Long ofPort) {
-        InstanceIdentifier<TerminationPoint> tpIid = createTerminationPointInstanceIdentifier(bridgeNode, portName);
         OvsdbTerminationPointAugmentationBuilder tpAugmentationBuilder = new OvsdbTerminationPointAugmentationBuilder();
 
         tpAugmentationBuilder.setName(portName);
@@ -552,7 +737,7 @@ public class SouthboundUtils {
             List<Options> optionsList = new ArrayList<>();
             for (Map.Entry<String, String> entry : options.entrySet()) {
                 OptionsBuilder optionsBuilder = new OptionsBuilder();
-                optionsBuilder.setKey(new OptionsKey(entry.getKey()));
+                optionsBuilder.withKey(new OptionsKey(entry.getKey()));
                 optionsBuilder.setOption(entry.getKey());
                 optionsBuilder.setValue(entry.getValue());
                 optionsList.add(optionsBuilder.build());
@@ -564,7 +749,7 @@ public class SouthboundUtils {
             List<InterfaceExternalIds> externalIdsList = new ArrayList<>();
             for (Map.Entry<String, String> entry : externalIds.entrySet()) {
                 InterfaceExternalIdsBuilder interfaceExternalIdsBuilder = new InterfaceExternalIdsBuilder();
-                interfaceExternalIdsBuilder.setKey(new InterfaceExternalIdsKey(entry.getKey()));
+                interfaceExternalIdsBuilder.withKey(new InterfaceExternalIdsKey(entry.getKey()));
                 interfaceExternalIdsBuilder.setExternalIdKey(entry.getKey());
                 interfaceExternalIdsBuilder.setExternalIdValue(entry.getValue());
                 externalIdsList.add(interfaceExternalIdsBuilder.build());
@@ -573,14 +758,63 @@ public class SouthboundUtils {
         }
 
         TerminationPointBuilder tpBuilder = new TerminationPointBuilder();
-        tpBuilder.setKey(InstanceIdentifier.keyOf(tpIid));
+        InstanceIdentifier<TerminationPoint> tpIid = createTerminationPointInstanceIdentifier(bridgeNode, portName);
+        tpBuilder.withKey(InstanceIdentifier.keyOf(tpIid));
         tpBuilder.addAugmentation(OvsdbTerminationPointAugmentation.class, tpAugmentationBuilder.build());
         /* TODO SB_MIGRATION should this be merge or mdsalUtils.put */
         return mdsalUtils.put(LogicalDatastoreType.CONFIGURATION, tpIid, tpBuilder.build());
     }
 
     public Boolean addTerminationPoint(Node bridgeNode, String portName, String type) {
-        return addTerminationPoint(bridgeNode, portName, type, null, null);
+        return addTerminationPoint(bridgeNode, portName, type, Collections.EMPTY_MAP, null);
+    }
+
+    public Boolean addTerminationPoint(Node bridgeNode, String bridgeName, String portName,
+                                       String type, Map<String, String> options) {
+        OvsdbTerminationPointAugmentationBuilder tpAugmentationBuilder = new OvsdbTerminationPointAugmentationBuilder();
+
+        tpAugmentationBuilder.setName(portName);
+        if (type != null) {
+            tpAugmentationBuilder.setInterfaceType(OVSDB_INTERFACE_TYPE_MAP.get(type));
+        }
+
+        List<Options> optionsList = new ArrayList<>();
+        for (Map.Entry<String, String> entry : options.entrySet()) {
+            OptionsBuilder optionsBuilder = new OptionsBuilder();
+            optionsBuilder.withKey(new OptionsKey(entry.getKey()));
+            optionsBuilder.setOption(entry.getKey());
+            optionsBuilder.setValue(entry.getValue());
+            optionsList.add(optionsBuilder.build());
+        }
+        tpAugmentationBuilder.setOptions(optionsList);
+
+        TerminationPointBuilder tpBuilder = new TerminationPointBuilder();
+        InstanceIdentifier<TerminationPoint> tpIid = createTerminationPointInstanceIdentifier(bridgeNode, portName);
+        tpBuilder.withKey(InstanceIdentifier.keyOf(tpIid));
+        tpBuilder.addAugmentation(OvsdbTerminationPointAugmentation.class, tpAugmentationBuilder.build());
+        /* TODO SB_MIGRATION should this be merge or mdsalUtils.put */
+        return mdsalUtils.put(LogicalDatastoreType.CONFIGURATION, tpIid, tpBuilder.build());
+    }
+
+    public Boolean addTerminationPoint(Node bridgeNode, String bridgeName, String portName, String type) {
+        InstanceIdentifier<TerminationPoint> tpIid = createTerminationPointInstanceIdentifier(bridgeNode, portName);
+        OvsdbTerminationPointAugmentationBuilder tpAugmentationBuilder =
+                new OvsdbTerminationPointAugmentationBuilder();
+
+        tpAugmentationBuilder.setName(portName);
+        if (type != null) {
+            tpAugmentationBuilder.setInterfaceType(OVSDB_INTERFACE_TYPE_MAP.get(type));
+        }
+        TerminationPointBuilder tpBuilder = new TerminationPointBuilder();
+        tpBuilder.withKey(InstanceIdentifier.keyOf(tpIid));
+        tpBuilder.addAugmentation(OvsdbTerminationPointAugmentation.class, tpAugmentationBuilder.build());
+        return mdsalUtils.put(LogicalDatastoreType.CONFIGURATION, tpIid, tpBuilder.build());
+    }
+
+    public Boolean addPatchTerminationPoint(Node node, String bridgeName, String portName, String peerPortName) {
+        Map<String, String> option = new HashMap<>();
+        option.put("peer", peerPortName);
+        return addTerminationPoint(node, bridgeName, portName, PATCH_PORT_TYPE, option);
     }
 
     private String getControllerIPAddress() {
@@ -655,6 +889,18 @@ public class SouthboundUtils {
                             } else {
                                 LOG.warn("Ovsdb Node does not contain connection info: {}", node);
                             }
+                        } else if (tokens.length == 3 && tokens[0].equalsIgnoreCase("ssl")) {
+                            controllersStr.add(OPENFLOW_SECURE_PROTOCOL
+                                    + ":" + tokens[1] + ":" + getControllerOFPort());
+                        } else if (tokens[0].equalsIgnoreCase("pssl")) {
+                            ConnectionInfo connectionInfo = ovsdbNodeAugmentation.getConnectionInfo();
+                            if (connectionInfo != null && connectionInfo.getLocalIp() != null) {
+                                controllerIpStr = String.valueOf(connectionInfo.getLocalIp().getValue());
+                                controllersStr.add(OPENFLOW_SECURE_PROTOCOL
+                                        + ":" + controllerIpStr + ":" + OPENFLOW_PORT);
+                            } else {
+                                LOG.warn("Ovsdb Node does not contain connection info: {}", node);
+                            }
                         } else {
                             LOG.trace("Skipping manager entry {} for node {}",
                                     managerEntry.getTarget(), node.getNodeId().getValue());
@@ -679,11 +925,8 @@ public class SouthboundUtils {
         if (controllersStr.isEmpty()) {
             LOG.warn("Failed to determine OpenFlow controller ip address");
         } else if (LOG.isDebugEnabled()) {
-            controllerIpStr = "";
-            for (String currControllerIpStr : controllersStr) {
-                controllerIpStr += " " + currControllerIpStr;
-            }
-            LOG.debug("Found {} OpenFlow Controller(s) :{}", controllersStr.size(), controllerIpStr);
+            LOG.debug("Found {} OpenFlow Controller(s) :{}", controllersStr.size(),
+                    controllersStr.stream().collect(Collectors.joining(" ")));
         }
 
         return controllersStr;
@@ -691,8 +934,9 @@ public class SouthboundUtils {
 
     private String getLocalControllerHostIpAddress() {
         String ipaddress = null;
-        try{
-            for (Enumeration<NetworkInterface> ifaces = NetworkInterface.getNetworkInterfaces(); ifaces.hasMoreElements();){
+        try {
+            for (Enumeration<NetworkInterface> ifaces = NetworkInterface.getNetworkInterfaces();
+                    ifaces.hasMoreElements();) {
                 NetworkInterface iface = ifaces.nextElement();
 
                 for (Enumeration<InetAddress> inetAddrs = iface.getInetAddresses(); inetAddrs.hasMoreElements();) {
@@ -703,7 +947,7 @@ public class SouthboundUtils {
                     }
                 }
             }
-        }catch (Exception e){
+        } catch (SocketException e) {
             LOG.warn("Exception while fetching local host ip address ", e);
         }
         return ipaddress;
@@ -718,8 +962,19 @@ public class SouthboundUtils {
         return dpid;
     }
 
+    public String getDataPathIdStr(final Node node) {
+        if (node != null) {
+            long dpId = getDataPathId(node);
+            if (dpId != 0) {
+                return String.valueOf(dpId);
+            }
+        }
+
+        return null;
+    }
+
     public String getDatapathId(Node node) {
-        OvsdbBridgeAugmentation ovsdbBridgeAugmentation = node.getAugmentation(OvsdbBridgeAugmentation.class);
+        OvsdbBridgeAugmentation ovsdbBridgeAugmentation = node.augmentation(OvsdbBridgeAugmentation.class);
         return getDatapathId(ovsdbBridgeAugmentation);
     }
 
@@ -730,4 +985,285 @@ public class SouthboundUtils {
         }
         return datapathId;
     }
+
+    public String extractBridgeName(Node node) {
+        return node.augmentation(OvsdbBridgeAugmentation.class).getBridgeName().getValue();
+    }
+
+    public boolean isBridgeOnOvsdbNode(Node ovsdbNode, String bridgeName) {
+        boolean found = false;
+        OvsdbNodeAugmentation ovsdbNodeAugmentation = extractNodeAugmentation(ovsdbNode);
+        if (ovsdbNodeAugmentation != null) {
+            List<ManagedNodeEntry> managedNodes = ovsdbNodeAugmentation.getManagedNodeEntry();
+            if (managedNodes != null) {
+                for (ManagedNodeEntry managedNode : managedNodes) {
+                    InstanceIdentifier<?> bridgeIid = managedNode.getBridgeRef().getValue();
+                    if (bridgeIid.toString().contains(bridgeName)) {
+                        found = true;
+                        break;
+                    }
+                }
+            }
+        }
+        return found;
+    }
+
+    public OvsdbBridgeAugmentation getBridgeFromConfig(Node node, String bridge) {
+        OvsdbBridgeAugmentation ovsdbBridgeAugmentation = null;
+        InstanceIdentifier<Node> bridgeIid =
+                createInstanceIdentifier(node.key(), bridge);
+        Node bridgeNode = mdsalUtils.read(LogicalDatastoreType.CONFIGURATION, bridgeIid);
+        if (bridgeNode != null) {
+            ovsdbBridgeAugmentation = bridgeNode.augmentation(OvsdbBridgeAugmentation.class);
+        }
+        return ovsdbBridgeAugmentation;
+    }
+
+    private void setManagedByForBridge(OvsdbBridgeAugmentationBuilder ovsdbBridgeAugmentationBuilder,
+                                       NodeKey ovsdbNodeKey) {
+        InstanceIdentifier<Node> connectionNodePath = createInstanceIdentifier(ovsdbNodeKey.getNodeId());
+        ovsdbBridgeAugmentationBuilder.setManagedBy(new OvsdbNodeRef(connectionNodePath));
+    }
+
+    public boolean isOvsdbNodeDpdk(Node ovsdbNode) {
+        boolean found = false;
+        OvsdbNodeAugmentation ovsdbNodeAugmentation = extractNodeAugmentation(ovsdbNode);
+        if (ovsdbNodeAugmentation != null) {
+            List<InterfaceTypeEntry> ifTypes = ovsdbNodeAugmentation.getInterfaceTypeEntry();
+            if (ifTypes != null) {
+                for (InterfaceTypeEntry ifType : ifTypes) {
+                    if (ifType.getInterfaceType().equals(InterfaceTypeDpdk.class)) {
+                        found = true;
+                        break;
+                    }
+                }
+            }
+        }
+        return found;
+    }
+
+    private List<ControllerEntry> createControllerEntries(List<String> controllersStr,
+            Long maxBackoff, Long inactivityProbe) {
+        List<ControllerEntry> controllerEntries = new ArrayList<>();
+        if (controllersStr != null) {
+            for (String controllerStr : controllersStr) {
+                ControllerEntryBuilder controllerEntryBuilder = new ControllerEntryBuilder();
+                controllerEntryBuilder.setTarget(new Uri(controllerStr));
+                if (maxBackoff != null) {
+                    controllerEntryBuilder.setMaxBackoff(maxBackoff);
+                }
+                if (inactivityProbe != null) {
+                    controllerEntryBuilder.setInactivityProbe(inactivityProbe);
+                }
+                controllerEntries.add(controllerEntryBuilder.build());
+            }
+        }
+        return controllerEntries;
+    }
+
+    public OvsdbTerminationPointAugmentation extractTerminationPointAugmentation(Node bridgeNode, String portName) {
+        if (bridgeNode.augmentation(OvsdbBridgeAugmentation.class) != null) {
+            List<OvsdbTerminationPointAugmentation> tpAugmentations = extractTerminationPointAugmentations(bridgeNode);
+            for (OvsdbTerminationPointAugmentation ovsdbTerminationPointAugmentation : tpAugmentations) {
+                if (ovsdbTerminationPointAugmentation.getName().equals(portName)) {
+                    return ovsdbTerminationPointAugmentation;
+                }
+            }
+        }
+        return null;
+    }
+
+    public List<OvsdbTerminationPointAugmentation> extractTerminationPointAugmentations(Node node) {
+        List<OvsdbTerminationPointAugmentation> tpAugmentations = new ArrayList<>();
+        if (node == null) {
+            LOG.error("extractTerminationPointAugmentations: Node value is null");
+            return Collections.emptyList();
+        }
+        List<TerminationPoint> terminationPoints = node.getTerminationPoint();
+        if (terminationPoints != null && !terminationPoints.isEmpty()) {
+            for (TerminationPoint tp : terminationPoints) {
+                OvsdbTerminationPointAugmentation ovsdbTerminationPointAugmentation =
+                        tp.augmentation(OvsdbTerminationPointAugmentation.class);
+                if (ovsdbTerminationPointAugmentation != null) {
+                    tpAugmentations.add(ovsdbTerminationPointAugmentation);
+                }
+            }
+        }
+        return tpAugmentations;
+    }
+
+    /**
+     * Extract the <code>OvsdbTerminationPointAugmentation</code> for the particular <code>node</code> identified by
+     * <code>portName</code>.
+     */
+    public OvsdbTerminationPointAugmentation getTerminationPointOfBridge(Node node, String portName) {
+        OvsdbTerminationPointAugmentation tpAugmentation = extractTerminationPointAugmentation(node,portName);
+        if (tpAugmentation == null) {
+            List<OvsdbTerminationPointAugmentation> tpAugmentations = readTerminationPointAugmentations(node);
+            if (tpAugmentations != null) {
+                for (OvsdbTerminationPointAugmentation ovsdbTpAugmentation : tpAugmentations) {
+                    if (ovsdbTpAugmentation.getName().equals(portName)) {
+                        return ovsdbTpAugmentation;
+                    }
+                }
+            }
+        }
+        return tpAugmentation;
+    }
+
+    /**
+     * Read the list of <code>OvsdbTerminationPointAugmentation</code> for the particular <code>node</code>.
+     */
+    public List<OvsdbTerminationPointAugmentation> readTerminationPointAugmentations(Node node) {
+        if (node == null) {
+            LOG.error("readTerminationPointAugmentations: Node value is null");
+            return Collections.emptyList();
+        }
+        Node operNode = mdsalUtils.read(LogicalDatastoreType.OPERATIONAL, InstanceIdentifier
+                .create(NetworkTopology.class)
+                .child(Topology.class, new TopologyKey(OVSDB_TOPOLOGY_ID))
+                .child(Node.class, new NodeKey(node.getNodeId())));
+        if (operNode != null) {
+            return extractTerminationPointAugmentations(operNode);
+        }
+        return new ArrayList<>();
+    }
+
+    /**
+     * Get all OVSDB nodes from topology.
+     * @return a list of nodes or null if the topology could not found
+     */
+    public List<Node> getOvsdbNodes() {
+        InstanceIdentifier<Topology> inst = InstanceIdentifier.create(NetworkTopology.class).child(Topology.class,
+                new TopologyKey(OVSDB_TOPOLOGY_ID));
+        Topology topology = mdsalUtils.read(LogicalDatastoreType.OPERATIONAL, inst);
+        return topology != null ? topology.getNode() : null;
+    }
+
+    /**
+     * Get OpenvSwitch other-config by key.
+     * @param node OVSDB node
+     * @param key key to extract from other-config
+     * @return the value for key or null if key not found
+     */
+    public String getOpenvswitchOtherConfig(Node node, String key) {
+        OvsdbNodeAugmentation ovsdbNode = node.augmentation(OvsdbNodeAugmentation.class);
+        if (ovsdbNode == null) {
+            Node nodeFromReadOvsdbNode = readOvsdbNode(node);
+            if (nodeFromReadOvsdbNode != null) {
+                ovsdbNode = nodeFromReadOvsdbNode.augmentation(OvsdbNodeAugmentation.class);
+            }
+        }
+
+        if (ovsdbNode != null && ovsdbNode.getOpenvswitchOtherConfigs() != null) {
+            for (OpenvswitchOtherConfigs openvswitchOtherConfigs : ovsdbNode.getOpenvswitchOtherConfigs()) {
+                if (openvswitchOtherConfigs.getOtherConfigKey().equals(key)) {
+                    return openvswitchOtherConfigs.getOtherConfigValue();
+                }
+            }
+        }
+
+        return null;
+    }
+
+    public static TerminationPoint getTerminationPointByExternalId(final Node bridgeNode, final String interfaceName) {
+        if (bridgeNode.getTerminationPoint() != null) {
+            for (TerminationPoint tp : bridgeNode.getTerminationPoint()) {
+                OvsdbTerminationPointAugmentation ovsdbTp = tp.augmentation(OvsdbTerminationPointAugmentation.class);
+                String externalIdValue = getExternalInterfaceIdValue(ovsdbTp);
+                if (externalIdValue != null && externalIdValue.equals(interfaceName)) {
+                    LOG.debug("Found matching termination point with iface-id {} on bridgeNode {}, returning tp {}",
+                            interfaceName, bridgeNode, tp);
+                    return tp;
+                }
+            }
+        }
+        return null;
+    }
+
+    // This utility shouldn't be called often, as it reads all OVSDB nodes each time - not good for scale
+    public Node getNodeByTerminationPointExternalId(final String interfaceName) {
+        List<Node> nodes = getOvsdbNodes();
+        if (nodes != null) {
+            for (Node node : nodes) {
+                TerminationPoint tp = getTerminationPointByExternalId(node, interfaceName);
+                if (tp != null) {
+                    return node;
+                }
+            }
+        }
+        return null;
+    }
+
+    public static String getExternalInterfaceIdValue(final OvsdbTerminationPointAugmentation ovsdbTp) {
+        if (ovsdbTp != null) {
+            List<InterfaceExternalIds> ifaceExtIds = ovsdbTp.getInterfaceExternalIds();
+            if (ifaceExtIds != null) {
+                for (InterfaceExternalIds entry : ifaceExtIds) {
+                    if (entry.getExternalIdKey().equals(EXTERNAL_INTERFACE_ID_KEY)) {
+                        return entry.getExternalIdValue();
+                    }
+                }
+            }
+        }
+        return null;
+    }
+
+    public String getDatapathIdFromNodeInstanceId(InstanceIdentifier<Node> nodeInstanceId) {
+        Node node = mdsalUtils.read(LogicalDatastoreType.OPERATIONAL, nodeInstanceId);
+        String dpId = node != null ? getDataPathIdStr(node) : null;
+        if (dpId != null) {
+            return dpId;
+        }
+        return null;
+    }
+
+    public static boolean compareDbVersionToMinVersion(final String dbVersion, final String minVersion) {
+        final Matcher dbVersionMatcher = PATTERN.matcher(dbVersion);
+        final Matcher minVersionMatcher = PATTERN.matcher(minVersion);
+        LOG.debug("dbVersion {}, minVersion {}", dbVersion, minVersion);
+        if (!dbVersionMatcher.find()) {
+            LOG.error("Invalid DB version format {}", dbVersion);
+            return false;
+        }
+        if (!minVersionMatcher.find()) {
+            LOG.error("Invalid Min DB version format {}", minVersion);
+            return false;
+        }
+
+        if (dbVersion != null && !dbVersion.isEmpty() && minVersion != null && !minVersion.isEmpty()) {
+            final int dbVersionMatch1 = Integer.parseInt(dbVersionMatcher.group(1));
+            final int dbVersionMatch2 = Integer.parseInt(dbVersionMatcher.group(2));
+            final int dbVersionMatch3 = Integer.parseInt(dbVersionMatcher.group(3));
+            final int minVersionMatch1 = Integer.parseInt(minVersionMatcher.group(1));
+            final int minVersionMatch2 = Integer.parseInt(minVersionMatcher.group(2));
+            final int minVersionMatch3 = Integer.parseInt(minVersionMatcher.group(3));
+            if (dbVersionMatch1 == minVersionMatch1 && dbVersionMatch2 == minVersionMatch2
+                    && dbVersionMatch3 == minVersionMatch3) {
+                return true;
+            }
+
+            if (dbVersionMatch1 > minVersionMatch1) {
+                return true;
+            }
+
+            if (dbVersionMatch1 < minVersionMatch1) {
+                return false;
+            }
+
+            // major version is equal
+            if (dbVersionMatch2 > minVersionMatch2) {
+                return true;
+            }
+
+            if (dbVersionMatch2 < minVersionMatch2) {
+                return false;
+            }
+
+            if (dbVersionMatch3 > minVersionMatch3) {
+                return true;
+            }
+        }
+        return false;
+    }
 }