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();
134 def setInventoryPublisher(IPluginOutInventoryService listener){
135 inventoryPublisher.add(listener);
138 def unsetInventoryPublisher(IPluginOutInventoryService listener){
139 inventoryPublisher.remove(listener);
142 def setReadPublisher(IPluginOutReadService listener) {
143 statisticsPublisher.add(listener);
146 def unsetReadPublisher (IPluginOutReadService listener) {
147 if( listener != null)
148 statisticsPublisher.remove(listener);
151 protected def startChange() {
152 return dataProviderService.beginTransaction;
155 override getTransmitRate(org.opendaylight.controller.sal.core.NodeConnector connector) {
156 val nodeConnector = readFlowCapableNodeConnector(connector.toNodeConnectorRef);
157 return nodeConnector.currentSpeed
160 override readAllFlow(Node node, boolean cached) {
162 val output = new ArrayList<FlowOnNode>();
163 val tableRef = InstanceIdentifier.builder(Nodes)
164 .child(org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node, InventoryMapping.toNodeKey(node))
165 .augmentation(FlowCapableNode).child(Table, new TableKey(OPENFLOWV10_TABLE_ID)).toInstance();
167 val it = this.startChange();
169 val table= it.readConfigurationData(tableRef) as Table;
172 LOG.trace("Number of flows installed in table 0 of node {} : {}",node,table.flow.size);
174 for(flow : table.flow){
176 val adsalFlow = ToSalConversionsUtils.toFlow(flow,node);
177 val statsFromDataStore = flow.getAugmentation(FlowStatisticsData);
179 if(statsFromDataStore != null){
180 val it = new FlowOnNode(adsalFlow);
181 byteCount = statsFromDataStore.flowStatistics.byteCount.value.longValue;
182 packetCount = statsFromDataStore.flowStatistics.packetCount.value.longValue;
183 durationSeconds = statsFromDataStore.flowStatistics.duration.second.value.intValue;
184 durationNanoseconds = statsFromDataStore.flowStatistics.duration.nanosecond.value.intValue;
191 //TODO (main): Shell we send request to the switch? It will make async request to the switch.
192 // Once plugin receive response, it will let adaptor know through onFlowStatisticsUpdate()
193 // If we assume that md-sal statistics manager will always be running, then its not required
194 // But if not, then sending request will collect the latest data for adaptor atleast.
195 val input = new GetAllFlowsStatisticsFromAllFlowTablesInputBuilder;
196 input.setNode(node.toNodeRef);
197 flowStatisticsService.getAllFlowsStatisticsFromAllFlowTables(input.build)
202 override readAllNodeConnector(Node node, boolean cached) {
204 val ret = new ArrayList<NodeConnectorStatistics>();
205 val nodeRef = InstanceIdentifier.builder(Nodes)
206 .child(org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node, InventoryMapping.toNodeKey(node))
209 val provider = this.startChange();
211 val dsNode= provider.readConfigurationData(nodeRef) as org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node;
215 for (dsNodeConnector : dsNode.nodeConnector){
216 val nodeConnectorRef = InstanceIdentifier.builder(Nodes)
217 .child(org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node, InventoryMapping.toNodeKey(node))
218 .child(NodeConnector, dsNodeConnector.key)
221 val nodeConnectorFromDS = provider.readConfigurationData(nodeConnectorRef) as NodeConnector;
223 if(nodeConnectorFromDS != null){
224 val nodeConnectorStatsFromDs = nodeConnectorFromDS.getAugmentation(FlowCapableNodeConnectorStatisticsData) as FlowCapableNodeConnectorStatistics;
226 ret.add(toNodeConnectorStatistics(nodeConnectorStatsFromDs.flowCapableNodeConnectorStatistics,dsNode.id,dsNodeConnector.id));
231 //TODO: Refer TODO (main)
232 val input = new GetAllNodeConnectorsStatisticsInputBuilder();
233 input.setNode(node.toNodeRef);
234 nodeConnectorStatisticsService.getAllNodeConnectorsStatistics(input.build());
238 override readAllNodeTable(Node node, boolean cached) {
239 val ret = new ArrayList<NodeTableStatistics>();
241 val dsFlowCapableNode= readFlowCapableNode(node.toNodeRef)
243 if(dsFlowCapableNode != null){
245 for (table : dsFlowCapableNode.table){
247 val tableStats = table.getAugmentation(FlowTableStatisticsData);
249 if(tableStats != null){
250 ret.add(toNodeTableStatistics(tableStats.flowTableStatistics,table.id,node));
255 //TODO: Refer TODO (main)
256 val input = new GetFlowTablesStatisticsInputBuilder();
257 input.setNode(node.toNodeRef);
258 flowTableStatisticsService.getFlowTablesStatistics(input.build);
262 override readDescription(Node node, boolean cached) {
263 return toNodeDescription(node.toNodeRef);
266 override readFlow(Node node, Flow targetFlow, boolean cached) {
267 var FlowOnNode ret= null;
269 val tableRef = InstanceIdentifier.builder(Nodes)
270 .child(org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node, InventoryMapping.toNodeKey(node))
271 .augmentation(FlowCapableNode).child(Table, new TableKey(OPENFLOWV10_TABLE_ID)).toInstance();
273 val it = this.startChange();
275 val table= it.readConfigurationData(tableRef) as Table;
278 LOG.trace("Number of flows installed in table 0 of node {} : {}",node,table.flow.size);
280 for(mdsalFlow : table.flow){
281 if(FromSalConversionsUtils.flowEquals(mdsalFlow, MDFlowMapping.toMDSalflow(targetFlow))){
282 val statsFromDataStore = mdsalFlow.getAugmentation(FlowStatisticsData);
284 if(statsFromDataStore != null){
285 LOG.debug("Found matching flow in the data store flow table ");
286 val it = new FlowOnNode(targetFlow);
287 byteCount = statsFromDataStore.flowStatistics.byteCount.value.longValue;
288 packetCount = statsFromDataStore.flowStatistics.packetCount.value.longValue;
289 durationSeconds = statsFromDataStore.flowStatistics.duration.second.value.intValue;
290 durationNanoseconds = statsFromDataStore.flowStatistics.duration.nanosecond.value.intValue;
298 //TODO: Refer TODO (main)
299 val input = new GetFlowStatisticsFromFlowTableInputBuilder;
300 input.setNode(node.toNodeRef);
301 input.fieldsFrom(MDFlowMapping.toMDSalflow(targetFlow));
302 flowStatisticsService.getFlowStatisticsFromFlowTable(input.build)
308 override readNodeConnector(org.opendaylight.controller.sal.core.NodeConnector connector, boolean cached) {
309 var NodeConnectorStatistics nodeConnectorStatistics = null;
311 val nodeConnectorRef = InstanceIdentifier.builder(Nodes)
312 .child(org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node, InventoryMapping.toNodeKey(connector.node))
313 .child(NodeConnector, InventoryMapping.toNodeConnectorKey(connector))
315 val provider = this.startChange();
317 val nodeConnectorFromDS = provider.readConfigurationData(nodeConnectorRef) as NodeConnector;
319 if(nodeConnectorFromDS != null){
320 val nodeConnectorStatsFromDs = nodeConnectorFromDS.getAugmentation(FlowCapableNodeConnectorStatisticsData) as FlowCapableNodeConnectorStatistics;
321 if(nodeConnectorStatsFromDs != null) {
322 nodeConnectorStatistics = toNodeConnectorStatistics(nodeConnectorStatsFromDs.flowCapableNodeConnectorStatistics,
323 InventoryMapping.toNodeKey(connector.node).id,
324 InventoryMapping.toNodeConnectorKey(connector).id);
328 //TODO: Refer TODO (main)
329 val input = new GetNodeConnectorStatisticsInputBuilder();
330 input.setNode(connector.node.toNodeRef);
331 input.setNodeConnectorId(InventoryMapping.toNodeConnectorKey(connector).id);
332 nodeConnectorStatisticsService.getNodeConnectorStatistics(input.build());
333 return nodeConnectorStatistics;
336 override readNodeTable(NodeTable nodeTable, boolean cached) {
337 var NodeTableStatistics nodeStats = null
339 val tableRef = InstanceIdentifier.builder(Nodes)
340 .child(org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node, InventoryMapping.toNodeKey(nodeTable.node))
341 .augmentation(FlowCapableNode).child(Table, new TableKey(nodeTable.ID as Short)).toInstance();
343 val it = this.startChange();
345 val table= it.readConfigurationData(tableRef) as Table;
348 val tableStats = table.getAugmentation(FlowTableStatisticsData);
350 if(tableStats != null){
351 nodeStats = toNodeTableStatistics(tableStats.flowTableStatistics,table.id,nodeTable.node);
355 //TODO: Refer TODO (main)
356 val input = new GetFlowTablesStatisticsInputBuilder();
357 input.setNode(nodeTable.node.toNodeRef);
358 flowTableStatisticsService.getFlowTablesStatistics(input.build);
363 override onNodeConnectorRemoved(NodeConnectorRemoved update) {
367 override onNodeRemoved(NodeRemoved notification) {
368 val properties = Collections.<org.opendaylight.controller.sal.core.Property>emptySet();
370 removeNodeConnectors(notification.nodeRef.value);
372 publishNodeUpdate(notification.nodeRef.toADNode, UpdateType.REMOVED, properties);
375 override onNodeConnectorUpdated(NodeConnectorUpdated update) {
376 var updateType = UpdateType.CHANGED;
377 if(!isKnownNodeConnector(update.nodeConnectorRef.value)){
378 updateType = UpdateType.ADDED;
379 recordNodeConnector(update.nodeConnectorRef.value);
382 var nodeConnector = update.nodeConnectorRef.toADNodeConnector
384 publishNodeConnectorUpdate(nodeConnector , updateType , update.toADNodeConnectorProperties);
387 override onNodeUpdated(NodeUpdated notification) {
388 val InstanceIdentifier<? extends DataObject> identifier = notification.nodeRef.value as InstanceIdentifier<? extends DataObject>;
390 var updateType = UpdateType.CHANGED;
391 if ( this._dataService.readOperationalData(identifier) == null ){
392 updateType = UpdateType.ADDED;
394 publishNodeUpdate(notification.nodeRef.toADNode, updateType, notification.toADNodeProperties);
396 //Notify the listeners of IPluginOutReadService
398 for (statsPublisher : statisticsPublisher){
399 val nodeRef = InstanceIdentifier.builder(Nodes).child(org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node,new NodeKey(notification.id)).toInstance;
400 val description = notification.nodeRef.toNodeDescription
401 if(description != null) {
402 statsPublisher.descriptionStatisticsUpdated(nodeRef.toADNode,description);
407 override getNodeProps() {
408 val props = new ConcurrentHashMap<Node, Map<String, org.opendaylight.controller.sal.core.Property>>()
410 val nodes = readAllMDNodes()
411 for (node : nodes.node ) {
412 val fcn = node.getAugmentation(FlowCapableNode)
414 val perNodeProps = fcn.toADNodeProperties(node.id)
415 val perNodePropMap = new ConcurrentHashMap<String, org.opendaylight.controller.sal.core.Property>
416 if(perNodeProps != null ) {
417 for(perNodeProp : perNodeProps) {
418 perNodePropMap.put(perNodeProp.name,perNodeProp)
421 props.put(new Node(MD_SAL_TYPE, node.id.toADNodeId),perNodePropMap)
427 private def readAllMDNodes() {
428 val nodesRef = InstanceIdentifier.builder(Nodes)
430 val reader = TypeSafeDataReader.forReader(dataService)
431 return reader.readOperationalData(nodesRef)
434 private def readAllMDNodeConnectors(org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node node) {
435 val nodeRef = InstanceIdentifier.builder(Nodes)
436 .child(org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node,new NodeKey(node.id))
438 val reader = TypeSafeDataReader.forReader(dataService)
439 return reader.readOperationalData(nodeRef).nodeConnector
442 override getNodeConnectorProps(Boolean refresh) {
443 // Note, because the MD-SAL has a unified data store, we can ignore the Boolean refresh, as we have no secondary
444 // data store to refresh from
445 val props = new ConcurrentHashMap<org.opendaylight.controller.sal.core.NodeConnector, Map<String, org.opendaylight.controller.sal.core.Property>>()
446 val nodes = readAllMDNodes()
447 for (node : nodes.node) {
448 val ncs = node.readAllMDNodeConnectors
451 val fcnc = nc.getAugmentation(FlowCapableNodeConnector)
453 val ncps = fcnc.toADNodeConnectorProperties
454 val ncpsm = new ConcurrentHashMap<String, org.opendaylight.controller.sal.core.Property>
460 props.put(nc.id.toADNodeConnector(node.id),ncpsm)
468 private def FlowCapableNode readFlowCapableNode(NodeRef ref) {
469 val dataObject = dataService.readOperationalData(ref.value as InstanceIdentifier<? extends DataObject>);
470 if(dataObject != null) {
471 val node = dataObject.checkInstanceOf(
472 org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node);
473 return node.getAugmentation(FlowCapableNode);
478 private def FlowCapableNodeConnector readFlowCapableNodeConnector(NodeConnectorRef ref) {
479 val dataObject = dataService.readOperationalData(ref.value as InstanceIdentifier<? extends DataObject>);
480 val node = dataObject.checkInstanceOf(
482 return node.getAugmentation(FlowCapableNodeConnector);
485 private def toNodeConnectorStatistics(
486 org.opendaylight.yang.gen.v1.urn.opendaylight.model.statistics.types.rev130925.NodeConnectorStatistics nodeConnectorStatistics, NodeId nodeId, NodeConnectorId nodeConnectorId) {
488 val it = new NodeConnectorStatistics();
490 receivePacketCount = nodeConnectorStatistics.packets.received.longValue;
491 transmitPacketCount = nodeConnectorStatistics.packets.transmitted.longValue;
493 receiveByteCount = nodeConnectorStatistics.bytes.received.longValue;
494 transmitByteCount = nodeConnectorStatistics.bytes.transmitted.longValue;
496 receiveDropCount = nodeConnectorStatistics.receiveDrops.longValue;
497 transmitDropCount = nodeConnectorStatistics.transmitDrops.longValue;
499 receiveErrorCount = nodeConnectorStatistics.receiveErrors.longValue;
500 transmitErrorCount = nodeConnectorStatistics.transmitErrors.longValue;
502 receiveFrameErrorCount = nodeConnectorStatistics.receiveFrameError.longValue;
503 receiveOverRunErrorCount = nodeConnectorStatistics.receiveOverRunError.longValue;
504 receiveCRCErrorCount = nodeConnectorStatistics.receiveCrcError.longValue;
505 collisionCount = nodeConnectorStatistics.collisionCount.longValue;
507 val nodeConnectorRef = InstanceIdentifier.builder(Nodes)
508 .child(org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node,new NodeKey(nodeId))
509 .child(NodeConnector,new NodeConnectorKey(nodeConnectorId)).toInstance;
511 nodeConnector = NodeMapping.toADNodeConnector(new NodeConnectorRef(nodeConnectorRef));
516 private def toNodeTableStatistics(
517 FlowTableStatistics tableStats,
518 Short tableId,Node node){
519 var it = new NodeTableStatistics();
521 activeCount = tableStats.activeFlows.value.intValue;
522 lookupCount = tableStats.packetsLookedUp.value.intValue;
523 matchedCount = tableStats.packetsMatched.value.intValue;
524 name = tableId.toString;
525 nodeTable = new NodeTable(NodeMapping.MD_SAL_TYPE,tableId,node);
529 private def toNodeDescription(NodeRef nodeRef){
530 val capableNode = readFlowCapableNode(nodeRef);
531 if(capableNode !=null) {
532 val it = new NodeDescription()
533 manufacturer = capableNode.manufacturer
534 serialNumber = capableNode.serialNumber
535 software = capableNode.software
536 description = capableNode.description
544 def Edge toADEdge(Link link) {
545 new Edge(link.source.toADNodeConnector,link.destination.toADNodeConnector)
549 * OpendaylightFlowStatisticsListener interface implementation
551 override onAggregateFlowStatisticsUpdate(AggregateFlowStatisticsUpdate notification) {
552 //Ignoring this notification as there does not seem to be a way to bubble this up to AD-SAL
555 override onFlowsStatisticsUpdate(FlowsStatisticsUpdate notification) {
557 val adsalFlowsStatistics = new ArrayList<FlowOnNode>();
558 val nodeRef = InstanceIdentifier.builder(Nodes).child(org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node,new NodeKey(notification.id)).toInstance;
560 for(flowStats : notification.flowAndStatisticsMapList){
561 if(flowStats.tableId == 0)
562 adsalFlowsStatistics.add(toFlowOnNode(flowStats,nodeRef.toADNode));
565 for (statsPublisher : statisticsPublisher){
566 statsPublisher.nodeFlowStatisticsUpdated(nodeRef.toADNode,adsalFlowsStatistics);
571 * OpendaylightFlowTableStatisticsListener interface implementation
573 override onFlowTableStatisticsUpdate(FlowTableStatisticsUpdate notification) {
574 var adsalFlowTableStatistics = new ArrayList<NodeTableStatistics>();
576 for(stats : notification.flowTableAndStatisticsMap){
577 if (stats.tableId.value == 0){
578 val it = new NodeTableStatistics();
579 activeCount = stats.activeFlows.value.intValue;
580 lookupCount = stats.packetsLookedUp.value.longValue;
581 matchedCount = stats.packetsMatched.value.longValue;
583 adsalFlowTableStatistics.add(it);
586 for (statsPublisher : statisticsPublisher){
587 val nodeRef = InstanceIdentifier.builder(Nodes).child(org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node,new NodeKey(notification.id)).toInstance;
588 statsPublisher.nodeTableStatisticsUpdated(nodeRef.toADNode,adsalFlowTableStatistics);
593 * OpendaylightPortStatisticsUpdate interface implementation
595 override onNodeConnectorStatisticsUpdate(NodeConnectorStatisticsUpdate notification) {
597 val adsalPortStatistics = new ArrayList<NodeConnectorStatistics>();
599 for(nodeConnectorStatistics : notification.nodeConnectorStatisticsAndPortNumberMap){
600 adsalPortStatistics.add(toNodeConnectorStatistics(nodeConnectorStatistics,notification.id,nodeConnectorStatistics.nodeConnectorId));
603 for (statsPublisher : statisticsPublisher){
604 val nodeRef = InstanceIdentifier.builder(Nodes).child(org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node,new NodeKey(notification.id)).toInstance;
605 statsPublisher.nodeConnectorStatisticsUpdated(nodeRef.toADNode,adsalPortStatistics);
610 private static def toFlowOnNode (FlowAndStatisticsMapList flowAndStatsMap,Node node){
612 val it = new FlowOnNode(ToSalConversionsUtils.toFlow(flowAndStatsMap,node));
614 byteCount = flowAndStatsMap.byteCount.value.longValue;
615 packetCount = flowAndStatsMap.packetCount.value.longValue;
616 durationSeconds = flowAndStatsMap.duration.second.value.intValue;
617 durationNanoseconds = flowAndStatsMap.duration.nanosecond.value.intValue;
622 override getConfiguredNotConnectedNodes() {
623 return Collections.emptySet();
627 private def publishNodeUpdate(Node node, UpdateType updateType, Set<org.opendaylight.controller.sal.core.Property> properties){
628 for( publisher : inventoryPublisher){
629 publisher.updateNode(node, updateType, properties);
633 private def publishNodeConnectorUpdate(org.opendaylight.controller.sal.core.NodeConnector nodeConnector, UpdateType updateType, Set<org.opendaylight.controller.sal.core.Property> properties){
634 for( publisher : inventoryPublisher){
635 publisher.updateNodeConnector(nodeConnector, updateType, properties);
639 private def isKnownNodeConnector(InstanceIdentifier<? extends Object> nodeConnectorIdentifier){
640 if(nodeConnectorIdentifier.path.size() < 3) {
644 val nodePath = nodeConnectorIdentifier.path.get(1);
645 val nodeConnectorPath = nodeConnectorIdentifier.getPath().get(2);
647 val nodeConnectors = nodeToNodeConnectorsMap.get(nodePath);
649 if(nodeConnectors == null){
652 return nodeConnectors.contains(nodeConnectorPath);
656 private def recordNodeConnector(InstanceIdentifier<? extends Object> nodeConnectorIdentifier){
657 if(nodeConnectorIdentifier.path.size() < 3) {
661 val nodePath = nodeConnectorIdentifier.path.get(1);
662 val nodeConnectorPath = nodeConnectorIdentifier.getPath().get(2);
664 nodeToNodeConnectorsLock.lock();
667 var nodeConnectors = nodeToNodeConnectorsMap.get(nodePath);
669 if(nodeConnectors == null){
670 nodeConnectors = new ArrayList<InstanceIdentifier.PathArgument>();
671 nodeToNodeConnectorsMap.put(nodePath, nodeConnectors);
674 nodeConnectors.add(nodeConnectorPath);
676 nodeToNodeConnectorsLock.unlock();
680 private def removeNodeConnectors(InstanceIdentifier<? extends Object> nodeIdentifier){
681 val nodePath = nodeIdentifier.path.get(1);
683 nodeToNodeConnectorsMap.remove(nodePath);