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 com.google.common.collect.Iterables;
12 import java.util.ArrayList;
13 import java.util.Collections;
14 import java.util.HashSet;
15 import java.util.Iterator;
16 import java.util.List;
19 import java.util.concurrent.ConcurrentHashMap;
20 import java.util.concurrent.ConcurrentMap;
21 import java.util.concurrent.CopyOnWriteArrayList;
23 import org.opendaylight.controller.md.sal.binding.util.TypeSafeDataReader;
24 import org.opendaylight.controller.sal.binding.api.data.DataBrokerService;
25 import org.opendaylight.controller.sal.binding.api.data.DataModificationTransaction;
26 import org.opendaylight.controller.sal.binding.api.data.DataProviderService;
27 import org.opendaylight.controller.sal.core.ConstructionException;
28 import org.opendaylight.controller.sal.core.Edge;
29 import org.opendaylight.controller.sal.core.Node;
30 import org.opendaylight.controller.sal.core.NodeConnector;
31 import org.opendaylight.controller.sal.core.NodeTable;
32 import org.opendaylight.controller.sal.core.NodeTable.NodeTableIDType;
33 import org.opendaylight.controller.sal.core.Property;
34 import org.opendaylight.controller.sal.core.UpdateType;
35 import org.opendaylight.controller.sal.inventory.IPluginInInventoryService;
36 import org.opendaylight.controller.sal.inventory.IPluginOutInventoryService;
37 import org.opendaylight.controller.sal.reader.FlowOnNode;
38 import org.opendaylight.controller.sal.reader.IPluginInReadService;
39 import org.opendaylight.controller.sal.reader.IPluginOutReadService;
40 import org.opendaylight.controller.sal.reader.NodeConnectorStatistics;
41 import org.opendaylight.controller.sal.reader.NodeDescription;
42 import org.opendaylight.controller.sal.reader.NodeTableStatistics;
43 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNode;
44 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNodeConnector;
45 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.Table;
46 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.TableKey;
47 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.table.Flow;
48 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.AggregateFlowStatisticsUpdate;
49 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.FlowStatisticsData;
50 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.FlowsStatisticsUpdate;
51 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.GetAllFlowsStatisticsFromAllFlowTablesInputBuilder;
52 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.GetFlowStatisticsFromFlowTableInputBuilder;
53 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.OpendaylightFlowStatisticsListener;
54 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.OpendaylightFlowStatisticsService;
55 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.flow.and.statistics.map.list.FlowAndStatisticsMapList;
56 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.table.statistics.rev131215.FlowTableStatisticsData;
57 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.table.statistics.rev131215.FlowTableStatisticsUpdate;
58 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.table.statistics.rev131215.GetFlowTablesStatisticsInputBuilder;
59 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.table.statistics.rev131215.OpendaylightFlowTableStatisticsListener;
60 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.table.statistics.rev131215.OpendaylightFlowTableStatisticsService;
61 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.table.statistics.rev131215.flow.table.and.statistics.map.FlowTableAndStatisticsMap;
62 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.table.statistics.rev131215.flow.table.statistics.FlowTableStatistics;
63 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.topology.discovery.rev130819.FlowTopologyDiscoveryService;
64 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.topology.discovery.rev130819.Link;
65 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeConnectorId;
66 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeConnectorRef;
67 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeConnectorRemoved;
68 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeConnectorUpdated;
69 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeId;
70 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeRef;
71 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeRemoved;
72 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeUpdated;
73 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.Nodes;
74 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.OpendaylightInventoryListener;
75 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.node.NodeConnectorKey;
76 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.NodeKey;
77 import org.opendaylight.yang.gen.v1.urn.opendaylight.model.statistics.types.rev130925.GenericStatistics;
78 import org.opendaylight.yang.gen.v1.urn.opendaylight.model.statistics.types.rev130925.node.connector.statistics.Bytes;
79 import org.opendaylight.yang.gen.v1.urn.opendaylight.model.statistics.types.rev130925.node.connector.statistics.Packets;
80 import org.opendaylight.yang.gen.v1.urn.opendaylight.port.statistics.rev131214.FlowCapableNodeConnectorStatistics;
81 import org.opendaylight.yang.gen.v1.urn.opendaylight.port.statistics.rev131214.FlowCapableNodeConnectorStatisticsData;
82 import org.opendaylight.yang.gen.v1.urn.opendaylight.port.statistics.rev131214.GetAllNodeConnectorsStatisticsInputBuilder;
83 import org.opendaylight.yang.gen.v1.urn.opendaylight.port.statistics.rev131214.GetNodeConnectorStatisticsInputBuilder;
84 import org.opendaylight.yang.gen.v1.urn.opendaylight.port.statistics.rev131214.NodeConnectorStatisticsUpdate;
85 import org.opendaylight.yang.gen.v1.urn.opendaylight.port.statistics.rev131214.OpendaylightPortStatisticsListener;
86 import org.opendaylight.yang.gen.v1.urn.opendaylight.port.statistics.rev131214.OpendaylightPortStatisticsService;
87 import org.opendaylight.yang.gen.v1.urn.opendaylight.port.statistics.rev131214.node.connector.statistics.and.port.number.map.NodeConnectorStatisticsAndPortNumberMap;
88 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
89 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier.PathArgument;
90 import org.slf4j.Logger;
91 import org.slf4j.LoggerFactory;
93 public class InventoryAndReadAdapter implements IPluginInReadService, IPluginInInventoryService, OpendaylightInventoryListener, OpendaylightFlowStatisticsListener, OpendaylightFlowTableStatisticsListener, OpendaylightPortStatisticsListener {
94 private static final Logger LOG = LoggerFactory.getLogger(InventoryAndReadAdapter.class);
95 private static final short OPENFLOWV10_TABLE_ID = 0;
97 private final InventoryNotificationProvider inventoryNotificationProvider = new InventoryNotificationProvider();
98 private final Map<PathArgument,List<PathArgument>> nodeToNodeConnectorsMap = new ConcurrentHashMap<>();
99 private List<IPluginOutInventoryService> inventoryPublisher = new CopyOnWriteArrayList<>();
100 private List<IPluginOutReadService> statisticsPublisher = new CopyOnWriteArrayList<>();
102 private OpendaylightFlowTableStatisticsService flowTableStatisticsService;
103 private OpendaylightPortStatisticsService nodeConnectorStatisticsService;
104 private OpendaylightFlowStatisticsService flowStatisticsService;
105 private FlowTopologyDiscoveryService topologyDiscovery;
106 private DataProviderService dataProviderService;
107 private DataBrokerService dataService;
109 public DataBrokerService getDataService() {
113 public void setDataService(final DataBrokerService dataService) {
114 this.dataService = dataService;
117 public DataProviderService getDataProviderService() {
118 return dataProviderService;
121 public void setDataProviderService(final DataProviderService dataProviderService) {
122 this.dataProviderService = dataProviderService;
125 public OpendaylightFlowStatisticsService getFlowStatisticsService() {
126 return flowStatisticsService;
129 public void setFlowStatisticsService(final OpendaylightFlowStatisticsService flowStatisticsService) {
130 this.flowStatisticsService = flowStatisticsService;
133 public OpendaylightPortStatisticsService getNodeConnectorStatisticsService() {
134 return nodeConnectorStatisticsService;
137 public void setNodeConnectorStatisticsService(final OpendaylightPortStatisticsService nodeConnectorStatisticsService) {
138 this.nodeConnectorStatisticsService = nodeConnectorStatisticsService;
141 public OpendaylightFlowTableStatisticsService getFlowTableStatisticsService() {
142 return flowTableStatisticsService;
145 public void setFlowTableStatisticsService(final OpendaylightFlowTableStatisticsService flowTableStatisticsService) {
146 this.flowTableStatisticsService = flowTableStatisticsService;
149 public FlowTopologyDiscoveryService getTopologyDiscovery() {
150 return topologyDiscovery;
153 public void setTopologyDiscovery(final FlowTopologyDiscoveryService topologyDiscovery) {
154 this.topologyDiscovery = topologyDiscovery;
157 public List<IPluginOutReadService> getStatisticsPublisher() {
158 return statisticsPublisher;
161 public void setStatisticsPublisher(final List<IPluginOutReadService> statisticsPublisher) {
162 this.statisticsPublisher = statisticsPublisher;
165 public List<IPluginOutInventoryService> getInventoryPublisher() {
166 return inventoryPublisher;
169 public void setInventoryPublisher(final List<IPluginOutInventoryService> inventoryPublisher) {
170 this.inventoryPublisher = inventoryPublisher;
173 public void startAdapter() {
174 inventoryNotificationProvider.setDataProviderService(getDataProviderService());
175 inventoryNotificationProvider.setInventoryPublisher(getInventoryPublisher());
176 // inventoryNotificationProvider.start();
179 public boolean setInventoryPublisher(final IPluginOutInventoryService listener) {
180 return getInventoryPublisher().add(listener);
183 public boolean unsetInventoryPublisher(final IPluginOutInventoryService listener) {
184 return getInventoryPublisher().remove(listener);
187 public boolean setReadPublisher(final IPluginOutReadService listener) {
188 return getStatisticsPublisher().add(listener);
191 public Boolean unsetReadPublisher(final IPluginOutReadService listener) {
192 if (listener != null) {
193 return getStatisticsPublisher().remove(listener);
198 protected DataModificationTransaction startChange() {
199 return getDataProviderService().beginTransaction();
203 public long getTransmitRate(final NodeConnector connector) {
204 final FlowCapableNodeConnector nodeConnector = this.readOperFlowCapableNodeConnector(NodeMapping.toNodeConnectorRef(connector));
205 return nodeConnector.getCurrentSpeed().longValue();
208 private FlowCapableNode readOperFlowCapableNode(final NodeRef ref) {
209 final org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node node =
210 (org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node)getDataService().readOperationalData(ref.getValue());
215 return node.getAugmentation(FlowCapableNode.class);
218 private org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node readConfigNode(final Node node) {
219 final InstanceIdentifier<org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node> nodeRef =
220 InstanceIdentifier.builder(Nodes.class)
221 .child(org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node.class, InventoryMapping.toNodeKey(node))
224 return (org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node) startChange().readConfigurationData(nodeRef);
227 private org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.node.NodeConnector readConfigNodeConnector(final NodeConnector connector) {
228 final InstanceIdentifier<org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.node.NodeConnector> nodeConnectorRef =
229 InstanceIdentifier.builder(Nodes.class)
230 .child(org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node.class, InventoryMapping.toNodeKey(connector.getNode()))
231 .child(org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.node.NodeConnector.class, InventoryMapping.toNodeConnectorKey(connector))
234 return((org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.node.NodeConnector) startChange().readConfigurationData(nodeConnectorRef));
238 * Read a table of a node from configuration data store.
240 * @param node Node id
242 * @return Table contents, or null if not present
244 private Table readConfigTable(final Node node, final short id) {
245 final InstanceIdentifier<Table> tableRef = InstanceIdentifier.builder(Nodes.class)
246 .child(org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node.class, InventoryMapping.toNodeKey(node))
247 .augmentation(FlowCapableNode.class)
248 .child(Table.class, new TableKey(id))
251 return (Table) startChange().readConfigurationData(tableRef);
255 public List<FlowOnNode> readAllFlow(final Node node, final boolean cached) {
256 final ArrayList<FlowOnNode> output = new ArrayList<>();
257 final Table table = readConfigTable(node, OPENFLOWV10_TABLE_ID);
259 final List<Flow> flows = table.getFlow();
260 LOG.trace("Number of flows installed in table 0 of node {} : {}", node, flows.size());
262 for (final Flow flow : flows) {
263 final FlowStatisticsData statsFromDataStore = flow.getAugmentation(FlowStatisticsData.class);
264 if (statsFromDataStore != null) {
265 final FlowOnNode it = new FlowOnNode(ToSalConversionsUtils.toFlow(flow, node));
266 output.add(addFlowStats(it, statsFromDataStore.getFlowStatistics()));
271 // TODO (main): Shall we send request to the switch? It will make async request to the switch.
272 // Once the plugin receives a response, it will let the adaptor know through onFlowStatisticsUpdate()
273 // If we assume that md-sal statistics manager will always be running, then it is not required
274 // But if not, then sending request will collect the latest data for adaptor at least.
275 getFlowStatisticsService().getAllFlowsStatisticsFromAllFlowTables(
276 new GetAllFlowsStatisticsFromAllFlowTablesInputBuilder().setNode(NodeMapping.toNodeRef(node)).build());
281 public List<NodeConnectorStatistics> readAllNodeConnector(final Node node, final boolean cached) {
282 final ArrayList<NodeConnectorStatistics> ret = new ArrayList<>();
284 final org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node dsNode = readConfigNode(node);
285 if (dsNode != null) {
286 for (final org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.node.NodeConnector dsNodeConnector : dsNode.getNodeConnector()) {
287 final FlowCapableNodeConnectorStatistics stats = (dsNodeConnector.getAugmentation(FlowCapableNodeConnectorStatisticsData.class));
290 ret.add(toNodeConnectorStatistics(stats.getFlowCapableNodeConnectorStatistics(), dsNode.getId(), dsNodeConnector.getId()));
291 } catch (ConstructionException e) {
292 LOG.warn("Failed to instantiate node connector statistics for node {} connector {}, ignoring it",
293 dsNode.getId(), dsNodeConnector.getId(), e);
299 //TODO: Refer TODO (main)
300 getNodeConnectorStatisticsService().getAllNodeConnectorsStatistics(
301 new GetAllNodeConnectorsStatisticsInputBuilder().setNode(NodeMapping.toNodeRef(node)).build());
306 public List<NodeTableStatistics> readAllNodeTable(final Node node, final boolean cached) {
307 final NodeRef nodeRef = NodeMapping.toNodeRef(node);
309 final ArrayList<NodeTableStatistics> ret = new ArrayList<>();
310 final FlowCapableNode dsFlowCapableNode = this.readOperFlowCapableNode(nodeRef);
311 if (dsFlowCapableNode != null) {
312 for (final Table table : dsFlowCapableNode.getTable()) {
313 final FlowTableStatisticsData tableStats = table.getAugmentation(FlowTableStatisticsData.class);
314 if (tableStats != null) {
316 ret.add(toNodeTableStatistics(tableStats.getFlowTableStatistics(), table.getId(), node));
317 } catch (ConstructionException e) {
318 LOG.warn("Failed to instantiate table statistics for node {} table {}, ignoring it", node, table.getId(), e);
324 //TODO: Refer TODO (main)
325 getFlowTableStatisticsService().getFlowTablesStatistics(new GetFlowTablesStatisticsInputBuilder().setNode(nodeRef).build());
330 public NodeDescription readDescription(final Node node, final boolean cached) {
331 return this.toNodeDescription(NodeMapping.toNodeRef(node));
335 public FlowOnNode readFlow(final Node node, final org.opendaylight.controller.sal.flowprogrammer.Flow targetFlow, final boolean cached) {
336 FlowOnNode ret = null;
337 final Table table = readConfigTable(node, OPENFLOWV10_TABLE_ID);
339 final List<Flow> flows = table.getFlow();
340 InventoryAndReadAdapter.LOG.trace("Number of flows installed in table 0 of node {} : {}", node, flows.size());
342 for (final Flow mdsalFlow : flows) {
343 if(FromSalConversionsUtils.flowEquals(mdsalFlow, MDFlowMapping.toMDSalflow(targetFlow))) {
344 final FlowStatisticsData statsFromDataStore = mdsalFlow.getAugmentation(FlowStatisticsData.class);
345 if (statsFromDataStore != null) {
346 InventoryAndReadAdapter.LOG.debug("Found matching flow in the data store flow table ");
347 ret = addFlowStats(new FlowOnNode(targetFlow), statsFromDataStore.getFlowStatistics());
355 //TODO: Refer TODO (main)
356 final GetFlowStatisticsFromFlowTableInputBuilder input = new GetFlowStatisticsFromFlowTableInputBuilder().setNode(NodeMapping.toNodeRef(node));
357 input.fieldsFrom(MDFlowMapping.toMDSalflow(targetFlow));
358 getFlowStatisticsService().getFlowStatisticsFromFlowTable(input.build());
363 public NodeConnectorStatistics readNodeConnector(final NodeConnector connector, final boolean cached) {
364 final NodeConnectorId ncId = InventoryMapping.toNodeConnectorKey(connector).getId();
366 NodeConnectorStatistics ret = null;
367 final org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.node.NodeConnector nodeConnectorFromDS = readConfigNodeConnector(connector);
368 if (nodeConnectorFromDS != null) {
369 final FlowCapableNodeConnectorStatistics stats = nodeConnectorFromDS.getAugmentation(FlowCapableNodeConnectorStatisticsData.class);
372 ret = toNodeConnectorStatistics(stats.getFlowCapableNodeConnectorStatistics(),
373 InventoryMapping.toNodeKey(connector.getNode()).getId(), ncId);
374 } catch (ConstructionException e) {
375 LOG.warn("Failed to instantiate node connector statistics for connector {}, ignoring it",
381 getNodeConnectorStatisticsService().getNodeConnectorStatistics(
382 new GetNodeConnectorStatisticsInputBuilder().setNode(NodeMapping.toNodeRef(connector.getNode())).setNodeConnectorId(ncId).build());
387 public NodeTableStatistics readNodeTable(final NodeTable nodeTable, final boolean cached) {
388 NodeTableStatistics nodeStats = null;
389 final Table table = readConfigTable(nodeTable.getNode(), (short) nodeTable.getID());
391 final FlowTableStatisticsData tableStats = table.getAugmentation(FlowTableStatisticsData.class);
392 if (tableStats != null) {
394 nodeStats = toNodeTableStatistics(tableStats.getFlowTableStatistics(), table.getId(), nodeTable.getNode());
395 } catch (ConstructionException e) {
396 LOG.warn("Failed to instantiate table statistics for node {} table {}, ignoring it",
397 nodeTable.getNode(), table.getId(), e);
402 //TODO: Refer TODO (main)
403 getFlowTableStatisticsService().getFlowTablesStatistics(
404 new GetFlowTablesStatisticsInputBuilder().setNode(NodeMapping.toNodeRef(nodeTable.getNode())).build());
409 public void onNodeConnectorRemoved(final NodeConnectorRemoved update) {
414 public void onNodeRemoved(final NodeRemoved notification) {
415 this.removeNodeConnectors(notification.getNodeRef().getValue());
417 final Node aDNode = NodeMapping.toADNode(notification.getNodeRef());
418 this.publishNodeUpdate(aDNode, UpdateType.REMOVED, Collections.<Property>emptySet());
419 } catch (ConstructionException e) {
420 LOG.warn("Failed to construct node for {}, not propagating update", notification.getNodeRef(), e);
425 public void onNodeConnectorUpdated(final NodeConnectorUpdated update) {
426 final NodeConnectorRef ref = update.getNodeConnectorRef();
427 final UpdateType updateType;
428 if (!this.isKnownNodeConnector(ref.getValue())) {
429 this.recordNodeConnector(ref.getValue());
430 updateType = UpdateType.ADDED;
432 updateType = UpdateType.CHANGED;
436 final NodeConnector nodeConnector;
437 nodeConnector = NodeMapping.toADNodeConnector(ref);
438 this.publishNodeConnectorUpdate(nodeConnector, updateType, NodeMapping.toADNodeConnectorProperties(update));
439 } catch (ConstructionException e) {
440 LOG.warn("Failed to construct node connector for {}, not reporting the update", ref, e);
445 public void onNodeUpdated(final NodeUpdated notification) {
446 final NodeRef ref = notification.getNodeRef();
448 final UpdateType updateType;
449 if (dataService.readOperationalData(ref.getValue()) == null) {
450 updateType = UpdateType.ADDED;
452 updateType = UpdateType.CHANGED;
457 aDNode = NodeMapping.toADNode(ref);
458 } catch (ConstructionException e) {
459 LOG.warn("Failed to construct node for {}, not reporting the update", ref, e);
463 this.publishNodeUpdate(aDNode, updateType, NodeMapping.toADNodeProperties(notification));
464 for (final IPluginOutReadService statsPublisher : getStatisticsPublisher()) {
465 final NodeDescription description = this.toNodeDescription(ref);
466 if (description != null) {
467 final InstanceIdentifier<org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node> nodeRef =
468 InstanceIdentifier.builder(Nodes.class)
469 .child(org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node.class, new NodeKey(notification.getId()))
472 statsPublisher.descriptionStatisticsUpdated(NodeMapping.toADNode(nodeRef), description);
473 } catch (ConstructionException e) {
474 LOG.warn("Failed to construct node for {}, not reporting the update to publisher {}", nodeRef, statsPublisher, e);
481 public ConcurrentMap<Node,Map<String,Property>> getNodeProps() {
482 final ConcurrentHashMap<Node,Map<String,Property>> props = new ConcurrentHashMap<>();
483 final Nodes nodes = this.readOperAllMDNodes();
484 for (final org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node node : nodes.getNode()) {
485 final FlowCapableNode fcn = node.getAugmentation(FlowCapableNode.class);
487 final ConcurrentHashMap<String,Property> perNodePropMap = new ConcurrentHashMap<String, Property>();
488 final HashSet<Property> perNodeProps = NodeMapping.toADNodeProperties(fcn, node.getId());
489 if (perNodeProps != null) {
490 for (final Property perNodeProp : perNodeProps) {
491 perNodePropMap.put(perNodeProp.getName(), perNodeProp);
496 final Node adNode = NodeMapping.toADNode(node.getId());
497 props.put(adNode, perNodePropMap);
498 } catch (ConstructionException e) {
499 LOG.warn("Failed to construct node for {}, skipping it", node, e);
506 private Nodes readOperAllMDNodes() {
507 final TypeSafeDataReader reader = TypeSafeDataReader.forReader(getDataService());
508 return reader.readOperationalData(InstanceIdentifier.builder(Nodes.class).build());
512 public ConcurrentMap<NodeConnector,Map<String,Property>> getNodeConnectorProps(final Boolean refresh) {
513 final ConcurrentHashMap<NodeConnector,Map<String,Property>> props = new ConcurrentHashMap<>();
514 for (final org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node node : this.readOperAllMDNodes().getNode()) {
515 for (final org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.node.NodeConnector nc : node.getNodeConnector()) {
516 final FlowCapableNodeConnector fcnc = nc.getAugmentation(FlowCapableNodeConnector.class);
518 final ConcurrentHashMap<String,Property> ncpsm = new ConcurrentHashMap<>();
519 final HashSet<Property> ncps = NodeMapping.toADNodeConnectorProperties(fcnc);
521 for (final Property p : ncps) {
522 ncpsm.put(p.getName(), p);
527 props.put(NodeMapping.toADNodeConnector(nc.getId(), node.getId()), ncpsm);
528 } catch (ConstructionException e) {
529 LOG.warn("Failed to instantiate node {} connector {}, not reporting it", node.getId(), nc.getId(), e);
537 private FlowCapableNodeConnector readOperFlowCapableNodeConnector(final NodeConnectorRef ref) {
538 final org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.node.NodeConnector nc =
539 (org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.node.NodeConnector)
540 getDataService().readOperationalData(ref.getValue());
541 return nc.getAugmentation(FlowCapableNodeConnector.class);
544 private static NodeConnectorStatistics toNodeConnectorStatistics(final org.opendaylight.yang.gen.v1.urn.opendaylight.model.statistics.types.rev130925.NodeConnectorStatistics nodeConnectorStatistics, final NodeId nodeId, final NodeConnectorId nodeConnectorId) throws ConstructionException {
545 final NodeConnectorStatistics it = new NodeConnectorStatistics();
547 final Packets packets = nodeConnectorStatistics.getPackets();
548 it.setReceivePacketCount(packets.getReceived().longValue());
549 it.setTransmitPacketCount(packets.getTransmitted().longValue());
551 final Bytes bytes = nodeConnectorStatistics.getBytes();
552 it.setReceiveByteCount(bytes.getReceived().longValue());
553 it.setTransmitByteCount(bytes.getTransmitted().longValue());
555 it.setReceiveDropCount(nodeConnectorStatistics.getReceiveDrops().longValue());
556 it.setTransmitDropCount(nodeConnectorStatistics.getTransmitDrops().longValue());
557 it.setReceiveErrorCount(nodeConnectorStatistics.getReceiveErrors().longValue());
558 it.setTransmitErrorCount(nodeConnectorStatistics.getTransmitErrors().longValue());
559 it.setReceiveFrameErrorCount(nodeConnectorStatistics.getReceiveFrameError().longValue());
560 it.setReceiveOverRunErrorCount(nodeConnectorStatistics.getReceiveOverRunError().longValue());
561 it.setReceiveCRCErrorCount(nodeConnectorStatistics.getReceiveCrcError().longValue());
562 it.setCollisionCount(nodeConnectorStatistics.getCollisionCount().longValue());
564 final InstanceIdentifier<org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.node.NodeConnector> nodeConnectorRef =
565 InstanceIdentifier.builder(Nodes.class)
566 .child(org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node.class, new NodeKey(nodeId))
567 .child(org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.node.NodeConnector.class, new NodeConnectorKey(nodeConnectorId))
569 it.setNodeConnector(NodeMapping.toADNodeConnector(new NodeConnectorRef(nodeConnectorRef)));
573 private static NodeTableStatistics toNodeTableStatistics(final FlowTableStatistics tableStats, final Short tableId, final Node node) throws ConstructionException {
574 final NodeTableStatistics it = new NodeTableStatistics();
575 it.setActiveCount(tableStats.getActiveFlows().getValue().intValue());
576 it.setLookupCount(tableStats.getPacketsLookedUp().getValue().longValue());
577 it.setMatchedCount(tableStats.getPacketsMatched().getValue().longValue());
578 it.setName(tableId.toString());
579 it.setNodeTable(new NodeTable(NodeTableIDType.OPENFLOW, tableId.byteValue(), node));
583 private NodeDescription toNodeDescription(final NodeRef nodeRef) {
584 final FlowCapableNode capableNode = this.readOperFlowCapableNode(nodeRef);
585 if (capableNode == null) {
589 final NodeDescription it = new NodeDescription();
590 it.setManufacturer(capableNode.getManufacturer());
591 it.setSerialNumber(capableNode.getSerialNumber());
592 it.setSoftware(capableNode.getSoftware());
593 it.setDescription(capableNode.getDescription());
597 public Edge toADEdge(final Link link) throws ConstructionException {
598 NodeConnectorRef _source = link.getSource();
599 NodeConnector _aDNodeConnector = NodeMapping.toADNodeConnector(_source);
600 NodeConnectorRef _destination = link.getDestination();
601 NodeConnector _aDNodeConnector_1 = NodeMapping.toADNodeConnector(_destination);
602 Edge _edge = new Edge(_aDNodeConnector, _aDNodeConnector_1);
607 * OpendaylightFlowStatisticsListener interface implementation
610 public void onAggregateFlowStatisticsUpdate(final AggregateFlowStatisticsUpdate notification) {
611 // Ignoring this notification as there does not seem to be a way to bubble this up to AD-SAL
615 public void onFlowsStatisticsUpdate(final FlowsStatisticsUpdate notification) {
616 final ArrayList<FlowOnNode> adsalFlowsStatistics = new ArrayList<>();
617 final InstanceIdentifier<org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node> nodeRef =
618 InstanceIdentifier.builder(Nodes.class)
619 .child(org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node.class, new NodeKey(notification.getId()))
624 aDNode = NodeMapping.toADNode(nodeRef);
625 } catch (ConstructionException e) {
626 LOG.warn("Failed to construct node for {}, ignoring it", notification.getId(), e);
630 for (final FlowAndStatisticsMapList flowStats : notification.getFlowAndStatisticsMapList()) {
631 if (flowStats.getTableId() == 0) {
632 adsalFlowsStatistics.add(InventoryAndReadAdapter.toFlowOnNode(flowStats, aDNode));
635 for (final IPluginOutReadService statsPublisher : getStatisticsPublisher()) {
636 statsPublisher.nodeFlowStatisticsUpdated(aDNode, adsalFlowsStatistics);
641 * OpendaylightFlowTableStatisticsListener interface implementation
644 public void onFlowTableStatisticsUpdate(final FlowTableStatisticsUpdate notification) {
645 ArrayList<NodeTableStatistics> adsalFlowTableStatistics = new ArrayList<>();
646 for (final FlowTableAndStatisticsMap stats : notification.getFlowTableAndStatisticsMap()) {
647 if (stats.getTableId().getValue() == 0) {
648 final NodeTableStatistics it = new NodeTableStatistics();
649 it.setActiveCount(stats.getActiveFlows().getValue().intValue());
650 it.setLookupCount(stats.getPacketsLookedUp().getValue().longValue());
651 it.setMatchedCount(stats.getPacketsMatched().getValue().longValue());
652 adsalFlowTableStatistics.add(it);
656 final InstanceIdentifier<org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node> nodeRef =
657 InstanceIdentifier.builder(Nodes.class)
658 .child(org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node.class, new NodeKey(notification.getId()))
663 aDNode = NodeMapping.toADNode(nodeRef);
664 } catch (ConstructionException e) {
665 LOG.warn("Failed to construct node for {}, ignoring it", notification.getId(), e);
669 for (final IPluginOutReadService statsPublisher : getStatisticsPublisher()) {
670 statsPublisher.nodeTableStatisticsUpdated(aDNode, adsalFlowTableStatistics);
675 * OpendaylightPortStatisticsUpdate interface implementation
678 public void onNodeConnectorStatisticsUpdate(final NodeConnectorStatisticsUpdate notification) {
679 final ArrayList<NodeConnectorStatistics> adsalPortStatistics = new ArrayList<NodeConnectorStatistics>();
680 for (final NodeConnectorStatisticsAndPortNumberMap nodeConnectorStatistics : notification.getNodeConnectorStatisticsAndPortNumberMap()) {
682 adsalPortStatistics.add(toNodeConnectorStatistics(
683 nodeConnectorStatistics, notification.getId(), nodeConnectorStatistics.getNodeConnectorId()));
684 } catch (ConstructionException e) {
685 LOG.warn("Failed to create statistics for node {} connector {}, not updating them",
686 notification.getId(), nodeConnectorStatistics.getNodeConnectorId(), e);
690 final InstanceIdentifier<org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node> nodeRef =
691 InstanceIdentifier.builder(Nodes.class)
692 .child(org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node.class, new NodeKey(notification.getId()))
697 aDNode = NodeMapping.toADNode(nodeRef);
698 } catch (ConstructionException e) {
699 LOG.warn("Failed to construct node for {}, ignoring it", notification.getId(), e);
703 for (final IPluginOutReadService statsPublisher : getStatisticsPublisher()) {
704 statsPublisher.nodeConnectorStatisticsUpdated(aDNode, adsalPortStatistics);
708 private static FlowOnNode toFlowOnNode(final FlowAndStatisticsMapList flowAndStatsMap, final Node node) {
709 final FlowOnNode it = new FlowOnNode(ToSalConversionsUtils.toFlow(flowAndStatsMap, node));
710 return addFlowStats(it, flowAndStatsMap);
713 private static FlowOnNode addFlowStats(final FlowOnNode node, final GenericStatistics stats) {
714 node.setByteCount(stats.getByteCount().getValue().longValue());
715 node.setPacketCount(stats.getPacketCount().getValue().longValue());
716 node.setDurationSeconds(stats.getDuration().getSecond().getValue().intValue());
717 node.setDurationNanoseconds(stats.getDuration().getNanosecond().getValue().intValue());
722 public Set<Node> getConfiguredNotConnectedNodes() {
723 return Collections.emptySet();
726 private void publishNodeUpdate(final Node node, final UpdateType updateType, final Set<Property> properties) {
727 for (final IPluginOutInventoryService publisher : getInventoryPublisher()) {
728 publisher.updateNode(node, updateType, properties);
732 private void publishNodeConnectorUpdate(final NodeConnector nodeConnector, final UpdateType updateType, final Set<Property> properties) {
733 for (final IPluginOutInventoryService publisher : getInventoryPublisher()) {
734 publisher.updateNodeConnector(nodeConnector, updateType, properties);
738 private boolean isKnownNodeConnector(final InstanceIdentifier<? extends Object> nodeConnectorIdentifier) {
739 final Iterator<PathArgument> it = nodeConnectorIdentifier.getPathArguments().iterator();
749 final PathArgument nodePath = it.next();
754 final PathArgument nodeConnectorPath = it.next();
756 final List<PathArgument> nodeConnectors = nodeToNodeConnectorsMap.get(nodePath);
757 return nodeConnectors == null ? false :
758 nodeConnectors.contains(nodeConnectorPath);
761 private boolean recordNodeConnector(final InstanceIdentifier<? extends Object> nodeConnectorIdentifier) {
762 final Iterator<PathArgument> it = nodeConnectorIdentifier.getPathArguments().iterator();
772 final PathArgument nodePath = it.next();
777 final PathArgument nodeConnectorPath = it.next();
779 synchronized (this) {
780 List<PathArgument> nodeConnectors = this.nodeToNodeConnectorsMap.get(nodePath);
781 if (nodeConnectors == null) {
782 nodeConnectors = new ArrayList<>();
783 this.nodeToNodeConnectorsMap.put(nodePath, nodeConnectors);
786 return nodeConnectors.add(nodeConnectorPath);
790 private List<PathArgument> removeNodeConnectors(final InstanceIdentifier<? extends Object> nodeIdentifier) {
791 return this.nodeToNodeConnectorsMap.remove(Iterables.get(nodeIdentifier.getPathArguments(), 1));