- SAL Inventory needs to be modified to be able to take multiple IPluginInInventorySe... 17/417/1
authorJason Ye <yisye@cisco.com>
Fri, 31 May 2013 18:17:55 +0000 (11:17 -0700)
committerJason Ye <yisye@cisco.com>
Fri, 31 May 2013 18:17:55 +0000 (11:17 -0700)
- Plugin needs to introduce a wrapper of SAL interface if it's going to be used locally within the plugin.

Signed-off-by: Jason Ye <yisye@cisco.com>
opendaylight/protocol_plugins/openflow/src/main/java/org/opendaylight/controller/protocol_plugin/openflow/IDiscoveryListener.java [new file with mode: 0644]
opendaylight/protocol_plugins/openflow/src/main/java/org/opendaylight/controller/protocol_plugin/openflow/IInventoryProvider.java [new file with mode: 0644]
opendaylight/protocol_plugins/openflow/src/main/java/org/opendaylight/controller/protocol_plugin/openflow/internal/Activator.java
opendaylight/protocol_plugins/openflow/src/main/java/org/opendaylight/controller/protocol_plugin/openflow/internal/DiscoveryService.java
opendaylight/protocol_plugins/openflow/src/main/java/org/opendaylight/controller/protocol_plugin/openflow/internal/InventoryService.java
opendaylight/protocol_plugins/openflow/src/main/java/org/opendaylight/controller/protocol_plugin/openflow/internal/TopologyServiceShim.java
opendaylight/sal/implementation/src/main/java/org/opendaylight/controller/sal/implementation/internal/Inventory.java

diff --git a/opendaylight/protocol_plugins/openflow/src/main/java/org/opendaylight/controller/protocol_plugin/openflow/IDiscoveryListener.java b/opendaylight/protocol_plugins/openflow/src/main/java/org/opendaylight/controller/protocol_plugin/openflow/IDiscoveryListener.java
new file mode 100644 (file)
index 0000000..ecc5d6e
--- /dev/null
@@ -0,0 +1,19 @@
+/*
+ * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.controller.protocol_plugin.openflow;
+
+import org.opendaylight.controller.sal.discovery.IDiscoveryService;
+
+/**
+ * The interface provides method to notify the local plugin listener when an
+ * edge is discovered or removed.
+ */
+public interface IDiscoveryListener extends IDiscoveryService {
+
+}
diff --git a/opendaylight/protocol_plugins/openflow/src/main/java/org/opendaylight/controller/protocol_plugin/openflow/IInventoryProvider.java b/opendaylight/protocol_plugins/openflow/src/main/java/org/opendaylight/controller/protocol_plugin/openflow/IInventoryProvider.java
new file mode 100644 (file)
index 0000000..6b2ea30
--- /dev/null
@@ -0,0 +1,18 @@
+/*
+ * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.controller.protocol_plugin.openflow;
+
+import org.opendaylight.controller.sal.inventory.IPluginInInventoryService;
+
+/**
+ * The Interface provides inventory service to the local plugin modules
+ */
+public interface IInventoryProvider extends IPluginInInventoryService {
+
+}
index 30834cb..a93a8b7 100644 (file)
@@ -14,7 +14,9 @@ import java.util.Hashtable;
 import org.apache.felix.dm.Component;
 import org.opendaylight.controller.protocol_plugin.openflow.IDataPacketListen;
 import org.opendaylight.controller.protocol_plugin.openflow.IDataPacketMux;
+import org.opendaylight.controller.protocol_plugin.openflow.IDiscoveryListener;
 import org.opendaylight.controller.protocol_plugin.openflow.IFlowProgrammerNotifier;
+import org.opendaylight.controller.protocol_plugin.openflow.IInventoryProvider;
 import org.opendaylight.controller.protocol_plugin.openflow.IInventoryShimExternalListener;
 import org.opendaylight.controller.protocol_plugin.openflow.IInventoryShimInternalListener;
 import org.opendaylight.controller.protocol_plugin.openflow.IOFStatisticsManager;
@@ -28,7 +30,6 @@ import org.opendaylight.controller.protocol_plugin.openflow.core.internal.Contro
 import org.opendaylight.controller.sal.core.ComponentActivatorAbstractBase;
 import org.opendaylight.controller.sal.core.IContainerListener;
 import org.opendaylight.controller.sal.core.Node;
-import org.opendaylight.controller.sal.discovery.IDiscoveryService;
 import org.opendaylight.controller.sal.flowprogrammer.IPluginInFlowProgrammerService;
 import org.opendaylight.controller.sal.flowprogrammer.IPluginOutFlowProgrammerService;
 import org.opendaylight.controller.sal.inventory.IPluginInInventoryService;
@@ -44,8 +45,8 @@ import org.slf4j.LoggerFactory;
 
 /**
  * Openflow protocol plugin Activator
- * 
- * 
+ *
+ *
  */
 public class Activator extends ComponentActivatorAbstractBase {
     protected static final Logger logger = LoggerFactory
@@ -54,7 +55,7 @@ public class Activator extends ComponentActivatorAbstractBase {
     /**
      * Function called when the activator starts just after some initializations
      * are done by the ComponentActivatorAbstractBase.
-     * 
+     *
      */
     public void init() {
     }
@@ -62,7 +63,7 @@ public class Activator extends ComponentActivatorAbstractBase {
     /**
      * Function called when the activator stops just before the cleanup done by
      * ComponentActivatorAbstractBase
-     * 
+     *
      */
     public void destroy() {
     }
@@ -70,8 +71,8 @@ public class Activator extends ComponentActivatorAbstractBase {
     /**
      * Function that is used to communicate to dependency manager the list of
      * known implementations for services inside a container
-     * 
-     * 
+     *
+     *
      * @return An array containing all the CLASS objects that will be
      *         instantiated in order to get an fully working implementation
      *         Object
@@ -86,7 +87,7 @@ public class Activator extends ComponentActivatorAbstractBase {
     /**
      * Function that is called when configuration of the dependencies is
      * required.
-     * 
+     *
      * @param c
      *            dependency manager Component object, used for configuring the
      *            dependencies exported and imported
@@ -121,8 +122,8 @@ public class Activator extends ComponentActivatorAbstractBase {
             // export the service
             c.setInterface(
                     new String[] { IPluginInInventoryService.class.getName(),
-                            IInventoryShimInternalListener.class.getName() },
-                    null);
+                            IInventoryShimInternalListener.class.getName(),
+                            IInventoryProvider.class.getName() }, null);
 
             // Now lets add a service dependency to make sure the
             // provider of service exists
@@ -193,8 +194,8 @@ public class Activator extends ComponentActivatorAbstractBase {
     /**
      * Function that is used to communicate to dependency manager the list of
      * known implementations for services that are container independent.
-     * 
-     * 
+     *
+     *
      * @return An array containing all the CLASS objects that will be
      *         instantiated in order to get an fully working implementation
      *         Object
@@ -210,7 +211,7 @@ public class Activator extends ComponentActivatorAbstractBase {
     /**
      * Function that is called when configuration of the dependencies is
      * required.
-     * 
+     *
      * @param c
      *            dependency manager Component object, used for configuring the
      *            dependencies exported and imported
@@ -299,16 +300,16 @@ public class Activator extends ComponentActivatorAbstractBase {
                     .setRequired(true));
             c.add(createContainerServiceDependency(
                     GlobalConstants.DEFAULT.toString())
-                    .setService(IPluginInInventoryService.class)
-                    .setCallbacks("setPluginInInventoryService",
-                            "unsetPluginInInventoryService").setRequired(true));
+                    .setService(IInventoryProvider.class)
+                    .setCallbacks("setInventoryProvider",
+                    "unsetInventoryProvider").setRequired(true));
             c.add(createServiceDependency().setService(IDataPacketMux.class)
                     .setCallbacks("setIDataPacketMux", "unsetIDataPacketMux")
                     .setRequired(true));
             c.add(createServiceDependency()
-                    .setService(IDiscoveryService.class)
-                    .setCallbacks("setDiscoveryService",
-                            "unsetDiscoveryService").setRequired(true));
+                    .setService(IDiscoveryListener.class)
+                    .setCallbacks("setDiscoveryListener",
+                            "unsetDiscoveryListener").setRequired(true));
         }
 
         // DataPacket mux/demux services, which is teh actual engine
@@ -355,7 +356,7 @@ public class Activator extends ComponentActivatorAbstractBase {
         }
 
         if (imp.equals(TopologyServiceShim.class)) {
-            c.setInterface(new String[] { IDiscoveryService.class.getName(),
+            c.setInterface(new String[] { IDiscoveryListener.class.getName(),
                     IContainerListener.class.getName(),
                     IRefreshInternalProvider.class.getName(),
                     IInventoryShimExternalListener.class.getName() }, null);
index 0cbaf67..3be6f22 100644 (file)
@@ -26,6 +26,8 @@ import org.eclipse.osgi.framework.console.CommandInterpreter;
 import org.eclipse.osgi.framework.console.CommandProvider;
 import org.opendaylight.controller.protocol_plugin.openflow.IDataPacketListen;
 import org.opendaylight.controller.protocol_plugin.openflow.IDataPacketMux;
+import org.opendaylight.controller.protocol_plugin.openflow.IDiscoveryListener;
+import org.opendaylight.controller.protocol_plugin.openflow.IInventoryProvider;
 import org.opendaylight.controller.protocol_plugin.openflow.IInventoryShimExternalListener;
 import org.opendaylight.controller.protocol_plugin.openflow.core.IController;
 import org.opendaylight.controller.protocol_plugin.openflow.core.ISwitch;
@@ -45,8 +47,6 @@ import org.opendaylight.controller.sal.core.NodeConnector;
 import org.opendaylight.controller.sal.core.Property;
 import org.opendaylight.controller.sal.core.State;
 import org.opendaylight.controller.sal.core.UpdateType;
-import org.opendaylight.controller.sal.discovery.IDiscoveryService;
-import org.opendaylight.controller.sal.inventory.IPluginInInventoryService;
 import org.opendaylight.controller.sal.packet.Ethernet;
 import org.opendaylight.controller.sal.packet.LLDP;
 import org.opendaylight.controller.sal.packet.LLDPTLV;
@@ -67,8 +67,8 @@ public class DiscoveryService implements IInventoryShimExternalListener,
     private static Logger logger = LoggerFactory
             .getLogger(DiscoveryService.class);
     private IController controller = null;
-    private IDiscoveryService discoveryService = null;
-    private IPluginInInventoryService pluginInInventoryService = null;
+    private IDiscoveryListener discoveryListener = null;
+    private IInventoryProvider inventoryProvider = null;
     private IDataPacketMux iDataPacketMux = null;
 
     private List<NodeConnector> readyListHi = null; // newly added ports go into
@@ -292,6 +292,7 @@ public class DiscoveryService implements IInventoryShimExternalListener,
                     inPkt.getIncomingNodeConnector(), e);
             return PacketResult.IGNORED;
         }
+
         if (ethPkt.getPayload() instanceof LLDP) {
             NodeConnector dst = inPkt.getIncomingNodeConnector();
             if (isEnabled(dst)) {
@@ -360,7 +361,7 @@ public class DiscoveryService implements IInventoryShimExternalListener,
 
     /*
      * Handle discovery frames generated by our controller
-     * 
+     *
      * @return true if it's a success
      */
     private boolean processDiscoveryPacket(NodeConnector dstNodeConnector,
@@ -430,11 +431,11 @@ public class DiscoveryService implements IInventoryShimExternalListener,
             return null;
         }
 
-        if (pluginInInventoryService == null) {
+        if (inventoryProvider == null) {
             return null;
         }
 
-        Map<NodeConnector, Map<String, Property>> props = pluginInInventoryService
+        Map<NodeConnector, Map<String, Property>> props = inventoryProvider
                 .getNodeConnectorProps(false);
         if (props == null) {
             return null;
@@ -775,7 +776,7 @@ public class DiscoveryService implements IInventoryShimExternalListener,
 
     /**
      * Update Production Edge
-     * 
+     *
      * @param edge
      *            The Production Edge
      * @param props
@@ -811,7 +812,7 @@ public class DiscoveryService implements IInventoryShimExternalListener,
 
     /**
      * Remove Production Edge for a given edge port
-     * 
+     *
      * @param edgePort
      *            The OF edge port
      */
@@ -826,8 +827,8 @@ public class DiscoveryService implements IInventoryShimExternalListener,
         }
 
         // notify Topology
-        if (this.discoveryService != null) {
-            this.discoveryService.notifyEdge(edge, UpdateType.REMOVED, null);
+        if (this.discoveryListener != null) {
+            this.discoveryListener.notifyEdge(edge, UpdateType.REMOVED, null);
         }
         logger.trace("Remove edge {}", edge);
     }
@@ -858,8 +859,8 @@ public class DiscoveryService implements IInventoryShimExternalListener,
         }
 
         // notify Topology
-        if (this.discoveryService != null) {
-            this.discoveryService.notifyEdge(edge, UpdateType.REMOVED, null);
+        if (this.discoveryListener != null) {
+            this.discoveryListener.notifyEdge(edge, UpdateType.REMOVED, null);
         }
         logger.trace("Remove {}", nodeConnector);
     }
@@ -869,11 +870,11 @@ public class DiscoveryService implements IInventoryShimExternalListener,
     }
 
     private void updateEdge(Edge edge, UpdateType type, Set<Property> props) {
-        if (discoveryService == null) {
+        if (discoveryListener == null) {
             return;
         }
 
-        this.discoveryService.notifyEdge(edge, type, props);
+        this.discoveryListener.notifyEdge(edge, type, props);
 
         NodeConnector src = edge.getTailNodeConnector(), dst = edge
                 .getHeadNodeConnector();
@@ -1382,9 +1383,6 @@ public class DiscoveryService implements IInventoryShimExternalListener,
         removeDiscovery(node);
     }
 
-    public void updateNode(Node node, Set<Property> props) {
-    }
-
     void setController(IController s) {
         this.controller = s;
     }
@@ -1395,12 +1393,12 @@ public class DiscoveryService implements IInventoryShimExternalListener,
         }
     }
 
-    public void setPluginInInventoryService(IPluginInInventoryService service) {
-        this.pluginInInventoryService = service;
+    public void setInventoryProvider(IInventoryProvider service) {
+        this.inventoryProvider = service;
     }
 
-    public void unsetPluginInInventoryService(IPluginInInventoryService service) {
-        this.pluginInInventoryService = null;
+    public void unsetInventoryProvider(IInventoryProvider service) {
+        this.inventoryProvider = null;
     }
 
     public void setIDataPacketMux(IDataPacketMux service) {
@@ -1413,13 +1411,13 @@ public class DiscoveryService implements IInventoryShimExternalListener,
         }
     }
 
-    void setDiscoveryService(IDiscoveryService s) {
-        this.discoveryService = s;
+    void setDiscoveryListener(IDiscoveryListener s) {
+        this.discoveryListener = s;
     }
 
-    void unsetDiscoveryService(IDiscoveryService s) {
-        if (this.discoveryService == s) {
-            this.discoveryService = null;
+    void unsetDiscoveryListener(IDiscoveryListener s) {
+        if (this.discoveryListener == s) {
+            this.discoveryListener = null;
         }
     }
 
@@ -1444,7 +1442,7 @@ public class DiscoveryService implements IInventoryShimExternalListener,
     /**
      * Function called by the dependency manager when all the required
      * dependencies are satisfied
-     * 
+     *
      */
     void init() {
         logger.trace("Init called");
@@ -1474,7 +1472,7 @@ public class DiscoveryService implements IInventoryShimExternalListener,
      * Function called by the dependency manager when at least one dependency
      * become unsatisfied or when the component is shutting down because for
      * example bundle is being stopped.
-     * 
+     *
      */
     void destroy() {
         transmitQ = null;
@@ -1493,7 +1491,7 @@ public class DiscoveryService implements IInventoryShimExternalListener,
     /**
      * Function called by dependency manager after "init ()" is called and after
      * the services provided by the class are registered in the service registry
-     * 
+     *
      */
     void start() {
         discoveryTimer.schedule(discoveryTimerTask, discoveryTimerTick,
@@ -1513,7 +1511,7 @@ public class DiscoveryService implements IInventoryShimExternalListener,
      * Function called by the dependency manager before the services exported by
      * the component are unregistered, this will be followed by a "destroy ()"
      * calls
-     * 
+     *
      */
     void stop() {
         shuttingDown = true;
@@ -1563,7 +1561,7 @@ public class DiscoveryService implements IInventoryShimExternalListener,
     /**
      * This method returns the interval which determines how often the discovery
      * packets will be sent. Default is 300 seconds.
-     * 
+     *
      * @return The discovery interval in second
      */
     private int getDiscoveryInterval() {
@@ -1583,7 +1581,7 @@ public class DiscoveryService implements IInventoryShimExternalListener,
     /**
      * This method returns the timeout value in waiting for response of a
      * discovery query. Default is 60 seconds.
-     * 
+     *
      * @return The discovery timeout in second
      */
     private int getDiscoveryTimeout() {
@@ -1603,7 +1601,7 @@ public class DiscoveryService implements IInventoryShimExternalListener,
     /**
      * This method returns the number of retries after the initial discovery
      * packet is not received within the timeout period. Default is 2 times.
-     * 
+     *
      * @return The number of discovery retries
      */
     private int getDiscoveryRetry() {
index 8af9b3e..7a2ace5 100644 (file)
@@ -19,6 +19,7 @@ import java.util.concurrent.ConcurrentHashMap;
 import java.util.concurrent.ConcurrentMap;
 
 import org.apache.felix.dm.Component;
+import org.opendaylight.controller.protocol_plugin.openflow.IInventoryProvider;
 import org.opendaylight.controller.protocol_plugin.openflow.IInventoryShimInternalListener;
 import org.opendaylight.controller.protocol_plugin.openflow.core.IController;
 import org.opendaylight.controller.protocol_plugin.openflow.core.ISwitch;
@@ -44,11 +45,11 @@ import org.slf4j.LoggerFactory;
  * container of the network. Each instance gets container specific inventory
  * events from InventoryServiceShim. It interacts with SAL to pass inventory
  * data to the upper application.
- * 
- * 
+ *
+ *
  */
 public class InventoryService implements IInventoryShimInternalListener,
-        IPluginInInventoryService {
+        IPluginInInventoryService, IInventoryProvider {
     protected static final Logger logger = LoggerFactory
             .getLogger(InventoryService.class);
     private Set<IPluginOutInventoryService> pluginOutInventoryServices = Collections
@@ -71,7 +72,7 @@ public class InventoryService implements IInventoryShimInternalListener,
     /**
      * Function called by the dependency manager when all the required
      * dependencies are satisfied
-     * 
+     *
      */
     @SuppressWarnings("rawtypes")
     void init(Component c) {
@@ -92,7 +93,7 @@ public class InventoryService implements IInventoryShimInternalListener,
      * Function called by the dependency manager when at least one dependency
      * become unsatisfied or when the component is shutting down because for
      * example bundle is being stopped.
-     * 
+     *
      */
     void destroy() {
         logger.trace("DESTROY called!");
@@ -101,7 +102,7 @@ public class InventoryService implements IInventoryShimInternalListener,
     /**
      * Function called by dependency manager after "init ()" is called and after
      * the services provided by the class are registered in the service registry
-     * 
+     *
      */
     void start() {
         logger.trace("START called!");
@@ -111,7 +112,7 @@ public class InventoryService implements IInventoryShimInternalListener,
      * Function called by the dependency manager before the services exported by
      * the component are unregistered, this will be followed by a "destroy ()"
      * calls
-     * 
+     *
      */
     void stop() {
         logger.trace("STOP called!");
@@ -299,7 +300,7 @@ public class InventoryService implements IInventoryShimInternalListener,
             }
         }
     }
-    
+
     private void updateNode(Node node, Set<Property> properties) {
         logger.trace("{} updated, props: {}", node, properties);
         if (nodeProps == null || !nodeProps.containsKey(node) ||
@@ -315,7 +316,7 @@ public class InventoryService implements IInventoryShimInternalListener,
             Property currentProperty = propertyMap.get(name);
             if (!property.equals(currentProperty)) {
                 propertyMap.put(name, property);
-                newProperties.add(property);                
+                newProperties.add(property);
             }
         }
 
index 873b53f..1d7b426 100644 (file)
@@ -25,6 +25,7 @@ import org.apache.commons.lang3.tuple.ImmutablePair;
 import org.apache.commons.lang3.tuple.Pair;
 import org.eclipse.osgi.framework.console.CommandInterpreter;
 import org.eclipse.osgi.framework.console.CommandProvider;
+import org.opendaylight.controller.protocol_plugin.openflow.IDiscoveryListener;
 import org.opendaylight.controller.protocol_plugin.openflow.IInventoryShimExternalListener;
 import org.opendaylight.controller.protocol_plugin.openflow.IOFStatisticsManager;
 import org.opendaylight.controller.protocol_plugin.openflow.IRefreshInternalProvider;
@@ -44,7 +45,6 @@ import org.opendaylight.controller.sal.core.NodeConnector;
 import org.opendaylight.controller.sal.core.Property;
 import org.opendaylight.controller.sal.core.State;
 import org.opendaylight.controller.sal.core.UpdateType;
-import org.opendaylight.controller.sal.discovery.IDiscoveryService;
 import org.opendaylight.controller.sal.topology.TopoEdgeUpdate;
 import org.opendaylight.controller.sal.utils.GlobalConstants;
 
@@ -53,7 +53,7 @@ import org.opendaylight.controller.sal.utils.GlobalConstants;
  * OpenFlow core to various listeners. The notifications are filtered based on
  * container configurations.
  */
-public class TopologyServiceShim implements IDiscoveryService,
+public class TopologyServiceShim implements IDiscoveryListener,
         IContainerListener, CommandProvider, IRefreshInternalProvider,
         IInventoryShimExternalListener {
     protected static final Logger logger = LoggerFactory
@@ -124,7 +124,7 @@ public class TopologyServiceShim implements IDiscoveryService,
                         teuMap.put(entry.container, teuList);
                         notifyListeners = true;
                     }
-                    
+
                     if (notifyListeners) {
                         for (String container : teuMap.keySet()) {
                             // notify the listener
@@ -203,7 +203,7 @@ public class TopologyServiceShim implements IDiscoveryService,
     /**
      * Function called by the dependency manager when all the required
      * dependencies are satisfied
-     * 
+     *
      */
     void init() {
         logger.trace("Init called");
@@ -313,7 +313,7 @@ public class TopologyServiceShim implements IDiscoveryService,
      * Function called by the dependency manager when at least one dependency
      * become unsatisfied or when the component is shutting down because for
      * example bundle is being stopped.
-     * 
+     *
      */
     void destroy() {
         logger.trace("DESTROY called!");
@@ -324,7 +324,7 @@ public class TopologyServiceShim implements IDiscoveryService,
     /**
      * Function called by dependency manager after "init ()" is called and after
      * the services provided by the class are registered in the service registry
-     * 
+     *
      */
     void start() {
         logger.trace("START called!");
@@ -338,7 +338,7 @@ public class TopologyServiceShim implements IDiscoveryService,
      * Function called by the dependency manager before the services exported by
      * the component are unregistered, this will be followed by a "destroy ()"
      * calls
-     * 
+     *
      */
     void stop() {
         logger.trace("STOP called!");
@@ -431,7 +431,7 @@ public class TopologyServiceShim implements IDiscoveryService,
     /**
      * Update local cache and return true if it needs to notify upper layer
      * Topology listeners.
-     * 
+     *
      * @param container
      *            The network container
      * @param edge
@@ -493,14 +493,14 @@ public class TopologyServiceShim implements IDiscoveryService,
                     "notifyLocalEdgeMap: {} for Edge {} in container {}",
                     new Object[] { type.getName(), edge, container });
         }
-        
+
         return rv;
     }
 
     private void notifyEdge(String container, Edge edge, UpdateType type,
             Set<Property> props) {
         boolean notifyListeners;
-        
+
         // Update local cache
         notifyListeners = updateLocalEdgeMap(container, edge, type, props);
 
@@ -508,7 +508,7 @@ public class TopologyServiceShim implements IDiscoveryService,
         if (notifyListeners) {
             notifyQ.add(new NotifyEntry(container, new TopoEdgeUpdate(edge, props,
                     type)));
-            logger.debug("notifyEdge: {} Edge {} in container {}", 
+            logger.debug("notifyEdge: {} Edge {} in container {}",
                     new Object[] { type.getName(), edge, container });
         }
     }
@@ -712,11 +712,11 @@ public class TopologyServiceShim implements IDiscoveryService,
      * pushes the updates to ALL the applications that have registered as
      * listeners for this service. SAL has no way of knowing which application
      * requested for the refresh.
-     * 
+     *
      * As an example of this case, is stopping and starting the Topology
      * Manager. When the topology Manager is stopped, and restarted, it will no
      * longer have the latest topology. Hence, a request is sent here.
-     * 
+     *
      * @param containerName
      * @return void
      */
@@ -731,7 +731,7 @@ public class TopologyServiceShim implements IDiscoveryService,
      * Reading the current topology database, the method will replay all the
      * edge updates for the ITopologyServiceShimListener instance in the given
      * container, which will in turn publish them toward SAL.
-     * 
+     *
      * @param containerName
      */
     private void TopologyBulkUpdate(String containerName) {
index b5f5e2b..1cc57ba 100644 (file)
@@ -9,9 +9,12 @@
 
 package org.opendaylight.controller.sal.implementation.internal;
 
+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.CopyOnWriteArrayList;
 
 import org.opendaylight.controller.sal.core.Node;
 import org.opendaylight.controller.sal.core.NodeConnector;
@@ -31,8 +34,8 @@ import org.slf4j.LoggerFactory;
 public class Inventory implements IPluginOutInventoryService, IInventoryService {
     protected static final Logger logger = LoggerFactory
             .getLogger(Inventory.class);
-    private IListenInventoryUpdates updateService = null;
-    private IPluginInInventoryService pluginService = null;
+    private List<IListenInventoryUpdates> updateService = new CopyOnWriteArrayList<IListenInventoryUpdates>();
+    private List<IPluginInInventoryService> pluginService = new CopyOnWriteArrayList<IPluginInInventoryService>();
 
     /**
      * Function called by the dependency manager when all the required
@@ -80,55 +83,80 @@ public class Inventory implements IPluginOutInventoryService, IInventoryService
 
     public void setPluginService(IPluginInInventoryService service) {
         logger.trace("Got plugin service set request {}", service);
-        this.pluginService = service;
+        this.pluginService.add(service);
     }
 
     public void unsetPluginService(IPluginInInventoryService service) {
         logger.trace("Got plugin service UNset request");
-        this.pluginService = null;
+        this.pluginService.remove(service);
     }
 
     public void setUpdateService(IListenInventoryUpdates service) {
         logger.trace("Got update service set request {}", service);
-        this.updateService = service;
+        this.updateService.add(service);
     }
 
     public void unsetUpdateService(IListenInventoryUpdates service) {
         logger.trace("Got a service UNset request");
-        this.updateService = null;
+        this.updateService.remove(service);
     }
 
     @Override
     public void updateNode(Node node, UpdateType type, Set<Property> props) {
+        if (type == null) {
+            logger.trace("Input type is null");
+            return;
+        }
+
         logger.trace("{} {}", node, type);
-        if (updateService != null) {
-            updateService.updateNode(node, type, props);
+
+        for (IListenInventoryUpdates s : this.updateService) {
+            s.updateNode(node, type, props);
         }
     }
 
     @Override
     public void updateNodeConnector(NodeConnector nodeConnector,
             UpdateType type, Set<Property> props) {
+        if (type == null) {
+            logger.trace("Input type is null");
+            return;
+        }
+
         logger.trace("{} {}", nodeConnector, type);
 
-        if ((updateService != null) && (type != null)) {
-            updateService.updateNodeConnector(nodeConnector, type, props);
+        for (IListenInventoryUpdates s : this.updateService) {
+            s.updateNodeConnector(nodeConnector, type, props);
         }
     }
 
     @Override
     public ConcurrentMap<Node, Map<String, Property>> getNodeProps() {
-        if (pluginService != null)
-            return pluginService.getNodeProps();
-        else
-            return null;
+        ConcurrentMap<Node, Map<String, Property>> nodeProps =
+            new ConcurrentHashMap<Node, Map<String, Property>>(), rv;
+
+        for (IPluginInInventoryService s : this.pluginService) {
+            rv = s.getNodeProps();
+            if (rv != null) {
+                nodeProps.putAll(rv);
+            }
+        }
+
+        return nodeProps;
     }
 
     @Override
     public ConcurrentMap<NodeConnector, Map<String, Property>> getNodeConnectorProps() {
-        if (pluginService != null)
-            return pluginService.getNodeConnectorProps(true);
-        else
-            return null;
+        ConcurrentMap<NodeConnector, Map<String, Property>> ncProps =
+            new ConcurrentHashMap<NodeConnector, Map<String, Property>>(), rv;
+
+        for (IPluginInInventoryService s : this.pluginService) {
+            rv = s.getNodeConnectorProps(true);
+            if (rv != null) {
+                ncProps.putAll(rv);
+            }
+        }
+
+        return ncProps;
     }
 }