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