Bump upstream dependencies to Potassium GA
[transportpce.git] / networkmodel / src / main / java / org / opendaylight / transportpce / networkmodel / util / OpenRoadmTopology.java
1 /*
2  * Copyright © 2016 AT&T and others.  All rights reserved.
3  *
4  * This program and the accompanying materials are made available under the
5  * terms of the Eclipse Public License v1.0 which accompanies this distribution,
6  * and is available at http://www.eclipse.org/legal/epl-v10.html
7  */
8
9 package org.opendaylight.transportpce.networkmodel.util;
10
11 import static org.opendaylight.yang.gen.v1.http.org.openroadm.device.types.rev191129.XpdrNodeTypes.Tpdr;
12
13 import java.util.ArrayList;
14 import java.util.Comparator;
15 import java.util.HashMap;
16 import java.util.List;
17 import java.util.Map;
18 import java.util.Set;
19 import java.util.concurrent.ExecutionException;
20 import java.util.concurrent.TimeUnit;
21 import java.util.concurrent.TimeoutException;
22 import java.util.stream.Collectors;
23 import org.opendaylight.mdsal.common.api.LogicalDatastoreType;
24 import org.opendaylight.transportpce.common.NetworkUtils;
25 import org.opendaylight.transportpce.common.fixedflex.GridUtils;
26 import org.opendaylight.transportpce.common.network.NetworkTransactionService;
27 import org.opendaylight.transportpce.networkmodel.dto.TopologyShard;
28 import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.portmapping.rev220922.mapping.Mapping;
29 import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.portmapping.rev220922.network.Nodes;
30 import org.opendaylight.yang.gen.v1.http.org.openroadm.common.network.rev211210.Link1;
31 import org.opendaylight.yang.gen.v1.http.org.openroadm.common.network.rev211210.Link1Builder;
32 import org.opendaylight.yang.gen.v1.http.org.openroadm.common.state.types.rev191129.State;
33 import org.opendaylight.yang.gen.v1.http.org.openroadm.equipment.states.types.rev191129.AdminStates;
34 import org.opendaylight.yang.gen.v1.http.org.openroadm.network.topology.rev211210.Node1;
35 import org.opendaylight.yang.gen.v1.http.org.openroadm.network.topology.rev211210.Node1Builder;
36 import org.opendaylight.yang.gen.v1.http.org.openroadm.network.topology.rev211210.networks.network.node.DegreeAttributes;
37 import org.opendaylight.yang.gen.v1.http.org.openroadm.network.topology.rev211210.networks.network.node.DegreeAttributesBuilder;
38 import org.opendaylight.yang.gen.v1.http.org.openroadm.network.topology.rev211210.networks.network.node.SrgAttributes;
39 import org.opendaylight.yang.gen.v1.http.org.openroadm.network.topology.rev211210.networks.network.node.SrgAttributesBuilder;
40 import org.opendaylight.yang.gen.v1.http.org.openroadm.network.types.rev211210.OpenroadmLinkType;
41 import org.opendaylight.yang.gen.v1.http.org.openroadm.network.types.rev211210.OpenroadmNodeType;
42 import org.opendaylight.yang.gen.v1.http.org.openroadm.network.types.rev211210.OpenroadmTpType;
43 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.rev180226.NetworkId;
44 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.rev180226.Networks;
45 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.rev180226.NodeId;
46 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.rev180226.networks.Network;
47 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.rev180226.networks.NetworkKey;
48 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.rev180226.networks.network.Node;
49 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.rev180226.networks.network.NodeBuilder;
50 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.rev180226.networks.network.NodeKey;
51 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.rev180226.networks.network.node.SupportingNode;
52 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.rev180226.networks.network.node.SupportingNodeBuilder;
53 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.rev180226.networks.network.node.SupportingNodeKey;
54 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.topology.rev180226.LinkId;
55 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.topology.rev180226.Network1;
56 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.topology.rev180226.TpId;
57 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.topology.rev180226.networks.network.Link;
58 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.topology.rev180226.networks.network.LinkBuilder;
59 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.topology.rev180226.networks.network.LinkKey;
60 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.topology.rev180226.networks.network.link.DestinationBuilder;
61 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.topology.rev180226.networks.network.link.SourceBuilder;
62 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.topology.rev180226.networks.network.node.TerminationPoint;
63 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.topology.rev180226.networks.network.node.TerminationPointBuilder;
64 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.topology.rev180226.networks.network.node.TerminationPointKey;
65 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
66 import org.opendaylight.yangtools.yang.common.Uint16;
67 import org.slf4j.Logger;
68 import org.slf4j.LoggerFactory;
69
70 public final class OpenRoadmTopology {
71
72     private static final Logger LOG = LoggerFactory.getLogger(OpenRoadmTopology.class);
73
74     private static Map<String, OpenroadmTpType> PORTQUAL_ORD_TYPE_MAP = Map.of(
75         "xpdr-network", OpenroadmTpType.XPONDERNETWORK,
76         "switch-network", OpenroadmTpType.XPONDERNETWORK,
77         "xpdr-client", OpenroadmTpType.XPONDERCLIENT
78     );
79     private static Map<String, List<OpenroadmTpType>> PORTDIR_ORD_TYPE_MAP = Map.of(
80         "bidirectional", List.of(OpenroadmTpType.DEGREETXRXTTP, OpenroadmTpType.SRGTXRXPP),
81         "tx", List.of(OpenroadmTpType.DEGREETXTTP, OpenroadmTpType.SRGTXPP),
82         "rx", List.of(OpenroadmTpType.DEGREERXTTP, OpenroadmTpType.SRGRXPP)
83     );
84
85     private OpenRoadmTopology() {
86     }
87
88     public static TopologyShard createTopologyShard(Nodes mappingNode) {
89         return createTopologyShard(mappingNode, true);
90     }
91
92     public static TopologyShard createTopologyShard(Nodes mappingNode, boolean firstMount) {
93         switch (mappingNode.getNodeInfo().getNodeType()) {
94             case Rdm :
95                 return createRdmTopologyShard(mappingNode, firstMount);
96             case Xpdr :
97                 return createXpdrTopologyShard(mappingNode);
98             default :
99                 LOG.error("Device node Type not managed yet");
100                 return null;
101         }
102     }
103
104     public static TopologyShard createRdmTopologyShard(Nodes mappingNode, boolean firstMount) {
105         List<Node> nodes = new ArrayList<>();
106         LOG.info("creating rdm node in openroadmtopology for node {}",
107                 mappingNode.getNodeId());
108         // transform flat mapping list to per degree and per srg mapping lists
109         Map<String, List<Mapping>> mapDeg = new HashMap<>();
110         Map<String, List<Mapping>> mapSrg = new HashMap<>();
111         List<Mapping> mappingList = new ArrayList<>(mappingNode.nonnullMapping().values());
112         mappingList.sort(Comparator.comparing(Mapping::getLogicalConnectionPoint));
113         List<String> nodeShardList = new ArrayList<>();
114         for (Mapping mapping : mappingList) {
115             String str = mapping.getLogicalConnectionPoint().split("-")[0];
116             if (!nodeShardList.contains(str)) {
117                 nodeShardList.add(str);
118             }
119         }
120         for (String str : nodeShardList) {
121             List<Mapping> interList =
122                     mappingList.stream()
123                             .filter(x -> x.getLogicalConnectionPoint().split("-")[0].equals(str))
124                             .collect(Collectors.toList());
125             if (str.contains("DEG")) {
126                 mapDeg.put(str, interList);
127             } else if (str.contains("SRG")) {
128                 mapSrg.put(str, interList);
129             } else {
130                 LOG.error("unknow element");
131             }
132         }
133         // create degree nodes
134         for (Map.Entry<String, List<Mapping>> entry : mapDeg.entrySet()) {
135             nodes.add(
136                 createDegree(entry.getKey(), entry.getValue(), mappingNode.getNodeId(),
137                         mappingNode.getNodeInfo().getNodeClli(), firstMount)
138                     .build());
139         }
140         // create srg nodes
141         for (Map.Entry<String, List<Mapping>> entry : mapSrg.entrySet()) {
142             nodes.add(
143                 createSrg(entry.getKey(), entry.getValue(), mappingNode.getNodeId(),
144                         mappingNode.getNodeInfo().getNodeClli(), firstMount)
145                     .build());
146         }
147         LOG.info("adding links numOfDegrees={} numOfSrgs={}", mapDeg.size(), mapSrg.size());
148         List<Link> links = createNewLinks(nodes);
149         LOG.info("created nodes/links: {}/{}", nodes.size(), links.size());
150         return new TopologyShard(nodes, links);
151     }
152
153     public static TopologyShard createXpdrTopologyShard(Nodes mappingNode) {
154         List<Node> nodes = new ArrayList<>();
155         List<Mapping> networkMappings =
156                 mappingNode.nonnullMapping().values()
157                         .stream().filter(k -> k.getLogicalConnectionPoint().contains("NETWORK"))
158                         .collect(Collectors.toList());
159         List<Integer> tpdrList = new ArrayList<>();
160         for (Mapping mapping : networkMappings) {
161             Integer xpdrNb = Integer.parseInt(mapping.getLogicalConnectionPoint().split("XPDR")[1].split("-")[0]);
162             if (!tpdrList.contains(xpdrNb)) {
163                 tpdrList.add(xpdrNb);
164                 List<Mapping> extractedMappings = mappingNode.nonnullMapping().values()
165                         .stream().filter(lcp -> lcp.getLogicalConnectionPoint().contains("XPDR" + xpdrNb))
166                         .collect(Collectors.toList());
167                 Boolean isOtn;
168                 String xpdrType;
169                 switch (mapping.getXpdrType() == null ? Tpdr : mapping.getXpdrType()) {
170                     case Tpdr :
171                         isOtn = false;
172                         xpdrType = "Tpdr";
173                         break;
174                     case Mpdr :
175                     case Switch :
176                         isOtn = true;
177                         xpdrType = mapping.getXpdrType().getName();
178                         break;
179                     // Both regen and regen-uni are added here, though initial support is
180                     // only for regen xpdr-type
181                     case Regen:
182                     case RegenUni:
183                         isOtn = false;
184                         xpdrType = mapping.getXpdrType().getName();
185                         break;
186                     default :
187                         LOG.warn("cannot create xpdr node {} in openroadm-topology: type {} not supported",
188                              mappingNode.getNodeId() + "-XPDR" + xpdrNb, mapping.getXpdrType().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                                 isOtn)
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_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_TYPE_MAP.get(m.getPortDirection()).get(0))
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_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_TYPE_MAP.get(m.getPortDirection()).get(1))
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().orElseThrow().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().orElseThrow().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().orElseThrow()
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().orElseThrow()
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             InstanceIdentifier.Builder<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.orElseThrow());
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 InstanceIdentifier.Builder<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 an instance identifier related to network node.
574      * @param nodeId String
575      * @return InstanceIdentifier
576      */
577     public static InstanceIdentifier<Node1> createNetworkNodeIID(String nodeId) {
578         return InstanceIdentifier.builder(Networks.class)
579                 .child(Network.class, new NetworkKey(new NetworkId(NetworkUtils.OVERLAY_NETWORK_ID)))
580                 .child(org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.rev180226
581                         .networks.network.Node.class,
582                      new NodeKey(new NodeId(nodeId)))
583                 .augmentation(Node1.class).build();
584     }
585
586     /**
587      * Get an instance identifier related to common network node.
588      * @param nodeId String
589      * @return InstanceIdentifier
590      */
591     public static InstanceIdentifier<org.opendaylight.yang.gen.v1.http.org.openroadm.common.network.rev211210
592             .Node1> createCommonNetworkNodeIID(String nodeId) {
593         return InstanceIdentifier.builder(Networks.class)
594                 .child(Network.class, new NetworkKey(new NetworkId(NetworkUtils.OVERLAY_NETWORK_ID)))
595                 .child(org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.rev180226
596                         .networks.network.Node.class,
597                     new NodeKey(new NodeId(nodeId)))
598                 .augmentation(org.opendaylight.yang.gen.v1.http.org.openroadm.common.network.rev211210.Node1.class)
599                 .build();
600     }
601 }