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