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.ArrayList;
15 import java.util.concurrent.locks.ReentrantLock;
16 import java.util.concurrent.locks.Lock;
17 import java.util.concurrent.CopyOnWriteArrayList;
18 import org.opendaylight.controller.sal.binding.api.data.DataBrokerService
19 import org.opendaylight.controller.sal.binding.api.data.DataProviderService
20 import org.opendaylight.controller.sal.core.Edge
21 import org.opendaylight.controller.sal.core.Node
22 import org.opendaylight.controller.sal.core.NodeTable
23 import org.opendaylight.controller.sal.core.UpdateType
24 import org.opendaylight.controller.sal.flowprogrammer.Flow
25 import org.opendaylight.controller.sal.inventory.IPluginInInventoryService
26 import org.opendaylight.controller.sal.inventory.IPluginOutInventoryService
27 import org.opendaylight.controller.sal.reader.FlowOnNode
28 import org.opendaylight.controller.sal.reader.IPluginInReadService
29 import org.opendaylight.controller.sal.reader.IPluginOutReadService
30 import org.opendaylight.controller.sal.reader.NodeConnectorStatistics
31 import org.opendaylight.controller.sal.reader.NodeDescription
32 import org.opendaylight.controller.sal.reader.NodeTableStatistics
33 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNode
34 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNodeConnector
35 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.Table
36 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.TableKey
37 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.AggregateFlowStatisticsUpdate
38 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.FlowStatisticsData
39 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.FlowsStatisticsUpdate
40 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.GetAllFlowsStatisticsFromAllFlowTablesInputBuilder
41 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.GetFlowStatisticsFromFlowTableInputBuilder
42 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.OpendaylightFlowStatisticsListener
43 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.OpendaylightFlowStatisticsService
44 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.flow.and.statistics.map.list.FlowAndStatisticsMapList
45 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.table.statistics.rev131215.FlowTableStatisticsData
46 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.table.statistics.rev131215.FlowTableStatisticsUpdate
47 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.table.statistics.rev131215.GetFlowTablesStatisticsInputBuilder
48 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.table.statistics.rev131215.OpendaylightFlowTableStatisticsListener
49 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.table.statistics.rev131215.OpendaylightFlowTableStatisticsService
50 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.table.statistics.rev131215.flow.table.statistics.FlowTableStatistics
51 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.topology.discovery.rev130819.FlowTopologyDiscoveryService
52 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.topology.discovery.rev130819.Link
53 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeConnectorId
54 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeConnectorRef
55 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeConnectorRemoved
56 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeConnectorUpdated
57 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeId
58 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeRef
59 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeRemoved
60 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeUpdated
61 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.Nodes
62 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.OpendaylightInventoryListener
63 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.node.NodeConnector
64 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.node.NodeConnectorKey
65 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.NodeKey
66 import org.opendaylight.yang.gen.v1.urn.opendaylight.port.statistics.rev131214.FlowCapableNodeConnectorStatistics
67 import org.opendaylight.yang.gen.v1.urn.opendaylight.port.statistics.rev131214.FlowCapableNodeConnectorStatisticsData
68 import org.opendaylight.yang.gen.v1.urn.opendaylight.port.statistics.rev131214.GetAllNodeConnectorsStatisticsInputBuilder
69 import org.opendaylight.yang.gen.v1.urn.opendaylight.port.statistics.rev131214.GetNodeConnectorStatisticsInputBuilder
70 import org.opendaylight.yang.gen.v1.urn.opendaylight.port.statistics.rev131214.NodeConnectorStatisticsUpdate
71 import org.opendaylight.yang.gen.v1.urn.opendaylight.port.statistics.rev131214.OpendaylightPortStatisticsListener
72 import org.opendaylight.yang.gen.v1.urn.opendaylight.port.statistics.rev131214.OpendaylightPortStatisticsService
73 import org.opendaylight.yangtools.yang.binding.DataObject
74 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier
75 import org.slf4j.LoggerFactory
77 import static extension org.opendaylight.controller.sal.common.util.Arguments.*
78 import static extension org.opendaylight.controller.sal.compatibility.NodeMapping.*
79 import org.opendaylight.controller.md.sal.binding.util.TypeSafeDataReader
80 import java.util.concurrent.ConcurrentHashMap
82 import java.util.HashMap
84 class InventoryAndReadAdapter implements IPluginInReadService,
85 IPluginInInventoryService,
86 OpendaylightInventoryListener,
87 OpendaylightFlowStatisticsListener,
88 OpendaylightFlowTableStatisticsListener,
89 OpendaylightPortStatisticsListener {
91 private static val LOG = LoggerFactory.getLogger(InventoryAndReadAdapter);
93 private static val OPENFLOWV10_TABLE_ID = new Integer(0).shortValue;
95 DataBrokerService dataService;
98 DataProviderService dataProviderService;
101 OpendaylightFlowStatisticsService flowStatisticsService;
104 OpendaylightPortStatisticsService nodeConnectorStatisticsService;
107 OpendaylightFlowTableStatisticsService flowTableStatisticsService;
110 FlowTopologyDiscoveryService topologyDiscovery;
113 List<IPluginOutReadService> statisticsPublisher = new CopyOnWriteArrayList<IPluginOutReadService>();
116 List<IPluginOutInventoryService> inventoryPublisher = new CopyOnWriteArrayList<IPluginOutInventoryService>();
118 private final InventoryNotificationProvider inventoryNotificationProvider = new InventoryNotificationProvider();
120 private final Map<InstanceIdentifier.PathArgument, List<InstanceIdentifier.PathArgument>> nodeToNodeConnectorsMap = new ConcurrentHashMap<InstanceIdentifier.PathArgument, List<InstanceIdentifier.PathArgument>>();
122 private final Lock nodeToNodeConnectorsLock = new ReentrantLock();
126 inventoryNotificationProvider.dataProviderService = dataProviderService;
127 inventoryNotificationProvider.inventoryPublisher = inventoryPublisher;
128 // inventoryNotificationProvider.start();
131 def setInventoryPublisher(IPluginOutInventoryService listener){
132 inventoryPublisher.add(listener);
135 def unsetInventoryPublisher(IPluginOutInventoryService listener){
136 inventoryPublisher.remove(listener);
139 def setReadPublisher(IPluginOutReadService listener) {
140 statisticsPublisher.add(listener);
143 def unsetReadPublisher (IPluginOutReadService listener) {
144 if( listener != null)
145 statisticsPublisher.remove(listener);
148 protected def startChange() {
149 return dataProviderService.beginTransaction;
152 override getTransmitRate(org.opendaylight.controller.sal.core.NodeConnector connector) {
153 val nodeConnector = readFlowCapableNodeConnector(connector.toNodeConnectorRef);
154 return nodeConnector.currentSpeed
157 override readAllFlow(Node node, boolean cached) {
159 val output = new ArrayList<FlowOnNode>();
160 val tableRef = InstanceIdentifier.builder(Nodes)
161 .child(org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node, InventoryMapping.toNodeKey(node))
162 .augmentation(FlowCapableNode).child(Table, new TableKey(OPENFLOWV10_TABLE_ID)).toInstance();
164 val it = this.startChange();
166 val table= it.readConfigurationData(tableRef) as Table;
169 LOG.trace("Number of flows installed in table 0 of node {} : {}",node,table.flow.size);
171 for(flow : table.flow){
173 val adsalFlow = ToSalConversionsUtils.toFlow(flow,node);
174 val statsFromDataStore = flow.getAugmentation(FlowStatisticsData);
176 if(statsFromDataStore != null){
177 val it = new FlowOnNode(adsalFlow);
178 byteCount = statsFromDataStore.flowStatistics.byteCount.value.longValue;
179 packetCount = statsFromDataStore.flowStatistics.packetCount.value.longValue;
180 durationSeconds = statsFromDataStore.flowStatistics.duration.second.value.intValue;
181 durationNanoseconds = statsFromDataStore.flowStatistics.duration.nanosecond.value.intValue;
188 //TODO (main): Shell we send request to the switch? It will make async request to the switch.
189 // Once plugin receive response, it will let adaptor know through onFlowStatisticsUpdate()
190 // If we assume that md-sal statistics manager will always be running, then its not required
191 // But if not, then sending request will collect the latest data for adaptor atleast.
192 val input = new GetAllFlowsStatisticsFromAllFlowTablesInputBuilder;
193 input.setNode(node.toNodeRef);
194 flowStatisticsService.getAllFlowsStatisticsFromAllFlowTables(input.build)
199 override readAllNodeConnector(Node node, boolean cached) {
201 val ret = new ArrayList<NodeConnectorStatistics>();
202 val nodeRef = InstanceIdentifier.builder(Nodes)
203 .child(org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node, InventoryMapping.toNodeKey(node))
206 val provider = this.startChange();
208 val dsNode= provider.readConfigurationData(nodeRef) as org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node;
212 for (dsNodeConnector : dsNode.nodeConnector){
213 val nodeConnectorRef = InstanceIdentifier.builder(Nodes)
214 .child(org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node, InventoryMapping.toNodeKey(node))
215 .child(NodeConnector, dsNodeConnector.key)
218 val nodeConnectorFromDS = provider.readConfigurationData(nodeConnectorRef) as NodeConnector;
220 if(nodeConnectorFromDS != null){
221 val nodeConnectorStatsFromDs = nodeConnectorFromDS.getAugmentation(FlowCapableNodeConnectorStatisticsData) as FlowCapableNodeConnectorStatistics;
223 ret.add(toNodeConnectorStatistics(nodeConnectorStatsFromDs.flowCapableNodeConnectorStatistics,dsNode.id,dsNodeConnector.id));
228 //TODO: Refer TODO (main)
229 val input = new GetAllNodeConnectorsStatisticsInputBuilder();
230 input.setNode(node.toNodeRef);
231 nodeConnectorStatisticsService.getAllNodeConnectorsStatistics(input.build());
235 override readAllNodeTable(Node node, boolean cached) {
236 val ret = new ArrayList<NodeTableStatistics>();
238 val dsFlowCapableNode= readFlowCapableNode(node.toNodeRef)
240 if(dsFlowCapableNode != null){
242 for (table : dsFlowCapableNode.table){
244 val tableStats = table.getAugmentation(FlowTableStatisticsData);
246 if(tableStats != null){
247 ret.add(toNodeTableStatistics(tableStats.flowTableStatistics,table.id,node));
252 //TODO: Refer TODO (main)
253 val input = new GetFlowTablesStatisticsInputBuilder();
254 input.setNode(node.toNodeRef);
255 flowTableStatisticsService.getFlowTablesStatistics(input.build);
259 override readDescription(Node node, boolean cached) {
260 return toNodeDescription(node.toNodeRef);
263 override readFlow(Node node, Flow targetFlow, boolean cached) {
264 var FlowOnNode ret= null;
266 val tableRef = InstanceIdentifier.builder(Nodes)
267 .child(org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node, InventoryMapping.toNodeKey(node))
268 .augmentation(FlowCapableNode).child(Table, new TableKey(OPENFLOWV10_TABLE_ID)).toInstance();
270 val it = this.startChange();
272 val table= it.readConfigurationData(tableRef) as Table;
275 LOG.trace("Number of flows installed in table 0 of node {} : {}",node,table.flow.size);
277 for(mdsalFlow : table.flow){
278 if(FromSalConversionsUtils.flowEquals(mdsalFlow, MDFlowMapping.toMDSalflow(targetFlow))){
279 val statsFromDataStore = mdsalFlow.getAugmentation(FlowStatisticsData);
281 if(statsFromDataStore != null){
282 LOG.debug("Found matching flow in the data store flow table ");
283 val it = new FlowOnNode(targetFlow);
284 byteCount = statsFromDataStore.flowStatistics.byteCount.value.longValue;
285 packetCount = statsFromDataStore.flowStatistics.packetCount.value.longValue;
286 durationSeconds = statsFromDataStore.flowStatistics.duration.second.value.intValue;
287 durationNanoseconds = statsFromDataStore.flowStatistics.duration.nanosecond.value.intValue;
295 //TODO: Refer TODO (main)
296 val input = new GetFlowStatisticsFromFlowTableInputBuilder;
297 input.setNode(node.toNodeRef);
298 input.fieldsFrom(MDFlowMapping.toMDSalflow(targetFlow));
299 flowStatisticsService.getFlowStatisticsFromFlowTable(input.build)
305 override readNodeConnector(org.opendaylight.controller.sal.core.NodeConnector connector, boolean cached) {
306 var NodeConnectorStatistics nodeConnectorStatistics = null;
308 val nodeConnectorRef = InstanceIdentifier.builder(Nodes)
309 .child(org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node, InventoryMapping.toNodeKey(connector.node))
310 .child(NodeConnector, InventoryMapping.toNodeConnectorKey(connector))
312 val provider = this.startChange();
314 val nodeConnectorFromDS = provider.readConfigurationData(nodeConnectorRef) as NodeConnector;
316 if(nodeConnectorFromDS != null){
317 val nodeConnectorStatsFromDs = nodeConnectorFromDS.getAugmentation(FlowCapableNodeConnectorStatisticsData) as FlowCapableNodeConnectorStatistics;
318 if(nodeConnectorStatsFromDs != null) {
319 nodeConnectorStatistics = toNodeConnectorStatistics(nodeConnectorStatsFromDs.flowCapableNodeConnectorStatistics,
320 InventoryMapping.toNodeKey(connector.node).id,
321 InventoryMapping.toNodeConnectorKey(connector).id);
325 //TODO: Refer TODO (main)
326 val input = new GetNodeConnectorStatisticsInputBuilder();
327 input.setNode(connector.node.toNodeRef);
328 input.setNodeConnectorId(InventoryMapping.toNodeConnectorKey(connector).id);
329 nodeConnectorStatisticsService.getNodeConnectorStatistics(input.build());
330 return nodeConnectorStatistics;
333 override readNodeTable(NodeTable nodeTable, boolean cached) {
334 var NodeTableStatistics nodeStats = null
336 val tableRef = InstanceIdentifier.builder(Nodes)
337 .child(org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node, InventoryMapping.toNodeKey(nodeTable.node))
338 .augmentation(FlowCapableNode).child(Table, new TableKey(nodeTable.ID as Short)).toInstance();
340 val it = this.startChange();
342 val table= it.readConfigurationData(tableRef) as Table;
345 val tableStats = table.getAugmentation(FlowTableStatisticsData);
347 if(tableStats != null){
348 nodeStats = toNodeTableStatistics(tableStats.flowTableStatistics,table.id,nodeTable.node);
352 //TODO: Refer TODO (main)
353 val input = new GetFlowTablesStatisticsInputBuilder();
354 input.setNode(nodeTable.node.toNodeRef);
355 flowTableStatisticsService.getFlowTablesStatistics(input.build);
360 override onNodeConnectorRemoved(NodeConnectorRemoved update) {
364 override onNodeRemoved(NodeRemoved notification) {
365 val properties = Collections.<org.opendaylight.controller.sal.core.Property>emptySet();
367 removeNodeConnectors(notification.nodeRef.value);
369 publishNodeUpdate(notification.nodeRef.toADNode, UpdateType.REMOVED, properties);
372 override onNodeConnectorUpdated(NodeConnectorUpdated update) {
373 var updateType = UpdateType.CHANGED;
374 if(!isKnownNodeConnector(update.nodeConnectorRef.value)){
375 updateType = UpdateType.ADDED;
376 recordNodeConnector(update.nodeConnectorRef.value);
379 var nodeConnector = update.nodeConnectorRef.toADNodeConnector
381 publishNodeConnectorUpdate(nodeConnector , updateType , update.toADNodeConnectorProperties);
384 override onNodeUpdated(NodeUpdated notification) {
385 val InstanceIdentifier<? extends DataObject> identifier = notification.nodeRef.value as InstanceIdentifier<? extends DataObject>;
387 var updateType = UpdateType.CHANGED;
388 if ( this._dataService.readOperationalData(identifier) == null ){
389 updateType = UpdateType.ADDED;
391 publishNodeUpdate(notification.nodeRef.toADNode, updateType, notification.toADNodeProperties);
393 //Notify the listeners of IPluginOutReadService
395 for (statsPublisher : statisticsPublisher){
396 val nodeRef = InstanceIdentifier.builder(Nodes).child(org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node,new NodeKey(notification.id)).toInstance;
397 val description = notification.nodeRef.toNodeDescription
398 if(description != null) {
399 statsPublisher.descriptionStatisticsUpdated(nodeRef.toADNode,description);
404 override getNodeProps() {
405 val props = new ConcurrentHashMap<Node, Map<String, org.opendaylight.controller.sal.core.Property>>()
407 val nodes = readAllMDNodes()
408 for (node : nodes.node ) {
409 val fcn = node.getAugmentation(FlowCapableNode)
411 val perNodeProps = fcn.toADNodeProperties(node.id)
412 val perNodePropMap = new ConcurrentHashMap<String, org.opendaylight.controller.sal.core.Property>
413 if(perNodeProps != null ) {
414 for(perNodeProp : perNodeProps) {
415 perNodePropMap.put(perNodeProp.name,perNodeProp)
418 props.put(new Node(MD_SAL_TYPE, node.id.toADNodeId),perNodePropMap)
424 private def readAllMDNodes() {
425 val nodesRef = InstanceIdentifier.builder(Nodes)
427 val reader = TypeSafeDataReader.forReader(dataService)
428 return reader.readOperationalData(nodesRef)
431 private def readAllMDNodeConnectors(org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node node) {
432 val nodeRef = InstanceIdentifier.builder(Nodes)
433 .child(org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node,new NodeKey(node.id))
435 val reader = TypeSafeDataReader.forReader(dataService)
436 return reader.readOperationalData(nodeRef).nodeConnector
439 override getNodeConnectorProps(Boolean refresh) {
440 // Note, because the MD-SAL has a unified data store, we can ignore the Boolean refresh, as we have no secondary
441 // data store to refresh from
442 val props = new ConcurrentHashMap<org.opendaylight.controller.sal.core.NodeConnector, Map<String, org.opendaylight.controller.sal.core.Property>>()
443 val nodes = readAllMDNodes()
444 for (node : nodes.node) {
445 val ncs = node.readAllMDNodeConnectors
448 val fcnc = nc.getAugmentation(FlowCapableNodeConnector)
450 val ncps = fcnc.toADNodeConnectorProperties
451 val ncpsm = new ConcurrentHashMap<String, org.opendaylight.controller.sal.core.Property>
457 props.put(nc.id.toADNodeConnector(node.id),ncpsm)
465 private def FlowCapableNode readFlowCapableNode(NodeRef ref) {
466 val dataObject = dataService.readOperationalData(ref.value as InstanceIdentifier<? extends DataObject>);
467 if(dataObject != null) {
468 val node = dataObject.checkInstanceOf(
469 org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node);
470 return node.getAugmentation(FlowCapableNode);
475 private def FlowCapableNodeConnector readFlowCapableNodeConnector(NodeConnectorRef ref) {
476 val dataObject = dataService.readOperationalData(ref.value as InstanceIdentifier<? extends DataObject>);
477 val node = dataObject.checkInstanceOf(
479 return node.getAugmentation(FlowCapableNodeConnector);
482 private def toNodeConnectorStatistics(
483 org.opendaylight.yang.gen.v1.urn.opendaylight.model.statistics.types.rev130925.NodeConnectorStatistics nodeConnectorStatistics, NodeId nodeId, NodeConnectorId nodeConnectorId) {
485 val it = new NodeConnectorStatistics();
487 receivePacketCount = nodeConnectorStatistics.packets.received.longValue;
488 transmitPacketCount = nodeConnectorStatistics.packets.transmitted.longValue;
490 receiveByteCount = nodeConnectorStatistics.bytes.received.longValue;
491 transmitByteCount = nodeConnectorStatistics.bytes.transmitted.longValue;
493 receiveDropCount = nodeConnectorStatistics.receiveDrops.longValue;
494 transmitDropCount = nodeConnectorStatistics.transmitDrops.longValue;
496 receiveErrorCount = nodeConnectorStatistics.receiveErrors.longValue;
497 transmitErrorCount = nodeConnectorStatistics.transmitErrors.longValue;
499 receiveFrameErrorCount = nodeConnectorStatistics.receiveFrameError.longValue;
500 receiveOverRunErrorCount = nodeConnectorStatistics.receiveOverRunError.longValue;
501 receiveCRCErrorCount = nodeConnectorStatistics.receiveCrcError.longValue;
502 collisionCount = nodeConnectorStatistics.collisionCount.longValue;
504 val nodeConnectorRef = InstanceIdentifier.builder(Nodes)
505 .child(org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node,new NodeKey(nodeId))
506 .child(NodeConnector,new NodeConnectorKey(nodeConnectorId)).toInstance;
508 nodeConnector = NodeMapping.toADNodeConnector(new NodeConnectorRef(nodeConnectorRef));
513 private def toNodeTableStatistics(
514 FlowTableStatistics tableStats,
515 Short tableId,Node node){
516 var it = new NodeTableStatistics();
518 activeCount = tableStats.activeFlows.value.intValue;
519 lookupCount = tableStats.packetsLookedUp.value.intValue;
520 matchedCount = tableStats.packetsMatched.value.intValue;
521 name = tableId.toString;
522 nodeTable = new NodeTable(NodeMapping.MD_SAL_TYPE,tableId,node);
526 private def toNodeDescription(NodeRef nodeRef){
527 val capableNode = readFlowCapableNode(nodeRef);
528 if(capableNode !=null) {
529 val it = new NodeDescription()
530 manufacturer = capableNode.manufacturer
531 serialNumber = capableNode.serialNumber
532 software = capableNode.software
533 description = capableNode.description
541 def Edge toADEdge(Link link) {
542 new Edge(link.source.toADNodeConnector,link.destination.toADNodeConnector)
546 * OpendaylightFlowStatisticsListener interface implementation
548 override onAggregateFlowStatisticsUpdate(AggregateFlowStatisticsUpdate notification) {
549 //Ignoring this notification as there does not seem to be a way to bubble this up to AD-SAL
552 override onFlowsStatisticsUpdate(FlowsStatisticsUpdate notification) {
554 val adsalFlowsStatistics = new ArrayList<FlowOnNode>();
555 val nodeRef = InstanceIdentifier.builder(Nodes).child(org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node,new NodeKey(notification.id)).toInstance;
557 for(flowStats : notification.flowAndStatisticsMapList){
558 if(flowStats.tableId == 0)
559 adsalFlowsStatistics.add(toFlowOnNode(flowStats,nodeRef.toADNode));
562 for (statsPublisher : statisticsPublisher){
563 statsPublisher.nodeFlowStatisticsUpdated(nodeRef.toADNode,adsalFlowsStatistics);
568 * OpendaylightFlowTableStatisticsListener interface implementation
570 override onFlowTableStatisticsUpdate(FlowTableStatisticsUpdate notification) {
571 var adsalFlowTableStatistics = new ArrayList<NodeTableStatistics>();
573 for(stats : notification.flowTableAndStatisticsMap){
574 if (stats.tableId.value == 0){
575 val it = new NodeTableStatistics();
576 activeCount = stats.activeFlows.value.intValue;
577 lookupCount = stats.packetsLookedUp.value.longValue;
578 matchedCount = stats.packetsMatched.value.longValue;
580 adsalFlowTableStatistics.add(it);
583 for (statsPublisher : statisticsPublisher){
584 val nodeRef = InstanceIdentifier.builder(Nodes).child(org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node,new NodeKey(notification.id)).toInstance;
585 statsPublisher.nodeTableStatisticsUpdated(nodeRef.toADNode,adsalFlowTableStatistics);
590 * OpendaylightPortStatisticsUpdate interface implementation
592 override onNodeConnectorStatisticsUpdate(NodeConnectorStatisticsUpdate notification) {
594 val adsalPortStatistics = new ArrayList<NodeConnectorStatistics>();
596 for(nodeConnectorStatistics : notification.nodeConnectorStatisticsAndPortNumberMap){
597 adsalPortStatistics.add(toNodeConnectorStatistics(nodeConnectorStatistics,notification.id,nodeConnectorStatistics.nodeConnectorId));
600 for (statsPublisher : statisticsPublisher){
601 val nodeRef = InstanceIdentifier.builder(Nodes).child(org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node,new NodeKey(notification.id)).toInstance;
602 statsPublisher.nodeConnectorStatisticsUpdated(nodeRef.toADNode,adsalPortStatistics);
607 private static def toFlowOnNode (FlowAndStatisticsMapList flowAndStatsMap,Node node){
609 val it = new FlowOnNode(ToSalConversionsUtils.toFlow(flowAndStatsMap,node));
611 byteCount = flowAndStatsMap.byteCount.value.longValue;
612 packetCount = flowAndStatsMap.packetCount.value.longValue;
613 durationSeconds = flowAndStatsMap.duration.second.value.intValue;
614 durationNanoseconds = flowAndStatsMap.duration.nanosecond.value.intValue;
619 override getConfiguredNotConnectedNodes() {
620 return Collections.emptySet();
624 private def publishNodeUpdate(Node node, UpdateType updateType, Set<org.opendaylight.controller.sal.core.Property> properties){
625 for( publisher : inventoryPublisher){
626 publisher.updateNode(node, updateType, properties);
630 private def publishNodeConnectorUpdate(org.opendaylight.controller.sal.core.NodeConnector nodeConnector, UpdateType updateType, Set<org.opendaylight.controller.sal.core.Property> properties){
631 for( publisher : inventoryPublisher){
632 publisher.updateNodeConnector(nodeConnector, updateType, properties);
636 private def isKnownNodeConnector(InstanceIdentifier<? extends Object> nodeConnectorIdentifier){
637 if(nodeConnectorIdentifier.path.size() < 3) {
641 val nodePath = nodeConnectorIdentifier.path.get(1);
642 val nodeConnectorPath = nodeConnectorIdentifier.getPath().get(2);
644 val nodeConnectors = nodeToNodeConnectorsMap.get(nodePath);
646 if(nodeConnectors == null){
649 return nodeConnectors.contains(nodeConnectorPath);
653 private def recordNodeConnector(InstanceIdentifier<? extends Object> nodeConnectorIdentifier){
654 if(nodeConnectorIdentifier.path.size() < 3) {
658 val nodePath = nodeConnectorIdentifier.path.get(1);
659 val nodeConnectorPath = nodeConnectorIdentifier.getPath().get(2);
661 nodeToNodeConnectorsLock.lock();
664 var nodeConnectors = nodeToNodeConnectorsMap.get(nodePath);
666 if(nodeConnectors == null){
667 nodeConnectors = new ArrayList<InstanceIdentifier.PathArgument>();
668 nodeToNodeConnectorsMap.put(nodePath, nodeConnectors);
671 nodeConnectors.add(nodeConnectorPath);
673 nodeToNodeConnectorsLock.unlock();
677 private def removeNodeConnectors(InstanceIdentifier<? extends Object> nodeIdentifier){
678 val nodePath = nodeIdentifier.path.get(1);
680 nodeToNodeConnectorsMap.remove(nodePath);