2 * Copyright © 2017 AT&T 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
9 package org.opendaylight.transportpce.renderer.mapping;
11 import com.google.common.base.Optional;
12 import com.google.common.util.concurrent.CheckedFuture;
14 import java.util.ArrayList;
15 import java.util.List;
16 import java.util.concurrent.ExecutionException;
18 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
19 import org.opendaylight.controller.md.sal.binding.api.MountPoint;
20 import org.opendaylight.controller.md.sal.binding.api.MountPointService;
21 import org.opendaylight.controller.md.sal.binding.api.ReadOnlyTransaction;
22 import org.opendaylight.controller.md.sal.binding.api.WriteTransaction;
23 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
24 import org.opendaylight.controller.md.sal.common.api.data.TransactionCommitFailedException;
25 import org.opendaylight.yang.gen.v1.http.org.openroadm.device.rev161014.circuit.pack.Ports;
26 import org.opendaylight.yang.gen.v1.http.org.openroadm.device.rev161014.circuit.pack.PortsKey;
27 import org.opendaylight.yang.gen.v1.http.org.openroadm.device.rev161014.circuit.packs.CircuitPacks;
28 import org.opendaylight.yang.gen.v1.http.org.openroadm.device.rev161014.circuit.packs.CircuitPacksKey;
29 import org.opendaylight.yang.gen.v1.http.org.openroadm.device.rev161014.degree.ConnectionPorts;
30 import org.opendaylight.yang.gen.v1.http.org.openroadm.device.rev161014.org.openroadm.device.container.OrgOpenroadmDevice;
31 import org.opendaylight.yang.gen.v1.http.org.openroadm.device.rev161014.org.openroadm.device.container.org.openroadm.device.Degree;
32 import org.opendaylight.yang.gen.v1.http.org.openroadm.device.rev161014.org.openroadm.device.container.org.openroadm.device.DegreeKey;
33 import org.opendaylight.yang.gen.v1.http.org.openroadm.device.rev161014.org.openroadm.device.container.org.openroadm.device.Info;
34 import org.opendaylight.yang.gen.v1.http.org.openroadm.device.rev161014.org.openroadm.device.container.org.openroadm.device.SharedRiskGroup;
35 import org.opendaylight.yang.gen.v1.http.org.openroadm.device.rev161014.org.openroadm.device.container.org.openroadm.device.SharedRiskGroupKey;
36 import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.node.topology.rev150114.network.topology.topology.topology.types.TopologyNetconf;
37 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.portmapping.rev170228.Network;
38 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.portmapping.rev170228.NetworkBuilder;
39 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.portmapping.rev170228.network.Nodes;
40 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.portmapping.rev170228.network.NodesBuilder;
41 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.portmapping.rev170228.network.NodesKey;
42 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.portmapping.rev170228.network.nodes.Mapping;
43 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.portmapping.rev170228.network.nodes.MappingBuilder;
44 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.portmapping.rev170228.network.nodes.MappingKey;
45 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NetworkTopology;
46 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NodeId;
47 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.TopologyId;
48 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.Topology;
49 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.TopologyKey;
50 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Node;
51 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.NodeKey;
52 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
53 import org.slf4j.Logger;
54 import org.slf4j.LoggerFactory;
56 public class PortMapping {
58 private static final Logger LOG = LoggerFactory.getLogger(PortMapping.class);
59 private final DataBroker db;
60 private final MountPointService mps;
62 private final String nodeId;
64 public PortMapping(DataBroker db, MountPointService mps, String nodeId) {
72 * This method creates logical to physical port mapping
74 * Instead of parsing all the circuit packs/ports in the device
75 * this methods does a selective read operation on degree/srg
76 * subtree to get circuit packs/ports that map to :
81 * This methods skips the logical ports that are internal.
82 * if operation is successful the mapping gets stored in
83 * datastore corresponding to portmapping.yang data model.
85 * @return true/false based on status of operation
87 public boolean createMappingData() {
89 LOG.info(" Create Mapping Data for node " + nodeId);
91 DataBroker deviceDb = getDeviceDataBroker(nodeId, mps);
92 Info deviceInfo = getDeviceInfo(deviceDb);
94 InstanceIdentifier<Network> nodesIID = InstanceIdentifier.builder(Network.class).build();
96 NetworkBuilder nwBldr = new NetworkBuilder();
97 List<Mapping> portMapList = new ArrayList<>();
98 List<Nodes> nodesList = new ArrayList<>();
100 if (deviceDb != null && deviceInfo != null) {
102 // Creating mapping data for degree TTP's
103 List<ConnectionPorts> degreeConPorts = getDegreePorts(deviceDb, deviceInfo);
105 //Getting circuit-pack-name/port-name corresponding to TTP's
106 for (ConnectionPorts cp : degreeConPorts) {
108 InstanceIdentifier<Ports> portIID = InstanceIdentifier.create(OrgOpenroadmDevice.class).child(
109 CircuitPacks.class, new CircuitPacksKey(cp.getCircuitPackName())).child(Ports.class, new PortsKey(cp
110 .getPortName().toString()));
112 LOG.info("Fetching logical Connection Point value for port " + cp.getPortName().toString()
113 + " at circuit pack " + cp.getCircuitPackName());
114 ReadOnlyTransaction rtx = deviceDb.newReadOnlyTransaction();
115 Optional<Ports> portObject = rtx.read(LogicalDatastoreType.OPERATIONAL, portIID).get();
117 if (portObject.isPresent()) {
118 Ports port = portObject.get();
119 if (port.getLogicalConnectionPoint() != null) {
121 LOG.info("Logical Connection Point for " + cp.getCircuitPackName() + " " + port
122 .getPortName() + " is " + port.getLogicalConnectionPoint());
123 MappingBuilder mpBldr = new MappingBuilder();
124 mpBldr.setKey(new MappingKey(port.getLogicalConnectionPoint())).setLogicalConnectionPoint(
125 port.getLogicalConnectionPoint()).setSupportingCircuitPackName(cp.getCircuitPackName())
126 .setSupportingPort(port.getPortName());
127 portMapList.add(mpBldr.build());
131 LOG.warn("Logical Connection Point value missing for " + cp.getCircuitPackName() + " "
132 + port.getPortName());
135 } catch (InterruptedException | ExecutionException ex) {
136 LOG.warn("Read failed for Logical Connection Point value missing for " + cp.getCircuitPackName()
137 + " " + cp.getPortName());
140 // Creating mapping data for degree PP's
141 List<org.opendaylight.yang.gen.v1.http.org.openroadm.device.rev161014.srg.CircuitPacks> srgCps = getSrgCps(
142 deviceDb, deviceInfo);
144 for (org.opendaylight.yang.gen.v1.http.org.openroadm.device.rev161014.srg.CircuitPacks cps : srgCps) {
145 InstanceIdentifier<CircuitPacks> cpIID = InstanceIdentifier.create(OrgOpenroadmDevice.class).child(
146 CircuitPacks.class, new CircuitPacksKey(cps.getCircuitPackName()));
149 ReadOnlyTransaction rtx = deviceDb.newReadOnlyTransaction();
150 Optional<CircuitPacks> circuitPackObject = rtx.read(LogicalDatastoreType.OPERATIONAL, cpIID).get();
152 if (circuitPackObject.isPresent()) {
153 CircuitPacks circuitPack = circuitPackObject.get();
154 if (!circuitPack.getPorts().isEmpty()) {
155 for (Ports port : circuitPack.getPorts()) {
157 if (port.getLogicalConnectionPoint() != null && port.getPortQual().getIntValue() == 2) {
159 LOG.info("Logical Connection Point for " + circuitPack.getCircuitPackName() + " "
160 + port.getPortName() + " is " + port.getLogicalConnectionPoint());
161 MappingBuilder mpBldr = new MappingBuilder();
162 mpBldr.setKey(new MappingKey(port.getLogicalConnectionPoint()))
163 .setLogicalConnectionPoint(port.getLogicalConnectionPoint())
164 .setSupportingCircuitPackName(circuitPack.getCircuitPackName())
165 .setSupportingPort(port.getPortName());
166 portMapList.add(mpBldr.build());
168 } else if (port.getPortQual().getIntValue() == 1) {
170 LOG.info("Port is internal, skipping Logical Connection Point missing for "
171 + circuitPack.getCircuitPackName() + " " + port.getPortName());
173 } else if (port.getLogicalConnectionPoint() == null) {
175 LOG.info("Value missing, Skipping Logical Connection Point missing for "
176 + circuitPack.getCircuitPackName() + " " + port.getPortName());
184 } catch (InterruptedException | ExecutionException ex) {
185 LOG.warn("Read failed for " + cps.getCircuitPackName());
190 NodesBuilder nodesBldr = new NodesBuilder();
191 nodesBldr.setKey(new NodesKey(deviceInfo.getNodeId())).setNodeId(deviceInfo.getNodeId());
192 nodesBldr.setMapping(portMapList);
193 nodesList.add(nodesBldr.build());
194 nwBldr.setNodes(nodesList);
195 final WriteTransaction writeTransaction = db.newWriteOnlyTransaction();
196 writeTransaction.merge(LogicalDatastoreType.CONFIGURATION, nodesIID, nwBldr.build());
197 CheckedFuture<Void, TransactionCommitFailedException> submit = writeTransaction.submit();
202 } catch (TransactionCommitFailedException e) {
203 LOG.warn("Failed to post {} ", nwBldr.build(), e);
208 LOG.info(" Unable to get Data broker for node " + nodeId);
215 * This method does a get operation on info subtree
216 * of the netconf device's config datastore and returns
217 * info object.It is required to get device attributes such
218 * as maxDegrees,maxSrgs.
220 * @param deviceDb Reference to device's databroker
221 * @return Info object
224 public Info getDeviceInfo(DataBroker deviceDb) {
225 ReadOnlyTransaction rtx = deviceDb.newReadOnlyTransaction();
226 InstanceIdentifier<Info> infoIID = InstanceIdentifier.create(OrgOpenroadmDevice.class).child(Info.class);
228 Optional<Info> ordmInfoObject = rtx.read(LogicalDatastoreType.CONFIGURATION, infoIID).get();
229 if (ordmInfoObject.isPresent()) {
230 return ordmInfoObject.get();
232 LOG.info("Info subtree is not present");
234 } catch (InterruptedException | ExecutionException ex) {
235 LOG.info("Read failed on info subtree for");
242 * This method does a get operation on degree subtree
243 * of the netconf device's config datastore and returns a list
244 * of all connection port objects.
245 * It is required for doing a selective get on ports that
246 * correspond to logical connection points of interest.
248 * @param deviceDb Reference to device's databroker
249 * @param ordmInfo Info subtree from the device
250 * @return List of connection ports object belonging to-
253 public List<ConnectionPorts> getDegreePorts(DataBroker deviceDb, Info ordmInfo) {
255 List<ConnectionPorts> degreeConPorts = new ArrayList<>();
256 ReadOnlyTransaction rtx = deviceDb.newReadOnlyTransaction();
259 //Get value for max degree from info subtree, required for iteration
260 //if not present assume to be 20 (temporary)
261 if (ordmInfo.getMaxDegrees() != null) {
262 maxDegree = ordmInfo.getMaxDegrees();
266 Integer degreeCounter = 1;
267 while (degreeCounter <= maxDegree) {
268 LOG.info("Getting Connection ports for Degree Number " + degreeCounter);
269 InstanceIdentifier<Degree> deviceIID = InstanceIdentifier.create(OrgOpenroadmDevice.class).child(
270 Degree.class, new DegreeKey(degreeCounter));
272 Optional<Degree> ordmDegreeObject = rtx.read(LogicalDatastoreType.CONFIGURATION, deviceIID).get();
274 if (ordmDegreeObject.isPresent()) {
275 degreeConPorts.addAll(new ArrayList<ConnectionPorts>(ordmDegreeObject.get().getConnectionPorts()));
278 LOG.info("Device has " + (degreeCounter - 1) + " degree");
281 } catch (InterruptedException | ExecutionException ex) {
282 LOG.info("Failed to read degree " + degreeCounter);
288 return degreeConPorts;
292 * This method does a get operation on shared risk group subtree
293 * of the netconf device's config datastore and returns a list
294 * of all circuit packs objects that are part of srgs.
295 * It is required to do a selective get on all the circuit packs
296 * that contain add/drop ports of interest.
298 * @param deviceDb Reference to device's databroker
299 * @param ordmInfo Info subtree from the device
300 * @return List of circuit packs object belonging to-
301 * shared risk group subtree
304 public List<org.opendaylight.yang.gen.v1.http.org.openroadm.device.rev161014.srg.CircuitPacks> getSrgCps(
305 DataBroker deviceDb, Info ordmInfo) {
307 List<org.opendaylight.yang.gen.v1.http.org.openroadm.device.rev161014.srg.CircuitPacks> srgCps =
309 ReadOnlyTransaction rtx = deviceDb.newReadOnlyTransaction();
311 //Get value for max Srg from info subtree, required for iteration
312 //if not present assume to be 20 (temporary)
313 if (ordmInfo.getMaxSrgs() != null) {
314 maxSrg = ordmInfo.getMaxSrgs();
319 Integer srgCounter = 1;
320 while (srgCounter <= maxSrg) {
321 LOG.info("Getting Circuitpacks for Srg Number " + srgCounter);
322 InstanceIdentifier<SharedRiskGroup> srgIID = InstanceIdentifier.create(OrgOpenroadmDevice.class).child(
323 SharedRiskGroup.class, new SharedRiskGroupKey(srgCounter));
325 Optional<SharedRiskGroup> ordmSrgObject = rtx.read(LogicalDatastoreType.CONFIGURATION, srgIID).get();
327 if (ordmSrgObject.isPresent()) {
330 new ArrayList<org.opendaylight.yang.gen.v1.http.org.openroadm.device.rev161014.srg
331 .CircuitPacks>(ordmSrgObject.get().getCircuitPacks()));
334 LOG.info("Device has " + (srgCounter - 1) + " Srg");
337 } catch (InterruptedException | ExecutionException ex) {
338 LOG.warn("Failed to read Srg " + srgCounter);
348 * This static method returns the DataBroker for a netconf
351 * @param nodeId Unique identifier for the mounted netconf-
353 * @param mps Reference to mount service
354 * @return Databroker for the given device
357 public static DataBroker getDeviceDataBroker(String nodeId, MountPointService mps) {
358 InstanceIdentifier<Node> netconfNodeIID = InstanceIdentifier.builder(NetworkTopology.class).child(
359 Topology.class, new TopologyKey(new TopologyId(TopologyNetconf.QNAME.getLocalName()))).child(Node.class,
360 new NodeKey(new NodeId(nodeId))).build();
362 // Get the mount point for the specified node
363 final Optional<MountPoint> netconfNodeOptional = mps.getMountPoint(netconfNodeIID);
364 if (netconfNodeOptional.isPresent()) {
365 MountPoint netconfNode = netconfNodeOptional.get();
366 // Get the DataBroker for the mounted node
367 DataBroker netconfNodeDataBroker = netconfNode.getService(DataBroker.class).get();
368 return netconfNodeDataBroker;
370 LOG.info("Device Data broker not found for :" + nodeId);