Fixed OVSDB Passive Connection interaction bugs with Connection Manager. 74/2574/1
authorMadhu Venugopal <mavenugo@gmail.com>
Sun, 10 Nov 2013 02:18:43 +0000 (18:18 -0800)
committerMadhu Venugopal <mavenugo@gmail.com>
Sun, 10 Nov 2013 02:18:43 +0000 (18:18 -0800)
Luis (from the integration project) identified the SAL Connection service interaction issues
during OVSDB Passive connection to the controller.
Also introduced the disconnect handling, including cleaning up the tableCache for that node.

Change-Id: Ieb7ed88e164574c3f27413d8ccae38222e82d89f
Signed-off-by: Madhu Venugopal <mavenugo@gmail.com>
ovsdb/src/main/java/org/opendaylight/ovsdb/plugin/Activator.java
ovsdb/src/main/java/org/opendaylight/ovsdb/plugin/ChannelConnectionHandler.java [new file with mode: 0644]
ovsdb/src/main/java/org/opendaylight/ovsdb/plugin/ConnectionService.java
ovsdb/src/main/java/org/opendaylight/ovsdb/plugin/InventoryService.java
ovsdb/src/main/java/org/opendaylight/ovsdb/plugin/InventoryServiceInternal.java

index 2268bc9dfdbfcf6b57485df44be7f102f44d29c8..ebab6599cb1e4efd6cb2b38df330d82f3d587bd1 100755 (executable)
@@ -13,6 +13,7 @@ import org.opendaylight.controller.sal.utils.INodeFactory;
 import org.opendaylight.controller.sal.core.Node;
 import org.opendaylight.controller.sal.core.NodeConnector;
 import org.opendaylight.controller.sal.inventory.IPluginInInventoryService;
+import org.opendaylight.controller.sal.inventory.IPluginOutInventoryService;
 import org.opendaylight.controller.sal.utils.GlobalConstants;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -95,6 +96,11 @@ public class Activator extends ComponentActivatorAbstractBase {
             c.setInterface(
                     new String[] {IPluginInInventoryService.class.getName(),
                             InventoryServiceInternal.class.getName()}, props);
+            c.add(createServiceDependency()
+                    .setService(IPluginOutInventoryService.class, "(scope=Global)")
+                    .setCallbacks("setPluginOutInventoryServices",
+                            "unsetPluginOutInventoryServices")
+                    .setRequired(true));
         }
 
         if (imp.equals(NodeFactory.class)) {
diff --git a/ovsdb/src/main/java/org/opendaylight/ovsdb/plugin/ChannelConnectionHandler.java b/ovsdb/src/main/java/org/opendaylight/ovsdb/plugin/ChannelConnectionHandler.java
new file mode 100644 (file)
index 0000000..2e2ab04
--- /dev/null
@@ -0,0 +1,27 @@
+package org.opendaylight.ovsdb.plugin;
+
+import org.opendaylight.controller.sal.core.Node;
+
+import io.netty.channel.ChannelFuture;
+import io.netty.channel.ChannelFutureListener;
+
+public class ChannelConnectionHandler implements ChannelFutureListener {
+    Node node;
+    ConnectionService connectionService;
+    public Node getNode() {
+        return node;
+    }
+    public void setNode(Node node) {
+        this.node = node;
+    }
+    public ConnectionService getConnectionService() {
+        return connectionService;
+    }
+    public void setConnectionService(ConnectionService connectionService) {
+        this.connectionService = connectionService;
+    }
+    @Override
+    public void operationComplete(ChannelFuture arg0) throws Exception {
+        connectionService.channelClosed(node);
+    }
+}
index a41fc02aa039d8fba1493629c57646680e2d3079..7449d6da7b60b2b5431ed9bb04d42863565d2b1f 100755 (executable)
@@ -15,6 +15,7 @@ import io.netty.util.CharsetUtil;
 import org.opendaylight.controller.sal.connection.ConnectionConstants;
 import org.opendaylight.controller.sal.connection.IPluginInConnectionService;
 import org.opendaylight.controller.sal.core.Node;
+import org.opendaylight.controller.sal.core.Property;
 import org.opendaylight.controller.sal.utils.Status;
 import org.opendaylight.controller.sal.utils.StatusCode;
 import org.opendaylight.ovsdb.lib.database.DatabaseSchema;
@@ -39,8 +40,10 @@ import com.google.common.util.concurrent.ListenableFuture;
 import java.net.InetAddress;
 import java.net.InetSocketAddress;
 import java.util.Arrays;
+import java.util.HashSet;
 import java.util.List;
 import java.util.Map;
+import java.util.Set;
 import java.util.concurrent.ConcurrentHashMap;
 import java.util.concurrent.ConcurrentMap;
 import java.util.concurrent.ExecutionException;
@@ -215,6 +218,11 @@ public class ConnectionService implements IPluginInConnectionService, IConnectio
         ovsdb.registerCallback(instance);
         ovsdbConnections.put(identifier, connection);
 
+        ChannelConnectionHandler handler = new ChannelConnectionHandler();
+        handler.setNode(node);
+        handler.setConnectionService(this);
+        ChannelFuture closeFuture = channel.closeFuture();
+        closeFuture.addListener(handler);
         // Keeping the Initial inventory update(s) on its own thread.
         new Thread() {
             Connection connection;
@@ -237,14 +245,21 @@ public class ConnectionService implements IPluginInConnectionService, IConnectio
         return node;
     }
 
+    public void channelClosed(Node node) throws Exception {
+        logger.error("Connection to Node : {} closed", node);
+        inventoryServiceInternal.removeNode(node);
+    }
+
     private void initializeInventoryForNewNode (Connection connection) throws InterruptedException, ExecutionException {
         Channel channel = connection.getChannel();
         InetAddress address = ((InetSocketAddress)channel.remoteAddress()).getAddress();
         int port = ((InetSocketAddress)channel.remoteAddress()).getPort();
         IPAddressProperty addressProp = new IPAddressProperty(address);
         L4PortProperty l4Port = new L4PortProperty(port);
-        inventoryServiceInternal.addNodeProperty(connection.getNode(), addressProp);
-        inventoryServiceInternal.addNodeProperty(connection.getNode(), l4Port);
+        Set<Property> props = new HashSet<Property>();
+        props.add(addressProp);
+        props.add(l4Port);
+        inventoryServiceInternal.addNode(connection.getNode(), props);
 
         List<String> dbNames = Arrays.asList(Open_vSwitch.NAME.getName());
         ListenableFuture<DatabaseSchema> dbSchemaF = connection.getRpc().get_schema(dbNames);
index 5c90aab5a2a7a7b2e6631951cc5648caf15f8856..86106166b4e0d32946f5420f764b9ca0ffdd03ff 100755 (executable)
@@ -6,13 +6,16 @@ import java.util.Map;
 import java.util.Set;
 import java.util.concurrent.ConcurrentHashMap;
 import java.util.concurrent.ConcurrentMap;
+import java.util.concurrent.CopyOnWriteArraySet;
 
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.opendaylight.controller.sal.core.Node;
 import org.opendaylight.controller.sal.core.NodeConnector;
 import org.opendaylight.controller.sal.core.Property;
+import org.opendaylight.controller.sal.core.UpdateType;
 import org.opendaylight.controller.sal.inventory.IPluginInInventoryService;
+import org.opendaylight.controller.sal.inventory.IPluginOutInventoryService;
 import org.opendaylight.ovsdb.lib.database.DatabaseSchema;
 import org.opendaylight.ovsdb.lib.message.TableUpdate;
 import org.opendaylight.ovsdb.lib.message.TableUpdate.Row;
@@ -29,7 +32,8 @@ import com.google.common.collect.Maps;
 public class InventoryService implements IPluginInInventoryService, InventoryServiceInternal {
     private static final Logger logger = LoggerFactory
             .getLogger(InventoryService.class);
-
+    private final Set<IPluginOutInventoryService> pluginOutInventoryServices =
+            new CopyOnWriteArraySet<IPluginOutInventoryService>();
     private ConcurrentMap<Node, Map<String, Property>> nodeProps;
     private ConcurrentMap<NodeConnector, Map<String, Property>> nodeConnectorProps;
     private Map<Node, NodeDB> dbCache = Maps.newHashMap();
@@ -72,6 +76,19 @@ public class InventoryService implements IPluginInInventoryService, InventorySer
     public void stop() {
     }
 
+    public void setPluginOutInventoryServices(IPluginOutInventoryService service) {
+        if (this.pluginOutInventoryServices != null) {
+            this.pluginOutInventoryServices.add(service);
+        }
+    }
+
+    public void unsetPluginOutInventoryServices(
+            IPluginOutInventoryService service) {
+        if (this.pluginOutInventoryServices != null) {
+            this.pluginOutInventoryServices.remove(service);
+        }
+    }
+
     /**
      * Retrieve nodes from openflow
      */
@@ -161,11 +178,21 @@ public class InventoryService implements IPluginInInventoryService, InventorySer
     }
 
     @Override
-    public void addNodeProperty(Node n, Property prop) {
-        Map<String, Property> nProp = nodeProps.get(n);
+    public void addNode(Node node, Set<Property> props) {
+        addNodeProperty(node, UpdateType.ADDED, props);
+    }
+
+    @Override
+    public void addNodeProperty(Node node, UpdateType type, Set<Property> props) {
+        Map<String, Property> nProp = nodeProps.get(node);
         if (nProp == null) nProp = new HashMap<String, Property>();
-        nProp.put(prop.getName(), prop);
-        nodeProps.put(n, nProp);
+        for (Property prop : props) {
+            nProp.put(prop.getName(), prop);
+        }
+        nodeProps.put(node, nProp);
+        for (IPluginOutInventoryService service : pluginOutInventoryServices) {
+            service.updateNode(node, type, props);
+        }
     }
 
     @Override
@@ -184,4 +211,13 @@ public class InventoryService implements IPluginInInventoryService, InventorySer
         }
         db.setSchema(schema);
     }
+
+    @Override
+    public void removeNode(Node node) {
+        for (IPluginOutInventoryService service : pluginOutInventoryServices) {
+            service.updateNode(node, UpdateType.REMOVED, null);
+        }
+        nodeProps.remove(node);
+        dbCache.remove(node);
+    }
 }
index 17b0d6b9b207c95883122c35e90ebdd07e77d511..9eec13ec251d5ddebc2c59f426815ae73d7019d3 100644 (file)
@@ -1,9 +1,11 @@
 package org.opendaylight.ovsdb.plugin;
 
 import java.util.Map;
+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.ovsdb.lib.database.DatabaseSchema;
 import org.opendaylight.ovsdb.lib.message.TableUpdates;
 import org.opendaylight.ovsdb.lib.table.internal.Table;
@@ -16,8 +18,10 @@ public interface InventoryServiceInternal {
     public void removeRow(Node n, String tableName, String uuid);
     public void processTableUpdates(Node n, TableUpdates tableUpdates);
     public void updateDatabaseSchema(Node n, DatabaseSchema schema);
-    public     DatabaseSchema getDatabaseSchema(Node n);
+    public DatabaseSchema getDatabaseSchema(Node n);
     public void printCache(Node n);
 
-    public void addNodeProperty(Node n, Property prop);
+    public void addNode(Node n, Set<Property> props);
+    public void removeNode(Node n);
+    public void addNodeProperty(Node node, UpdateType type, Set<Property> props);
 }
\ No newline at end of file