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.binding.api.DataBroker;
20 import org.opendaylight.controller.md.sal.binding.api.WriteTransaction;
21 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
22 import org.opendaylight.transportpce.common.NetworkUtils;
23 import org.opendaylight.transportpce.common.Timeouts;
24 import org.opendaylight.transportpce.common.device.DeviceTransactionManager;
25 import org.opendaylight.transportpce.networkmodel.dto.NodeData;
26 import org.opendaylight.transportpce.networkmodel.dto.TopologyShard;
27 import org.opendaylight.yang.gen.v1.http.org.openroadm.common.types.rev161014.NodeTypes;
28 import org.opendaylight.yang.gen.v1.http.org.openroadm.degree.rev170929.degree.node.attributes.AvailableWavelengths;
29 import org.opendaylight.yang.gen.v1.http.org.openroadm.degree.rev170929.degree.node.attributes.AvailableWavelengthsBuilder;
30 import org.opendaylight.yang.gen.v1.http.org.openroadm.degree.rev170929.degree.node.attributes.AvailableWavelengthsKey;
31 import org.opendaylight.yang.gen.v1.http.org.openroadm.device.rev170206.circuit.pack.Ports;
32 import org.opendaylight.yang.gen.v1.http.org.openroadm.device.rev170206.circuit.pack.PortsKey;
33 import org.opendaylight.yang.gen.v1.http.org.openroadm.device.rev170206.circuit.packs.CircuitPacks;
34 import org.opendaylight.yang.gen.v1.http.org.openroadm.device.rev170206.circuit.packs.CircuitPacksKey;
35 import org.opendaylight.yang.gen.v1.http.org.openroadm.device.rev170206.degree.ConnectionPorts;
36 import org.opendaylight.yang.gen.v1.http.org.openroadm.device.rev170206.org.openroadm.device.container.OrgOpenroadmDevice;
37 import org.opendaylight.yang.gen.v1.http.org.openroadm.device.rev170206.org.openroadm.device.container.org.openroadm.device.Degree;
38 import org.opendaylight.yang.gen.v1.http.org.openroadm.device.rev170206.org.openroadm.device.container.org.openroadm.device.DegreeKey;
39 import org.opendaylight.yang.gen.v1.http.org.openroadm.device.rev170206.org.openroadm.device.container.org.openroadm.device.Info;
40 import org.opendaylight.yang.gen.v1.http.org.openroadm.device.rev170206.org.openroadm.device.container.org.openroadm.device.SharedRiskGroup;
41 import org.opendaylight.yang.gen.v1.http.org.openroadm.device.rev170206.org.openroadm.device.container.org.openroadm.device.SharedRiskGroupKey;
42 import org.opendaylight.yang.gen.v1.http.org.openroadm.network.topology.rev170929.Link1;
43 import org.opendaylight.yang.gen.v1.http.org.openroadm.network.topology.rev170929.Link1Builder;
44 import org.opendaylight.yang.gen.v1.http.org.openroadm.network.topology.rev170929.NetworkTypes1;
45 import org.opendaylight.yang.gen.v1.http.org.openroadm.network.topology.rev170929.NetworkTypes1Builder;
46 import org.opendaylight.yang.gen.v1.http.org.openroadm.network.topology.rev170929.Node1;
47 import org.opendaylight.yang.gen.v1.http.org.openroadm.network.topology.rev170929.Node1Builder;
48 import org.opendaylight.yang.gen.v1.http.org.openroadm.network.topology.rev170929.TerminationPoint1;
49 import org.opendaylight.yang.gen.v1.http.org.openroadm.network.topology.rev170929.TerminationPoint1Builder;
50 import org.opendaylight.yang.gen.v1.http.org.openroadm.network.topology.rev170929.network.network.types.OpenroadmTopologyBuilder;
51 import org.opendaylight.yang.gen.v1.http.org.openroadm.network.topology.rev170929.network.node.DegreeAttributesBuilder;
52 import org.opendaylight.yang.gen.v1.http.org.openroadm.network.topology.rev170929.network.node.SrgAttributesBuilder;
53 import org.opendaylight.yang.gen.v1.http.org.openroadm.network.topology.rev170929.network.node.termination.point.XpdrClientAttributesBuilder;
54 import org.opendaylight.yang.gen.v1.http.org.openroadm.network.topology.rev170929.network.node.termination.point.XpdrNetworkAttributesBuilder;
55 import org.opendaylight.yang.gen.v1.http.org.openroadm.network.types.rev170929.OpenroadmLinkType;
56 import org.opendaylight.yang.gen.v1.http.org.openroadm.network.types.rev170929.OpenroadmNodeType;
57 import org.opendaylight.yang.gen.v1.http.org.openroadm.network.types.rev170929.OpenroadmTpType;
58 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.rev150608.Network;
59 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.rev150608.NetworkBuilder;
60 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.rev150608.NetworkId;
61 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.rev150608.NetworkKey;
62 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.rev150608.NodeId;
63 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.rev150608.network.NetworkTypesBuilder;
64 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.rev150608.network.Node;
65 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.rev150608.network.NodeBuilder;
66 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.rev150608.network.NodeKey;
67 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.rev150608.network.node.SupportingNode;
68 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.rev150608.network.node.SupportingNodeBuilder;
69 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.rev150608.network.node.SupportingNodeKey;
70 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.topology.rev150608.LinkId;
71 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.topology.rev150608.Network1;
72 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.topology.rev150608.Network1Builder;
73 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.topology.rev150608.TpId;
74 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.topology.rev150608.network.Link;
75 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.topology.rev150608.network.LinkBuilder;
76 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.topology.rev150608.network.LinkKey;
77 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.topology.rev150608.network.link.DestinationBuilder;
78 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.topology.rev150608.network.link.SourceBuilder;
79 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.topology.rev150608.network.node.TerminationPoint;
80 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.topology.rev150608.network.node.TerminationPointBuilder;
81 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.topology.rev150608.network.node.TerminationPointKey;
82 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
83 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier.InstanceIdentifierBuilder;
84 import org.slf4j.Logger;
85 import org.slf4j.LoggerFactory;
87 public class OpenRoadmTopology {
89 private static final Logger LOG = LoggerFactory.getLogger(OpenRoadmTopology.class);
90 private static final int DEFAULT_PORT_DIRECTION = -1;
91 private static final int MAX_DEGREE = 20;
92 private static final int MAX_SRG = 20;
94 private final DataBroker dataBroker;
95 private final DeviceTransactionManager deviceTransactionManager;
97 public OpenRoadmTopology(DataBroker dataBroker, DeviceTransactionManager deviceTransactionManager) {
98 this.dataBroker = dataBroker;
99 this.deviceTransactionManager = deviceTransactionManager;
103 * This public method creates the OpenROADM Topology Layer and posts it to
106 public void createTopoLayer(DataBroker controllerdb) {
108 Network openRoadmTopology = createOpenRoadmTopology();
109 InstanceIdentifierBuilder<Network> nwIID = InstanceIdentifier.builder(Network.class,
110 new NetworkKey(new NetworkId(NetworkUtils.OVERLAY_NETWORK_ID)));
111 WriteTransaction wrtx = controllerdb.newWriteOnlyTransaction();
112 wrtx.put(LogicalDatastoreType.CONFIGURATION, nwIID.build(), openRoadmTopology);
113 wrtx.submit().get(1, TimeUnit.SECONDS);
114 LOG.info("OpenRoadm-Topology created successfully.");
115 } catch (ExecutionException | TimeoutException | InterruptedException e) {
116 LOG.warn("Failed to create OpenRoadm-Topology", e);
121 * Create empty OpenROADM topology.
123 private Network createOpenRoadmTopology() {
124 NetworkBuilder nwBuilder = new NetworkBuilder();
125 NetworkId nwId = new NetworkId(NetworkUtils.OVERLAY_NETWORK_ID);
126 nwBuilder.setNetworkId(nwId);
127 nwBuilder.setKey(new NetworkKey(nwId));
128 // set network type to Transport Underlay
129 NetworkTypes1Builder topoNetworkTypesBldr = new NetworkTypes1Builder();
130 topoNetworkTypesBldr.setOpenroadmTopology(new OpenroadmTopologyBuilder().build());
131 NetworkTypesBuilder nwTypeBuilder = new NetworkTypesBuilder();
132 nwTypeBuilder.addAugmentation(NetworkTypes1.class, topoNetworkTypesBldr.build());
133 nwBuilder.setNetworkTypes(nwTypeBuilder.build());
134 // Array to store nodes in the topolayer of a roadm/Xponder
135 Network1Builder nwBldr1 = new Network1Builder();
136 // adding expressLinks
137 nwBldr1.setLink(Collections.emptyList());
138 nwBuilder.addAugmentation(Network1.class, nwBldr1.build());
139 nwBuilder.setNode(Collections.emptyList());
140 return nwBuilder.build();
143 public TopologyShard createTopologyShard(String nodeId) {
146 int portDirectionEnum = DEFAULT_PORT_DIRECTION;
148 InstanceIdentifier<Info> infoIID = InstanceIdentifier.create(OrgOpenroadmDevice.class).child(Info.class);
149 java.util.Optional<Info> deviceInfoOpt = this.deviceTransactionManager.getDataFromDevice(nodeId,
150 LogicalDatastoreType.OPERATIONAL, infoIID, Timeouts.DEVICE_READ_TIMEOUT,
151 Timeouts.DEVICE_READ_TIMEOUT_UNIT);
153 if (deviceInfoOpt.isPresent()) {
154 deviceInfo = deviceInfoOpt.get();
156 LOG.error("Unable to get device info for device {}!", nodeId);
159 List<Node> nodes = new ArrayList<>();
161 // Check if node is ROADM
162 if (NodeTypes.Rdm.equals(deviceInfo.getNodeType())) {
165 * Adding Degree Node Get Degree Number -> x
166 * then get connection ports
167 * then find the port directions to decide whether TX/RX/TXRX
168 * Get value for max degree from info subtree, required for iteration
169 * if not present assume to be 20 (temporary)
173 if (deviceInfo.getMaxDegrees() != null) {
174 maxDegree = deviceInfo.getMaxDegrees();
176 maxDegree = MAX_DEGREE;
179 // Starting with degree Number = 1
180 Integer degreeCounter = 1;
182 while (degreeCounter <= maxDegree) {
183 LOG.info("creating degree node {}/{}", degreeCounter, maxDegree);
184 NodeData nodeData = createDegreeNode(nodeId, degreeCounter);
185 if (nodeData != null) {
186 NodeBuilder tempNode = nodeData.getNodeBuilder();
187 portDirectionEnum = nodeData.getPortDirectionEnum();
188 nodes.add(tempNode.build());
191 // 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;
221 LOG.info("adding links numOfDegrees={} numOfSrgs={}", numOfDegrees, numOfSrgs);
222 List<Link> links = new ArrayList<>();
223 links.addAll(createExpressLinks(nodeId, numOfDegrees, portDirectionEnum));
224 links.addAll(createAddDropLinks(nodeId, numOfDegrees, numOfSrgs, portDirectionEnum));
225 LOG.info("created nodes/links: {}/{}", nodes.size(), links.size());
226 return new TopologyShard(nodes, links);
227 } else if (NodeTypes.Xpdr.equals(deviceInfo.getNodeType())) {
228 // Check if node is XPONDER
229 Integer clientport = getNoOfClientPorts(nodeId);
230 List<Link> links = new ArrayList<>();
231 Integer clientCounter = 1;
232 Integer lineCounter = 1;
233 while (clientCounter <= clientport) {
234 NodeBuilder tempNode = createXpdr(clientCounter, lineCounter, nodeId);
235 if (tempNode == null) {
238 nodes.add(tempNode.build());
241 LOG.info("Entered this loop");
243 return new TopologyShard(nodes, links);
250 * This private method gets the list of circuit packs on a xponder.
251 * For each circuit pack on a Xponder, it does a get on circuit-pack subtree with
252 * circuit-pack-name as key in order to get the list of ports.
253 * It then iterates over the list of ports to get ports with port-qual as
254 * xpdr-network/xpdr-client. The line and client ports are saved as:
262 private int getNoOfClientPorts(String deviceId) {
263 // Creating for Xponder Line and Client Ports
264 InstanceIdentifier<OrgOpenroadmDevice> deviceIID = InstanceIdentifier.create(OrgOpenroadmDevice.class);
265 Optional<OrgOpenroadmDevice> deviceObject = this.deviceTransactionManager.getDataFromDevice(deviceId,
266 LogicalDatastoreType.OPERATIONAL, deviceIID, Timeouts.DEVICE_READ_TIMEOUT,
267 Timeouts.DEVICE_READ_TIMEOUT_UNIT);
269 // Variable to keep track of number of client ports
271 if (deviceObject.isPresent()) {
272 for (CircuitPacks cp : deviceObject.get().getCircuitPacks()) {
273 if (cp.getPorts() != null) {
274 for (Ports port : cp.getPorts()) {
275 if (port.getPortQual() != null) {
276 if (port.getPortQual().getIntValue() == 4) {
289 private NodeBuilder createXpdr(Integer clientCounter, Integer lineCounter, String nodeId) {
290 // Create a generic Topo Layer node
291 NodeBuilder nodebldr = createTopoLayerNode(nodeId);
292 // Create augmentation node to inorder to add degree
293 Node1Builder node1bldr = new Node1Builder();
294 TerminationPoint1Builder tp1Bldr = new TerminationPoint1Builder();
295 TerminationPointBuilder tempTpBldr;
297 // set node type to Xponder
298 node1bldr.setNodeType(OpenroadmNodeType.XPONDER);
299 List<TerminationPoint> tpList = new ArrayList<>();
300 String nodeIdtopo = new StringBuilder().append(nodeId).append("-XPDR1").toString();
301 // Ad degree node specific augmentation
302 nodebldr.setNodeId(new NodeId(nodeIdtopo));
303 nodebldr.setKey(new NodeKey(new NodeId(nodeIdtopo)));
304 nodebldr.addAugmentation(Node1.class, node1bldr.build());
305 while (clientCounter != 0) {
306 // Create CLNT-TX termination
307 tempTpBldr = createTpBldr("XPDR1-CLIENT" + clientCounter);
308 tp1Bldr.setTpType(OpenroadmTpType.XPONDERCLIENT);
309 XpdrClientAttributesBuilder xpdrClntBldr = new XpdrClientAttributesBuilder();
310 xpdrClntBldr.setTailEquipmentId("XPDR1-NETWORK" + clientCounter);
311 tp1Bldr.setXpdrClientAttributes(xpdrClntBldr.build());
312 tempTpBldr.addAugmentation(TerminationPoint1.class, tp1Bldr.build());
313 tpList.add(tempTpBldr.build());
316 while (lineCounter != 0) {
317 // Create LINE-TX termination
318 tempTpBldr = (createTpBldr("XPDR1-NETWORK" + lineCounter));
319 tp1Bldr.setTpType(OpenroadmTpType.XPONDERNETWORK);
320 XpdrNetworkAttributesBuilder xpdrNwAttrBldr = new XpdrNetworkAttributesBuilder();
321 xpdrNwAttrBldr.setTailEquipmentId("XPDR1-CLIENT" + lineCounter);
322 tp1Bldr.setXpdrNetworkAttributes(xpdrNwAttrBldr.build());
323 tempTpBldr.addAugmentation(TerminationPoint1.class, tp1Bldr.build());
324 tpList.add(tempTpBldr.build());
327 LOG.info("printing tpList {}", tpList);
328 org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.topology.rev150608.Node1Builder tpNode1 =
329 new org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.topology.rev150608.Node1Builder();
330 tpNode1.setTerminationPoint(tpList);
331 nodebldr.addAugmentation(
332 org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.topology.rev150608.Node1.class,
334 LOG.info("The nodebldr {}", nodebldr);
338 private NodeData createDegreeNode(String nodeId, int degreeCounter) {
339 // Create augmentation node to inorder to add degree
340 Node1Builder node1bldr = new Node1Builder();
341 // set node type to degree
342 node1bldr.setNodeType(OpenroadmNodeType.DEGREE);
344 // Get connection ports on degree number = degreeCounter in order to get port
346 List<ConnectionPorts> degreeConPorts = getDegreePorts(nodeId, degreeCounter);
347 if ((degreeConPorts == null) || degreeConPorts.isEmpty()) {
351 DegreeAttributesBuilder degAttBldr = new DegreeAttributesBuilder();
352 degAttBldr.setDegreeNumber(degreeCounter);
353 degAttBldr.setAvailableWavelengths(create96AvalWaveDegree());
354 node1bldr.setDegreeAttributes(degAttBldr.build());
356 String nodeIdtopo = new StringBuilder(nodeId).append("-DEG").append(degreeCounter).toString();
357 // Create a generic Topo Layer node
358 NodeBuilder nodebldr = createTopoLayerNode(nodeId);
359 nodebldr.setNodeId(new NodeId(nodeIdtopo));
360 // Ad degree node specific augmentation
361 nodebldr.addAugmentation(Node1.class, node1bldr.build());
362 // Get Port direction
363 int portDirectionEnum = getPortDirection(nodeId, degreeConPorts.get(0).getCircuitPackName(),
364 degreeConPorts.get(0).getPortName().toString());
367 * if bi-directional then create 2 tp's :
369 * --> TTP-TXRX --> CTP-TXRX
371 * if uni-directional :
373 * --> TTP-TX --> TTP-RX --> CTP-TX --> CTP-RX
375 TerminationPoint1Builder tp1Bldr = new TerminationPoint1Builder();
376 TerminationPointBuilder tempTpBldr;
378 List<TerminationPoint> tpList = new ArrayList<>();
379 if ((portDirectionEnum == 1) || (portDirectionEnum == 2)) {
380 // ports are uni Directional on a degree, therefore 4 termination points
381 // Create TTP-TX termination
383 tempTpBldr = createTpBldr("DEG" + degreeCounter + "-TTP-TX");
384 tp1Bldr.setTpType(OpenroadmTpType.DEGREETXTTP);
385 tempTpBldr.addAugmentation(TerminationPoint1.class, tp1Bldr.build());
386 tpList.add(tempTpBldr.build());
388 // Create TTP-RX termination
389 tp1Bldr = new TerminationPoint1Builder();
390 tempTpBldr = createTpBldr("DEG" + degreeCounter + "-TTP-RX");
391 tp1Bldr.setTpType(OpenroadmTpType.DEGREERXTTP);
393 tempTpBldr.addAugmentation(TerminationPoint1.class, tp1Bldr.build());
394 tpList.add(tempTpBldr.build());
396 // Create CTP-TX termination
397 tp1Bldr = new TerminationPoint1Builder();
398 tempTpBldr = createTpBldr("DEG" + degreeCounter + "-CTP-TX");
399 tp1Bldr.setTpType(OpenroadmTpType.DEGREETXCTP);
400 tempTpBldr.addAugmentation(TerminationPoint1.class, tp1Bldr.build());
401 tpList.add(tempTpBldr.build());
403 // Create CTP-RX termination
404 tp1Bldr = new TerminationPoint1Builder();
405 tempTpBldr = createTpBldr("DEG" + degreeCounter + "-CTP-RX");
406 tp1Bldr.setTpType(OpenroadmTpType.DEGREERXCTP);
407 tempTpBldr.addAugmentation(TerminationPoint1.class, tp1Bldr.build());
408 tpList.add(tempTpBldr.build());
410 } else if (portDirectionEnum == 3) {
411 // Ports are bi directional therefore 2 termination points
412 // Create TTP-TXRX termination
413 tp1Bldr = new TerminationPoint1Builder();
414 tempTpBldr = createTpBldr("DEG" + degreeCounter + "-TTP-TXRX");
415 tp1Bldr.setTpType(OpenroadmTpType.DEGREETXRXTTP);
416 tempTpBldr.addAugmentation(TerminationPoint1.class, tp1Bldr.build());
417 tpList.add(tempTpBldr.build());
419 // Create CTP-TXRX termination
420 tp1Bldr = new TerminationPoint1Builder();
421 tempTpBldr = createTpBldr("DEG" + degreeCounter + "-CTP-TXRX");
422 tp1Bldr.setTpType(OpenroadmTpType.DEGREETXRXCTP);
423 tempTpBldr.addAugmentation(TerminationPoint1.class, tp1Bldr.build());
424 tpList.add(tempTpBldr.build());
428 org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.topology.rev150608.Node1Builder tpNode1 =
429 new org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.topology.rev150608.Node1Builder();
431 tpNode1.setTerminationPoint(tpList);
433 nodebldr.addAugmentation(
434 org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.topology.rev150608.Node1.class,
436 return new NodeData(nodebldr, portDirectionEnum);
439 private NodeBuilder createSrgNode(String nodeId, int srgCounter, int portDirectionEnum) {
440 // Create augmentation node to inorder to add degree
441 Node1Builder node1bldr = new Node1Builder();
442 // set node type to degree
443 node1bldr.setNodeType(OpenroadmNodeType.SRG);
445 node1bldr.setNodeType(OpenroadmNodeType.SRG);
447 SrgAttributesBuilder srgAttrBldr = new SrgAttributesBuilder();
448 srgAttrBldr.setAvailableWavelengths(create96AvalWaveSrg());
449 node1bldr.setSrgAttributes(srgAttrBldr.build());
451 // Create a generic Topo Layer node
452 NodeBuilder nodebldr = createTopoLayerNode(nodeId);
453 nodebldr.addAugmentation(Node1.class, node1bldr.build());
455 // Get connection ports on degree number = degreeCounter in order to get port
457 int maxPpPorts = getMaxPp(nodeId, srgCounter);
458 if (maxPpPorts == -1) {
462 String nodeIdtopo = new StringBuilder().append(nodeId).append("-SRG").append(srgCounter).toString();
463 nodebldr.setNodeId(new NodeId(nodeIdtopo));
464 List<TerminationPoint> tpList = new ArrayList<>();
466 TerminationPoint1Builder tp1Bldr;
467 TerminationPointBuilder tempTpBldr;
469 for (int i = 1; i <= maxPpPorts; i++) {
470 if ((portDirectionEnum == 1) || (portDirectionEnum == 2)) {
471 if (i >= (maxPpPorts / 2)) {
474 // ports are uni Directional on a degree, therefore 4 termination points
475 // Create PP-TX termination
476 tempTpBldr = createTpBldr("SRG" + srgCounter + "-PP" + i + "-TX");
477 tp1Bldr = new TerminationPoint1Builder();
478 tp1Bldr.setTpType(OpenroadmTpType.SRGTXPP);
479 tempTpBldr.addAugmentation(TerminationPoint1.class, tp1Bldr.build());
480 tpList.add(tempTpBldr.build());
482 // Create PP-RX termination
483 tempTpBldr = createTpBldr("SRG" + srgCounter + "-PP" + i + "-RX");
484 tp1Bldr = new TerminationPoint1Builder();
485 tp1Bldr.setTpType(OpenroadmTpType.SRGRXPP);
486 tempTpBldr.addAugmentation(TerminationPoint1.class, tp1Bldr.build());
487 tpList.add(tempTpBldr.build());
489 } else if (portDirectionEnum == 3) {
490 // Ports are bi directional therefore 2 termination points
491 // Create PP-TXRX termination
492 tempTpBldr = createTpBldr("SRG" + srgCounter + "-PP" + i + "-TXRX");
493 tp1Bldr = new TerminationPoint1Builder();
494 tp1Bldr.setTpType(OpenroadmTpType.SRGTXRXPP);
495 tempTpBldr.addAugmentation(TerminationPoint1.class, tp1Bldr.build());
496 tpList.add(tempTpBldr.build());
500 switch (portDirectionEnum) {
501 case 1: // ports are uni Directional on a degree
502 // Create CP-TX termination
503 tempTpBldr = createTpBldr("SRG" + srgCounter + "-CP" + "-TX");
504 tp1Bldr = new TerminationPoint1Builder();
505 tp1Bldr.setTpType(OpenroadmTpType.SRGTXCP);
506 tempTpBldr.addAugmentation(TerminationPoint1.class, tp1Bldr.build());
507 tpList.add(tempTpBldr.build());
510 // Create CP-RX termination
511 tempTpBldr = createTpBldr("SRG" + srgCounter + "-CP" + "-RX");
512 tp1Bldr = new TerminationPoint1Builder();
513 tp1Bldr.setTpType(OpenroadmTpType.SRGRXCP);
514 tempTpBldr.addAugmentation(TerminationPoint1.class, tp1Bldr.build());
515 tpList.add(tempTpBldr.build());
518 // Ports are bi directional therefore 2 termination points
519 // Create CP-TXRX termination
520 tempTpBldr = createTpBldr("SRG" + srgCounter + "-CP" + "-TXRX");
521 tp1Bldr = new TerminationPoint1Builder();
522 tp1Bldr.setTpType(OpenroadmTpType.SRGTXRXCP);
523 tempTpBldr.addAugmentation(TerminationPoint1.class, tp1Bldr.build());
524 tpList.add(tempTpBldr.build());
527 LOG.error("No correponsding direction to the value: {}", portDirectionEnum);
531 org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.topology.rev150608.Node1Builder tpNode1 =
532 new org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.topology.rev150608.Node1Builder();
534 tpNode1.setTerminationPoint(tpList);
536 nodebldr.addAugmentation(
537 org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.topology.rev150608.Node1.class,
544 * This method will return the TTP ports in the device for a given degree number to
545 * be used by the node to create TTP and CTP termination point on the device.
547 private List<ConnectionPorts> getDegreePorts(String deviceId, Integer degreeCounter) {
548 List<ConnectionPorts> degreeConPorts = new ArrayList<>();
549 LOG.info("Getting Connection ports for Degree Number {}", degreeCounter);
550 InstanceIdentifier<Degree> deviceIID = InstanceIdentifier.create(OrgOpenroadmDevice.class).child(Degree.class,
551 new DegreeKey(degreeCounter));
553 Optional<Degree> ordmDegreeObject = this.deviceTransactionManager.getDataFromDevice(deviceId,
554 LogicalDatastoreType.CONFIGURATION, deviceIID, Timeouts.DEVICE_READ_TIMEOUT,
555 Timeouts.DEVICE_READ_TIMEOUT_UNIT);
557 if (ordmDegreeObject.isPresent()) {
558 degreeConPorts.addAll(new ArrayList<>(ordmDegreeObject.get().getConnectionPorts()));
560 LOG.info("Device has {} degree", (degreeCounter - 1));
561 return Collections.emptyList();
563 return degreeConPorts;
566 private int getMaxPp(String deviceId, Integer srgCounter) {
568 LOG.info("Getting max pp ports for Srg Number {}", srgCounter);
569 InstanceIdentifier<SharedRiskGroup> deviceIID = InstanceIdentifier.create(OrgOpenroadmDevice.class)
570 .child(SharedRiskGroup.class, new SharedRiskGroupKey(srgCounter));
571 Optional<SharedRiskGroup> ordmSrgObject = this.deviceTransactionManager.getDataFromDevice(deviceId,
572 LogicalDatastoreType.OPERATIONAL, deviceIID, Timeouts.DEVICE_READ_TIMEOUT,
573 Timeouts.DEVICE_READ_TIMEOUT_UNIT);
574 if (ordmSrgObject.isPresent()) {
575 if (ordmSrgObject.get().getMaxAddDropPorts() != null) {
576 maxPpPorts = ordmSrgObject.get().getMaxAddDropPorts();
578 LOG.info("Max add drop ports absent");
582 LOG.info("SRG absent");
588 private NodeBuilder createTopoLayerNode(String nodeId) {
589 // Sets the value of Network-ref and Node-ref as a part of the supporting node
591 SupportingNodeBuilder supportbldr = new SupportingNodeBuilder();
592 supportbldr.setKey(new SupportingNodeKey(new NetworkId(NetworkUtils.UNDERLAY_NETWORK_ID), new NodeId(nodeId)));
593 supportbldr.setNetworkRef(new NetworkId(NetworkUtils.UNDERLAY_NETWORK_ID));
594 supportbldr.setNodeRef(new NodeId(nodeId));
595 ArrayList<SupportingNode> supportlist = new ArrayList<>();
596 supportlist.add(supportbldr.build());
597 NodeBuilder nodebldr = new NodeBuilder();
598 nodebldr.setSupportingNode(supportlist);
602 // Return 0 for null/error values
605 // Return 3 for bi-directional
607 private int getPortDirection(String deviceId, String circuitPackName, String portName) {
608 InstanceIdentifier<Ports> portIID = InstanceIdentifier.create(OrgOpenroadmDevice.class)
609 .child(CircuitPacks.class, new CircuitPacksKey(circuitPackName))
610 .child(Ports.class, new PortsKey(portName));
611 LOG.info("Fetching Port Direction for port {} at circuit pack {}", portName, circuitPackName);
612 Optional<Ports> portObject = this.deviceTransactionManager.getDataFromDevice(deviceId,
613 LogicalDatastoreType.OPERATIONAL, portIID, Timeouts.DEVICE_READ_TIMEOUT,
614 Timeouts.DEVICE_READ_TIMEOUT_UNIT);
615 if (portObject.isPresent()) {
616 Ports port = portObject.get();
617 if (port.getPortDirection() != null) {
618 return port.getPortDirection().getIntValue();
620 LOG.warn("Port direction value missing for {} {}", circuitPackName, port.getPortName());
627 // This method returns a generic termination point builder for a given tpid
628 private TerminationPointBuilder createTpBldr(String tpId) {
629 TerminationPointBuilder tpBldr = new TerminationPointBuilder();
630 TpId tp = new TpId(tpId);
631 TerminationPointKey tpKey = new TerminationPointKey(tp);
632 tpBldr.setKey(tpKey);
637 // This method returns the linkBuilder object for given source and destination.
638 public LinkBuilder createLink(String srcNode, String dstNode, String srcTp, String destTp) {
639 LOG.info("creating link for {}-{}", srcNode, dstNode);
640 // Create Destination for link
641 DestinationBuilder dstNodeBldr = new DestinationBuilder();
642 dstNodeBldr.setDestTp(destTp);
643 dstNodeBldr.setDestNode(new NodeId(dstNode));
644 // Create Source for the link
645 SourceBuilder srcNodeBldr = new SourceBuilder();
646 srcNodeBldr.setSourceNode(new NodeId(srcNode));
647 srcNodeBldr.setSourceTp(srcTp);
648 LinkBuilder lnkBldr = new LinkBuilder();
649 // set link builder attribute
650 lnkBldr.setDestination(dstNodeBldr.build());
651 lnkBldr.setSource(srcNodeBldr.build());
652 lnkBldr.setLinkId(LinkIdUtil.buildLinkId(srcNode, srcTp, dstNode, destTp));
653 lnkBldr.setKey(new LinkKey(lnkBldr.getLinkId()));
654 org.opendaylight.yang.gen.v1.http.org.openroadm.opposite.links.rev170929.Link1Builder lnk1Bldr =
655 new org.opendaylight.yang.gen.v1.http.org.openroadm.opposite.links.rev170929.Link1Builder();
656 LinkId oppositeLinkId = LinkIdUtil.getOppositeLinkId(srcNode, srcTp, dstNode, destTp);
657 lnk1Bldr.setOppositeLink(oppositeLinkId);
658 lnkBldr.addAugmentation(org.opendaylight.yang.gen.v1.http.org.openroadm.opposite.links.rev170929.Link1.class,
663 private List<Link> createExpressLinks(String nodeId, int numOfDegrees, int portDirectionEnum) {
664 LOG.info("creating express links {} {} {}", nodeId, numOfDegrees, portDirectionEnum);
665 List<Link> links = new ArrayList<>();
673 // ports are uni-directional
674 if ((portDirectionEnum == 1) || (portDirectionEnum == 2)) {
675 LOG.info("creating uni-directional express links");
676 for (int i = 1; i <= numOfDegrees; i++) {
677 for (int j = i + 1; j <= numOfDegrees; j++) {
679 srcNode = nodeId + "-DEG" + i;
680 destNode = nodeId + "-DEG" + j;
683 srcTp = "DEG" + i + "-CTP-TX";
684 destTp = "DEG" + j + "-CTP-RX";
686 LinkBuilder expLinkBldr = createLink(srcNode, destNode, srcTp, destTp);
688 Link1Builder lnk1Bldr = new Link1Builder();
689 lnk1Bldr.setLinkType(OpenroadmLinkType.EXPRESSLINK);
690 expLinkBldr.addAugmentation(Link1.class, lnk1Bldr.build());
692 links.add(expLinkBldr.build());
695 srcTp = "DEG" + i + "-CTP-RX";
696 destTp = "DEG" + j + "-CTP-TX";
698 expLinkBldr = createLink(destNode, srcNode, destTp, srcTp);
699 expLinkBldr.addAugmentation(Link1.class, lnk1Bldr.build());
701 links.add(expLinkBldr.build());
707 // ports are bi-directional
708 if (portDirectionEnum == 3) {
709 LOG.info("creating bi-directional express links");
710 for (int i = 1; i <= numOfDegrees; i++) {
711 for (int j = i + 1; j <= numOfDegrees; j++) {
713 srcNode = nodeId + "-DEG" + i;
714 destNode = nodeId + "-DEG" + j;
717 srcTp = "DEG" + i + "-CTP-TXRX";
718 destTp = "DEG" + j + "-CTP-TXRX";
720 Link1Builder lnk1Bldr = new Link1Builder();
721 lnk1Bldr.setLinkType(OpenroadmLinkType.EXPRESSLINK);
723 LinkBuilder expLinkBldr = createLink(srcNode, destNode, srcTp, destTp);
724 expLinkBldr.addAugmentation(Link1.class, lnk1Bldr.build());
725 links.add(expLinkBldr.build());
728 expLinkBldr = createLink(destNode, srcNode, destTp, srcTp);
729 expLinkBldr.addAugmentation(Link1.class, lnk1Bldr.build());
730 links.add(expLinkBldr.build());
737 private List<Link> createAddDropLinks(String nodeId, int numOfDegrees, int numOfSrgs, int portDirectionEnum) {
738 LOG.info("creating add-drop links {} {} {} {}", nodeId, numOfDegrees, numOfSrgs, portDirectionEnum);
739 List<Link> links = new ArrayList<>();
747 // ports are uni-directional
748 if ((portDirectionEnum == 1) || (portDirectionEnum == 2)) {
749 LOG.info("creating uni-directional add-drop links");
750 for (int i = 1; i <= numOfDegrees; i++) {
751 for (int j = 1; j <= numOfSrgs; j++) {
753 srcNode = nodeId + "-DEG" + i;
754 destNode = nodeId + "-SRG" + j;
757 srcTp = "DEG" + i + "-CTP-TX";
758 destTp = "SRG" + j + "-CP-RX";
760 LinkBuilder addDropLinkBldr = createLink(srcNode, destNode, srcTp, destTp);
761 Link1Builder lnk1Bldr = new Link1Builder();
762 lnk1Bldr.setLinkType(OpenroadmLinkType.DROPLINK);
763 addDropLinkBldr.addAugmentation(Link1.class, lnk1Bldr.build());
764 links.add(addDropLinkBldr.build());
766 // add links direction
767 srcTp = "DEG" + i + "-CTP-RX";
768 destTp = "SRG" + j + "-CP-TX";
770 addDropLinkBldr = createLink(destNode, srcNode, destTp, srcTp);
771 lnk1Bldr.setLinkType(OpenroadmLinkType.ADDLINK);
772 addDropLinkBldr.addAugmentation(Link1.class, lnk1Bldr.build());
773 links.add(addDropLinkBldr.build());
778 // ports are bi-directional
779 if (portDirectionEnum == 3) {
780 LOG.info("creating bi-directional add-drop links");
781 for (int i = 1; i <= numOfDegrees; i++) {
782 for (int j = 1; j <= numOfSrgs; j++) {
784 srcNode = nodeId + "-DEG" + i;
785 destNode = nodeId + "-SRG" + j;
788 srcTp = "DEG" + i + "-CTP-TXRX";
789 destTp = "SRG" + j + "-CP-TXRX";
791 LinkBuilder addDropLinkBldr = createLink(srcNode, destNode, srcTp, destTp);
792 Link1Builder lnk1Bldr = new Link1Builder();
793 lnk1Bldr.setLinkType(OpenroadmLinkType.DROPLINK);
794 addDropLinkBldr.addAugmentation(Link1.class, lnk1Bldr.build());
795 links.add(addDropLinkBldr.build());
798 addDropLinkBldr = createLink(destNode, srcNode, destTp, srcTp);
799 lnk1Bldr.setLinkType(OpenroadmLinkType.ADDLINK);
800 addDropLinkBldr.addAugmentation(Link1.class, lnk1Bldr.build());
801 links.add(addDropLinkBldr.build());
808 // This method returns the linkBuilder object for given source and destination.
809 public boolean deleteLink(String srcNode, String dstNode, String srcTp, String destTp) {
810 LOG.info("deleting link for {}-{}", srcNode, dstNode);
812 InstanceIdentifierBuilder<Link> linkIID = InstanceIdentifier
813 .builder(Network.class, new NetworkKey(new NetworkId(NetworkUtils.OVERLAY_NETWORK_ID)))
814 .augmentation(Network1.class)
815 .child(Link.class, new LinkKey(LinkIdUtil.buildLinkId(srcNode, srcTp, dstNode, destTp)));
816 WriteTransaction wrtx = this.dataBroker.newWriteOnlyTransaction();
817 wrtx.delete(LogicalDatastoreType.CONFIGURATION, linkIID.build());
818 wrtx.submit().get(1, TimeUnit.SECONDS);
819 } catch (InterruptedException | ExecutionException | TimeoutException e) {
820 LOG.error(e.getMessage(), e);
826 private List<AvailableWavelengths> create96AvalWaveDegree() {
827 List<AvailableWavelengths> waveList = new ArrayList<>();
829 for (int i = 1; i < 97; i++) {
830 AvailableWavelengthsBuilder avalBldr = new AvailableWavelengthsBuilder();
831 avalBldr.setIndex((long) i);
832 avalBldr.setKey(new AvailableWavelengthsKey((long) i));
833 waveList.add(avalBldr.build());
839 private List<org.opendaylight.yang.gen.v1.http.org.openroadm.srg.rev170929.srg.node.attributes.AvailableWavelengths>
840 create96AvalWaveSrg() {
842 List<org.opendaylight.yang.gen.v1.http.org.openroadm.srg.rev170929.srg.node.attributes.AvailableWavelengths>
843 waveList = new ArrayList<>();
845 for (int i = 1; i < 97; i++) {
846 org.opendaylight.yang.gen.v1.http.org.openroadm.srg.rev170929.srg.node.attributes
847 .AvailableWavelengthsBuilder avalBldr =
848 new org.opendaylight.yang.gen.v1.http.org.openroadm.srg.rev170929.srg.node.attributes
849 .AvailableWavelengthsBuilder();
850 avalBldr.setIndex((long) i);
852 new org.opendaylight.yang.gen.v1.http.org.openroadm.srg.rev170929.srg.node.attributes
853 .AvailableWavelengthsKey((long) i));
854 waveList.add(avalBldr.build());