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