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