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