Refactor TAPI 2.4
[transportpce.git] / tapi / src / main / java / org / opendaylight / transportpce / tapi / topology / ConvertORTopoToTapiFullTopo.java
1 /*
2  * Copyright © 2021 Nokia.  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 package org.opendaylight.transportpce.tapi.topology;
9
10 import java.nio.charset.Charset;
11 import java.util.ArrayList;
12 import java.util.HashMap;
13 import java.util.List;
14 import java.util.Map;
15 import java.util.Set;
16 import java.util.UUID;
17 import java.util.stream.Collectors;
18 import org.opendaylight.transportpce.common.fixedflex.GridConstant;
19 import org.opendaylight.transportpce.tapi.TapiStringConstants;
20 import org.opendaylight.transportpce.tapi.utils.TapiLink;
21 import org.opendaylight.yang.gen.v1.http.org.openroadm.common.network.rev230526.Link1;
22 import org.opendaylight.yang.gen.v1.http.org.openroadm.common.network.rev230526.TerminationPoint1;
23 import org.opendaylight.yang.gen.v1.http.org.openroadm.common.state.types.rev191129.State;
24 import org.opendaylight.yang.gen.v1.http.org.openroadm.equipment.states.types.rev191129.AdminStates;
25 import org.opendaylight.yang.gen.v1.http.org.openroadm.network.types.rev230526.OpenroadmNodeType;
26 import org.opendaylight.yang.gen.v1.http.org.openroadm.network.types.rev230526.OpenroadmTpType;
27 import org.opendaylight.yang.gen.v1.http.org.openroadm.otn.network.topology.rev230526.Node1;
28 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.rev180226.networks.Network;
29 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.rev180226.networks.network.Node;
30 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.topology.rev180226.networks.network.node.TerminationPoint;
31 import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.common.rev221121.AdministrativeState;
32 import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.common.rev221121.Direction;
33 import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.common.rev221121.LayerProtocolName;
34 import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.common.rev221121.LifecycleState;
35 import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.common.rev221121.OperationalState;
36 import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.common.rev221121.PortRole;
37 import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.common.rev221121.Uuid;
38 import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.common.rev221121.global._class.Name;
39 import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.common.rev221121.global._class.NameBuilder;
40 import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.common.rev221121.global._class.NameKey;
41 import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.common.rev221121.tapi.context.ServiceInterfacePoint;
42 import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.common.rev221121.tapi.context.ServiceInterfacePointKey;
43 import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.photonic.media.rev221121.PHOTONICLAYERQUALIFIERMC;
44 import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.photonic.media.rev221121.PHOTONICLAYERQUALIFIEROMS;
45 import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.photonic.media.rev221121.PHOTONICLAYERQUALIFIEROTS;
46 import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.photonic.media.rev221121.PHOTONICLAYERQUALIFIEROTSiMC;
47 import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.topology.rev221121.node.InterRuleGroup;
48 import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.topology.rev221121.node.InterRuleGroupKey;
49 import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.topology.rev221121.node.NodeRuleGroup;
50 import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.topology.rev221121.node.NodeRuleGroupKey;
51 import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.topology.rev221121.node.OwnedNodeEdgePoint;
52 import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.topology.rev221121.node.OwnedNodeEdgePointBuilder;
53 import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.topology.rev221121.node.OwnedNodeEdgePointKey;
54 import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.topology.rev221121.node.RiskParameterPacBuilder;
55 import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.topology.rev221121.node.edge.point.SupportedCepLayerProtocolQualifierInstancesBuilder;
56 import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.topology.rev221121.risk.parameter.pac.RiskCharacteristic;
57 import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.topology.rev221121.risk.parameter.pac.RiskCharacteristicBuilder;
58 import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.topology.rev221121.topology.Link;
59 import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.topology.rev221121.topology.LinkKey;
60 import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.topology.rev221121.topology.NodeBuilder;
61 import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.topology.rev221121.topology.NodeKey;
62 import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.topology.rev221121.transfer.cost.pac.CostCharacteristic;
63 import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.topology.rev221121.transfer.cost.pac.CostCharacteristicBuilder;
64 import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.topology.rev221121.transfer.timing.pac.LatencyCharacteristic;
65 import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.topology.rev221121.transfer.timing.pac.LatencyCharacteristicBuilder;
66 import org.opendaylight.yangtools.yang.common.Uint64;
67 import org.slf4j.Logger;
68 import org.slf4j.LoggerFactory;
69
70
71 public class ConvertORTopoToTapiFullTopo {
72
73     private static final Logger LOG = LoggerFactory.getLogger(ConvertORTopoToTapiFullTopo.class);
74     private String ietfNodeId;
75     private OpenroadmNodeType ietfNodeType;
76     private Uuid tapiTopoUuid;
77     private Map<NodeKey, org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.topology.rev221121.topology.Node>
78         tapiNodes;
79     private Map<LinkKey, Link> tapiLinks;
80     private Map<ServiceInterfacePointKey, ServiceInterfacePoint> tapiSips;
81     private final TapiLink tapiLink;
82     private static String topologicalMode;
83
84
85     public ConvertORTopoToTapiFullTopo(Uuid tapiTopoUuid, TapiLink tapiLink) {
86         this.tapiTopoUuid = tapiTopoUuid;
87         this.tapiNodes = new HashMap<>();
88         this.tapiLinks = new HashMap<>();
89         this.tapiSips = new HashMap<>();
90         this.tapiLink = tapiLink;
91         if (topologicalMode == null) {
92             ConvertORTopoToTapiFullTopo.topologicalMode = "Full";
93         }
94     }
95
96     public void convertRdmToRdmLinks(
97             List<org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.topology.rev180226
98                 .networks.network.Link> rdmTordmLinkList) {
99         List<String> linksToNotConvert = new ArrayList<>();
100         LOG.info("creation of {} roadm to roadm links", rdmTordmLinkList.size() / 2);
101         for (var link : rdmTordmLinkList) {
102             if (!linksToNotConvert.contains(link.getLinkId().getValue())) {
103                 var oppositeLink = rdmTordmLinkList.stream()
104                     .filter(l -> l.getLinkId().equals(link.augmentation(Link1.class).getOppositeLink()))
105                     .findAny().orElse(null);
106                 AdminStates oppLnkAdmState = null;
107                 State oppLnkOpState = null;
108                 if (oppositeLink != null) {
109                     oppLnkAdmState = oppositeLink.augmentation(Link1.class).getAdministrativeState();
110                     oppLnkOpState = oppositeLink.augmentation(Link1.class).getOperationalState();
111                 }
112
113                 Link tapLink = this.tapiLink.createTapiLink(
114                     String.join("-",
115                         link.getSource().getSourceNode().getValue().split("-")[0],
116                         link.getSource().getSourceNode().getValue().split("-")[1]),
117                     link.getSource().getSourceTp().getValue(),
118                     String.join("-",
119                         link.getDestination().getDestNode().getValue().split("-")[0],
120                         link.getDestination().getDestNode().getValue().split("-")[1]),
121                     link.getDestination().getDestTp().getValue(), TapiStringConstants.OMS_RDM_RDM_LINK,
122                     TapiStringConstants.PHTNC_MEDIA, TapiStringConstants.PHTNC_MEDIA,
123                     TapiStringConstants.PHTNC_MEDIA_OTS, TapiStringConstants.PHTNC_MEDIA_OTS,
124                     //adminState,
125                     link.augmentation(Link1.class).getAdministrativeState() == null || oppLnkAdmState == null
126                         ? null
127                         : this.tapiLink.setTapiAdminState(
128                             link.augmentation(Link1.class).getAdministrativeState(), oppLnkAdmState).getName(),
129                     //operState,
130                     link.augmentation(Link1.class).getOperationalState() == null || oppLnkOpState == null
131                         ? null
132                         : this.tapiLink.setTapiOperationalState(
133                             link.augmentation(Link1.class).getOperationalState(), oppLnkOpState).getName(),
134                     Set.of(LayerProtocolName.PHOTONICMEDIA), Set.of(LayerProtocolName.PHOTONICMEDIA.getName()),
135                     this.tapiTopoUuid);
136                 linksToNotConvert.add(link.augmentation(Link1.class).getOppositeLink().getValue());
137                 tapiLinks.put(tapLink.key(), tapLink);
138             }
139         }
140     }
141
142     public void convertRoadmNode(Node roadm, Network openroadmTopo, String topoMode) {
143         setTopologicalMode(topoMode);
144         if (topoMode.equals("Full")) {
145             convertRoadmNodeFull(roadm, openroadmTopo);
146         } else {
147             convertRoadmNodeAbstracted(openroadmTopo);
148         }
149     }
150
151     private void convertRoadmNodeFull(Node roadm, Network openroadmTopo) {
152         this.ietfNodeId = roadm.getNodeId().getValue();
153         this.ietfNodeType = roadm.augmentation(
154                 org.opendaylight.yang.gen.v1.http.org.openroadm.common.network.rev230526.Node1.class)
155             .getNodeType();
156         Map<OwnedNodeEdgePointKey, OwnedNodeEdgePoint> oneplist = new HashMap<>();
157         // 1. Get degree and srg nodes to map TPs into NEPs
158         if (openroadmTopo.getNode() == null) {
159             LOG.warn("Openroadm-topology is null.");
160             return;
161         }
162         int numNeps = 0;
163         int numSips = 0;
164         List<Node> nodeList = new ArrayList<Node>(openroadmTopo.getNode().values());
165         for (Node node:nodeList) {
166             if (node.getSupportingNode().values().stream()
167                     .noneMatch(sp -> sp.getNodeRef().getValue().equals(this.ietfNodeId))) {
168                 LOG.debug("Abstracted node {} is not part of {}", node.getNodeId().getValue(), this.ietfNodeId);
169                 continue;
170             }
171             if (node.augmentation(Node1.class) == null
172                     && node.augmentation(
173                             org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.topology.rev180226
174                         .Node1.class) == null) {
175                 LOG.warn("Abstracted node {} doesnt have type of node or is not disaggregated",
176                     node.getNodeId().getValue());
177                 continue;
178             }
179             OpenroadmNodeType nodeType = node.augmentation(
180                         org.opendaylight.yang.gen.v1.http.org.openroadm.common.network.rev230526.Node1.class)
181                 .getNodeType();
182             var node1 = node.augmentation(
183                 org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.topology.rev180226.Node1.class);
184             LOG.info("TPs of node: {}", node1.getTerminationPoint().values());
185             switch (nodeType.getIntValue()) {
186                 case 11:
187                     LOG.info("Degree node");
188                     // Get only external TPs of the degree
189                     List<TerminationPoint> degPortList = node1.getTerminationPoint().values().stream()
190                         .filter(tp -> tp.augmentation(TerminationPoint1.class).getTpType().getIntValue()
191                                 == OpenroadmTpType.DEGREETXRXTTP.getIntValue()
192                             || tp.augmentation(TerminationPoint1.class).getTpType().getIntValue()
193                                 == OpenroadmTpType.DEGREERXTTP.getIntValue()
194                             || tp.augmentation(TerminationPoint1.class).getTpType().getIntValue()
195                                 == OpenroadmTpType.DEGREETXTTP.getIntValue())
196                         .collect(Collectors.toList());
197                     // Convert TP List in NEPs and put it in onepl
198                     LOG.info("Degree port List: {}", degPortList.toString());
199                     // TODO: deg port could be sip. e.g. MDONS
200                     oneplist.putAll(populateNepsForRdmNode(node.getNodeId().getValue(), degPortList, false,
201                         TapiStringConstants.PHTNC_MEDIA_OTS));
202                     oneplist.putAll(populateNepsForRdmNode(node.getNodeId().getValue(), degPortList, false,
203                         TapiStringConstants.PHTNC_MEDIA_OMS));
204                     numNeps += degPortList.size() * 2;
205                     break;
206                 case 12:
207                     LOG.info("SRG node");
208                     // Get only external TPs of the srg
209                     List<TerminationPoint> srgPortList = node1.getTerminationPoint().values().stream()
210                         .filter(tp -> tp.augmentation(TerminationPoint1.class).getTpType().getIntValue()
211                                 == OpenroadmTpType.SRGTXRXPP.getIntValue()
212                             || tp.augmentation(TerminationPoint1.class).getTpType().getIntValue()
213                                 == OpenroadmTpType.SRGRXPP.getIntValue()
214                             || tp.augmentation(TerminationPoint1.class).getTpType().getIntValue()
215                                 == OpenroadmTpType.SRGTXPP.getIntValue())
216                         .collect(Collectors.toList());
217                     // Convert TP List in NEPs and put it in onepl
218                     LOG.info("Srg port List: {}", srgPortList);
219                     oneplist.putAll(populateNepsForRdmNode(node.getNodeId().getValue(), srgPortList, true,
220                         TapiStringConstants.PHTNC_MEDIA_OTS));
221                     numNeps += srgPortList.size();
222                     numSips += srgPortList.size();
223                     break;
224                 default:
225                     LOG.error("Node {} type not supported", nodeType.getName());
226             }
227         }
228         // create tapi Node
229         // UUID
230         String nodeIdPhMed = String.join("+", roadm.getNodeId().getValue(), TapiStringConstants.PHTNC_MEDIA);
231         Uuid nodeUuid = new Uuid(UUID.nameUUIDFromBytes(nodeIdPhMed.getBytes(Charset.forName("UTF-8"))).toString());
232         LOG.info("Creation of PHOTONIC node for {}, of Uuid {}", roadm.getNodeId().getValue(), nodeUuid);
233         // Names
234         Name nodeNames =  new NameBuilder().setValueName("roadm node name").setValue(nodeIdPhMed).build();
235         Name nameNodeType = new NameBuilder().setValueName("Node Type").setValue(this.ietfNodeType.getName()).build();
236         // Protocol Layer
237         Set<LayerProtocolName> layerProtocols = Set.of(LayerProtocolName.PHOTONICMEDIA);
238         // Build tapi node
239         LOG.debug("CONVERTTOFULL SRG OTSNode of retrieved OnepMap {} ",
240             oneplist.entrySet().stream().filter(e -> e.getValue()
241                 .getSupportedCepLayerProtocolQualifierInstances()
242                     .contains(new SupportedCepLayerProtocolQualifierInstancesBuilder()
243                         .setNumberOfCepInstances(Uint64.valueOf(1))
244                         .setLayerProtocolQualifier(PHOTONICLAYERQUALIFIEROTS.VALUE)
245                     .build()))
246             .collect(Collectors.toList()).toString());
247         //org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.topology.rev221121.topology.Node
248         var roadmNode = createRoadmTapiNode(nodeUuid,
249             Map.of(nodeNames.key(), nodeNames, nameNodeType.key(), nameNodeType), layerProtocols, oneplist, "Full");
250         // TODO add states corresponding to device config
251         LOG.info("ROADM node {} should have {} NEPs and {} SIPs", roadm.getNodeId().getValue(), numNeps, numSips);
252         LOG.info("ROADM node {} has {} NEPs and {} SIPs",
253             roadm.getNodeId().getValue(),
254             roadmNode.nonnullOwnedNodeEdgePoint().values().size(),
255             roadmNode.nonnullOwnedNodeEdgePoint().values().stream()
256                 .filter(nep -> nep.getMappedServiceInterfacePoint() != null).count());
257         tapiNodes.put(roadmNode.key(), roadmNode);
258     }
259
260     private void convertRoadmNodeAbstracted(Network openroadmTopo) {
261         Map<OwnedNodeEdgePointKey, OwnedNodeEdgePoint> oneMap = new HashMap<>();
262         // 1. Get degree and srg nodes to map TPs into NEPs
263         if (openroadmTopo.getNode() == null) {
264             LOG.warn("Openroadm-topology is null.");
265             return;
266         }
267         int numNeps = 0;
268         int numSips = 0;
269         List<Node> nodeList = new ArrayList<Node>(openroadmTopo.getNode().values());
270         for (Node node:nodeList) {
271             var node1 = node.augmentation(
272                 org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.topology.rev180226.Node1.class);
273             if (node.augmentation(Node1.class) == null && node1 == null) {
274                 LOG.warn("Abstracted node {} doesnt have type of node or is not disaggregated",
275                     node.getNodeId().getValue());
276                 continue;
277             }
278             OpenroadmNodeType nodeType = node.augmentation(
279                     org.opendaylight.yang.gen.v1.http.org.openroadm.common.network.rev230526.Node1.class)
280                 .getNodeType();
281             if (nodeType.getIntValue() != 11) {
282                 // Only consider ROADMS SRG Nodes
283                 continue;
284             }
285             LOG.debug("Handling SRG node in Topology abstraction {}", node.getNodeId().toString());
286             // Get only external TPs of the srg
287             List<TerminationPoint> srgPortList = node1.getTerminationPoint().values().stream()
288                 .filter(tp -> tp.augmentation(TerminationPoint1.class).getTpType().getIntValue()
289                         == OpenroadmTpType.SRGTXRXPP.getIntValue()
290                     || tp.augmentation(TerminationPoint1.class).getTpType().getIntValue()
291                         == OpenroadmTpType.SRGRXPP.getIntValue()
292                     || tp.augmentation(TerminationPoint1.class).getTpType().getIntValue()
293                         == OpenroadmTpType.SRGTXPP.getIntValue())
294                 .collect(Collectors.toList());
295             // Convert TP List in NEPs and put it in onepl
296             LOG.debug("Srg port List: {}", srgPortList);
297             oneMap.putAll(populateNepsForRdmNode(node.getNodeId().getValue(), srgPortList, true,
298                 TapiStringConstants.PHTNC_MEDIA_OTS));
299             numNeps += srgPortList.size();
300             numSips += srgPortList.size();
301         }
302         // create a unique ROADM tapi Node
303         LOG.info("abstraction of the ROADM infrastructure towards a photonic node");
304         Uuid nodeUuid = new Uuid(UUID.nameUUIDFromBytes(
305             TapiStringConstants.RDM_INFRA.getBytes(Charset.forName("UTF-8"))).toString());
306         Name nodeName =
307             new NameBuilder().setValueName("roadm node name").setValue(TapiStringConstants.RDM_INFRA).build();
308         Name nameNodeType =
309             new NameBuilder().setValueName("Node Type").setValue(OpenroadmNodeType.ROADM.getName()).build();
310
311         // Protocol Layer
312         Set<LayerProtocolName> layerProtocols = Set.of(LayerProtocolName.PHOTONICMEDIA);
313         // Build tapi node
314         org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.topology.rev221121.topology.Node roadmNode =
315             createRoadmTapiNode(nodeUuid, Map.of(nodeName.key(), nodeName, nameNodeType.key(), nameNodeType),
316                 layerProtocols, oneMap, "Abstracted");
317         // TODO add states corresponding to device config
318         LOG.info("ROADM node {} should have {} NEPs and {} SIPs", TapiStringConstants.RDM_INFRA, numNeps, numSips);
319         LOG.info("ROADM node {} has {} NEPs and {} SIPs", TapiStringConstants.RDM_INFRA,
320             roadmNode.nonnullOwnedNodeEdgePoint().values().size(),
321             roadmNode.nonnullOwnedNodeEdgePoint().values().stream()
322                 .filter(nep -> nep.getMappedServiceInterfacePoint() != null).count());
323
324         tapiNodes.put(roadmNode.key(), roadmNode);
325     }
326
327     private org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.topology.rev221121.topology.Node
328              createRoadmTapiNode(Uuid nodeUuid, Map<NameKey, Name> nameMap, Set<LayerProtocolName> layerProtocols,
329              Map<OwnedNodeEdgePointKey, OwnedNodeEdgePoint> onepMap, String topoMode) {
330         // Empty random creation of mandatory fields for avoiding errors....
331         CostCharacteristic costCharacteristic = new CostCharacteristicBuilder()
332             .setCostAlgorithm("Restricted Shortest Path - RSP")
333             .setCostName("HOP_COUNT")
334             .setCostValue(TapiStringConstants.COST_HOP_VALUE)
335             .build();
336         LatencyCharacteristic latencyCharacteristic = new LatencyCharacteristicBuilder()
337             .setFixedLatencyCharacteristic(TapiStringConstants.FIXED_LATENCY_VALUE)
338             .setQueuingLatencyCharacteristic(TapiStringConstants.QUEING_LATENCY_VALUE)
339             .setJitterCharacteristic(TapiStringConstants.JITTER_VALUE)
340             .setWanderCharacteristic(TapiStringConstants.WANDER_VALUE)
341             .setTrafficPropertyName("FIXED_LATENCY")
342             .build();
343         RiskCharacteristic riskCharacteristic = new RiskCharacteristicBuilder()
344             .setRiskCharacteristicName("risk characteristic")
345             .setRiskIdentifierList(Set.of("risk identifier1", "risk identifier2"))
346             .build();
347
348         var tapiFactory = new ConvertORToTapiTopology(this.tapiTopoUuid);
349         String choosenMode = topoMode.equals("Full") ? "Full" : "Abstracted";
350         Map<NodeRuleGroupKey, NodeRuleGroup> nodeRuleGroupMap =
351             tapiFactory.createAllNodeRuleGroupForRdmNode(choosenMode, nodeUuid, this.ietfNodeId, onepMap.values());
352         Map<InterRuleGroupKey, InterRuleGroup> interRuleGroupMap =
353             tapiFactory.createInterRuleGroupForRdmNode(choosenMode, nodeUuid, this.ietfNodeId,
354                 nodeRuleGroupMap.entrySet().stream().map(e -> e.getKey()).collect(Collectors.toList()));
355         return new NodeBuilder()
356             .setUuid(nodeUuid)
357             .setName(nameMap)
358             .setLayerProtocolName(layerProtocols)
359             .setAdministrativeState(AdministrativeState.UNLOCKED)
360             .setOperationalState(OperationalState.ENABLED)
361             .setLifecycleState(LifecycleState.INSTALLED)
362             .setOwnedNodeEdgePoint(onepMap)
363             .setNodeRuleGroup(nodeRuleGroupMap)
364             .setInterRuleGroup(interRuleGroupMap)
365             .setCostCharacteristic(Map.of(costCharacteristic.key(), costCharacteristic))
366             .setLatencyCharacteristic(Map.of(latencyCharacteristic.key(), latencyCharacteristic))
367             .setRiskParameterPac(
368                 new RiskParameterPacBuilder()
369                     .setRiskCharacteristic(Map.of(riskCharacteristic.key(), riskCharacteristic))
370                     .build())
371             .setErrorCharacteristic("error")
372             .setLossCharacteristic("loss")
373             .setRepeatDeliveryCharacteristic("repeat delivery")
374             .setDeliveryOrderCharacteristic("delivery order")
375             .setUnavailableTimeCharacteristic("unavailable time")
376             .setServerIntegrityProcessCharacteristic("server integrity process")
377             .build();
378     }
379
380     public Map<OwnedNodeEdgePointKey, OwnedNodeEdgePoint> populateNepsForRdmNode(String nodeId,
381             List<TerminationPoint> tpList, boolean withSip, String nepPhotonicSublayer) {
382         // create neps for MC and and Photonic Media OTS/OMS
383         Map<OwnedNodeEdgePointKey, OwnedNodeEdgePoint> onepMap = new HashMap<>();
384         for (TerminationPoint tp:tpList) {
385             // Admin and oper state common for all tps
386             OpenroadmTpType tpType = tp.augmentation(TerminationPoint1.class).getTpType();
387             // PHOTONIC MEDIA nep
388             LOG.debug("PHOTO NEP = {}", String.join("+", this.ietfNodeId, nepPhotonicSublayer,
389                 tp.getTpId().getValue()));
390             SupportedCepLayerProtocolQualifierInstancesBuilder sclpqiBd =
391                 new SupportedCepLayerProtocolQualifierInstancesBuilder()
392                     .setNumberOfCepInstances(Uint64.valueOf(1));
393             switch (nepPhotonicSublayer) {
394                 case TapiStringConstants.PHTNC_MEDIA_OMS:
395                     sclpqiBd.setLayerProtocolQualifier(PHOTONICLAYERQUALIFIEROMS.VALUE);
396                     break;
397                 case TapiStringConstants.PHTNC_MEDIA_OTS:
398                     sclpqiBd.setLayerProtocolQualifier(PHOTONICLAYERQUALIFIEROTS.VALUE);
399                     break;
400                 case TapiStringConstants.MC:
401                     sclpqiBd.setLayerProtocolQualifier(PHOTONICLAYERQUALIFIERMC.VALUE);
402                     break;
403                 case TapiStringConstants.OTSI_MC:
404                     sclpqiBd.setLayerProtocolQualifier(PHOTONICLAYERQUALIFIEROTSiMC.VALUE);
405                     break;
406                 default:
407                     break;
408             }
409             //List<SupportedCepLayerProtocolQualifierInstances> sclpqiList = new ArrayList<>(List.of(sclpqiBd.build()));
410             OwnedNodeEdgePointBuilder onepBd = new OwnedNodeEdgePointBuilder();
411             if (!nepPhotonicSublayer.equals(TapiStringConstants.MC)
412                     && !nepPhotonicSublayer.equals(TapiStringConstants.OTSI_MC)) {
413                 ConvertORToTapiTopology tapiFactory = new ConvertORToTapiTopology(this.tapiTopoUuid);
414                 Map<Double,Double> usedFreqMap = new HashMap<>();
415                 Map<Double,Double> availableFreqMap = new HashMap<>();
416                 switch (tpType) {
417                     // Whatever is the TP and its type we consider that it is handled in a bidirectional way :
418                     // same wavelength(s) used in both direction.
419                     case SRGRXPP:
420                     case SRGTXPP:
421                     case SRGTXRXPP:
422                         usedFreqMap = tapiFactory.getPPUsedWavelength(tp);
423                         if (usedFreqMap == null || usedFreqMap.isEmpty()) {
424                             availableFreqMap.put(GridConstant.START_EDGE_FREQUENCY * 1E09,
425                                 GridConstant.START_EDGE_FREQUENCY * 1E09
426                                 + GridConstant.GRANULARITY * GridConstant.EFFECTIVE_BITS * 1E06);
427                         } else {
428                             LOG.debug("EnteringLOOPcreateOTSiMC & MC with usedFreqMap non empty {} NEP {} for Node {}",
429                                 usedFreqMap.toString(), String.join("+", this.ietfNodeId, nepPhotonicSublayer,
430                                 tp.getTpId().getValue()), nodeId);
431                             onepMap.putAll(populateNepsForRdmNode(nodeId, new ArrayList<>(List.of(tp)),
432                                 true, TapiStringConstants.MC));
433                             onepMap.putAll(populateNepsForRdmNode(nodeId, new ArrayList<>(List.of(tp)),
434                                 true, TapiStringConstants.OTSI_MC));
435                         }
436                         break;
437                     case DEGREERXTTP:
438                     case DEGREETXTTP:
439                     case DEGREETXRXTTP:
440                         usedFreqMap = tapiFactory.getTTPUsedFreqMap(tp);
441                         availableFreqMap = tapiFactory.getTTPAvailableFreqMap(tp);
442                         break;
443                     default:
444                         break;
445                 }
446                 LOG.debug("calling add Photonic NEP spec for Roadm");
447                 onepBd = tapiFactory.addPhotSpecToRoadmOnep(nodeId, usedFreqMap, availableFreqMap, onepBd,
448                     nepPhotonicSublayer);
449             }
450             AdminStates admin = tp.augmentation(TerminationPoint1.class).getAdministrativeState();
451             State oper = tp.augmentation(TerminationPoint1.class).getOperationalState();
452             Name nepName = new NameBuilder()
453                 .setValueName(nepPhotonicSublayer + "NodeEdgePoint")
454                 .setValue(String.join("+", this.ietfNodeId, nepPhotonicSublayer, tp.getTpId().getValue()))
455                 .build();
456             OwnedNodeEdgePoint onep = onepBd
457                 .setUuid(new Uuid(UUID.nameUUIDFromBytes((String.join("+", this.ietfNodeId,
458                     nepPhotonicSublayer, tp.getTpId().getValue()))
459                         .getBytes(Charset.forName("UTF-8"))).toString()))
460                 .setLayerProtocolName(LayerProtocolName.PHOTONICMEDIA)
461                 .setName(Map.of(nepName.key(), nepName))
462                 .setSupportedCepLayerProtocolQualifierInstances(
463                     new ArrayList<>(List.of(
464                         new SupportedCepLayerProtocolQualifierInstancesBuilder()
465                             .setLayerProtocolQualifier(
466                                 TapiStringConstants.PHTNC_MEDIA_OMS.equals(nepPhotonicSublayer)
467                                     ? PHOTONICLAYERQUALIFIEROMS.VALUE
468                                     : PHOTONICLAYERQUALIFIEROTS.VALUE)
469                             .setNumberOfCepInstances(Uint64.valueOf(1))
470                             .build())))
471                 .setDirection(Direction.BIDIRECTIONAL)
472                 .setLinkPortRole(PortRole.SYMMETRIC)
473                 .setAdministrativeState(this.tapiLink.setTapiAdminState(admin.getName()))
474                 .setOperationalState(this.tapiLink.setTapiOperationalState(oper.getName()))
475                 .setLifecycleState(LifecycleState.INSTALLED)
476                 .build();
477             onepMap.put(onep.key(), onep);
478         }
479         return onepMap;
480     }
481
482     public void convertXpdrToRdmLinks(
483             List<org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.topology.rev180226
484                 .networks.network.Link> xpdrRdmLinkList) {
485         List<String> linksToNotConvert = new ArrayList<>();
486         LOG.info("creation of {} xpdr to roadm links", xpdrRdmLinkList.size() / 2);
487         LOG.debug("Link list = {}", xpdrRdmLinkList);
488         for (var link:xpdrRdmLinkList) {
489             if (!linksToNotConvert.contains(link.getLinkId().getValue())) {
490                 var oppositeLink = xpdrRdmLinkList.stream()
491                     .filter(l -> l.getLinkId().equals(link.augmentation(Link1.class).getOppositeLink())).findAny()
492                     .orElse(null);
493                 AdminStates oppLnkAdmState = null;
494                 State oppLnkOpState = null;
495                 if (oppositeLink != null) {
496                     oppLnkAdmState = oppositeLink.augmentation(Link1.class).getAdministrativeState();
497                     oppLnkOpState = oppositeLink.augmentation(Link1.class).getOperationalState();
498                 }
499                 String sourceNode =
500                     link.getSource().getSourceNode().getValue().contains("ROADM")
501                         ? getIdBasedOnModelVersion(link.getSource().getSourceNode().getValue())
502                         : link.getSource().getSourceNode().getValue();
503                 String destNode =
504                     link.getDestination().getDestNode().getValue().contains("ROADM")
505                         ? getIdBasedOnModelVersion(link.getDestination().getDestNode().getValue())
506                         : link.getDestination().getDestNode().getValue();
507                 Link tapLink = this.tapiLink.createTapiLink(
508                     sourceNode, link.getSource().getSourceTp().getValue(),
509                     destNode, link.getDestination().getDestTp().getValue(),
510                     TapiStringConstants.OMS_XPDR_RDM_LINK,
511                     sourceNode.contains("ROADM") ? TapiStringConstants.PHTNC_MEDIA : TapiStringConstants.XPDR,
512                     destNode.contains("ROADM") ? TapiStringConstants.PHTNC_MEDIA : TapiStringConstants.XPDR,
513                     TapiStringConstants.PHTNC_MEDIA_OTS, TapiStringConstants.PHTNC_MEDIA_OTS,
514                     //adminState,
515                     link.augmentation(Link1.class).getAdministrativeState() == null || oppLnkAdmState == null
516                         ? null
517                         : this.tapiLink.setTapiAdminState(
518                             link.augmentation(Link1.class).getAdministrativeState(), oppLnkAdmState).getName(),
519                     //operState,
520                     link.augmentation(Link1.class).getOperationalState() == null || oppLnkOpState == null
521                         ? null
522                         : this.tapiLink.setTapiOperationalState(
523                             link.augmentation(Link1.class).getOperationalState(), oppLnkOpState).getName(),
524                     Set.of(LayerProtocolName.PHOTONICMEDIA), Set.of(LayerProtocolName.PHOTONICMEDIA.getName()),
525                     this.tapiTopoUuid);
526                 linksToNotConvert.add(link.augmentation(Link1.class).getOppositeLink().getValue());
527                 this.tapiLinks.put(tapLink.key(), tapLink);
528             }
529         }
530     }
531
532     private String getIdBasedOnModelVersion(String linknodeid) {
533         if (linknodeid.matches("[A-Z]{5}-[A-Z0-9]{2}-.*")) {
534             LOG.info("OpenROADM version > 1.2.1 {}", linknodeid);
535             return String.join("-", linknodeid.split("-")[0], linknodeid.split("-")[1]);
536         } else {
537             LOG.info("OpenROADM version <= 1.2.1 {}", linknodeid);
538             return linknodeid.split("-")[0];
539         }
540     }
541
542     public void setTapiNodes(Map<NodeKey,
543             org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.topology.rev221121.topology.Node> nodeMap) {
544         this.tapiNodes.putAll(nodeMap);
545     }
546
547     public Map<NodeKey, org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.topology.rev221121.topology.Node>
548             getTapiNodes() {
549         return tapiNodes;
550     }
551
552     public Map<LinkKey, Link> getTapiLinks() {
553         return tapiLinks;
554     }
555
556     public void setTapiSips(Map<ServiceInterfacePointKey, ServiceInterfacePoint> tapiSip) {
557         this.tapiSips.putAll(tapiSip);
558     }
559
560     public Map<ServiceInterfacePointKey, ServiceInterfacePoint> getTapiSips() {
561         return tapiSips;
562     }
563
564     public static void setTopologicalMode(String topoMode) {
565         ConvertORTopoToTapiFullTopo.topologicalMode = topoMode;
566     }
567
568     public String getTopologicalMode() {
569         return topologicalMode;
570     }
571 }