25994f7116af65dd41600cea1dbb0e3555a232b2
[transportpce.git] / networkmodel / src / main / java / org / opendaylight / transportpce / networkmodel / util / OpenRoadmTopology.java
1 /*
2  * Copyright © 2016 AT&T and others.  All rights reserved.
3  *
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
7  */
8
9 package org.opendaylight.transportpce.networkmodel.util;
10
11 import static org.opendaylight.yang.gen.v1.http.org.openroadm.device.types.rev191129.XpdrNodeTypes.Tpdr;
12
13 import java.util.ArrayList;
14 import java.util.Comparator;
15 import java.util.HashMap;
16 import java.util.List;
17 import java.util.Map;
18 import java.util.concurrent.ExecutionException;
19 import java.util.concurrent.TimeUnit;
20 import java.util.concurrent.TimeoutException;
21 import java.util.stream.Collectors;
22 import org.opendaylight.mdsal.common.api.LogicalDatastoreType;
23 import org.opendaylight.transportpce.common.NetworkUtils;
24 import org.opendaylight.transportpce.common.fixedflex.GridUtils;
25 import org.opendaylight.transportpce.common.network.NetworkTransactionService;
26 import org.opendaylight.transportpce.networkmodel.dto.TopologyShard;
27 import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.portmapping.rev220316.mapping.Mapping;
28 import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.portmapping.rev220316.network.Nodes;
29 import org.opendaylight.yang.gen.v1.http.org.openroadm.common.network.rev211210.Link1;
30 import org.opendaylight.yang.gen.v1.http.org.openroadm.common.network.rev211210.Link1Builder;
31 import org.opendaylight.yang.gen.v1.http.org.openroadm.common.state.types.rev191129.State;
32 import org.opendaylight.yang.gen.v1.http.org.openroadm.equipment.states.types.rev191129.AdminStates;
33 import org.opendaylight.yang.gen.v1.http.org.openroadm.network.topology.rev211210.Node1;
34 import org.opendaylight.yang.gen.v1.http.org.openroadm.network.topology.rev211210.Node1Builder;
35 import org.opendaylight.yang.gen.v1.http.org.openroadm.network.topology.rev211210.TerminationPoint1;
36 import org.opendaylight.yang.gen.v1.http.org.openroadm.network.topology.rev211210.networks.network.node.DegreeAttributes;
37 import org.opendaylight.yang.gen.v1.http.org.openroadm.network.topology.rev211210.networks.network.node.DegreeAttributesBuilder;
38 import org.opendaylight.yang.gen.v1.http.org.openroadm.network.topology.rev211210.networks.network.node.SrgAttributes;
39 import org.opendaylight.yang.gen.v1.http.org.openroadm.network.topology.rev211210.networks.network.node.SrgAttributesBuilder;
40 import org.opendaylight.yang.gen.v1.http.org.openroadm.network.types.rev211210.OpenroadmLinkType;
41 import org.opendaylight.yang.gen.v1.http.org.openroadm.network.types.rev211210.OpenroadmNodeType;
42 import org.opendaylight.yang.gen.v1.http.org.openroadm.network.types.rev211210.OpenroadmTpType;
43 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.rev180226.NetworkId;
44 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.rev180226.Networks;
45 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.rev180226.NodeId;
46 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.rev180226.networks.Network;
47 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.rev180226.networks.NetworkKey;
48 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.rev180226.networks.network.Node;
49 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.rev180226.networks.network.NodeBuilder;
50 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.rev180226.networks.network.NodeKey;
51 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.rev180226.networks.network.node.SupportingNode;
52 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.rev180226.networks.network.node.SupportingNodeBuilder;
53 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.rev180226.networks.network.node.SupportingNodeKey;
54 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.topology.rev180226.LinkId;
55 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.topology.rev180226.Network1;
56 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.topology.rev180226.TpId;
57 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.topology.rev180226.networks.network.Link;
58 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.topology.rev180226.networks.network.LinkBuilder;
59 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.topology.rev180226.networks.network.LinkKey;
60 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.topology.rev180226.networks.network.link.DestinationBuilder;
61 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.topology.rev180226.networks.network.link.SourceBuilder;
62 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.topology.rev180226.networks.network.node.TerminationPoint;
63 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.topology.rev180226.networks.network.node.TerminationPointBuilder;
64 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.topology.rev180226.networks.network.node.TerminationPointKey;
65 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
66 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier.InstanceIdentifierBuilder;
67 import org.opendaylight.yangtools.yang.common.Uint16;
68 import org.slf4j.Logger;
69 import org.slf4j.LoggerFactory;
70
71 public final class OpenRoadmTopology {
72
73     private static final Logger LOG = LoggerFactory.getLogger(OpenRoadmTopology.class);
74
75     private static Map<String, OpenroadmTpType> PORTQUAL_ORD_TYPE_MAP = Map.of(
76         "xpdr-network", OpenroadmTpType.XPONDERNETWORK,
77         "switch-network", OpenroadmTpType.XPONDERNETWORK,
78         "xpdr-client", OpenroadmTpType.XPONDERCLIENT
79     );
80     private static Map<String, List<OpenroadmTpType>> PORTDIR_ORD_TYPE_MAP = Map.of(
81         "bidirectional", List.of(OpenroadmTpType.DEGREETXRXTTP, OpenroadmTpType.SRGTXRXPP),
82         "tx", List.of(OpenroadmTpType.DEGREETXTTP, OpenroadmTpType.SRGTXPP),
83         "rx", List.of(OpenroadmTpType.DEGREERXTTP, OpenroadmTpType.SRGRXPP)
84     );
85
86     private OpenRoadmTopology() {
87     }
88
89     public static TopologyShard createTopologyShard(Nodes mappingNode) {
90         return createTopologyShard(mappingNode, true);
91     }
92
93     public static TopologyShard createTopologyShard(Nodes mappingNode, boolean firstMount) {
94         switch (mappingNode.getNodeInfo().getNodeType()) {
95             case Rdm :
96                 return createRdmTopologyShard(mappingNode, firstMount);
97             case Xpdr :
98                 return createXpdrTopologyShard(mappingNode);
99             default :
100                 LOG.error("Device node Type not managed yet");
101                 return null;
102         }
103     }
104
105     public static TopologyShard createRdmTopologyShard(Nodes mappingNode, boolean firstMount) {
106         List<Node> nodes = new ArrayList<>();
107         LOG.info("creating rdm node in openroadmtopology for node {}",
108                 mappingNode.getNodeId());
109         // transform flat mapping list to per degree and per srg mapping lists
110         Map<String, List<Mapping>> mapDeg = new HashMap<>();
111         Map<String, List<Mapping>> mapSrg = new HashMap<>();
112         List<Mapping> mappingList = new ArrayList<>(mappingNode.nonnullMapping().values());
113         mappingList.sort(Comparator.comparing(Mapping::getLogicalConnectionPoint));
114         List<String> nodeShardList = new ArrayList<>();
115         for (Mapping mapping : mappingList) {
116             String str = mapping.getLogicalConnectionPoint().split("-")[0];
117             if (!nodeShardList.contains(str)) {
118                 nodeShardList.add(str);
119             }
120         }
121         for (String str : nodeShardList) {
122             List<Mapping> interList =
123                     mappingList.stream()
124                             .filter(x -> x.getLogicalConnectionPoint().split("-")[0].equals(str))
125                             .collect(Collectors.toList());
126             if (str.contains("DEG")) {
127                 mapDeg.put(str, interList);
128             } else if (str.contains("SRG")) {
129                 mapSrg.put(str, interList);
130             } else {
131                 LOG.error("unknow element");
132             }
133         }
134         // create degree nodes
135         for (Map.Entry<String, List<Mapping>> entry : mapDeg.entrySet()) {
136             nodes.add(
137                 createDegree(entry.getKey(), entry.getValue(), mappingNode.getNodeId(),
138                         mappingNode.getNodeInfo().getNodeClli(), firstMount)
139                     .build());
140         }
141         // create srg nodes
142         for (Map.Entry<String, List<Mapping>> entry : mapSrg.entrySet()) {
143             nodes.add(
144                 createSrg(entry.getKey(), entry.getValue(), mappingNode.getNodeId(),
145                         mappingNode.getNodeInfo().getNodeClli(), firstMount)
146                     .build());
147         }
148         LOG.info("adding links numOfDegrees={} numOfSrgs={}", mapDeg.size(), mapSrg.size());
149         List<Link> links = createNewLinks(nodes);
150         LOG.info("created nodes/links: {}/{}", nodes.size(), links.size());
151         return new TopologyShard(nodes, links);
152     }
153
154     public static TopologyShard createXpdrTopologyShard(Nodes mappingNode) {
155         List<Node> nodes = new ArrayList<>();
156         List<Mapping> networkMappings =
157                 mappingNode.nonnullMapping().values()
158                         .stream().filter(k -> k.getLogicalConnectionPoint().contains("NETWORK"))
159                         .collect(Collectors.toList());
160         List<Integer> tpdrList = new ArrayList<>();
161         for (Mapping mapping : networkMappings) {
162             Integer xpdrNb = Integer.parseInt(mapping.getLogicalConnectionPoint().split("XPDR")[1].split("-")[0]);
163             if (!tpdrList.contains(xpdrNb)) {
164                 tpdrList.add(xpdrNb);
165                 List<Mapping> extractedMappings = mappingNode.nonnullMapping().values()
166                         .stream().filter(lcp -> lcp.getLogicalConnectionPoint().contains("XPDR" + xpdrNb))
167                         .collect(Collectors.toList());
168                 Boolean isOtn;
169                 String xpdrType;
170                 switch (mapping.getXponderType() == null ? Tpdr : mapping.getXponderType()) {
171                     case Tpdr :
172                         isOtn = false;
173                         xpdrType = "Tpdr";
174                         break;
175                     case Mpdr :
176                     case Switch :
177                         isOtn = true;
178                         xpdrType = mapping.getXponderType().getName();
179                         break;
180                     default :
181                         LOG.warn("cannot create xpdr node {} in openroadm-topology: type {} not supported",
182                              mappingNode.getNodeId() + "-XPDR" + xpdrNb, mapping.getXponderType().getName());
183                         continue;
184                 }
185                 LOG.info("creating xpdr node {} of type {} in openroadm-topology",
186                         mappingNode.getNodeId() + "-XPDR" + xpdrNb, xpdrType);
187                 nodes.add(createXpdr(
188                                 mappingNode.getNodeId(),
189                                 mappingNode.getNodeInfo().getNodeClli(),
190                                 xpdrNb,
191                                 extractedMappings,
192                                 isOtn)
193                           .build());
194             }
195         }
196         return nodes.isEmpty() ? null : new TopologyShard(nodes, new ArrayList<Link>());
197     }
198
199     private static NodeBuilder createXpdr(String nodeId, String clli, Integer xpdrNb, List<Mapping> mappings,
200                                           boolean isOtn) {
201         // Create ietf node setting supporting-node data
202         String nodeIdtopo = new StringBuilder().append(nodeId).append("-XPDR").append(xpdrNb).toString();
203         NodeBuilder ietfNodeBldr = createTopoLayerNode(nodeId, clli)
204                 .setNodeId(new NodeId(nodeIdtopo))
205                 .withKey((new NodeKey(new NodeId(nodeIdtopo))))
206                 .addAugmentation(
207                     // Create openroadm-network-topo augmentation to set node type to Xponder
208                     new org.opendaylight.yang.gen.v1.http.org.openroadm.common.network.rev211210.Node1Builder()
209                         .setNodeType(OpenroadmNodeType.XPONDER)
210                         .setAdministrativeState(AdminStates.InService)
211                         .setOperationalState(State.InService)
212                         .build());
213         // Create tp-map
214         Map<TerminationPointKey, TerminationPoint> tpMap = new HashMap<>();
215         for (Mapping m : mappings) {
216             if (!PORTQUAL_ORD_TYPE_MAP.containsKey(m.getPortQual())) {
217                 continue;
218             }
219             if (isOtn && m.getPortQual().equals("xpdr-client")) {
220                 continue;
221             }
222             TerminationPointBuilder ietfTpBldr = createTpBldr(m.getLogicalConnectionPoint())
223                 .addAugmentation(
224                     // Add openroadm-network-topology tp augmentations
225                     new org.opendaylight.yang.gen.v1.http.org.openroadm.common.network.rev211210
226                             .TerminationPoint1Builder()
227                         .setTpType(PORTQUAL_ORD_TYPE_MAP.get(m.getPortQual()))
228                         .setAdministrativeState(TopologyUtils.setNetworkAdminState(m.getPortAdminState()))
229                         .setOperationalState(TopologyUtils.setNetworkOperState(m.getPortOperState()))
230                         .build());
231             if (!isOtn) {
232                 ietfTpBldr.addAugmentation(
233                     new org.opendaylight.yang.gen.v1.http.transportpce.topology.rev220123
234                             .TerminationPoint1Builder()
235                         .setAssociatedConnectionMapPort(m.getConnectionMapLcp())
236                         .build());
237             }
238             TerminationPoint ietfTp = ietfTpBldr.build();
239             tpMap.put(ietfTp.key(),ietfTp);
240         }
241         // Create ietf node augmentation to support ietf tp-list
242         return ietfNodeBldr.addAugmentation(
243             new org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.topology.rev180226.Node1Builder()
244                     .setTerminationPoint(tpMap)
245                     .build());
246     }
247
248     private static NodeBuilder createDegree(String degNb, List<Mapping> degListMap, String nodeId, String clli,
249                                             boolean firstMount) {
250         // Create tp-list
251         Map<TerminationPointKey,TerminationPoint> tpMap = new HashMap<>();
252         for (Mapping m : degListMap) {
253             // Add openroadm-common-network tp type augmentations
254             // Added states to degree port. TODO: add to mapping relation between abstracted and physical node states
255             if (!PORTDIR_ORD_TYPE_MAP.containsKey(m.getPortDirection())) {
256                 LOG.error("impossible to set tp-type to {}", m.getLogicalConnectionPoint());
257             }
258             TerminationPoint ietfTp =  createTpBldr(m.getLogicalConnectionPoint())
259                 .addAugmentation(
260                     new org.opendaylight.yang.gen.v1.http.org.openroadm.common.network.rev211210
261                             .TerminationPoint1Builder()
262                         .setTpType(PORTDIR_ORD_TYPE_MAP.get(m.getPortDirection()).get(0))
263                         .setAdministrativeState(TopologyUtils.setNetworkAdminState(m.getPortAdminState()))
264                         .setOperationalState(TopologyUtils.setNetworkOperState(m.getPortOperState()))
265                         .build())
266                 .build();
267             tpMap.put(ietfTp.key(),ietfTp);
268         }
269         // Add CTP to tp-list + added states. TODO: same comment as before with the relation between states
270         TerminationPoint ietfTp = createTpBldr(degNb + "-CTP-TXRX")
271                 .addAugmentation(new org.opendaylight.yang.gen.v1.http
272                     .org.openroadm.common.network.rev211210.TerminationPoint1Builder()
273                          .setTpType(OpenroadmTpType.DEGREETXRXCTP)
274                          .setAdministrativeState(AdminStates.InService)
275                          .setOperationalState(State.InService)
276                          .build())
277                  .build();
278         tpMap.put(ietfTp.key(),ietfTp);
279         // set degree-attributes
280         DegreeAttributesBuilder degAttBldr = new DegreeAttributesBuilder()
281                 .setDegreeNumber(Uint16.valueOf(degNb.split("DEG")[1]));
282         if (firstMount) {
283             degAttBldr.setAvailFreqMaps(GridUtils.initFreqMaps4FixedGrid2Available());
284         }
285         DegreeAttributes degAtt = degAttBldr.build();
286         // set node-id
287         String nodeIdtopo = new StringBuilder().append(nodeId).append("-").append(degNb).toString();
288         // Create ietf node setting supporting-node data
289         return createTopoLayerNode(nodeId, clli)
290                 .setNodeId(new NodeId(nodeIdtopo))
291                 .withKey((new NodeKey(new NodeId(nodeIdtopo))))
292                 .addAugmentation(new Node1Builder().setDegreeAttributes(degAtt).build())
293                 .addAugmentation(
294                     new org.opendaylight.yang.gen.v1.http.org.openroadm.common.network.rev211210
295                             .Node1Builder()
296                         .setNodeType(OpenroadmNodeType.DEGREE)
297                         .setAdministrativeState(AdminStates.InService)
298                         .setOperationalState(State.InService)
299                         .build())
300                 .addAugmentation(
301                     new org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.topology.rev180226
302                             .Node1Builder()
303                         .setTerminationPoint(tpMap)
304                         .build());
305     }
306
307     private static NodeBuilder createSrg(String srgNb, List<Mapping> srgListMap, String nodeId, String clli,
308                                          boolean firstMount) {
309         // Create tp-list
310         Map<TerminationPointKey,TerminationPoint> tpMap = new HashMap<>();
311         for (Mapping m : srgListMap) {
312             // Added states to srg port. TODO: add to mapping relation between abstracted and physical node states
313             if (!PORTDIR_ORD_TYPE_MAP.containsKey(m.getPortDirection())) {
314                 LOG.error("impossible to set tp-type to {}", m.getLogicalConnectionPoint());
315             }
316             TerminationPoint ietfTp = createTpBldr(m.getLogicalConnectionPoint())
317                 .addAugmentation(
318                     // Add openroadm-common-network tp type augmentations
319                     new org.opendaylight.yang.gen.v1.http.org.openroadm.common.network.rev211210
320                             .TerminationPoint1Builder()
321                         .setTpType(PORTDIR_ORD_TYPE_MAP.get(m.getPortDirection()).get(1))
322                         .setAdministrativeState(TopologyUtils.setNetworkAdminState(m.getPortAdminState()))
323                         .setOperationalState(TopologyUtils.setNetworkOperState(m.getPortOperState()))
324                         .build())
325                 .build();
326             tpMap.put(ietfTp.key(),ietfTp);
327         }
328         // Add CP to tp-list + added states. TODO: same comment as before with the relation between states
329         TerminationPoint ietfTp = createTpBldr(srgNb + "-CP-TXRX")
330             .addAugmentation(
331                 new org.opendaylight.yang.gen.v1.http.org.openroadm.common.network.rev211210
332                         .TerminationPoint1Builder()
333                     .setTpType(OpenroadmTpType.SRGTXRXCP)
334                     .setAdministrativeState(AdminStates.InService)
335                     .setOperationalState(State.InService)
336                     .build())
337             .build();
338         tpMap.put(ietfTp.key(),ietfTp);
339         // set srg-attributes
340         SrgAttributesBuilder srgAttrBldr = new SrgAttributesBuilder();
341         if (firstMount) {
342             srgAttrBldr.setAvailFreqMaps(GridUtils.initFreqMaps4FixedGrid2Available());
343         }
344         SrgAttributes srgAttr = srgAttrBldr.build();
345         // Create ietf node augmentation to support ietf tp-list
346         // Create ietf node setting supporting-node data
347         String nodeIdtopo = new StringBuilder().append(nodeId).append("-").append(srgNb).toString();
348         return createTopoLayerNode(nodeId, clli)
349             .setNodeId(new NodeId(nodeIdtopo))
350             .withKey((new NodeKey(new NodeId(nodeIdtopo))))
351             .addAugmentation(new Node1Builder().setSrgAttributes(srgAttr).build())
352             .addAugmentation(
353                 new org.opendaylight.yang.gen.v1.http.org.openroadm.common.network.rev211210
354                         .Node1Builder()
355                     .setNodeType(OpenroadmNodeType.SRG)
356                     .setAdministrativeState(AdminStates.InService)
357                     .setOperationalState(State.InService)
358                     .build())
359             .addAugmentation(
360                 new org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.topology.rev180226
361                        .Node1Builder()
362                     .setTerminationPoint(tpMap)
363                     .build());
364     }
365
366     private static NodeBuilder createTopoLayerNode(String nodeId, String clli) {
367         // Sets the value of Network-ref and Node-ref as a part of the supporting node
368         // attribute
369         SupportingNode support1 = new SupportingNodeBuilder()
370                 .withKey(new SupportingNodeKey(new NetworkId(NetworkUtils.UNDERLAY_NETWORK_ID), new NodeId(nodeId)))
371                 .setNetworkRef(new NetworkId(NetworkUtils.UNDERLAY_NETWORK_ID))
372                 .setNodeRef(new NodeId(nodeId))
373                 .build();
374         SupportingNode support2 = new SupportingNodeBuilder()
375                 .withKey(new SupportingNodeKey(new NetworkId(NetworkUtils.CLLI_NETWORK_ID), new NodeId(clli)))
376                 .setNetworkRef(new NetworkId(NetworkUtils.CLLI_NETWORK_ID))
377                 .setNodeRef(new NodeId(clli))
378                 .build();
379         Map<SupportingNodeKey, SupportingNode> supportlist = new HashMap<>();
380         supportlist.put(support1.key(), support1);
381         supportlist.put(support2.key(), support2);
382         return new NodeBuilder().setSupportingNode(supportlist);
383     }
384
385
386     // This method returns a generic termination point builder for a given tpid
387     private static TerminationPointBuilder createTpBldr(String tpId) {
388         TpId tp = new TpId(tpId);
389         return new TerminationPointBuilder().withKey(new TerminationPointKey(tp)).setTpId(tp);
390     }
391
392     private static LinkBuilder createLink(String srcNode, String destNode, String srcTp, String destTp) {
393         LinkId linkId = LinkIdUtil.buildLinkId(srcNode, srcTp, destNode, destTp);
394         return new LinkBuilder()
395                 .setSource(
396                     new SourceBuilder()
397                         .setSourceNode(new NodeId(srcNode))
398                         .setSourceTp(new TpId(srcTp))
399                         .build())
400                 .setDestination(
401                     new DestinationBuilder()
402                         .setDestNode(new NodeId(destNode))
403                         .setDestTp(new TpId(destTp))
404                         .build())
405                 .setLinkId(linkId)
406                 .withKey(new LinkKey(linkId));
407     }
408
409     private static List<Link> createNewLinks(List<Node> nodes) {
410         List<Link> links = new ArrayList<>();
411         String srcNode;
412         String destNode;
413         String srcTp;
414         String destTp;
415         for (int i = 0; i < nodes.size() - 1; i++) {
416             for (int j = i + 1; j < nodes.size(); j++) {
417                 srcNode = nodes.get(i).getNodeId().getValue();
418                 destNode = nodes.get(j).getNodeId().getValue();
419                 // A to Z direction
420                 srcTp = nodes.get(i)
421                         .augmentation(org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang
422                                 .ietf.network.topology.rev180226.Node1.class)
423                         .nonnullTerminationPoint().values().stream()
424                         .filter(tp -> tp.getTpId().getValue().contains("CP") || tp.getTpId().getValue().contains("CTP"))
425                         .findFirst().get().getTpId().getValue();
426                 destTp = nodes.get(j)
427                         .augmentation(org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang
428                                 .ietf.network.topology.rev180226.Node1.class)
429                         .nonnullTerminationPoint().values().stream()
430                         .filter(tp -> tp.getTpId().getValue().contains("CP") || tp.getTpId().getValue().contains("CTP"))
431                         .findFirst().get().getTpId().getValue();
432                 Link1Builder ocnAzLinkBldr = new Link1Builder();
433                 Link1Builder ocnZaLinkBldr = new Link1Builder();
434                 int srcNodeType = nodes.get(i).augmentation(org.opendaylight.yang.gen.v1.http
435                         .org.openroadm.common.network.rev211210.Node1.class).getNodeType().getIntValue();
436                 int destNodeType = nodes.get(j).augmentation(org.opendaylight.yang.gen.v1.http
437                         .org.openroadm.common.network.rev211210.Node1.class).getNodeType().getIntValue();
438
439                 if (srcNodeType == 11 && destNodeType == 11) {
440                     ocnAzLinkBldr.setLinkType(OpenroadmLinkType.EXPRESSLINK);
441                     ocnZaLinkBldr.setLinkType(OpenroadmLinkType.EXPRESSLINK);
442                 } else if (srcNodeType == 11 && destNodeType == 12) {
443                     ocnAzLinkBldr.setLinkType(OpenroadmLinkType.DROPLINK);
444                     ocnZaLinkBldr.setLinkType(OpenroadmLinkType.ADDLINK);
445                 } else if (srcNodeType == 12 && destNodeType == 11) {
446                     ocnAzLinkBldr.setLinkType(OpenroadmLinkType.ADDLINK);
447                     ocnZaLinkBldr.setLinkType(OpenroadmLinkType.DROPLINK);
448                 } else {
449                     continue;
450                 }
451
452                 // Add state to link. Based on the operational state of the TPs at the edge of the link.
453                 // Similar to getting srcTp and destTp
454                 State srcTpState = nodes.get(i)
455                         .augmentation(org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang
456                             .ietf.network.topology.rev180226.Node1.class)
457                         .getTerminationPoint().values().stream()
458                         .filter(tp -> tp.getTpId().getValue().contains("CP") || tp.getTpId().getValue().contains("CTP"))
459                         .findFirst().get()
460                         .augmentation(org.opendaylight.yang.gen.v1.http.org.openroadm.common.network.rev211210
461                             .TerminationPoint1.class)
462                         .getOperationalState();
463                 State destTpState = nodes.get(j)
464                         .augmentation(org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang
465                             .ietf.network.topology.rev180226.Node1.class)
466                         .getTerminationPoint().values().stream()
467                         .filter(tp -> tp.getTpId().getValue().contains("CP") || tp.getTpId().getValue().contains("CTP"))
468                         .findFirst().get()
469                         .augmentation(org.opendaylight.yang.gen.v1.http.org.openroadm.common.network.rev211210
470                             .TerminationPoint1.class)
471                         .getOperationalState();
472                 if (State.InService.equals(srcTpState) && State.InService.equals(destTpState)) {
473                     ocnAzLinkBldr.setAdministrativeState(AdminStates.InService)
474                             .setOperationalState(State.InService);
475                     ocnZaLinkBldr.setAdministrativeState(AdminStates.InService)
476                             .setOperationalState(State.InService);
477                 } else {
478                     ocnAzLinkBldr.setAdministrativeState(AdminStates.OutOfService)
479                             .setOperationalState(State.OutOfService);
480                     ocnZaLinkBldr.setAdministrativeState(AdminStates.OutOfService)
481                             .setOperationalState(State.OutOfService);
482                 }
483                 // set opposite link augmentations
484                 LinkBuilder ietfAzLinkBldr = createLink(srcNode, destNode, srcTp, destTp);
485                 LinkBuilder ietfZaLinkBldr = createLink(destNode, srcNode, destTp, srcTp);
486                 ocnAzLinkBldr.setOppositeLink(ietfZaLinkBldr.getLinkId());
487                 ietfAzLinkBldr.addAugmentation(ocnAzLinkBldr.build());
488                 ocnZaLinkBldr.setOppositeLink(ietfAzLinkBldr.getLinkId());
489                 ietfZaLinkBldr.addAugmentation(ocnZaLinkBldr.build());
490                 links.add(ietfAzLinkBldr.build());
491                 links.add(ietfZaLinkBldr.build());
492             }
493         }
494         return links;
495     }
496
497     // This method returns the linkBuilder object for given source and destination
498     public static boolean deleteLink(String srcNode, String dstNode, String srcTp, String destTp,
499                                      NetworkTransactionService networkTransactionService) {
500         LOG.info("deleting link for {}-{}", srcNode, dstNode);
501         LinkId linkId = LinkIdUtil.buildLinkId(srcNode, srcTp, dstNode, destTp);
502         if (deleteLinkLinkId(linkId, networkTransactionService)) {
503             LOG.debug("Link Id {} updated to have admin state down", linkId);
504             return true;
505         } else {
506             LOG.debug("Link Id not found for Source {} and Dest {}", srcNode, dstNode);
507             return false;
508         }
509     }
510
511     // This method returns the linkBuilder object for given source and destination
512     public static boolean deleteLinkLinkId(LinkId linkId , NetworkTransactionService networkTransactionService) {
513         LOG.info("deleting link for LinkId: {}", linkId.getValue());
514         try {
515             InstanceIdentifierBuilder<Link> linkIID = InstanceIdentifier.builder(Networks.class)
516                 .child(Network.class, new NetworkKey(new NetworkId(NetworkUtils.OVERLAY_NETWORK_ID)))
517                 .augmentation(Network1.class)
518                 .child(Link.class, new LinkKey(linkId));
519             java.util.Optional<Link> link =
520                     networkTransactionService.read(LogicalDatastoreType.CONFIGURATION,linkIID.build()).get();
521             if (link.isEmpty()) {
522                 LOG.error("No link found for given LinkId: {}", linkId);
523                 return false;
524             }
525             LinkBuilder linkBuilder = new LinkBuilder(link.get());
526             networkTransactionService.merge(
527                 LogicalDatastoreType.CONFIGURATION,
528                 linkIID.build(),
529                 linkBuilder
530                     .removeAugmentation(Link1.class)
531                     .addAugmentation(
532                         new org.opendaylight.yang.gen.v1.http.org.openroadm.network.topology.rev211210
533                             .Link1Builder(linkBuilder
534                                 .augmentation(org.opendaylight.yang.gen.v1.http.org.openroadm.network.topology.rev211210
535                                     .Link1.class))
536                                 .build())
537                     .build());
538             networkTransactionService.commit().get(1, TimeUnit.SECONDS);
539             return true;
540
541         } catch (InterruptedException | ExecutionException | TimeoutException e) {
542             LOG.error("Error deleting link {}", linkId.getValue(), e);
543             return false;
544         }
545     }
546
547     /**
548      * Get a builder for instance identifier related to common network termination point.
549      * @param nodeId String
550      * @param tpId String
551      * @return InstanceIdentifierBuilder
552      */
553     public static InstanceIdentifierBuilder<org.opendaylight.yang.gen.v1.http.org.openroadm.common.network.rev211210
554             .TerminationPoint1> createCommonNetworkTerminationPointIIDBuilder(String nodeId, String tpId) {
555         return InstanceIdentifier.builder(Networks.class)
556                 .child(Network.class, new NetworkKey(new NetworkId(NetworkUtils.OVERLAY_NETWORK_ID)))
557                 .child(org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.rev180226
558                         .networks.network.Node.class,
559                     new NodeKey(new NodeId(nodeId)))
560                 .augmentation(org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.topology.rev180226
561                     .Node1.class)
562                 .child(org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.topology.rev180226
563                         .networks.network.node.TerminationPoint.class,
564                     new TerminationPointKey(new TpId(tpId)))
565                 .augmentation(org.opendaylight.yang.gen.v1.http.org.openroadm.common.network.rev211210
566                         .TerminationPoint1.class);
567     }
568
569     /**
570      * Get a builder for instance identifier related to network termination point.
571      * @param nodeId String
572      * @param tpId String
573      * @return InstanceIdentifierBuilder
574      */
575     public static InstanceIdentifierBuilder<TerminationPoint1> createNetworkTerminationPointIIDBuilder(String nodeId,
576                                                                                                        String tpId) {
577         return InstanceIdentifier.builder(Networks.class)
578                 .child(Network.class, new NetworkKey(new NetworkId(NetworkUtils.OVERLAY_NETWORK_ID)))
579                 .child(org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.rev180226
580                         .networks.network.Node.class,
581                     new NodeKey(new NodeId(nodeId)))
582                 .augmentation(org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.topology.rev180226
583                         .Node1.class)
584                 .child(org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.topology.rev180226
585                         .networks.network.node.TerminationPoint.class,
586                     new TerminationPointKey(new TpId(tpId)))
587                 .augmentation(TerminationPoint1.class);
588     }
589
590     /**
591      * Get an instance identifier related to network node.
592      * @param nodeId String
593      * @return InstanceIdentifier
594      */
595     public static InstanceIdentifier<Node1> createNetworkNodeIID(String nodeId) {
596         return InstanceIdentifier.builder(Networks.class)
597                 .child(Network.class, new NetworkKey(new NetworkId(NetworkUtils.OVERLAY_NETWORK_ID)))
598                 .child(org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.rev180226
599                         .networks.network.Node.class,
600                      new NodeKey(new NodeId(nodeId)))
601                 .augmentation(Node1.class).build();
602     }
603
604     /**
605      * Get an instance identifier related to common network node.
606      * @param nodeId String
607      * @return InstanceIdentifier
608      */
609     public static InstanceIdentifier<org.opendaylight.yang.gen.v1.http.org.openroadm.common.network.rev211210
610             .Node1> createCommonNetworkNodeIID(String nodeId) {
611         return InstanceIdentifier.builder(Networks.class)
612                 .child(Network.class, new NetworkKey(new NetworkId(NetworkUtils.OVERLAY_NETWORK_ID)))
613                 .child(org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.rev180226
614                         .networks.network.Node.class,
615                     new NodeKey(new NodeId(nodeId)))
616                 .augmentation(org.opendaylight.yang.gen.v1.http.org.openroadm.common.network.rev211210.Node1.class)
617                 .build();
618     }
619 }