Merge "Upgrade jackson library to version 2.3.0"
[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     FlowTopologyDiscoveryService topologyDiscovery;
111     
112     @Property
113     List<IPluginOutReadService> statisticsPublisher = new ArrayList<IPluginOutReadService>();
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(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) as 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(org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.node.NodeConnector, dsNodeConnector.key)
192                                                                         .toInstance();
193                                 
194                                 val nodeConnectorFromDS = provider.readConfigurationData(nodeConnectorRef) as org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.node.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) as 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) as 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(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(org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.node.NodeConnector, InventoryMapping.toNodeConnectorKey(connector))
287                                                                         .toInstance();
288                 val provider = this.startChange();
289                                 
290                 val nodeConnectorFromDS = provider.readConfigurationData(nodeConnectorRef) as org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.node.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) as 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         inventoryPublisher.updateNode(notification.nodeRef.toADNode, UpdateType.REMOVED, properties);
344     }
345
346     override onNodeConnectorUpdated(NodeConnectorUpdated update) {
347         val properties = new java.util.HashSet<org.opendaylight.controller.sal.core.Property>();
348
349
350         val org.opendaylight.yangtools.yang.binding.InstanceIdentifier<? extends DataObject> identifier = update.nodeConnectorRef.value as org.opendaylight.yangtools.yang.binding.InstanceIdentifier<? extends DataObject>;
351         var updateType = UpdateType.CHANGED;
352         if ( this._dataService.readOperationalData(identifier) == null ){
353             updateType = UpdateType.ADDED;
354         }
355
356         var nodeConnector = update.nodeConnectorRef.toADNodeConnector
357
358
359         properties.add(new org.opendaylight.controller.sal.core.Name(nodeConnector.ID.toString()));
360
361         inventoryPublisher.updateNodeConnector(nodeConnector , updateType , properties);
362     }
363
364     override onNodeUpdated(NodeUpdated notification) {
365         val properties = Collections.<org.opendaylight.controller.sal.core.Property>emptySet();
366         val org.opendaylight.yangtools.yang.binding.InstanceIdentifier<? extends DataObject> identifier = notification.nodeRef.value  as org.opendaylight.yangtools.yang.binding.InstanceIdentifier<? extends DataObject>;
367
368         var updateType = UpdateType.CHANGED;
369         if ( this._dataService.readOperationalData(identifier) == null ){
370             updateType = UpdateType.ADDED;
371         }
372         inventoryPublisher.updateNode(notification.nodeRef.toADNode, updateType, properties);
373         
374                 //Notify the listeners of IPluginOutReadService
375         
376         for (statsPublisher : statisticsPublisher){
377                         val nodeRef = InstanceIdentifier.builder(Nodes).child(org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node,new NodeKey(notification.id)).toInstance;
378                         statsPublisher.descriptionStatisticsUpdated(nodeRef.toADNode,toNodeDescription(notification.nodeRef));
379                 }
380     }
381
382     override getNodeProps() {
383
384         // FIXME: Read from MD-SAL inventory service
385         return null;
386     }
387
388     override getNodeConnectorProps(Boolean refresh) {
389
390         // FIXME: Read from MD-SAL Invcentory Service
391         return null;
392     }
393
394     private def FlowCapableNode readFlowCapableNode(NodeRef ref) {
395         val dataObject = dataService.readOperationalData(ref.value as InstanceIdentifier<? extends DataObject>);
396         val node = dataObject.checkInstanceOf(
397             org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node);
398         return node.getAugmentation(FlowCapableNode);
399     }
400
401     private def FlowCapableNodeConnector readFlowCapableNodeConnector(NodeConnectorRef ref) {
402         val dataObject = dataService.readOperationalData(ref.value as InstanceIdentifier<? extends DataObject>);
403         val node = dataObject.checkInstanceOf(
404             org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.node.NodeConnector);
405         return node.getAugmentation(FlowCapableNodeConnector);
406     }
407
408     private def toNodeConnectorStatistics(
409         org.opendaylight.yang.gen.v1.urn.opendaylight.model.statistics.types.rev130925.NodeConnectorStatistics nodeConnectorStatistics, NodeId nodeId, NodeConnectorId nodeConnectorId) {
410                 
411                         val it = new NodeConnectorStatistics();
412                         
413                         receivePacketCount = nodeConnectorStatistics.packets.received.longValue;
414                         transmitPacketCount = nodeConnectorStatistics.packets.transmitted.longValue;
415                         
416                         receiveByteCount = nodeConnectorStatistics.bytes.received.longValue;
417                         transmitByteCount = nodeConnectorStatistics.bytes.transmitted.longValue;
418                         
419                         receiveDropCount = nodeConnectorStatistics.receiveDrops.longValue;
420                         transmitDropCount = nodeConnectorStatistics.transmitDrops.longValue;
421                         
422                         receiveErrorCount = nodeConnectorStatistics.receiveErrors.longValue;
423                         transmitErrorCount = nodeConnectorStatistics.transmitErrors.longValue;
424                         
425                         receiveFrameErrorCount = nodeConnectorStatistics.receiveFrameError.longValue;
426                         receiveOverRunErrorCount = nodeConnectorStatistics.receiveOverRunError.longValue;
427                         receiveCRCErrorCount = nodeConnectorStatistics.receiveCrcError.longValue;
428                         collisionCount = nodeConnectorStatistics.collisionCount.longValue;
429                         
430                         val nodeConnectorRef = InstanceIdentifier.builder(Nodes)
431                                                                 .child(org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node,new NodeKey(nodeId))
432                                                                 .child(org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.node.NodeConnector,new NodeConnectorKey(nodeConnectorId)).toInstance;
433                         
434                         nodeConnector = NodeMapping.toADNodeConnector(new NodeConnectorRef(nodeConnectorRef));
435                         
436                         return it;
437     }
438
439         private def toNodeTableStatistics(
440                 org.opendaylight.yang.gen.v1.urn.opendaylight.flow.table.statistics.rev131215.flow.table.statistics.FlowTableStatistics tableStats,
441                 Short tableId,Node node){
442                 var it = new NodeTableStatistics();
443                 
444                 activeCount = tableStats.activeFlows.value.intValue;
445                 lookupCount = tableStats.packetsLookedUp.value.intValue;
446                 matchedCount = tableStats.packetsMatched.value.intValue;
447                 name = tableId.toString;
448                 nodeTable = new NodeTable(NodeMapping.MD_SAL_TYPE,tableId,node);
449                 return it;
450         }
451         
452         private def toNodeDescription(NodeRef nodeRef){
453                 val capableNode = readFlowCapableNode(nodeRef);
454
455         val it = new NodeDescription()
456         manufacturer = capableNode.manufacturer
457         serialNumber = capableNode.serialNumber
458         software = capableNode.software
459         description = capableNode.description
460         
461         return it;
462         }
463
464     override sollicitRefresh() {
465         topologyDiscovery.solicitRefresh
466     }
467     
468     override onLinkDiscovered(LinkDiscovered notification) {
469         val update = new TopoEdgeUpdate(notification.toADEdge,Collections.emptySet(),UpdateType.ADDED);
470         topologyPublisher.edgeUpdate(Collections.singletonList(update))
471     }
472     
473     override onLinkOverutilized(LinkOverutilized notification) {
474         topologyPublisher.edgeOverUtilized(notification.toADEdge)
475     }
476     
477     override onLinkRemoved(LinkRemoved notification) {
478         val update = new TopoEdgeUpdate(notification.toADEdge,Collections.emptySet(),UpdateType.REMOVED);
479         topologyPublisher.edgeUpdate(Collections.singletonList(update))
480     }
481     
482     override onLinkUtilizationNormal(LinkUtilizationNormal notification) {
483         topologyPublisher.edgeUtilBackToNormal(notification.toADEdge)
484     }
485     
486     
487     def Edge toADEdge(Link link) {
488         new Edge(link.source.toADNodeConnector,link.destination.toADNodeConnector)
489     }
490         
491         /*
492          * OpendaylightFlowStatisticsListener interface implementation
493          */
494         override onAggregateFlowStatisticsUpdate(AggregateFlowStatisticsUpdate notification) {
495                 throw new UnsupportedOperationException("TODO: auto-generated method stub")
496         }
497         
498         override onFlowsStatisticsUpdate(FlowsStatisticsUpdate notification) {
499                 
500                 val adsalFlowsStatistics = new ArrayList<FlowOnNode>();
501                 
502                 for(flowStats : notification.flowAndStatisticsMapList){
503                         if(flowStats.tableId == 0)
504                                 adsalFlowsStatistics.add(toFlowOnNode(flowStats));
505                 }
506                 
507                 for (statsPublisher : statisticsPublisher){
508                         val nodeRef = InstanceIdentifier.builder(Nodes).child(org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node,new NodeKey(notification.id)).toInstance;
509                         statsPublisher.nodeFlowStatisticsUpdated(nodeRef.toADNode,adsalFlowsStatistics);
510                 }
511                 
512         }
513         /*
514          * OpendaylightFlowTableStatisticsListener interface implementation
515          */     
516         override onFlowTableStatisticsUpdate(FlowTableStatisticsUpdate notification) {
517                 var adsalFlowTableStatistics = new ArrayList<NodeTableStatistics>();
518                 
519                 for(stats : notification.flowTableAndStatisticsMap){
520                         if (stats.tableId.value == 0){
521                                 val it = new NodeTableStatistics();
522                                 activeCount = stats.activeFlows.value.intValue;
523                                 lookupCount = stats.packetsLookedUp.value.longValue;
524                                 matchedCount = stats.packetsMatched.value.longValue;
525                                 
526                                 adsalFlowTableStatistics.add(it);
527                         }
528                 }
529                 for (statsPublisher : statisticsPublisher){
530                         val nodeRef = InstanceIdentifier.builder(Nodes).child(org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node,new NodeKey(notification.id)).toInstance;
531                         statsPublisher.nodeTableStatisticsUpdated(nodeRef.toADNode,adsalFlowTableStatistics);
532                 }
533         }
534         
535         /*
536          * OpendaylightPortStatisticsUpdate interface implementation
537          */
538         override onNodeConnectorStatisticsUpdate(NodeConnectorStatisticsUpdate notification) {
539                 
540                 val adsalPortStatistics  = new ArrayList<NodeConnectorStatistics>();
541                 
542                 for(nodeConnectorStatistics : notification.nodeConnectorStatisticsAndPortNumberMap){
543                         adsalPortStatistics.add(toNodeConnectorStatistics(nodeConnectorStatistics,notification.id,nodeConnectorStatistics.nodeConnectorId));
544                 }
545                 
546                 for (statsPublisher : statisticsPublisher){
547                         val nodeRef = InstanceIdentifier.builder(Nodes).child(org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node,new NodeKey(notification.id)).toInstance;
548                         statsPublisher.nodeConnectorStatisticsUpdated(nodeRef.toADNode,adsalPortStatistics);
549                 }
550                 
551         }
552         
553         private static def toFlowOnNode (FlowAndStatisticsMapList flowAndStatsMap){
554                 
555                 val it = new FlowOnNode(ToSalConversionsUtils.toFlow(flowAndStatsMap));
556                 
557                 byteCount = flowAndStatsMap.byteCount.value.longValue;
558                 packetCount = flowAndStatsMap.packetCount.value.longValue;
559                 durationSeconds = flowAndStatsMap.duration.second.value.intValue;
560                 durationNanoseconds = flowAndStatsMap.duration.nanosecond.value.intValue;
561                 
562                 return it;
563         }
564 }