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.l2switch.arphandler.inventory;
10 import com.google.common.base.Optional;
11 import java.util.ArrayList;
12 import java.util.HashMap;
13 import java.util.List;
14 import java.util.concurrent.ExecutionException;
15 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
16 import org.opendaylight.controller.md.sal.binding.api.ReadOnlyTransaction;
17 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
18 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev100924.MacAddress;
19 import org.opendaylight.yang.gen.v1.urn.opendaylight.address.tracker.rev140617.AddressCapableNodeConnector;
20 import org.opendaylight.yang.gen.v1.urn.opendaylight.address.tracker.rev140617.address.node.connector.Addresses;
21 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeConnectorId;
22 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeConnectorRef;
23 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.Nodes;
24 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.node.NodeConnector;
25 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.node.NodeConnectorKey;
26 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node;
27 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.NodeKey;
28 import org.opendaylight.yang.gen.v1.urn.opendaylight.l2switch.loopremover.rev140714.StpStatus;
29 import org.opendaylight.yang.gen.v1.urn.opendaylight.l2switch.loopremover.rev140714.StpStatusAwareNodeConnector;
30 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
31 import org.slf4j.Logger;
32 import org.slf4j.LoggerFactory;
35 * InventoryReader reads the opendaylight-inventory tree in MD-SAL data store.
37 public class InventoryReader {
39 private static final Logger LOG = LoggerFactory.getLogger(InventoryReader.class);
40 private DataBroker dataService;
41 // Key: SwitchId, Value: NodeConnectorRef that corresponds to NC between
42 // controller & switch
43 private HashMap<String, NodeConnectorRef> controllerSwitchConnectors;
44 // Key: SwitchId, Value: List of node connectors on this switch
45 private HashMap<String, List<NodeConnectorRef>> switchNodeConnectors;
47 public void setRefreshData(boolean refreshData) {
48 this.refreshData = refreshData;
51 private boolean refreshData = false;
54 * Construct an InventoryService object with the specified inputs.
57 * The DataBrokerService associated with the InventoryService.
59 public InventoryReader(DataBroker dataService) {
60 this.dataService = dataService;
61 controllerSwitchConnectors = new HashMap<String, NodeConnectorRef>();
62 switchNodeConnectors = new HashMap<String, List<NodeConnectorRef>>();
65 public HashMap<String, NodeConnectorRef> getControllerSwitchConnectors() {
66 return controllerSwitchConnectors;
69 public HashMap<String, List<NodeConnectorRef>> getSwitchNodeConnectors() {
70 return switchNodeConnectors;
74 * Read the Inventory data tree to find information about the Nodes and
75 * NodeConnectors. Create the list of NodeConnectors for a given switch.
76 * Also determine the STP status of each NodeConnector.
78 public void readInventory() {
79 // Only run once for now
87 InstanceIdentifier.InstanceIdentifierBuilder<Nodes> nodesInsIdBuilder = InstanceIdentifier
88 .<Nodes>builder(Nodes.class);
90 ReadOnlyTransaction readOnlyTransaction = dataService.newReadOnlyTransaction();
93 Optional<Nodes> dataObjectOptional = null;
94 dataObjectOptional = readOnlyTransaction
95 .read(LogicalDatastoreType.OPERATIONAL, nodesInsIdBuilder.build()).get();
96 if (dataObjectOptional.isPresent())
97 nodes = (Nodes) dataObjectOptional.get();
98 } catch (InterruptedException e) {
99 LOG.error("Failed to read nodes from Operation data store.");
100 readOnlyTransaction.close();
101 throw new RuntimeException("Failed to read nodes from Operation data store.", e);
102 } catch (ExecutionException e) {
103 LOG.error("Failed to read nodes from Operation data store.");
104 readOnlyTransaction.close();
105 throw new RuntimeException("Failed to read nodes from Operation data store.", e);
109 // Get NodeConnectors for each node
110 for (Node node : nodes.getNode()) {
111 ArrayList<NodeConnectorRef> nodeConnectorRefs = new ArrayList<NodeConnectorRef>();
112 List<NodeConnector> nodeConnectors = node.getNodeConnector();
113 if (nodeConnectors != null) {
114 for (NodeConnector nodeConnector : nodeConnectors) {
115 // Read STP status for this NodeConnector
116 StpStatusAwareNodeConnector saNodeConnector = nodeConnector
117 .getAugmentation(StpStatusAwareNodeConnector.class);
118 if (saNodeConnector != null && StpStatus.Discarding.equals(saNodeConnector.getStatus())) {
121 if (nodeConnector.getKey().toString().contains("LOCAL")) {
124 NodeConnectorRef ncRef = new NodeConnectorRef(InstanceIdentifier.<Nodes>builder(Nodes.class)
125 .<Node, NodeKey>child(Node.class, node.getKey())
126 .<NodeConnector, NodeConnectorKey>child(NodeConnector.class, nodeConnector.getKey())
128 nodeConnectorRefs.add(ncRef);
132 switchNodeConnectors.put(node.getId().getValue(), nodeConnectorRefs);
133 NodeConnectorRef ncRef = new NodeConnectorRef(InstanceIdentifier.<Nodes>builder(Nodes.class)
134 .<Node, NodeKey>child(Node.class, node.getKey())
135 .<NodeConnector, NodeConnectorKey>child(NodeConnector.class,
136 new NodeConnectorKey(new NodeConnectorId(node.getId().getValue() + ":LOCAL")))
138 LOG.debug("Local port for node {} is {}", node.getKey(), ncRef);
139 controllerSwitchConnectors.put(node.getId().getValue(), ncRef);
142 readOnlyTransaction.close();
148 * Get the NodeConnector on the specified node with the specified MacAddress
152 * InstanceIdentifier for the node on which to search for.
154 * MacAddress to be searched for.
155 * @return NodeConnectorRef that pertains to the NodeConnector containing
156 * the MacAddress observation.
158 public NodeConnectorRef getNodeConnector(InstanceIdentifier<Node> nodeInsId, MacAddress macAddress) {
159 if (nodeInsId == null || macAddress == null) {
163 NodeConnectorRef destNodeConnector = null;
165 ReadOnlyTransaction readOnlyTransaction = dataService.newReadOnlyTransaction();
167 Optional<Node> dataObjectOptional = null;
168 dataObjectOptional = readOnlyTransaction.read(LogicalDatastoreType.OPERATIONAL, nodeInsId).get();
169 if (dataObjectOptional.isPresent()) {
170 Node node = (Node) dataObjectOptional.get();
171 LOG.debug("Looking address{} in node : {}", macAddress, nodeInsId);
172 if (node.getNodeConnector() != null) {
173 for (NodeConnector nc : node.getNodeConnector()) {
174 // Don't look for mac in discarding node connectors
175 StpStatusAwareNodeConnector saNodeConnector = nc
176 .getAugmentation(StpStatusAwareNodeConnector.class);
177 if (saNodeConnector != null && StpStatus.Discarding.equals(saNodeConnector.getStatus())) {
180 LOG.debug("Looking address{} in nodeconnector : {}", macAddress, nc.getKey());
181 AddressCapableNodeConnector acnc = nc.getAugmentation(AddressCapableNodeConnector.class);
183 List<Addresses> addressesList = acnc.getAddresses();
184 for (Addresses add : addressesList) {
185 if (macAddress.equals(add.getMac())) {
186 if (add.getLastSeen() > latest) {
187 destNodeConnector = new NodeConnectorRef(
188 nodeInsId.child(NodeConnector.class, nc.getKey()));
189 latest = add.getLastSeen();
190 LOG.debug("Found address{} in nodeconnector : {}", macAddress, nc.getKey());
198 LOG.debug("Node connectors data is not present for node {}", node.getId());
201 } catch (InterruptedException e) {
202 LOG.error("Failed to read nodes from Operation data store.");
203 readOnlyTransaction.close();
204 throw new RuntimeException("Failed to read nodes from Operation data store.", e);
205 } catch (ExecutionException e) {
206 LOG.error("Failed to read nodes from Operation data store.");
207 readOnlyTransaction.close();
208 throw new RuntimeException("Failed to read nodes from Operation data store.", e);
210 readOnlyTransaction.close();
211 return destNodeConnector;