Merge "Make configuration push timeout configurable"
[controller.git] / opendaylight / md-sal / compatibility / sal-compatibility / src / main / java / org / opendaylight / controller / sal / compatibility / InventoryAndReadAdapter.xtend
index 746d32ff1665a1ee638c5396d2b3f07b1ba28fe9..39d224ba164c937dc9ca389259f640a22b177d20 100644 (file)
@@ -3,6 +3,8 @@ 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
@@ -64,6 +66,9 @@ import org.slf4j.LoggerFactory
 
 import static extension org.opendaylight.controller.sal.common.util.Arguments.*
 import static extension org.opendaylight.controller.sal.compatibility.NodeMapping.*
+import org.opendaylight.controller.md.sal.binding.util.TypeSafeDataReader
+import java.util.concurrent.ConcurrentHashMap
+import java.util.Map
 
 class InventoryAndReadAdapter implements IPluginInReadService,
                                                                                         IPluginInInventoryService,
@@ -90,15 +95,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);
     }
@@ -129,12 +142,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 statsFromDataStore = flow.getAugmentation(FlowStatisticsData);
                                
                                if(statsFromDataStore != null){
                                        val it = new FlowOnNode(adsalFlow);
@@ -204,7 +217,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));
@@ -235,11 +248,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 ");
@@ -305,7 +318,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);
@@ -327,7 +340,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) {
@@ -338,18 +351,17 @@ 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
         
@@ -360,15 +372,64 @@ class InventoryAndReadAdapter implements IPluginInReadService,
     }
 
     override getNodeProps() {
-
-        // FIXME: Read from MD-SAL inventory service
-        return null;
+        val props = new ConcurrentHashMap<Node, Map<String, org.opendaylight.controller.sal.core.Property>>()
+        
+        val nodes = readAllMDNodes()
+        for (node : nodes.node ) {
+            val fcn = node.getAugmentation(FlowCapableNode)
+            if(fcn != null) {
+                val perNodeProps = fcn.toADNodeProperties(node.id)
+                val perNodePropMap = new ConcurrentHashMap<String, org.opendaylight.controller.sal.core.Property>
+                if(perNodeProps != null ) {
+                    for(perNodeProp : perNodeProps) {
+                        perNodePropMap.put(perNodeProp.name,perNodeProp)
+                    }
+                }
+                props.put(new Node(MD_SAL_TYPE, node.id.toADNodeId),perNodePropMap)
+            }
+        }
+        return props;
+    }
+    
+    private def readAllMDNodes() {
+        val nodesRef = InstanceIdentifier.builder(Nodes)
+            .toInstance
+        val reader = TypeSafeDataReader.forReader(dataService)
+        return reader.readOperationalData(nodesRef)
+    }
+    
+    private def readAllMDNodeConnectors(org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node node) {
+        val nodeRef = InstanceIdentifier.builder(Nodes)
+            .child(org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node,new NodeKey(node.id))
+            .toInstance
+        val reader = TypeSafeDataReader.forReader(dataService)
+        return reader.readOperationalData(nodeRef).nodeConnector
     }
 
     override getNodeConnectorProps(Boolean refresh) {
-
-        // FIXME: Read from MD-SAL Invcentory Service
-        return null;
+        // Note, because the MD-SAL has a unified data store, we can ignore the Boolean refresh, as we have no secondary 
+        // data store to refresh from
+        val props = new ConcurrentHashMap<org.opendaylight.controller.sal.core.NodeConnector, Map<String, org.opendaylight.controller.sal.core.Property>>()
+        val nodes = readAllMDNodes()
+        for (node : nodes.node) {
+            val ncs = node.readAllMDNodeConnectors
+            if(ncs != null) {
+                for( nc : ncs ) {
+                    val fcnc = nc.getAugmentation(FlowCapableNodeConnector)
+                    if(fcnc != null) {
+                        val ncps = fcnc.toADNodeConnectorProperties
+                        val ncpsm = new ConcurrentHashMap<String, org.opendaylight.controller.sal.core.Property>
+                        if(ncps != null) {
+                            for(p : ncps) {
+                                ncpsm.put(p.name,p)
+                            }
+                        }  
+                        props.put(nc.id.toADNodeConnector(node.id),ncpsm)
+                    }
+                }
+            }
+        }
+        return props
     }
 
     private def FlowCapableNode readFlowCapableNode(NodeRef ref) {
@@ -450,7 +511,7 @@ 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) {
@@ -519,4 +580,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);
+           }
+       }
 }