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