9e83c91e6bac4b0c899f7d3e23241befe10d13e0
[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.tapi.TapiStringConstants;
19 import org.opendaylight.transportpce.tapi.utils.TapiLink;
20 import org.opendaylight.yang.gen.v1.http.org.openroadm.common.network.rev230526.Link1;
21 import org.opendaylight.yang.gen.v1.http.org.openroadm.common.network.rev230526.TerminationPoint1;
22 import org.opendaylight.yang.gen.v1.http.org.openroadm.common.state.types.rev191129.State;
23 import org.opendaylight.yang.gen.v1.http.org.openroadm.equipment.states.types.rev191129.AdminStates;
24 import org.opendaylight.yang.gen.v1.http.org.openroadm.network.types.rev230526.OpenroadmNodeType;
25 import org.opendaylight.yang.gen.v1.http.org.openroadm.network.types.rev230526.OpenroadmTpType;
26 import org.opendaylight.yang.gen.v1.http.org.openroadm.otn.network.topology.rev230526.Node1;
27 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.rev180226.networks.Network;
28 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.rev180226.networks.network.Node;
29 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.topology.rev180226.networks.network.node.TerminationPoint;
30 import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.common.rev221121.AdministrativeState;
31 import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.common.rev221121.Direction;
32 import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.common.rev221121.LayerProtocolName;
33 import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.common.rev221121.LifecycleState;
34 import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.common.rev221121.OperationalState;
35 import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.common.rev221121.PortRole;
36 import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.common.rev221121.Uuid;
37 import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.common.rev221121.global._class.Name;
38 import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.common.rev221121.global._class.NameBuilder;
39 import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.common.rev221121.global._class.NameKey;
40 import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.common.rev221121.tapi.context.ServiceInterfacePoint;
41 import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.common.rev221121.tapi.context.ServiceInterfacePointKey;
42 import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.photonic.media.rev221121.PHOTONICLAYERQUALIFIEROMS;
43 import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.photonic.media.rev221121.PHOTONICLAYERQUALIFIEROTS;
44 import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.topology.rev221121.node.OwnedNodeEdgePoint;
45 import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.topology.rev221121.node.OwnedNodeEdgePointBuilder;
46 import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.topology.rev221121.node.OwnedNodeEdgePointKey;
47 import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.topology.rev221121.node.RiskParameterPac;
48 import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.topology.rev221121.node.RiskParameterPacBuilder;
49 import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.topology.rev221121.node.edge.point.SupportedCepLayerProtocolQualifierInstances;
50 import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.topology.rev221121.node.edge.point.SupportedCepLayerProtocolQualifierInstancesBuilder;
51 import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.topology.rev221121.risk.parameter.pac.RiskCharacteristic;
52 import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.topology.rev221121.risk.parameter.pac.RiskCharacteristicBuilder;
53 import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.topology.rev221121.topology.Link;
54 import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.topology.rev221121.topology.LinkKey;
55 import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.topology.rev221121.topology.NodeBuilder;
56 import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.topology.rev221121.topology.NodeKey;
57 import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.topology.rev221121.transfer.cost.pac.CostCharacteristic;
58 import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.topology.rev221121.transfer.cost.pac.CostCharacteristicBuilder;
59 import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.topology.rev221121.transfer.timing.pac.LatencyCharacteristic;
60 import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.topology.rev221121.transfer.timing.pac.LatencyCharacteristicBuilder;
61 import org.opendaylight.yangtools.yang.common.Uint64;
62 import org.slf4j.Logger;
63 import org.slf4j.LoggerFactory;
64
65
66 public class ConvertORTopoToTapiFullTopo {
67
68     private static final Logger LOG = LoggerFactory.getLogger(ConvertORTopoToTapiFullTopo.class);
69     private String ietfNodeId;
70     private OpenroadmNodeType ietfNodeType;
71     private Uuid tapiTopoUuid;
72     private Map<NodeKey, org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.topology.rev221121.topology.Node>
73         tapiNodes;
74     private Map<LinkKey, Link> tapiLinks;
75     private Map<ServiceInterfacePointKey, ServiceInterfacePoint> tapiSips;
76     private final TapiLink tapiLink;
77
78
79     public ConvertORTopoToTapiFullTopo(Uuid tapiTopoUuid, TapiLink tapiLink) {
80         this.tapiTopoUuid = tapiTopoUuid;
81         this.tapiNodes = new HashMap<>();
82         this.tapiLinks = new HashMap<>();
83         this.tapiSips = new HashMap<>();
84         this.tapiLink = tapiLink;
85     }
86
87     public void convertRdmToRdmLinks(List<org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang
88             .ietf.network.topology.rev180226.networks.network.Link> rdmTordmLinkList) {
89         List<String> linksToNotConvert = new ArrayList<>();
90         LOG.info("creation of {} roadm to roadm links", rdmTordmLinkList.size() / 2);
91         for (org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.topology.rev180226.networks.network
92             .Link link : rdmTordmLinkList) {
93             if (!linksToNotConvert.contains(link.getLinkId().getValue())) {
94                 org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang
95                         .ietf.network.topology.rev180226.networks.network.Link oppositeLink = rdmTordmLinkList.stream()
96                     .filter(l -> l.getLinkId().equals(link.augmentation(Link1.class).getOppositeLink()))
97                     .findAny().orElse(null);
98
99                 AdminStates oppLnkAdmState = null;
100                 State oppLnkOpState = null;
101                 if (oppositeLink != null) {
102                     oppLnkAdmState = oppositeLink.augmentation(Link1.class).getAdministrativeState();
103                     oppLnkOpState = oppositeLink.augmentation(Link1.class).getOperationalState();
104                 }
105                 String adminState =
106                     link.augmentation(Link1.class).getAdministrativeState() == null
107                         || oppLnkAdmState == null
108                     ? null
109                     : this.tapiLink.setTapiAdminState(
110                         link.augmentation(Link1.class).getAdministrativeState(), oppLnkAdmState).getName();
111                 String operState =
112                     link.augmentation(Link1.class).getOperationalState() == null
113                         || oppLnkOpState == null
114                     ? null
115                     : this.tapiLink.setTapiOperationalState(
116                         link.augmentation(Link1.class).getOperationalState(), oppLnkOpState).getName();
117
118                 Link tapLink = this.tapiLink.createTapiLink(String.join("-",
119                         link.getSource().getSourceNode().getValue().split("-")[0],
120                         link.getSource().getSourceNode().getValue().split("-")[1]),
121                     link.getSource().getSourceTp().getValue(), String.join("-",
122                         link.getDestination().getDestNode().getValue().split("-")[0],
123                         link.getDestination().getDestNode().getValue().split("-")[1]),
124                     link.getDestination().getDestTp().getValue(), TapiStringConstants.OMS_RDM_RDM_LINK,
125                     TapiStringConstants.PHTNC_MEDIA, TapiStringConstants.PHTNC_MEDIA,
126                     TapiStringConstants.PHTNC_MEDIA_OTS, TapiStringConstants.PHTNC_MEDIA_OTS, adminState, operState,
127                     Set.of(LayerProtocolName.PHOTONICMEDIA), Set.of(LayerProtocolName.PHOTONICMEDIA.getName()),
128                     this.tapiTopoUuid);
129                 linksToNotConvert.add(link
130                     .augmentation(Link1.class)
131                     .getOppositeLink().getValue());
132                 tapiLinks.put(tapLink.key(), tapLink);
133             }
134         }
135     }
136
137     public void convertRoadmNode(Node roadm, Network openroadmTopo) {
138         this.ietfNodeId = roadm.getNodeId().getValue();
139         this.ietfNodeType = roadm.augmentation(
140             org.opendaylight.yang.gen.v1.http.org.openroadm.common.network.rev230526.Node1.class).getNodeType();
141         Map<OwnedNodeEdgePointKey, OwnedNodeEdgePoint> oneplist = new HashMap<>();
142         // 1. Get degree and srg nodes to map TPs into NEPs
143         if (openroadmTopo.getNode() == null) {
144             LOG.warn("Openroadm-topology is null.");
145             return;
146         }
147         int numNeps = 0;
148         int numSips = 0;
149         List<Node> nodeList = new ArrayList<Node>(openroadmTopo.getNode().values());
150         for (Node node:nodeList) {
151             if (node.getSupportingNode().values().stream().noneMatch(sp -> sp.getNodeRef().getValue()
152                 .equals(this.ietfNodeId))) {
153                 LOG.debug("Abstracted node {} is not part of {}",
154                     node.getNodeId().getValue(), this.ietfNodeId);
155                 continue;
156             }
157             if (node.augmentation(Node1.class) == null
158                 && node.augmentation(org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang
159                 .ietf.network.topology.rev180226.Node1.class) == null) {
160                 LOG.warn("Abstracted node {} doesnt have type of node or is not disaggregated",
161                     node.getNodeId().getValue());
162                 continue;
163             }
164             OpenroadmNodeType nodeType = node.augmentation(org.opendaylight.yang.gen.v1.http
165                 .org.openroadm.common.network.rev230526.Node1.class).getNodeType();
166             org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.topology.rev180226.Node1 node1 =
167                 node.augmentation(org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang
168                     .ietf.network.topology.rev180226.Node1.class);
169             LOG.info("TPs of node: {}", node1.getTerminationPoint().values());
170             switch (nodeType.getIntValue()) {
171                 case 11:
172                     LOG.info("Degree node");
173                     // Get only external TPs of the degree
174                     List<TerminationPoint> degPortList = node1.getTerminationPoint().values().stream()
175                         .filter(tp -> tp.augmentation(TerminationPoint1.class).getTpType().getIntValue()
176                             == OpenroadmTpType.DEGREETXRXTTP.getIntValue()
177                             || tp.augmentation(TerminationPoint1.class).getTpType().getIntValue()
178                             == OpenroadmTpType.DEGREERXTTP.getIntValue()
179                             || tp.augmentation(TerminationPoint1.class).getTpType().getIntValue()
180                             == OpenroadmTpType.DEGREETXTTP.getIntValue())
181                         .collect(Collectors.toList());
182                     // Convert TP List in NEPs and put it in onepl
183                     LOG.info("Degree port List: {}", degPortList);
184                     // TODO: deg port could be sip. e.g. MDONS
185                     oneplist.putAll(populateNepsForRdmNode(degPortList, false, TapiStringConstants.PHTNC_MEDIA_OTS));
186                     oneplist.putAll(populateNepsForRdmNode(degPortList, false, TapiStringConstants.PHTNC_MEDIA_OMS));
187                     numNeps += degPortList.size() * 2;
188                     break;
189                 case 12:
190                     LOG.info("SRG node");
191                     // Get only external TPs of the srg
192                     List<TerminationPoint> srgPortList = node1.getTerminationPoint().values().stream()
193                         .filter(tp -> tp.augmentation(TerminationPoint1.class).getTpType().getIntValue()
194                             == OpenroadmTpType.SRGTXRXPP.getIntValue()
195                             || tp.augmentation(TerminationPoint1.class).getTpType().getIntValue()
196                             == OpenroadmTpType.SRGRXPP.getIntValue()
197                             || tp.augmentation(TerminationPoint1.class).getTpType().getIntValue()
198                             == OpenroadmTpType.SRGTXPP.getIntValue())
199                         .collect(Collectors.toList());
200                     // Convert TP List in NEPs and put it in onepl
201                     LOG.info("Srg port List: {}", srgPortList);
202                     oneplist.putAll(populateNepsForRdmNode(srgPortList, true, TapiStringConstants.PHTNC_MEDIA_OTS));
203                     numNeps += srgPortList.size();
204                     numSips += srgPortList.size();
205                     break;
206                 default:
207                     LOG.error("Node {} type not supported", nodeType.getName());
208             }
209         }
210         // create tapi Node
211         // UUID
212         Uuid nodeUuid = new Uuid(UUID.nameUUIDFromBytes((String.join("+", roadm.getNodeId().getValue(),
213             TapiStringConstants.PHTNC_MEDIA)).getBytes(Charset.forName("UTF-8"))).toString());
214         LOG.info("Creation of PHOTONIC node for {}, of Uuid {}", roadm.getNodeId().getValue(), nodeUuid.toString());
215         // Names
216         Name nodeNames =  new NameBuilder().setValueName("roadm node name")
217             .setValue(String.join("+", roadm.getNodeId().getValue(), TapiStringConstants.PHTNC_MEDIA)).build();
218         Name nameNodeType = new NameBuilder().setValueName("Node Type")
219             .setValue(this.ietfNodeType.getName()).build();
220         // Protocol Layer
221         Set<LayerProtocolName> layerProtocols = Set.of(LayerProtocolName.PHOTONICMEDIA);
222         // Build tapi node
223         org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.topology.rev221121.topology
224             .Node roadmNode = createRoadmTapiNode(nodeUuid,
225             Map.of(nodeNames.key(), nodeNames, nameNodeType.key(), nameNodeType), layerProtocols, oneplist);
226         // TODO add states corresponding to device config
227         LOG.info("ROADM node {} should have {} NEPs and {} SIPs", roadm.getNodeId().getValue(), numNeps, numSips);
228         LOG.info("ROADM node {} has {} NEPs and {} SIPs", roadm.getNodeId().getValue(),
229             roadmNode.nonnullOwnedNodeEdgePoint().values().size(),
230             roadmNode.nonnullOwnedNodeEdgePoint().values().stream()
231                 .filter(nep -> nep.getMappedServiceInterfacePoint() != null).count());
232
233         tapiNodes.put(roadmNode.key(), roadmNode);
234     }
235
236     private org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.topology.rev221121.topology.Node
237              createRoadmTapiNode(Uuid nodeUuid, Map<NameKey, Name> nameMap, Set<LayerProtocolName> layerProtocols,
238              Map<OwnedNodeEdgePointKey, OwnedNodeEdgePoint> oneplist) {
239         // Empty random creation of mandatory fields for avoiding errors....
240         CostCharacteristic costCharacteristic = new CostCharacteristicBuilder()
241             .setCostAlgorithm("Restricted Shortest Path - RSP")
242             .setCostName("HOP_COUNT")
243             .setCostValue(TapiStringConstants.COST_HOP_VALUE)
244             .build();
245         LatencyCharacteristic latencyCharacteristic = new LatencyCharacteristicBuilder()
246             .setFixedLatencyCharacteristic(TapiStringConstants.FIXED_LATENCY_VALUE)
247             .setQueuingLatencyCharacteristic(TapiStringConstants.QUEING_LATENCY_VALUE)
248             .setJitterCharacteristic(TapiStringConstants.JITTER_VALUE)
249             .setWanderCharacteristic(TapiStringConstants.WANDER_VALUE)
250             .setTrafficPropertyName("FIXED_LATENCY")
251             .build();
252         RiskCharacteristic riskCharacteristic = new RiskCharacteristicBuilder()
253             .setRiskCharacteristicName("risk characteristic")
254             .setRiskIdentifierList(Set.of("risk identifier1", "risk identifier2"))
255             .build();
256         RiskParameterPac riskParamPac = new RiskParameterPacBuilder()
257             .setRiskCharacteristic(Map.of(riskCharacteristic.key(), riskCharacteristic))
258             .build();
259         return new NodeBuilder()
260             .setUuid(nodeUuid)
261             .setName(nameMap)
262             .setLayerProtocolName(layerProtocols)
263             .setAdministrativeState(AdministrativeState.UNLOCKED)
264             .setOperationalState(OperationalState.ENABLED)
265             .setLifecycleState(LifecycleState.INSTALLED)
266             .setOwnedNodeEdgePoint(oneplist)
267             .setNodeRuleGroup(new ConvertORToTapiTopology(this.tapiTopoUuid)
268                 .createNodeRuleGroupForRdmNode("Full",nodeUuid, this.ietfNodeId, oneplist.values()))
269             .setCostCharacteristic(Map.of(costCharacteristic.key(), costCharacteristic))
270             .setLatencyCharacteristic(Map.of(latencyCharacteristic.key(), latencyCharacteristic))
271             .setRiskParameterPac(riskParamPac)
272             .setErrorCharacteristic("error")
273             .setLossCharacteristic("loss")
274             .setRepeatDeliveryCharacteristic("repeat delivery")
275             .setDeliveryOrderCharacteristic("delivery order")
276             .setUnavailableTimeCharacteristic("unavailable time")
277             .setServerIntegrityProcessCharacteristic("server integrity process")
278             .build();
279     }
280
281     private Map<OwnedNodeEdgePointKey, OwnedNodeEdgePoint> populateNepsForRdmNode(List<TerminationPoint> tpList,
282             boolean withSip, String nepPhotonicSublayer) {
283         // create neps for MC and OTSiMC and Photonic Media
284         Map<OwnedNodeEdgePointKey, OwnedNodeEdgePoint> onepMap = new HashMap<>();
285         for (TerminationPoint tp:tpList) {
286             // Admin and oper state common for all tps
287             AdminStates admin = tp.augmentation(TerminationPoint1.class).getAdministrativeState();
288             State oper = tp.augmentation(TerminationPoint1.class).getOperationalState();
289             // PHOTONIC MEDIA nep
290             LOG.info("PHOTO NEP = {}", String.join("+", this.ietfNodeId, nepPhotonicSublayer,
291                 tp.getTpId().getValue()));
292             Name nepName = new NameBuilder()
293                 .setValueName(nepPhotonicSublayer + "NodeEdgePoint")
294                 .setValue(String.join("+", this.ietfNodeId, nepPhotonicSublayer,
295                     tp.getTpId().getValue()))
296                 .build();
297
298             List<SupportedCepLayerProtocolQualifierInstances> sclpqiList = new ArrayList<>();
299             sclpqiList.add(
300                 new SupportedCepLayerProtocolQualifierInstancesBuilder()
301                     .setLayerProtocolQualifier(
302                         TapiStringConstants.PHTNC_MEDIA_OMS.equals(nepPhotonicSublayer)
303                             ? PHOTONICLAYERQUALIFIEROMS.VALUE
304                             : PHOTONICLAYERQUALIFIEROTS.VALUE)
305                     .setNumberOfCepInstances(Uint64.valueOf(1))
306                     .build());
307             OwnedNodeEdgePoint onep = new OwnedNodeEdgePointBuilder()
308                 .setUuid(new Uuid(UUID.nameUUIDFromBytes((String.join("+", this.ietfNodeId,
309                     nepPhotonicSublayer, tp.getTpId().getValue()))
310                     .getBytes(Charset.forName("UTF-8"))).toString()))
311                 .setLayerProtocolName(LayerProtocolName.PHOTONICMEDIA)
312                 .setName(Map.of(nepName.key(), nepName))
313                 .setSupportedCepLayerProtocolQualifierInstances(sclpqiList)
314                 .setDirection(Direction.BIDIRECTIONAL)
315                 .setLinkPortRole(PortRole.SYMMETRIC)
316                 .setAdministrativeState(this.tapiLink.setTapiAdminState(admin.getName()))
317                 .setOperationalState(this.tapiLink.setTapiOperationalState(oper.getName()))
318                 .setLifecycleState(LifecycleState.INSTALLED)
319                 .build();
320             onepMap.put(onep.key(), onep);
321         }
322         return onepMap;
323     }
324
325     public void convertXpdrToRdmLinks(List<org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang
326             .ietf.network.topology.rev180226.networks.network.Link> xpdrRdmLinkList) {
327         List<String> linksToNotConvert = new ArrayList<>();
328         LOG.info("creation of {} xpdr to roadm links", xpdrRdmLinkList.size() / 2);
329         // LOG.info("Link list = {}", xpdrRdmLinkList.toString());
330         for (org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang
331             .ietf.network.topology.rev180226.networks.network.Link link:xpdrRdmLinkList) {
332             if (!linksToNotConvert.contains(link.getLinkId().getValue())) {
333                 org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang
334                     .ietf.network.topology.rev180226.networks.network.Link oppositeLink = xpdrRdmLinkList.stream()
335                     .filter(l -> l.getLinkId().equals(link.augmentation(Link1.class).getOppositeLink())).findAny()
336                     .orElse(null);
337
338                 AdminStates oppLnkAdmState = null;
339                 State oppLnkOpState = null;
340                 if (oppositeLink != null) {
341                     oppLnkAdmState = oppositeLink.augmentation(Link1.class).getAdministrativeState();
342                     oppLnkOpState = oppositeLink.augmentation(Link1.class).getOperationalState();
343                 }
344                 String adminState =
345                     link.augmentation(Link1.class).getAdministrativeState() == null
346                         || oppLnkAdmState == null
347                     ? null
348                     : this.tapiLink.setTapiAdminState(
349                         link.augmentation(Link1.class).getAdministrativeState(), oppLnkAdmState).getName();
350                 String operState =
351                     link.augmentation(Link1.class).getOperationalState() == null
352                         || oppLnkOpState == null
353                     ? null
354                     : this.tapiLink.setTapiOperationalState(
355                         link.augmentation(Link1.class).getOperationalState(), oppLnkOpState).getName();
356
357                 String sourceNode = (link.getSource().getSourceNode().getValue().contains("ROADM"))
358                     ? getIdBasedOnModelVersion(link.getSource().getSourceNode().getValue())
359                     : link.getSource().getSourceNode().getValue();
360                 String sourceTp = link.getSource().getSourceTp().getValue();
361                 String sourceNodeQual = sourceNode.contains("ROADM") ? TapiStringConstants.PHTNC_MEDIA
362                     : TapiStringConstants.XPDR;
363                 String destNode = (link.getDestination().getDestNode().getValue().contains("ROADM"))
364                     ? getIdBasedOnModelVersion(link.getDestination().getDestNode().getValue())
365                     : link.getDestination().getDestNode().getValue();
366                 String destTp = link.getDestination().getDestTp().getValue();
367                 String destNodeQual = destNode.contains("ROADM") ? TapiStringConstants.PHTNC_MEDIA
368                     : TapiStringConstants.XPDR;
369                 Link tapLink = this.tapiLink.createTapiLink(sourceNode, sourceTp, destNode, destTp,
370                     TapiStringConstants.OMS_XPDR_RDM_LINK, sourceNodeQual, destNodeQual,
371                     TapiStringConstants.PHTNC_MEDIA_OTS, TapiStringConstants.PHTNC_MEDIA_OTS, adminState,
372                     operState, Set.of(LayerProtocolName.PHOTONICMEDIA),
373                     Set.of(LayerProtocolName.PHOTONICMEDIA.getName()), this.tapiTopoUuid);
374                 linksToNotConvert.add(link.augmentation(Link1.class).getOppositeLink().getValue());
375                 this.tapiLinks.put(tapLink.key(), tapLink);
376             }
377         }
378     }
379
380     private String getIdBasedOnModelVersion(String linknodeid) {
381         if (linknodeid.matches("[A-Z]{5}-[A-Z0-9]{2}-.*")) {
382             LOG.info("OpenROADM version > 1.2.1 {}", linknodeid);
383             return String.join("-", linknodeid.split("-")[0], linknodeid.split("-")[1]);
384         } else {
385             LOG.info("OpenROADM version <= 1.2.1 {}", linknodeid);
386             return linknodeid.split("-")[0];
387         }
388     }
389
390
391     public void setTapiNodes(Map<NodeKey,
392             org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.topology.rev221121.topology.Node> nodeMap) {
393         this.tapiNodes.putAll(nodeMap);
394     }
395
396     public Map<NodeKey, org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.topology.rev221121.topology.Node>
397             getTapiNodes() {
398         return tapiNodes;
399     }
400
401     public Map<LinkKey, Link> getTapiLinks() {
402         return tapiLinks;
403     }
404
405     public void setTapiSips(Map<ServiceInterfacePointKey, ServiceInterfacePoint> tapiSip) {
406         this.tapiSips.putAll(tapiSip);
407     }
408
409     public Map<ServiceInterfacePointKey, ServiceInterfacePoint> getTapiSips() {
410         return tapiSips;
411     }
412 }