Merge "Config save support for networkconfiguration.neutron"
[controller.git] / opendaylight / md-sal / compatibility / sal-compatibility / src / main / java / org / opendaylight / controller / sal / compatibility / InventoryAndReadAdapter.xtend
1 package org.opendaylight.controller.sal.compatibility
2
3 import java.util.ArrayList
4 import java.util.Collections
5 import java.util.List
6 import java.util.Set
7 import java.util.concurrent.CopyOnWriteArrayList;
8 import org.opendaylight.controller.sal.binding.api.data.DataBrokerService
9 import org.opendaylight.controller.sal.binding.api.data.DataProviderService
10 import org.opendaylight.controller.sal.core.Edge
11 import org.opendaylight.controller.sal.core.Node
12 import org.opendaylight.controller.sal.core.NodeTable
13 import org.opendaylight.controller.sal.core.UpdateType
14 import org.opendaylight.controller.sal.flowprogrammer.Flow
15 import org.opendaylight.controller.sal.inventory.IPluginInInventoryService
16 import org.opendaylight.controller.sal.inventory.IPluginOutInventoryService
17 import org.opendaylight.controller.sal.reader.FlowOnNode
18 import org.opendaylight.controller.sal.reader.IPluginInReadService
19 import org.opendaylight.controller.sal.reader.IPluginOutReadService
20 import org.opendaylight.controller.sal.reader.NodeConnectorStatistics
21 import org.opendaylight.controller.sal.reader.NodeDescription
22 import org.opendaylight.controller.sal.reader.NodeTableStatistics
23 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNode
24 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNodeConnector
25 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.Table
26 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.TableKey
27 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.AggregateFlowStatisticsUpdate
28 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.FlowStatisticsData
29 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.FlowsStatisticsUpdate
30 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.GetAllFlowsStatisticsFromAllFlowTablesInputBuilder
31 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.GetFlowStatisticsFromFlowTableInputBuilder
32 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.OpendaylightFlowStatisticsListener
33 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.OpendaylightFlowStatisticsService
34 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.flow.and.statistics.map.list.FlowAndStatisticsMapList
35 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.table.statistics.rev131215.FlowTableStatisticsData
36 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.table.statistics.rev131215.FlowTableStatisticsUpdate
37 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.table.statistics.rev131215.GetFlowTablesStatisticsInputBuilder
38 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.table.statistics.rev131215.OpendaylightFlowTableStatisticsListener
39 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.table.statistics.rev131215.OpendaylightFlowTableStatisticsService
40 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.table.statistics.rev131215.flow.table.statistics.FlowTableStatistics
41 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.topology.discovery.rev130819.FlowTopologyDiscoveryService
42 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.topology.discovery.rev130819.Link
43 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeConnectorId
44 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeConnectorRef
45 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeConnectorRemoved
46 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeConnectorUpdated
47 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeId
48 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeRef
49 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeRemoved
50 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeUpdated
51 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.Nodes
52 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.OpendaylightInventoryListener
53 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.node.NodeConnector
54 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.node.NodeConnectorKey
55 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.NodeKey
56 import org.opendaylight.yang.gen.v1.urn.opendaylight.port.statistics.rev131214.FlowCapableNodeConnectorStatistics
57 import org.opendaylight.yang.gen.v1.urn.opendaylight.port.statistics.rev131214.FlowCapableNodeConnectorStatisticsData
58 import org.opendaylight.yang.gen.v1.urn.opendaylight.port.statistics.rev131214.GetAllNodeConnectorsStatisticsInputBuilder
59 import org.opendaylight.yang.gen.v1.urn.opendaylight.port.statistics.rev131214.GetNodeConnectorStatisticsInputBuilder
60 import org.opendaylight.yang.gen.v1.urn.opendaylight.port.statistics.rev131214.NodeConnectorStatisticsUpdate
61 import org.opendaylight.yang.gen.v1.urn.opendaylight.port.statistics.rev131214.OpendaylightPortStatisticsListener
62 import org.opendaylight.yang.gen.v1.urn.opendaylight.port.statistics.rev131214.OpendaylightPortStatisticsService
63 import org.opendaylight.yangtools.yang.binding.DataObject
64 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier
65 import org.slf4j.LoggerFactory
66
67 import static extension org.opendaylight.controller.sal.common.util.Arguments.*
68 import static extension org.opendaylight.controller.sal.compatibility.NodeMapping.*
69 import org.opendaylight.controller.md.sal.binding.util.TypeSafeDataReader
70 import java.util.concurrent.ConcurrentHashMap
71 import java.util.Map
72
73 class InventoryAndReadAdapter implements IPluginInReadService,
74                                                                                          IPluginInInventoryService,
75                                                                                          OpendaylightInventoryListener,
76                                                                                          OpendaylightFlowStatisticsListener,
77                                                                                          OpendaylightFlowTableStatisticsListener,
78                                                                                          OpendaylightPortStatisticsListener {
79
80     private static val LOG = LoggerFactory.getLogger(InventoryAndReadAdapter);
81
82         private static val OPENFLOWV10_TABLE_ID = new Integer(0).shortValue;
83     @Property
84     DataBrokerService dataService;
85
86     @Property
87     DataProviderService dataProviderService;
88
89     @Property
90     OpendaylightFlowStatisticsService flowStatisticsService;
91
92     @Property
93     OpendaylightPortStatisticsService nodeConnectorStatisticsService;
94     
95     @Property
96     OpendaylightFlowTableStatisticsService flowTableStatisticsService;
97
98     @Property
99     FlowTopologyDiscoveryService topologyDiscovery;
100     
101     @Property
102     List<IPluginOutReadService> statisticsPublisher = new CopyOnWriteArrayList<IPluginOutReadService>();
103
104     @Property
105     List<IPluginOutInventoryService> inventoryPublisher = new CopyOnWriteArrayList<IPluginOutInventoryService>();
106
107         def setInventoryPublisher(IPluginOutInventoryService listener){
108         inventoryPublisher.add(listener);
109         }
110
111         def unsetInventoryPublisher(IPluginOutInventoryService listener){
112         inventoryPublisher.remove(listener);
113         }
114
115     def setReadPublisher(IPluginOutReadService listener) {
116         statisticsPublisher.add(listener);
117     }
118     
119     def unsetReadPublisher (IPluginOutReadService listener) {
120         if( listener != null)
121                 statisticsPublisher.remove(listener);
122     }
123
124     protected def startChange() {
125         return dataProviderService.beginTransaction;
126     }
127
128     override getTransmitRate(org.opendaylight.controller.sal.core.NodeConnector connector) {
129         val nodeConnector = readFlowCapableNodeConnector(connector.toNodeConnectorRef);
130         return nodeConnector.currentSpeed
131     }
132
133     override readAllFlow(Node node, boolean cached) {
134
135         val output = new ArrayList<FlowOnNode>();
136                 val tableRef = InstanceIdentifier.builder(Nodes)
137                                                                                 .child(org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node, InventoryMapping.toNodeKey(node))
138                                                         .augmentation(FlowCapableNode).child(Table, new TableKey(OPENFLOWV10_TABLE_ID)).toInstance();
139                 
140                 val it = this.startChange();
141                 
142                 val table= it.readConfigurationData(tableRef) as Table;
143                 
144                 if(table != null){
145                         LOG.info("Number of flows installed in table 0 of node {} : {}",node,table.flow.size);
146                         
147                         for(flow : table.flow){
148                                 
149                                 val adsalFlow = ToSalConversionsUtils.toFlow(flow);
150                                 val statsFromDataStore = flow.getAugmentation(FlowStatisticsData);
151                                 
152                                 if(statsFromDataStore != null){
153                                         val it = new FlowOnNode(adsalFlow);
154                                         byteCount =  statsFromDataStore.flowStatistics.byteCount.value.longValue;
155                                         packetCount = statsFromDataStore.flowStatistics.packetCount.value.longValue;
156                                         durationSeconds = statsFromDataStore.flowStatistics.duration.second.value.intValue;
157                                         durationNanoseconds = statsFromDataStore.flowStatistics.duration.nanosecond.value.intValue;
158                                         
159                                         output.add(it);
160                                 }
161                         }
162                 }
163         
164         //TODO (main): Shell we send request to the switch? It will make async request to the switch.
165         // Once plugin receive response, it will let adaptor know through onFlowStatisticsUpdate()
166         // If we assume that md-sal statistics manager will always be running, then its not required
167         // But if not, then sending request will collect the latest data for adaptor atleast.
168         val input = new GetAllFlowsStatisticsFromAllFlowTablesInputBuilder;
169         input.setNode(node.toNodeRef);
170         flowStatisticsService.getAllFlowsStatisticsFromAllFlowTables(input.build)
171         
172         return output;
173     }
174
175     override readAllNodeConnector(Node node, boolean cached) {
176         
177         val ret = new ArrayList<NodeConnectorStatistics>();
178                 val nodeRef = InstanceIdentifier.builder(Nodes)
179                                                                         .child(org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node, InventoryMapping.toNodeKey(node))
180                                                                         .toInstance();
181                 
182                 val provider = this.startChange();
183                 
184                 val dsNode= provider.readConfigurationData(nodeRef) as org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node;
185                 
186                 if(dsNode != null){
187                         
188                         for (dsNodeConnector : dsNode.nodeConnector){
189                                 val nodeConnectorRef = InstanceIdentifier.builder(Nodes)
190                                                                         .child(org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node, InventoryMapping.toNodeKey(node))
191                                                                         .child(NodeConnector, dsNodeConnector.key)
192                                                                         .toInstance();
193                                 
194                                 val nodeConnectorFromDS = provider.readConfigurationData(nodeConnectorRef) as NodeConnector;
195                                 
196                                 if(nodeConnectorFromDS != null){
197                                         val nodeConnectorStatsFromDs = nodeConnectorFromDS.getAugmentation(FlowCapableNodeConnectorStatisticsData) as FlowCapableNodeConnectorStatistics;
198                                         
199                                         ret.add(toNodeConnectorStatistics(nodeConnectorStatsFromDs.flowCapableNodeConnectorStatistics,dsNode.id,dsNodeConnector.id));
200                                 }
201                         }
202                 }
203
204                 //TODO: Refer TODO (main)
205         val input = new GetAllNodeConnectorsStatisticsInputBuilder();
206         input.setNode(node.toNodeRef);
207         nodeConnectorStatisticsService.getAllNodeConnectorsStatistics(input.build());
208         return ret;
209     }
210
211     override readAllNodeTable(Node node, boolean cached) {
212         val ret = new ArrayList<NodeTableStatistics>();
213         
214                 val dsFlowCapableNode= readFlowCapableNode(node.toNodeRef)
215                 
216                 if(dsFlowCapableNode != null){
217                         
218                         for (table : dsFlowCapableNode.table){
219                                 
220                                 val tableStats = table.getAugmentation(FlowTableStatisticsData);
221                                 
222                                 if(tableStats != null){
223                                         ret.add(toNodeTableStatistics(tableStats.flowTableStatistics,table.id,node));
224                                 }
225                         }
226                 }
227
228                 //TODO: Refer TODO (main)
229         val input = new GetFlowTablesStatisticsInputBuilder();
230         input.setNode(node.toNodeRef);
231         flowTableStatisticsService.getFlowTablesStatistics(input.build);
232         return ret;
233     }
234
235     override readDescription(Node node, boolean cached) {
236         return toNodeDescription(node.toNodeRef);
237         }
238
239     override readFlow(Node node, Flow targetFlow, boolean cached) {
240                 var FlowOnNode ret= null;
241                 
242                 val tableRef = InstanceIdentifier.builder(Nodes)
243                                                                                 .child(org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node, InventoryMapping.toNodeKey(node))
244                                                         .augmentation(FlowCapableNode).child(Table, new TableKey(OPENFLOWV10_TABLE_ID)).toInstance();
245                 
246                 val it = this.startChange();
247                 
248                 val table= it.readConfigurationData(tableRef) as Table;
249                 
250                 if(table != null){
251                         LOG.info("Number of flows installed in table 0 of node {} : {}",node,table.flow.size);
252                         
253                         for(mdsalFlow : table.flow){
254                                 if(FromSalConversionsUtils.flowEquals(mdsalFlow, MDFlowMapping.toMDSalflow(targetFlow))){
255                                         val statsFromDataStore = mdsalFlow.getAugmentation(FlowStatisticsData);
256                                         
257                                         if(statsFromDataStore != null){
258                                                 LOG.debug("Found matching flow in the data store flow table ");
259                                                 val it = new FlowOnNode(targetFlow);
260                                                 byteCount =  statsFromDataStore.flowStatistics.byteCount.value.longValue;
261                                                 packetCount = statsFromDataStore.flowStatistics.packetCount.value.longValue;
262                                                 durationSeconds = statsFromDataStore.flowStatistics.duration.second.value.intValue;
263                                                 durationNanoseconds = statsFromDataStore.flowStatistics.duration.nanosecond.value.intValue;
264                                                 
265                                                 ret = it;
266                                         }
267                                 }                       
268                         }
269                 }
270         
271         //TODO: Refer TODO (main)
272         val input = new GetFlowStatisticsFromFlowTableInputBuilder;
273         input.setNode(node.toNodeRef);
274         input.fieldsFrom(MDFlowMapping.toMDSalflow(targetFlow));
275         flowStatisticsService.getFlowStatisticsFromFlowTable(input.build)
276         
277         return ret;
278         
279     }
280
281     override readNodeConnector(org.opendaylight.controller.sal.core.NodeConnector connector, boolean cached) {
282         var NodeConnectorStatistics  nodeConnectorStatistics = null;
283         
284                 val nodeConnectorRef = InstanceIdentifier.builder(Nodes)
285                                                                         .child(org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node, InventoryMapping.toNodeKey(connector.node))
286                                                                         .child(NodeConnector, InventoryMapping.toNodeConnectorKey(connector))
287                                                                         .toInstance();
288                 val provider = this.startChange();
289                                 
290                 val nodeConnectorFromDS = provider.readConfigurationData(nodeConnectorRef) as NodeConnector;
291                                 
292                 if(nodeConnectorFromDS != null){
293                         val nodeConnectorStatsFromDs = nodeConnectorFromDS.getAugmentation(FlowCapableNodeConnectorStatisticsData) as FlowCapableNodeConnectorStatistics;
294                         if(nodeConnectorStatsFromDs != null) {
295                                 nodeConnectorStatistics = toNodeConnectorStatistics(nodeConnectorStatsFromDs.flowCapableNodeConnectorStatistics,
296                                                                                                                                                 InventoryMapping.toNodeKey(connector.node).id,
297                                                                                                                                                 InventoryMapping.toNodeConnectorKey(connector).id);
298                         }
299                 }
300
301                 //TODO: Refer TODO (main)
302         val input = new GetNodeConnectorStatisticsInputBuilder();
303         input.setNode(connector.node.toNodeRef);
304         input.setNodeConnectorId(InventoryMapping.toNodeConnectorKey(connector).id);
305         nodeConnectorStatisticsService.getNodeConnectorStatistics(input.build());
306         return nodeConnectorStatistics;
307     }
308
309     override readNodeTable(NodeTable nodeTable, boolean cached) {
310         var NodeTableStatistics nodeStats = null
311         
312         val tableRef = InstanceIdentifier.builder(Nodes)
313                                                                                 .child(org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node, InventoryMapping.toNodeKey(nodeTable.node))
314                                                         .augmentation(FlowCapableNode).child(Table, new TableKey(nodeTable.ID as Short)).toInstance();
315                 
316                 val it = this.startChange();
317                 
318                 val table= it.readConfigurationData(tableRef) as Table;
319                 
320                 if(table != null){
321                         val tableStats = table.getAugmentation(FlowTableStatisticsData);
322                                 
323                         if(tableStats != null){
324                                 nodeStats =  toNodeTableStatistics(tableStats.flowTableStatistics,table.id,nodeTable.node);
325                         }
326                 }
327
328                 //TODO: Refer TODO (main)
329         val input = new GetFlowTablesStatisticsInputBuilder();
330         input.setNode(nodeTable.node.toNodeRef);
331         flowTableStatisticsService.getFlowTablesStatistics(input.build);
332         
333         return nodeStats;
334     }
335
336     override onNodeConnectorRemoved(NodeConnectorRemoved update) {
337         // NOOP
338     }
339
340     override onNodeRemoved(NodeRemoved notification) {
341         val properties = Collections.<org.opendaylight.controller.sal.core.Property>emptySet();
342
343         publishNodeUpdate(notification.nodeRef.toADNode, UpdateType.REMOVED, properties);
344     }
345
346     override onNodeConnectorUpdated(NodeConnectorUpdated update) {
347         var updateType = UpdateType.CHANGED;
348         if ( this._dataService.readOperationalData(update.nodeConnectorRef.value as InstanceIdentifier<? extends DataObject>) == null ){
349             updateType = UpdateType.ADDED;
350         }
351
352         var nodeConnector = update.nodeConnectorRef.toADNodeConnector
353
354         publishNodeConnectorUpdate(nodeConnector , updateType , update.toADNodeConnectorProperties);
355     }
356
357     override onNodeUpdated(NodeUpdated notification) {
358         val InstanceIdentifier<? extends DataObject> identifier = notification.nodeRef.value  as InstanceIdentifier<? extends DataObject>;
359
360         var updateType = UpdateType.CHANGED;
361         if ( this._dataService.readOperationalData(identifier) == null ){
362             updateType = UpdateType.ADDED;
363         }
364         publishNodeUpdate(notification.nodeRef.toADNode, updateType, notification.toADNodeProperties);
365         
366                 //Notify the listeners of IPluginOutReadService
367         
368         for (statsPublisher : statisticsPublisher){
369                         val nodeRef = InstanceIdentifier.builder(Nodes).child(org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node,new NodeKey(notification.id)).toInstance;
370                         statsPublisher.descriptionStatisticsUpdated(nodeRef.toADNode,toNodeDescription(notification.nodeRef));
371                 }
372     }
373
374     override getNodeProps() {
375         val props = new ConcurrentHashMap<Node, Map<String, org.opendaylight.controller.sal.core.Property>>()
376         
377         val nodes = readAllMDNodes()
378         for (node : nodes.node ) {
379             val fcn = node.getAugmentation(FlowCapableNode)
380             if(fcn != null) {
381                 val perNodeProps = fcn.toADNodeProperties(node.id)
382                 val perNodePropMap = new ConcurrentHashMap<String, org.opendaylight.controller.sal.core.Property>
383                 if(perNodeProps != null ) {
384                     for(perNodeProp : perNodeProps) {
385                         perNodePropMap.put(perNodeProp.name,perNodeProp)
386                     }
387                 }
388                 props.put(new Node(MD_SAL_TYPE, node.id.toADNodeId),perNodePropMap)
389             }
390         }
391         return props;
392     }
393     
394     private def readAllMDNodes() {
395         val nodesRef = InstanceIdentifier.builder(Nodes)
396             .toInstance
397         val reader = TypeSafeDataReader.forReader(dataService)
398         return reader.readOperationalData(nodesRef)
399     }
400     
401     private def readAllMDNodeConnectors(org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node node) {
402         val nodeRef = InstanceIdentifier.builder(Nodes)
403             .child(org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node,new NodeKey(node.id))
404             .toInstance
405         val reader = TypeSafeDataReader.forReader(dataService)
406         return reader.readOperationalData(nodeRef).nodeConnector
407     }
408
409     override getNodeConnectorProps(Boolean refresh) {
410         // Note, because the MD-SAL has a unified data store, we can ignore the Boolean refresh, as we have no secondary 
411         // data store to refresh from
412         val props = new ConcurrentHashMap<org.opendaylight.controller.sal.core.NodeConnector, Map<String, org.opendaylight.controller.sal.core.Property>>()
413         val nodes = readAllMDNodes()
414         for (node : nodes.node) {
415             val ncs = node.readAllMDNodeConnectors
416             if(ncs != null) {
417                 for( nc : ncs ) {
418                     val fcnc = nc.getAugmentation(FlowCapableNodeConnector)
419                     if(fcnc != null) {
420                         val ncps = fcnc.toADNodeConnectorProperties
421                         val ncpsm = new ConcurrentHashMap<String, org.opendaylight.controller.sal.core.Property>
422                         if(ncps != null) {
423                             for(p : ncps) {
424                                 ncpsm.put(p.name,p)
425                             }
426                         }  
427                         props.put(nc.id.toADNodeConnector(node.id),ncpsm)
428                     }
429                 }
430             }
431         }
432         return props
433     }
434
435     private def FlowCapableNode readFlowCapableNode(NodeRef ref) {
436         val dataObject = dataService.readOperationalData(ref.value as InstanceIdentifier<? extends DataObject>);
437         val node = dataObject.checkInstanceOf(
438             org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node);
439         return node.getAugmentation(FlowCapableNode);
440     }
441
442     private def FlowCapableNodeConnector readFlowCapableNodeConnector(NodeConnectorRef ref) {
443         val dataObject = dataService.readOperationalData(ref.value as InstanceIdentifier<? extends DataObject>);
444         val node = dataObject.checkInstanceOf(
445             NodeConnector);
446         return node.getAugmentation(FlowCapableNodeConnector);
447     }
448
449     private def toNodeConnectorStatistics(
450         org.opendaylight.yang.gen.v1.urn.opendaylight.model.statistics.types.rev130925.NodeConnectorStatistics nodeConnectorStatistics, NodeId nodeId, NodeConnectorId nodeConnectorId) {
451                 
452                         val it = new NodeConnectorStatistics();
453                         
454                         receivePacketCount = nodeConnectorStatistics.packets.received.longValue;
455                         transmitPacketCount = nodeConnectorStatistics.packets.transmitted.longValue;
456                         
457                         receiveByteCount = nodeConnectorStatistics.bytes.received.longValue;
458                         transmitByteCount = nodeConnectorStatistics.bytes.transmitted.longValue;
459                         
460                         receiveDropCount = nodeConnectorStatistics.receiveDrops.longValue;
461                         transmitDropCount = nodeConnectorStatistics.transmitDrops.longValue;
462                         
463                         receiveErrorCount = nodeConnectorStatistics.receiveErrors.longValue;
464                         transmitErrorCount = nodeConnectorStatistics.transmitErrors.longValue;
465                         
466                         receiveFrameErrorCount = nodeConnectorStatistics.receiveFrameError.longValue;
467                         receiveOverRunErrorCount = nodeConnectorStatistics.receiveOverRunError.longValue;
468                         receiveCRCErrorCount = nodeConnectorStatistics.receiveCrcError.longValue;
469                         collisionCount = nodeConnectorStatistics.collisionCount.longValue;
470                         
471                         val nodeConnectorRef = InstanceIdentifier.builder(Nodes)
472                                                                 .child(org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node,new NodeKey(nodeId))
473                                                                 .child(NodeConnector,new NodeConnectorKey(nodeConnectorId)).toInstance;
474                         
475                         nodeConnector = NodeMapping.toADNodeConnector(new NodeConnectorRef(nodeConnectorRef));
476                         
477                         return it;
478     }
479
480         private def toNodeTableStatistics(
481                 FlowTableStatistics tableStats,
482                 Short tableId,Node node){
483                 var it = new NodeTableStatistics();
484                 
485                 activeCount = tableStats.activeFlows.value.intValue;
486                 lookupCount = tableStats.packetsLookedUp.value.intValue;
487                 matchedCount = tableStats.packetsMatched.value.intValue;
488                 name = tableId.toString;
489                 nodeTable = new NodeTable(NodeMapping.MD_SAL_TYPE,tableId,node);
490                 return it;
491         }
492         
493         private def toNodeDescription(NodeRef nodeRef){
494                 val capableNode = readFlowCapableNode(nodeRef);
495
496         val it = new NodeDescription()
497         manufacturer = capableNode.manufacturer
498         serialNumber = capableNode.serialNumber
499         software = capableNode.software
500         description = capableNode.description
501         
502         return it;
503         }
504     
505     
506     def Edge toADEdge(Link link) {
507         new Edge(link.source.toADNodeConnector,link.destination.toADNodeConnector)
508     }
509         
510         /*
511          * OpendaylightFlowStatisticsListener interface implementation
512          */
513         override onAggregateFlowStatisticsUpdate(AggregateFlowStatisticsUpdate notification) {
514         //Ignoring this notification as there does not seem to be a way to bubble this up to AD-SAL
515         }
516         
517         override onFlowsStatisticsUpdate(FlowsStatisticsUpdate notification) {
518                 
519                 val adsalFlowsStatistics = new ArrayList<FlowOnNode>();
520                 
521                 for(flowStats : notification.flowAndStatisticsMapList){
522                         if(flowStats.tableId == 0)
523                                 adsalFlowsStatistics.add(toFlowOnNode(flowStats));
524                 }
525                 
526                 for (statsPublisher : statisticsPublisher){
527                         val nodeRef = InstanceIdentifier.builder(Nodes).child(org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node,new NodeKey(notification.id)).toInstance;
528                         statsPublisher.nodeFlowStatisticsUpdated(nodeRef.toADNode,adsalFlowsStatistics);
529                 }
530                 
531         }
532         /*
533          * OpendaylightFlowTableStatisticsListener interface implementation
534          */     
535         override onFlowTableStatisticsUpdate(FlowTableStatisticsUpdate notification) {
536                 var adsalFlowTableStatistics = new ArrayList<NodeTableStatistics>();
537                 
538                 for(stats : notification.flowTableAndStatisticsMap){
539                         if (stats.tableId.value == 0){
540                                 val it = new NodeTableStatistics();
541                                 activeCount = stats.activeFlows.value.intValue;
542                                 lookupCount = stats.packetsLookedUp.value.longValue;
543                                 matchedCount = stats.packetsMatched.value.longValue;
544                                 
545                                 adsalFlowTableStatistics.add(it);
546                         }
547                 }
548                 for (statsPublisher : statisticsPublisher){
549                         val nodeRef = InstanceIdentifier.builder(Nodes).child(org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node,new NodeKey(notification.id)).toInstance;
550                         statsPublisher.nodeTableStatisticsUpdated(nodeRef.toADNode,adsalFlowTableStatistics);
551                 }
552         }
553         
554         /*
555          * OpendaylightPortStatisticsUpdate interface implementation
556          */
557         override onNodeConnectorStatisticsUpdate(NodeConnectorStatisticsUpdate notification) {
558                 
559                 val adsalPortStatistics  = new ArrayList<NodeConnectorStatistics>();
560                 
561                 for(nodeConnectorStatistics : notification.nodeConnectorStatisticsAndPortNumberMap){
562                         adsalPortStatistics.add(toNodeConnectorStatistics(nodeConnectorStatistics,notification.id,nodeConnectorStatistics.nodeConnectorId));
563                 }
564                 
565                 for (statsPublisher : statisticsPublisher){
566                         val nodeRef = InstanceIdentifier.builder(Nodes).child(org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node,new NodeKey(notification.id)).toInstance;
567                         statsPublisher.nodeConnectorStatisticsUpdated(nodeRef.toADNode,adsalPortStatistics);
568                 }
569                 
570         }
571         
572         private static def toFlowOnNode (FlowAndStatisticsMapList flowAndStatsMap){
573                 
574                 val it = new FlowOnNode(ToSalConversionsUtils.toFlow(flowAndStatsMap));
575                 
576                 byteCount = flowAndStatsMap.byteCount.value.longValue;
577                 packetCount = flowAndStatsMap.packetCount.value.longValue;
578                 durationSeconds = flowAndStatsMap.duration.second.value.intValue;
579                 durationNanoseconds = flowAndStatsMap.duration.nanosecond.value.intValue;
580                 
581                 return it;
582         }
583
584         override  getConfiguredNotConnectedNodes() {
585         return Collections.emptySet();
586         }
587
588
589         private def publishNodeUpdate(Node node, UpdateType updateType, Set<org.opendaylight.controller.sal.core.Property> properties){
590             for( publisher : inventoryPublisher){
591                 publisher.updateNode(node, updateType, properties);
592             }
593         }
594
595         private def publishNodeConnectorUpdate(org.opendaylight.controller.sal.core.NodeConnector nodeConnector, UpdateType updateType, Set<org.opendaylight.controller.sal.core.Property> properties){
596             for( publisher : inventoryPublisher){
597                 publisher.updateNodeConnector(nodeConnector, updateType, properties);
598             }
599         }
600 }