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