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