Update port-mapping data for REGEN xpdr-type
[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.rev220922.mapping.Mapping;
29 import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.portmapping.rev220922.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.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.getXpdrType() == null ? Tpdr : mapping.getXpdrType()) {
171                     case Tpdr :
172                         isOtn = false;
173                         xpdrType = "Tpdr";
174                         break;
175                     case Mpdr :
176                     case Switch :
177                         isOtn = true;
178                         xpdrType = mapping.getXpdrType().getName();
179                         break;
180                     // Both regen and regen-uni are added here, though initial support is
181                     // only for regen xpdr-type
182                     case Regen:
183                     case RegenUni:
184                         isOtn = false;
185                         xpdrType = mapping.getXpdrType().getName();
186                         break;
187                     default :
188                         LOG.warn("cannot create xpdr node {} in openroadm-topology: type {} not supported",
189                              mappingNode.getNodeId() + "-XPDR" + xpdrNb, mapping.getXpdrType().getName());
190                         continue;
191                 }
192                 LOG.info("creating xpdr node {} of type {} in openroadm-topology",
193                         mappingNode.getNodeId() + "-XPDR" + xpdrNb, xpdrType);
194                 nodes.add(createXpdr(
195                                 mappingNode.getNodeId(),
196                                 mappingNode.getNodeInfo().getNodeClli(),
197                                 xpdrNb,
198                                 extractedMappings,
199                                 isOtn)
200                           .build());
201             }
202         }
203         return nodes.isEmpty() ? null : new TopologyShard(nodes, new ArrayList<Link>());
204     }
205
206     private static NodeBuilder createXpdr(String nodeId, String clli, Integer xpdrNb, List<Mapping> mappings,
207                                           boolean isOtn) {
208         // Create ietf node setting supporting-node data
209         String nodeIdtopo = new StringBuilder().append(nodeId).append("-XPDR").append(xpdrNb).toString();
210         NodeBuilder ietfNodeBldr = createTopoLayerNode(nodeId, clli)
211                 .setNodeId(new NodeId(nodeIdtopo))
212                 .withKey((new NodeKey(new NodeId(nodeIdtopo))))
213                 .addAugmentation(
214                     // Create openroadm-network-topo augmentation to set node type to Xponder
215                     new org.opendaylight.yang.gen.v1.http.org.openroadm.common.network.rev211210.Node1Builder()
216                         .setNodeType(OpenroadmNodeType.XPONDER)
217                         .setAdministrativeState(AdminStates.InService)
218                         .setOperationalState(State.InService)
219                         .build());
220         // Create tp-map
221         Map<TerminationPointKey, TerminationPoint> tpMap = new HashMap<>();
222         for (Mapping m : mappings) {
223             if (!PORTQUAL_ORD_TYPE_MAP.containsKey(m.getPortQual())) {
224                 continue;
225             }
226             if (isOtn && m.getPortQual().equals("xpdr-client")) {
227                 continue;
228             }
229             org.opendaylight.yang.gen.v1.http.org.openroadm.common.network.rev211210.TerminationPoint1Builder
230                     ocnTp1Bldr = new org.opendaylight.yang.gen.v1.http.org.openroadm.common.network.rev211210
231                     .TerminationPoint1Builder()
232                     .setTpType(PORTQUAL_ORD_TYPE_MAP.get(m.getPortQual()))
233                     .setAdministrativeState(TopologyUtils.setNetworkAdminState(m.getPortAdminState()))
234                     .setOperationalState(TopologyUtils.setNetworkOperState(m.getPortOperState()));
235             if (!isOtn && m.getConnectionMapLcp() != null) {
236                 ocnTp1Bldr.setAssociatedConnectionMapTp(Set.of(new TpId(m.getConnectionMapLcp())));
237             }
238             TerminationPointBuilder ietfTpBldr = createTpBldr(m.getLogicalConnectionPoint())
239                 .addAugmentation(
240                     // Add openroadm-network-topology tp augmentations
241                         ocnTp1Bldr.build());
242             TerminationPoint ietfTp = ietfTpBldr.build();
243             tpMap.put(ietfTp.key(),ietfTp);
244         }
245         // Create ietf node augmentation to support ietf tp-list
246         return ietfNodeBldr.addAugmentation(
247             new org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.topology.rev180226.Node1Builder()
248                     .setTerminationPoint(tpMap)
249                     .build());
250     }
251
252     private static NodeBuilder createDegree(String degNb, List<Mapping> degListMap, String nodeId, String clli,
253                                             boolean firstMount) {
254         // Create tp-list
255         Map<TerminationPointKey,TerminationPoint> tpMap = new HashMap<>();
256         for (Mapping m : degListMap) {
257             // Add openroadm-common-network tp type augmentations
258             // Added states to degree port. TODO: add to mapping relation between abstracted and physical node states
259             if (!PORTDIR_ORD_TYPE_MAP.containsKey(m.getPortDirection())) {
260                 LOG.error("impossible to set tp-type to {}", m.getLogicalConnectionPoint());
261             }
262             TerminationPoint ietfTp =  createTpBldr(m.getLogicalConnectionPoint())
263                 .addAugmentation(
264                     new org.opendaylight.yang.gen.v1.http.org.openroadm.common.network.rev211210
265                             .TerminationPoint1Builder()
266                         .setTpType(PORTDIR_ORD_TYPE_MAP.get(m.getPortDirection()).get(0))
267                         .setAdministrativeState(TopologyUtils.setNetworkAdminState(m.getPortAdminState()))
268                         .setOperationalState(TopologyUtils.setNetworkOperState(m.getPortOperState()))
269                         .build())
270                 .build();
271             tpMap.put(ietfTp.key(),ietfTp);
272         }
273         // Add CTP to tp-list + added states. TODO: same comment as before with the relation between states
274         TerminationPoint ietfTp = createTpBldr(degNb + "-CTP-TXRX")
275                 .addAugmentation(new org.opendaylight.yang.gen.v1.http
276                     .org.openroadm.common.network.rev211210.TerminationPoint1Builder()
277                          .setTpType(OpenroadmTpType.DEGREETXRXCTP)
278                          .setAdministrativeState(AdminStates.InService)
279                          .setOperationalState(State.InService)
280                          .build())
281                  .build();
282         tpMap.put(ietfTp.key(),ietfTp);
283         // set degree-attributes
284         DegreeAttributesBuilder degAttBldr = new DegreeAttributesBuilder()
285                 .setDegreeNumber(Uint16.valueOf(degNb.split("DEG")[1]));
286         if (firstMount) {
287             degAttBldr.setAvailFreqMaps(GridUtils.initFreqMaps4FixedGrid2Available());
288         }
289         DegreeAttributes degAtt = degAttBldr.build();
290         // set node-id
291         String nodeIdtopo = new StringBuilder().append(nodeId).append("-").append(degNb).toString();
292         // Create ietf node setting supporting-node data
293         return createTopoLayerNode(nodeId, clli)
294                 .setNodeId(new NodeId(nodeIdtopo))
295                 .withKey((new NodeKey(new NodeId(nodeIdtopo))))
296                 .addAugmentation(new Node1Builder().setDegreeAttributes(degAtt).build())
297                 .addAugmentation(
298                     new org.opendaylight.yang.gen.v1.http.org.openroadm.common.network.rev211210
299                             .Node1Builder()
300                         .setNodeType(OpenroadmNodeType.DEGREE)
301                         .setAdministrativeState(AdminStates.InService)
302                         .setOperationalState(State.InService)
303                         .build())
304                 .addAugmentation(
305                     new org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.topology.rev180226
306                             .Node1Builder()
307                         .setTerminationPoint(tpMap)
308                         .build());
309     }
310
311     private static NodeBuilder createSrg(String srgNb, List<Mapping> srgListMap, String nodeId, String clli,
312                                          boolean firstMount) {
313         // Create tp-list
314         Map<TerminationPointKey,TerminationPoint> tpMap = new HashMap<>();
315         for (Mapping m : srgListMap) {
316             // Added states to srg port. TODO: add to mapping relation between abstracted and physical node states
317             if (!PORTDIR_ORD_TYPE_MAP.containsKey(m.getPortDirection())) {
318                 LOG.error("impossible to set tp-type to {}", m.getLogicalConnectionPoint());
319             }
320             TerminationPoint ietfTp = createTpBldr(m.getLogicalConnectionPoint())
321                 .addAugmentation(
322                     // Add openroadm-common-network tp type augmentations
323                     new org.opendaylight.yang.gen.v1.http.org.openroadm.common.network.rev211210
324                             .TerminationPoint1Builder()
325                         .setTpType(PORTDIR_ORD_TYPE_MAP.get(m.getPortDirection()).get(1))
326                         .setAdministrativeState(TopologyUtils.setNetworkAdminState(m.getPortAdminState()))
327                         .setOperationalState(TopologyUtils.setNetworkOperState(m.getPortOperState()))
328                         .build())
329                 .build();
330             tpMap.put(ietfTp.key(),ietfTp);
331         }
332         // Add CP to tp-list + added states. TODO: same comment as before with the relation between states
333         TerminationPoint ietfTp = createTpBldr(srgNb + "-CP-TXRX")
334             .addAugmentation(
335                 new org.opendaylight.yang.gen.v1.http.org.openroadm.common.network.rev211210
336                         .TerminationPoint1Builder()
337                     .setTpType(OpenroadmTpType.SRGTXRXCP)
338                     .setAdministrativeState(AdminStates.InService)
339                     .setOperationalState(State.InService)
340                     .build())
341             .build();
342         tpMap.put(ietfTp.key(),ietfTp);
343         // set srg-attributes
344         SrgAttributesBuilder srgAttrBldr = new SrgAttributesBuilder();
345         if (firstMount) {
346             srgAttrBldr.setAvailFreqMaps(GridUtils.initFreqMaps4FixedGrid2Available());
347         }
348         SrgAttributes srgAttr = srgAttrBldr.build();
349         // Create ietf node augmentation to support ietf tp-list
350         // Create ietf node setting supporting-node data
351         String nodeIdtopo = new StringBuilder().append(nodeId).append("-").append(srgNb).toString();
352         return createTopoLayerNode(nodeId, clli)
353             .setNodeId(new NodeId(nodeIdtopo))
354             .withKey((new NodeKey(new NodeId(nodeIdtopo))))
355             .addAugmentation(new Node1Builder().setSrgAttributes(srgAttr).build())
356             .addAugmentation(
357                 new org.opendaylight.yang.gen.v1.http.org.openroadm.common.network.rev211210
358                         .Node1Builder()
359                     .setNodeType(OpenroadmNodeType.SRG)
360                     .setAdministrativeState(AdminStates.InService)
361                     .setOperationalState(State.InService)
362                     .build())
363             .addAugmentation(
364                 new org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.topology.rev180226
365                        .Node1Builder()
366                     .setTerminationPoint(tpMap)
367                     .build());
368     }
369
370     private static NodeBuilder createTopoLayerNode(String nodeId, String clli) {
371         // Sets the value of Network-ref and Node-ref as a part of the supporting node
372         // attribute
373         SupportingNode support1 = new SupportingNodeBuilder()
374                 .withKey(new SupportingNodeKey(new NetworkId(NetworkUtils.UNDERLAY_NETWORK_ID), new NodeId(nodeId)))
375                 .setNetworkRef(new NetworkId(NetworkUtils.UNDERLAY_NETWORK_ID))
376                 .setNodeRef(new NodeId(nodeId))
377                 .build();
378         SupportingNode support2 = new SupportingNodeBuilder()
379                 .withKey(new SupportingNodeKey(new NetworkId(NetworkUtils.CLLI_NETWORK_ID), new NodeId(clli)))
380                 .setNetworkRef(new NetworkId(NetworkUtils.CLLI_NETWORK_ID))
381                 .setNodeRef(new NodeId(clli))
382                 .build();
383         Map<SupportingNodeKey, SupportingNode> supportlist = new HashMap<>();
384         supportlist.put(support1.key(), support1);
385         supportlist.put(support2.key(), support2);
386         return new NodeBuilder().setSupportingNode(supportlist);
387     }
388
389
390     // This method returns a generic termination point builder for a given tpid
391     private static TerminationPointBuilder createTpBldr(String tpId) {
392         TpId tp = new TpId(tpId);
393         return new TerminationPointBuilder().withKey(new TerminationPointKey(tp)).setTpId(tp);
394     }
395
396     private static LinkBuilder createLink(String srcNode, String destNode, String srcTp, String destTp) {
397         LinkId linkId = LinkIdUtil.buildLinkId(srcNode, srcTp, destNode, destTp);
398         return new LinkBuilder()
399                 .setSource(
400                     new SourceBuilder()
401                         .setSourceNode(new NodeId(srcNode))
402                         .setSourceTp(new TpId(srcTp))
403                         .build())
404                 .setDestination(
405                     new DestinationBuilder()
406                         .setDestNode(new NodeId(destNode))
407                         .setDestTp(new TpId(destTp))
408                         .build())
409                 .setLinkId(linkId)
410                 .withKey(new LinkKey(linkId));
411     }
412
413     private static List<Link> createNewLinks(List<Node> nodes) {
414         List<Link> links = new ArrayList<>();
415         String srcNode;
416         String destNode;
417         String srcTp;
418         String destTp;
419         for (int i = 0; i < nodes.size() - 1; i++) {
420             for (int j = i + 1; j < nodes.size(); j++) {
421                 srcNode = nodes.get(i).getNodeId().getValue();
422                 destNode = nodes.get(j).getNodeId().getValue();
423                 // A to Z direction
424                 srcTp = nodes.get(i)
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                 destTp = nodes.get(j)
431                         .augmentation(org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang
432                                 .ietf.network.topology.rev180226.Node1.class)
433                         .nonnullTerminationPoint().values().stream()
434                         .filter(tp -> tp.getTpId().getValue().contains("CP") || tp.getTpId().getValue().contains("CTP"))
435                         .findFirst().get().getTpId().getValue();
436                 Link1Builder ocnAzLinkBldr = new Link1Builder();
437                 Link1Builder ocnZaLinkBldr = new Link1Builder();
438                 int srcNodeType = nodes.get(i).augmentation(org.opendaylight.yang.gen.v1.http
439                         .org.openroadm.common.network.rev211210.Node1.class).getNodeType().getIntValue();
440                 int destNodeType = nodes.get(j).augmentation(org.opendaylight.yang.gen.v1.http
441                         .org.openroadm.common.network.rev211210.Node1.class).getNodeType().getIntValue();
442
443                 if (srcNodeType == 11 && destNodeType == 11) {
444                     ocnAzLinkBldr.setLinkType(OpenroadmLinkType.EXPRESSLINK);
445                     ocnZaLinkBldr.setLinkType(OpenroadmLinkType.EXPRESSLINK);
446                 } else if (srcNodeType == 11 && destNodeType == 12) {
447                     ocnAzLinkBldr.setLinkType(OpenroadmLinkType.DROPLINK);
448                     ocnZaLinkBldr.setLinkType(OpenroadmLinkType.ADDLINK);
449                 } else if (srcNodeType == 12 && destNodeType == 11) {
450                     ocnAzLinkBldr.setLinkType(OpenroadmLinkType.ADDLINK);
451                     ocnZaLinkBldr.setLinkType(OpenroadmLinkType.DROPLINK);
452                 } else {
453                     continue;
454                 }
455
456                 // Add state to link. Based on the operational state of the TPs at the edge of the link.
457                 // Similar to getting srcTp and destTp
458                 State srcTpState = nodes.get(i)
459                         .augmentation(org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang
460                             .ietf.network.topology.rev180226.Node1.class)
461                         .getTerminationPoint().values().stream()
462                         .filter(tp -> tp.getTpId().getValue().contains("CP") || tp.getTpId().getValue().contains("CTP"))
463                         .findFirst().get()
464                         .augmentation(org.opendaylight.yang.gen.v1.http.org.openroadm.common.network.rev211210
465                             .TerminationPoint1.class)
466                         .getOperationalState();
467                 State destTpState = nodes.get(j)
468                         .augmentation(org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang
469                             .ietf.network.topology.rev180226.Node1.class)
470                         .getTerminationPoint().values().stream()
471                         .filter(tp -> tp.getTpId().getValue().contains("CP") || tp.getTpId().getValue().contains("CTP"))
472                         .findFirst().get()
473                         .augmentation(org.opendaylight.yang.gen.v1.http.org.openroadm.common.network.rev211210
474                             .TerminationPoint1.class)
475                         .getOperationalState();
476                 if (State.InService.equals(srcTpState) && State.InService.equals(destTpState)) {
477                     ocnAzLinkBldr.setAdministrativeState(AdminStates.InService)
478                             .setOperationalState(State.InService);
479                     ocnZaLinkBldr.setAdministrativeState(AdminStates.InService)
480                             .setOperationalState(State.InService);
481                 } else {
482                     ocnAzLinkBldr.setAdministrativeState(AdminStates.OutOfService)
483                             .setOperationalState(State.OutOfService);
484                     ocnZaLinkBldr.setAdministrativeState(AdminStates.OutOfService)
485                             .setOperationalState(State.OutOfService);
486                 }
487                 // set opposite link augmentations
488                 LinkBuilder ietfAzLinkBldr = createLink(srcNode, destNode, srcTp, destTp);
489                 LinkBuilder ietfZaLinkBldr = createLink(destNode, srcNode, destTp, srcTp);
490                 ocnAzLinkBldr.setOppositeLink(ietfZaLinkBldr.getLinkId());
491                 ietfAzLinkBldr.addAugmentation(ocnAzLinkBldr.build());
492                 ocnZaLinkBldr.setOppositeLink(ietfAzLinkBldr.getLinkId());
493                 ietfZaLinkBldr.addAugmentation(ocnZaLinkBldr.build());
494                 links.add(ietfAzLinkBldr.build());
495                 links.add(ietfZaLinkBldr.build());
496             }
497         }
498         return links;
499     }
500
501     // This method returns the linkBuilder object for given source and destination
502     public static boolean deleteLink(String srcNode, String dstNode, String srcTp, String destTp,
503                                      NetworkTransactionService networkTransactionService) {
504         LOG.info("deleting link for {}-{}", srcNode, dstNode);
505         LinkId linkId = LinkIdUtil.buildLinkId(srcNode, srcTp, dstNode, destTp);
506         if (deleteLinkLinkId(linkId, networkTransactionService)) {
507             LOG.debug("Link Id {} updated to have admin state down", linkId);
508             return true;
509         } else {
510             LOG.debug("Link Id not found for Source {} and Dest {}", srcNode, dstNode);
511             return false;
512         }
513     }
514
515     // This method returns the linkBuilder object for given source and destination
516     public static boolean deleteLinkLinkId(LinkId linkId , NetworkTransactionService networkTransactionService) {
517         LOG.info("deleting link for LinkId: {}", linkId.getValue());
518         try {
519             InstanceIdentifierBuilder<Link> linkIID = InstanceIdentifier.builder(Networks.class)
520                 .child(Network.class, new NetworkKey(new NetworkId(NetworkUtils.OVERLAY_NETWORK_ID)))
521                 .augmentation(Network1.class)
522                 .child(Link.class, new LinkKey(linkId));
523             java.util.Optional<Link> link =
524                     networkTransactionService.read(LogicalDatastoreType.CONFIGURATION,linkIID.build()).get();
525             if (link.isEmpty()) {
526                 LOG.error("No link found for given LinkId: {}", linkId);
527                 return false;
528             }
529             LinkBuilder linkBuilder = new LinkBuilder(link.get());
530             networkTransactionService.merge(
531                 LogicalDatastoreType.CONFIGURATION,
532                 linkIID.build(),
533                 linkBuilder
534                     .removeAugmentation(Link1.class)
535                     .addAugmentation(
536                         new org.opendaylight.yang.gen.v1.http.org.openroadm.network.topology.rev211210
537                             .Link1Builder(linkBuilder
538                                 .augmentation(org.opendaylight.yang.gen.v1.http.org.openroadm.network.topology.rev211210
539                                     .Link1.class))
540                                 .build())
541                     .build());
542             networkTransactionService.commit().get(1, TimeUnit.SECONDS);
543             return true;
544
545         } catch (InterruptedException | ExecutionException | TimeoutException e) {
546             LOG.error("Error deleting link {}", linkId.getValue(), e);
547             return false;
548         }
549     }
550
551     /**
552      * Get a builder for instance identifier related to common network termination point.
553      * @param nodeId String
554      * @param tpId String
555      * @return InstanceIdentifierBuilder
556      */
557     public static InstanceIdentifierBuilder<org.opendaylight.yang.gen.v1.http.org.openroadm.common.network.rev211210
558             .TerminationPoint1> createCommonNetworkTerminationPointIIDBuilder(String nodeId, String tpId) {
559         return InstanceIdentifier.builder(Networks.class)
560                 .child(Network.class, new NetworkKey(new NetworkId(NetworkUtils.OVERLAY_NETWORK_ID)))
561                 .child(org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.rev180226
562                         .networks.network.Node.class,
563                     new NodeKey(new NodeId(nodeId)))
564                 .augmentation(org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.topology.rev180226
565                     .Node1.class)
566                 .child(org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.topology.rev180226
567                         .networks.network.node.TerminationPoint.class,
568                     new TerminationPointKey(new TpId(tpId)))
569                 .augmentation(org.opendaylight.yang.gen.v1.http.org.openroadm.common.network.rev211210
570                         .TerminationPoint1.class);
571     }
572
573     /**
574      * Get an instance identifier related to network node.
575      * @param nodeId String
576      * @return InstanceIdentifier
577      */
578     public static InstanceIdentifier<Node1> createNetworkNodeIID(String nodeId) {
579         return InstanceIdentifier.builder(Networks.class)
580                 .child(Network.class, new NetworkKey(new NetworkId(NetworkUtils.OVERLAY_NETWORK_ID)))
581                 .child(org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.rev180226
582                         .networks.network.Node.class,
583                      new NodeKey(new NodeId(nodeId)))
584                 .augmentation(Node1.class).build();
585     }
586
587     /**
588      * Get an instance identifier related to common network node.
589      * @param nodeId String
590      * @return InstanceIdentifier
591      */
592     public static InstanceIdentifier<org.opendaylight.yang.gen.v1.http.org.openroadm.common.network.rev211210
593             .Node1> createCommonNetworkNodeIID(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(org.opendaylight.yang.gen.v1.http.org.openroadm.common.network.rev211210.Node1.class)
600                 .build();
601     }
602 }