VM location aware of Full-mesh Tenant-specific GRE Tunnel support over OF1.0 datapath. 41/3041/2
authorMadhu Venugopal <mavenugo@gmail.com>
Sun, 24 Nov 2013 13:30:46 +0000 (05:30 -0800)
committerGerrit Code Review <gerrit@opendaylight.org>
Sun, 24 Nov 2013 19:26:46 +0000 (19:26 +0000)
This push also includes the following major changes :
1. OVSDB Port tagging on the internal integration bridge (br-int) on Tenant VM connected ports
2. Proper Container support with Flow Spec (internal Vlan) and Openflow ports as Container NodeConnectors
3. Moved most of the logic away from the Neutron Northbound Handlers to the Southbound Handler
4. More fixes to make the OVSDB bundles restartable without the need to force restart the Openstack components.
5. Moved the Southbound events to be handled in its own event thread.

Change-Id: Icb9ffc3a18f1dc15ca0b459ab690d98ce5d91b8f
Signed-off-by: Madhu Venugopal <mavenugo@gmail.com>
16 files changed:
neutron/src/main/java/org/opendaylight/ovsdb/neutron/AdminConfigManager.java
neutron/src/main/java/org/opendaylight/ovsdb/neutron/InternalNetworkManager.java
neutron/src/main/java/org/opendaylight/ovsdb/neutron/NetworkHandler.java
neutron/src/main/java/org/opendaylight/ovsdb/neutron/PortHandler.java
neutron/src/main/java/org/opendaylight/ovsdb/neutron/ProviderNetworkManager.java [deleted file]
neutron/src/main/java/org/opendaylight/ovsdb/neutron/SouthboundEvent.java [new file with mode: 0644]
neutron/src/main/java/org/opendaylight/ovsdb/neutron/SouthboundHandler.java
neutron/src/main/java/org/opendaylight/ovsdb/neutron/TenantNetworkManager.java
neutron/src/main/java/org/opendaylight/ovsdb/neutron/provider/OF10ProviderManager.java [new file with mode: 0644]
neutron/src/main/java/org/opendaylight/ovsdb/neutron/provider/OF13ProviderManager.java [new file with mode: 0644]
neutron/src/main/java/org/opendaylight/ovsdb/neutron/provider/ProviderNetworkManager.java [new file with mode: 0644]
ovsdb/src/main/java/org/opendaylight/ovsdb/lib/notation/UUID.java
ovsdb/src/main/java/org/opendaylight/ovsdb/lib/table/Interface.java
ovsdb/src/main/java/org/opendaylight/ovsdb/plugin/InventoryService.java
ovsdb/src/main/java/org/opendaylight/ovsdb/plugin/InventoryServiceInternal.java
ovsdb/src/main/java/org/opendaylight/ovsdb/plugin/OVSDBInventoryListener.java

index a4d734385fa5d85c55d119ff8cd71a5883fbdaf7..d787ba9d9c9d9812ef2d425eed66e5ff877f0227 100644 (file)
@@ -84,7 +84,7 @@ public class AdminConfigManager {
     }
 
     public boolean isInterested (String tableName) {
-        return tableName.equalsIgnoreCase("Open_vSwitch");
+        return tableName.equalsIgnoreCase(Open_vSwitch.NAME.getName());
     }
 
     private void populateTunnelEndpoint (Node node, Open_vSwitch row) {
@@ -106,7 +106,7 @@ public class AdminConfigManager {
     public void populateTunnelEndpoint (Node node) {
         OVSDBConfigService ovsdbTable = (OVSDBConfigService)ServiceHelper.getGlobalInstance(OVSDBConfigService.class, this);
         try {
-            Map<String, Table<?>> openvswitchTable = ovsdbTable.getRows(node, "Open_vSwitch");
+            Map<String, Table<?>> openvswitchTable = ovsdbTable.getRows(node, Open_vSwitch.NAME.getName());
             if (openvswitchTable == null) {
                 logger.debug("Open_vSwitch table is null for Node {} ", node);
                 return;
index 51404d3ed62e8d65e07d3d052b4225f2cc7d751f..cc195870cab011e05cfe966548d920c4bd37ef51 100644 (file)
@@ -129,7 +129,7 @@ public class InternalNetworkManager {
         String interfaceUUID = null;
         int timeout = 6;
         while ((interfaceUUID == null) && (timeout > 0)) {
-            patchPort = (Port)ovsdbTable.getRow(node, Port.NAME.getName(), status.getDescription());
+            patchPort = (Port)ovsdbTable.getRow(node, Port.NAME.getName(), patchPortUUID);
             OvsDBSet<UUID> interfaces = patchPort.getInterfaces();
             if (interfaces == null || interfaces.size() == 0) {
                 // Wait for the OVSDB update to sync up the Local cache.
index 62800951a87e7fd85117fd3ee9ad58a1cffd5213..18594c647ddf6b8f11333472251ea0524d310a91 100644 (file)
@@ -1,7 +1,6 @@
 package org.opendaylight.ovsdb.neutron;
 
 import java.net.HttpURLConnection;
-import java.util.List;
 
 import org.opendaylight.controller.containermanager.ContainerConfig;
 import org.opendaylight.controller.networkconfig.neutron.INeutronNetworkAware;
@@ -33,14 +32,6 @@ public class NetworkHandler extends BaseHandler
             return HttpURLConnection.HTTP_NOT_ACCEPTABLE;
         }
 
-        String networkID = convertNeutronIDToKey(network.getID());
-
-        List<String> containers = containerManager.getContainerNames();
-        if (containers.contains(networkID)) {
-            logger.debug("Container with name {} exists", networkID);
-            return HttpURLConnection.HTTP_CONFLICT;
-        }
-
         return HttpURLConnection.HTTP_CREATED;
     }
 
@@ -58,14 +49,8 @@ public class NetworkHandler extends BaseHandler
             logger.debug("Network creation failed {} ", result);
             return;
         }
-        String networkId = convertNeutronIDToKey(network.getID());
-
-        // Get Network Tenant ready - Containers and Internal Vlans.
-        result = TenantNetworkManager.getManager().networkCreated(networkId);
-        logger.debug("Neutron Network {} Created with Internal Vlan : {}", network.toString(), result);
 
-        // Get internal network ready for Overlays
-        InternalNetworkManager.getManager().prepareInternalNetwork(network);
+        TenantNetworkManager.getManager().networkCreated(network.getID());
     }
 
     /**
index 3724368e1733dd64645e3eeff305bb7628d5c0f2..3899616fe882a8fb1f0107b7fc924e3d1cf1a13f 100644 (file)
@@ -49,27 +49,16 @@ public class PortHandler extends BaseHandler
         String portID = convertNeutronIDToKey(port.getID());
         String portDesc = port.getName();
         Boolean portAdminState = port.getAdminStateUp();
-/*
- * Add the Corresponding OF NodeConnector to the Container
- *
-        ContainerConfig config = new ContainerConfig();
-        config.setContainer(networkID);
-        logger.debug("Adding Port {} to Container : {}", port.toString(), config.getContainer());
-        List<String> ncList = new ArrayList<String>();
-        ncList.add("OVS|"+ portID +"@OVS|"+networkID);
-        config.addNodeConnectors(ncList);
-        Status status = containerManager.addContainerEntry(networkID, ncList);
 
-        if (!status.isSuccess()) {
-            logger.error(" Port-ADD failed for tenant-id - {}," +
-                    " bridge-id - {}, port-id - {}, result - {} ",
-                    tenantID, networkID, portID, result);
-        } else {
-            logger.debug(" Port-ADD successful for tenant-id - {}," +
-                    " bridge-id - {}, port-id - {}, result - {} ",
-                    tenantID, networkID, portID, result);
-        }
-*/
+        // Create Full Mesh Tunnels
+        /*
+         * Is this required ?
+         * The Tunnel Creation logic is completely owned by the Southbound handler at this point.
+
+        NeutronNetwork network = this.neutronNetworkCache.getNetwork(port.getNetworkUUID());
+        ProviderNetworkManager.getManager().createTunnels(network.getProviderNetworkType(),
+                                                          network.getProviderSegmentationID());
+         */
         logger.debug(" Port-ADD successful for tenant-id - {}," +
                 " network-id - {}, port-id - {}, result - {} ",
                 tenantID, networkID, portID, result);
diff --git a/neutron/src/main/java/org/opendaylight/ovsdb/neutron/ProviderNetworkManager.java b/neutron/src/main/java/org/opendaylight/ovsdb/neutron/ProviderNetworkManager.java
deleted file mode 100644 (file)
index 760211d..0000000
+++ /dev/null
@@ -1,15 +0,0 @@
-package org.opendaylight.ovsdb.neutron;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-public class ProviderNetworkManager {
-    static final Logger logger = LoggerFactory.getLogger(ProviderNetworkManager.class);
-    private static ProviderNetworkManager provider = new ProviderNetworkManager();
-    private ProviderNetworkManager() {
-    }
-
-    public static ProviderNetworkManager getManager() {
-        return provider;
-    }
-}
diff --git a/neutron/src/main/java/org/opendaylight/ovsdb/neutron/SouthboundEvent.java b/neutron/src/main/java/org/opendaylight/ovsdb/neutron/SouthboundEvent.java
new file mode 100644 (file)
index 0000000..a6da759
--- /dev/null
@@ -0,0 +1,94 @@
+package org.opendaylight.ovsdb.neutron;
+
+import org.opendaylight.controller.sal.core.Node;
+import org.opendaylight.ovsdb.lib.table.internal.Table;
+
+public class SouthboundEvent {
+    public enum Type { NODE, ROW };
+    public enum Action { ADD, UPDATE, DELETE };
+    private Type type;
+    private Action action;
+    private Node node;
+    private String tableName;
+    private String uuid;
+    private Table<?> row;
+    public SouthboundEvent(Node node, Action action) {
+        super();
+        this.type = Type.NODE;
+        this.action = action;
+        this.node = node;
+    }
+    public SouthboundEvent(Node node, String tableName, String uuid, Table<?> row, Action action) {
+        super();
+        this.type = Type.ROW;
+        this.action = action;
+        this.node = node;
+        this.tableName = tableName;
+        this.uuid = uuid;
+        this.row = row;
+    }
+    public Type getType() {
+        return type;
+    }
+    public Action getAction() {
+        return action;
+    }
+    public Node getNode() {
+        return node;
+    }
+    public String getTableName() {
+        return tableName;
+    }
+    public String getUuid() {
+        return uuid;
+    }
+    public Table<?> getRow() {
+        return row;
+    }
+    @Override
+    public String toString() {
+        return "SouthboundEvent [type=" + type + ", action=" + action + ", node=" + node + ", tableName=" + tableName
+                + ", uuid=" + uuid + ", row=" + row + "]";
+    }
+    @Override
+    public int hashCode() {
+        final int prime = 31;
+        int result = 1;
+        result = prime * result + ((action == null) ? 0 : action.hashCode());
+        result = prime * result + ((node == null) ? 0 : node.hashCode());
+        result = prime * result + ((tableName == null) ? 0 : tableName.hashCode());
+        result = prime * result + ((type == null) ? 0 : type.hashCode());
+        result = prime * result + ((uuid == null) ? 0 : uuid.hashCode());
+        return result;
+    }
+    @Override
+    public boolean equals(Object obj) {
+        if (this == obj)
+            return true;
+        if (obj == null)
+            return false;
+        if (getClass() != obj.getClass())
+            return false;
+        SouthboundEvent other = (SouthboundEvent) obj;
+        if (action != other.action)
+            return false;
+        if (node == null) {
+            if (other.node != null)
+                return false;
+        } else if (!node.equals(other.node))
+            return false;
+        if (tableName == null) {
+            if (other.tableName != null)
+                return false;
+        } else if (!tableName.equals(other.tableName))
+            return false;
+        if (type != other.type)
+            return false;
+        if (uuid == null) {
+            if (other.uuid != null)
+                return false;
+        } else if (!uuid.equals(other.uuid))
+            return false;
+        return true;
+    }
+}
index 321c72c48d416532e6ded947cab7876ba4f5df2a..281aecf3d14787fb2de1651f4b88761d6e9b2a2c 100644 (file)
 package org.opendaylight.ovsdb.neutron;
 
+import java.util.Map;
+import java.util.Set;
+import java.util.concurrent.BlockingQueue;
+import java.util.concurrent.LinkedBlockingQueue;
+
+import org.opendaylight.controller.networkconfig.neutron.NeutronNetwork;
 import org.opendaylight.controller.sal.core.Node;
+import org.opendaylight.ovsdb.lib.notation.UUID;
+import org.opendaylight.ovsdb.lib.table.Interface;
+import org.opendaylight.ovsdb.lib.table.Open_vSwitch;
+import org.opendaylight.ovsdb.lib.table.Port;
 import org.opendaylight.ovsdb.lib.table.internal.Table;
+import org.opendaylight.ovsdb.neutron.provider.ProviderNetworkManager;
 import org.opendaylight.ovsdb.plugin.OVSDBInventoryListener;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
 public class SouthboundHandler extends BaseHandler implements OVSDBInventoryListener {
     static final Logger logger = LoggerFactory.getLogger(SouthboundHandler.class);
+    private Thread eventThread;
+    private BlockingQueue<SouthboundEvent> events;
+
+    void init() {
+        eventThread = new Thread(new EventHandler(), "SouthBound Event Thread");
+        this.events = new LinkedBlockingQueue<SouthboundEvent>();
+    }
+
+    void start() {
+        eventThread.start();
+    }
+
+    void stop() {
+        eventThread.interrupt();
+    }
     @Override
     public void nodeAdded(Node node) {
-        logger.debug("NODE ADDED {}", node);
-        AdminConfigManager.getManager().populateTunnelEndpoint(node);
-        InternalNetworkManager.getManager().prepareInternalNetwork(node);
+        this.enqueueEvent(new SouthboundEvent(node, SouthboundEvent.Action.ADD));
     }
 
     @Override
     public void nodeRemoved(Node node) {
-        logger.debug("NODE REMOVED {}", node);
+        this.enqueueEvent(new SouthboundEvent(node, SouthboundEvent.Action.DELETE));
     }
 
     @Override
-    public void rowAdded(Node node, String tableName, Table<?> row) {
-        logger.debug("ROW ADDED {} , {}", node, row);
-        /*
-         * Should we support dynamic update of the Tunnel endpoint configuration ?
-         *
-        if (AdminConfigManager.getManager().isInterested(tableName)) {
-            AdminConfigManager.getManager().populateTunnelEndpoint(node, tableName, row);
-        }
-        */
+    public void rowAdded(Node node, String tableName, String uuid, Table<?> row) {
+        this.enqueueEvent(new SouthboundEvent(node, tableName, uuid, row, SouthboundEvent.Action.ADD));
     }
 
     @Override
-    public void rowRemoved(Node node, String tableName, Table<?> row) {
-        logger.debug("ROW REMOVED {} , {}", node, row);
+    public void rowUpdated(Node node, String tableName, String uuid, Table<?> row) {
+        this.enqueueEvent(new SouthboundEvent(node, tableName, uuid, row, SouthboundEvent.Action.UPDATE));
+    }
+
+    @Override
+    public void rowRemoved(Node node, String tableName, String uuid, Table<?> row) {
+        this.enqueueEvent(new SouthboundEvent(node, tableName, uuid, row, SouthboundEvent.Action.DELETE));
+    }
+
+    private void enqueueEvent (SouthboundEvent event) {
+        try {
+            events.put(event);
+        } catch (InterruptedException e) {
+            e.printStackTrace();
+        }
+
+    }
+    private class EventHandler implements Runnable {
+        @Override
+        public void run() {
+            while (true) {
+                try {
+                    SouthboundEvent ev = events.take();
+                    switch (ev.getType()) {
+                    case NODE:
+                        ProcessNodeUpdate(ev.getNode(), ev.getAction());
+                    case ROW:
+                        ProcessRowUpdate(ev.getNode(), ev.getTableName(), ev.getUuid(), ev.getRow(), ev.getAction());
+                        break;
+                    }
+                } catch (Exception e) {
+                    e.printStackTrace();
+                }
+            }
+        }
+    }
+
+    public void ProcessNodeUpdate(Node node, SouthboundEvent.Action action) {
+        if (action == SouthboundEvent.Action.DELETE) return;
+        logger.trace("Process Node added {}", node);
+        InternalNetworkManager.getManager().prepareInternalNetwork(node);
+    }
+
+    private void ProcessRowUpdate(Node node, String tableName, String uuid, Table<?> row,
+                                  SouthboundEvent.Action action) {
+        if (action == SouthboundEvent.Action.DELETE) return;
+
+        if (Interface.NAME.getName().equalsIgnoreCase(tableName)) {
+            logger.debug("trace {} Added / Updated {} , {}, {}", tableName, node, uuid, row);
+            Interface intf = (Interface)row;
+            NeutronNetwork network = TenantNetworkManager.getManager().getTenantNetworkForInterface(intf);
+            if (network != null) {
+                int vlan = TenantNetworkManager.getManager().networkCreated(network.getID());
+                logger.trace("Neutron Network {} Created with Internal Vlan : {}", network.toString(), vlan);
+
+                String portUUID = this.getPortIdForInterface(node, uuid, intf);
+                if (portUUID != null) {
+                    TenantNetworkManager.getManager().programTenantNetworkInternalVlan(node, portUUID, network);
+                }
+                this.createTunnels(node, uuid, intf);
+            }
+        } else if (Port.NAME.getName().equalsIgnoreCase(tableName)) {
+            logger.debug("trace {} Added / Updated {} , {}, {}", tableName, node, uuid, row);
+            Port port = (Port)row;
+            Set<UUID> interfaceUUIDs = port.getInterfaces();
+            for (UUID intfUUID : interfaceUUIDs) {
+                logger.trace("Scanning interface "+intfUUID);
+                try {
+                    Interface intf = (Interface)this.ovsdbConfigService.getRow(node, Interface.NAME.getName(), intfUUID.toString());
+                    NeutronNetwork network = TenantNetworkManager.getManager().getTenantNetworkForInterface(intf);
+                    if (network != null) {
+                        TenantNetworkManager.getManager().programTenantNetworkInternalVlan(node, uuid, network);
+                    }
+                } catch (Exception e) {
+                    e.printStackTrace();
+                }
+            }
+        } else if (Open_vSwitch.NAME.getName().equalsIgnoreCase(tableName)) {
+            logger.debug("trace {} Added / Updated {} , {}, {}", tableName, node, uuid, row);
+            AdminConfigManager.getManager().populateTunnelEndpoint(node);
+            try {
+                Map<String, Table<?>> interfaces = this.ovsdbConfigService.getRows(node, Interface.NAME.getName());
+                if (interfaces != null) {
+                    for (String intfUUID : interfaces.keySet()) {
+                        Interface intf = (Interface) interfaces.get(intfUUID);
+                        createTunnels(node, intfUUID, intf);
+                    }
+                }
+            } catch (Exception e) {
+                logger.error("Error fetching Interface Rows for node {}", node);
+            }
+        }
+    }
+
+    private void createTunnels (Node node, String uuid, Interface intf) {
+        if (AdminConfigManager.getManager().getTunnelEndPoint(node) == null) {
+            logger.error("Tunnel end-point configuration missing. Please configure it in Open_vSwitch Table");
+            return;
+        }
+        NeutronNetwork network = TenantNetworkManager.getManager().getTenantNetworkForInterface(intf);
+        if (network != null) {
+            ProviderNetworkManager.getManager().createTunnels(network.getProviderNetworkType(),
+                    network.getProviderSegmentationID());
+        }
+    }
+
+    private String getPortIdForInterface (Node node, String uuid, Interface intf) {
+        try {
+            Map<String, Table<?>> ports = this.ovsdbConfigService.getRows(node, Port.NAME.getName());
+            if (ports == null) return null;
+            for (String portUUID : ports.keySet()) {
+                Port port = (Port)ports.get(portUUID);
+                Set<UUID> interfaceUUIDs = port.getInterfaces();
+                logger.trace("Scanning Port {} to identify interface : {} ",port, uuid);
+                for (UUID intfUUID : interfaceUUIDs) {
+                    if (intfUUID.toString().equalsIgnoreCase(uuid)) {
+                        logger.trace("Found Interafce {} -> {}", uuid, portUUID);
+                        return portUUID;
+                    }
+                }
+            }
+        } catch (Exception e) {
+            logger.debug("Failed to add Port tag for for Intf {}",intf, e);
+        }
+        return null;
     }
 }
index 92ac2b7aa0ad412ced1c2545050555dacf9ae4aa..9107ee4bff12156c6560a606c749ceb511ef9123 100644 (file)
@@ -1,17 +1,33 @@
 package org.opendaylight.ovsdb.neutron;
 
+import java.math.BigInteger;
 import java.util.ArrayList;
 import java.util.HashMap;
 import java.util.LinkedList;
 import java.util.List;
 import java.util.Map;
 import java.util.Queue;
+import java.util.Set;
 
 import org.opendaylight.controller.containermanager.ContainerConfig;
 import org.opendaylight.controller.containermanager.ContainerFlowConfig;
 import org.opendaylight.controller.containermanager.IContainerManager;
+import org.opendaylight.controller.networkconfig.neutron.INeutronNetworkCRUD;
+import org.opendaylight.controller.networkconfig.neutron.INeutronPortCRUD;
+import org.opendaylight.controller.networkconfig.neutron.NeutronNetwork;
+import org.opendaylight.controller.networkconfig.neutron.NeutronPort;
+import org.opendaylight.controller.sal.core.Node;
+import org.opendaylight.controller.sal.core.NodeConnector;
+import org.opendaylight.controller.sal.utils.HexEncode;
 import org.opendaylight.controller.sal.utils.ServiceHelper;
 import org.opendaylight.controller.sal.utils.Status;
+import org.opendaylight.ovsdb.lib.notation.OvsDBSet;
+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.lib.table.internal.Table;
+import org.opendaylight.ovsdb.plugin.OVSDBConfigService;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -19,6 +35,9 @@ public class TenantNetworkManager {
     static final Logger logger = LoggerFactory.getLogger(TenantNetworkManager.class);
 
     private static final int MAX_VLAN = 4096;
+    private static final String EXTERNAL_ID_VM_ID = "vm-id";
+    private static final String EXTERNAL_ID_INTERFACE_ID = "iface-id";
+    private static final String EXTERNAL_ID_VM_MAC = "attached-mac";
     private static TenantNetworkManager tenantHelper = new TenantNetworkManager();
     private Queue<Integer> internalVlans = new LinkedList<Integer>();
     private Map<String, Integer> tenantVlanMap = new HashMap<String, Integer>();
@@ -45,27 +64,229 @@ public class TenantNetworkManager {
     }
 
     public int getInternalVlan (String networkId) {
-        return tenantVlanMap.get(networkId);
+        Integer vlan = tenantVlanMap.get(networkId);
+        if (vlan == null) return 0;
+        return vlan.intValue();
     }
 
     public int networkCreated (String networkId) {
+        IContainerManager containerManager = (IContainerManager)ServiceHelper.getGlobalInstance(IContainerManager.class, this);
+        if (containerManager == null) {
+            logger.error("ContainerManager is null. Failed to create Container for {}", networkId);
+            return 0;
+        }
         int internalVlan = this.assignInternalVlan(networkId);
         if (internalVlan != 0) {
             ContainerConfig config = new ContainerConfig();
-            config.setContainer(networkId);
+            config.setContainer(BaseHandler.convertNeutronIDToKey(networkId));
+            Status status = containerManager.addContainer(config);
+            logger.debug("Container Creation Status for {} : {}", networkId, status.toString());
+
             ContainerFlowConfig flowConfig = new ContainerFlowConfig("InternalVlan", internalVlan+"",
                     null, null, null, null, null);
             List<ContainerFlowConfig> containerFlowConfigs = new ArrayList<ContainerFlowConfig>();
             containerFlowConfigs.add(flowConfig);
-            config.addContainerFlows(containerFlowConfigs);
-            IContainerManager containerManager = (IContainerManager)ServiceHelper.getGlobalInstance(IContainerManager.class, this);
-            if (containerManager != null) {
-                Status status = containerManager.addContainer(config);
-                logger.debug("Network Creation Status : {}", status.toString());
-            } else {
-                logger.error("ContainerManager is null. Failed to create Container for {}", networkId);
-            }
+            containerManager.addContainerFlows(BaseHandler.convertNeutronIDToKey(networkId), containerFlowConfigs);
         }
         return internalVlan;
     }
+
+    /**
+     * Are there any TenantNetwork VM present on this Node ?
+     * This method uses Interface Table's external-id field to locate the VM.
+     */
+    public boolean isTenantNetworkPresentInNode(Node node, String segmentationId) {
+        String networkId = this.getNetworkIdForSegmentationId(segmentationId);
+        if (networkId == null) {
+            logger.debug("Tenant Network not found with Segmenation-id {}",segmentationId);
+            return false;
+        }
+        int internalVlan = this.getInternalVlan(networkId);
+        if (internalVlan == 0) {
+            logger.debug("No InternalVlan provisioned for Tenant Network {}",networkId);
+            return false;
+        }
+        OVSDBConfigService ovsdbTable = (OVSDBConfigService)ServiceHelper.getGlobalInstance(OVSDBConfigService.class, this);
+        try {
+            /*
+            // Vlan Tag based identification
+            Map<String, Table<?>> portTable = ovsdbTable.getRows(node, Port.NAME.getName());
+            if (portTable == null) {
+                logger.debug("Port table is null for Node {} ", node);
+                return false;
+            }
+
+            for (Table<?> row : portTable.values()) {
+                Port port = (Port)row;
+                Set<BigInteger> tags = port.getTag();
+                if (tags.contains(internalVlan)) {
+                    logger.debug("Tenant Network {} with Segmenation-id {} is present in Node {} / Port {}",
+                                  networkId, segmentationId, node, port);
+                    return true;
+                }
+            }
+             */
+            // External-id based more accurate VM Location identification
+            Map<String, Table<?>> ifTable = ovsdbTable.getRows(node, Interface.NAME.getName());
+            if (ifTable == null) {
+                logger.debug("Interface table is null for Node {} ", node);
+                return false;
+            }
+
+            for (Table<?> row : ifTable.values()) {
+                Interface intf = (Interface)row;
+                Map<String, String> externalIds = intf.getExternal_ids();
+                if (externalIds != null) {
+                    if (this.isInterfacePresentInTenantNetwork(externalIds.get(EXTERNAL_ID_INTERFACE_ID), networkId)) {
+                        logger.debug("Tenant Network {} with Segmenation-id {} is present in Node {} / Interface {}",
+                                      networkId, segmentationId, node, intf);
+                        return true;
+                    }
+                }
+            }
+
+        } catch (Exception e) {
+            e.printStackTrace();
+            return false;
+        }
+
+        logger.debug("Tenant Network {} with Segmenation-id {} is NOT present in Node {}",
+                networkId, segmentationId, node);
+
+        return false;
+    }
+
+    private String getNetworkIdForSegmentationId (String segmentationId) {
+        INeutronNetworkCRUD neutronNetworkService = (INeutronNetworkCRUD)ServiceHelper.getGlobalInstance(INeutronNetworkCRUD.class, this);
+        List <NeutronNetwork> networks = neutronNetworkService.getAllNetworks();
+        for (NeutronNetwork network : networks) {
+            if (network.getProviderSegmentationID().equalsIgnoreCase(segmentationId)) return network.getNetworkUUID();
+        }
+        return null;
+    }
+
+    private boolean isInterfacePresentInTenantNetwork (String portId, String networkId) {
+        INeutronPortCRUD neutronPortService = (INeutronPortCRUD)ServiceHelper.getGlobalInstance(INeutronPortCRUD.class, this);
+        NeutronPort neutronPort = neutronPortService.getPort(portId);
+        if (neutronPort.getNetworkUUID().equalsIgnoreCase(networkId)) return true;
+        return false;
+    }
+
+    public NeutronNetwork getTenantNetworkForInterface (Interface intf) {
+        logger.trace("getTenantNetworkForInterface for {}", intf);
+        if (intf == null) return null;
+        Map<String, String> externalIds = intf.getExternal_ids();
+        logger.trace("externalIds {}", externalIds);
+        if (externalIds == null) return null;
+        String neutronPortId = externalIds.get(EXTERNAL_ID_INTERFACE_ID);
+        if (neutronPortId == null) return null;
+        INeutronPortCRUD neutronPortService = (INeutronPortCRUD)ServiceHelper.getGlobalInstance(INeutronPortCRUD.class, this);
+        NeutronPort neutronPort = neutronPortService.getPort(neutronPortId);
+        logger.trace("neutronPort {}", neutronPort);
+        if (neutronPort == null) return null;
+        INeutronNetworkCRUD neutronNetworkService = (INeutronNetworkCRUD)ServiceHelper.getGlobalInstance(INeutronNetworkCRUD.class, this);
+        NeutronNetwork neutronNetwork = neutronNetworkService.getNetwork(neutronPort.getNetworkUUID());
+        logger.debug("{} mappped to {}", intf, neutronNetwork);
+        return neutronNetwork;
+    }
+
+    public void programTenantNetworkInternalVlan(Node node, String portUUID, NeutronNetwork network) {
+        int vlan = this.getInternalVlan(network.getID());
+        logger.debug("Programming Vlan {} on {}", vlan, portUUID);
+        if (vlan <= 0) {
+            logger.error("Unable to get an internalVlan for Network {}", network);
+            return;
+        }
+        OVSDBConfigService ovsdbTable = (OVSDBConfigService)ServiceHelper.getGlobalInstance(OVSDBConfigService.class, this);
+        Port port = new Port();
+        OvsDBSet<BigInteger> tags = new OvsDBSet<BigInteger>();
+        tags.add(BigInteger.valueOf(vlan));
+        port.setTag(tags);
+        ovsdbTable.updateRow(node, Port.NAME.getName(), null, portUUID, port);
+        this.addPortToTenantNetworkContainer(node, portUUID, network);
+    }
+
+    private void addPortToTenantNetworkContainer(Node node, String portUUID, NeutronNetwork network) {
+        IContainerManager containerManager = (IContainerManager)ServiceHelper.getGlobalInstance(IContainerManager.class, this);
+        if (containerManager == null) {
+            logger.error("ContainerManager is not accessible");
+            return;
+        }
+        OVSDBConfigService ovsdbTable = (OVSDBConfigService)ServiceHelper.getGlobalInstance(OVSDBConfigService.class, this);
+        try {
+            Port port = (Port)ovsdbTable.getRow(node, Port.NAME.getName(), portUUID);
+            if (port == null) {
+                logger.trace("Unable to identify Port with UUID {}", portUUID);
+                return;
+            }
+            Set<UUID> interfaces = port.getInterfaces();
+            if (interfaces == null) {
+                logger.trace("No interfaces available to fetch the OF Port");
+                return;
+            }
+            Bridge bridge = this.getBridgeIdForPort(node, portUUID);
+            if (bridge == null) {
+                logger.debug("Unable to spot Bridge for Port {} in node {}", port, node);
+                return;
+            }
+            Set<String> dpids = bridge.getDatapath_id();
+            if (dpids == null || dpids.size() ==  0) return;
+            Long dpidLong = Long.valueOf(HexEncode.stringToLong((String)dpids.toArray()[0]));
+
+            for (UUID intfUUID : interfaces) {
+                Interface intf = (Interface)ovsdbTable.getRow(node, Interface.NAME.getName(), intfUUID.toString());
+                if (intf == null) continue;
+                Set<BigInteger> of_ports = intf.getOfport();
+                if (of_ports == null) continue;
+                for (BigInteger of_port : of_ports) {
+                    ContainerConfig config = new ContainerConfig();
+                    config.setContainer(BaseHandler.convertNeutronIDToKey(network.getID()));
+                    logger.debug("Adding Port {} to Container : {}", port.toString(), config.getContainer());
+                    List<String> ncList = new ArrayList<String>();
+                    Node ofNode = new Node(Node.NodeIDType.OPENFLOW, dpidLong);
+                    NodeConnector nc = NodeConnector.fromStringNoNode(Node.NodeIDType.OPENFLOW.toString(),
+                                                                      Long.valueOf(of_port.longValue()).intValue()+"",
+                                                                      ofNode);
+                    ncList.add(nc.toString());
+                    config.addNodeConnectors(ncList);
+
+                    Status status = containerManager.addContainerEntry(BaseHandler.convertNeutronIDToKey(network.getID()), ncList);
+
+                    if (!status.isSuccess()) {
+                        logger.error(" Failed {} : to add port {} to container - {}",
+                                status, nc, network.getID());
+                    } else {
+                        logger.error(" Successfully added port {} to container - {}",
+                                       nc, network.getID());
+                    }
+                }
+            }
+        } catch (Exception e) {
+            // TODO Auto-generated catch block
+            e.printStackTrace();
+        }
+    }
+
+    private Bridge getBridgeIdForPort (Node node, String uuid) {
+        OVSDBConfigService ovsdbTable = (OVSDBConfigService)ServiceHelper.getGlobalInstance(OVSDBConfigService.class, this);
+        try {
+            Map<String, Table<?>> bridges = ovsdbTable.getRows(node, Bridge.NAME.getName());
+            if (bridges == null) return null;
+            for (String bridgeUUID : bridges.keySet()) {
+                Bridge bridge = (Bridge)bridges.get(bridgeUUID);
+                Set<UUID> portUUIDs = bridge.getPorts();
+                logger.trace("Scanning Bridge {} to identify Port : {} ",bridge, uuid);
+                for (UUID portUUID : portUUIDs) {
+                    if (portUUID.toString().equalsIgnoreCase(uuid)) {
+                        logger.trace("Found Port {} -> ", uuid, bridgeUUID);
+                        return bridge;
+                    }
+                }
+            }
+        } catch (Exception e) {
+            logger.debug("Failed to get BridgeId port {} in Node {}", uuid, node);
+        }
+        return null;
+    }
+
 }
diff --git a/neutron/src/main/java/org/opendaylight/ovsdb/neutron/provider/OF10ProviderManager.java b/neutron/src/main/java/org/opendaylight/ovsdb/neutron/provider/OF10ProviderManager.java
new file mode 100644 (file)
index 0000000..152ba0a
--- /dev/null
@@ -0,0 +1,174 @@
+package org.opendaylight.ovsdb.neutron.provider;
+
+import java.net.InetAddress;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import org.opendaylight.controller.sal.core.Node;
+import org.opendaylight.controller.sal.utils.ServiceHelper;
+import org.opendaylight.controller.sal.utils.Status;
+import org.opendaylight.controller.sal.utils.StatusCode;
+import org.opendaylight.ovsdb.lib.notation.OvsDBMap;
+import org.opendaylight.ovsdb.lib.notation.OvsDBSet;
+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.lib.table.internal.Table;
+import org.opendaylight.ovsdb.neutron.AdminConfigManager;
+import org.opendaylight.ovsdb.neutron.InternalNetworkManager;
+import org.opendaylight.ovsdb.neutron.TenantNetworkManager;
+import org.opendaylight.ovsdb.plugin.IConnectionServiceInternal;
+import org.opendaylight.ovsdb.plugin.OVSDBConfigService;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+
+class OF10ProviderManager extends ProviderNetworkManager {
+    private static final Logger logger = LoggerFactory.getLogger(OF10ProviderManager.class);
+
+    @Override
+    public boolean hasPerTenantTunneling() {
+        return true;
+    }
+
+    private Status getTunnelReadinessStatus (Node node, String tunnelKey) {
+        InetAddress srcTunnelEndPoint = AdminConfigManager.getManager().getTunnelEndPoint(node);
+        if (srcTunnelEndPoint == null) {
+            logger.error("Tunnel Endpoint not configured for Node {}", node);
+            return new Status(StatusCode.NOTFOUND, "Tunnel Endpoint not configured for "+ node);
+        }
+
+        try {
+            if (!InternalNetworkManager.getManager().isInternalNetworkOverlayReady(node)) {
+                logger.error(node+" is not Overlay ready");
+                return new Status(StatusCode.NOTACCEPTABLE, node+" is not Overlay ready");
+            }
+        } catch (Exception e) {
+            logger.error(node+" is not Overlay ready");
+            return new Status(StatusCode.NOTACCEPTABLE, node+" is not Overlay ready");
+        }
+
+        if (!TenantNetworkManager.getManager().isTenantNetworkPresentInNode(node, tunnelKey)) {
+            logger.debug(node+" has no VM corresponding to segment "+ tunnelKey);
+            return new Status(StatusCode.NOTACCEPTABLE, node+" has no VM corresponding to segment "+ tunnelKey);
+        }
+        return new Status(StatusCode.SUCCESS);
+    }
+
+    @Override
+    public Status createTunnels(String tunnelType, String tunnelKey, Node srcNode) {
+        Status status = getTunnelReadinessStatus(srcNode, tunnelKey);
+        if (!status.isSuccess()) return status;
+
+        IConnectionServiceInternal connectionService = (IConnectionServiceInternal)ServiceHelper.getGlobalInstance(IConnectionServiceInternal.class, this);
+        List<Node> nodes = connectionService.getNodes();
+        nodes.remove(srcNode);
+        for (Node dstNode : nodes) {
+            status = getTunnelReadinessStatus(dstNode, tunnelKey);
+            if (!status.isSuccess()) continue;
+            InetAddress src = AdminConfigManager.getManager().getTunnelEndPoint(srcNode);
+            InetAddress dst = AdminConfigManager.getManager().getTunnelEndPoint(dstNode);
+            addTunnelPort(srcNode, tunnelType, src, dst, tunnelKey);
+            addTunnelPort(dstNode, tunnelType, dst, src, tunnelKey);
+        }
+        return new Status(StatusCode.SUCCESS);
+    }
+
+    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);
+        if (bridge != null) {
+            Set<UUID> ports = bridge.getPorts();
+            for (UUID portUUID : ports) {
+                Port port = (Port)ovsdbTable.getRow(node, Port.NAME.getName(), portUUID.toString());
+                if (port != null && port.getName().equalsIgnoreCase(tunnelName)) return true;
+            }
+        }
+        return false;
+    }
+
+    private Status addTunnelPort (Node node, String tunnelType, InetAddress src, InetAddress dst, String key) {
+        try {
+            String bridgeUUID = null;
+            String tunnelBridgeName = AdminConfigManager.getManager().getTunnelBridgeName();
+            OVSDBConfigService ovsdbTable = (OVSDBConfigService)ServiceHelper.getGlobalInstance(OVSDBConfigService.class, this);
+            Map<String, Table<?>> bridgeTable = ovsdbTable.getRows(node, Bridge.NAME.getName());
+            if (bridgeTable != null) {
+                for (String uuid : bridgeTable.keySet()) {
+                    Bridge bridge = (Bridge)bridgeTable.get(uuid);
+                    if (bridge.getName().equals(tunnelBridgeName)) {
+                        bridgeUUID = uuid;
+                        break;
+                    }
+                }
+            }
+            if (bridgeUUID == null) {
+                logger.error("Could not find Bridge {} in {}", tunnelBridgeName, node);
+                return new Status(StatusCode.NOTFOUND, "Could not find "+tunnelBridgeName+" in "+node);
+            }
+            String portName = tunnelType+"-"+key+"-"+dst.getHostAddress();
+
+            if (this.isTunnelPresent(node, portName, bridgeUUID)) {
+                logger.trace("Tunnel {} is present in {} of {}", portName, tunnelBridgeName, node);
+                return new Status(StatusCode.SUCCESS);
+            }
+
+            Port tunnelPort = new Port();
+            tunnelPort.setName(portName);
+            Status status = ovsdbTable.insertRow(node, Port.NAME.getName(), bridgeUUID, tunnelPort);
+            if (!status.isSuccess()) {
+                logger.error("Failed to insert Tunnel port {} in {}", portName, bridgeUUID);
+                return status;
+            }
+
+            String tunnelPortUUID = status.getDescription();
+
+            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();
+                if (interfaces == null || interfaces.size() == 0) {
+                    // Wait for the OVSDB update to sync up the Local cache.
+                    Thread.sleep(500);
+                    timeout--;
+                    continue;
+                }
+                interfaceUUID = interfaces.toArray()[0].toString();
+                Interface intf = (Interface)ovsdbTable.getRow(node, Interface.NAME.getName(), interfaceUUID);
+                if (intf == null) interfaceUUID = null;
+            }
+
+            if (interfaceUUID == null) {
+                logger.error("Cannot identify Tunnel Interface for port {}/{}", portName, tunnelPortUUID);
+                return new Status(StatusCode.INTERNALERROR);
+            }
+
+            Interface tunInterface = new Interface();
+            tunInterface.setType(tunnelType);
+            OvsDBMap<String, String> options = new OvsDBMap<String, String>();
+            options.put("key", key);
+            options.put("local_ip", src.getHostAddress());
+            options.put("remote_ip", dst.getHostAddress());
+            tunInterface.setOptions(options);
+            status = ovsdbTable.updateRow(node, Interface.NAME.getName(), tunnelPortUUID, interfaceUUID, tunInterface);
+            logger.debug("Tunnel {} add status : {}", tunInterface, status);
+            return status;
+        } catch (Exception e) {
+            e.printStackTrace();
+            return new Status(StatusCode.INTERNALERROR);
+        }
+    }
+
+    @Override
+    public Status createTunnels(String tunnelType, String tunnelKey) {
+        IConnectionServiceInternal connectionService = (IConnectionServiceInternal)ServiceHelper.getGlobalInstance(IConnectionServiceInternal.class, this);
+        List<Node> nodes = connectionService.getNodes();
+        for (Node srcNode : nodes) {
+            this.createTunnels(tunnelType, tunnelKey, srcNode);
+        }
+        return null;
+    }
+}
diff --git a/neutron/src/main/java/org/opendaylight/ovsdb/neutron/provider/OF13ProviderManager.java b/neutron/src/main/java/org/opendaylight/ovsdb/neutron/provider/OF13ProviderManager.java
new file mode 100644 (file)
index 0000000..5db85e3
--- /dev/null
@@ -0,0 +1,24 @@
+package org.opendaylight.ovsdb.neutron.provider;
+
+import org.opendaylight.controller.sal.core.Node;
+import org.opendaylight.controller.sal.utils.Status;
+
+
+class OF13ProviderManager extends ProviderNetworkManager {
+    @Override
+    public boolean hasPerTenantTunneling() {
+        return false;
+    }
+
+    @Override
+    public Status createTunnels(String tunnelType, String tunnelKey, Node source) {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public Status createTunnels(String tunnelType, String tunnelKey) {
+        // TODO Auto-generated method stub
+        return null;
+    }
+}
diff --git a/neutron/src/main/java/org/opendaylight/ovsdb/neutron/provider/ProviderNetworkManager.java b/neutron/src/main/java/org/opendaylight/ovsdb/neutron/provider/ProviderNetworkManager.java
new file mode 100644 (file)
index 0000000..09654fc
--- /dev/null
@@ -0,0 +1,25 @@
+package org.opendaylight.ovsdb.neutron.provider;
+
+import org.opendaylight.controller.sal.core.Node;
+import org.opendaylight.controller.sal.utils.Status;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public abstract class ProviderNetworkManager {
+    static final Logger logger = LoggerFactory.getLogger(ProviderNetworkManager.class);
+    private static ProviderNetworkManager provider;
+
+    public static ProviderNetworkManager getManager() {
+        if (provider != null) return provider;
+        if (System.getProperty("OF1.3_Provider") != null) {
+            provider = new OF13ProviderManager();
+        } else {
+            provider = new OF10ProviderManager();
+        }
+        return provider;
+    }
+
+    public abstract boolean hasPerTenantTunneling();
+    public abstract Status createTunnels(String tunnelType, String tunnelKey);
+    public abstract Status createTunnels(String tunnelType, String tunnelKey, Node source);
+}
index e0f97cf986148db7203dac1e066f03e4bb9883af..a1aefaddf503fafe6268df2093fec57cf7a8d8f2 100644 (file)
@@ -1,14 +1,11 @@
 package org.opendaylight.ovsdb.lib.notation;
 
-import com.fasterxml.jackson.annotation.JsonTypeInfo;
-import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
-import com.fasterxml.jackson.databind.annotation.JsonSerialize;
-import com.fasterxml.jackson.databind.annotation.JsonTypeIdResolver;
-
-import org.opendaylight.ovsdb.lib.notation.json.OVSDBTypesIDResolver;
 import org.opendaylight.ovsdb.lib.notation.json.UUIDSerializer;
 import org.opendaylight.ovsdb.lib.notation.json.UUIDStringConverter;
 
+import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
+import com.fasterxml.jackson.databind.annotation.JsonSerialize;
+
 @JsonDeserialize(contentConverter = UUIDStringConverter.class)
 @JsonSerialize(using = UUIDSerializer.class)
 /*
@@ -21,7 +18,33 @@ public class UUID {
         this.val = value;
     }
 
+    @Override
     public String toString() {
         return val;
     }
+
+    @Override
+    public int hashCode() {
+        final int prime = 31;
+        int result = 1;
+        result = prime * result + ((val == null) ? 0 : val.hashCode());
+        return result;
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (this == obj)
+            return true;
+        if (obj == null)
+            return false;
+        if (getClass() != obj.getClass())
+            return false;
+        UUID other = (UUID) obj;
+        if (val == null) {
+            if (other.val != null)
+                return false;
+        } else if (!val.equals(other.val))
+            return false;
+        return true;
+    }
 }
index 7dbf8850e9f2e4d8d91d925bc5368da65e544111..cb29b1b7291c24eef9bca017832998df89128278 100644 (file)
@@ -1,5 +1,7 @@
 package org.opendaylight.ovsdb.lib.table;
 
+import java.math.BigInteger;
+
 import org.opendaylight.ovsdb.lib.notation.OvsDBMap;
 import org.opendaylight.ovsdb.lib.notation.OvsDBSet;
 import org.opendaylight.ovsdb.lib.table.internal.Table;
@@ -13,7 +15,7 @@ public class Interface extends Table<Interface> {
     private String name;
     private OvsDBMap<String, String> options;
     private String type;
-    private OvsDBSet<Integer> ofport;
+    private OvsDBSet<BigInteger> ofport;
     private OvsDBSet<String> mac;
     private OvsDBMap<String, Integer> statistics;
     private OvsDBMap<String, String> status;
@@ -44,11 +46,11 @@ public class Interface extends Table<Interface> {
         this.type = type;
     }
 
-    public OvsDBSet<Integer> getOfport() {
+    public OvsDBSet<BigInteger> getOfport() {
         return ofport;
     }
 
-    public void setOfport(OvsDBSet<Integer> ofport) {
+    public void setOfport(OvsDBSet<BigInteger> ofport) {
         this.ofport = ofport;
     }
 
index bbbc79638a59c8487c2bcc6f8de0d2d3bbe5d13d..8c1d7b83bee6092fde906718ee74e1272b26fbef 100755 (executable)
@@ -187,11 +187,13 @@ public class InventoryService implements IPluginInInventoryService, InventorySer
                         updateOFBridgeName(n, (Bridge)newRow);
                     }
                     if ((oldRow == null) && (inventoryListener != null)) {
-                        inventoryListener.rowAdded(n, name.getName(), newRow);
+                        inventoryListener.rowAdded(n, name.getName(), uuid, newRow);
+                    } else if (inventoryListener != null) {
+                        inventoryListener.rowUpdated(n, name.getName(), uuid, newRow);
                     }
                 } else if (oldRow != null) {
                     if (inventoryListener != null) {
-                        inventoryListener.rowRemoved(n, name.getName(), oldRow);
+                        inventoryListener.rowRemoved(n, name.getName(), uuid, oldRow);
                     }
                     db.removeRow(name.getName(), uuid);
                 }
index 0ad26a64d76128000f2233636dda8d774f48a8ce..cff86ab176b33c1c6c408b4c6f56bc6500d822e3 100644 (file)
@@ -6,11 +6,12 @@ import java.util.Set;
 import org.opendaylight.controller.sal.core.Node;
 import org.opendaylight.controller.sal.core.Property;
 import org.opendaylight.controller.sal.core.UpdateType;
+import org.opendaylight.controller.sal.inventory.IPluginInInventoryService;
 import org.opendaylight.ovsdb.lib.database.DatabaseSchema;
 import org.opendaylight.ovsdb.lib.message.TableUpdates;
 import org.opendaylight.ovsdb.lib.table.internal.Table;
 
-public interface InventoryServiceInternal {
+public interface InventoryServiceInternal extends IPluginInInventoryService {
     public Map<String, Map<String, Table<?>>> getCache(Node n);
     public Map<String, Table<?>> getTableCache(Node n, String tableName);
     public Table<?> getRow (Node n, String tableName, String uuid);
index c0d964ebd5a502a2249a8a84b6ec02474cf9173b..1638adb30825f8be5b3797e99e4f09e5272dc7bd 100644 (file)
@@ -6,6 +6,7 @@ import org.opendaylight.ovsdb.lib.table.internal.Table;
 public interface OVSDBInventoryListener {
     public void nodeAdded(Node node);
     public void nodeRemoved(Node node);
-    public void rowAdded(Node node, String tableName, Table<?> row);
-    public void rowRemoved(Node node, String tableName, Table<?> row);
+    public void rowAdded(Node node, String tableName, String uuid, Table<?> row);
+    public void rowUpdated(Node node, String tableName, String uuid, Table<?> row);
+    public void rowRemoved(Node node, String tableName, String uuid, Table<?> row);
 }