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