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 org.opendaylight.controller.md.sal.binding.api.DataBroker;
12 import org.opendaylight.controller.md.sal.binding.api.ReadOnlyTransaction;
13 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
14 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev100924.MacAddress;
15 import org.opendaylight.yang.gen.v1.urn.opendaylight.address.tracker.rev140617.AddressCapableNodeConnector;
16 import org.opendaylight.yang.gen.v1.urn.opendaylight.address.tracker.rev140617.address.node.connector.Addresses;
17 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeConnectorId;
18 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeConnectorRef;
19 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.Nodes;
20 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.node.NodeConnector;
21 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.node.NodeConnectorKey;
22 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node;
23 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.NodeKey;
24 import org.opendaylight.yang.gen.v1.urn.opendaylight.l2switch.loopremover.rev140714.StpStatus;
25 import org.opendaylight.yang.gen.v1.urn.opendaylight.l2switch.loopremover.rev140714.StpStatusAwareNodeConnector;
26 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
27 import org.slf4j.Logger;
28 import org.slf4j.LoggerFactory;
30 import java.util.ArrayList;
31 import java.util.HashMap;
32 import java.util.List;
33 import java.util.concurrent.ExecutionException;
36 * InventoryReader reads the opendaylight-inventory tree in MD-SAL data store.
38 public class InventoryReader {
40 private Logger _logger = LoggerFactory.getLogger(InventoryReader.class);
41 private DataBroker dataService;
42 // Key: SwitchId, Value: NodeConnectorRef that corresponds to NC between 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.
56 * @param dataService The DataBrokerService associated with the InventoryService.
58 public InventoryReader(DataBroker dataService) {
59 this.dataService = dataService;
60 controllerSwitchConnectors = new HashMap<String, NodeConnectorRef>();
61 switchNodeConnectors = new HashMap<String, List<NodeConnectorRef>>();
64 public HashMap<String, NodeConnectorRef> getControllerSwitchConnectors() {
65 return controllerSwitchConnectors;
68 public HashMap<String, List<NodeConnectorRef>> getSwitchNodeConnectors() {
69 return switchNodeConnectors;
73 * Read the Inventory data tree to find information about the Nodes & NodeConnectors.
74 * Create the list of NodeConnectors for a given switch. Also determine the STP status of each NodeConnector.
76 public void readInventory() {
77 // Only run once for now
85 InstanceIdentifier.InstanceIdentifierBuilder<Nodes> nodesInsIdBuilder = InstanceIdentifier.<Nodes>builder(Nodes.class);
87 ReadOnlyTransaction readOnlyTransaction = dataService.newReadOnlyTransaction();
90 Optional<Nodes> dataObjectOptional = null;
91 dataObjectOptional = readOnlyTransaction.read(LogicalDatastoreType.OPERATIONAL, nodesInsIdBuilder.toInstance()).get();
92 if(dataObjectOptional.isPresent())
93 nodes = (Nodes) dataObjectOptional.get();
94 } catch(InterruptedException e) {
95 _logger.error("Failed to read nodes from Operation data store.");
96 readOnlyTransaction.close();
97 throw new RuntimeException("Failed to read nodes from Operation data store.", e);
98 } catch(ExecutionException e) {
99 _logger.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);
105 // Get NodeConnectors for each node
106 for(Node node : nodes.getNode()) {
107 ArrayList<NodeConnectorRef> nodeConnectorRefs = new ArrayList<NodeConnectorRef>();
108 List<NodeConnector> nodeConnectors = node.getNodeConnector();
109 if(nodeConnectors != null) {
110 for(NodeConnector nodeConnector : nodeConnectors) {
111 // Read STP status for this NodeConnector
112 StpStatusAwareNodeConnector saNodeConnector = nodeConnector.getAugmentation(StpStatusAwareNodeConnector.class);
113 if(saNodeConnector != null && StpStatus.Discarding.equals(saNodeConnector.getStatus())) {
116 if(nodeConnector.getKey().toString().contains("LOCAL")) {
119 NodeConnectorRef ncRef = new NodeConnectorRef(
120 InstanceIdentifier.<Nodes>builder(Nodes.class).<Node, NodeKey>child(Node.class, node.getKey())
121 .<NodeConnector, NodeConnectorKey>child(NodeConnector.class, nodeConnector.getKey()).toInstance());
122 nodeConnectorRefs.add(ncRef);
126 switchNodeConnectors.put(node.getId().getValue(), nodeConnectorRefs);
127 NodeConnectorRef ncRef = new NodeConnectorRef(
128 InstanceIdentifier.<Nodes>builder(Nodes.class).<Node, NodeKey>child(Node.class, node.getKey())
129 .<NodeConnector, NodeConnectorKey>child(NodeConnector.class, new NodeConnectorKey(new NodeConnectorId(node.getId().getValue() + ":LOCAL"))).toInstance());
130 _logger.debug("Local port for node {} is {}", node.getKey(), ncRef);
131 controllerSwitchConnectors.put(node.getId().getValue(), ncRef);
134 readOnlyTransaction.close();
140 * Get the NodeConnector on the specified node with the specified MacAddress observation.
142 * @param nodeInsId InstanceIdentifier for the node on which to search for.
143 * @param macAddress MacAddress to be searched for.
144 * @return NodeConnectorRef that pertains to the NodeConnector containing the MacAddress observation.
146 public NodeConnectorRef getNodeConnector(InstanceIdentifier<Node> nodeInsId, MacAddress macAddress) {
147 if(nodeInsId == null || macAddress == null) {
151 NodeConnectorRef destNodeConnector = null;
153 ReadOnlyTransaction readOnlyTransaction = dataService.newReadOnlyTransaction();
155 Optional<Node> dataObjectOptional = null;
156 dataObjectOptional = readOnlyTransaction.read(LogicalDatastoreType.OPERATIONAL, nodeInsId).get();
157 if(dataObjectOptional.isPresent()) {
158 Node node = (Node) dataObjectOptional.get();
159 _logger.debug("Looking address{} in node : {}", macAddress, nodeInsId);
160 for(NodeConnector nc : node.getNodeConnector()) {
161 // Don't look for mac in discarding node connectors
162 StpStatusAwareNodeConnector saNodeConnector = nc.getAugmentation(StpStatusAwareNodeConnector.class);
163 if(saNodeConnector != null && StpStatus.Discarding.equals(saNodeConnector.getStatus())) {
166 _logger.debug("Looking address{} in nodeconnector : {}", macAddress, nc.getKey());
167 AddressCapableNodeConnector acnc = nc.getAugmentation(AddressCapableNodeConnector.class);
169 List<Addresses> addressesList = acnc.getAddresses();
170 for(Addresses add : addressesList) {
171 if(macAddress.equals(add.getMac())) {
172 if(add.getLastSeen() > latest) {
173 destNodeConnector = new NodeConnectorRef(nodeInsId.child(NodeConnector.class, nc.getKey()));
174 latest = add.getLastSeen();
175 _logger.debug("Found address{} in nodeconnector : {}", macAddress, nc.getKey());
183 } catch(InterruptedException e) {
184 _logger.error("Failed to read nodes from Operation data store.");
185 readOnlyTransaction.close();
186 throw new RuntimeException("Failed to read nodes from Operation data store.", e);
187 } catch(ExecutionException e) {
188 _logger.error("Failed to read nodes from Operation data store.");
189 readOnlyTransaction.close();
190 throw new RuntimeException("Failed to read nodes from Operation data store.", e);
192 readOnlyTransaction.close();
193 return destNodeConnector;