Move stats caching to FM StatisticsManager
[controller.git] / opendaylight / protocol_plugins / openflow / src / main / java / org / opendaylight / controller / protocol_plugin / openflow / internal / InventoryServiceShim.java
index b522063ad73fbc5bbf6239bfd829e0d26b065710..a6d5a15313719829f92d8be37f2ec3766d7dea1e 100644 (file)
@@ -19,6 +19,7 @@ import java.util.concurrent.CopyOnWriteArrayList;
 
 import org.opendaylight.controller.protocol_plugin.openflow.IInventoryShimExternalListener;
 import org.opendaylight.controller.protocol_plugin.openflow.IInventoryShimInternalListener;
+import org.opendaylight.controller.protocol_plugin.openflow.IOFStatisticsListener;
 import org.opendaylight.controller.protocol_plugin.openflow.core.IController;
 import org.opendaylight.controller.protocol_plugin.openflow.core.IMessageListener;
 import org.opendaylight.controller.protocol_plugin.openflow.core.ISwitch;
@@ -28,7 +29,9 @@ import org.opendaylight.controller.sal.core.Buffers;
 import org.opendaylight.controller.sal.core.Capabilities;
 import org.opendaylight.controller.sal.core.ConstructionException;
 import org.opendaylight.controller.sal.core.ContainerFlow;
+import org.opendaylight.controller.sal.core.Description;
 import org.opendaylight.controller.sal.core.IContainerListener;
+import org.opendaylight.controller.sal.core.MacAddress;
 import org.opendaylight.controller.sal.core.Node;
 import org.opendaylight.controller.sal.core.Node.NodeIDType;
 import org.opendaylight.controller.sal.core.NodeConnector;
@@ -37,10 +40,13 @@ import org.opendaylight.controller.sal.core.Tables;
 import org.opendaylight.controller.sal.core.TimeStamp;
 import org.opendaylight.controller.sal.core.UpdateType;
 import org.opendaylight.controller.sal.utils.GlobalConstants;
+import org.opendaylight.controller.sal.utils.NodeCreator;
 import org.openflow.protocol.OFMessage;
 import org.openflow.protocol.OFPortStatus;
 import org.openflow.protocol.OFPortStatus.OFPortReason;
 import org.openflow.protocol.OFType;
+import org.openflow.protocol.statistics.OFDescriptionStatistics;
+import org.openflow.protocol.statistics.OFStatistics;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -48,17 +54,17 @@ import org.slf4j.LoggerFactory;
  * The class describes a shim layer that bridges inventory events from Openflow
  * core to various listeners. The notifications are filtered based on container
  * configurations.
- * 
- * 
+ *
+ *
  */
 public class InventoryServiceShim implements IContainerListener,
-        IMessageListener, ISwitchStateListener {
+        IMessageListener, ISwitchStateListener, IOFStatisticsListener {
     protected static final Logger logger = LoggerFactory
             .getLogger(InventoryServiceShim.class);
     private IController controller = null;
-    private ConcurrentMap<String, IInventoryShimInternalListener> inventoryShimInternalListeners = new ConcurrentHashMap<String, IInventoryShimInternalListener>();
-    private List<IInventoryShimExternalListener> inventoryShimExternalListeners = new CopyOnWriteArrayList<IInventoryShimExternalListener>();
-    private ConcurrentMap<NodeConnector, List<String>> containerMap = new ConcurrentHashMap<NodeConnector, List<String>>();
+    private final ConcurrentMap<String, IInventoryShimInternalListener> inventoryShimInternalListeners = new ConcurrentHashMap<String, IInventoryShimInternalListener>();
+    private final List<IInventoryShimExternalListener> inventoryShimExternalListeners = new CopyOnWriteArrayList<IInventoryShimExternalListener>();
+    private final ConcurrentMap<NodeConnector, List<String>> containerMap = new ConcurrentHashMap<NodeConnector, List<String>>();
 
     void setController(IController s) {
         this.controller = s;
@@ -130,7 +136,7 @@ public class InventoryServiceShim implements IContainerListener,
     /**
      * Function called by the dependency manager when all the required
      * dependencies are satisfied
-     * 
+     *
      */
     void init() {
         this.controller.addMessageListener(OFType.PORT_STATUS, this);
@@ -149,7 +155,7 @@ public class InventoryServiceShim implements IContainerListener,
      * 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() {
         this.controller.removeMessageListener(OFType.PACKET_IN, this);
@@ -174,7 +180,7 @@ public class InventoryServiceShim implements IContainerListener,
 
     protected void handlePortStatusMessage(ISwitch sw, OFPortStatus m)
             throws ConstructionException {
-        Node node = new Node(NodeIDType.OPENFLOW, sw.getId());
+        Node node = NodeCreator.createOFNode(sw.getId());
         NodeConnector nodeConnector = PortConverter.toNodeConnector(m.getDesc()
                 .getPortNumber(), node);
         UpdateType type = null;
@@ -199,8 +205,9 @@ public class InventoryServiceShim implements IContainerListener,
 
     @Override
     public void switchAdded(ISwitch sw) {
-        if (sw == null)
+        if (sw == null) {
             return;
+        }
 
         // Add all the nodeConnectors of this switch
         Map<NodeConnector, Set<Property>> ncProps = InventoryServiceHelper
@@ -216,8 +223,9 @@ public class InventoryServiceShim implements IContainerListener,
 
     @Override
     public void switchDeleted(ISwitch sw) {
-        if (sw == null)
+        if (sw == null) {
             return;
+        }
 
         removeNode(sw);
     }
@@ -230,6 +238,8 @@ public class InventoryServiceShim implements IContainerListener,
     @Override
     public void tagUpdated(String containerName, Node n, short oldTag,
             short newTag, UpdateType t) {
+        logger.debug("tagUpdated: {} type {} for container {}", new Object[] {
+                n, t, containerName });
     }
 
     @Override
@@ -240,6 +250,8 @@ public class InventoryServiceShim implements IContainerListener,
     @Override
     public void nodeConnectorUpdated(String containerName, NodeConnector p,
             UpdateType t) {
+        logger.debug("nodeConnectorUpdated: {} type {} for container {}",
+                new Object[] { p, t, containerName });
         if (this.containerMap == null) {
             logger.error("containerMap is NULL");
             return;
@@ -277,6 +289,7 @@ public class InventoryServiceShim implements IContainerListener,
 
         // notify InventoryService
         notifyInventoryShimInternalListener(containerName, p, t, null);
+        notifyInventoryShimInternalListener(containerName, p.getNode(), t, null);
     }
 
     private void notifyInventoryShimExternalListener(Node node,
@@ -302,7 +315,7 @@ public class InventoryServiceShim implements IContainerListener,
                     type, props);
             logger.trace(
                     "notifyInventoryShimInternalListener {} type {} for container {}",
-                    nodeConnector, type, container);
+                    new Object[] { nodeConnector, type, container });
         }
     }
 
@@ -351,6 +364,14 @@ public class InventoryServiceShim implements IContainerListener,
                 inventoryShimInternalListener.updateNode(node, type, null);
             }
             break;
+        case CHANGED:
+            // Notify only the default Inventory Service
+            inventoryShimDefaultListener = inventoryShimInternalListeners
+                    .get(GlobalConstants.DEFAULT.toString());
+            if (inventoryShimDefaultListener != null) {
+                inventoryShimDefaultListener.updateNode(node, type, props);
+            }
+            break;
         default:
             break;
         }
@@ -359,15 +380,20 @@ public class InventoryServiceShim implements IContainerListener,
         notifyInventoryShimExternalListener(node, type, props);
     }
 
-    private void addNode(ISwitch sw) {
-        Node node;
-        try {
-            node = new Node(NodeIDType.OPENFLOW, sw.getId());
-        } catch (ConstructionException e) {
-            logger.error("{}", e.getMessage());
-            return;
+    private void notifyInventoryShimInternalListener(String container,
+            Node node, UpdateType type, Set<Property> props) {
+        IInventoryShimInternalListener inventoryShimInternalListener = inventoryShimInternalListeners
+                .get(container);
+        if (inventoryShimInternalListener != null) {
+            inventoryShimInternalListener.updateNode(node, type, props);
+            logger.trace(
+                    "notifyInventoryShimInternalListener {} type {} for container {}",
+                    new Object[] { node, type, container });
         }
+    }
 
+    private void addNode(ISwitch sw) {
+        Node node = NodeCreator.createOFNode(sw.getId());
         UpdateType type = UpdateType.ADDED;
 
         Set<Property> props = new HashSet<Property>();
@@ -378,6 +404,7 @@ public class InventoryServiceShim implements IContainerListener,
         Long connectedSinceTime = (connectedSince == null) ? 0 : connectedSince
                 .getTime();
         props.add(new TimeStamp(connectedSinceTime, "connectedSince"));
+        props.add(new MacAddress(deriveMacAddress(sid)));
 
         byte tables = sw.getTables();
         Tables t = new Tables(tables);
@@ -399,6 +426,7 @@ public class InventoryServiceShim implements IContainerListener,
         if (b != null) {
             props.add(b);
         }
+
         // Notify all internal and external listeners
         notifyInventoryShimListener(node, type, props);
     }
@@ -425,4 +453,42 @@ public class InventoryServiceShim implements IContainerListener,
             switchAdded(sw);
         }
     }
+
+    @Override
+    public void descriptionStatisticsRefreshed(Long switchId, List<OFStatistics> descriptionStats) {
+        Node node = NodeCreator.createOFNode(switchId);
+        Set<Property> properties = new HashSet<Property>(1);
+        OFDescriptionStatistics ofDesc = (OFDescriptionStatistics) descriptionStats.get(0);
+        Description desc = new Description(ofDesc.getDatapathDescription());
+        properties.add(desc);
+
+        // Notify all internal and external listeners
+        notifyInventoryShimListener(node, UpdateType.CHANGED, properties);
+    }
+
+    private byte[] deriveMacAddress(long dpid) {
+        byte[] mac = new byte[] { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
+
+        for (short i = 0; i < 6; i++) {
+            mac[5 - i] = (byte) dpid;
+            dpid >>= 8;
+        }
+
+        return mac;
+    }
+
+    @Override
+    public void flowStatisticsRefreshed(Long switchId, List<OFStatistics> flows) {
+        // Nothing to do
+    }
+
+    @Override
+    public void portStatisticsRefreshed(Long switchId, List<OFStatistics> ports) {
+        // Nothing to do
+    }
+
+    @Override
+    public void tableStatisticsRefreshed(Long switchId, List<OFStatistics> tables) {
+        // Nothing to do
+    }
 }