Fixing a ClassCastException issue with an incorect Row to TypedClass cast introduced...
[ovsdb.git] / neutron / src / main / java / org / opendaylight / ovsdb / neutron / provider / OF13Provider.java
index 8b9348469074aa6e24db846bbf5ea9f5810c6e1a..0b1d4c1dda419f3f25deadec60fafddeb5238e03 100644 (file)
@@ -12,6 +12,7 @@ package org.opendaylight.ovsdb.neutron.provider;
 import java.math.BigInteger;
 import java.net.InetAddress;
 import java.util.ArrayList;
+import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
 import java.util.Set;
@@ -28,20 +29,19 @@ import org.opendaylight.controller.sal.utils.ServiceHelper;
 import org.opendaylight.controller.sal.utils.Status;
 import org.opendaylight.controller.sal.utils.StatusCode;
 import org.opendaylight.controller.switchmanager.ISwitchManager;
-import org.opendaylight.ovsdb.lib.notation.OvsDBMap;
-import org.opendaylight.ovsdb.lib.notation.OvsDBSet;
+import org.opendaylight.ovsdb.lib.notation.Row;
 import org.opendaylight.ovsdb.lib.notation.UUID;
-import org.opendaylight.ovsdb.lib.table.Bridge;
-import org.opendaylight.ovsdb.lib.table.Interface;
-import org.opendaylight.ovsdb.lib.table.Port;
 import org.opendaylight.ovsdb.neutron.IAdminConfigManager;
 import org.opendaylight.ovsdb.neutron.IInternalNetworkManager;
 import org.opendaylight.ovsdb.neutron.IMDSALConsumer;
-import org.opendaylight.ovsdb.neutron.NetworkHandler;
 import org.opendaylight.ovsdb.neutron.ITenantNetworkManager;
+import org.opendaylight.ovsdb.neutron.NetworkHandler;
 import org.opendaylight.ovsdb.plugin.IConnectionServiceInternal;
 import org.opendaylight.ovsdb.plugin.OVSDBConfigService;
 import org.opendaylight.ovsdb.plugin.StatusWithUuid;
+import org.opendaylight.ovsdb.schema.openvswitch.Bridge;
+import org.opendaylight.ovsdb.schema.openvswitch.Interface;
+import org.opendaylight.ovsdb.schema.openvswitch.Port;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Ipv4Prefix;
 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;
@@ -54,19 +54,19 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.acti
 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.OutputActionCaseBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.PopVlanActionCase;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.PopVlanActionCaseBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.PushVlanActionCaseBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.SetFieldCaseBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.SetNwDstActionCaseBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.SetNwSrcActionCaseBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.SetVlanIdActionCaseBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.PushVlanActionCaseBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.dec.nw.ttl._case.DecNwTtl;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.dec.nw.ttl._case.DecNwTtlBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.drop.action._case.DropAction;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.drop.action._case.DropActionBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.group.action._case.GroupActionBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.output.action._case.OutputActionBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.push.vlan.action._case.PushVlanActionBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.pop.vlan.action._case.PopVlanActionBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.push.vlan.action._case.PushVlanActionBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.set.field._case.SetFieldBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.set.nw.dst.action._case.SetNwDstActionBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.set.nw.src.action._case.SetNwSrcActionBuilder;
@@ -96,6 +96,7 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instru
 import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.BucketId;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.GroupId;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.GroupTypes;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.group.Buckets;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.group.BucketsBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.group.buckets.Bucket;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.group.buckets.BucketBuilder;
@@ -103,7 +104,6 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.group
 import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.groups.Group;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.groups.GroupBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.groups.GroupKey;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.group.Buckets;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeConnectorId;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeId;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.Nodes;
@@ -186,11 +186,13 @@ public class OF13Provider implements NetworkProvider {
 
     private boolean isTunnelPresent(Node node, String tunnelName, String bridgeUUID) throws Exception {
         OVSDBConfigService ovsdbTable = (OVSDBConfigService)ServiceHelper.getGlobalInstance(OVSDBConfigService.class, this);
-        Bridge bridge = (Bridge)ovsdbTable.getRow(node, Bridge.NAME.getName(), bridgeUUID);
+        Row bridgeRow = ovsdbTable.getRow(node, ovsdbTable.getTableName(node, Bridge.class), bridgeUUID);
+        Bridge bridge = ovsdbTable.getTypedRow(node, Bridge.class, bridgeRow);
         if (bridge != null) {
-            Set<UUID> ports = bridge.getPorts();
+            Set<UUID> ports = bridge.getPortsColumn().getData();
             for (UUID portUUID : ports) {
-                Port port = (Port)ovsdbTable.getRow(node, Port.NAME.getName(), portUUID.toString());
+                Row portRow = ovsdbTable.getRow(node, ovsdbTable.getTableName(node, Port.class), portUUID.toString());
+                Port port = ovsdbTable.getTypedRow(node, Port.class, portRow);
                 if (port != null && port.getName().equalsIgnoreCase(tunnelName)) return true;
             }
         }
@@ -199,11 +201,13 @@ public class OF13Provider implements NetworkProvider {
 
     private String getPortUuid(Node node, String name, String bridgeUUID) throws Exception {
         OVSDBConfigService ovsdbTable = (OVSDBConfigService)ServiceHelper.getGlobalInstance(OVSDBConfigService.class, this);
-        Bridge bridge = (Bridge)ovsdbTable.getRow(node, Bridge.NAME.getName(), bridgeUUID);
+        Row bridgeRow = ovsdbTable.getRow(node, ovsdbTable.getTableName(node, Bridge.class), bridgeUUID);
+        Bridge bridge = ovsdbTable.getTypedRow(node, Bridge.class, bridgeRow);
         if (bridge != null) {
-            Set<UUID> ports = bridge.getPorts();
+            Set<UUID> ports = bridge.getPortsColumn().getData();
             for (UUID portUUID : ports) {
-                Port port = (Port)ovsdbTable.getRow(node, Port.NAME.getName(), portUUID.toString());
+                Row portRow = ovsdbTable.getRow(node, ovsdbTable.getTableName(node, Port.class), portUUID.toString());
+                Port port = ovsdbTable.getTypedRow(node, Port.class, portRow);
                 if (port != null && port.getName().equalsIgnoreCase(name)) return portUUID.toString();
             }
         }
@@ -215,10 +219,10 @@ public class OF13Provider implements NetworkProvider {
             String bridgeUUID = null;
             String tunnelBridgeName = adminConfigManager.getIntegrationBridgeName();
             OVSDBConfigService ovsdbTable = (OVSDBConfigService)ServiceHelper.getGlobalInstance(OVSDBConfigService.class, this);
-            Map<String, org.opendaylight.ovsdb.lib.table.internal.Table<?>> bridgeTable = ovsdbTable.getRows(node, Bridge.NAME.getName());
+            Map<String, Row> bridgeTable = ovsdbTable.getRows(node, ovsdbTable.getTableName(node, Bridge.class));
             if (bridgeTable != null) {
                 for (String uuid : bridgeTable.keySet()) {
-                    Bridge bridge = (Bridge)bridgeTable.get(uuid);
+                    Bridge bridge = ovsdbTable.getTypedRow(node,Bridge.class, bridgeTable.get(uuid));
                     if (bridge.getName().equals(tunnelBridgeName)) {
                         bridgeUUID = uuid;
                         break;
@@ -236,9 +240,9 @@ public class OF13Provider implements NetworkProvider {
                 return new Status(StatusCode.SUCCESS);
             }
 
-            Port tunnelPort = new Port();
+            Port tunnelPort = ovsdbTable.createTypedRow(node, Port.class);
             tunnelPort.setName(portName);
-            StatusWithUuid statusWithUuid = ovsdbTable.insertRow(node, Port.NAME.getName(), bridgeUUID, tunnelPort);
+            StatusWithUuid statusWithUuid = ovsdbTable.insertRow(node, ovsdbTable.getTableName(node, Port.class), bridgeUUID, tunnelPort.getRow());
             if (!statusWithUuid.isSuccess()) {
                 logger.error("Failed to insert Tunnel port {} in {}", portName, bridgeUUID);
                 return statusWithUuid;
@@ -248,8 +252,9 @@ public class OF13Provider implements NetworkProvider {
             String interfaceUUID = null;
             int timeout = 6;
             while ((interfaceUUID == null) && (timeout > 0)) {
-                tunnelPort = (Port)ovsdbTable.getRow(node, Port.NAME.getName(), tunnelPortUUID);
-                OvsDBSet<UUID> interfaces = tunnelPort.getInterfaces();
+                Row portRow = ovsdbTable.getRow(node, ovsdbTable.getTableName(node, Port.class), tunnelPortUUID);
+                tunnelPort = ovsdbTable.getTypedRow(node, Port.class, portRow);
+                Set<UUID> interfaces = tunnelPort.getInterfacesColumn().getData();
                 if (interfaces == null || interfaces.size() == 0) {
                     // Wait for the OVSDB update to sync up the Local cache.
                     Thread.sleep(500);
@@ -257,7 +262,7 @@ public class OF13Provider implements NetworkProvider {
                     continue;
                 }
                 interfaceUUID = interfaces.toArray()[0].toString();
-                Interface intf = (Interface)ovsdbTable.getRow(node, Interface.NAME.getName(), interfaceUUID);
+                Interface intf = (Interface)ovsdbTable.getRow(node, ovsdbTable.getTableName(node, Interface.class), interfaceUUID);
                 if (intf == null) interfaceUUID = null;
             }
 
@@ -266,14 +271,14 @@ public class OF13Provider implements NetworkProvider {
                 return new Status(StatusCode.INTERNALERROR);
             }
 
-            Interface tunInterface = new Interface();
+            Interface tunInterface = ovsdbTable.createTypedRow(node, Interface.class);
             tunInterface.setType(tunnelType);
-            OvsDBMap<String, String> options = new OvsDBMap<String, String>();
+            Map<String, String> options = new HashMap<String, String>();
             options.put("key", "flow");
             options.put("local_ip", src.getHostAddress());
             options.put("remote_ip", dst.getHostAddress());
             tunInterface.setOptions(options);
-            Status status = ovsdbTable.updateRow(node, Interface.NAME.getName(), tunnelPortUUID, interfaceUUID, tunInterface);
+            Status status = ovsdbTable.updateRow(node, ovsdbTable.getTableName(node, Interface.class), tunnelPortUUID, interfaceUUID, tunInterface.getRow());
             logger.debug("Tunnel {} add status : {}", tunInterface, status);
             return status;
         } catch (Exception e) {
@@ -287,10 +292,10 @@ public class OF13Provider implements NetworkProvider {
         try {
             String bridgeUUID = null;
             OVSDBConfigService ovsdbTable = (OVSDBConfigService)ServiceHelper.getGlobalInstance(OVSDBConfigService.class, this);
-            Map<String, org.opendaylight.ovsdb.lib.table.internal.Table<?>> bridgeTable = ovsdbTable.getRows(node, Bridge.NAME.getName());
+            Map<String, Row> bridgeTable = ovsdbTable.getRows(node, ovsdbTable.getTableName(node, Bridge.class));
             if (bridgeTable != null) {
                 for (String uuid : bridgeTable.keySet()) {
-                    Bridge bridge = (Bridge)bridgeTable.get(uuid);
+                    Bridge bridge = ovsdbTable.getTypedRow(node, Bridge.class, bridgeTable.get(uuid));
                     if (bridge.getName().equals(bridgeName)) {
                         bridgeUUID = uuid;
                         break;
@@ -305,7 +310,7 @@ public class OF13Provider implements NetworkProvider {
             String portUUID = this.getPortUuid(node, portName, bridgeUUID);
             Status status = new Status(StatusCode.SUCCESS);
             if (portUUID != null) {
-               status = ovsdbTable.deleteRow(node, Port.NAME.getName(), portUUID);
+               status = ovsdbTable.deleteRow(node, ovsdbTable.getTableName(node, Port.class), portUUID);
                if (!status.isSuccess()) {
                    logger.error("Failed to delete port {} in {} status : {}", portName, bridgeUUID,
                                 status);
@@ -754,6 +759,20 @@ public class OF13Provider implements NetworkProvider {
          handleVlanMiss(dpid, TABLE_1_ISOLATE_TENANT, TABLE_2_LOCAL_FORWARD,
                         segmentationId, ethPort, false);
    }
+    private Long getDpid (Node node, String bridgeUuid) {
+        try {
+            OVSDBConfigService ovsdbTable = (OVSDBConfigService) ServiceHelper.getGlobalInstance(OVSDBConfigService.class, this);
+            Row bridgeRow =  ovsdbTable.getRow(node, ovsdbTable.getTableName(node, Bridge.class), bridgeUuid);
+            Bridge bridge = ovsdbTable.getTypedRow(node, Bridge.class, bridgeRow);
+            Set<String> dpids = bridge.getDatapathIdColumn().getData();
+            if (dpids == null || dpids.size() == 0) return 0L;
+            return Long.valueOf(HexEncode.stringToLong((String) dpids.toArray()[0]));
+        } catch (Exception e) {
+            logger.error("Error finding Bridge's OF DPID", e);
+            return 0L;
+        }
+    }
+
     private Long getIntegrationBridgeOFDPID (Node node) {
         try {
             String bridgeName = adminConfigManager.getIntegrationBridgeName();
@@ -763,16 +782,29 @@ public class OF13Provider implements NetworkProvider {
                 return 0L;
             }
 
-            OVSDBConfigService ovsdbTable = (OVSDBConfigService) ServiceHelper.getGlobalInstance(OVSDBConfigService.class, this);
-            Bridge bridge = (Bridge) ovsdbTable.getRow(node, Bridge.NAME.getName(), brIntId);
-            Set<String> dpids = bridge.getDatapath_id();
-            if (dpids == null || dpids.size() == 0) return 0L;
-            return Long.valueOf(HexEncode.stringToLong((String) dpids.toArray()[0]));
+            return getDpid(node, brIntId);
         } catch (Exception e) {
             logger.error("Error finding Integration Bridge's OF DPID", e);
             return 0L;
         }
     }
+
+    private Long getExternalBridgeDpid (Node node) {
+        try {
+            String bridgeName = adminConfigManager.getExternalBridgeName();
+            String brUuid = this.getInternalBridgeUUID(node, bridgeName);
+            if (brUuid == null) {
+                logger.error("Unable to spot Bridge Identifier for {} in {}", bridgeName, node);
+                return 0L;
+            }
+
+            return getDpid(node, brUuid);
+        } catch (Exception e) {
+            logger.error("Error finding External Bridge's OF DPID", e);
+            return 0L;
+        }
+    }
+
     private void programLocalRules (String networkType, String segmentationId, Node node, Interface intf) {
         try {
             Long dpid = this.getIntegrationBridgeOFDPID(node);
@@ -781,14 +813,14 @@ public class OF13Provider implements NetworkProvider {
                 return;
             }
 
-            Set<BigInteger> of_ports = intf.getOfport();
+            Set<Integer> of_ports = intf.getOpenFlowPortColumn().getData();
             if (of_ports == null || of_ports.size() <= 0) {
                 logger.error("Could NOT Identify OF value for port {} on {}", intf.getName(), node);
                 return;
             }
-            long localPort = ((BigInteger)of_ports.toArray()[0]).longValue();
+            long localPort = ((Integer)of_ports.toArray()[0]).longValue();
 
-            Map<String, String> externalIds = intf.getExternal_ids();
+            Map<String, String> externalIds = intf.getExternalIdsColumn().getData();
             if (externalIds == null) {
                 logger.error("No external_ids seen in {}", intf);
                 return;
@@ -822,14 +854,14 @@ public class OF13Provider implements NetworkProvider {
                 return;
             }
 
-            Set<BigInteger> of_ports = intf.getOfport();
+            Set<Integer> of_ports = intf.getOpenFlowPortColumn().getData();
             if (of_ports == null || of_ports.size() <= 0) {
                 logger.error("Could NOT Identify OF value for port {} on {}", intf.getName(), node);
                 return;
             }
-            long localPort = ((BigInteger)of_ports.toArray()[0]).longValue();
+            long localPort = ((Integer)of_ports.toArray()[0]).longValue();
 
-            Map<String, String> externalIds = intf.getExternal_ids();
+            Map<String, String> externalIds = intf.getExternalIdsColumn().getData();
             if (externalIds == null) {
                 logger.error("No external_ids seen in {}", intf);
                 return;
@@ -866,14 +898,14 @@ public class OF13Provider implements NetworkProvider {
             }
             OVSDBConfigService ovsdbTable = (OVSDBConfigService) ServiceHelper.getGlobalInstance(OVSDBConfigService.class, this);
 
-            Set<BigInteger> of_ports = intf.getOfport();
+            Set<Integer> of_ports = intf.getOpenFlowPortColumn().getData();
             if (of_ports == null || of_ports.size() <= 0) {
                 logger.error("Could NOT Identify OF value for port {} on {}", intf.getName(), node);
                 return;
             }
-            long localPort = ((BigInteger)of_ports.toArray()[0]).longValue();
+            long localPort = ((Integer)of_ports.toArray()[0]).longValue();
 
-            Map<String, String> externalIds = intf.getExternal_ids();
+            Map<String, String> externalIds = intf.getExternalIdsColumn().getData();
             if (externalIds == null) {
                 logger.error("No external_ids seen in {}", intf);
                 return;
@@ -885,17 +917,17 @@ public class OF13Provider implements NetworkProvider {
                 return;
             }
 
-            Map<String, org.opendaylight.ovsdb.lib.table.internal.Table<?>> intfs = ovsdbTable.getRows(node, Interface.NAME.getName());
+            Map<String, Row> intfs = ovsdbTable.getRows(node, ovsdbTable.getTableName(node, Interface.class));
             if (intfs != null) {
-                for (org.opendaylight.ovsdb.lib.table.internal.Table<?> row : intfs.values()) {
-                    Interface tunIntf = (Interface)row;
+                for (Row row : intfs.values()) {
+                    Interface tunIntf = ovsdbTable.getTypedRow(node, Interface.class, row);
                     if (tunIntf.getName().equals(this.getTunnelName(tunnelType, dst))) {
-                        of_ports = tunIntf.getOfport();
+                        of_ports = tunIntf.getOpenFlowPortColumn().getData();
                         if (of_ports == null || of_ports.size() <= 0) {
                             logger.error("Could NOT Identify Tunnel port {} on {}", tunIntf.getName(), node);
                             continue;
                         }
-                        long tunnelOFPort = ((BigInteger)of_ports.toArray()[0]).longValue();
+                        long tunnelOFPort = ((Integer)of_ports.toArray()[0]).longValue();
 
                         if (tunnelOFPort == -1) {
                             logger.error("Could NOT Identify Tunnel port {} -> OF ({}) on {}", tunIntf.getName(), tunnelOFPort, node);
@@ -930,14 +962,14 @@ public class OF13Provider implements NetworkProvider {
             }
             OVSDBConfigService ovsdbTable = (OVSDBConfigService) ServiceHelper.getGlobalInstance(OVSDBConfigService.class, this);
 
-            Set<BigInteger> of_ports = intf.getOfport();
+            Set<Integer> of_ports = intf.getOpenFlowPortColumn().getData();
             if (of_ports == null || of_ports.size() <= 0) {
                 logger.error("Could NOT Identify OF value for port {} on {}", intf.getName(), node);
                 return;
             }
             long localPort = ((BigInteger)of_ports.toArray()[0]).longValue();
 
-            Map<String, String> externalIds = intf.getExternal_ids();
+            Map<String, String> externalIds = intf.getExternalIdsColumn().getData();
             if (externalIds == null) {
                 logger.error("No external_ids seen in {}", intf);
                 return;
@@ -949,12 +981,12 @@ public class OF13Provider implements NetworkProvider {
                 return;
             }
 
-            Map<String, org.opendaylight.ovsdb.lib.table.internal.Table<?>> intfs = ovsdbTable.getRows(node, Interface.NAME.getName());
+            Map<String, Row> intfs = ovsdbTable.getRows(node, ovsdbTable.getTableName(node, Interface.class));
             if (intfs != null) {
-                for (org.opendaylight.ovsdb.lib.table.internal.Table<?> row : intfs.values()) {
-                    Interface tunIntf = (Interface)row;
+                for (Row row : intfs.values()) {
+                    Interface tunIntf = ovsdbTable.getTypedRow(node, Interface.class, row);
                     if (tunIntf.getName().equals(this.getTunnelName(tunnelType, dst))) {
-                        of_ports = tunIntf.getOfport();
+                        of_ports = tunIntf.getOpenFlowPortColumn().getData();
                         if (of_ports == null || of_ports.size() <= 0) {
                             logger.error("Could NOT Identify Tunnel port {} on {}", tunIntf.getName(), node);
                             continue;
@@ -994,10 +1026,10 @@ public class OF13Provider implements NetworkProvider {
             }
             OVSDBConfigService ovsdbTable = (OVSDBConfigService) ServiceHelper.getGlobalInstance(OVSDBConfigService.class, this);
 
-            Set<BigInteger> of_ports = intf.getOfport();
+            Set<Integer> of_ports = intf.getOpenFlowPortColumn().getData();
             int timeout = 6;
             while ((of_ports == null) && (timeout > 0)) {
-                of_ports = intf.getOfport();
+                of_ports = intf.getOpenFlowPortColumn().getData();
                 if (of_ports == null || of_ports.size() <= 0) {
                     // Wait for the OVSDB update to sync up the Local cache.
                     Thread.sleep(500);
@@ -1010,7 +1042,7 @@ public class OF13Provider implements NetworkProvider {
                 return;
             }
 
-            Map<String, String> externalIds = intf.getExternal_ids();
+            Map<String, String> externalIds = intf.getExternalIdsColumn().getData();
             if (externalIds == null) {
                 logger.error("No external_ids seen in {}", intf);
                 return;
@@ -1022,15 +1054,15 @@ public class OF13Provider implements NetworkProvider {
                 return;
             }
 
-            Map<String, org.opendaylight.ovsdb.lib.table.internal.Table<?>> intfs = ovsdbTable.getRows(node, Interface.NAME.getName());
+            Map<String, Row> intfs = ovsdbTable.getRows(node, ovsdbTable.getTableName(node, Interface.class));
             if (intfs != null) {
-                for (org.opendaylight.ovsdb.lib.table.internal.Table<?> row : intfs.values()) {
-                    Interface ethIntf = (Interface)row;
+                for (Row row : intfs.values()) {
+                    Interface ethIntf = ovsdbTable.getTypedRow(node, Interface.class, row);
                     if (ethIntf.getName().equalsIgnoreCase(adminConfigManager.getPhysicalInterfaceName(node, network.getProviderPhysicalNetwork()))) {
-                        of_ports = ethIntf.getOfport();
+                        of_ports = ethIntf.getOpenFlowPortColumn().getData();
                         timeout = 6;
                         while ((of_ports == null) && (timeout > 0)) {
-                            of_ports = ethIntf.getOfport();
+                            of_ports = ethIntf.getOpenFlowPortColumn().getData();
                             if (of_ports == null || of_ports.size() <= 0) {
                                 // Wait for the OVSDB update to sync up the Local cache.
                                 Thread.sleep(500);
@@ -1075,13 +1107,13 @@ public class OF13Provider implements NetworkProvider {
             }
             OVSDBConfigService ovsdbTable = (OVSDBConfigService) ServiceHelper.getGlobalInstance(OVSDBConfigService.class, this);
 
-            Set<BigInteger> of_ports = intf.getOfport();
+            Set<Integer> of_ports = intf.getOpenFlowPortColumn().getData();
             if (of_ports == null || of_ports.size() <= 0) {
                 logger.error("Could NOT Identify OF value for port {} on {}", intf.getName(), node);
                 return;
             }
 
-            Map<String, String> externalIds = intf.getExternal_ids();
+            Map<String, String> externalIds = intf.getExternalIdsColumn().getData();
             if (externalIds == null) {
                 logger.error("No external_ids seen in {}", intf);
                 return;
@@ -1093,13 +1125,13 @@ public class OF13Provider implements NetworkProvider {
                 return;
             }
 
-            Map<String, org.opendaylight.ovsdb.lib.table.internal.Table<?>> intfs = ovsdbTable.getRows(node, Interface.NAME.getName());
+            Map<String, Row> intfs = ovsdbTable.getRows(node, ovsdbTable.getTableName(node, Interface.class));
             if (intfs != null) {
-                for (org.opendaylight.ovsdb.lib.table.internal.Table<?> row : intfs.values()) {
-                    Interface ethIntf = (Interface)row;
+                for (Row row : intfs.values()) {
+                    Interface ethIntf = ovsdbTable.getTypedRow(node, Interface.class, row);
                     if (ethIntf.getName().equalsIgnoreCase(adminConfigManager.getPhysicalInterfaceName(node,
                                                                    network.getProviderPhysicalNetwork()))) {
-                        of_ports = ethIntf.getOfport();
+                        of_ports = ethIntf.getOpenFlowPortColumn().getData();
                         if (of_ports == null || of_ports.size() <= 0) {
                             logger.error("Could NOT Identify eth port {} on {}", ethIntf.getName(), node);
                             continue;
@@ -1184,10 +1216,10 @@ public class OF13Provider implements NetworkProvider {
     private Status triggerInterfaceUpdates(Node node) {
         try {
             OVSDBConfigService ovsdbTable = (OVSDBConfigService)ServiceHelper.getGlobalInstance(OVSDBConfigService.class, this);
-            Map<String, org.opendaylight.ovsdb.lib.table.internal.Table<?>> intfs = ovsdbTable.getRows(node, Interface.NAME.getName());
+            Map<String, Row> intfs = ovsdbTable.getRows(node, ovsdbTable.getTableName(node, Interface.class));
             if (intfs != null) {
-                for (org.opendaylight.ovsdb.lib.table.internal.Table<?> row : intfs.values()) {
-                    Interface intf = (Interface)row;
+                for (Row row : intfs.values()) {
+                    Interface intf = ovsdbTable.getTypedRow(node, Interface.class, row);
                     NeutronNetwork network = tenantNetworkManager.getTenantNetworkForInterface(intf);
                     logger.debug("Trigger Interface update for {}", intf);
                     if (network != null) {
@@ -1217,14 +1249,14 @@ public class OF13Provider implements NetworkProvider {
 
         logger.info("Delete intf " + intf.getName() + " isLastInstanceOnNode " + isLastInstanceOnNode);
         List<String> phyIfName = adminConfigManager.getAllPhysicalInterfaceNames(srcNode);
-        if (intf.getType().equalsIgnoreCase(NetworkHandler.NETWORK_TYPE_VXLAN)
-            || intf.getType().equalsIgnoreCase(NetworkHandler.NETWORK_TYPE_GRE)) {
+        if (intf.getTypeColumn().getData().equalsIgnoreCase(NetworkHandler.NETWORK_TYPE_VXLAN)
+            || intf.getTypeColumn().getData().equalsIgnoreCase(NetworkHandler.NETWORK_TYPE_GRE)) {
             /* Delete tunnel port */
             try {
-                OvsDBMap<String, String> options = intf.getOptions();
+                Map<String, String> options = intf.getOptionsColumn().getData();
                 InetAddress src = InetAddress.getByName(options.get("local_ip"));
                 InetAddress dst = InetAddress.getByName(options.get("remote_ip"));
-                status = deleteTunnelPort(srcNode, intf.getType(), src, dst);
+                status = deleteTunnelPort(srcNode, intf.getTypeColumn().getData(), src, dst);
             } catch (Exception e) {
                 logger.error(e.getMessage(), e);
             }
@@ -1259,6 +1291,7 @@ public class OF13Provider implements NetworkProvider {
     @Override
     public void initializeFlowRules(Node node) {
         this.initializeFlowRules(node, adminConfigManager.getIntegrationBridgeName());
+        this.initializeFlowRules(node, adminConfigManager.getExternalBridgeName());
         this.triggerInterfaceUpdates(node);
     }
 
@@ -1267,7 +1300,13 @@ public class OF13Provider implements NetworkProvider {
      * @param bridgeName
      */
     private void initializeFlowRules(Node node, String bridgeName) {
-        Long dpid = this.getIntegrationBridgeOFDPID(node);
+        String bridgeUuid = this.getInternalBridgeUUID(node, bridgeName);
+        if (bridgeUuid == null) {
+            return;
+        }
+
+        Long dpid = getDpid(node, bridgeUuid);
+
         if (dpid == 0L) {
             logger.debug("Openflow Datapath-ID not set for the integration bridge in {}", node);
             return;
@@ -1281,6 +1320,9 @@ public class OF13Provider implements NetworkProvider {
          */
 
          writeLLDPRule(dpid);
+         if (bridgeName == adminConfigManager.getExternalBridgeName()) {
+             writeNormalRule(dpid);
+         }
     }
 
     /*
@@ -1334,6 +1376,53 @@ public class OF13Provider implements NetworkProvider {
         writeFlow(flowBuilder, nodeBuilder);
     }
 
+    /*
+    * Create a NORMAL Table Miss Flow Rule
+    * Match: any
+    * Action: forward to NORMAL pipeline
+    */
+
+    private void writeNormalRule(Long dpidLong) {
+
+        String nodeName = "openflow:" + dpidLong;
+
+        MatchBuilder matchBuilder = new MatchBuilder();
+        NodeBuilder nodeBuilder = createNodeBuilder(nodeName);
+        FlowBuilder flowBuilder = new FlowBuilder();
+
+        // Create the OF Actions and Instructions
+        InstructionBuilder ib = new InstructionBuilder();
+        InstructionsBuilder isb = new InstructionsBuilder();
+
+        // Instructions List Stores Individual Instructions
+        List<Instruction> instructions = new ArrayList<Instruction>();
+
+        // Call the InstructionBuilder Methods Containing Actions
+        createNormalInstructions(ib);
+        ib.setOrder(0);
+        ib.setKey(new InstructionKey(0));
+        instructions.add(ib.build());
+
+        // Add InstructionBuilder to the Instruction(s)Builder List
+        isb.setInstruction(instructions);
+
+        // Add InstructionsBuilder to FlowBuilder
+        flowBuilder.setInstructions(isb.build());
+
+        String flowId = "NORMAL";
+        flowBuilder.setId(new FlowId(flowId));
+        FlowKey key = new FlowKey(new FlowId(flowId));
+        flowBuilder.setMatch(matchBuilder.build());
+        flowBuilder.setPriority(0);
+        flowBuilder.setBarrier(true);
+        flowBuilder.setTableId((short) 0);
+        flowBuilder.setKey(key);
+        flowBuilder.setFlowName(flowId);
+        flowBuilder.setHardTimeout(0);
+        flowBuilder.setIdleTimeout(0);
+        writeFlow(flowBuilder, nodeBuilder);
+    }
+
     /*
      * (Table:0) Ingress Tunnel Traffic
      * Match: OpenFlow InPort and Tunnel ID
@@ -2918,7 +3007,7 @@ public class OF13Provider implements NetworkProvider {
         ActionBuilder ab = new ActionBuilder();
 
         OutputActionBuilder output = new OutputActionBuilder();
-        output.setMaxLength(56);
+        output.setMaxLength(0xffff);
         Uri value = new Uri("CONTROLLER");
         output.setOutputNodeConnector(value);
         ab.setAction(new OutputActionCaseBuilder().setOutputAction(output.build()).build());
@@ -2936,6 +3025,36 @@ public class OF13Provider implements NetworkProvider {
         return ib;
     }
 
+    /**
+     * Create NORMAL Reserved Port Instruction (packet_in)
+     *
+     * @param ib Map InstructionBuilder without any instructions
+     * @return ib Map InstructionBuilder with instructions
+     */
+
+    protected static InstructionBuilder createNormalInstructions(InstructionBuilder ib) {
+
+        List<Action> actionList = new ArrayList<Action>();
+        ActionBuilder ab = new ActionBuilder();
+
+        OutputActionBuilder output = new OutputActionBuilder();
+        Uri value = new Uri("NORMAL");
+        output.setOutputNodeConnector(value);
+        ab.setAction(new OutputActionCaseBuilder().setOutputAction(output.build()).build());
+        ab.setOrder(0);
+        ab.setKey(new ActionKey(0));
+        actionList.add(ab.build());
+
+        // Create an Apply Action
+        ApplyActionsBuilder aab = new ApplyActionsBuilder();
+        aab.setAction(actionList);
+
+        // Wrap our Apply Action in an Instruction
+        ib.setInstruction(new ApplyActionsCaseBuilder().setApplyActions(aab.build()).build());
+
+        return ib;
+    }
+
     /**
      * Create Output Port Instruction
      *
@@ -3920,10 +4039,15 @@ public class OF13Provider implements NetworkProvider {
         List<Node> ovsNodes = connectionService.getNodes();
         if (ovsNodes == null) return;
         for (Node ovsNode : ovsNodes) {
-            Long dpid = this.getIntegrationBridgeOFDPID(ovsNode);
-            logger.debug("Compare openflowNode to OVS br-int node {} vs {}", openflowNode.getID(), dpid);
-            String openflowID = ""+openflowNode.getID();
-            if (openflowID.contains(""+dpid)) {
+            Long brIntDpid = this.getIntegrationBridgeOFDPID(ovsNode);
+            Long brExDpid = this.getExternalBridgeDpid(ovsNode);
+            logger.debug("Compare openflowNode to OVS node {} vs {} and {}", openflowNode.getID(), brIntDpid, brExDpid);
+            String openflowID = openflowNode.getID().toString();
+            if (openflowID.contains(brExDpid.toString())) {
+                this.initializeFlowRules(ovsNode, adminConfigManager.getExternalBridgeName());
+                this.triggerInterfaceUpdates(ovsNode);
+            }
+            if (openflowID.contains(brIntDpid.toString())) {
                 this.initializeFlowRules(ovsNode, adminConfigManager.getIntegrationBridgeName());
                 this.triggerInterfaceUpdates(ovsNode);
             }
@@ -3946,10 +4070,10 @@ public class OF13Provider implements NetworkProvider {
     private String getInternalBridgeUUID (Node node, String bridgeName) {
         try {
             OVSDBConfigService ovsdbTable = (OVSDBConfigService)ServiceHelper.getGlobalInstance(OVSDBConfigService.class, this);
-            Map<String, org.opendaylight.ovsdb.lib.table.internal.Table<?>> bridgeTable = ovsdbTable.getRows(node, Bridge.NAME.getName());
+            Map<String, Row> bridgeTable = ovsdbTable.getRows(node, ovsdbTable.getTableName(node, Bridge.class));
             if (bridgeTable == null) return null;
             for (String key : bridgeTable.keySet()) {
-                Bridge bridge = (Bridge)bridgeTable.get(key);
+                Bridge bridge = ovsdbTable.getTypedRow(node, Bridge.class, bridgeTable.get(key));
                 if (bridge.getName().equals(bridgeName)) return key;
             }
         } catch (Exception e) {