2 * Copyright © 2016 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.networkmodel.util;
11 import java.util.ArrayList;
12 import java.util.Collections;
13 import java.util.List;
14 import java.util.Optional;
15 import java.util.concurrent.ExecutionException;
16 import java.util.concurrent.TimeUnit;
17 import java.util.concurrent.TimeoutException;
19 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
20 import org.opendaylight.transportpce.common.NetworkUtils;
21 import org.opendaylight.transportpce.common.Timeouts;
22 import org.opendaylight.transportpce.common.device.DeviceTransactionManager;
23 import org.opendaylight.transportpce.common.network.NetworkTransactionService;
24 import org.opendaylight.transportpce.networkmodel.dto.NodeData;
25 import org.opendaylight.transportpce.networkmodel.dto.TopologyShard;
26 import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.portmapping.rev170228.network.Nodes;
27 import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.portmapping.rev170228.network.nodes.Mapping;
28 import org.opendaylight.yang.gen.v1.http.org.openroadm.common.network.rev181130.NetworkTypes1;
29 import org.opendaylight.yang.gen.v1.http.org.openroadm.common.network.rev181130.NetworkTypes1Builder;
30 import org.opendaylight.yang.gen.v1.http.org.openroadm.common.network.rev181130.networks.network.network.types.OpenroadmCommonNetworkBuilder;
31 import org.opendaylight.yang.gen.v1.http.org.openroadm.common.state.types.rev181130.State;
32 import org.opendaylight.yang.gen.v1.http.org.openroadm.common.types.rev161014.NodeTypes;
33 import org.opendaylight.yang.gen.v1.http.org.openroadm.degree.rev181130.degree.node.attributes.AvailableWavelengths;
34 import org.opendaylight.yang.gen.v1.http.org.openroadm.degree.rev181130.degree.node.attributes.AvailableWavelengthsBuilder;
35 import org.opendaylight.yang.gen.v1.http.org.openroadm.degree.rev181130.degree.node.attributes.AvailableWavelengthsKey;
36 import org.opendaylight.yang.gen.v1.http.org.openroadm.device.rev181019.circuit.pack.Ports;
37 import org.opendaylight.yang.gen.v1.http.org.openroadm.device.rev181019.circuit.pack.PortsKey;
38 import org.opendaylight.yang.gen.v1.http.org.openroadm.device.rev181019.circuit.packs.CircuitPacks;
39 import org.opendaylight.yang.gen.v1.http.org.openroadm.device.rev181019.circuit.packs.CircuitPacksKey;
40 import org.opendaylight.yang.gen.v1.http.org.openroadm.device.rev181019.degree.ConnectionPorts;
41 import org.opendaylight.yang.gen.v1.http.org.openroadm.device.rev181019.org.openroadm.device.container.OrgOpenroadmDevice;
42 import org.opendaylight.yang.gen.v1.http.org.openroadm.device.rev181019.org.openroadm.device.container.org.openroadm.device.Degree;
43 import org.opendaylight.yang.gen.v1.http.org.openroadm.device.rev181019.org.openroadm.device.container.org.openroadm.device.DegreeKey;
44 import org.opendaylight.yang.gen.v1.http.org.openroadm.device.rev181019.org.openroadm.device.container.org.openroadm.device.Info;
45 import org.opendaylight.yang.gen.v1.http.org.openroadm.device.rev181019.org.openroadm.device.container.org.openroadm.device.SharedRiskGroup;
46 import org.opendaylight.yang.gen.v1.http.org.openroadm.device.rev181019.org.openroadm.device.container.org.openroadm.device.SharedRiskGroupKey;
47 import org.opendaylight.yang.gen.v1.http.org.openroadm.network.topology.rev181130.Link1;
48 import org.opendaylight.yang.gen.v1.http.org.openroadm.network.topology.rev181130.Link1Builder;
49 import org.opendaylight.yang.gen.v1.http.org.openroadm.network.topology.rev181130.Node1;
50 import org.opendaylight.yang.gen.v1.http.org.openroadm.network.topology.rev181130.Node1Builder;
51 import org.opendaylight.yang.gen.v1.http.org.openroadm.network.topology.rev181130.TerminationPoint1;
52 import org.opendaylight.yang.gen.v1.http.org.openroadm.network.topology.rev181130.TerminationPoint1Builder;
53 import org.opendaylight.yang.gen.v1.http.org.openroadm.network.topology.rev181130.networks.network.node.DegreeAttributesBuilder;
54 import org.opendaylight.yang.gen.v1.http.org.openroadm.network.topology.rev181130.networks.network.node.SrgAttributesBuilder;
55 import org.opendaylight.yang.gen.v1.http.org.openroadm.network.topology.rev181130.networks.network.node.termination.point.XpdrClientAttributesBuilder;
56 import org.opendaylight.yang.gen.v1.http.org.openroadm.network.topology.rev181130.networks.network.node.termination.point.XpdrNetworkAttributesBuilder;
57 import org.opendaylight.yang.gen.v1.http.org.openroadm.network.types.rev181130.OpenroadmLinkType;
58 import org.opendaylight.yang.gen.v1.http.org.openroadm.network.types.rev181130.OpenroadmNodeType;
59 import org.opendaylight.yang.gen.v1.http.org.openroadm.network.types.rev181130.OpenroadmTpType;
60 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.rev180226.NetworkId;
61 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.rev180226.Networks;
62 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.rev180226.NodeId;
63 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.rev180226.networks.Network;
64 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.rev180226.networks.NetworkBuilder;
65 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.rev180226.networks.NetworkKey;
66 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.rev180226.networks.network.NetworkTypesBuilder;
67 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.rev180226.networks.network.Node;
68 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.rev180226.networks.network.NodeBuilder;
69 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.rev180226.networks.network.NodeKey;
70 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.rev180226.networks.network.node.SupportingNode;
71 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.rev180226.networks.network.node.SupportingNodeBuilder;
72 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.rev180226.networks.network.node.SupportingNodeKey;
73 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.topology.rev180226.LinkId;
74 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.topology.rev180226.Network1;
75 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.topology.rev180226.Network1Builder;
76 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.topology.rev180226.TpId;
77 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.topology.rev180226.networks.network.Link;
78 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.topology.rev180226.networks.network.LinkBuilder;
79 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.topology.rev180226.networks.network.LinkKey;
80 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.topology.rev180226.networks.network.node.TerminationPoint;
81 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.topology.rev180226.networks.network.node.TerminationPointBuilder;
82 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.topology.rev180226.networks.network.node.TerminationPointKey;
83 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
84 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier.InstanceIdentifierBuilder;
85 import org.slf4j.Logger;
86 import org.slf4j.LoggerFactory;
88 public class OpenRoadmTopology22 {
90 private static final Logger LOG = LoggerFactory.getLogger(OpenRoadmTopology22.class);
91 private static final int DEFAULT_PORT_DIRECTION = -1;
92 private static final int MAX_DEGREE = 20;
93 private static final int MAX_SRG = 20;
95 private NetworkTransactionService networkTransactionService;
96 private final DeviceTransactionManager deviceTransactionManager;
98 public OpenRoadmTopology22(NetworkTransactionService networkTransactionService,
99 DeviceTransactionManager deviceTransactionManager) {
100 this.networkTransactionService = networkTransactionService;
101 this.deviceTransactionManager = deviceTransactionManager;
105 * This public method creates the OpenROADM Topology
106 * Layer and posts it to the controller.
108 public void createTopoLayer() {
110 Network openRoadmTopology = createOpenRoadmTopology();
111 InstanceIdentifierBuilder<Network> nwIID = InstanceIdentifier.builder(Networks.class).child(Network.class,
112 new NetworkKey(new NetworkId(NetworkUtils.OVERLAY_NETWORK_ID)));
114 this.networkTransactionService.put(LogicalDatastoreType.CONFIGURATION, nwIID.build(), openRoadmTopology);
115 this.networkTransactionService.submit().get(1, TimeUnit.SECONDS);
116 LOG.info("OpenRoadm-Topology created successfully.");
117 } catch (ExecutionException | TimeoutException | InterruptedException e) {
118 LOG.warn("Failed to create OpenRoadm-Topology", e);
123 * Create empty OpenROADM topology.
125 private Network createOpenRoadmTopology() {
126 NetworkBuilder nwBuilder = new NetworkBuilder();
127 NetworkId nwId = new NetworkId(NetworkUtils.OVERLAY_NETWORK_ID);
128 nwBuilder.setNetworkId(nwId);
129 nwBuilder.withKey(new NetworkKey(nwId));
130 NetworkTypes1Builder topoNetworkTypesBldr = new NetworkTypes1Builder();
131 topoNetworkTypesBldr.setOpenroadmCommonNetwork(new OpenroadmCommonNetworkBuilder().build());
132 NetworkTypesBuilder nwTypeBuilder = new NetworkTypesBuilder();
133 nwTypeBuilder.addAugmentation(NetworkTypes1.class, topoNetworkTypesBldr.build());
134 nwBuilder.setNetworkTypes(nwTypeBuilder.build());
135 // Array to store nodes in the topolayer of a roadm/Xponder
136 Network1Builder nwBldr1 = new Network1Builder();
137 // adding expressLinks
138 nwBldr1.setLink(Collections.emptyList());
139 nwBuilder.addAugmentation(Network1.class, nwBldr1.build());
140 nwBuilder.setNode(Collections.emptyList());
141 return nwBuilder.build();
144 public TopologyShard createTopologyShard(Nodes mappingNode) {
147 int portDirectionEnum = DEFAULT_PORT_DIRECTION;
148 String nodeId = mappingNode.getNodeId();
150 InstanceIdentifier<Info> infoIID = InstanceIdentifier.create(OrgOpenroadmDevice.class).child(Info.class);
151 java.util.Optional<Info> deviceInfoOpt =
152 deviceTransactionManager.getDataFromDevice(nodeId, LogicalDatastoreType.OPERATIONAL, infoIID,
153 Timeouts.DEVICE_READ_TIMEOUT, Timeouts.DEVICE_READ_TIMEOUT_UNIT);
155 if (deviceInfoOpt.isPresent()) {
156 deviceInfo = deviceInfoOpt.get();
158 LOG.error("Unable to get device info for device {}!", nodeId);
161 List<Node> nodes = new ArrayList<>();
162 // Check if node is ROADM
163 if (NodeTypes.Rdm.getName().equals(mappingNode.getNodeType().getName())) {
166 * Adding Degree Node Get Degree Number -> x then get connection ports then find the port directions
167 * to decide whether TX/RX/TXRX Get value for max degree from info subtree, required for iteration
168 * if not present assume to be 20 (temporary)
172 if (deviceInfo.getMaxDegrees() != null) {
173 maxDegree = deviceInfo.getMaxDegrees();
175 maxDegree = MAX_DEGREE;
178 // Starting with degree Number = 1
179 Integer degreeCounter = 1;
181 while (degreeCounter <= maxDegree) {
182 LOG.info("creating degree node {}/{}", degreeCounter, maxDegree);
183 NodeData nodeData = createDegreeNode(nodeId, degreeCounter);
184 if (nodeData != null) {
185 NodeBuilder tempNode = nodeData.getNodeBuilder();
186 portDirectionEnum = nodeData.getPortDirectionEnum();
187 nodes.add(tempNode.build());
190 // null returned if Degree number= degreeCounter not present in the device
195 numOfDegrees = degreeCounter - 1;
198 if (deviceInfo.getMaxSrgs() != null) {
199 maxSrg = deviceInfo.getMaxSrgs();
204 // Starting with degree Number = 1
205 Integer srgCounter = 1;
207 while (srgCounter <= maxSrg) {
208 LOG.info("creating SRG node {}/{}", srgCounter, maxSrg);
209 NodeBuilder tempNode = createSrgNode(nodeId, srgCounter, portDirectionEnum);
211 if (tempNode != null) {
212 nodes.add(tempNode.build());
215 // null returned if Degree number= degreeCounter not present in the device
219 numOfSrgs = srgCounter - 1;
222 LOG.info("adding links numOfDegrees={} numOfSrgs={}", numOfDegrees, numOfSrgs);
223 List<Link> links = new ArrayList<>();
224 links.addAll(createExpressLinks(nodeId, numOfDegrees, portDirectionEnum));
225 links.addAll(createAddDropLinks(nodeId, numOfDegrees, numOfSrgs, portDirectionEnum));
226 LOG.info("created nodes/links: {}/{}", nodes.size(), links.size());
227 return new TopologyShard(nodes, links);
228 } else if (NodeTypes.Xpdr.getName().equals(mappingNode.getNodeType().getName())) {
229 // Check if node is XPONDER
230 LOG.info("creating xpdr node in openroadmtopology for node {}", mappingNode.getNodeId());
231 NodeBuilder ietfNode = createXpdr(mappingNode);
232 nodes.add(ietfNode.build());
233 List<Link> links = new ArrayList<>();
234 return new TopologyShard(nodes, links);
236 LOG.error("Device node Type not managed yet");
241 * This private method gets the list of circuit packs on a xponder. For each circuit pack on a
242 * Xponder, it does a get on circuit-pack subtree with circuit-pack-name as key in order to get the
243 * list of ports. It then iterates over the list of ports to get ports with port-qual as
244 * xpdr-network/xpdr-client. The line and client ports are saved as:
252 private int getNoOfClientPorts(String deviceId) {
253 // Creating for Xponder Line and Client Ports
254 InstanceIdentifier<OrgOpenroadmDevice> deviceIID = InstanceIdentifier.create(OrgOpenroadmDevice.class);
255 Optional<OrgOpenroadmDevice> deviceObject =
256 deviceTransactionManager.getDataFromDevice(deviceId, LogicalDatastoreType.CONFIGURATION, deviceIID,
257 Timeouts.DEVICE_READ_TIMEOUT, Timeouts.DEVICE_READ_TIMEOUT_UNIT);
259 // Variable to keep track of number of client ports
261 if (deviceObject.isPresent()) {
262 for (CircuitPacks cp : deviceObject.get().getCircuitPacks()) {
263 if (cp.getPorts() != null) {
264 for (Ports port : cp.getPorts()) {
265 if ((port.getPortQual() != null) && (port.getPortQual().getIntValue() == 4)) {
277 private NodeBuilder createXpdr(Nodes mappingNode) {
278 // Create ietf node setting supporting-node data
279 NodeBuilder ietfNodeBldr = createTopoLayerNode(mappingNode.getNodeId());
281 String nodeIdtopo = new StringBuilder().append(mappingNode.getNodeId()).append("-XPDR1").toString();
282 ietfNodeBldr.setNodeId(new NodeId(nodeIdtopo));
283 ietfNodeBldr.withKey((new NodeKey(new NodeId(nodeIdtopo))));
284 // Create openroadm-network-topo augmentation to set node type to Xponder
285 Node1Builder ontNode1Bldr = new Node1Builder();
286 ontNode1Bldr.setNodeType(OpenroadmNodeType.XPONDER);
287 ietfNodeBldr.addAugmentation(Node1.class, ontNode1Bldr.build());
290 List<TerminationPoint> tpList = new ArrayList<>();
291 TerminationPointBuilder ietfTpBldr;
292 for (Mapping m : mappingNode.getMapping()) {
293 ietfTpBldr = createTpBldr(m.getLogicalConnectionPoint());
294 // Add openroadm-network-topology tp augmentations
295 TerminationPoint1Builder ontTp1Bldr = new TerminationPoint1Builder();
296 if (m.getPortQual().equals("xpdr-network")) {
297 ontTp1Bldr.setTpType(OpenroadmTpType.XPONDERNETWORK);
298 XpdrNetworkAttributesBuilder xpdrNwAttrBldr = new XpdrNetworkAttributesBuilder();
299 xpdrNwAttrBldr.setTailEquipmentId(m.getAssociatedLcp());
300 ontTp1Bldr.setXpdrNetworkAttributes(xpdrNwAttrBldr.build());
301 ietfTpBldr.addAugmentation(TerminationPoint1.class, ontTp1Bldr.build());
302 org.opendaylight.yang.gen.v1.http.transportpce.topology.rev190625
303 .TerminationPoint1Builder tpceTp1Bldr = new org.opendaylight.yang.gen.v1.http.transportpce
304 .topology.rev190625.TerminationPoint1Builder();
305 tpceTp1Bldr.setAssociatedConnectionMapPort(m.getAssociatedLcp());
306 ietfTpBldr.addAugmentation(org.opendaylight.yang.gen.v1.http.transportpce.topology.rev190625
307 .TerminationPoint1.class, tpceTp1Bldr.build());
308 tpList.add(ietfTpBldr.build());
309 } else if (m.getPortQual().equals("xpdr-client")) {
310 ontTp1Bldr.setTpType(OpenroadmTpType.XPONDERCLIENT);
311 XpdrClientAttributesBuilder xpdrNwAttrBldr = new XpdrClientAttributesBuilder();
312 xpdrNwAttrBldr.setTailEquipmentId(m.getAssociatedLcp());
313 ontTp1Bldr.setXpdrClientAttributes(xpdrNwAttrBldr.build());
314 ietfTpBldr.addAugmentation(TerminationPoint1.class, ontTp1Bldr.build());
315 org.opendaylight.yang.gen.v1.http.transportpce.topology.rev190625
316 .TerminationPoint1Builder tpceTp1Bldr = new org.opendaylight.yang.gen.v1.http.transportpce
317 .topology.rev190625.TerminationPoint1Builder();
318 tpceTp1Bldr.setAssociatedConnectionMapPort(m.getAssociatedLcp());
319 ietfTpBldr.addAugmentation(org.opendaylight.yang.gen.v1.http.transportpce.topology.rev190625
320 .TerminationPoint1.class, tpceTp1Bldr.build());
321 tpList.add(ietfTpBldr.build());
325 // Create ietf node augmentation to support ietf tp-list
326 org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.topology.rev180226
327 .Node1Builder ietfNode1 = new org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.topology
328 .rev180226.Node1Builder();
329 ietfNode1.setTerminationPoint(tpList);
330 ietfNodeBldr.addAugmentation(
331 org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.topology.rev180226.Node1.class,
337 private NodeData createDegreeNode(String nodeId, int degreeCounter) {
338 // Create augmentation node to inorder to add degree
339 Node1Builder node1bldr = new Node1Builder();
340 // set node type to degree
341 node1bldr.setNodeType(OpenroadmNodeType.DEGREE);
343 // Get connection ports on degree number = degreeCounter in order to get port
345 List<ConnectionPorts> degreeConPorts = getDegreePorts(nodeId, degreeCounter);
346 if (degreeConPorts == null || degreeConPorts.isEmpty()) {
350 DegreeAttributesBuilder degAttBldr = new DegreeAttributesBuilder();
351 degAttBldr.setDegreeNumber(degreeCounter);
352 degAttBldr.setAvailableWavelengths(create96AvalWaveDegree());
353 node1bldr.setDegreeAttributes(degAttBldr.build());
355 String nodeIdtopo = new StringBuilder(nodeId).append("-DEG").append(degreeCounter).toString();
356 // Create a generic Topo Layer node
357 NodeBuilder nodebldr = createTopoLayerNode(nodeId);
358 nodebldr.setNodeId(new NodeId(nodeIdtopo));
359 // Ad degree node specific augmentation
360 nodebldr.addAugmentation(Node1.class, node1bldr.build());
361 // Get Port direction
362 int portDirectionEnum = getPortDirection(nodeId, degreeConPorts.get(0).getCircuitPackName(),
363 degreeConPorts.get(0).getPortName().toString());
366 * if bi-directional then create 2 tp's :
368 * --> TTP-TXRX --> CTP-TXRX
370 * if uni-directional :
377 TerminationPoint1Builder tp1Bldr = new TerminationPoint1Builder();
378 TerminationPointBuilder tempTpBldr;
380 List<TerminationPoint> tpList = new ArrayList<>();
381 if (portDirectionEnum == 1 || portDirectionEnum == 2) {
382 // ports are uni Directional on a degree, therefore 4 termination points
383 // Create TTP-TX termination
385 tempTpBldr = createTpBldr("DEG" + degreeCounter + "-TTP-TX");
386 tp1Bldr.setTpType(OpenroadmTpType.DEGREETXTTP);
387 tempTpBldr.addAugmentation(TerminationPoint1.class, tp1Bldr.build());
388 tpList.add(tempTpBldr.build());
390 // Create TTP-RX termination
391 tp1Bldr = new TerminationPoint1Builder();
392 tempTpBldr = createTpBldr("DEG" + degreeCounter + "-TTP-RX");
393 tp1Bldr.setTpType(OpenroadmTpType.DEGREERXTTP);
395 tempTpBldr.addAugmentation(TerminationPoint1.class,tp1Bldr.build());
396 tpList.add(tempTpBldr.build());
398 // Create CTP-TX termination
399 tp1Bldr = new TerminationPoint1Builder();
400 tempTpBldr = createTpBldr("DEG" + degreeCounter + "-CTP-TX");
401 tp1Bldr.setTpType(OpenroadmTpType.DEGREETXCTP);
402 tempTpBldr.addAugmentation(TerminationPoint1.class,tp1Bldr.build());
403 tpList.add(tempTpBldr.build());
405 // Create CTP-RX termination
406 tp1Bldr = new TerminationPoint1Builder();
407 tempTpBldr = createTpBldr("DEG" + degreeCounter + "-CTP-RX");
408 tp1Bldr.setTpType(OpenroadmTpType.DEGREERXCTP);
409 tempTpBldr.addAugmentation(TerminationPoint1.class,tp1Bldr.build());
410 tpList.add(tempTpBldr.build());
412 } else if (portDirectionEnum == 3) {
413 // Ports are bi directional therefore 2 termination points
414 // Create TTP-TXRX termination
415 tp1Bldr = new TerminationPoint1Builder();
416 tempTpBldr = createTpBldr("DEG" + degreeCounter + "-TTP-TXRX");
417 tp1Bldr.setTpType(OpenroadmTpType.DEGREETXRXTTP);
418 tempTpBldr.addAugmentation(TerminationPoint1.class,tp1Bldr.build());
419 tpList.add(tempTpBldr.build());
421 // Create CTP-TXRX termination
422 tp1Bldr = new TerminationPoint1Builder();
423 tempTpBldr = createTpBldr("DEG" + degreeCounter + "-CTP-TXRX");
424 tp1Bldr.setTpType(OpenroadmTpType.DEGREETXRXCTP);
425 tempTpBldr.addAugmentation(TerminationPoint1.class,tp1Bldr.build());
426 tpList.add(tempTpBldr.build());
430 org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.topology.rev180226.Node1Builder tpNode1
431 = new org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.topology
432 .rev180226.Node1Builder();
434 tpNode1.setTerminationPoint(tpList);
436 nodebldr.addAugmentation(
437 org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.topology.rev180226.Node1.class,
439 return new NodeData(nodebldr, portDirectionEnum);
443 private NodeBuilder createSrgNode(String nodeId, int srgCounter, int portDirectionEnum) {
444 // Create augmentation node to in order to add srg
445 Node1Builder node1bldr = new Node1Builder();
446 // set node type to SRG
447 node1bldr.setNodeType(OpenroadmNodeType.SRG);
449 node1bldr.setNodeType(OpenroadmNodeType.SRG);
451 SrgAttributesBuilder srgAttrBldr = new SrgAttributesBuilder();
452 srgAttrBldr.setAvailableWavelengths(create96AvalWaveSrg());
453 node1bldr.setSrgAttributes(srgAttrBldr.build());
454 // Create a generic Topo Layer node
455 NodeBuilder nodebldr = createTopoLayerNode(nodeId);
456 nodebldr.addAugmentation(Node1.class, node1bldr.build());
459 // Get connection ports on degree number = degreeCounter in order to get port
461 int maxPpPorts = getMaxPp(nodeId, srgCounter);
462 if (maxPpPorts == -1) {
467 String nodeIdtopo = new StringBuilder().append(nodeId).append("-SRG").append(srgCounter).toString();
468 nodebldr.setNodeId(new NodeId(nodeIdtopo));
469 List<TerminationPoint> tpList = new ArrayList<>();
471 TerminationPoint1Builder tp1Bldr;
472 TerminationPointBuilder tempTpBldr;
474 for (int i = 1; i <= maxPpPorts; i++) {
475 if (portDirectionEnum == 1 || portDirectionEnum == 2) {
476 if (i >= maxPpPorts / 2) {
479 // ports are uni Directional on a degree, therefore 4 termination points
480 // Create PP-TX termination
481 tempTpBldr = createTpBldr("SRG" + srgCounter + "-PP" + i + "-TX");
482 tp1Bldr = new TerminationPoint1Builder();
483 tp1Bldr.setTpType(OpenroadmTpType.SRGTXPP);
484 tempTpBldr.addAugmentation(TerminationPoint1.class, tp1Bldr.build());
485 tpList.add(tempTpBldr.build());
487 // Create PP-RX termination
488 tempTpBldr = createTpBldr("SRG" + srgCounter + "-PP" + i + "-RX");
489 tp1Bldr = new TerminationPoint1Builder();
490 tp1Bldr.setTpType(OpenroadmTpType.SRGRXPP);
491 tempTpBldr.addAugmentation(TerminationPoint1.class, tp1Bldr.build());
492 tpList.add(tempTpBldr.build());
494 } else if (portDirectionEnum == 3) {
495 // Ports are bi directional therefore 2 termination points
496 // Create PP-TXRX termination
497 tempTpBldr = createTpBldr("SRG" + srgCounter + "-PP" + i + "-TXRX");
498 tp1Bldr = new TerminationPoint1Builder();
499 tp1Bldr.setTpType(OpenroadmTpType.SRGTXRXPP);
500 tempTpBldr.addAugmentation(TerminationPoint1.class, tp1Bldr.build());
501 tpList.add(tempTpBldr.build());
505 switch (portDirectionEnum) {
506 case 1: // ports are uni Directional on a degree
508 // Create CP-TX termination
509 tempTpBldr = createTpBldr("SRG" + srgCounter + "-CP" + "-TX");
510 tp1Bldr = new TerminationPoint1Builder();
511 tp1Bldr.setTpType(OpenroadmTpType.SRGTXCP);
512 tempTpBldr.addAugmentation(TerminationPoint1.class, tp1Bldr.build());
513 tpList.add(tempTpBldr.build());
514 // Create CP-RX termination
515 tempTpBldr = createTpBldr("SRG" + srgCounter + "-CP" + "-RX");
516 tp1Bldr = new TerminationPoint1Builder();
517 tp1Bldr.setTpType(OpenroadmTpType.SRGRXCP);
518 tempTpBldr.addAugmentation(TerminationPoint1.class, tp1Bldr.build());
519 tpList.add(tempTpBldr.build());
522 // Ports are bi directional therefore 2 termination points
523 // Create CP-TXRX termination
524 tempTpBldr = createTpBldr("SRG" + srgCounter + "-CP" + "-TXRX");
525 tp1Bldr = new TerminationPoint1Builder();
526 tp1Bldr.setTpType(OpenroadmTpType.SRGTXRXCP);
527 tempTpBldr.addAugmentation(TerminationPoint1.class, tp1Bldr.build());
528 tpList.add(tempTpBldr.build());
531 LOG.error("No correponsding direction to the value: {}", portDirectionEnum);
535 org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.topology.rev180226.Node1Builder tpNode1 =
536 new org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.topology.rev180226.Node1Builder();
538 tpNode1.setTerminationPoint(tpList);
540 nodebldr.addAugmentation(
541 org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.topology.rev180226.Node1.class,
548 * This method will return the TTP ports in the device for a given degree number to be used by the
549 * node to create TTP and CTP termination point on the device
551 private List<ConnectionPorts> getDegreePorts(String deviceId, Integer degreeCounter) {
552 List<ConnectionPorts> degreeConPorts = new ArrayList<>();
553 LOG.info("Getting Connection ports for Degree Number {}", degreeCounter);
554 InstanceIdentifier<Degree> deviceIID =
555 InstanceIdentifier.create(OrgOpenroadmDevice.class).child(Degree.class, new DegreeKey(degreeCounter));
557 Optional<Degree> ordmDegreeObject =
558 deviceTransactionManager.getDataFromDevice(deviceId, LogicalDatastoreType.CONFIGURATION, deviceIID,
559 Timeouts.DEVICE_READ_TIMEOUT, Timeouts.DEVICE_READ_TIMEOUT_UNIT);
561 if (ordmDegreeObject.isPresent()) {
562 degreeConPorts.addAll(new ArrayList<>(ordmDegreeObject.get().getConnectionPorts()));
564 LOG.info("Device has {} degree", (degreeCounter - 1));
565 return Collections.emptyList();
567 return degreeConPorts;
570 private int getMaxPp(String deviceId, Integer srgCounter) {
572 LOG.info("Getting max pp ports for Srg Number {}", srgCounter);
573 InstanceIdentifier<SharedRiskGroup> deviceIID = InstanceIdentifier.create(OrgOpenroadmDevice.class)
574 .child(SharedRiskGroup.class, new SharedRiskGroupKey(srgCounter));
575 Optional<SharedRiskGroup> ordmSrgObject =
576 deviceTransactionManager.getDataFromDevice(deviceId, LogicalDatastoreType.OPERATIONAL, deviceIID,
577 Timeouts.DEVICE_READ_TIMEOUT, Timeouts.DEVICE_READ_TIMEOUT_UNIT);
578 if (ordmSrgObject.isPresent()) {
579 if (ordmSrgObject.get().getMaxAddDropPorts() != null) {
580 maxPpPorts = ordmSrgObject.get().getMaxAddDropPorts();
582 LOG.info("Max add drop ports absent");
586 LOG.info("SRG absent");
592 private NodeBuilder createTopoLayerNode(String nodeId) {
593 // Sets the value of Network-ref and Node-ref as a part of the supporting node
595 SupportingNodeBuilder supportbldr = new SupportingNodeBuilder();
596 supportbldr.withKey(new SupportingNodeKey(new NetworkId(NetworkUtils.UNDERLAY_NETWORK_ID), new NodeId(nodeId)));
597 supportbldr.setNetworkRef(new NetworkId(NetworkUtils.UNDERLAY_NETWORK_ID));
598 supportbldr.setNodeRef(new NodeId(nodeId));
599 ArrayList<SupportingNode> supportlist = new ArrayList<>();
600 supportlist.add(supportbldr.build());
601 NodeBuilder nodebldr = new NodeBuilder();
602 nodebldr.setSupportingNode(supportlist);
606 // Return 0 for null/error values
609 // Return 3 for bi-directional
611 private int getPortDirection(String deviceId, String circuitPackName, String portName) {
612 InstanceIdentifier<Ports> portIID = InstanceIdentifier.create(OrgOpenroadmDevice.class)
613 .child(CircuitPacks.class, new CircuitPacksKey(circuitPackName))
614 .child(Ports.class, new PortsKey(portName));
615 LOG.info("Fetching Port Direction for port {} at circuit pack {}", portName, circuitPackName);
616 Optional<Ports> portObject =
617 deviceTransactionManager.getDataFromDevice(deviceId, LogicalDatastoreType.OPERATIONAL, portIID,
618 Timeouts.DEVICE_READ_TIMEOUT, Timeouts.DEVICE_READ_TIMEOUT_UNIT);
619 if (portObject.isPresent()) {
620 Ports port = portObject.get();
621 if (port.getPortDirection() != null) {
622 return port.getPortDirection().getIntValue();
624 LOG.warn("Port direction value missing for {} {}", circuitPackName, port.getPortName());
631 // This method returns a generic termination point builder for a given tpid
632 private TerminationPointBuilder createTpBldr(String tpId) {
633 TerminationPointBuilder tpBldr = new TerminationPointBuilder();
634 TpId tp = new TpId(tpId);
635 TerminationPointKey tpKey = new TerminationPointKey(tp);
636 tpBldr.withKey(tpKey);
645 private List<Link> createExpressLinks(String nodeId, int numOfDegrees, int portDirectionEnum) {
646 LOG.info("creating express links {} {} {}", nodeId, numOfDegrees, portDirectionEnum);
647 List<Link> links = new ArrayList<>();
655 // ports are uni-directional
656 if (portDirectionEnum == 1 || portDirectionEnum == 2) {
657 LOG.info("creating uni-directional express links");
658 for (int i = 1; i <= numOfDegrees; i++) {
659 for (int j = i + 1; j <= numOfDegrees; j++) {
661 srcNode = nodeId + "-DEG" + i;
662 destNode = nodeId + "-DEG" + j;
665 srcTp = "DEG" + i + "-CTP-TX";
666 destTp = "DEG" + j + "-CTP-RX";
668 LinkBuilder expLinkBldr = TopologyUtils.createLink(srcNode, destNode, srcTp, destTp);
670 Link1Builder lnk1Bldr = new Link1Builder();
671 lnk1Bldr.setLinkType(OpenroadmLinkType.EXPRESSLINK);
672 expLinkBldr.addAugmentation(Link1.class, lnk1Bldr.build());
673 links.add(expLinkBldr.build());
676 srcTp = "DEG" + i + "-CTP-RX";
677 destTp = "DEG" + j + "-CTP-TX";
679 expLinkBldr = TopologyUtils.createLink(destNode, srcNode, destTp, srcTp);
680 expLinkBldr.addAugmentation(Link1.class, lnk1Bldr.build());
681 links.add(expLinkBldr.build());
687 // ports are bi-directional
688 if (portDirectionEnum == 3) {
689 LOG.info("creating bi-directional express links");
690 for (int i = 1; i <= numOfDegrees; i++) {
691 for (int j = i + 1; j <= numOfDegrees; j++) {
693 srcNode = nodeId + "-DEG" + i;
694 destNode = nodeId + "-DEG" + j;
697 srcTp = "DEG" + i + "-CTP-TXRX";
698 destTp = "DEG" + j + "-CTP-TXRX";
700 Link1Builder lnk1Bldr = new Link1Builder();
701 lnk1Bldr.setLinkType(OpenroadmLinkType.EXPRESSLINK);
702 LinkBuilder expLinkBldr = TopologyUtils.createLink(srcNode, destNode, srcTp, destTp);
703 expLinkBldr.addAugmentation(Link1.class, lnk1Bldr.build());
704 links.add(expLinkBldr.build());
707 expLinkBldr = TopologyUtils.createLink(destNode, srcNode, destTp, srcTp);
708 expLinkBldr.addAugmentation(Link1.class, lnk1Bldr.build());
709 links.add(expLinkBldr.build());
716 private List<Link> createAddDropLinks(String nodeId, int numOfDegrees, int numOfSrgs, int portDirectionEnum) {
717 LOG.info("creating add-drop links {} {} {} {}", nodeId, numOfDegrees, numOfSrgs, portDirectionEnum);
718 List<Link> links = new ArrayList<>();
726 // ports are uni-directional
727 if (portDirectionEnum == 1 || portDirectionEnum == 2) {
728 LOG.info("creating uni-directional add-drop links");
729 for (int i = 1; i <= numOfDegrees; i++) {
730 for (int j = 1; j <= numOfSrgs; j++) {
732 srcNode = nodeId + "-DEG" + i;
733 destNode = nodeId + "-SRG" + j;
736 srcTp = "DEG" + i + "-CTP-TX";
737 destTp = "SRG" + j + "-CP-RX";
739 LinkBuilder addDropLinkBldr = TopologyUtils.createLink(srcNode, destNode, srcTp, destTp);
740 Link1Builder lnk1Bldr = new Link1Builder();
741 lnk1Bldr.setLinkType(OpenroadmLinkType.DROPLINK);
742 addDropLinkBldr.addAugmentation(Link1.class, lnk1Bldr.build());
743 links.add(addDropLinkBldr.build());
745 // add links direction
746 srcTp = "DEG" + i + "-CTP-RX";
747 destTp = "SRG" + j + "-CP-TX";
749 addDropLinkBldr = TopologyUtils.createLink(destNode, srcNode, destTp, srcTp);
750 lnk1Bldr.setLinkType(OpenroadmLinkType.ADDLINK);
751 addDropLinkBldr.addAugmentation(Link1.class, lnk1Bldr.build());
752 links.add(addDropLinkBldr.build());
757 // ports are bi-directional
758 if (portDirectionEnum == 3) {
759 LOG.info("creating bi-directional add-drop links");
760 for (int i = 1; i <= numOfDegrees; i++) {
761 for (int j = 1; j <= numOfSrgs; j++) {
763 srcNode = nodeId + "-DEG" + i;
764 destNode = nodeId + "-SRG" + j;
767 srcTp = "DEG" + i + "-CTP-TXRX";
768 destTp = "SRG" + j + "-CP-TXRX";
770 LinkBuilder addDropLinkBldr = TopologyUtils.createLink(srcNode, destNode, srcTp, destTp);
771 Link1Builder lnk1Bldr = new Link1Builder();
772 lnk1Bldr.setLinkType(OpenroadmLinkType.DROPLINK);
773 addDropLinkBldr.addAugmentation(Link1.class, lnk1Bldr.build());
774 links.add(addDropLinkBldr.build());
777 addDropLinkBldr = TopologyUtils.createLink(destNode, srcNode, destTp, srcTp);
778 lnk1Bldr.setLinkType(OpenroadmLinkType.ADDLINK);
779 addDropLinkBldr.addAugmentation(Link1.class, lnk1Bldr.build());
780 links.add(addDropLinkBldr.build());
787 // This method returns the linkBuilder object for given source and destination
788 public static boolean deleteLink(String srcNode, String dstNode, String srcTp, String destTp,
789 NetworkTransactionService networkTransactionService) {
790 LOG.info("deleting link for {}-{}", srcNode, dstNode);
791 LinkId linkId = LinkIdUtil.buildLinkId(srcNode, srcTp, dstNode, destTp);
792 if (deleteLinkLinkId(linkId, networkTransactionService)) {
793 LOG.debug("Link Id {} updated to have admin state down");
796 LOG.debug("Link Id not found for Source {} and Dest {}", srcNode, dstNode);
801 // This method returns the linkBuilder object for given source and destination
802 public static boolean deleteLinkLinkId(LinkId linkId , NetworkTransactionService networkTransactionService) {
803 LOG.info("deleting link for LinkId: {}", linkId);
805 InstanceIdentifierBuilder<Link> linkIID = InstanceIdentifier.builder(Networks.class).child(Network.class,
806 new NetworkKey(new NetworkId(NetworkUtils.OVERLAY_NETWORK_ID))).augmentation(Network1.class)
807 .child(Link.class, new LinkKey(linkId));
808 com.google.common.base.Optional<Link> link =
809 networkTransactionService.read(LogicalDatastoreType.CONFIGURATION,linkIID.build()).get();
810 if (link.isPresent()) {
811 LinkBuilder linkBuilder = new LinkBuilder(link.get());
812 Link1Builder link1Builder = new Link1Builder(linkBuilder.augmentation(org.opendaylight
813 .yang.gen.v1.http.org.openroadm.network.topology.rev181130.Link1.class));
814 link1Builder.setAdministrativeState(State.OutOfService);
815 linkBuilder.removeAugmentation(Link1.class);
816 linkBuilder.addAugmentation(Link1.class,link1Builder.build());
817 networkTransactionService.merge(LogicalDatastoreType.CONFIGURATION, linkIID.build(),
818 linkBuilder.build());
819 networkTransactionService.submit().get(1, TimeUnit.SECONDS);
822 LOG.error("No link found for given LinkId: {}",
827 } catch (InterruptedException | ExecutionException | TimeoutException e) {
828 LOG.error(e.getMessage(), e);
833 private List<AvailableWavelengths> create96AvalWaveDegree() {
834 List<AvailableWavelengths> waveList = new ArrayList<>();
836 for (int i = 1; i < 97; i++) {
837 AvailableWavelengthsBuilder avalBldr = new AvailableWavelengthsBuilder();
838 avalBldr.setIndex((long) i);
839 avalBldr.withKey(new AvailableWavelengthsKey((long) i));
840 waveList.add(avalBldr.build());
846 private List<org.opendaylight.yang.gen.v1.http.org.openroadm.srg.rev181130.srg.node
847 .attributes.AvailableWavelengths> create96AvalWaveSrg() {
849 List<org.opendaylight.yang.gen.v1.http.org.openroadm.srg.rev181130.srg.node.attributes
850 .AvailableWavelengths> waveList =
853 for (int i = 1; i < 97; i++) {
854 org.opendaylight.yang.gen.v1.http.org.openroadm.srg.rev181130.srg.node.attributes
855 .AvailableWavelengthsBuilder avalBldr =
856 new org.opendaylight.yang.gen.v1.http.org.openroadm.srg.rev181130.srg.node
857 .attributes.AvailableWavelengthsBuilder();
858 avalBldr.setIndex((long) i);
860 new org.opendaylight.yang.gen.v1.http.org.openroadm.srg.rev181130.srg.node
861 .attributes.AvailableWavelengthsKey(
863 waveList.add(avalBldr.build());