2 * Copyright (c) 2014 Cisco Systems, Inc. and others. All rights reserved.
4 * This program and the accompanying materials are made available under the
5 * terms of the Eclipse Public License v1.0 which accompanies this distribution,
6 * and is available at http://www.eclipse.org/legal/epl-v10.html
8 package org.opendaylight.controller.sal.compatibility
10 import java.util.ArrayList
11 import java.util.Collections
14 import java.util.concurrent.CopyOnWriteArrayList;
15 import org.opendaylight.controller.sal.binding.api.data.DataBrokerService
16 import org.opendaylight.controller.sal.binding.api.data.DataProviderService
17 import org.opendaylight.controller.sal.core.Edge
18 import org.opendaylight.controller.sal.core.Node
19 import org.opendaylight.controller.sal.core.NodeTable
20 import org.opendaylight.controller.sal.core.UpdateType
21 import org.opendaylight.controller.sal.flowprogrammer.Flow
22 import org.opendaylight.controller.sal.inventory.IPluginInInventoryService
23 import org.opendaylight.controller.sal.inventory.IPluginOutInventoryService
24 import org.opendaylight.controller.sal.reader.FlowOnNode
25 import org.opendaylight.controller.sal.reader.IPluginInReadService
26 import org.opendaylight.controller.sal.reader.IPluginOutReadService
27 import org.opendaylight.controller.sal.reader.NodeConnectorStatistics
28 import org.opendaylight.controller.sal.reader.NodeDescription
29 import org.opendaylight.controller.sal.reader.NodeTableStatistics
30 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNode
31 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNodeConnector
32 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.Table
33 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.TableKey
34 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.AggregateFlowStatisticsUpdate
35 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.FlowStatisticsData
36 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.FlowsStatisticsUpdate
37 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.GetAllFlowsStatisticsFromAllFlowTablesInputBuilder
38 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.GetFlowStatisticsFromFlowTableInputBuilder
39 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.OpendaylightFlowStatisticsListener
40 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.OpendaylightFlowStatisticsService
41 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.flow.and.statistics.map.list.FlowAndStatisticsMapList
42 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.table.statistics.rev131215.FlowTableStatisticsData
43 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.table.statistics.rev131215.FlowTableStatisticsUpdate
44 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.table.statistics.rev131215.GetFlowTablesStatisticsInputBuilder
45 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.table.statistics.rev131215.OpendaylightFlowTableStatisticsListener
46 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.table.statistics.rev131215.OpendaylightFlowTableStatisticsService
47 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.table.statistics.rev131215.flow.table.statistics.FlowTableStatistics
48 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.topology.discovery.rev130819.FlowTopologyDiscoveryService
49 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.topology.discovery.rev130819.Link
50 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeConnectorId
51 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeConnectorRef
52 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeConnectorRemoved
53 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeConnectorUpdated
54 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeId
55 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeRef
56 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeRemoved
57 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeUpdated
58 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.Nodes
59 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.OpendaylightInventoryListener
60 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.node.NodeConnector
61 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.node.NodeConnectorKey
62 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.NodeKey
63 import org.opendaylight.yang.gen.v1.urn.opendaylight.port.statistics.rev131214.FlowCapableNodeConnectorStatistics
64 import org.opendaylight.yang.gen.v1.urn.opendaylight.port.statistics.rev131214.FlowCapableNodeConnectorStatisticsData
65 import org.opendaylight.yang.gen.v1.urn.opendaylight.port.statistics.rev131214.GetAllNodeConnectorsStatisticsInputBuilder
66 import org.opendaylight.yang.gen.v1.urn.opendaylight.port.statistics.rev131214.GetNodeConnectorStatisticsInputBuilder
67 import org.opendaylight.yang.gen.v1.urn.opendaylight.port.statistics.rev131214.NodeConnectorStatisticsUpdate
68 import org.opendaylight.yang.gen.v1.urn.opendaylight.port.statistics.rev131214.OpendaylightPortStatisticsListener
69 import org.opendaylight.yang.gen.v1.urn.opendaylight.port.statistics.rev131214.OpendaylightPortStatisticsService
70 import org.opendaylight.yangtools.yang.binding.DataObject
71 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier
72 import org.slf4j.LoggerFactory
74 import static extension org.opendaylight.controller.sal.common.util.Arguments.*
75 import static extension org.opendaylight.controller.sal.compatibility.NodeMapping.*
76 import org.opendaylight.controller.md.sal.binding.util.TypeSafeDataReader
77 import java.util.concurrent.ConcurrentHashMap
80 class InventoryAndReadAdapter implements IPluginInReadService,
81 IPluginInInventoryService,
82 OpendaylightInventoryListener,
83 OpendaylightFlowStatisticsListener,
84 OpendaylightFlowTableStatisticsListener,
85 OpendaylightPortStatisticsListener {
87 private static val LOG = LoggerFactory.getLogger(InventoryAndReadAdapter);
89 private static val OPENFLOWV10_TABLE_ID = new Integer(0).shortValue;
91 DataBrokerService dataService;
94 DataProviderService dataProviderService;
97 OpendaylightFlowStatisticsService flowStatisticsService;
100 OpendaylightPortStatisticsService nodeConnectorStatisticsService;
103 OpendaylightFlowTableStatisticsService flowTableStatisticsService;
106 FlowTopologyDiscoveryService topologyDiscovery;
109 List<IPluginOutReadService> statisticsPublisher = new CopyOnWriteArrayList<IPluginOutReadService>();
112 List<IPluginOutInventoryService> inventoryPublisher = new CopyOnWriteArrayList<IPluginOutInventoryService>();
114 def setInventoryPublisher(IPluginOutInventoryService listener){
115 inventoryPublisher.add(listener);
118 def unsetInventoryPublisher(IPluginOutInventoryService listener){
119 inventoryPublisher.remove(listener);
122 def setReadPublisher(IPluginOutReadService listener) {
123 statisticsPublisher.add(listener);
126 def unsetReadPublisher (IPluginOutReadService listener) {
127 if( listener != null)
128 statisticsPublisher.remove(listener);
131 protected def startChange() {
132 return dataProviderService.beginTransaction;
135 override getTransmitRate(org.opendaylight.controller.sal.core.NodeConnector connector) {
136 val nodeConnector = readFlowCapableNodeConnector(connector.toNodeConnectorRef);
137 return nodeConnector.currentSpeed
140 override readAllFlow(Node node, boolean cached) {
142 val output = new ArrayList<FlowOnNode>();
143 val tableRef = InstanceIdentifier.builder(Nodes)
144 .child(org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node, InventoryMapping.toNodeKey(node))
145 .augmentation(FlowCapableNode).child(Table, new TableKey(OPENFLOWV10_TABLE_ID)).toInstance();
147 val it = this.startChange();
149 val table= it.readConfigurationData(tableRef) as Table;
152 LOG.trace("Number of flows installed in table 0 of node {} : {}",node,table.flow.size);
154 for(flow : table.flow){
156 val adsalFlow = ToSalConversionsUtils.toFlow(flow,node);
157 val statsFromDataStore = flow.getAugmentation(FlowStatisticsData);
159 if(statsFromDataStore != null){
160 val it = new FlowOnNode(adsalFlow);
161 byteCount = statsFromDataStore.flowStatistics.byteCount.value.longValue;
162 packetCount = statsFromDataStore.flowStatistics.packetCount.value.longValue;
163 durationSeconds = statsFromDataStore.flowStatistics.duration.second.value.intValue;
164 durationNanoseconds = statsFromDataStore.flowStatistics.duration.nanosecond.value.intValue;
171 //TODO (main): Shell we send request to the switch? It will make async request to the switch.
172 // Once plugin receive response, it will let adaptor know through onFlowStatisticsUpdate()
173 // If we assume that md-sal statistics manager will always be running, then its not required
174 // But if not, then sending request will collect the latest data for adaptor atleast.
175 val input = new GetAllFlowsStatisticsFromAllFlowTablesInputBuilder;
176 input.setNode(node.toNodeRef);
177 flowStatisticsService.getAllFlowsStatisticsFromAllFlowTables(input.build)
182 override readAllNodeConnector(Node node, boolean cached) {
184 val ret = new ArrayList<NodeConnectorStatistics>();
185 val nodeRef = InstanceIdentifier.builder(Nodes)
186 .child(org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node, InventoryMapping.toNodeKey(node))
189 val provider = this.startChange();
191 val dsNode= provider.readConfigurationData(nodeRef) as org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node;
195 for (dsNodeConnector : dsNode.nodeConnector){
196 val nodeConnectorRef = InstanceIdentifier.builder(Nodes)
197 .child(org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node, InventoryMapping.toNodeKey(node))
198 .child(NodeConnector, dsNodeConnector.key)
201 val nodeConnectorFromDS = provider.readConfigurationData(nodeConnectorRef) as NodeConnector;
203 if(nodeConnectorFromDS != null){
204 val nodeConnectorStatsFromDs = nodeConnectorFromDS.getAugmentation(FlowCapableNodeConnectorStatisticsData) as FlowCapableNodeConnectorStatistics;
206 ret.add(toNodeConnectorStatistics(nodeConnectorStatsFromDs.flowCapableNodeConnectorStatistics,dsNode.id,dsNodeConnector.id));
211 //TODO: Refer TODO (main)
212 val input = new GetAllNodeConnectorsStatisticsInputBuilder();
213 input.setNode(node.toNodeRef);
214 nodeConnectorStatisticsService.getAllNodeConnectorsStatistics(input.build());
218 override readAllNodeTable(Node node, boolean cached) {
219 val ret = new ArrayList<NodeTableStatistics>();
221 val dsFlowCapableNode= readFlowCapableNode(node.toNodeRef)
223 if(dsFlowCapableNode != null){
225 for (table : dsFlowCapableNode.table){
227 val tableStats = table.getAugmentation(FlowTableStatisticsData);
229 if(tableStats != null){
230 ret.add(toNodeTableStatistics(tableStats.flowTableStatistics,table.id,node));
235 //TODO: Refer TODO (main)
236 val input = new GetFlowTablesStatisticsInputBuilder();
237 input.setNode(node.toNodeRef);
238 flowTableStatisticsService.getFlowTablesStatistics(input.build);
242 override readDescription(Node node, boolean cached) {
243 return toNodeDescription(node.toNodeRef);
246 override readFlow(Node node, Flow targetFlow, boolean cached) {
247 var FlowOnNode ret= null;
249 val tableRef = InstanceIdentifier.builder(Nodes)
250 .child(org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node, InventoryMapping.toNodeKey(node))
251 .augmentation(FlowCapableNode).child(Table, new TableKey(OPENFLOWV10_TABLE_ID)).toInstance();
253 val it = this.startChange();
255 val table= it.readConfigurationData(tableRef) as Table;
258 LOG.trace("Number of flows installed in table 0 of node {} : {}",node,table.flow.size);
260 for(mdsalFlow : table.flow){
261 if(FromSalConversionsUtils.flowEquals(mdsalFlow, MDFlowMapping.toMDSalflow(targetFlow))){
262 val statsFromDataStore = mdsalFlow.getAugmentation(FlowStatisticsData);
264 if(statsFromDataStore != null){
265 LOG.debug("Found matching flow in the data store flow table ");
266 val it = new FlowOnNode(targetFlow);
267 byteCount = statsFromDataStore.flowStatistics.byteCount.value.longValue;
268 packetCount = statsFromDataStore.flowStatistics.packetCount.value.longValue;
269 durationSeconds = statsFromDataStore.flowStatistics.duration.second.value.intValue;
270 durationNanoseconds = statsFromDataStore.flowStatistics.duration.nanosecond.value.intValue;
278 //TODO: Refer TODO (main)
279 val input = new GetFlowStatisticsFromFlowTableInputBuilder;
280 input.setNode(node.toNodeRef);
281 input.fieldsFrom(MDFlowMapping.toMDSalflow(targetFlow));
282 flowStatisticsService.getFlowStatisticsFromFlowTable(input.build)
288 override readNodeConnector(org.opendaylight.controller.sal.core.NodeConnector connector, boolean cached) {
289 var NodeConnectorStatistics nodeConnectorStatistics = null;
291 val nodeConnectorRef = InstanceIdentifier.builder(Nodes)
292 .child(org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node, InventoryMapping.toNodeKey(connector.node))
293 .child(NodeConnector, InventoryMapping.toNodeConnectorKey(connector))
295 val provider = this.startChange();
297 val nodeConnectorFromDS = provider.readConfigurationData(nodeConnectorRef) as NodeConnector;
299 if(nodeConnectorFromDS != null){
300 val nodeConnectorStatsFromDs = nodeConnectorFromDS.getAugmentation(FlowCapableNodeConnectorStatisticsData) as FlowCapableNodeConnectorStatistics;
301 if(nodeConnectorStatsFromDs != null) {
302 nodeConnectorStatistics = toNodeConnectorStatistics(nodeConnectorStatsFromDs.flowCapableNodeConnectorStatistics,
303 InventoryMapping.toNodeKey(connector.node).id,
304 InventoryMapping.toNodeConnectorKey(connector).id);
308 //TODO: Refer TODO (main)
309 val input = new GetNodeConnectorStatisticsInputBuilder();
310 input.setNode(connector.node.toNodeRef);
311 input.setNodeConnectorId(InventoryMapping.toNodeConnectorKey(connector).id);
312 nodeConnectorStatisticsService.getNodeConnectorStatistics(input.build());
313 return nodeConnectorStatistics;
316 override readNodeTable(NodeTable nodeTable, boolean cached) {
317 var NodeTableStatistics nodeStats = null
319 val tableRef = InstanceIdentifier.builder(Nodes)
320 .child(org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node, InventoryMapping.toNodeKey(nodeTable.node))
321 .augmentation(FlowCapableNode).child(Table, new TableKey(nodeTable.ID as Short)).toInstance();
323 val it = this.startChange();
325 val table= it.readConfigurationData(tableRef) as Table;
328 val tableStats = table.getAugmentation(FlowTableStatisticsData);
330 if(tableStats != null){
331 nodeStats = toNodeTableStatistics(tableStats.flowTableStatistics,table.id,nodeTable.node);
335 //TODO: Refer TODO (main)
336 val input = new GetFlowTablesStatisticsInputBuilder();
337 input.setNode(nodeTable.node.toNodeRef);
338 flowTableStatisticsService.getFlowTablesStatistics(input.build);
343 override onNodeConnectorRemoved(NodeConnectorRemoved update) {
347 override onNodeRemoved(NodeRemoved notification) {
348 val properties = Collections.<org.opendaylight.controller.sal.core.Property>emptySet();
350 publishNodeUpdate(notification.nodeRef.toADNode, UpdateType.REMOVED, properties);
353 override onNodeConnectorUpdated(NodeConnectorUpdated update) {
354 var updateType = UpdateType.CHANGED;
355 if ( this._dataService.readOperationalData(update.nodeConnectorRef.value as InstanceIdentifier<? extends DataObject>) == null ){
356 updateType = UpdateType.ADDED;
359 var nodeConnector = update.nodeConnectorRef.toADNodeConnector
361 publishNodeConnectorUpdate(nodeConnector , updateType , update.toADNodeConnectorProperties);
364 override onNodeUpdated(NodeUpdated notification) {
365 val InstanceIdentifier<? extends DataObject> identifier = notification.nodeRef.value as InstanceIdentifier<? extends DataObject>;
367 var updateType = UpdateType.CHANGED;
368 if ( this._dataService.readOperationalData(identifier) == null ){
369 updateType = UpdateType.ADDED;
371 publishNodeUpdate(notification.nodeRef.toADNode, updateType, notification.toADNodeProperties);
373 //Notify the listeners of IPluginOutReadService
375 for (statsPublisher : statisticsPublisher){
376 val nodeRef = InstanceIdentifier.builder(Nodes).child(org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node,new NodeKey(notification.id)).toInstance;
377 val description = notification.nodeRef.toNodeDescription
378 if(description != null) {
379 statsPublisher.descriptionStatisticsUpdated(nodeRef.toADNode,description);
384 override getNodeProps() {
385 val props = new ConcurrentHashMap<Node, Map<String, org.opendaylight.controller.sal.core.Property>>()
387 val nodes = readAllMDNodes()
388 for (node : nodes.node ) {
389 val fcn = node.getAugmentation(FlowCapableNode)
391 val perNodeProps = fcn.toADNodeProperties(node.id)
392 val perNodePropMap = new ConcurrentHashMap<String, org.opendaylight.controller.sal.core.Property>
393 if(perNodeProps != null ) {
394 for(perNodeProp : perNodeProps) {
395 perNodePropMap.put(perNodeProp.name,perNodeProp)
398 props.put(new Node(MD_SAL_TYPE, node.id.toADNodeId),perNodePropMap)
404 private def readAllMDNodes() {
405 val nodesRef = InstanceIdentifier.builder(Nodes)
407 val reader = TypeSafeDataReader.forReader(dataService)
408 return reader.readOperationalData(nodesRef)
411 private def readAllMDNodeConnectors(org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node node) {
412 val nodeRef = InstanceIdentifier.builder(Nodes)
413 .child(org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node,new NodeKey(node.id))
415 val reader = TypeSafeDataReader.forReader(dataService)
416 return reader.readOperationalData(nodeRef).nodeConnector
419 override getNodeConnectorProps(Boolean refresh) {
420 // Note, because the MD-SAL has a unified data store, we can ignore the Boolean refresh, as we have no secondary
421 // data store to refresh from
422 val props = new ConcurrentHashMap<org.opendaylight.controller.sal.core.NodeConnector, Map<String, org.opendaylight.controller.sal.core.Property>>()
423 val nodes = readAllMDNodes()
424 for (node : nodes.node) {
425 val ncs = node.readAllMDNodeConnectors
428 val fcnc = nc.getAugmentation(FlowCapableNodeConnector)
430 val ncps = fcnc.toADNodeConnectorProperties
431 val ncpsm = new ConcurrentHashMap<String, org.opendaylight.controller.sal.core.Property>
437 props.put(nc.id.toADNodeConnector(node.id),ncpsm)
445 private def FlowCapableNode readFlowCapableNode(NodeRef ref) {
446 val dataObject = dataService.readOperationalData(ref.value as InstanceIdentifier<? extends DataObject>);
447 if(dataObject != null) {
448 val node = dataObject.checkInstanceOf(
449 org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node);
450 return node.getAugmentation(FlowCapableNode);
455 private def FlowCapableNodeConnector readFlowCapableNodeConnector(NodeConnectorRef ref) {
456 val dataObject = dataService.readOperationalData(ref.value as InstanceIdentifier<? extends DataObject>);
457 val node = dataObject.checkInstanceOf(
459 return node.getAugmentation(FlowCapableNodeConnector);
462 private def toNodeConnectorStatistics(
463 org.opendaylight.yang.gen.v1.urn.opendaylight.model.statistics.types.rev130925.NodeConnectorStatistics nodeConnectorStatistics, NodeId nodeId, NodeConnectorId nodeConnectorId) {
465 val it = new NodeConnectorStatistics();
467 receivePacketCount = nodeConnectorStatistics.packets.received.longValue;
468 transmitPacketCount = nodeConnectorStatistics.packets.transmitted.longValue;
470 receiveByteCount = nodeConnectorStatistics.bytes.received.longValue;
471 transmitByteCount = nodeConnectorStatistics.bytes.transmitted.longValue;
473 receiveDropCount = nodeConnectorStatistics.receiveDrops.longValue;
474 transmitDropCount = nodeConnectorStatistics.transmitDrops.longValue;
476 receiveErrorCount = nodeConnectorStatistics.receiveErrors.longValue;
477 transmitErrorCount = nodeConnectorStatistics.transmitErrors.longValue;
479 receiveFrameErrorCount = nodeConnectorStatistics.receiveFrameError.longValue;
480 receiveOverRunErrorCount = nodeConnectorStatistics.receiveOverRunError.longValue;
481 receiveCRCErrorCount = nodeConnectorStatistics.receiveCrcError.longValue;
482 collisionCount = nodeConnectorStatistics.collisionCount.longValue;
484 val nodeConnectorRef = InstanceIdentifier.builder(Nodes)
485 .child(org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node,new NodeKey(nodeId))
486 .child(NodeConnector,new NodeConnectorKey(nodeConnectorId)).toInstance;
488 nodeConnector = NodeMapping.toADNodeConnector(new NodeConnectorRef(nodeConnectorRef));
493 private def toNodeTableStatistics(
494 FlowTableStatistics tableStats,
495 Short tableId,Node node){
496 var it = new NodeTableStatistics();
498 activeCount = tableStats.activeFlows.value.intValue;
499 lookupCount = tableStats.packetsLookedUp.value.intValue;
500 matchedCount = tableStats.packetsMatched.value.intValue;
501 name = tableId.toString;
502 nodeTable = new NodeTable(NodeMapping.MD_SAL_TYPE,tableId,node);
506 private def toNodeDescription(NodeRef nodeRef){
507 val capableNode = readFlowCapableNode(nodeRef);
508 if(capableNode !=null) {
509 val it = new NodeDescription()
510 manufacturer = capableNode.manufacturer
511 serialNumber = capableNode.serialNumber
512 software = capableNode.software
513 description = capableNode.description
521 def Edge toADEdge(Link link) {
522 new Edge(link.source.toADNodeConnector,link.destination.toADNodeConnector)
526 * OpendaylightFlowStatisticsListener interface implementation
528 override onAggregateFlowStatisticsUpdate(AggregateFlowStatisticsUpdate notification) {
529 //Ignoring this notification as there does not seem to be a way to bubble this up to AD-SAL
532 override onFlowsStatisticsUpdate(FlowsStatisticsUpdate notification) {
534 val adsalFlowsStatistics = new ArrayList<FlowOnNode>();
535 val nodeRef = InstanceIdentifier.builder(Nodes).child(org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node,new NodeKey(notification.id)).toInstance;
537 for(flowStats : notification.flowAndStatisticsMapList){
538 if(flowStats.tableId == 0)
539 adsalFlowsStatistics.add(toFlowOnNode(flowStats,nodeRef.toADNode));
542 for (statsPublisher : statisticsPublisher){
543 statsPublisher.nodeFlowStatisticsUpdated(nodeRef.toADNode,adsalFlowsStatistics);
548 * OpendaylightFlowTableStatisticsListener interface implementation
550 override onFlowTableStatisticsUpdate(FlowTableStatisticsUpdate notification) {
551 var adsalFlowTableStatistics = new ArrayList<NodeTableStatistics>();
553 for(stats : notification.flowTableAndStatisticsMap){
554 if (stats.tableId.value == 0){
555 val it = new NodeTableStatistics();
556 activeCount = stats.activeFlows.value.intValue;
557 lookupCount = stats.packetsLookedUp.value.longValue;
558 matchedCount = stats.packetsMatched.value.longValue;
560 adsalFlowTableStatistics.add(it);
563 for (statsPublisher : statisticsPublisher){
564 val nodeRef = InstanceIdentifier.builder(Nodes).child(org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node,new NodeKey(notification.id)).toInstance;
565 statsPublisher.nodeTableStatisticsUpdated(nodeRef.toADNode,adsalFlowTableStatistics);
570 * OpendaylightPortStatisticsUpdate interface implementation
572 override onNodeConnectorStatisticsUpdate(NodeConnectorStatisticsUpdate notification) {
574 val adsalPortStatistics = new ArrayList<NodeConnectorStatistics>();
576 for(nodeConnectorStatistics : notification.nodeConnectorStatisticsAndPortNumberMap){
577 adsalPortStatistics.add(toNodeConnectorStatistics(nodeConnectorStatistics,notification.id,nodeConnectorStatistics.nodeConnectorId));
580 for (statsPublisher : statisticsPublisher){
581 val nodeRef = InstanceIdentifier.builder(Nodes).child(org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node,new NodeKey(notification.id)).toInstance;
582 statsPublisher.nodeConnectorStatisticsUpdated(nodeRef.toADNode,adsalPortStatistics);
587 private static def toFlowOnNode (FlowAndStatisticsMapList flowAndStatsMap,Node node){
589 val it = new FlowOnNode(ToSalConversionsUtils.toFlow(flowAndStatsMap,node));
591 byteCount = flowAndStatsMap.byteCount.value.longValue;
592 packetCount = flowAndStatsMap.packetCount.value.longValue;
593 durationSeconds = flowAndStatsMap.duration.second.value.intValue;
594 durationNanoseconds = flowAndStatsMap.duration.nanosecond.value.intValue;
599 override getConfiguredNotConnectedNodes() {
600 return Collections.emptySet();
604 private def publishNodeUpdate(Node node, UpdateType updateType, Set<org.opendaylight.controller.sal.core.Property> properties){
605 for( publisher : inventoryPublisher){
606 publisher.updateNode(node, updateType, properties);
610 private def publishNodeConnectorUpdate(org.opendaylight.controller.sal.core.NodeConnector nodeConnector, UpdateType updateType, Set<org.opendaylight.controller.sal.core.Property> properties){
611 for( publisher : inventoryPublisher){
612 publisher.updateNodeConnector(nodeConnector, updateType, properties);