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
15 import java.util.concurrent.ConcurrentHashMap
16 import java.util.concurrent.CopyOnWriteArrayList
17 import java.util.concurrent.locks.Lock
18 import java.util.concurrent.locks.ReentrantLock
19 import org.opendaylight.controller.md.sal.binding.util.TypeSafeDataReader
20 import org.opendaylight.controller.sal.binding.api.data.DataBrokerService
21 import org.opendaylight.controller.sal.binding.api.data.DataProviderService
22 import org.opendaylight.controller.sal.core.Edge
23 import org.opendaylight.controller.sal.core.Node
24 import org.opendaylight.controller.sal.core.NodeTable
25 import org.opendaylight.controller.sal.core.UpdateType
26 import org.opendaylight.controller.sal.flowprogrammer.Flow
27 import org.opendaylight.controller.sal.inventory.IPluginInInventoryService
28 import org.opendaylight.controller.sal.inventory.IPluginOutInventoryService
29 import org.opendaylight.controller.sal.reader.FlowOnNode
30 import org.opendaylight.controller.sal.reader.IPluginInReadService
31 import org.opendaylight.controller.sal.reader.IPluginOutReadService
32 import org.opendaylight.controller.sal.reader.NodeConnectorStatistics
33 import org.opendaylight.controller.sal.reader.NodeDescription
34 import org.opendaylight.controller.sal.reader.NodeTableStatistics
35 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNode
36 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNodeConnector
37 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.Table
38 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.TableKey
39 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.AggregateFlowStatisticsUpdate
40 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.FlowStatisticsData
41 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.FlowsStatisticsUpdate
42 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.GetAllFlowsStatisticsFromAllFlowTablesInputBuilder
43 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.GetFlowStatisticsFromFlowTableInputBuilder
44 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.OpendaylightFlowStatisticsListener
45 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.OpendaylightFlowStatisticsService
46 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.flow.and.statistics.map.list.FlowAndStatisticsMapList
47 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.table.statistics.rev131215.FlowTableStatisticsData
48 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.table.statistics.rev131215.FlowTableStatisticsUpdate
49 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.table.statistics.rev131215.GetFlowTablesStatisticsInputBuilder
50 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.table.statistics.rev131215.OpendaylightFlowTableStatisticsListener
51 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.table.statistics.rev131215.OpendaylightFlowTableStatisticsService
52 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.table.statistics.rev131215.flow.table.statistics.FlowTableStatistics
53 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.topology.discovery.rev130819.FlowTopologyDiscoveryService
54 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.topology.discovery.rev130819.Link
55 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeConnectorId
56 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeConnectorRef
57 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeConnectorRemoved
58 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeConnectorUpdated
59 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeId
60 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeRef
61 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeRemoved
62 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeUpdated
63 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.Nodes
64 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.OpendaylightInventoryListener
65 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.node.NodeConnector
66 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.node.NodeConnectorKey
67 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.NodeKey
68 import org.opendaylight.yang.gen.v1.urn.opendaylight.port.statistics.rev131214.FlowCapableNodeConnectorStatistics
69 import org.opendaylight.yang.gen.v1.urn.opendaylight.port.statistics.rev131214.FlowCapableNodeConnectorStatisticsData
70 import org.opendaylight.yang.gen.v1.urn.opendaylight.port.statistics.rev131214.GetAllNodeConnectorsStatisticsInputBuilder
71 import org.opendaylight.yang.gen.v1.urn.opendaylight.port.statistics.rev131214.GetNodeConnectorStatisticsInputBuilder
72 import org.opendaylight.yang.gen.v1.urn.opendaylight.port.statistics.rev131214.NodeConnectorStatisticsUpdate
73 import org.opendaylight.yang.gen.v1.urn.opendaylight.port.statistics.rev131214.OpendaylightPortStatisticsListener
74 import org.opendaylight.yang.gen.v1.urn.opendaylight.port.statistics.rev131214.OpendaylightPortStatisticsService
75 import org.opendaylight.yangtools.yang.binding.DataObject
76 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier
77 import org.slf4j.LoggerFactory
79 import static extension org.opendaylight.controller.sal.common.util.Arguments.*
80 import static extension org.opendaylight.controller.sal.compatibility.NodeMapping.*
82 class InventoryAndReadAdapter implements IPluginInReadService,
83 IPluginInInventoryService,
84 OpendaylightInventoryListener,
85 OpendaylightFlowStatisticsListener,
86 OpendaylightFlowTableStatisticsListener,
87 OpendaylightPortStatisticsListener {
89 private static val LOG = LoggerFactory.getLogger(InventoryAndReadAdapter);
91 private static val OPENFLOWV10_TABLE_ID = new Integer(0).shortValue;
93 DataBrokerService dataService;
96 DataProviderService dataProviderService;
99 OpendaylightFlowStatisticsService flowStatisticsService;
102 OpendaylightPortStatisticsService nodeConnectorStatisticsService;
105 OpendaylightFlowTableStatisticsService flowTableStatisticsService;
108 FlowTopologyDiscoveryService topologyDiscovery;
111 List<IPluginOutReadService> statisticsPublisher = new CopyOnWriteArrayList<IPluginOutReadService>();
114 List<IPluginOutInventoryService> inventoryPublisher = new CopyOnWriteArrayList<IPluginOutInventoryService>();
116 private final InventoryNotificationProvider inventoryNotificationProvider = new InventoryNotificationProvider();
118 private final Map<InstanceIdentifier.PathArgument, List<InstanceIdentifier.PathArgument>> nodeToNodeConnectorsMap = new ConcurrentHashMap<InstanceIdentifier.PathArgument, List<InstanceIdentifier.PathArgument>>();
120 private final Lock nodeToNodeConnectorsLock = new ReentrantLock();
124 inventoryNotificationProvider.dataProviderService = dataProviderService;
125 inventoryNotificationProvider.inventoryPublisher = inventoryPublisher;
126 // inventoryNotificationProvider.start();
132 def setInventoryPublisher(IPluginOutInventoryService listener){
133 inventoryPublisher.add(listener);
136 def unsetInventoryPublisher(IPluginOutInventoryService listener){
137 inventoryPublisher.remove(listener);
140 def setReadPublisher(IPluginOutReadService listener) {
141 statisticsPublisher.add(listener);
144 def unsetReadPublisher (IPluginOutReadService listener) {
145 if( listener != null)
146 statisticsPublisher.remove(listener);
149 protected def startChange() {
150 return dataProviderService.beginTransaction;
153 override getTransmitRate(org.opendaylight.controller.sal.core.NodeConnector connector) {
154 val nodeConnector = readFlowCapableNodeConnector(connector.toNodeConnectorRef);
155 return nodeConnector.currentSpeed
158 override readAllFlow(Node node, boolean cached) {
160 val output = new ArrayList<FlowOnNode>();
161 val tableRef = InstanceIdentifier.builder(Nodes)
162 .child(org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node, InventoryMapping.toNodeKey(node))
163 .augmentation(FlowCapableNode).child(Table, new TableKey(OPENFLOWV10_TABLE_ID)).toInstance();
165 val it = this.startChange();
167 val table= it.readConfigurationData(tableRef) as Table;
170 LOG.trace("Number of flows installed in table 0 of node {} : {}",node,table.flow.size);
172 for(flow : table.flow){
174 val adsalFlow = ToSalConversionsUtils.toFlow(flow,node);
175 val statsFromDataStore = flow.getAugmentation(FlowStatisticsData);
177 if(statsFromDataStore != null){
178 val it = new FlowOnNode(adsalFlow);
179 byteCount = statsFromDataStore.flowStatistics.byteCount.value.longValue;
180 packetCount = statsFromDataStore.flowStatistics.packetCount.value.longValue;
181 durationSeconds = statsFromDataStore.flowStatistics.duration.second.value.intValue;
182 durationNanoseconds = statsFromDataStore.flowStatistics.duration.nanosecond.value.intValue;
189 //TODO (main): Shell we send request to the switch? It will make async request to the switch.
190 // Once plugin receive response, it will let adaptor know through onFlowStatisticsUpdate()
191 // If we assume that md-sal statistics manager will always be running, then its not required
192 // But if not, then sending request will collect the latest data for adaptor atleast.
193 val input = new GetAllFlowsStatisticsFromAllFlowTablesInputBuilder;
194 input.setNode(node.toNodeRef);
195 flowStatisticsService.getAllFlowsStatisticsFromAllFlowTables(input.build)
200 override readAllNodeConnector(Node node, boolean cached) {
202 val ret = new ArrayList<NodeConnectorStatistics>();
203 val nodeRef = InstanceIdentifier.builder(Nodes)
204 .child(org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node, InventoryMapping.toNodeKey(node))
207 val provider = this.startChange();
209 val dsNode= provider.readConfigurationData(nodeRef) as org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node;
213 for (dsNodeConnector : dsNode.nodeConnector){
214 val nodeConnectorRef = InstanceIdentifier.builder(Nodes)
215 .child(org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node, InventoryMapping.toNodeKey(node))
216 .child(NodeConnector, dsNodeConnector.key)
219 val nodeConnectorFromDS = provider.readConfigurationData(nodeConnectorRef) as NodeConnector;
221 if(nodeConnectorFromDS != null){
222 val nodeConnectorStatsFromDs = nodeConnectorFromDS.getAugmentation(FlowCapableNodeConnectorStatisticsData) as FlowCapableNodeConnectorStatistics;
224 ret.add(toNodeConnectorStatistics(nodeConnectorStatsFromDs.flowCapableNodeConnectorStatistics,dsNode.id,dsNodeConnector.id));
229 //TODO: Refer TODO (main)
230 val input = new GetAllNodeConnectorsStatisticsInputBuilder();
231 input.setNode(node.toNodeRef);
232 nodeConnectorStatisticsService.getAllNodeConnectorsStatistics(input.build());
236 override readAllNodeTable(Node node, boolean cached) {
237 val ret = new ArrayList<NodeTableStatistics>();
239 val dsFlowCapableNode= readFlowCapableNode(node.toNodeRef)
241 if(dsFlowCapableNode != null){
243 for (table : dsFlowCapableNode.table){
245 val tableStats = table.getAugmentation(FlowTableStatisticsData);
247 if(tableStats != null){
248 ret.add(toNodeTableStatistics(tableStats.flowTableStatistics,table.id,node));
253 //TODO: Refer TODO (main)
254 val input = new GetFlowTablesStatisticsInputBuilder();
255 input.setNode(node.toNodeRef);
256 flowTableStatisticsService.getFlowTablesStatistics(input.build);
260 override readDescription(Node node, boolean cached) {
261 return toNodeDescription(node.toNodeRef);
264 override readFlow(Node node, Flow targetFlow, boolean cached) {
265 var FlowOnNode ret= null;
267 val tableRef = InstanceIdentifier.builder(Nodes)
268 .child(org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node, InventoryMapping.toNodeKey(node))
269 .augmentation(FlowCapableNode).child(Table, new TableKey(OPENFLOWV10_TABLE_ID)).toInstance();
271 val it = this.startChange();
273 val table= it.readConfigurationData(tableRef) as Table;
276 LOG.trace("Number of flows installed in table 0 of node {} : {}",node,table.flow.size);
278 for(mdsalFlow : table.flow){
279 if(FromSalConversionsUtils.flowEquals(mdsalFlow, MDFlowMapping.toMDSalflow(targetFlow))){
280 val statsFromDataStore = mdsalFlow.getAugmentation(FlowStatisticsData);
282 if(statsFromDataStore != null){
283 LOG.debug("Found matching flow in the data store flow table ");
284 val it = new FlowOnNode(targetFlow);
285 byteCount = statsFromDataStore.flowStatistics.byteCount.value.longValue;
286 packetCount = statsFromDataStore.flowStatistics.packetCount.value.longValue;
287 durationSeconds = statsFromDataStore.flowStatistics.duration.second.value.intValue;
288 durationNanoseconds = statsFromDataStore.flowStatistics.duration.nanosecond.value.intValue;
296 //TODO: Refer TODO (main)
297 val input = new GetFlowStatisticsFromFlowTableInputBuilder;
298 input.setNode(node.toNodeRef);
299 input.fieldsFrom(MDFlowMapping.toMDSalflow(targetFlow));
300 flowStatisticsService.getFlowStatisticsFromFlowTable(input.build)
306 override readNodeConnector(org.opendaylight.controller.sal.core.NodeConnector connector, boolean cached) {
307 var NodeConnectorStatistics nodeConnectorStatistics = null;
309 val nodeConnectorRef = InstanceIdentifier.builder(Nodes)
310 .child(org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node, InventoryMapping.toNodeKey(connector.node))
311 .child(NodeConnector, InventoryMapping.toNodeConnectorKey(connector))
313 val provider = this.startChange();
315 val nodeConnectorFromDS = provider.readConfigurationData(nodeConnectorRef) as NodeConnector;
317 if(nodeConnectorFromDS != null){
318 val nodeConnectorStatsFromDs = nodeConnectorFromDS.getAugmentation(FlowCapableNodeConnectorStatisticsData) as FlowCapableNodeConnectorStatistics;
319 if(nodeConnectorStatsFromDs != null) {
320 nodeConnectorStatistics = toNodeConnectorStatistics(nodeConnectorStatsFromDs.flowCapableNodeConnectorStatistics,
321 InventoryMapping.toNodeKey(connector.node).id,
322 InventoryMapping.toNodeConnectorKey(connector).id);
326 //TODO: Refer TODO (main)
327 val input = new GetNodeConnectorStatisticsInputBuilder();
328 input.setNode(connector.node.toNodeRef);
329 input.setNodeConnectorId(InventoryMapping.toNodeConnectorKey(connector).id);
330 nodeConnectorStatisticsService.getNodeConnectorStatistics(input.build());
331 return nodeConnectorStatistics;
334 override readNodeTable(NodeTable nodeTable, boolean cached) {
335 var NodeTableStatistics nodeStats = null
337 val tableRef = InstanceIdentifier.builder(Nodes)
338 .child(org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node, InventoryMapping.toNodeKey(nodeTable.node))
339 .augmentation(FlowCapableNode).child(Table, new TableKey(nodeTable.ID as Short)).toInstance();
341 val it = this.startChange();
343 val table= it.readConfigurationData(tableRef) as Table;
346 val tableStats = table.getAugmentation(FlowTableStatisticsData);
348 if(tableStats != null){
349 nodeStats = toNodeTableStatistics(tableStats.flowTableStatistics,table.id,nodeTable.node);
353 //TODO: Refer TODO (main)
354 val input = new GetFlowTablesStatisticsInputBuilder();
355 input.setNode(nodeTable.node.toNodeRef);
356 flowTableStatisticsService.getFlowTablesStatistics(input.build);
361 override onNodeConnectorRemoved(NodeConnectorRemoved update) {
365 override onNodeRemoved(NodeRemoved notification) {
366 val properties = Collections.<org.opendaylight.controller.sal.core.Property>emptySet();
368 removeNodeConnectors(notification.nodeRef.value);
370 publishNodeUpdate(notification.nodeRef.toADNode, UpdateType.REMOVED, properties);
373 override onNodeConnectorUpdated(NodeConnectorUpdated update) {
374 var updateType = UpdateType.CHANGED;
375 if(!isKnownNodeConnector(update.nodeConnectorRef.value)){
376 updateType = UpdateType.ADDED;
377 recordNodeConnector(update.nodeConnectorRef.value);
380 var nodeConnector = update.nodeConnectorRef.toADNodeConnector
382 publishNodeConnectorUpdate(nodeConnector , updateType , update.toADNodeConnectorProperties);
385 override onNodeUpdated(NodeUpdated notification) {
386 val InstanceIdentifier<? extends DataObject> identifier = notification.nodeRef.value as InstanceIdentifier<? extends DataObject>;
388 var updateType = UpdateType.CHANGED;
389 if ( this._dataService.readOperationalData(identifier) == null ){
390 updateType = UpdateType.ADDED;
392 publishNodeUpdate(notification.nodeRef.toADNode, updateType, notification.toADNodeProperties);
394 //Notify the listeners of IPluginOutReadService
396 for (statsPublisher : statisticsPublisher){
397 val nodeRef = InstanceIdentifier.builder(Nodes).child(org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node,new NodeKey(notification.id)).toInstance;
398 val description = notification.nodeRef.toNodeDescription
399 if(description != null) {
400 statsPublisher.descriptionStatisticsUpdated(nodeRef.toADNode,description);
405 override getNodeProps() {
406 val props = new ConcurrentHashMap<Node, Map<String, org.opendaylight.controller.sal.core.Property>>()
408 val nodes = readAllMDNodes()
409 for (node : nodes.node ) {
410 val fcn = node.getAugmentation(FlowCapableNode)
412 val perNodeProps = fcn.toADNodeProperties(node.id)
413 val perNodePropMap = new ConcurrentHashMap<String, org.opendaylight.controller.sal.core.Property>
414 if(perNodeProps != null ) {
415 for(perNodeProp : perNodeProps) {
416 perNodePropMap.put(perNodeProp.name,perNodeProp)
419 props.put(new Node(MD_SAL_TYPE, node.id.toADNodeId),perNodePropMap)
425 private def readAllMDNodes() {
426 val nodesRef = InstanceIdentifier.builder(Nodes)
428 val reader = TypeSafeDataReader.forReader(dataService)
429 return reader.readOperationalData(nodesRef)
432 private def readAllMDNodeConnectors(org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node node) {
433 val nodeRef = InstanceIdentifier.builder(Nodes)
434 .child(org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node,new NodeKey(node.id))
436 val reader = TypeSafeDataReader.forReader(dataService)
437 return reader.readOperationalData(nodeRef).nodeConnector
440 override getNodeConnectorProps(Boolean refresh) {
441 // Note, because the MD-SAL has a unified data store, we can ignore the Boolean refresh, as we have no secondary
442 // data store to refresh from
443 val props = new ConcurrentHashMap<org.opendaylight.controller.sal.core.NodeConnector, Map<String, org.opendaylight.controller.sal.core.Property>>()
444 val nodes = readAllMDNodes()
445 for (node : nodes.node) {
446 val ncs = node.readAllMDNodeConnectors
449 val fcnc = nc.getAugmentation(FlowCapableNodeConnector)
451 val ncps = fcnc.toADNodeConnectorProperties
452 val ncpsm = new ConcurrentHashMap<String, org.opendaylight.controller.sal.core.Property>
458 props.put(nc.id.toADNodeConnector(node.id),ncpsm)
466 private def FlowCapableNode readFlowCapableNode(NodeRef ref) {
467 val dataObject = dataService.readOperationalData(ref.value as InstanceIdentifier<? extends DataObject>);
468 if(dataObject != null) {
469 val node = dataObject.checkInstanceOf(
470 org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node);
471 return node.getAugmentation(FlowCapableNode);
476 private def FlowCapableNodeConnector readFlowCapableNodeConnector(NodeConnectorRef ref) {
477 val dataObject = dataService.readOperationalData(ref.value as InstanceIdentifier<? extends DataObject>);
478 val node = dataObject.checkInstanceOf(
480 return node.getAugmentation(FlowCapableNodeConnector);
483 private def toNodeConnectorStatistics(
484 org.opendaylight.yang.gen.v1.urn.opendaylight.model.statistics.types.rev130925.NodeConnectorStatistics nodeConnectorStatistics, NodeId nodeId, NodeConnectorId nodeConnectorId) {
486 val it = new NodeConnectorStatistics();
488 receivePacketCount = nodeConnectorStatistics.packets.received.longValue;
489 transmitPacketCount = nodeConnectorStatistics.packets.transmitted.longValue;
491 receiveByteCount = nodeConnectorStatistics.bytes.received.longValue;
492 transmitByteCount = nodeConnectorStatistics.bytes.transmitted.longValue;
494 receiveDropCount = nodeConnectorStatistics.receiveDrops.longValue;
495 transmitDropCount = nodeConnectorStatistics.transmitDrops.longValue;
497 receiveErrorCount = nodeConnectorStatistics.receiveErrors.longValue;
498 transmitErrorCount = nodeConnectorStatistics.transmitErrors.longValue;
500 receiveFrameErrorCount = nodeConnectorStatistics.receiveFrameError.longValue;
501 receiveOverRunErrorCount = nodeConnectorStatistics.receiveOverRunError.longValue;
502 receiveCRCErrorCount = nodeConnectorStatistics.receiveCrcError.longValue;
503 collisionCount = nodeConnectorStatistics.collisionCount.longValue;
505 val nodeConnectorRef = InstanceIdentifier.builder(Nodes)
506 .child(org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node,new NodeKey(nodeId))
507 .child(NodeConnector,new NodeConnectorKey(nodeConnectorId)).toInstance;
509 nodeConnector = NodeMapping.toADNodeConnector(new NodeConnectorRef(nodeConnectorRef));
514 private def toNodeTableStatistics(
515 FlowTableStatistics tableStats,
516 Short tableId,Node node){
517 var it = new NodeTableStatistics();
519 activeCount = tableStats.activeFlows.value.intValue;
520 lookupCount = tableStats.packetsLookedUp.value.intValue;
521 matchedCount = tableStats.packetsMatched.value.intValue;
522 name = tableId.toString;
523 nodeTable = new NodeTable(NodeMapping.MD_SAL_TYPE,tableId,node);
527 private def toNodeDescription(NodeRef nodeRef){
528 val capableNode = readFlowCapableNode(nodeRef);
529 if(capableNode !=null) {
530 val it = new NodeDescription()
531 manufacturer = capableNode.manufacturer
532 serialNumber = capableNode.serialNumber
533 software = capableNode.software
534 description = capableNode.description
542 def Edge toADEdge(Link link) {
543 new Edge(link.source.toADNodeConnector,link.destination.toADNodeConnector)
547 * OpendaylightFlowStatisticsListener interface implementation
549 override onAggregateFlowStatisticsUpdate(AggregateFlowStatisticsUpdate notification) {
550 //Ignoring this notification as there does not seem to be a way to bubble this up to AD-SAL
553 override onFlowsStatisticsUpdate(FlowsStatisticsUpdate notification) {
555 val adsalFlowsStatistics = new ArrayList<FlowOnNode>();
556 val nodeRef = InstanceIdentifier.builder(Nodes).child(org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node,new NodeKey(notification.id)).toInstance;
558 for(flowStats : notification.flowAndStatisticsMapList){
559 if(flowStats.tableId == 0)
560 adsalFlowsStatistics.add(toFlowOnNode(flowStats,nodeRef.toADNode));
563 for (statsPublisher : statisticsPublisher){
564 statsPublisher.nodeFlowStatisticsUpdated(nodeRef.toADNode,adsalFlowsStatistics);
569 * OpendaylightFlowTableStatisticsListener interface implementation
571 override onFlowTableStatisticsUpdate(FlowTableStatisticsUpdate notification) {
572 var adsalFlowTableStatistics = new ArrayList<NodeTableStatistics>();
574 for(stats : notification.flowTableAndStatisticsMap){
575 if (stats.tableId.value == 0){
576 val it = new NodeTableStatistics();
577 activeCount = stats.activeFlows.value.intValue;
578 lookupCount = stats.packetsLookedUp.value.longValue;
579 matchedCount = stats.packetsMatched.value.longValue;
581 adsalFlowTableStatistics.add(it);
584 for (statsPublisher : statisticsPublisher){
585 val nodeRef = InstanceIdentifier.builder(Nodes).child(org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node,new NodeKey(notification.id)).toInstance;
586 statsPublisher.nodeTableStatisticsUpdated(nodeRef.toADNode,adsalFlowTableStatistics);
591 * OpendaylightPortStatisticsUpdate interface implementation
593 override onNodeConnectorStatisticsUpdate(NodeConnectorStatisticsUpdate notification) {
595 val adsalPortStatistics = new ArrayList<NodeConnectorStatistics>();
597 for(nodeConnectorStatistics : notification.nodeConnectorStatisticsAndPortNumberMap){
598 adsalPortStatistics.add(toNodeConnectorStatistics(nodeConnectorStatistics,notification.id,nodeConnectorStatistics.nodeConnectorId));
601 for (statsPublisher : statisticsPublisher){
602 val nodeRef = InstanceIdentifier.builder(Nodes).child(org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node,new NodeKey(notification.id)).toInstance;
603 statsPublisher.nodeConnectorStatisticsUpdated(nodeRef.toADNode,adsalPortStatistics);
608 private static def toFlowOnNode (FlowAndStatisticsMapList flowAndStatsMap,Node node){
610 val it = new FlowOnNode(ToSalConversionsUtils.toFlow(flowAndStatsMap,node));
612 byteCount = flowAndStatsMap.byteCount.value.longValue;
613 packetCount = flowAndStatsMap.packetCount.value.longValue;
614 durationSeconds = flowAndStatsMap.duration.second.value.intValue;
615 durationNanoseconds = flowAndStatsMap.duration.nanosecond.value.intValue;
620 override getConfiguredNotConnectedNodes() {
621 return Collections.emptySet();
625 private def publishNodeUpdate(Node node, UpdateType updateType, Set<org.opendaylight.controller.sal.core.Property> properties){
626 for( publisher : inventoryPublisher){
627 publisher.updateNode(node, updateType, properties);
631 private def publishNodeConnectorUpdate(org.opendaylight.controller.sal.core.NodeConnector nodeConnector, UpdateType updateType, Set<org.opendaylight.controller.sal.core.Property> properties){
632 for( publisher : inventoryPublisher){
633 publisher.updateNodeConnector(nodeConnector, updateType, properties);
637 private def isKnownNodeConnector(InstanceIdentifier<? extends Object> nodeConnectorIdentifier){
638 if(nodeConnectorIdentifier.path.size() < 3) {
642 val nodePath = nodeConnectorIdentifier.path.get(1);
643 val nodeConnectorPath = nodeConnectorIdentifier.getPath().get(2);
645 val nodeConnectors = nodeToNodeConnectorsMap.get(nodePath);
647 if(nodeConnectors == null){
650 return nodeConnectors.contains(nodeConnectorPath);
654 private def recordNodeConnector(InstanceIdentifier<? extends Object> nodeConnectorIdentifier){
655 if(nodeConnectorIdentifier.path.size() < 3) {
659 val nodePath = nodeConnectorIdentifier.path.get(1);
660 val nodeConnectorPath = nodeConnectorIdentifier.getPath().get(2);
662 nodeToNodeConnectorsLock.lock();
665 var nodeConnectors = nodeToNodeConnectorsMap.get(nodePath);
667 if(nodeConnectors == null){
668 nodeConnectors = new ArrayList<InstanceIdentifier.PathArgument>();
669 nodeToNodeConnectorsMap.put(nodePath, nodeConnectors);
672 nodeConnectors.add(nodeConnectorPath);
674 nodeToNodeConnectorsLock.unlock();
678 private def removeNodeConnectors(InstanceIdentifier<? extends Object> nodeIdentifier){
679 val nodePath = nodeIdentifier.path.get(1);
681 nodeToNodeConnectorsMap.remove(nodePath);