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