Migration to TAPI 2.4 Step3
[transportpce.git] / tapi / src / main / java / org / opendaylight / transportpce / tapi / listeners / TapiPceNotificationHandler.java
1 /*
2  * Copyright © 2021 Nokia, Inc. and others.  All rights reserved.
3  *
4  * This program and the accompanying materials are made available under the
5  * terms of the Eclipse Public License v1.0 which accompanies this distribution,
6  * and is available at http://www.eclipse.org/legal/epl-v10.html
7  */
8 package org.opendaylight.transportpce.tapi.listeners;
9
10 import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
11 import java.nio.charset.Charset;
12 import java.nio.charset.StandardCharsets;
13 import java.util.ArrayList;
14 import java.util.Comparator;
15 import java.util.HashMap;
16 import java.util.List;
17 import java.util.Map;
18 import java.util.Optional;
19 import java.util.Set;
20 import java.util.UUID;
21 import java.util.concurrent.ExecutionException;
22 import java.util.stream.Collectors;
23 import org.opendaylight.mdsal.binding.api.DataBroker;
24 import org.opendaylight.mdsal.binding.api.NotificationService.CompositeListener;
25 import org.opendaylight.mdsal.common.api.LogicalDatastoreType;
26 import org.opendaylight.transportpce.common.network.NetworkTransactionImpl;
27 import org.opendaylight.transportpce.common.network.NetworkTransactionService;
28 import org.opendaylight.transportpce.tapi.TapiStringConstants;
29 import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.pce.rev230925.ServicePathRpcResult;
30 import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.pce.rev230925.service.path.rpc.result.PathDescription;
31 import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.pce.rev230925.service.path.rpc.result.PathDescriptionBuilder;
32 import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.portmapping.rev220922.Network;
33 import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.portmapping.rev220922.mapping.Mapping;
34 import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.portmapping.rev220922.mapping.MappingKey;
35 import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.portmapping.rev220922.network.Nodes;
36 import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.portmapping.rev220922.network.NodesKey;
37 import org.opendaylight.yang.gen.v1.http.org.openroadm.network.types.rev230526.OpenroadmNodeType;
38 import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.pathdescription.rev230501.path.description.atoz.direction.AToZ;
39 import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.pathdescription.rev230501.pce.resource.resource.resource.Node;
40 import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.pathdescription.rev230501.pce.resource.resource.resource.TerminationPoint;
41 import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.service.types.rev220118.RpcStatusEx;
42 import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.common.rev221121.AdministrativeState;
43 import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.common.rev221121.Context;
44 import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.common.rev221121.Direction;
45 import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.common.rev221121.ForwardingDirection;
46 import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.common.rev221121.LayerProtocolName;
47 import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.common.rev221121.LifecycleState;
48 import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.common.rev221121.OperationalState;
49 import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.common.rev221121.PortRole;
50 import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.common.rev221121.Uuid;
51 import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.common.rev221121.global._class.Name;
52 import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.common.rev221121.global._class.NameBuilder;
53 import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.common.rev221121.global._class.NameKey;
54 import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.connectivity.rev221121.Context1;
55 import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.connectivity.rev221121.CreateConnectivityServiceInput;
56 import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.connectivity.rev221121.OwnedNodeEdgePoint1;
57 import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.connectivity.rev221121.OwnedNodeEdgePoint1Builder;
58 import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.connectivity.rev221121.cep.list.ConnectionEndPoint;
59 import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.connectivity.rev221121.cep.list.ConnectionEndPointBuilder;
60 import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.connectivity.rev221121.connection.ConnectionEndPointKey;
61 import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.connectivity.rev221121.connection.LowerConnection;
62 import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.connectivity.rev221121.connection.LowerConnectionBuilder;
63 import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.connectivity.rev221121.connection.LowerConnectionKey;
64 import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.connectivity.rev221121.connection.end.point.ClientNodeEdgePoint;
65 import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.connectivity.rev221121.connection.end.point.ClientNodeEdgePointBuilder;
66 import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.connectivity.rev221121.connection.end.point.ParentNodeEdgePoint;
67 import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.connectivity.rev221121.connection.end.point.ParentNodeEdgePointBuilder;
68 import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.connectivity.rev221121.connectivity.context.ConnectivityService;
69 import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.connectivity.rev221121.connectivity.context.ConnectivityServiceBuilder;
70 import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.connectivity.rev221121.connectivity.context.ConnectivityServiceKey;
71 import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.connectivity.rev221121.connectivity.service.Connection;
72 import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.connectivity.rev221121.connectivity.service.ConnectionBuilder;
73 import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.connectivity.rev221121.connectivity.service.ConnectionKey;
74 import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.connectivity.rev221121.context.ConnectivityContextBuilder;
75 import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.connectivity.rev221121.context.topology.context.topology.node.owned.node.edge.point.CepList;
76 import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.connectivity.rev221121.context.topology.context.topology.node.owned.node.edge.point.CepListBuilder;
77 import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.photonic.media.rev221121.PHOTONICLAYERQUALIFIERMC;
78 import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.photonic.media.rev221121.PHOTONICLAYERQUALIFIEROTSiMC;
79 import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.topology.rev221121.context.TopologyContext;
80 import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.topology.rev221121.node.OwnedNodeEdgePoint;
81 import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.topology.rev221121.node.OwnedNodeEdgePointBuilder;
82 import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.topology.rev221121.node.OwnedNodeEdgePointKey;
83 import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.topology.rev221121.node.edge.point.SupportedCepLayerProtocolQualifierInstances;
84 import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.topology.rev221121.node.edge.point.SupportedCepLayerProtocolQualifierInstancesBuilder;
85 import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.topology.rev221121.topology.NodeKey;
86 import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.topology.rev221121.topology.context.Topology;
87 import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.topology.rev221121.topology.context.TopologyKey;
88 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
89 import org.opendaylight.yangtools.yang.common.Uint64;
90 import org.slf4j.Logger;
91 import org.slf4j.LoggerFactory;
92
93 public class TapiPceNotificationHandler {
94
95     private static final Logger LOG = LoggerFactory.getLogger(TapiPceNotificationHandler.class);
96
97     private final Uuid tapiTopoUuid = new Uuid(UUID.nameUUIDFromBytes(TapiStringConstants.T0_FULL_MULTILAYER
98         .getBytes(Charset.forName("UTF-8"))).toString());
99     private ServicePathRpcResult servicePathRpcResult;
100     private CreateConnectivityServiceInput input;
101     private Uuid serviceUuid;
102     private final DataBroker dataBroker;
103     private final NetworkTransactionService networkTransactionService;
104     private final Map<org.opendaylight.yang.gen.v1.urn
105         .onf.otcc.yang.tapi.connectivity.rev221121.connectivity.context.ConnectionKey,
106         org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.connectivity.rev221121.connectivity.context.Connection>
107         connectionFullMap; // this variable is for complete connection objects
108     private Connection topConnRdmRdm;
109     private Connection topConnXpdrXpdrPhtn;
110     private Connection topConnXpdrXpdrOdu;
111
112     public TapiPceNotificationHandler(DataBroker dataBroker) {
113         this.connectionFullMap = new HashMap<>();
114         this.dataBroker = dataBroker;
115         this.networkTransactionService = new NetworkTransactionImpl(this.dataBroker);
116         this.topConnRdmRdm = null;
117         this.topConnXpdrXpdrPhtn = null;
118         this.topConnXpdrXpdrOdu = null;
119     }
120
121     public CompositeListener getCompositeListener() {
122         return new CompositeListener(Set.of(
123             new CompositeListener.Component<>(ServicePathRpcResult.class, this::onServicePathRpcResult)));
124     }
125
126     private void onServicePathRpcResult(ServicePathRpcResult notification) {
127         if (compareServicePathRpcResult(notification)) {
128             LOG.warn("ServicePathRpcResult already wired !");
129             return;
130         }
131         servicePathRpcResult = notification;
132         switch (servicePathRpcResult.getNotificationType().getIntValue()) {
133             /* path-computation-request. */
134             case 1:
135                 onPathComputationResult(notification);
136                 break;
137             /* cancel-resource-reserve. */
138             case 2:
139                 onCancelResourceResult(notification.getServiceName());
140                 break;
141             default:
142                 break;
143         }
144     }
145
146     /**
147      * Process path computation request result.
148      * @param notification the result notification.
149      */
150     private void onPathComputationResult(ServicePathRpcResult notification) {
151         this.connectionFullMap.clear();
152         LOG.info("PCE '{}' Notification received : {}",servicePathRpcResult.getNotificationType().getName(),
153             notification);
154         if (servicePathRpcResult.getStatus() == RpcStatusEx.Failed) {
155             LOG.error("PCE path computation failed !");
156             return;
157         } else if (servicePathRpcResult.getStatus() == RpcStatusEx.Pending) {
158             LOG.warn("PCE path computation returned a Penging RpcStatusEx code!");
159             return;
160         } else if (servicePathRpcResult.getStatus() != RpcStatusEx.Successful) {
161             LOG.error("PCE path computation returned an unknown RpcStatusEx code!");
162             return;
163         }
164
165         LOG.info("PCE calculation done OK !");
166         if (servicePathRpcResult.getPathDescription() == null) {
167             LOG.error("'PathDescription' parameter is null ");
168             return;
169         }
170         PathDescription pathDescription = new PathDescriptionBuilder()
171             .setAToZDirection(servicePathRpcResult.getPathDescription().getAToZDirection())
172             .setZToADirection(servicePathRpcResult.getPathDescription().getZToADirection())
173             .build();
174         LOG.info("PathDescription for TAPI gets : {}", pathDescription);
175         if (input == null) {
176             LOG.error("Input is null !");
177             return;
178         }
179         // TODO: check kind of service: based on the device Id of the input,
180         //  verify the type of XPDR and the capacity and determine if it is an OTN service or pure WDM service
181         // Create connections and ceps for the connectivity service.
182         //  Connections must be with a locked stated. As the renderer hasnt implemented yet the oc's
183         Map<ConnectionKey, Connection> connectionMap = createConnectionsAndCepsForService(pathDescription,
184             input.getLayerProtocolName());
185         LOG.debug("Connection Map from createConnectionsAndCepsForService is {}, LAYERPROTOCOL of service is {} ",
186             connectionMap.toString(), input.getLayerProtocolName());
187         // add connections to connection context and to connectivity context
188         updateConnectionContextWithConn(this.connectionFullMap, connectionMap, serviceUuid);
189     }
190
191     private Map<ConnectionKey, Connection> createConnectionsAndCepsForService(PathDescription pathDescription,
192                                                                               LayerProtocolName serviceProtName) {
193         Map<ConnectionKey, Connection> connectionServMap = new HashMap<>();
194         // build lists with ROADM nodes, XPDR/MUX/SWITCH nodes, ROADM DEG TTPs, ROADM SRG TTPs, XPDR CLIENT TTPs
195         //  and XPDR NETWORK TTPs (if any). From the path description. This will help to build the uuid of the CEPs
196         //  and the connections
197         String resourceType;
198         List<String> xpdrClientTplist = new ArrayList<>();
199         List<String> xpdrNetworkTplist = new ArrayList<>();
200         List<String> rdmAddDropTplist = new ArrayList<>();
201         List<String> rdmDegTplist = new ArrayList<>();
202         List<String> rdmNodelist = new ArrayList<>();
203         List<String> xpdrNodelist = new ArrayList<>();
204         for (AToZ elem:pathDescription.getAToZDirection().getAToZ().values().stream()
205             .sorted((Comparator.comparing(atoz -> Integer.valueOf(atoz.getId())))).collect(Collectors.toList())) {
206             resourceType = elem.getResource().getResource().implementedInterface().getSimpleName();
207             switch (resourceType) {
208                 case TapiStringConstants.TP:
209                     TerminationPoint tp = (TerminationPoint) elem.getResource().getResource();
210                     String tpID = tp.getTpId();
211                     String tpNode;
212                     if (tpID.contains("CLIENT")) {
213                         tpNode = tp.getTpNodeId();
214                         if (!xpdrClientTplist.contains(String.join("+", tpNode, tpID))) {
215                             xpdrClientTplist.add(String.join("+", tpNode, tpID));
216                         }
217                     }
218                     if (tpID.contains("NETWORK")) {
219                         tpNode = tp.getTpNodeId();
220                         if (!xpdrNetworkTplist.contains(String.join("+", tpNode, tpID))) {
221                             xpdrNetworkTplist.add(String.join("+", tpNode, tpID));
222                         }
223                     }
224                     if (tpID.contains("PP")) {
225                         tpNode = getIdBasedOnModelVersion(tp.getTpNodeId());
226                         LOG.info("ROADM Node of tp = {}", tpNode);
227                         if (!rdmAddDropTplist.contains(String.join("+", tpNode, tpID))) {
228                             rdmAddDropTplist.add(String.join("+", tpNode, tpID));
229                         }
230                     }
231                     if (tpID.contains("TTP")) {
232                         tpNode = getIdBasedOnModelVersion(tp.getTpNodeId());
233                         LOG.info("ROADM Node of tp = {}", tpNode);
234                         if (!rdmDegTplist.contains(String.join("+", tpNode, tpID))) {
235                             rdmDegTplist.add(String.join("+", tpNode, tpID));
236                         }
237                     }
238                     break;
239                 case TapiStringConstants.NODE:
240                     Node node = (Node) elem.getResource().getResource();
241                     String nodeId = node.getNodeId();
242                     if (nodeId.contains("XPDR") || nodeId.contains("SPDR") || nodeId.contains("MXPDR")) {
243                         LOG.info("Node id = {}", nodeId);
244                         if (!xpdrNodelist.contains(nodeId)) {
245                             xpdrNodelist.add(nodeId); // should contain only 2
246                         }
247                     }
248                     if (nodeId.contains("ROADM")) {
249                         nodeId = getIdBasedOnModelVersion(nodeId);
250                         LOG.info("Node id = {}", nodeId);
251                         if (!rdmNodelist.contains(nodeId)) {
252                             rdmNodelist.add(nodeId);
253                         }
254                     }
255                     break;
256                 default:
257                     LOG.warn("Resource is a {}", resourceType);
258             }
259         }
260         LOG.info("ROADM node list = {}", rdmNodelist.toString());
261         LOG.info("ROADM degree list = {}", rdmDegTplist.toString());
262         LOG.info("ROADM addrop list = {}", rdmAddDropTplist.toString());
263         LOG.info("XPDR node list = {}", xpdrNodelist.toString());
264         LOG.info("XPDR network list = {}", xpdrNetworkTplist.toString());
265         LOG.info("XPDR client list = {}", xpdrClientTplist.toString());
266         // TODO -> for 10GB eth and ODU services there are no ROADMs in path description as they use the OTU link,
267         //  but for 100GB eth all is created at once. Check if the roadm list is empty to determine whether we need
268         //  to trigger all the steps or not
269         String edgeRoadm1 = "";
270         String edgeRoadm2 = "";
271         if (!rdmNodelist.isEmpty()) {
272             edgeRoadm1 = rdmNodelist.get(0);
273             edgeRoadm2 = rdmNodelist.get(rdmNodelist.size() - 1);
274             LOG.info("edgeRoadm1 = {}", edgeRoadm1);
275             LOG.info("edgeRoadm2 = {}", edgeRoadm2);
276         }
277         // create corresponding CEPs and Connections. Connections should be added to the corresponding context
278         // CEPs must be included in the topology context as an augmentation for each ONEP!!
279         // TODO -> Maybe we dont need to create the connections and ceps if the previous service doesnt exist??
280         //  As mentioned above, for 100GbE service creation there are ROADMs in the path description.
281         //  What are the configurations needed here? No OTU, ODU... what kind of cross connections is needed?
282         //  this needs to be changed
283
284         // TODO: OpenROADM getNodeType from the NamesList to verify what needs to be created
285         OpenroadmNodeType openroadmNodeType = getOpenRoadmNodeType(xpdrNodelist);
286         switch (serviceProtName) {
287             case PHOTONICMEDIA:
288                 // Identify number of ROADMs
289                 // - XC Connection between MC CEPs mapped from MC NEPs (within a roadm)
290                 // - XC Connection between OTSiMC CEPs mapped from OTSiMC NEPs (within a roadm)
291                 // - Top Connection MC betwwen MC CEPs of different roadms
292                 // - Top Connection OTSiMC betwwen OTSiMC CEPs of extreme roadms
293                 connectionServMap.putAll(createRoadmCepsAndConnections(rdmAddDropTplist, rdmDegTplist, rdmNodelist,
294                     edgeRoadm1, edgeRoadm2));
295                 if (!pathDescription.getAToZDirection().getAToZ().values().stream().findFirst().orElseThrow().getId()
296                         .contains("ROADM")) {
297                     // - XC Connection OTSi betwwen iOTSi y eOTSi of xpdr
298                     // - Top connection OTSi between network ports of xpdrs in the Photonic media layer -> i_OTSi
299                     connectionServMap.putAll(createXpdrCepsAndConnectionsPht(xpdrNetworkTplist, xpdrNodelist));
300                     this.topConnRdmRdm = null;
301                 }
302                 break;
303             case ODU:
304                 // TODO: verify if this is correct
305                 LOG.info("OTN ODU service");
306                 // - XC Connection OTSi between iODU and eODU of xpdr
307                 // - Top connection in the ODU layer, between xpdr iODU ports
308                 if (openroadmNodeType.equals(OpenroadmNodeType.MUXPDR)) {
309                     connectionServMap.putAll(createXpdrCepsAndConnectionsOdu(xpdrNetworkTplist, xpdrNodelist));
310                     this.topConnXpdrXpdrPhtn = null;
311                 }
312                 break;
313             case ETH:
314                 LOG.info("WDM service");
315                 if (openroadmNodeType.equals(OpenroadmNodeType.TPDR)) {
316                     // TODO: WDM service. Only och/otu4 needed and then directly DSR top connection.
317                     //  Need to find the associated client ports of the network port
318                     // - Same as for PHOTONIC MEDIA service
319                     // - Do we nedd cross connection in the ODU layer??
320                     // - Top connection DSR between client ports of the transponder
321                     connectionServMap.putAll(createRoadmCepsAndConnections(rdmAddDropTplist, rdmDegTplist, rdmNodelist,
322                         edgeRoadm1, edgeRoadm2));
323                     connectionServMap.putAll(createXpdrCepsAndConnectionsPht(xpdrNetworkTplist, xpdrNodelist));
324                     this.topConnRdmRdm = null;
325                     xpdrClientTplist = getAssociatedClientsPort(xpdrNetworkTplist);
326                     LOG.info("Associated client ports = {}", xpdrClientTplist);
327                     connectionServMap.putAll(createXpdrCepsAndConnectionsEth(xpdrClientTplist, xpdrNodelist,
328                         connectionServMap));
329                     this.topConnXpdrXpdrPhtn = null;
330                 }
331                 break;
332             case DSR:
333                 LOG.info("OTN XGE/ODUe service");
334                 // - XC connection between iODU and eODU
335                 // - Top connection between eODU ports
336                 // - Top connection between DSR ports
337                 if (openroadmNodeType.equals(OpenroadmNodeType.SWITCH)) {
338                     // TODO: We create both ODU and DSR because there is no ODU service creation for the switch
339                     // - XC Connection OTSi betwwen iODU and eODU of xpdr
340                     // - Top connection in the ODU layer, between xpdr eODU ports (?)
341                     connectionServMap.putAll(createXpdrCepsAndConnectionsDsr(xpdrClientTplist, xpdrNetworkTplist,
342                         xpdrNodelist));
343                     this.topConnXpdrXpdrPhtn = null;
344                 }
345                 if (openroadmNodeType.equals(OpenroadmNodeType.MUXPDR)) {
346                     // TODO: OTN service but mux has 3 steps at rendering. Verify that things exist
347                     connectionServMap.putAll(createXpdrCepsAndConnectionsDsr(xpdrClientTplist, xpdrNetworkTplist,
348                         xpdrNodelist));
349                     this.topConnXpdrXpdrOdu = null;
350                 }
351                 break;
352             default:
353                 LOG.error("Service type format {} not supported", serviceProtName.getName());
354         }
355         LOG.info("CONNSERVERMAP PceListener= {}", connectionServMap.toString());
356         return connectionServMap;
357     }
358
359     /**
360      * Process cancel resource result.
361      * @param serviceName Service name to build uuid.
362      */
363     private void onCancelResourceResult(String serviceName) {
364         if (servicePathRpcResult.getStatus() == RpcStatusEx.Failed) {
365             LOG.info("PCE cancel resource failed !");
366             return;
367         } else if (servicePathRpcResult.getStatus() == RpcStatusEx.Pending) {
368             LOG.warn("PCE cancel returned a Penging RpcStatusEx code!");
369             return;
370         } else if (servicePathRpcResult.getStatus() != RpcStatusEx.Successful) {
371             LOG.error("PCE cancel returned an unknown RpcStatusEx code!");
372             return;
373         }
374         LOG.info("PCE cancel resource done OK !");
375         Uuid suuid = new Uuid(UUID.nameUUIDFromBytes(serviceName.getBytes(Charset.forName("UTF-8")))
376             .toString());
377         // get connections of connectivity service and remove them from tapi context and then remove
378         //  service from context. The CEPs are maintained as they could be reused by another service
379         ConnectivityService connService = getConnectivityService(suuid);
380         if (connService == null) {
381             LOG.error("Service doesnt exist in tapi context");
382             return;
383         }
384         for (Connection connection:connService.getConnection().values()) {
385             deleteConnection(connection.getConnectionUuid());
386         }
387         deleteConnectivityService(suuid);
388     }
389
390     @SuppressFBWarnings(
391         value = "ES_COMPARING_STRINGS_WITH_EQ",
392         justification = "false positives, not strings but real object references comparisons")
393     private Boolean compareServicePathRpcResult(ServicePathRpcResult notification) {
394         if (servicePathRpcResult == null) {
395             return false;
396         }
397         if (servicePathRpcResult.getNotificationType() != notification.getNotificationType()) {
398             return false;
399         }
400         if (servicePathRpcResult.getServiceName() != notification.getServiceName()) {
401             return false;
402         }
403         if (servicePathRpcResult.getStatus() != notification.getStatus()) {
404             return false;
405         }
406         if (servicePathRpcResult.getStatusMessage() != notification.getStatusMessage()) {
407             return false;
408         }
409         return true;
410     }
411
412     private Map<ConnectionKey, Connection> createXpdrCepsAndConnectionsEth(List<String> xpdrClientTplist,
413                                                                            List<String> xpdrNodelist,
414                                                                            Map<ConnectionKey, Connection> lowerConn) {
415         // TODO: do we need to create cross connection between iODU and eODU??
416         // add the lower connections of the previous steps for this kind of service
417         Map<LowerConnectionKey, LowerConnection> xcMap = new HashMap<>();
418         for (Connection lowConn: lowerConn.values()) {
419             LowerConnection conn = new LowerConnectionBuilder().setConnectionUuid(lowConn.getConnectionUuid()).build();
420             xcMap.put(conn.key(), conn);
421         }
422         Map<ConnectionKey, Connection> connServMap = new HashMap<>();
423         Map<org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.connectivity.rev221121.cep.list.ConnectionEndPointKey,
424             ConnectionEndPoint> cepMapDsr = new HashMap<>();
425         // Create 1 cep per Xpdr in the CLIENT
426         // 1 top connection DSR between the CLIENT xpdrs
427         for (String xpdr:xpdrNodelist) {
428             LOG.info("Creating ceps and xc for xpdr {}", xpdr);
429             String spcXpdrClient = xpdrClientTplist.stream().filter(netp -> netp.contains(xpdr)).findFirst()
430                     .orElseThrow();
431             ConnectionEndPoint netCep1 = createCepXpdr(spcXpdrClient, TapiStringConstants.DSR, TapiStringConstants.XPDR,
432                 LayerProtocolName.DSR);
433             putXpdrCepInTopologyContext(xpdr, spcXpdrClient, TapiStringConstants.DSR, TapiStringConstants.XPDR,
434                 netCep1);
435
436             cepMapDsr.put(netCep1.key(), netCep1);
437         }
438         String spcXpdr1 = xpdrClientTplist.stream().filter(adp -> adp.contains(xpdrNodelist
439             .get(0))).findFirst().orElseThrow();
440         String spcXpdr2 = xpdrClientTplist.stream().filter(adp -> adp.contains(xpdrNodelist
441             .get(xpdrNodelist.size() - 1))).findFirst().orElseThrow();
442
443         // DSR top connection between edge xpdr CLIENT DSR
444         org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.connectivity.rev221121.connectivity.context.Connection
445             connectionDsr = createTopConnection(spcXpdr1, spcXpdr2, cepMapDsr, TapiStringConstants.DSR,
446                 LayerProtocolName.DSR, xcMap, this.topConnXpdrXpdrPhtn);
447         this.connectionFullMap.put(connectionDsr.key(), connectionDsr);
448
449         // DSR top connection that will be added to the service object
450         Connection conn1 = new ConnectionBuilder().setConnectionUuid(connectionDsr.getUuid()).build();
451         connServMap.put(conn1.key(), conn1);
452
453         return connServMap;
454     }
455
456     private Map<ConnectionKey,Connection> createXpdrCepsAndConnectionsDsr(List<String> xpdrClientTplist,
457                                                                           List<String> xpdrNetworkTplist,
458                                                                           List<String> xpdrNodelist) {
459         Map<ConnectionKey, Connection> connServMap = new HashMap<>();
460         Map<org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.connectivity.rev221121.cep.list.ConnectionEndPointKey,
461             ConnectionEndPoint> cepMapDsr = new HashMap<>();
462         Map<org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.connectivity.rev221121.cep.list.ConnectionEndPointKey,
463             ConnectionEndPoint> cepMapOdu = new HashMap<>();
464         // TODO: when upgrading the models to 2.1.3, get the connection inclusion because those connections will
465         //  be added to the lower connection of a top connection
466         Map<LowerConnectionKey, LowerConnection> xcMap = new HashMap<>();
467
468         // Create 1 cep per Xpdr in the CLIENT, 1 cep per Xpdr eODU, 1 XC between eODU and iODE,
469         // 1 top connection between eODU and a top connection DSR between the CLIENT xpdrs
470         for (String xpdr:xpdrNodelist) {
471             LOG.info("Creating ceps and xc for xpdr {}", xpdr);
472             String spcXpdrClient = xpdrClientTplist.stream().filter(netp -> netp.contains(xpdr)).findFirst()
473                     .orElseThrow();
474             ConnectionEndPoint clientCep1 = createCepXpdr(spcXpdrClient, TapiStringConstants.DSR,
475                 TapiStringConstants.XPDR, LayerProtocolName.DSR);
476             putXpdrCepInTopologyContext(xpdr, spcXpdrClient, TapiStringConstants.DSR, TapiStringConstants.XPDR,
477                 clientCep1);
478
479             ConnectionEndPoint clientCep2 = createCepXpdr(spcXpdrClient, TapiStringConstants.E_ODU,
480                 TapiStringConstants.XPDR, LayerProtocolName.ODU);
481             putXpdrCepInTopologyContext(xpdr, spcXpdrClient, TapiStringConstants.E_ODU, TapiStringConstants.XPDR,
482                 clientCep2);
483
484             String spcXpdrNetwork = getAssociatedNetworkPort(spcXpdrClient, xpdrNetworkTplist);
485             ConnectionEndPoint netCep3 = getAssociatediODUCep(spcXpdrNetwork);
486
487             cepMapDsr.put(clientCep1.key(), clientCep1);
488             cepMapOdu.put(clientCep2.key(), clientCep2);
489             // Create x connection between I_ODU and E_ODU within xpdr
490             org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.connectivity.rev221121.connectivity.context.Connection
491                 connection = createXCBetweenCeps(clientCep2, netCep3, spcXpdrClient, spcXpdrNetwork,
492                     TapiStringConstants.ODU, LayerProtocolName.ODU);
493             this.connectionFullMap.put(connection.key(), connection);
494
495             // Create X connection that will be added to the service object
496             LowerConnection conn = new LowerConnectionBuilder().setConnectionUuid(connection.getUuid()).build();
497             xcMap.put(conn.key(), conn);
498         }
499
500         String spcXpdr1 = xpdrClientTplist.stream().filter(adp -> adp.contains(xpdrNodelist
501             .get(0))).findFirst().orElseThrow();
502         String spcXpdr2 = xpdrClientTplist.stream().filter(adp -> adp.contains(xpdrNodelist
503             .get(xpdrNodelist.size() - 1))).findFirst().orElseThrow();
504
505         // eODU top connection between edge xpdr CLIENT eODU
506         org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.connectivity.rev221121.connectivity.context.Connection
507             connectionOdu = createTopConnection(spcXpdr1, spcXpdr2, cepMapOdu, TapiStringConstants.E_ODU,
508                 LayerProtocolName.ODU, xcMap, this.topConnXpdrXpdrOdu);
509         this.connectionFullMap.put(connectionOdu.key(), connectionOdu);
510
511         // ODU top connection that will be added to the service object and also lower connection
512         Connection conn = new ConnectionBuilder().setConnectionUuid(connectionOdu.getUuid()).build();
513         connServMap.put(conn.key(), conn);
514         LowerConnection lowerConn = new LowerConnectionBuilder().setConnectionUuid(connectionOdu.getUuid()).build();
515         xcMap.put(lowerConn.key(), lowerConn);
516
517         // DSR top connection between edge xpdr CLIENT DSR
518         org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.connectivity.rev221121.connectivity.context.Connection
519             connectionDsr = createTopConnection(spcXpdr1, spcXpdr2, cepMapDsr, TapiStringConstants.DSR,
520                 LayerProtocolName.DSR, xcMap, this.topConnXpdrXpdrPhtn);
521         this.connectionFullMap.put(connectionDsr.key(), connectionDsr);
522
523         // DSR top connection that will be added to the service object
524         Connection conn1 = new ConnectionBuilder().setConnectionUuid(connectionDsr.getUuid()).build();
525         connServMap.put(conn1.key(), conn1);
526
527         return connServMap;
528     }
529
530     private Map<ConnectionKey, Connection> createXpdrCepsAndConnectionsOdu(List<String> xpdrNetworkTplist,
531                                                                            List<String> xpdrNodelist) {
532         Map<ConnectionKey, Connection> connServMap = new HashMap<>();
533         Map<org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.connectivity.rev221121.cep.list.ConnectionEndPointKey,
534             ConnectionEndPoint> cepMap = new HashMap<>();
535         // TODO: when upgrading the models to 2.1.3, get the connection inclusion because those connections will
536         //  be added to the lower connection of a top connection
537         Map<LowerConnectionKey, LowerConnection> xcMap = new HashMap<>();
538         // Create 1 cep per Xpdr in the I_ODU and a top
539         // connection iODU between the xpdrs
540         for (String xpdr:xpdrNodelist) {
541             LOG.info("Creating ceps and xc for xpdr {}", xpdr);
542             String spcXpdrNetwork = xpdrNetworkTplist.stream().filter(netp -> netp.contains(xpdr)).findFirst()
543                     .orElseThrow();
544             ConnectionEndPoint netCep1 = createCepXpdr(spcXpdrNetwork, TapiStringConstants.I_ODU,
545                 TapiStringConstants.XPDR, LayerProtocolName.ODU);
546             putXpdrCepInTopologyContext(xpdr, spcXpdrNetwork, TapiStringConstants.I_ODU, TapiStringConstants.XPDR,
547                 netCep1);
548
549             cepMap.put(netCep1.key(), netCep1);
550         }
551
552         // ODU top connection between edge xpdr i_ODU
553         String spcXpdr1 = xpdrNetworkTplist.stream().filter(adp -> adp.contains(xpdrNodelist
554             .get(0))).findFirst().orElseThrow();
555         String spcXpdr2 = xpdrNetworkTplist.stream().filter(adp -> adp.contains(xpdrNodelist
556             .get(xpdrNodelist.size() - 1))).findFirst().orElseThrow();
557         org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.connectivity.rev221121.connectivity.context.Connection
558             connection = createTopConnection(spcXpdr1, spcXpdr2, cepMap, TapiStringConstants.I_ODU,
559                 LayerProtocolName.ODU, xcMap, this.topConnXpdrXpdrPhtn);
560         this.connectionFullMap.put(connection.key(), connection);
561
562         // ODU top connection that will be added to the service object
563         Connection conn = new ConnectionBuilder().setConnectionUuid(connection.getUuid()).build();
564         connServMap.put(conn.key(), conn);
565         this.topConnXpdrXpdrOdu = conn;
566
567         return connServMap;
568     }
569
570     private Map<ConnectionKey, Connection> createXpdrCepsAndConnectionsPht(List<String> xpdrNetworkTplist,
571                                                                            List<String> xpdrNodelist) {
572         Map<org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.connectivity.rev221121.cep.list.ConnectionEndPointKey,
573             ConnectionEndPoint> cepMap = new HashMap<>();
574         // TODO: when upgrading the models to 2.1.3, get the connection inclusion because those connections will
575         //  be added to the lower connection of a top connection
576 //        Map<LowerConnectionKey, LowerConnection> xcMap = new HashMap<>();
577
578         // create ceps and xc connections within xpdr
579         for (String xpdr:xpdrNodelist) {
580             LOG.info("Creating ceps and xc for xpdr {}", xpdr);
581             String spcXpdrNetwork = xpdrNetworkTplist.stream().filter(netp -> netp.contains(xpdr)).findFirst()
582                 .orElseThrow();
583             // There should be 1 network tp per xpdr
584             //   Just create 2 different CEPs (1 OTS + 1 OTSI_MC)
585             ConnectionEndPoint netCep1 = createCepXpdr(spcXpdrNetwork, TapiStringConstants.PHTNC_MEDIA_OTS,
586                 TapiStringConstants.XPDR, LayerProtocolName.PHOTONICMEDIA);
587             putXpdrCepInTopologyContext(xpdr, spcXpdrNetwork, TapiStringConstants.PHTNC_MEDIA_OTS,
588                 TapiStringConstants.XPDR, netCep1);
589             ConnectionEndPoint netCep2 = createCepXpdr(spcXpdrNetwork, TapiStringConstants.OTSI_MC,
590                 TapiStringConstants.XPDR, LayerProtocolName.PHOTONICMEDIA);
591             putXpdrCepInTopologyContext(xpdr, spcXpdrNetwork, TapiStringConstants.OTSI_MC, TapiStringConstants.XPDR,
592                 netCep2);
593 //            ConnectionEndPoint netCep3 = createCepXpdr(spcXpdrNetwork, TapiStringConstants.I_OTSI,
594 //                TapiStringConstants.XPDR, LayerProtocolName.PHOTONICMEDIA);
595 //            putXpdrCepInTopologyContext(xpdr, spcXpdrNetwork, TapiStringConstants.I_OTSI, TapiStringConstants.OTSI,
596 //                netCep3);
597 //          cepMap.put(netCep3.key(), netCep3);
598             cepMap.put(netCep1.key(), netCep1);
599             cepMap.put(netCep2.key(), netCep2);
600
601
602         }
603
604      // OTSi top connection between edge OTSI_MC Xpdr
605         Map<LowerConnectionKey, LowerConnection> xcMap = new HashMap<>();
606         String spcXpdr1 = xpdrNetworkTplist.stream().filter(adp -> adp.contains(xpdrNodelist
607             .get(0))).findFirst().orElseThrow();
608         String spcXpdr2 = xpdrNetworkTplist.stream().filter(adp -> adp.contains(xpdrNodelist
609             .get(xpdrNodelist.size() - 1))).findFirst().orElseThrow();
610         org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.connectivity.rev221121.connectivity.context.Connection
611             connection = createTopConnection(spcXpdr1, spcXpdr2, cepMap, TapiStringConstants.OTSI_MC,
612             LayerProtocolName.PHOTONICMEDIA, xcMap, this.topConnRdmRdm);
613         this.connectionFullMap.put(connection.key(), connection);
614
615       // OTSi top connection that will be added to the service object
616         Map<ConnectionKey, Connection> connServMap = new HashMap<>();
617         Connection conn = new ConnectionBuilder().setConnectionUuid(connection.getUuid()).build();
618         connServMap.put(conn.key(), conn);
619         this.topConnXpdrXpdrPhtn = conn;
620         return connServMap;
621     }
622
623     private Map<ConnectionKey, Connection> createRoadmCepsAndConnections(List<String> rdmAddDropTplist,
624                                                                          List<String> rdmDegTplist,
625                                                                          List<String> rdmNodelist,
626                                                                          String edgeRoadm1, String edgeRoadm2) {
627         // TODO: will need to check if things exist already or not
628         Map<org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.connectivity.rev221121.cep.list.ConnectionEndPointKey,
629             ConnectionEndPoint> cepMap = new HashMap<>();
630         // create ceps and x connections within roadm
631         Map<LowerConnectionKey, LowerConnection> xcLowerMap = new HashMap<>();
632         for (String roadm : rdmNodelist) {
633             LOG.info("Creating ceps and xc for roadm {}", roadm);
634             if (roadm.equals(edgeRoadm1) || roadm.equals(edgeRoadm2)) {
635                 LOG.info("EDGE ROADM, cross connections needed between SRG and DEG");
636                 String spcRdmAD = rdmAddDropTplist.stream().filter(adp -> adp.contains(roadm)).findFirst()
637                     .orElseThrow();
638                 LOG.info("AD port of ROADm {} = {}", roadm, spcRdmAD);
639                 // There should be only 1 AD and 1 DEG per roadm
640                 // TODO photonic media model should be updated to have the corresponding CEPs. I will just create
641                 //  3 different MC CEPs giving different IDs to show that they are different
642                 // Create 3 CEPs for each AD and DEG and the corresponding cross connections, matching the NEPs
643                 // created in the topology creation
644                 // add CEPs to the topology to the corresponding ONEP
645                 ConnectionEndPoint adCep1 = createCepRoadm(spcRdmAD, TapiStringConstants.PHTNC_MEDIA_OTS);
646                 putRdmCepInTopologyContext(roadm, spcRdmAD, TapiStringConstants.PHTNC_MEDIA_OTS, adCep1);
647                 ConnectionEndPoint adCep2 = createCepRoadm(spcRdmAD, TapiStringConstants.MC);
648                 putRdmCepInTopologyContext(roadm, spcRdmAD, TapiStringConstants.MC, adCep2);
649                 ConnectionEndPoint adCep3 = createCepRoadm(spcRdmAD, TapiStringConstants.OTSI_MC);
650                 putRdmCepInTopologyContext(roadm, spcRdmAD, TapiStringConstants.OTSI_MC, adCep3);
651                 cepMap.put(adCep1.key(), adCep1);
652                 cepMap.put(adCep2.key(), adCep2);
653                 cepMap.put(adCep3.key(), adCep3);
654
655                 String spcRdmDEG = rdmDegTplist.stream().filter(adp -> adp.contains(roadm)).findFirst().orElseThrow();
656                 LOG.info("Degree port of ROADm {} = {}", roadm, spcRdmDEG);
657
658                 ConnectionEndPoint degCep0 = createCepRoadm(spcRdmDEG, TapiStringConstants.PHTNC_MEDIA_OTS);
659                 putRdmCepInTopologyContext(roadm, spcRdmDEG, TapiStringConstants.PHTNC_MEDIA_OTS, degCep0);
660                 ConnectionEndPoint degCep1 = createCepRoadm(spcRdmDEG, TapiStringConstants.PHTNC_MEDIA_OMS);
661                 putRdmCepInTopologyContext(roadm, spcRdmDEG, TapiStringConstants.PHTNC_MEDIA_OMS, degCep1);
662                 ConnectionEndPoint degCep2 = createCepRoadm(spcRdmDEG, TapiStringConstants.MC);
663                 putRdmCepInTopologyContext(roadm, spcRdmDEG, TapiStringConstants.MC, degCep2);
664                 ConnectionEndPoint degCep3 = createCepRoadm(spcRdmDEG, TapiStringConstants.OTSI_MC);
665                 putRdmCepInTopologyContext(roadm, spcRdmDEG, TapiStringConstants.OTSI_MC, degCep3);
666                 cepMap.put(degCep0.key(), degCep0);
667                 cepMap.put(degCep1.key(), degCep1);
668                 cepMap.put(degCep2.key(), degCep2);
669                 cepMap.put(degCep3.key(), degCep3);
670
671                 LOG.info("Going to create cross connections for ROADM {}", roadm);
672                 // Create X connections between MC and OTSi_MC for full map
673                 org.opendaylight.yang.gen.v1.urn
674                         .onf.otcc.yang.tapi.connectivity.rev221121.connectivity.context.Connection connection1
675                     = createXCBetweenCeps(adCep2, degCep2, spcRdmAD, spcRdmDEG, TapiStringConstants.MC,
676                         LayerProtocolName.PHOTONICMEDIA);
677                 LOG.info("Cross connection 1 created = {}", connection1.toString());
678                 org.opendaylight.yang.gen.v1.urn
679                         .onf.otcc.yang.tapi.connectivity.rev221121.connectivity.context.Connection connection2
680                     = createXCBetweenCeps(adCep3, degCep3, spcRdmAD, spcRdmDEG, TapiStringConstants.OTSI_MC,
681                         LayerProtocolName.PHOTONICMEDIA);
682                 LOG.info("Cross connection 2 created = {}", connection2.toString());
683                 this.connectionFullMap.put(connection1.key(), connection1);
684                 this.connectionFullMap.put(connection2.key(), connection2);
685
686                 // Create X connections that will be added to the service object
687                 LowerConnection conn1 = new LowerConnectionBuilder().setConnectionUuid(connection1.getUuid()).build();
688                 LowerConnection conn2 = new LowerConnectionBuilder().setConnectionUuid(connection2.getUuid()).build();
689
690                 xcLowerMap.put(conn1.key(), conn1);
691                 xcLowerMap.put(conn2.key(), conn2);
692             } else {
693                 LOG.info("MIDDLE ROADM, cross connections needed between DEG and DEG");
694                 String spcRdmDEG1 = rdmDegTplist.stream().filter(adp -> adp.contains(roadm)).findFirst().orElseThrow();
695                 LOG.info("Degree 1 port of ROADm {} = {}", roadm, spcRdmDEG1);
696
697                 ConnectionEndPoint deg1Cep0 = createCepRoadm(spcRdmDEG1, TapiStringConstants.PHTNC_MEDIA_OTS);
698                 putRdmCepInTopologyContext(roadm, spcRdmDEG1, TapiStringConstants.PHTNC_MEDIA_OTS, deg1Cep0);
699                 ConnectionEndPoint deg1Cep1 = createCepRoadm(spcRdmDEG1, TapiStringConstants.PHTNC_MEDIA_OMS);
700                 putRdmCepInTopologyContext(roadm, spcRdmDEG1, TapiStringConstants.PHTNC_MEDIA_OMS, deg1Cep1);
701                 ConnectionEndPoint deg1Cep2 = createCepRoadm(spcRdmDEG1, TapiStringConstants.MC);
702                 putRdmCepInTopologyContext(roadm, spcRdmDEG1, TapiStringConstants.MC, deg1Cep2);
703                 ConnectionEndPoint deg1Cep3 = createCepRoadm(spcRdmDEG1, TapiStringConstants.OTSI_MC);
704                 putRdmCepInTopologyContext(roadm, spcRdmDEG1, TapiStringConstants.OTSI_MC, deg1Cep3);
705                 cepMap.put(deg1Cep0.key(), deg1Cep0);
706                 cepMap.put(deg1Cep1.key(), deg1Cep1);
707                 cepMap.put(deg1Cep2.key(), deg1Cep2);
708                 cepMap.put(deg1Cep3.key(), deg1Cep3);
709
710                 String spcRdmDEG2 = rdmDegTplist.stream().filter(adp -> adp.contains(roadm)).skip(1).findFirst()
711                     .orElseThrow();
712                 LOG.info("Degree 2 port of ROADm {} = {}", roadm, spcRdmDEG2);
713
714                 ConnectionEndPoint deg2Cep0 = createCepRoadm(spcRdmDEG2, TapiStringConstants.PHTNC_MEDIA_OTS);
715                 putRdmCepInTopologyContext(roadm, spcRdmDEG2, TapiStringConstants.PHTNC_MEDIA_OTS, deg2Cep0);
716                 ConnectionEndPoint deg2Cep1 = createCepRoadm(spcRdmDEG2, TapiStringConstants.PHTNC_MEDIA_OMS);
717                 putRdmCepInTopologyContext(roadm, spcRdmDEG2, TapiStringConstants.PHTNC_MEDIA_OMS, deg2Cep1);
718                 ConnectionEndPoint deg2Cep2 = createCepRoadm(spcRdmDEG2, TapiStringConstants.MC);
719                 putRdmCepInTopologyContext(roadm, spcRdmDEG2, TapiStringConstants.MC, deg2Cep2);
720                 ConnectionEndPoint deg2Cep3 = createCepRoadm(spcRdmDEG2, TapiStringConstants.OTSI_MC);
721                 putRdmCepInTopologyContext(roadm, spcRdmDEG2, TapiStringConstants.OTSI_MC, deg2Cep3);
722                 cepMap.put(deg2Cep0.key(), deg2Cep0);
723                 cepMap.put(deg2Cep1.key(), deg2Cep1);
724                 cepMap.put(deg2Cep2.key(), deg2Cep2);
725                 cepMap.put(deg2Cep3.key(), deg2Cep3);
726
727                 LOG.info("Going to create cross connections for ROADM {}", roadm);
728                 // Create X connections between MC and OTSi_MC for full map
729                 org.opendaylight.yang.gen.v1.urn
730                         .onf.otcc.yang.tapi.connectivity.rev221121.connectivity.context.Connection connection1
731                     = createXCBetweenCeps(deg1Cep2, deg2Cep2, spcRdmDEG1, spcRdmDEG2,
732                         TapiStringConstants.MC, LayerProtocolName.PHOTONICMEDIA);
733                 LOG.info("Cross connection 1 created = {}", connection1.toString());
734                 org.opendaylight.yang.gen.v1.urn
735                         .onf.otcc.yang.tapi.connectivity.rev221121.connectivity.context.Connection connection2
736                     = createXCBetweenCeps(deg1Cep3, deg2Cep3, spcRdmDEG1, spcRdmDEG2,
737                         TapiStringConstants.OTSI_MC, LayerProtocolName.PHOTONICMEDIA);
738                 LOG.info("Cross connection 2 created = {}", connection2.toString());
739                 this.connectionFullMap.put(connection1.key(), connection1);
740                 this.connectionFullMap.put(connection2.key(), connection2);
741
742                 // Create X connections that will be added to the service object
743                 LowerConnection conn1 = new LowerConnectionBuilder().setConnectionUuid(connection1.getUuid()).build();
744                 LowerConnection conn2 = new LowerConnectionBuilder().setConnectionUuid(connection2.getUuid()).build();
745
746                 xcLowerMap.put(conn1.key(), conn1);
747                 xcLowerMap.put(conn2.key(), conn2);
748             }
749         }
750         LOG.info("Going to create top connections between roadms");
751         String spcRdmAD1 = rdmAddDropTplist.stream().filter(adp -> adp.contains(edgeRoadm1)).findFirst().orElseThrow();
752         String spcRdmAD2 = rdmAddDropTplist.stream().filter(adp -> adp.contains(edgeRoadm2)).findFirst().orElseThrow();
753         // MC top connection between edge roadms
754         LOG.info("Going to created top connection between MC");
755         org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.connectivity.rev221121.connectivity.context.Connection
756             connection = createTopConnection(spcRdmAD1, spcRdmAD2, cepMap, TapiStringConstants.MC,
757                 LayerProtocolName.PHOTONICMEDIA, xcLowerMap, null);
758         this.connectionFullMap.put(connection.key(), connection);
759         LOG.info("Top connection created = {}", connection.toString());
760
761         Map<ConnectionKey, Connection> connServMap = new HashMap<>();
762         // OTSiMC top connections that will be added to the service object
763         Connection conn = new ConnectionBuilder().setConnectionUuid(connection.getUuid()).build();
764         connServMap.put(conn.key(), conn);
765         LowerConnection conn1 = new LowerConnectionBuilder().setConnectionUuid(connection.getUuid()).build();
766         Map<LowerConnectionKey, LowerConnection> topLowerMap = new HashMap<>();
767         topLowerMap.put(conn1.key(), conn1);
768
769         // OTSiMC top connection between edge roadms
770         LOG.info("Going to created top connection between OTSiMC");
771         org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.connectivity.rev221121.connectivity.context.Connection
772             connection1 = createTopConnection(spcRdmAD1, spcRdmAD2, cepMap, TapiStringConstants.OTSI_MC,
773                 LayerProtocolName.PHOTONICMEDIA, topLowerMap, null);
774         this.connectionFullMap.put(connection1.key(), connection1);
775         LOG.info("Top connection created = {}", connection1.toString());
776
777         // OTSiMC top connections that will be added to the service object
778         Connection conn2 = new ConnectionBuilder().setConnectionUuid(connection1.getUuid()).build();
779         connServMap.put(conn2.key(), conn2);
780         this.topConnRdmRdm = conn2;
781         return connServMap;
782     }
783
784     private org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.connectivity.rev221121.connectivity.context.Connection
785             createTopConnection(String tp1, String tp2,
786                         Map<org.opendaylight.yang.gen.v1.urn
787                             .onf.otcc.yang.tapi.connectivity.rev221121.cep.list.ConnectionEndPointKey,
788                             ConnectionEndPoint> cepMap, String qual, LayerProtocolName topPortocol,
789                         Map<LowerConnectionKey, LowerConnection> xcMap, Connection additionalLowerConn) {
790         // find cep for each AD MC of roadm 1 and 2
791         LOG.info("Top connection name = {}", String.join("+", "TOP", tp1, tp2, qual));
792         org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.connectivity.rev221121.ConnectionEndPoint adCep1 =
793             cepMap.get(new org.opendaylight.yang.gen.v1.urn
794                     .onf.otcc.yang.tapi.connectivity.rev221121.cep.list.ConnectionEndPointKey(
795                 new Uuid(UUID.nameUUIDFromBytes((String.join("+", "CEP", tp1.split("\\+")[0],
796                         qual, tp1.split("\\+")[1])).getBytes(Charset.forName("UTF-8")))
797                     .toString())));
798         LOG.info("ADCEP1 = {}", adCep1.toString());
799         org.opendaylight.yang.gen.v1.urn
800                 .onf.otcc.yang.tapi.connectivity.rev221121.connection.ConnectionEndPoint cep1 =
801             new org.opendaylight.yang.gen.v1.urn
802                     .onf.otcc.yang.tapi.connectivity.rev221121.connection.ConnectionEndPointBuilder()
803                 .setNodeEdgePointUuid(adCep1.getParentNodeEdgePoint().getNodeEdgePointUuid())
804                 .setNodeUuid(adCep1.getParentNodeEdgePoint().getNodeUuid())
805                 .setTopologyUuid(adCep1.getParentNodeEdgePoint().getTopologyUuid())
806                 .setConnectionEndPointUuid(adCep1.getUuid())
807                 .build();
808         org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.connectivity.rev221121.ConnectionEndPoint adCep2 =
809             cepMap.get(new org.opendaylight.yang.gen.v1.urn
810                     .onf.otcc.yang.tapi.connectivity.rev221121.cep.list.ConnectionEndPointKey(
811                 new Uuid(UUID.nameUUIDFromBytes((String.join("+", "CEP", tp2.split("\\+")[0],
812                         qual, tp2.split("\\+")[1])).getBytes(Charset.forName("UTF-8")))
813                     .toString())));
814         LOG.info("ADCEP2 = {}", adCep2.toString());
815         org.opendaylight.yang.gen.v1.urn
816                 .onf.otcc.yang.tapi.connectivity.rev221121.connection.ConnectionEndPoint cep2 =
817             new org.opendaylight.yang.gen.v1.urn
818                     .onf.otcc.yang.tapi.connectivity.rev221121.connection.ConnectionEndPointBuilder()
819                 .setNodeEdgePointUuid(adCep2.getParentNodeEdgePoint().getNodeEdgePointUuid())
820                 .setNodeUuid(adCep2.getParentNodeEdgePoint().getNodeUuid())
821                 .setTopologyUuid(adCep2.getParentNodeEdgePoint().getTopologyUuid())
822                 .setConnectionEndPointUuid(adCep1.getUuid())
823                 .build();
824         Map<ConnectionEndPointKey, org.opendaylight.yang.gen.v1.urn
825             .onf.otcc.yang.tapi.connectivity.rev221121.connection.ConnectionEndPoint> ceps = new HashMap<>();
826         ceps.put(cep1.key(), cep1);
827         ceps.put(cep2.key(), cep2);
828         Name connName = new NameBuilder()
829             .setValueName("Connection name")
830             .setValue(String.join("+", "TOP", tp1, tp2, qual))
831             .build();
832         // TODO: lower connection, supported link.......
833         if (additionalLowerConn != null) {
834             xcMap.putIfAbsent(new LowerConnectionKey(additionalLowerConn.getConnectionUuid()),
835                 new LowerConnectionBuilder().setConnectionUuid(additionalLowerConn.getConnectionUuid()).build());
836         }
837         return new org.opendaylight.yang.gen.v1.urn
838                 .onf.otcc.yang.tapi.connectivity.rev221121.connectivity.context.ConnectionBuilder()
839             .setUuid(new Uuid(UUID.nameUUIDFromBytes((String.join("+", "TOP", tp1, tp2, qual))
840                 .getBytes(Charset.forName("UTF-8"))).toString()))
841             .setName(Map.of(connName.key(), connName))
842             .setConnectionEndPoint(ceps)
843             .setOperationalState(OperationalState.DISABLED)
844             .setLayerProtocolName(topPortocol)
845             .setLifecycleState(LifecycleState.POTENTIALAVAILABLE)
846             .setDirection(ForwardingDirection.BIDIRECTIONAL)
847             .setLowerConnection(xcMap)
848             .build();
849     }
850
851     private org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.connectivity.rev221121.connectivity.context.Connection
852             createXCBetweenCeps(ConnectionEndPoint cep1, ConnectionEndPoint cep2, String tp1, String tp2, String qual,
853                         LayerProtocolName xcProtocol) {
854         LOG.info("Creation cross connection between: {} and {}", tp1, tp2);
855         LOG.info("Cross connection name = {}", String.join("+", "XC", tp1, tp2, qual));
856         LOG.debug("Parent NEP of CEP1 = {}", cep1.getParentNodeEdgePoint().toString());
857         LOG.debug("Parent NEP CEP2 = {}", cep2.getParentNodeEdgePoint().toString());
858         org.opendaylight.yang.gen.v1.urn
859                 .onf.otcc.yang.tapi.connectivity.rev221121.connection.ConnectionEndPoint cepServ1 =
860             new org.opendaylight.yang.gen.v1.urn
861                     .onf.otcc.yang.tapi.connectivity.rev221121.connection.ConnectionEndPointBuilder()
862                 .setNodeEdgePointUuid(cep1.getParentNodeEdgePoint().getNodeEdgePointUuid())
863                 .setNodeUuid(cep1.getParentNodeEdgePoint().getNodeUuid())
864                 .setTopologyUuid(cep1.getParentNodeEdgePoint().getTopologyUuid())
865                 .setConnectionEndPointUuid(cep1.getUuid())
866                 .build();
867         org.opendaylight.yang.gen.v1.urn
868                 .onf.otcc.yang.tapi.connectivity.rev221121.connection.ConnectionEndPoint cepServ2 =
869             new org.opendaylight.yang.gen.v1.urn
870                     .onf.otcc.yang.tapi.connectivity.rev221121.connection.ConnectionEndPointBuilder()
871                 .setNodeEdgePointUuid(cep2.getParentNodeEdgePoint().getNodeEdgePointUuid())
872                 .setNodeUuid(cep2.getParentNodeEdgePoint().getNodeUuid())
873                 .setTopologyUuid(cep2.getParentNodeEdgePoint().getTopologyUuid())
874                 .setConnectionEndPointUuid(cep2.getUuid())
875                 .build();
876         Map<ConnectionEndPointKey, org.opendaylight.yang.gen.v1.urn
877             .onf.otcc.yang.tapi.connectivity.rev221121.connection.ConnectionEndPoint> ceps = new HashMap<>();
878         ceps.put(cepServ1.key(), cepServ1);
879         ceps.put(cepServ2.key(), cepServ2);
880         Name connName = new NameBuilder()
881             .setValueName("Connection name")
882             .setValue(String.join("+", "XC", tp1, tp2, qual))
883             .build();
884         // TODO: lower connection, supported link.......
885         return new org.opendaylight.yang.gen.v1.urn
886                 .onf.otcc.yang.tapi.connectivity.rev221121.connectivity.context.ConnectionBuilder()
887             .setUuid(new Uuid(UUID.nameUUIDFromBytes((String.join("+", "XC", tp1, tp2, qual))
888                 .getBytes(Charset.forName("UTF-8"))).toString()))
889             .setName(Map.of(connName.key(), connName))
890             .setConnectionEndPoint(ceps)
891             .setOperationalState(OperationalState.ENABLED)
892             .setLayerProtocolName(xcProtocol)
893             .setLifecycleState(LifecycleState.INSTALLED)
894             .setDirection(ForwardingDirection.BIDIRECTIONAL)
895             .build();
896     }
897
898     private ConnectionEndPoint createCepRoadm(String id, String qualifier) {
899         LOG.info("NEP = {}", String.join("+", id.split("\\+")[0], qualifier, id.split("\\+")[1]));
900         Name cepName = new NameBuilder()
901             .setValueName("ConnectionEndPoint name")
902             .setValue(String.join("+", id.split("\\+")[0], qualifier,
903                 id.split("\\+")[1]))
904             .build();
905         ParentNodeEdgePoint pnep = new ParentNodeEdgePointBuilder()
906             .setNodeEdgePointUuid(new Uuid(UUID.nameUUIDFromBytes((String.join("+", id.split("\\+")[0],
907                     qualifier, id.split("\\+")[1])).getBytes(StandardCharsets.UTF_8))
908                 .toString()))
909             .setNodeUuid(new Uuid(UUID.nameUUIDFromBytes((String.join("+",id.split("\\+")[0],
910                     TapiStringConstants.PHTNC_MEDIA)).getBytes(StandardCharsets.UTF_8))
911                 .toString()))
912             .setTopologyUuid(new Uuid(UUID.nameUUIDFromBytes(TapiStringConstants.T0_FULL_MULTILAYER
913                 .getBytes(StandardCharsets.UTF_8)).toString()))
914             .build();
915         String clientQualifier = "";
916         switch (qualifier) {
917             case TapiStringConstants.PHTNC_MEDIA_OTS:
918                 clientQualifier = TapiStringConstants.PHTNC_MEDIA_OMS;
919                 break;
920             case TapiStringConstants.PHTNC_MEDIA_OMS:
921                 clientQualifier = TapiStringConstants.MC;
922                 OwnedNodeEdgePoint onepMC = createRoadmNep(id.split("\\+")[0], id.split("\\+")[1],
923                     false, OperationalState.ENABLED, AdministrativeState.UNLOCKED, clientQualifier);
924                 putRdmNepInTopologyContext(id.split("\\+")[0], id.split("\\+")[1], TapiStringConstants.MC, onepMC);
925                 break;
926             case TapiStringConstants.MC:
927                 clientQualifier = TapiStringConstants.OTSI_MC;
928                 OwnedNodeEdgePoint onepOTSiMC = createRoadmNep(id.split("\\+")[0], id.split("\\+")[1],
929                     false, OperationalState.ENABLED, AdministrativeState.UNLOCKED, clientQualifier);
930                 putRdmNepInTopologyContext(id.split("\\+")[0], id.split("\\+")[1],
931                     TapiStringConstants.OTSI_MC, onepOTSiMC);
932                 break;
933             default:
934                 LOG.debug("not currently handling client NEP for OTSiMC CEP {}",
935                     String.join("+", id.split("\\+")[0], qualifier, id.split("\\+")[1]));
936                 break;
937         }
938         ClientNodeEdgePoint cnep = new ClientNodeEdgePointBuilder()
939             .setNodeEdgePointUuid(new Uuid(UUID.nameUUIDFromBytes((String.join("+", id.split("\\+")[0],
940                     clientQualifier, id.split("\\+")[1])).getBytes(StandardCharsets.UTF_8))
941                 .toString()))
942             .setNodeUuid(new Uuid(UUID.nameUUIDFromBytes((String.join("+",id.split("\\+")[0],
943                     TapiStringConstants.PHTNC_MEDIA)).getBytes(StandardCharsets.UTF_8))
944                 .toString()))
945             .setTopologyUuid(new Uuid(UUID.nameUUIDFromBytes(TapiStringConstants.T0_FULL_MULTILAYER
946                 .getBytes(StandardCharsets.UTF_8)).toString()))
947             .build();
948         // TODO: add augmentation with the corresponding cep-spec (i.e. MC, OTSiMC...)
949         // TODO: add parent ONEP??
950         ConnectionEndPointBuilder cepBldr = new ConnectionEndPointBuilder()
951             .setUuid(new Uuid(UUID.nameUUIDFromBytes((String.join("+", "CEP", id.split("\\+")[0],
952                     qualifier, id.split("\\+")[1])).getBytes(StandardCharsets.UTF_8))
953                 .toString()))
954             .setParentNodeEdgePoint(pnep)
955             .setName(Map.of(cepName.key(), cepName))
956             .setConnectionPortRole(PortRole.SYMMETRIC)
957             .setDirection(Direction.BIDIRECTIONAL)
958             .setOperationalState(OperationalState.ENABLED)
959             .setLifecycleState(LifecycleState.INSTALLED)
960             .setLayerProtocolName(LayerProtocolName.PHOTONICMEDIA);
961         if (!(TapiStringConstants.OTSI_MC.equals(qualifier))) {
962             cepBldr.setClientNodeEdgePoint(Map.of(cnep.key(), cnep));
963         }
964         return cepBldr.build();
965     }
966
967     private ConnectionEndPoint createCepXpdr(String id, String qualifier, String nodeLayer,
968                                              LayerProtocolName cepProtocol) {
969         Name cepName = new NameBuilder()
970             .setValueName("ConnectionEndPoint name")
971             .setValue(String.join("+", id.split("\\+")[0], qualifier,
972                 id.split("\\+")[1]))
973             .build();
974         ParentNodeEdgePoint pnep = new ParentNodeEdgePointBuilder()
975             .setNodeEdgePointUuid(new Uuid(UUID.nameUUIDFromBytes((String.join("+", id.split("\\+")[0],
976                     qualifier, id.split("\\+")[1])).getBytes(StandardCharsets.UTF_8))
977                 .toString()))
978             .setNodeUuid(new Uuid(UUID.nameUUIDFromBytes((String.join("+",id.split("\\+")[0],
979                     TapiStringConstants.XPDR)).getBytes(StandardCharsets.UTF_8))
980                 .toString()))
981             .setTopologyUuid(new Uuid(UUID.nameUUIDFromBytes(TapiStringConstants.T0_FULL_MULTILAYER
982                 .getBytes(StandardCharsets.UTF_8)).toString()))
983             .build();
984         String clientQualifier = "";
985         String clientNodeLayer = TapiStringConstants.PHTNC_MEDIA;
986         switch (qualifier) {
987             case TapiStringConstants.PHTNC_MEDIA_OTS:
988                 clientQualifier = TapiStringConstants.OTSI_MC;
989                 break;
990             case TapiStringConstants.OTSI_MC:
991                 clientQualifier = TapiStringConstants.E_ODU;
992                 clientNodeLayer = TapiStringConstants.ODU;
993                 break;
994             case TapiStringConstants.E_ODU:
995                 clientQualifier = TapiStringConstants.DSR;
996                 clientNodeLayer = TapiStringConstants.DSR;
997                 break;
998             default :
999                 LOG.debug("no client CEP for DSR NEP {}",
1000                     String.join("+", id.split("\\+")[0], qualifier, id.split("\\+")[1]));
1001                 break;
1002         }
1003         ClientNodeEdgePoint cnep = new ClientNodeEdgePointBuilder()
1004             .setNodeEdgePointUuid(new Uuid(UUID.nameUUIDFromBytes((String.join("+", id.split("\\+")[0],
1005                     clientQualifier, id.split("\\+")[1])).getBytes(StandardCharsets.UTF_8))
1006                 .toString()))
1007             .setNodeUuid(new Uuid(UUID.nameUUIDFromBytes((String.join("+",id.split("\\+")[0],
1008                     TapiStringConstants.XPDR)).getBytes(StandardCharsets.UTF_8))
1009                 .toString()))
1010             .setTopologyUuid(new Uuid(UUID.nameUUIDFromBytes(TapiStringConstants.T0_FULL_MULTILAYER
1011                 .getBytes(StandardCharsets.UTF_8)).toString()))
1012             .build();
1013         // TODO: add augmentation with the corresponding cep-spec (i.e. MC, OTSiMC...)
1014         // TODO: add parent ONEP??
1015         ConnectionEndPointBuilder cepBldr = new ConnectionEndPointBuilder()
1016             .setUuid(new Uuid(UUID.nameUUIDFromBytes((String.join("+", "CEP", id.split("\\+")[0],
1017                     qualifier, id.split("\\+")[1])).getBytes(StandardCharsets.UTF_8))
1018                 .toString()))
1019             .setParentNodeEdgePoint(pnep)
1020             .setName(Map.of(cepName.key(), cepName))
1021             .setConnectionPortRole(PortRole.SYMMETRIC)
1022             .setDirection(Direction.BIDIRECTIONAL)
1023             .setOperationalState(OperationalState.ENABLED)
1024             .setLifecycleState(LifecycleState.INSTALLED)
1025             .setLayerProtocolName(cepProtocol);
1026         if (!(TapiStringConstants.DSR.equals(qualifier))) {
1027             cepBldr.setClientNodeEdgePoint(Map.of(cnep.key(), cnep));
1028         }
1029         return cepBldr.build();
1030     }
1031
1032     private void putRdmCepInTopologyContext(String node, String spcRdmAD, String qual, ConnectionEndPoint cep) {
1033         LOG.info("NEP id before Merge = {}", String.join("+", node, qual, spcRdmAD.split("\\+")[1]));
1034         LOG.info("Node of NEP id before Merge = {}", String.join("+", node, TapiStringConstants.PHTNC_MEDIA));
1035         // Give uuids so that it is easier to look for things: topology uuid, node uuid, nep uuid, cep
1036         Uuid topoUuid = new Uuid(UUID.nameUUIDFromBytes(TapiStringConstants.T0_FULL_MULTILAYER
1037             .getBytes(Charset.forName("UTF-8"))).toString());
1038         Uuid nodeUuid = new Uuid(UUID.nameUUIDFromBytes(String.join("+", node, TapiStringConstants.PHTNC_MEDIA)
1039             .getBytes(Charset.forName("UTF-8"))).toString());
1040         Uuid nepUuid = new Uuid(UUID.nameUUIDFromBytes(String.join("+", node, qual, spcRdmAD.split("\\+")[1])
1041             .getBytes(Charset.forName("UTF-8"))).toString());
1042         updateTopologyWithCep(topoUuid, nodeUuid, nepUuid, cep);
1043     }
1044
1045     private void putXpdrCepInTopologyContext(String node, String spcXpdrNet, String qual, String nodeLayer,
1046                                              ConnectionEndPoint cep) {
1047         // Give uuids so that it is easier to look for things: topology uuid, node uuid, nep uuid, cep
1048         Uuid topoUuid = new Uuid(UUID.nameUUIDFromBytes(TapiStringConstants.T0_FULL_MULTILAYER
1049             .getBytes(Charset.forName("UTF-8"))).toString());
1050         Uuid nodeUuid = new Uuid(UUID.nameUUIDFromBytes(String.join("+", node, nodeLayer)
1051             .getBytes(Charset.forName("UTF-8"))).toString());
1052         Uuid nepUuid = new Uuid(UUID.nameUUIDFromBytes(String.join("+", node, qual, spcXpdrNet.split("\\+")[1])
1053             .getBytes(Charset.forName("UTF-8"))).toString());
1054         updateTopologyWithCep(topoUuid, nodeUuid, nepUuid, cep);
1055     }
1056
1057     public void updateTopologyWithCep(Uuid topoUuid, Uuid nodeUuid, Uuid nepUuid, ConnectionEndPoint cep) {
1058         // TODO: verify this is correct. Should we identify the context IID with the context UUID??
1059         InstanceIdentifier<OwnedNodeEdgePoint> onepIID = InstanceIdentifier.builder(Context.class)
1060             .augmentation(org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.topology.rev221121.Context1.class)
1061             .child(org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.topology.rev221121.context.TopologyContext.class)
1062             .child(Topology.class, new TopologyKey(topoUuid))
1063             .child(org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.topology.rev221121.topology.Node.class,
1064                 new NodeKey(nodeUuid))
1065             .child(OwnedNodeEdgePoint.class, new OwnedNodeEdgePointKey(nepUuid))
1066             .build();
1067         try {
1068             Optional<OwnedNodeEdgePoint> optionalOnep = this.networkTransactionService.read(
1069                 LogicalDatastoreType.OPERATIONAL, onepIID).get();
1070             if (!optionalOnep.isPresent()) {
1071                 LOG.error("ONEP is not present in datastore");
1072                 return;
1073             }
1074             OwnedNodeEdgePoint onep = optionalOnep.orElseThrow();
1075             LOG.info("ONEP found = {}", onep.toString());
1076             // TODO -> If cep exists -> skip merging to datasore
1077             OwnedNodeEdgePoint1 onep1 = onep.augmentation(OwnedNodeEdgePoint1.class);
1078             if (onep1 != null && onep1.getCepList() != null && onep1.getCepList().getConnectionEndPoint() != null) {
1079                 if (onep1.getCepList().getConnectionEndPoint().containsKey(
1080                         new org.opendaylight.yang.gen.v1
1081                             .urn.onf.otcc.yang.tapi.connectivity.rev221121.cep.list.ConnectionEndPointKey(cep.key()))) {
1082                     LOG.info("CEP already in topology, skipping merge");
1083                     return;
1084                 }
1085             }
1086             // Updated ONEP
1087             CepList cepList = new CepListBuilder().setConnectionEndPoint(Map.of(cep.key(), cep)).build();
1088             OwnedNodeEdgePoint1 onep1Bldr = new OwnedNodeEdgePoint1Builder().setCepList(cepList).build();
1089             OwnedNodeEdgePoint newOnep = new OwnedNodeEdgePointBuilder(onep)
1090                 .addAugmentation(onep1Bldr)
1091                 .build();
1092             LOG.info("New ONEP is {}", newOnep.toString());
1093             // merge in datastore
1094             this.networkTransactionService.merge(LogicalDatastoreType.OPERATIONAL, onepIID,
1095                 newOnep);
1096             this.networkTransactionService.commit().get();
1097             LOG.info("CEP added successfully.");
1098         } catch (InterruptedException | ExecutionException e) {
1099             LOG.error("Couldnt update cep in topology", e);
1100         }
1101     }
1102
1103     private void putRdmNepInTopologyContext(String orNodeId, String orTpId, String qual, OwnedNodeEdgePoint onep) {
1104         LOG.info("NEP id before Merge = {}", String.join("+", orNodeId, qual, orTpId));
1105         LOG.info("Node of NEP id before Merge = {}", String.join("+", orNodeId, TapiStringConstants.PHTNC_MEDIA));
1106         // Give uuids so that it is easier to look for things: topology uuid, node uuid, nep uuid, cep
1107         Uuid topoUuid = new Uuid(UUID.nameUUIDFromBytes(TapiStringConstants.T0_FULL_MULTILAYER
1108             .getBytes(Charset.forName("UTF-8"))).toString());
1109         Uuid nodeUuid = new Uuid(UUID.nameUUIDFromBytes(String.join("+", orNodeId, TapiStringConstants.PHTNC_MEDIA)
1110             .getBytes(Charset.forName("UTF-8"))).toString());
1111         Uuid nepUuid = new Uuid(UUID.nameUUIDFromBytes(String.join("+", orNodeId, qual, orTpId)
1112             .getBytes(Charset.forName("UTF-8"))).toString());
1113         updateTopologyWithNep(topoUuid, nodeUuid, nepUuid, onep);
1114     }
1115
1116     public void updateTopologyWithNep(Uuid topoUuid, Uuid nodeUuid, Uuid nepUuid, OwnedNodeEdgePoint onep) {
1117         // TODO: verify this is correct. Should we identify the context IID with the context UUID??
1118         InstanceIdentifier<OwnedNodeEdgePoint> onepIID = InstanceIdentifier.builder(Context.class)
1119             .augmentation(org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.topology.rev221121.Context1.class)
1120             .child(org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.topology.rev221121.context.TopologyContext.class)
1121             .child(Topology.class, new TopologyKey(topoUuid))
1122             .child(org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.topology.rev221121.topology.Node.class,
1123                 new NodeKey(nodeUuid))
1124             .child(OwnedNodeEdgePoint.class, new OwnedNodeEdgePointKey(nepUuid))
1125             .build();
1126         try {
1127             Optional<OwnedNodeEdgePoint> optionalOnep = this.networkTransactionService.read(
1128                 LogicalDatastoreType.OPERATIONAL, onepIID).get();
1129             if (optionalOnep.isPresent()) {
1130                 LOG.error("ONEP is already present in datastore");
1131                 return;
1132             }
1133             // merge in datastore
1134             this.networkTransactionService.merge(LogicalDatastoreType.OPERATIONAL, onepIID,
1135                 onep);
1136             this.networkTransactionService.commit().get();
1137             LOG.info("NEP {} added successfully.", onep.getName().toString());
1138         } catch (InterruptedException | ExecutionException e) {
1139             LOG.error("Couldnt put NEP {} in topology, error = ", onep.getName().toString(), e);
1140         }
1141     }
1142
1143
1144     private void updateConnectionContextWithConn(
1145             Map<org.opendaylight.yang.gen.v1.urn
1146                     .onf.otcc.yang.tapi.connectivity.rev221121.connectivity.context.ConnectionKey,
1147                 org.opendaylight.yang.gen.v1.urn
1148                     .onf.otcc.yang.tapi.connectivity.rev221121.connectivity.context.Connection> connFullMap,
1149             Map<ConnectionKey, Connection> connMap, Uuid suuid) {
1150         // TODO: verify this is correct. Should we identify the context IID with the context UUID??
1151         try {
1152             ConnectivityService connServ = getConnectivityService(suuid);
1153             ConnectivityService updtConnServ = new ConnectivityServiceBuilder(connServ)
1154                 .setConnection(connMap)
1155                 .build();
1156
1157             // Perform the merge operation with the new conn service and the connection context updated
1158             org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.connectivity.rev221121.context.ConnectivityContext
1159                 connectivityContext = new ConnectivityContextBuilder()
1160                     .setConnectivityService(Map.of(updtConnServ.key(), updtConnServ))
1161                     .setConnection(connFullMap)
1162                     .build();
1163             InstanceIdentifier<org.opendaylight.yang.gen.v1.urn
1164                     .onf.otcc.yang.tapi.connectivity.rev221121.context.ConnectivityContext> connectivitycontextIID =
1165                 InstanceIdentifier.builder(Context.class).augmentation(Context1.class)
1166                     .child(org.opendaylight.yang.gen.v1.urn
1167                         .onf.otcc.yang.tapi.connectivity.rev221121.context.ConnectivityContext.class)
1168                     .build();
1169             // merge in datastore
1170             this.networkTransactionService.merge(LogicalDatastoreType.OPERATIONAL, connectivitycontextIID,
1171                 connectivityContext);
1172             this.networkTransactionService.commit().get();
1173             LOG.info("TAPI connectivity merged successfully.");
1174         } catch (InterruptedException | ExecutionException e) {
1175             LOG.error("Failed to merge TAPI connectivity", e);
1176         }
1177     }
1178
1179     private ConnectivityService getConnectivityService(Uuid suuid) {
1180         try {
1181             // First read connectivity service with service uuid and update info
1182             InstanceIdentifier<ConnectivityService> connectivityServIID =
1183                 InstanceIdentifier.builder(Context.class).augmentation(Context1.class)
1184                     .child(org.opendaylight.yang.gen.v1.urn
1185                         .onf.otcc.yang.tapi.connectivity.rev221121.context.ConnectivityContext.class)
1186                     .child(ConnectivityService.class, new ConnectivityServiceKey(suuid))
1187                     .build();
1188
1189             Optional<ConnectivityService> optConnServ =
1190                 this.networkTransactionService.read(LogicalDatastoreType.OPERATIONAL, connectivityServIID).get();
1191             if (optConnServ.isEmpty()) {
1192                 LOG.error("Connectivity service not found in tapi context");
1193                 return null;
1194             }
1195             return optConnServ.orElseThrow();
1196         } catch (InterruptedException | ExecutionException e) {
1197             LOG.error("Connectivity service not found in tapi context. Error:", e);
1198             return null;
1199         }
1200     }
1201
1202     private void deleteConnectivityService(Uuid suuid) {
1203         // First read connectivity service with service uuid and update info
1204         InstanceIdentifier<ConnectivityService> connectivityServIID =
1205             InstanceIdentifier.builder(Context.class).augmentation(Context1.class)
1206                 .child(org.opendaylight.yang.gen.v1.urn
1207                     .onf.otcc.yang.tapi.connectivity.rev221121.context.ConnectivityContext.class)
1208                 .child(ConnectivityService.class, new ConnectivityServiceKey(suuid))
1209                 .build();
1210         try {
1211             this.networkTransactionService.delete(LogicalDatastoreType.OPERATIONAL, connectivityServIID);
1212             this.networkTransactionService.commit().get();
1213         } catch (InterruptedException | ExecutionException e) {
1214             LOG.error("Failed to delete TAPI connectivity service", e);
1215         }
1216     }
1217
1218     private void deleteConnection(Uuid connectionUuid) {
1219         // First read connectivity service with service uuid and update info
1220         InstanceIdentifier<org.opendaylight.yang.gen.v1
1221                 .urn.onf.otcc.yang.tapi.connectivity.rev221121.connectivity.context.Connection> connectionIID =
1222             InstanceIdentifier.builder(Context.class).augmentation(Context1.class)
1223                 .child(org.opendaylight.yang.gen.v1.urn
1224                     .onf.otcc.yang.tapi.connectivity.rev221121.context.ConnectivityContext.class)
1225                 .child(org.opendaylight.yang.gen.v1.urn
1226                         .onf.otcc.yang.tapi.connectivity.rev221121.connectivity.context.Connection.class,
1227                     new org.opendaylight.yang.gen.v1.urn
1228                             .onf.otcc.yang.tapi.connectivity.rev221121.connectivity.context.ConnectionKey(
1229                         connectionUuid))
1230                 .build();
1231         try {
1232             this.networkTransactionService.delete(LogicalDatastoreType.OPERATIONAL, connectionIID);
1233             this.networkTransactionService.commit().get();
1234         } catch (InterruptedException | ExecutionException e) {
1235             LOG.error("Failed to delete TAPI connection", e);
1236         }
1237     }
1238
1239     private String getIdBasedOnModelVersion(String nodeid) {
1240         return nodeid.matches("[A-Z]{5}-[A-Z0-9]{2}-.*")
1241             ? String.join("-", nodeid.split("-")[0], nodeid.split("-")[1]) : nodeid.split("-")[0];
1242     }
1243
1244     private ConnectionEndPoint getAssociatediODUCep(String spcXpdrNetwork) {
1245         Uuid topoUuid = new Uuid(UUID.nameUUIDFromBytes(TapiStringConstants.T0_FULL_MULTILAYER
1246             .getBytes(Charset.forName("UTF-8"))).toString());
1247         Uuid nodeUuid = new Uuid(UUID.nameUUIDFromBytes((String.join("+", spcXpdrNetwork.split("\\+")[0],
1248             TapiStringConstants.XPDR).getBytes(Charset.forName("UTF-8")))).toString());
1249         Uuid nepUuid = new Uuid(UUID.nameUUIDFromBytes((String.join("+", spcXpdrNetwork.split("\\+")[0],
1250                 TapiStringConstants.I_ODU, spcXpdrNetwork.split("\\+")[1]).getBytes(Charset.forName("UTF-8"))))
1251             .toString());
1252         Uuid cepUuid = new Uuid(UUID.nameUUIDFromBytes((String.join("+", "CEP",
1253             spcXpdrNetwork.split("\\+")[0], TapiStringConstants.I_ODU, spcXpdrNetwork.split("\\+")[1]))
1254             .getBytes(Charset.forName("UTF-8"))).toString());
1255         InstanceIdentifier<OwnedNodeEdgePoint> nepIID = InstanceIdentifier.builder(Context.class)
1256             .augmentation(org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.topology.rev221121.Context1.class)
1257             .child(org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.topology.rev221121.context.TopologyContext.class)
1258             .child(Topology.class, new TopologyKey(topoUuid))
1259             .child(org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.topology.rev221121.topology.Node.class,
1260                 new NodeKey(nodeUuid)).child(OwnedNodeEdgePoint.class, new OwnedNodeEdgePointKey(nepUuid)).build();
1261         try {
1262             Optional<OwnedNodeEdgePoint> optNode = this.networkTransactionService
1263                 .read(LogicalDatastoreType.OPERATIONAL, nepIID).get();
1264             if (!optNode.isPresent()) {
1265                 LOG.error("Node is not present in datastore");
1266                 return null;
1267             }
1268             if (optNode.orElseThrow().augmentation(OwnedNodeEdgePoint1.class) == null) {
1269                 LOG.error("Node doesnt have ceps");
1270                 return null;
1271             }
1272             return optNode.orElseThrow().augmentation(OwnedNodeEdgePoint1.class).getCepList().getConnectionEndPoint()
1273                 .get(new org.opendaylight.yang.gen.v1.urn
1274                     .onf.otcc.yang.tapi.connectivity.rev221121.cep.list.ConnectionEndPointKey(cepUuid));
1275         } catch (InterruptedException | ExecutionException e) {
1276             LOG.error("Couldnt read node in topology", e);
1277             return null;
1278         }
1279     }
1280
1281     private String getAssociatedNetworkPort(String spcXpdrClient, List<String> xpdrNetworkTplist) {
1282         for (String networkPort:xpdrNetworkTplist) {
1283             if (networkPort.split("\\+")[0].equals(spcXpdrClient.split("\\+")[0])) {
1284                 return networkPort;
1285             }
1286         }
1287         return null;
1288     }
1289
1290     private OpenroadmNodeType getOpenRoadmNodeType(List<String> xpdrNodelist) {
1291         List<OpenroadmNodeType> openroadmNodeTypeList = new ArrayList<>();
1292         for (String xpdrNode:xpdrNodelist) {
1293             Uuid nodeUuid = new Uuid(UUID.nameUUIDFromBytes((String.join("+",xpdrNode, TapiStringConstants.XPDR))
1294                 .getBytes(Charset.forName("UTF-8"))).toString());
1295             InstanceIdentifier<org.opendaylight.yang.gen.v1.urn
1296                     .onf.otcc.yang.tapi.topology.rev221121.topology.Node> nodeIID
1297                 = InstanceIdentifier.builder(Context.class).augmentation(org.opendaylight.yang.gen.v1.urn
1298                             .onf.otcc.yang.tapi.topology.rev221121.Context1.class).child(TopologyContext.class)
1299                     .child(Topology.class, new TopologyKey(this.tapiTopoUuid))
1300                     .child(org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.topology.rev221121.topology.Node.class,
1301                             new NodeKey(nodeUuid)).build();
1302             try {
1303                 Optional<org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.topology.rev221121.topology.Node> optNode
1304                     = this.networkTransactionService.read(LogicalDatastoreType.OPERATIONAL, nodeIID).get();
1305                 if (!optNode.isPresent()) {
1306                     return null;
1307                 }
1308                 OpenroadmNodeType openroadmNodeType = OpenroadmNodeType.forName(optNode.orElseThrow().getName().get(
1309                     new NameKey("Node Type")).getValue());
1310                 if (!openroadmNodeTypeList.contains(openroadmNodeType)) {
1311                     openroadmNodeTypeList.add(openroadmNodeType);
1312                 }
1313             } catch (InterruptedException | ExecutionException e) {
1314                 LOG.error("Couldnt read node in topology", e);
1315                 return null;
1316             }
1317         }
1318         // TODO for now check that there is only one type, otherwise error
1319         if (openroadmNodeTypeList.size() != 1) {
1320             LOG.error("More than one xpdr type. List = {}", openroadmNodeTypeList);
1321             return null;
1322         }
1323         return openroadmNodeTypeList.get(0);
1324     }
1325
1326     private List<String> getAssociatedClientsPort(List<String> xpdrNetworkTplist) {
1327         List<String> clientPortList = new ArrayList<>();
1328         for (String networkPort:xpdrNetworkTplist) {
1329             String nodeId = String.join("-", networkPort.split("\\+")[0].split("-")[0],
1330                 networkPort.split("\\+")[0].split("-")[1]);
1331             String tpId = networkPort.split("\\+")[1];
1332             InstanceIdentifier<Mapping> mapIID = InstanceIdentifier.builder(Network.class)
1333                 .child(Nodes.class, new NodesKey(nodeId))
1334                 .child(Mapping.class, new MappingKey(tpId)).build();
1335             try {
1336                 Optional<Mapping> optMapping = this.networkTransactionService.read(LogicalDatastoreType.CONFIGURATION,
1337                     mapIID).get();
1338                 if (!optMapping.isPresent()) {
1339                     LOG.error("Couldnt find mapping for port {} of node {}", tpId, nodeId);
1340                 }
1341                 Mapping mapping = optMapping.orElseThrow();
1342                 LOG.info("Mapping for node+port {}+{} = {}", nodeId, tpId, mapping);
1343                 String key = String.join("+", String.join("-", nodeId, tpId.split("\\-")[0]),
1344                     mapping.getConnectionMapLcp());
1345                 LOG.info("Key to be added to list = {}", key);
1346                 if (!clientPortList.contains(key)) {
1347                     clientPortList.add(key);
1348                 }
1349             } catch (InterruptedException | ExecutionException e) {
1350                 LOG.error("Couldnt read mapping from datastore", e);
1351                 return null;
1352             }
1353
1354         }
1355         return clientPortList;
1356     }
1357
1358     private OwnedNodeEdgePoint createRoadmNep(String orNodeId, String tpId,
1359         boolean withSip, OperationalState operState, AdministrativeState adminState, String nepPhotonicSublayer) {
1360
1361         //TODO : complete implementation with SIP
1362         Uuid nepUuid = new Uuid(UUID.nameUUIDFromBytes((String.join("+", orNodeId, nepPhotonicSublayer,
1363                 tpId)).getBytes(StandardCharsets.UTF_8)).toString());
1364         Name nepName = new NameBuilder()
1365                 .setValueName(TapiStringConstants.PHTNC_MEDIA + "NodeEdgePoint")
1366                 .setValue(String.join("+", orNodeId, nepPhotonicSublayer, tpId))
1367                 .build();
1368         List<SupportedCepLayerProtocolQualifierInstances> sclpqiList = new ArrayList<>();
1369         if (TapiStringConstants.MC.equals(nepPhotonicSublayer)) {
1370             sclpqiList.add(new SupportedCepLayerProtocolQualifierInstancesBuilder()
1371                 .setLayerProtocolQualifier(PHOTONICLAYERQUALIFIERMC.VALUE)
1372                 .setNumberOfCepInstances(Uint64.valueOf(1))
1373                 .build());
1374         } else {
1375             sclpqiList.add(new SupportedCepLayerProtocolQualifierInstancesBuilder()
1376                 .setLayerProtocolQualifier(PHOTONICLAYERQUALIFIEROTSiMC.VALUE)
1377                 .setNumberOfCepInstances(Uint64.valueOf(1))
1378                 .build());
1379         }
1380         OwnedNodeEdgePoint onep = new OwnedNodeEdgePointBuilder()
1381             .setUuid(nepUuid)
1382             .setLayerProtocolName(LayerProtocolName.PHOTONICMEDIA)
1383             .setName(Map.of(nepName.key(), nepName))
1384             .setSupportedCepLayerProtocolQualifierInstances(sclpqiList)
1385             .setDirection(Direction.BIDIRECTIONAL)
1386             .setLinkPortRole(PortRole.SYMMETRIC)
1387             .setAdministrativeState(adminState).setOperationalState(operState)
1388             .setLifecycleState(LifecycleState.INSTALLED)
1389             .build();
1390
1391         return onep;
1392     }
1393
1394     public void setInput(CreateConnectivityServiceInput input) {
1395         this.input = input;
1396     }
1397
1398     public void setServiceUuid(Uuid serviceUuid) {
1399         this.serviceUuid = serviceUuid;
1400     }
1401 }