Merge "Prevent ConfigPusher from killing its thread"
[controller.git] / opendaylight / md-sal / compatibility / sal-compatibility / src / main / java / org / opendaylight / controller / sal / compatibility / InventoryAndReadAdapter.xtend
index 56ca1b609cf2c6eeb6d5dfe669b660319d4d792d..60e43247c2810383f49b05a24699d14c1c1f355b 100644 (file)
@@ -1,8 +1,17 @@
+/*
+ * Copyright (c) 2014 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.sal.compatibility
 
 import java.util.ArrayList
 import java.util.Collections
 import java.util.List
+import java.util.Set
+import java.util.concurrent.CopyOnWriteArrayList;
 import org.opendaylight.controller.sal.binding.api.data.DataBrokerService
 import org.opendaylight.controller.sal.binding.api.data.DataProviderService
 import org.opendaylight.controller.sal.core.Edge
@@ -93,15 +102,23 @@ class InventoryAndReadAdapter implements IPluginInReadService,
     @Property
     OpendaylightFlowTableStatisticsService flowTableStatisticsService;
 
-    @Property
-    IPluginOutInventoryService inventoryPublisher;
-
     @Property
     FlowTopologyDiscoveryService topologyDiscovery;
     
     @Property
-    List<IPluginOutReadService> statisticsPublisher = new ArrayList<IPluginOutReadService>();
-       
+    List<IPluginOutReadService> statisticsPublisher = new CopyOnWriteArrayList<IPluginOutReadService>();
+
+    @Property
+    List<IPluginOutInventoryService> inventoryPublisher = new CopyOnWriteArrayList<IPluginOutInventoryService>();
+
+       def setInventoryPublisher(IPluginOutInventoryService listener){
+        inventoryPublisher.add(listener);
+       }
+
+       def unsetInventoryPublisher(IPluginOutInventoryService listener){
+        inventoryPublisher.remove(listener);
+       }
+
     def setReadPublisher(IPluginOutReadService listener) {
        statisticsPublisher.add(listener);
     }
@@ -132,12 +149,12 @@ class InventoryAndReadAdapter implements IPluginInReadService,
                val table= it.readConfigurationData(tableRef) as Table;
                
                if(table != null){
-                       LOG.info("Number of flows installed in table 0 of node {} : {}",node,table.flow.size);
+                       LOG.trace("Number of flows installed in table 0 of node {} : {}",node,table.flow.size);
                        
                        for(flow : table.flow){
                                
-                               val adsalFlow = ToSalConversionsUtils.toFlow(flow);
-                               val statsFromDataStore = flow.getAugmentation(FlowStatisticsData) as FlowStatisticsData;
+                               val adsalFlow = ToSalConversionsUtils.toFlow(flow,node);
+                               val statsFromDataStore = flow.getAugmentation(FlowStatisticsData);
                                
                                if(statsFromDataStore != null){
                                        val it = new FlowOnNode(adsalFlow);
@@ -207,7 +224,7 @@ class InventoryAndReadAdapter implements IPluginInReadService,
                        
                        for (table : dsFlowCapableNode.table){
                                
-                               val tableStats = table.getAugmentation(FlowTableStatisticsData) as FlowTableStatisticsData;
+                               val tableStats = table.getAugmentation(FlowTableStatisticsData);
                                
                                if(tableStats != null){
                                        ret.add(toNodeTableStatistics(tableStats.flowTableStatistics,table.id,node));
@@ -238,11 +255,11 @@ class InventoryAndReadAdapter implements IPluginInReadService,
                val table= it.readConfigurationData(tableRef) as Table;
                
                if(table != null){
-                       LOG.info("Number of flows installed in table 0 of node {} : {}",node,table.flow.size);
+                       LOG.trace("Number of flows installed in table 0 of node {} : {}",node,table.flow.size);
                        
                        for(mdsalFlow : table.flow){
                                if(FromSalConversionsUtils.flowEquals(mdsalFlow, MDFlowMapping.toMDSalflow(targetFlow))){
-                                       val statsFromDataStore = mdsalFlow.getAugmentation(FlowStatisticsData) as FlowStatisticsData;
+                                       val statsFromDataStore = mdsalFlow.getAugmentation(FlowStatisticsData);
                                        
                                        if(statsFromDataStore != null){
                                                LOG.debug("Found matching flow in the data store flow table ");
@@ -308,7 +325,7 @@ class InventoryAndReadAdapter implements IPluginInReadService,
                val table= it.readConfigurationData(tableRef) as Table;
                
                if(table != null){
-                       val tableStats = table.getAugmentation(FlowTableStatisticsData) as FlowTableStatisticsData;
+                       val tableStats = table.getAugmentation(FlowTableStatisticsData);
                                
                        if(tableStats != null){
                                nodeStats =  toNodeTableStatistics(tableStats.flowTableStatistics,table.id,nodeTable.node);
@@ -330,7 +347,7 @@ class InventoryAndReadAdapter implements IPluginInReadService,
     override onNodeRemoved(NodeRemoved notification) {
         val properties = Collections.<org.opendaylight.controller.sal.core.Property>emptySet();
 
-        inventoryPublisher.updateNode(notification.nodeRef.toADNode, UpdateType.REMOVED, properties);
+        publishNodeUpdate(notification.nodeRef.toADNode, UpdateType.REMOVED, properties);
     }
 
     override onNodeConnectorUpdated(NodeConnectorUpdated update) {
@@ -341,24 +358,26 @@ class InventoryAndReadAdapter implements IPluginInReadService,
 
         var nodeConnector = update.nodeConnectorRef.toADNodeConnector
 
-        inventoryPublisher.updateNodeConnector(nodeConnector , updateType , update.toADNodeConnectorProperties);
+        publishNodeConnectorUpdate(nodeConnector , updateType , update.toADNodeConnectorProperties);
     }
 
     override onNodeUpdated(NodeUpdated notification) {
-        val properties = Collections.<org.opendaylight.controller.sal.core.Property>emptySet();
         val InstanceIdentifier<? extends DataObject> identifier = notification.nodeRef.value  as InstanceIdentifier<? extends DataObject>;
 
         var updateType = UpdateType.CHANGED;
         if ( this._dataService.readOperationalData(identifier) == null ){
             updateType = UpdateType.ADDED;
         }
-        inventoryPublisher.updateNode(notification.nodeRef.toADNode, updateType, notification.toADNodeProperties);
+        publishNodeUpdate(notification.nodeRef.toADNode, updateType, notification.toADNodeProperties);
         
                //Notify the listeners of IPluginOutReadService
         
         for (statsPublisher : statisticsPublisher){
                        val nodeRef = InstanceIdentifier.builder(Nodes).child(org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node,new NodeKey(notification.id)).toInstance;
-                       statsPublisher.descriptionStatisticsUpdated(nodeRef.toADNode,toNodeDescription(notification.nodeRef));
+            val description = notification.nodeRef.toNodeDescription
+            if(description != null) {
+                         statsPublisher.descriptionStatisticsUpdated(nodeRef.toADNode,description);
+                       }
                }
     }
 
@@ -425,9 +444,12 @@ class InventoryAndReadAdapter implements IPluginInReadService,
 
     private def FlowCapableNode readFlowCapableNode(NodeRef ref) {
         val dataObject = dataService.readOperationalData(ref.value as InstanceIdentifier<? extends DataObject>);
-        val node = dataObject.checkInstanceOf(
-            org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node);
-        return node.getAugmentation(FlowCapableNode);
+        if(dataObject != null) {
+            val node = dataObject.checkInstanceOf(
+                org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node);
+            return node.getAugmentation(FlowCapableNode);
+        }
+        return null;
     }
 
     private def FlowCapableNodeConnector readFlowCapableNodeConnector(NodeConnectorRef ref) {
@@ -483,14 +505,16 @@ class InventoryAndReadAdapter implements IPluginInReadService,
        
        private def toNodeDescription(NodeRef nodeRef){
                val capableNode = readFlowCapableNode(nodeRef);
-
-        val it = new NodeDescription()
-        manufacturer = capableNode.manufacturer
-        serialNumber = capableNode.serialNumber
-        software = capableNode.software
-        description = capableNode.description
-        
-        return it;
+        if(capableNode !=null) {
+            val it = new NodeDescription()
+            manufacturer = capableNode.manufacturer
+            serialNumber = capableNode.serialNumber
+            software = capableNode.software
+            description = capableNode.description
+            
+            return it;
+         }
+         return null;
        }
     
     
@@ -502,20 +526,20 @@ class InventoryAndReadAdapter implements IPluginInReadService,
         * OpendaylightFlowStatisticsListener interface implementation
         */
        override onAggregateFlowStatisticsUpdate(AggregateFlowStatisticsUpdate notification) {
-               throw new UnsupportedOperationException("TODO: auto-generated method stub")
+        //Ignoring this notification as there does not seem to be a way to bubble this up to AD-SAL
        }
        
        override onFlowsStatisticsUpdate(FlowsStatisticsUpdate notification) {
                
                val adsalFlowsStatistics = new ArrayList<FlowOnNode>();
+               val nodeRef = InstanceIdentifier.builder(Nodes).child(org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node,new NodeKey(notification.id)).toInstance;
                
                for(flowStats : notification.flowAndStatisticsMapList){
                        if(flowStats.tableId == 0)
-                               adsalFlowsStatistics.add(toFlowOnNode(flowStats));
+                               adsalFlowsStatistics.add(toFlowOnNode(flowStats,nodeRef.toADNode));
                }
                
                for (statsPublisher : statisticsPublisher){
-                       val nodeRef = InstanceIdentifier.builder(Nodes).child(org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node,new NodeKey(notification.id)).toInstance;
                        statsPublisher.nodeFlowStatisticsUpdated(nodeRef.toADNode,adsalFlowsStatistics);
                }
                
@@ -560,9 +584,9 @@ class InventoryAndReadAdapter implements IPluginInReadService,
                
        }
        
-       private static def toFlowOnNode (FlowAndStatisticsMapList flowAndStatsMap){
+       private static def toFlowOnNode (FlowAndStatisticsMapList flowAndStatsMap,Node node){
                
-               val it = new FlowOnNode(ToSalConversionsUtils.toFlow(flowAndStatsMap));
+               val it = new FlowOnNode(ToSalConversionsUtils.toFlow(flowAndStatsMap,node));
                
                byteCount = flowAndStatsMap.byteCount.value.longValue;
                packetCount = flowAndStatsMap.packetCount.value.longValue;
@@ -571,4 +595,21 @@ class InventoryAndReadAdapter implements IPluginInReadService,
                
                return it;
        }
+
+       override  getConfiguredNotConnectedNodes() {
+        return Collections.emptySet();
+       }
+
+
+       private def publishNodeUpdate(Node node, UpdateType updateType, Set<org.opendaylight.controller.sal.core.Property> properties){
+           for( publisher : inventoryPublisher){
+               publisher.updateNode(node, updateType, properties);
+           }
+       }
+
+       private def publishNodeConnectorUpdate(org.opendaylight.controller.sal.core.NodeConnector nodeConnector, UpdateType updateType, Set<org.opendaylight.controller.sal.core.Property> properties){
+           for( publisher : inventoryPublisher){
+               publisher.updateNodeConnector(nodeConnector, updateType, properties);
+           }
+       }
 }