Modify spectrum assignment management in PCE
[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.topology.TopologyUtils;
27 import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.pce.rev210701.ServicePathRpcResult;
28 import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.pce.rev210701.TransportpcePceListener;
29 import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.pce.rev210701.service.path.rpc.result.PathDescription;
30 import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.pce.rev210701.service.path.rpc.result.PathDescriptionBuilder;
31 import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.pathdescription.rev201210.path.description.atoz.direction.AToZ;
32 import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.pathdescription.rev201210.pce.resource.resource.resource.Node;
33 import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.pathdescription.rev201210.pce.resource.resource.resource.TerminationPoint;
34 import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.service.types.rev200128.RpcStatusEx;
35 import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.common.rev181210.Context;
36 import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.common.rev181210.ForwardingDirection;
37 import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.common.rev181210.LayerProtocolName;
38 import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.common.rev181210.LifecycleState;
39 import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.common.rev181210.OperationalState;
40 import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.common.rev181210.PortDirection;
41 import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.common.rev181210.PortRole;
42 import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.common.rev181210.Uuid;
43 import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.common.rev181210.global._class.Name;
44 import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.common.rev181210.global._class.NameBuilder;
45 import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.connectivity.rev181210.Context1;
46 import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.connectivity.rev181210.CreateConnectivityServiceInput;
47 import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.connectivity.rev181210.OwnedNodeEdgePoint1;
48 import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.connectivity.rev181210.OwnedNodeEdgePoint1Builder;
49 import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.connectivity.rev181210.cep.list.ConnectionEndPoint;
50 import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.connectivity.rev181210.cep.list.ConnectionEndPointBuilder;
51 import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.connectivity.rev181210.connection.ConnectionEndPointKey;
52 import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.connectivity.rev181210.connection.end.point.ClientNodeEdgePoint;
53 import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.connectivity.rev181210.connection.end.point.ClientNodeEdgePointBuilder;
54 import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.connectivity.rev181210.connectivity.context.ConnectivityService;
55 import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.connectivity.rev181210.connectivity.context.ConnectivityServiceBuilder;
56 import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.connectivity.rev181210.connectivity.context.ConnectivityServiceKey;
57 import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.connectivity.rev181210.connectivity.service.Connection;
58 import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.connectivity.rev181210.connectivity.service.ConnectionBuilder;
59 import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.connectivity.rev181210.connectivity.service.ConnectionKey;
60 import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.connectivity.rev181210.context.ConnectivityContextBuilder;
61 import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.connectivity.rev181210.context.topology.context.topology.node.owned.node.edge.point.CepList;
62 import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.connectivity.rev181210.context.topology.context.topology.node.owned.node.edge.point.CepListBuilder;
63 import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.topology.rev181210.node.OwnedNodeEdgePoint;
64 import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.topology.rev181210.node.OwnedNodeEdgePointBuilder;
65 import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.topology.rev181210.node.OwnedNodeEdgePointKey;
66 import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.topology.rev181210.topology.NodeKey;
67 import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.topology.rev181210.topology.context.Topology;
68 import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.topology.rev181210.topology.context.TopologyKey;
69 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
70 import org.slf4j.Logger;
71 import org.slf4j.LoggerFactory;
72
73 public class TapiPceListenerImpl implements TransportpcePceListener {
74
75     private static final String DSR = "DSR";
76     private static final String ODU = "ODU";
77     private static final String E_ODU = "eODU";
78     private static final String I_ODU = "iODU";
79     private static final String OTSI = "OTSi";
80     private static final String E_OTSI = "eOTSi";
81     private static final String I_OTSI = "iOTSi";
82     private static final String PHTNC_MEDIA = "PHOTONIC_MEDIA";
83     private static final String MC = "MEDIA_CHANNEL";
84     private static final String OTSI_MC = "OTSi_MEDIA_CHANNEL";
85     private static final String TP = "TerminationPoint";
86     private static final String NODE = "Node";
87     private static final Logger LOG = LoggerFactory.getLogger(TapiPceListenerImpl.class);
88
89     private ServicePathRpcResult servicePathRpcResult;
90     private CreateConnectivityServiceInput input;
91     private Uuid serviceUuid;
92     private final DataBroker dataBroker;
93     private final NetworkTransactionService networkTransactionService;
94     private final Map<org.opendaylight.yang.gen.v1.urn
95         .onf.otcc.yang.tapi.connectivity.rev181210.connectivity.context.ConnectionKey,
96         org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.connectivity.rev181210.connectivity.context.Connection>
97         connectionFullMap; // this variable is for complete connection objects
98
99     public TapiPceListenerImpl(DataBroker dataBroker) {
100         this.connectionFullMap = new HashMap<>();
101         this.dataBroker = dataBroker;
102         this.networkTransactionService = new NetworkTransactionImpl(new RequestProcessor(this.dataBroker));
103     }
104
105     @Override
106     public void onServicePathRpcResult(ServicePathRpcResult notification) {
107         if (compareServicePathRpcResult(notification)) {
108             LOG.warn("ServicePathRpcResult already wired !");
109             return;
110         }
111         servicePathRpcResult = notification;
112         switch (servicePathRpcResult.getNotificationType().getIntValue()) {
113             /* path-computation-request. */
114             case 1:
115                 onPathComputationResult(notification);
116                 break;
117             /* cancel-resource-reserve. */
118             case 2:
119                 onCancelResourceResult(notification.getServiceName());
120                 break;
121             default:
122                 break;
123         }
124     }
125
126     /**
127      * Process path computation request result.
128      * @param notification the result notification.
129      */
130     private void onPathComputationResult(ServicePathRpcResult notification) {
131         this.connectionFullMap.clear();
132         LOG.info("PCE '{}' Notification received : {}",servicePathRpcResult.getNotificationType().getName(),
133                 notification);
134         if (servicePathRpcResult.getStatus() == RpcStatusEx.Failed) {
135             LOG.error("PCE path computation failed !");
136             return;
137         } else if (servicePathRpcResult.getStatus() == RpcStatusEx.Pending) {
138             LOG.warn("PCE path computation returned a Penging RpcStatusEx code!");
139             return;
140         } else if (servicePathRpcResult.getStatus() != RpcStatusEx.Successful) {
141             LOG.error("PCE path computation returned an unknown RpcStatusEx code!");
142             return;
143         }
144
145         LOG.info("PCE calculation done OK !");
146         if (servicePathRpcResult.getPathDescription() == null) {
147             LOG.error("'PathDescription' parameter is null ");
148             return;
149         }
150         PathDescription pathDescription = new PathDescriptionBuilder()
151             .setAToZDirection(servicePathRpcResult.getPathDescription().getAToZDirection())
152             .setZToADirection(servicePathRpcResult.getPathDescription().getZToADirection())
153             .build();
154         LOG.info("PathDescription gets : {}", pathDescription);
155         if (input == null) {
156             LOG.error("Input is null !");
157             return;
158         }
159         // Create connections and ceps for the connectivity service.
160         //  Connections must be with a locked stated. As the renderer hasnt implemented yet the oc's
161         Map<ConnectionKey, Connection> connectionMap = createConnectionsAndCepsForService(pathDescription,
162                 input.getConnectivityConstraint().getServiceLayer());
163         // add connections to connection context and to connectivity context
164         updateConnectionContextWithConn(this.connectionFullMap, connectionMap, serviceUuid);
165     }
166
167     private Map<ConnectionKey, Connection> createConnectionsAndCepsForService(PathDescription pathDescription,
168                                                                               LayerProtocolName serviceProtName) {
169         Map<ConnectionKey, Connection> connectionServMap = new HashMap<>();
170         // build lists with ROADM nodes, XPDR/MUX/SWITCH nodes, ROADM DEG TTPs, ROADM SRG TTPs, XPDR CLIENT TTPs
171         //  and XPDR NETWORK TTPs (if any). From the path description. This will help to build the uuid of the CEPs
172         //  and the connections
173         String resourceType;
174         List<String> xpdrClientTplist = new ArrayList<>();
175         List<String> xpdrNetworkTplist = new ArrayList<>();
176         List<String> rdmAddDropTplist = new ArrayList<>();
177         List<String> rdmDegTplist = new ArrayList<>();
178         List<String> rdmNodelist = new ArrayList<>();
179         List<String> xpdrNodelist = new ArrayList<>();
180         for (AToZ elem:pathDescription.getAToZDirection().getAToZ().values().stream()
181                 .sorted(Comparator.comparing(AToZ::getId)).collect(Collectors.toList())) {
182             resourceType = elem.getResource().getResource().implementedInterface().getSimpleName();
183             switch (resourceType) {
184                 case TP:
185                     TerminationPoint tp = (TerminationPoint) elem.getResource().getResource();
186                     String tpID = tp.getTpId();
187                     String tpNode;
188                     if (tpID.contains("CLIENT")) {
189                         tpNode = tp.getTpNodeId();
190                         if (!xpdrClientTplist.contains(String.join("+", tpNode, tpID))) {
191                             xpdrClientTplist.add(String.join("+", tpNode, tpID));
192                         }
193                     }
194                     if (tpID.contains("NETWORK")) {
195                         tpNode = tp.getTpNodeId();
196                         if (!xpdrNetworkTplist.contains(String.join("+", tpNode, tpID))) {
197                             xpdrNetworkTplist.add(String.join("+", tpNode, tpID));
198                         }
199                     }
200                     if (tpID.contains("PP")) {
201                         tpNode = getIdBasedOnModelVersion(tp.getTpNodeId());
202                         LOG.info("ROADM Node of tp = {}", tpNode);
203                         if (!rdmAddDropTplist.contains(String.join("+", tpNode, tpID))) {
204                             rdmAddDropTplist.add(String.join("+", tpNode, tpID));
205                         }
206                     }
207                     if (tpID.contains("TTP")) {
208                         tpNode = getIdBasedOnModelVersion(tp.getTpNodeId());
209                         LOG.info("ROADM Node of tp = {}", tpNode);
210                         if (!rdmDegTplist.contains(String.join("+", tpNode, tpID))) {
211                             rdmDegTplist.add(String.join("+", tpNode, tpID));
212                         }
213                     }
214                     break;
215                 case NODE:
216                     Node node = (Node) elem.getResource().getResource();
217                     String nodeId = node.getNodeId();
218                     if (nodeId.contains("XPDR") || nodeId.contains("SPDR") || nodeId.contains("MXPDR")) {
219                         LOG.info("Node id = {}", nodeId);
220                         if (!xpdrNodelist.contains(nodeId)) {
221                             xpdrNodelist.add(nodeId); // should contain only 2
222                         }
223                     }
224                     if (nodeId.contains("ROADM")) {
225                         nodeId = getIdBasedOnModelVersion(nodeId);
226                         LOG.info("Node id = {}", nodeId);
227                         if (!rdmNodelist.contains(nodeId)) {
228                             rdmNodelist.add(nodeId);
229                         }
230                     }
231                     break;
232                 default:
233                     LOG.warn("Resource is a {}", resourceType);
234             }
235         }
236         LOG.info("ROADM node list = {}", rdmNodelist.toString());
237         LOG.info("ROADM degree list = {}", rdmDegTplist.toString());
238         LOG.info("ROADM addrop list = {}", rdmAddDropTplist.toString());
239         LOG.info("XPDR node list = {}", xpdrNodelist.toString());
240         LOG.info("XPDR network list = {}", xpdrNetworkTplist.toString());
241         LOG.info("XPDR client list = {}", xpdrClientTplist.toString());
242         // TODO -> for 10GB eth and ODU services there are no ROADMs in path description as they use the OTU link,
243         //  but for 100GB eth all is created at once. Check if the roadm list is empty to determine whether we need
244         //  to trigger all the steps or not
245         String edgeRoadm1 = "";
246         String edgeRoadm2 = "";
247         if (!rdmNodelist.isEmpty()) {
248             edgeRoadm1 = rdmNodelist.get(0);
249             edgeRoadm2 = rdmNodelist.get(rdmNodelist.size() - 1);
250             LOG.info("edgeRoadm1 = {}", edgeRoadm1);
251             LOG.info("edgeRoadm2 = {}", edgeRoadm2);
252         }
253         // create corresponding CEPs and Connections. Connections should be added to the corresponding context
254         // CEPs must be included in the topology context as an augmentation for each ONEP!!
255         switch (serviceProtName) {
256             case PHOTONICMEDIA:
257                 // Identify number of ROADMs
258                 // - XC Connection between MC CEPs mapped from MC NEPs (within a roadm)
259                 // - XC Connection between OTSiMC CEPs mapped from OTSiMC NEPs (within a roadm)
260                 // - Top Connection MC betwwen MC CEPs of different roadms
261                 // - Top Connection OTSiMC betwwen OTSiMC CEPs of extreme roadms
262                 connectionServMap.putAll(createRoadmCepsAndConnections(rdmAddDropTplist, rdmDegTplist, rdmNodelist,
263                         edgeRoadm1, edgeRoadm2));
264                 if (!pathDescription.getAToZDirection().getAToZ().values().stream().findFirst().get().getId()
265                         .contains("ROADM")) {
266                     // - XC Connection OTSi betwwen iOTSi y eOTSi of xpdr
267                     // - Top connection OTSi between network ports of xpdrs in the Photonic media layer -> i_OTSi
268                     connectionServMap.putAll(createXpdrCepsAndConnectionsPht(xpdrNetworkTplist, xpdrNodelist));
269                 }
270                 break;
271             case ODU:
272                 // Check if OC and OTU are created
273                 if (!rdmNodelist.isEmpty()) {
274                     connectionServMap.putAll(createRoadmCepsAndConnections(rdmAddDropTplist, rdmDegTplist, rdmNodelist,
275                         edgeRoadm1, edgeRoadm2));
276                     connectionServMap.putAll(createXpdrCepsAndConnectionsPht(xpdrNetworkTplist, xpdrNodelist));
277                 }
278                 // - XC Connection OTSi betwwen iODU and eODU of xpdr
279                 // - Top connection in the ODU layer, between xpdr iODU ports (?)
280                 connectionServMap.putAll(createXpdrCepsAndConnectionsOdu(xpdrNetworkTplist, xpdrNodelist));
281                 break;
282             case DSR:
283                 // Check if OC, OTU and ODU are created
284                 // Check if OC, OTU and ODU are created
285                 if (!rdmNodelist.isEmpty()) {
286                     connectionServMap.putAll(createRoadmCepsAndConnections(rdmAddDropTplist, rdmDegTplist, rdmNodelist,
287                         edgeRoadm1, edgeRoadm2));
288                     connectionServMap.putAll(createXpdrCepsAndConnectionsPht(xpdrNetworkTplist, xpdrNodelist));
289                     connectionServMap.putAll(createXpdrCepsAndConnectionsOdu(xpdrNetworkTplist, xpdrNodelist));
290                 }
291                 // Top connection in the DSR layer, between client ports of the xpdrs
292                 connectionServMap.putAll(createXpdrCepsAndConnectionsDsr(xpdrClientTplist, xpdrNodelist));
293                 break;
294             default:
295                 LOG.error("Service type format {} not supported", serviceProtName.getName());
296         }
297         return connectionServMap;
298     }
299
300     /**
301      * Process cancel resource result.
302      * @param serviceName Service name to build uuid.
303      */
304     private void onCancelResourceResult(String serviceName) {
305         if (servicePathRpcResult.getStatus() == RpcStatusEx.Failed) {
306             LOG.info("PCE cancel resource failed !");
307             return;
308         } else if (servicePathRpcResult.getStatus() == RpcStatusEx.Pending) {
309             LOG.warn("PCE cancel returned a Penging RpcStatusEx code!");
310             return;
311         } else if (servicePathRpcResult.getStatus() != RpcStatusEx.Successful) {
312             LOG.error("PCE cancel returned an unknown RpcStatusEx code!");
313             return;
314         }
315         LOG.info("PCE cancel resource done OK !");
316         Uuid suuid = new Uuid(UUID.nameUUIDFromBytes(serviceName.getBytes(Charset.forName("UTF-8")))
317                 .toString());
318         // get connections of connectivity service and remove them from tapi context and then remove
319         //  service from context. The CEPs are maintained as they could be reused by another service
320         ConnectivityService connService = getConnectivityService(suuid);
321         if (connService == null) {
322             LOG.error("Service doesnt exist in tapi context");
323             return;
324         }
325         for (Connection connection:connService.getConnection().values()) {
326             deleteConnection(connection.getConnectionUuid());
327         }
328         deleteConnectivityService(suuid);
329     }
330
331     @SuppressFBWarnings(
332             value = "ES_COMPARING_STRINGS_WITH_EQ",
333             justification = "false positives, not strings but real object references comparisons")
334     private Boolean compareServicePathRpcResult(ServicePathRpcResult notification) {
335         if (servicePathRpcResult == null) {
336             return false;
337         }
338         if (servicePathRpcResult.getNotificationType() != notification.getNotificationType()) {
339             return false;
340         }
341         if (servicePathRpcResult.getServiceName() != notification.getServiceName()) {
342             return false;
343         }
344         if (servicePathRpcResult.getStatus() != notification.getStatus()) {
345             return false;
346         }
347         if (servicePathRpcResult.getStatusMessage() != notification.getStatusMessage()) {
348             return false;
349         }
350         return true;
351     }
352
353     private Map<ConnectionKey,Connection> createXpdrCepsAndConnectionsDsr(List<String> xpdrClientTplist,
354                                                                           List<String> xpdrNodelist) {
355         Map<ConnectionKey, Connection> connServMap = new HashMap<>();
356         Map<org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.connectivity.rev181210.cep.list.ConnectionEndPointKey,
357             ConnectionEndPoint> cepMap = new HashMap<>();
358
359         // Create 1 cep per Xpdr in the CLIENT and a top connection DSR between the CLIENT xpdrs
360         for (String xpdr:xpdrNodelist) {
361             LOG.info("Creating ceps and xc for xpdr {}", xpdr);
362             String spcXpdrClient = xpdrClientTplist.stream().filter(netp -> netp.contains(xpdr)).findFirst().get();
363
364             ConnectionEndPoint netCep1 = createCepXpdr(spcXpdrClient, DSR, DSR, LayerProtocolName.DSR);
365             putXpdrCepInTopologyContext(xpdr, spcXpdrClient, DSR, DSR, netCep1);
366
367             cepMap.put(netCep1.key(), netCep1);
368         }
369
370         // DSR top connection between edge xpdr CLIENT DSR
371         String spcXpdr1 = xpdrClientTplist.stream().filter(adp -> adp.contains(xpdrNodelist
372             .get(0))).findFirst().get();
373         String spcXpdr2 = xpdrClientTplist.stream().filter(adp -> adp.contains(xpdrNodelist
374             .get(xpdrNodelist.size() - 1))).findFirst().get();
375         org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.connectivity.rev181210.connectivity.context.Connection
376             connection = createTopConnection(spcXpdr1, spcXpdr2, cepMap, DSR, LayerProtocolName.DSR);
377         this.connectionFullMap.put(connection.key(), connection);
378
379         // ODU top connection that will be added to the service object
380         Connection conn = new ConnectionBuilder().setConnectionUuid(connection.getUuid()).build();
381         connServMap.put(conn.key(), conn);
382
383         return connServMap;
384     }
385
386     private Map<ConnectionKey, Connection> createXpdrCepsAndConnectionsOdu(List<String> xpdrNetworkTplist,
387                                                                            List<String> xpdrNodelist) {
388         Map<ConnectionKey, Connection> connServMap = new HashMap<>();
389         Map<org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.connectivity.rev181210.cep.list.ConnectionEndPointKey,
390             ConnectionEndPoint> cepMap = new HashMap<>();
391         // Create 1 cep per Xpdr in the I_ODU and E_ODU, X connection between iODU and eODU and a top
392         // connection iODU between the xpdrs
393         for (String xpdr:xpdrNodelist) {
394             LOG.info("Creating ceps and xc for xpdr {}", xpdr);
395             String spcXpdrNetwork = xpdrNetworkTplist.stream().filter(netp -> netp.contains(xpdr)).findFirst().get();
396
397             ConnectionEndPoint netCep1 = createCepXpdr(spcXpdrNetwork, E_ODU, DSR, LayerProtocolName.ODU);
398             putXpdrCepInTopologyContext(xpdr, spcXpdrNetwork, E_ODU, DSR, netCep1);
399             ConnectionEndPoint netCep2 = createCepXpdr(spcXpdrNetwork, I_ODU, DSR, LayerProtocolName.ODU);
400             putXpdrCepInTopologyContext(xpdr, spcXpdrNetwork, I_ODU, DSR, netCep2);
401
402             cepMap.put(netCep1.key(), netCep1);
403             cepMap.put(netCep2.key(), netCep2);
404
405             // Create x connection between I_ODU and E_ODU within xpdr
406             org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.connectivity.rev181210.connectivity.context.Connection
407                 connection = createXCBetweenCeps(netCep1, netCep2, spcXpdrNetwork, spcXpdrNetwork, ODU,
408                 LayerProtocolName.ODU);
409             this.connectionFullMap.put(connection.key(), connection);
410
411             // Create X connection that will be added to the service object
412             Connection conn = new ConnectionBuilder().setConnectionUuid(connection.getUuid()).build();
413             connServMap.put(conn.key(), conn);
414         }
415
416         // ODU top connection between edge xpdr e_ODU
417         String spcXpdr1 = xpdrNetworkTplist.stream().filter(adp -> adp.contains(xpdrNodelist
418             .get(0))).findFirst().get();
419         String spcXpdr2 = xpdrNetworkTplist.stream().filter(adp -> adp.contains(xpdrNodelist
420             .get(xpdrNodelist.size() - 1))).findFirst().get();
421         org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.connectivity.rev181210.connectivity.context.Connection
422             connection = createTopConnection(spcXpdr1, spcXpdr2, cepMap, E_ODU, LayerProtocolName.ODU);
423         this.connectionFullMap.put(connection.key(), connection);
424
425         // ODU top connection that will be added to the service object
426         Connection conn = new ConnectionBuilder().setConnectionUuid(connection.getUuid()).build();
427         connServMap.put(conn.key(), conn);
428
429         return connServMap;
430     }
431
432     private Map<ConnectionKey, Connection> createXpdrCepsAndConnectionsPht(List<String> xpdrNetworkTplist,
433                                                                            List<String> xpdrNodelist) {
434         Map<ConnectionKey, Connection> connServMap = new HashMap<>();
435         Map<org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.connectivity.rev181210.cep.list.ConnectionEndPointKey,
436             ConnectionEndPoint> cepMap = new HashMap<>();
437
438         // create ceps and x connections within xpdr
439         for (String xpdr:xpdrNodelist) {
440             LOG.info("Creating ceps and xc for xpdr {}", xpdr);
441             String spcXpdrNetwork = xpdrNetworkTplist.stream().filter(netp -> netp.contains(xpdr)).findFirst().get();
442             // There should be 1 network tp per xpdr
443             // TODO photonic media model should be updated to have the corresponding CEPs. I will just create
444             //  3 different MC CEPs giving different IDs to show that they are different
445             // Create 3 CEPs for each xpdr otsi node and the corresponding cross connection matchin the NEPs
446             ConnectionEndPoint netCep1 = createCepXpdr(spcXpdrNetwork, PHTNC_MEDIA, OTSI,
447                 LayerProtocolName.PHOTONICMEDIA);
448             putXpdrCepInTopologyContext(xpdr, spcXpdrNetwork, PHTNC_MEDIA, OTSI, netCep1);
449             ConnectionEndPoint netCep2 = createCepXpdr(spcXpdrNetwork, E_OTSI, OTSI, LayerProtocolName.PHOTONICMEDIA);
450             putXpdrCepInTopologyContext(xpdr, spcXpdrNetwork, E_OTSI, OTSI, netCep2);
451             ConnectionEndPoint netCep3 = createCepXpdr(spcXpdrNetwork, I_OTSI, OTSI, LayerProtocolName.PHOTONICMEDIA);
452             putXpdrCepInTopologyContext(xpdr, spcXpdrNetwork, I_OTSI, OTSI, netCep3);
453             cepMap.put(netCep1.key(), netCep1);
454             cepMap.put(netCep2.key(), netCep2);
455             cepMap.put(netCep3.key(), netCep3);
456
457             // Create x connection between I_OTSi and E_OTSi within xpdr
458             org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.connectivity.rev181210.connectivity.context.Connection
459                 connection = createXCBetweenCeps(netCep2, netCep3, spcXpdrNetwork, spcXpdrNetwork, OTSI,
460                 LayerProtocolName.PHOTONICMEDIA);
461             this.connectionFullMap.put(connection.key(), connection);
462
463             // Create X connection that will be added to the service object
464             Connection conn = new ConnectionBuilder().setConnectionUuid(connection.getUuid()).build();
465             connServMap.put(conn.key(), conn);
466         }
467         // OTSi top connection between edge I_OTSI Xpdr
468         String spcXpdr1 = xpdrNetworkTplist.stream().filter(adp -> adp.contains(xpdrNodelist
469             .get(0))).findFirst().get();
470         String spcXpdr2 = xpdrNetworkTplist.stream().filter(adp -> adp.contains(xpdrNodelist
471             .get(xpdrNodelist.size() - 1))).findFirst().get();
472         org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.connectivity.rev181210.connectivity.context.Connection
473             connection = createTopConnection(spcXpdr1, spcXpdr2, cepMap, I_OTSI, LayerProtocolName.PHOTONICMEDIA);
474         this.connectionFullMap.put(connection.key(), connection);
475
476         // OTSi top connection that will be added to the service object
477         Connection conn = new ConnectionBuilder().setConnectionUuid(connection.getUuid()).build();
478         connServMap.put(conn.key(), conn);
479
480
481         return connServMap;
482     }
483
484     private Map<ConnectionKey, Connection> createRoadmCepsAndConnections(List<String> rdmAddDropTplist,
485                                                                          List<String> rdmDegTplist,
486                                                                          List<String> rdmNodelist,
487                                                                          String edgeRoadm1, String edgeRoadm2) {
488         // TODO: will need to check if things exist already or not
489         Map<ConnectionKey, Connection> connServMap = new HashMap<>();
490         Map<org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.connectivity.rev181210.cep.list.ConnectionEndPointKey,
491             ConnectionEndPoint> cepMap = new HashMap<>();
492         // create ceps and x connections within roadm
493         for (String roadm : rdmNodelist) {
494             LOG.info("Creating ceps and xc for roadm {}", roadm);
495             String spcRdmAD = rdmAddDropTplist.stream().filter(adp -> adp.contains(roadm)).findFirst().get();
496             LOG.info("AD port of ROADm {} = {}", roadm, spcRdmAD);
497             // There should be only 1 AD and 1 DEG per roadm
498             // TODO photonic media model should be updated to have the corresponding CEPs. I will just create
499             //  3 different MC CEPs giving different IDs to show that they are different
500             // Create 3 CEPs for each AD and DEG and the corresponding cross connections, matching the NEPs
501             // created in the topology creation
502             // add CEPs to the topology to the corresponding ONEP
503             ConnectionEndPoint adCep1 = createCepRoadm(spcRdmAD, PHTNC_MEDIA);
504             putRdmCepInTopologyContext(roadm, spcRdmAD, PHTNC_MEDIA, adCep1);
505             ConnectionEndPoint adCep2 = createCepRoadm(spcRdmAD, MC);
506             putRdmCepInTopologyContext(roadm, spcRdmAD, MC, adCep2);
507             ConnectionEndPoint adCep3 = createCepRoadm(spcRdmAD, OTSI_MC);
508             putRdmCepInTopologyContext(roadm, spcRdmAD, OTSI_MC, adCep3);
509             cepMap.put(adCep1.key(), adCep1);
510             cepMap.put(adCep2.key(), adCep2);
511             cepMap.put(adCep3.key(), adCep3);
512
513             String spcRdmDEG = rdmDegTplist.stream().filter(adp -> adp.contains(roadm)).findFirst().get();
514             LOG.info("Degree port of ROADm {} = {}", roadm, spcRdmDEG);
515
516             ConnectionEndPoint degCep1 = createCepRoadm(spcRdmDEG, PHTNC_MEDIA);
517             putRdmCepInTopologyContext(roadm, spcRdmDEG, PHTNC_MEDIA, degCep1);
518             ConnectionEndPoint degCep2 = createCepRoadm(spcRdmDEG, MC);
519             putRdmCepInTopologyContext(roadm, spcRdmDEG, MC, degCep2);
520             ConnectionEndPoint degCep3 = createCepRoadm(spcRdmDEG, OTSI_MC);
521             putRdmCepInTopologyContext(roadm, spcRdmDEG, OTSI_MC, degCep3);
522             cepMap.put(degCep1.key(), degCep1);
523             cepMap.put(degCep2.key(), degCep2);
524             cepMap.put(degCep3.key(), degCep3);
525
526             LOG.info("Going to create cross connections for ROADM {}", roadm);
527             // Create X connections between MC and OTSi_MC for full map
528             org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.connectivity.rev181210.connectivity.context.Connection
529                 connection1 = createXCBetweenCeps(adCep2, degCep2, spcRdmAD, spcRdmDEG, MC,
530                 LayerProtocolName.PHOTONICMEDIA);
531             LOG.info("Cross connection 1 created = {}", connection1.toString());
532             org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.connectivity.rev181210.connectivity.context.Connection
533                 connection2 = createXCBetweenCeps(adCep3, degCep3, spcRdmAD, spcRdmDEG, OTSI_MC,
534                 LayerProtocolName.PHOTONICMEDIA);
535             LOG.info("Cross connection 2 created = {}", connection2.toString());
536             this.connectionFullMap.put(connection1.key(), connection1);
537             this.connectionFullMap.put(connection2.key(), connection2);
538
539             // Create X connections that will be added to the service object
540             Connection conn1 = new ConnectionBuilder().setConnectionUuid(connection1.getUuid()).build();
541             Connection conn2 = new ConnectionBuilder().setConnectionUuid(connection2.getUuid()).build();
542             connServMap.put(conn1.key(), conn1);
543             connServMap.put(conn2.key(), conn2);
544         }
545         LOG.info("Going to create top connections betwee roadms");
546         // create top connections between roadms: MC connections between AD MC CEPs of roadms
547         for (int i = 0; i < rdmNodelist.size(); i++) {
548             if (rdmNodelist.size() <= (i + 1)) {
549                 LOG.info("Reached last roadm. No more MC connections");
550                 break;
551             }
552             // Current roadm with roadm i + 1 --> MC
553             String roadm1 = rdmNodelist.get(i);
554             String spcRdmAD1 = rdmAddDropTplist.stream().filter(adp -> adp.contains(roadm1)).findFirst().get();
555             String roadm2 = rdmNodelist.get(i + 1);
556             String spcRdmAD2 = rdmAddDropTplist.stream().filter(adp -> adp.contains(roadm2)).findFirst().get();
557             LOG.info("Creating top connection from {} to {} between tps: {}-{}", roadm1, roadm2, spcRdmAD1, spcRdmAD2);
558
559             // Create top connections between MC for full map
560             org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.connectivity.rev181210.connectivity.context.Connection
561                 connection = createTopConnection(spcRdmAD1, spcRdmAD2, cepMap, MC, LayerProtocolName.PHOTONICMEDIA);
562             this.connectionFullMap.put(connection.key(), connection);
563             LOG.info("Top connection created = {}", connection.toString());
564
565             // Create top connections that will be added to the service object
566             Connection conn = new ConnectionBuilder().setConnectionUuid(connection.getUuid()).build();
567             connServMap.put(conn.key(), conn);
568         }
569
570         // OTSiMC top connection between edge roadms
571         LOG.info("Going to created top connection between OTSiMC");
572         String spcRdmAD1 = rdmAddDropTplist.stream().filter(adp -> adp.contains(edgeRoadm1)).findFirst().get();
573         String spcRdmAD2 = rdmAddDropTplist.stream().filter(adp -> adp.contains(edgeRoadm2)).findFirst().get();
574         org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.connectivity.rev181210.connectivity.context.Connection
575             connection = createTopConnection(spcRdmAD1, spcRdmAD2, cepMap, OTSI_MC,
576             LayerProtocolName.PHOTONICMEDIA);
577         this.connectionFullMap.put(connection.key(), connection);
578         LOG.info("Top connection created = {}", connection.toString());
579
580         // OTSiMC top connections that will be added to the service object
581         Connection conn = new ConnectionBuilder().setConnectionUuid(connection.getUuid()).build();
582         connServMap.put(conn.key(), conn);
583         return connServMap;
584     }
585
586     private org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.connectivity.rev181210.connectivity.context.Connection
587             createTopConnection(String tp1, String tp2,
588                         Map<org.opendaylight.yang.gen.v1.urn
589                                 .onf.otcc.yang.tapi.connectivity.rev181210.cep.list.ConnectionEndPointKey,
590                                 ConnectionEndPoint> cepMap, String qual, LayerProtocolName topPortocol) {
591         // find cep for each AD MC of roadm 1 and 2
592         LOG.info("Top connection name = {}", String.join("+", "TOP", tp1, tp2, qual));
593         org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.connectivity.rev181210.ConnectionEndPoint adCep1 =
594             cepMap.get(new org.opendaylight.yang.gen.v1.urn
595                 .onf.otcc.yang.tapi.connectivity.rev181210.cep.list.ConnectionEndPointKey(
596                 new Uuid(UUID.nameUUIDFromBytes((String.join("+", "CEP", tp1.split("\\+")[0],
597                     qual, tp1.split("\\+")[1])).getBytes(Charset.forName("UTF-8")))
598                     .toString())));
599         LOG.info("ADCEP1 = {}", adCep1.toString());
600         org.opendaylight.yang.gen.v1.urn
601             .onf.otcc.yang.tapi.connectivity.rev181210.connection.ConnectionEndPoint cep1 =
602             new org.opendaylight.yang.gen.v1.urn
603                 .onf.otcc.yang.tapi.connectivity.rev181210.connection.ConnectionEndPointBuilder()
604                 .setNodeEdgePointUuid(adCep1.getClientNodeEdgePoint()
605                     .values().stream().findFirst().get().getNodeEdgePointUuid())
606                 .setTopologyUuid(adCep1.getClientNodeEdgePoint()
607                     .values().stream().findFirst().get().getTopologyUuid())
608                 .setNodeUuid(adCep1.getClientNodeEdgePoint()
609                     .values().stream().findFirst().get().getNodeUuid())
610                 .setConnectionEndPointUuid(adCep1.getUuid())
611                 .build();
612         org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.connectivity.rev181210.ConnectionEndPoint adCep2 =
613             cepMap.get(new org.opendaylight.yang.gen.v1.urn
614                 .onf.otcc.yang.tapi.connectivity.rev181210.cep.list.ConnectionEndPointKey(
615                 new Uuid(UUID.nameUUIDFromBytes((String.join("+", "CEP", tp2.split("\\+")[0],
616                     qual, tp2.split("\\+")[1])).getBytes(Charset.forName("UTF-8")))
617                     .toString())));
618         LOG.info("ADCEP2 = {}", adCep2.toString());
619         org.opendaylight.yang.gen.v1.urn
620             .onf.otcc.yang.tapi.connectivity.rev181210.connection.ConnectionEndPoint cep2 =
621             new org.opendaylight.yang.gen.v1.urn
622                 .onf.otcc.yang.tapi.connectivity.rev181210.connection.ConnectionEndPointBuilder()
623                 .setNodeEdgePointUuid(adCep2.getClientNodeEdgePoint()
624                     .values().stream().findFirst().get().getNodeEdgePointUuid())
625                 .setTopologyUuid(adCep2.getClientNodeEdgePoint()
626                     .values().stream().findFirst().get().getTopologyUuid())
627                 .setNodeUuid(adCep2.getClientNodeEdgePoint()
628                     .values().stream().findFirst().get().getNodeUuid())
629                 .setConnectionEndPointUuid(adCep1.getUuid())
630                 .build();
631         Map<ConnectionEndPointKey, org.opendaylight.yang.gen.v1.urn
632             .onf.otcc.yang.tapi.connectivity.rev181210.connection.ConnectionEndPoint> ceps = new HashMap<>();
633         ceps.put(cep1.key(), cep1);
634         ceps.put(cep2.key(), cep2);
635         Name connName = new NameBuilder()
636             .setValueName("Connection name")
637             .setValue(String.join("+", "TOP", tp1, tp2, qual))
638             .build();
639         // TODO: lower connection, supported link.......
640         return new org.opendaylight.yang.gen.v1.urn
641             .onf.otcc.yang.tapi.connectivity.rev181210.connectivity.context.ConnectionBuilder()
642             .setUuid(new Uuid(UUID.nameUUIDFromBytes((String.join("+", "TOP", tp1, tp2, qual))
643                 .getBytes(Charset.forName("UTF-8"))).toString()))
644             .setName(Map.of(connName.key(), connName))
645             .setConnectionEndPoint(ceps)
646             .setOperationalState(OperationalState.DISABLED)
647             .setLayerProtocolName(topPortocol)
648             .setLifecycleState(LifecycleState.POTENTIALAVAILABLE)
649             .setDirection(ForwardingDirection.BIDIRECTIONAL)
650             .build();
651     }
652
653     private org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.connectivity.rev181210.connectivity.context.Connection
654             createXCBetweenCeps(ConnectionEndPoint cep1, ConnectionEndPoint cep2, String tp1, String tp2, String qual,
655                         LayerProtocolName xcProtocol) {
656         LOG.info("Creation cross connection between: {} and {}", tp1, tp2);
657         LOG.info("Cross connection name = {}", String.join("+", "XC", tp1, tp2, qual));
658         LOG.info("CEP1 = {}", cep1.getClientNodeEdgePoint().toString());
659         LOG.info("CEP2 = {}", cep2.getClientNodeEdgePoint().toString());
660         org.opendaylight.yang.gen.v1.urn
661             .onf.otcc.yang.tapi.connectivity.rev181210.connection.ConnectionEndPoint cepServ1 =
662             new org.opendaylight.yang.gen.v1.urn
663                 .onf.otcc.yang.tapi.connectivity.rev181210.connection.ConnectionEndPointBuilder()
664                 .setNodeEdgePointUuid(cep1.getClientNodeEdgePoint()
665                     .values().stream().findFirst().get().getNodeEdgePointUuid())
666                 .setTopologyUuid(cep1.getClientNodeEdgePoint()
667                     .values().stream().findFirst().get().getTopologyUuid())
668                 .setNodeUuid(cep1.getClientNodeEdgePoint()
669                     .values().stream().findFirst().get().getNodeUuid())
670                 .setConnectionEndPointUuid(cep1.getUuid())
671                 .build();
672         org.opendaylight.yang.gen.v1.urn
673             .onf.otcc.yang.tapi.connectivity.rev181210.connection.ConnectionEndPoint cepServ2 =
674             new org.opendaylight.yang.gen.v1.urn
675                 .onf.otcc.yang.tapi.connectivity.rev181210.connection.ConnectionEndPointBuilder()
676                 .setNodeEdgePointUuid(cep2.getClientNodeEdgePoint()
677                     .values().stream().findFirst().get().getNodeEdgePointUuid())
678                 .setTopologyUuid(cep2.getClientNodeEdgePoint()
679                     .values().stream().findFirst().get().getTopologyUuid())
680                 .setNodeUuid(cep2.getClientNodeEdgePoint()
681                     .values().stream().findFirst().get().getNodeUuid())
682                 .setConnectionEndPointUuid(cep2.getUuid())
683                 .build();
684         Map<ConnectionEndPointKey, org.opendaylight.yang.gen.v1.urn
685             .onf.otcc.yang.tapi.connectivity.rev181210.connection.ConnectionEndPoint> ceps = new HashMap<>();
686         ceps.put(cepServ1.key(), cepServ1);
687         ceps.put(cepServ2.key(), cepServ2);
688         Name connName = new NameBuilder()
689             .setValueName("Connection name")
690             .setValue(String.join("+", "XC", tp1, tp2, qual))
691             .build();
692         // TODO: lower connection, supported link.......
693         return new org.opendaylight.yang.gen.v1.urn
694             .onf.otcc.yang.tapi.connectivity.rev181210.connectivity.context.ConnectionBuilder()
695             .setUuid(new Uuid(UUID.nameUUIDFromBytes((String.join("+", "XC", tp1, tp2, qual))
696                 .getBytes(Charset.forName("UTF-8"))).toString()))
697             .setName(Map.of(connName.key(), connName))
698             .setConnectionEndPoint(ceps)
699             .setOperationalState(OperationalState.DISABLED)
700             .setLayerProtocolName(xcProtocol)
701             .setLifecycleState(LifecycleState.POTENTIALAVAILABLE)
702             .setDirection(ForwardingDirection.BIDIRECTIONAL)
703             .build();
704     }
705
706     private ConnectionEndPoint createCepRoadm(String id, String qualifier) {
707         LOG.info("NEP = {}", String.join("+", id.split("\\+")[0], qualifier, id.split("\\+")[1]));
708         Name cepName = new NameBuilder()
709             .setValueName("ConnectionEndPoint name")
710             .setValue(String.join("+", id.split("\\+")[0], qualifier,
711                 id.split("\\+")[1]))
712             .build();
713         ClientNodeEdgePoint cnep = new ClientNodeEdgePointBuilder()
714             .setNodeEdgePointUuid(new Uuid(UUID.nameUUIDFromBytes((String.join("+", id.split("\\+")[0],
715                 qualifier, id.split("\\+")[1])).getBytes(Charset.forName("UTF-8")))
716                 .toString()))
717             .setNodeUuid(new Uuid(UUID.nameUUIDFromBytes((String.join("+",id.split("\\+")[0],
718                 qualifier)).getBytes(Charset.forName("UTF-8")))
719                 .toString()))
720             .setTopologyUuid(new Uuid(UUID.nameUUIDFromBytes(TopologyUtils.T0_FULL_MULTILAYER
721                 .getBytes(Charset.forName("UTF-8"))).toString()))
722             .build();
723         // TODO: add augmentation with the corresponding cep-spec (i.e. MC, OTSiMC...)
724         // TODO: add parent ONEP??
725         ConnectionEndPointBuilder cepBldr = new ConnectionEndPointBuilder()
726             .setUuid(new Uuid(UUID.nameUUIDFromBytes((String.join("+", "CEP", id.split("\\+")[0],
727                 qualifier, id.split("\\+")[1])).getBytes(Charset.forName("UTF-8")))
728                 .toString()))
729             .setClientNodeEdgePoint(Map.of(cnep.key(), cnep))
730             .setName(Map.of(cepName.key(), cepName))
731             .setConnectionPortRole(PortRole.SYMMETRIC)
732             .setConnectionPortDirection(PortDirection.BIDIRECTIONAL)
733             .setOperationalState(OperationalState.ENABLED)
734             .setLifecycleState(LifecycleState.INSTALLED)
735             .setLayerProtocolName(LayerProtocolName.PHOTONICMEDIA);
736         return cepBldr.build();
737     }
738
739     private ConnectionEndPoint createCepXpdr(String id, String qualifier, String nodeLayer,
740                                              LayerProtocolName cepProtocol) {
741         Name cepName = new NameBuilder()
742             .setValueName("ConnectionEndPoint name")
743             .setValue(String.join("+", id.split("\\+")[0], qualifier,
744                 id.split("\\+")[1]))
745             .build();
746         ClientNodeEdgePoint cnep = new ClientNodeEdgePointBuilder()
747             .setNodeEdgePointUuid(new Uuid(UUID.nameUUIDFromBytes((String.join("+", id.split("\\+")[0],
748                 qualifier, id.split("\\+")[1])).getBytes(Charset.forName("UTF-8")))
749                 .toString()))
750             .setNodeUuid(new Uuid(UUID.nameUUIDFromBytes((String.join("+",id.split("\\+")[0],
751                 nodeLayer)).getBytes(Charset.forName("UTF-8")))
752                 .toString()))
753             .setTopologyUuid(new Uuid(UUID.nameUUIDFromBytes(TopologyUtils.T0_FULL_MULTILAYER
754                 .getBytes(Charset.forName("UTF-8"))).toString()))
755             .build();
756         // TODO: add augmentation with the corresponding cep-spec (i.e. MC, OTSiMC...)
757         // TODO: add parent ONEP??
758         ConnectionEndPointBuilder cepBldr = new ConnectionEndPointBuilder()
759             .setUuid(new Uuid(UUID.nameUUIDFromBytes((String.join("+", "CEP", id.split("\\+")[0],
760                 qualifier, id.split("\\+")[1])).getBytes(Charset.forName("UTF-8")))
761                 .toString()))
762             .setClientNodeEdgePoint(Map.of(cnep.key(), cnep))
763             .setName(Map.of(cepName.key(), cepName))
764             .setConnectionPortRole(PortRole.SYMMETRIC)
765             .setConnectionPortDirection(PortDirection.BIDIRECTIONAL)
766             .setOperationalState(OperationalState.ENABLED)
767             .setLifecycleState(LifecycleState.INSTALLED)
768             .setLayerProtocolName(cepProtocol);
769         return cepBldr.build();
770     }
771
772     private void putRdmCepInTopologyContext(String node, String spcRdmAD, String qual, ConnectionEndPoint cep) {
773         LOG.info("NEP id before Merge = {}", String.join("+", node, qual, spcRdmAD.split("\\+")[1]));
774         LOG.info("Node of NEP id before Merge = {}", String.join("+", node, PHTNC_MEDIA));
775         // Give uuids so that it is easier to look for things: topology uuid, node uuid, nep uuid, cep
776         Uuid topoUuid = new Uuid(UUID.nameUUIDFromBytes(TopologyUtils.T0_FULL_MULTILAYER
777             .getBytes(Charset.forName("UTF-8"))).toString());
778         Uuid nodeUuid = new Uuid(UUID.nameUUIDFromBytes(String.join("+", node, PHTNC_MEDIA)
779             .getBytes(Charset.forName("UTF-8"))).toString());
780         Uuid nepUuid = new Uuid(UUID.nameUUIDFromBytes(String.join("+", node, qual, spcRdmAD.split("\\+")[1])
781             .getBytes(Charset.forName("UTF-8"))).toString());
782         updateTopologyWithCep(topoUuid, nodeUuid, nepUuid, cep);
783     }
784
785     private void putXpdrCepInTopologyContext(String node, String spcXpdrNet, String qual, String nodeLayer,
786                                              ConnectionEndPoint cep) {
787         // Give uuids so that it is easier to look for things: topology uuid, node uuid, nep uuid, cep
788         Uuid topoUuid = new Uuid(UUID.nameUUIDFromBytes(TopologyUtils.T0_FULL_MULTILAYER
789             .getBytes(Charset.forName("UTF-8"))).toString());
790         Uuid nodeUuid = new Uuid(UUID.nameUUIDFromBytes(String.join("+", node, nodeLayer)
791             .getBytes(Charset.forName("UTF-8"))).toString());
792         Uuid nepUuid = new Uuid(UUID.nameUUIDFromBytes(String.join("+", node, qual, spcXpdrNet.split("\\+")[1])
793             .getBytes(Charset.forName("UTF-8"))).toString());
794         updateTopologyWithCep(topoUuid, nodeUuid, nepUuid, cep);
795     }
796
797     public void updateTopologyWithCep(Uuid topoUuid, Uuid nodeUuid, Uuid nepUuid, ConnectionEndPoint cep) {
798         // TODO: verify this is correct. Should we identify the context IID with the context UUID??
799         InstanceIdentifier<OwnedNodeEdgePoint> onepIID = InstanceIdentifier.builder(Context.class)
800             .augmentation(org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.topology.rev181210.Context1.class)
801             .child(org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.topology.rev181210.context.TopologyContext.class)
802             .child(Topology.class, new TopologyKey(topoUuid))
803             .child(org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.topology.rev181210.topology.Node.class,
804                 new NodeKey(nodeUuid))
805             .child(OwnedNodeEdgePoint.class, new OwnedNodeEdgePointKey(nepUuid))
806             .build();
807         try {
808             Optional<OwnedNodeEdgePoint> optionalOnep = this.networkTransactionService.read(
809                 LogicalDatastoreType.OPERATIONAL, onepIID).get();
810             if (!optionalOnep.isPresent()) {
811                 LOG.error("ONEP is not present in datastore");
812                 return;
813             }
814             OwnedNodeEdgePoint onep = optionalOnep.get();
815             LOG.info("ONEP found = {}", onep.toString());
816             // TODO -> If cep exists -> skip merging to datasore
817             OwnedNodeEdgePoint1 onep1 = onep.augmentation(OwnedNodeEdgePoint1.class);
818             if (onep1 != null && onep1.getCepList() != null && onep1.getCepList().getConnectionEndPoint() != null) {
819                 if (onep1.getCepList().getConnectionEndPoint().containsKey(
820                     new org.opendaylight.yang.gen.v1
821                         .urn.onf.otcc.yang.tapi.connectivity.rev181210.cep.list.ConnectionEndPointKey(cep.key()))) {
822                     LOG.info("CEP already in topology, skipping merge");
823                     return;
824                 }
825             }
826             // Updated ONEP
827             CepList cepList = new CepListBuilder().setConnectionEndPoint(Map.of(cep.key(), cep)).build();
828             OwnedNodeEdgePoint1 onep1Bldr = new OwnedNodeEdgePoint1Builder().setCepList(cepList).build();
829             OwnedNodeEdgePoint newOnep = new OwnedNodeEdgePointBuilder(onep)
830                 .addAugmentation(onep1Bldr)
831                 .build();
832             LOG.info("New ONEP is {}", newOnep.toString());
833             // merge in datastore
834             this.networkTransactionService.merge(LogicalDatastoreType.OPERATIONAL, onepIID,
835                 newOnep);
836             this.networkTransactionService.commit().get();
837             LOG.info("CEP added successfully.");
838         } catch (InterruptedException | ExecutionException e) {
839             LOG.error("Couldnt update cep in topology", e);
840         }
841     }
842
843     private void updateConnectionContextWithConn(
844             Map<org.opendaylight.yang.gen.v1.urn
845                 .onf.otcc.yang.tapi.connectivity.rev181210.connectivity.context.ConnectionKey,
846                 org.opendaylight.yang.gen.v1.urn
847                     .onf.otcc.yang.tapi.connectivity.rev181210.connectivity.context.Connection> connFullMap,
848             Map<ConnectionKey, Connection> connMap, Uuid suuid) {
849         // TODO: verify this is correct. Should we identify the context IID with the context UUID??
850         try {
851             ConnectivityService connServ = getConnectivityService(suuid);
852             ConnectivityService updtConnServ = new ConnectivityServiceBuilder(connServ)
853                     .setConnection(connMap)
854                     .build();
855
856             // Perform the merge operation with the new conn service and the connection context updated
857             org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.connectivity.rev181210.context.ConnectivityContext
858                     connectivityContext = new ConnectivityContextBuilder()
859                     .setConnectivityService(Map.of(updtConnServ.key(), updtConnServ))
860                     .setConnection(connFullMap)
861                     .build();
862             InstanceIdentifier<org.opendaylight.yang.gen.v1.urn
863                     .onf.otcc.yang.tapi.connectivity.rev181210.context.ConnectivityContext> connectivitycontextIID =
864                     InstanceIdentifier.builder(Context.class).augmentation(Context1.class)
865                             .child(org.opendaylight.yang.gen.v1.urn
866                                     .onf.otcc.yang.tapi.connectivity.rev181210.context.ConnectivityContext.class)
867                             .build();
868             // merge in datastore
869             this.networkTransactionService.merge(LogicalDatastoreType.OPERATIONAL, connectivitycontextIID,
870                     connectivityContext);
871             this.networkTransactionService.commit().get();
872             LOG.info("TAPI connectivity merged successfully.");
873         } catch (InterruptedException | ExecutionException e) {
874             LOG.error("Failed to merge TAPI connectivity", e);
875         }
876     }
877
878     private ConnectivityService getConnectivityService(Uuid suuid) {
879         try {
880         // First read connectivity service with service uuid and update info
881             InstanceIdentifier<ConnectivityService> connectivityServIID =
882                 InstanceIdentifier.builder(Context.class).augmentation(Context1.class)
883                         .child(org.opendaylight.yang.gen.v1.urn
884                                 .onf.otcc.yang.tapi.connectivity.rev181210.context.ConnectivityContext.class)
885                         .child(ConnectivityService.class, new ConnectivityServiceKey(suuid))
886                         .build();
887
888             Optional<ConnectivityService> optConnServ =
889                 this.networkTransactionService.read(LogicalDatastoreType.OPERATIONAL, connectivityServIID).get();
890             if (!optConnServ.isPresent()) {
891                 LOG.error("Connectivity service not found in tapi context");
892                 return null;
893             }
894             return optConnServ.get();
895         } catch (InterruptedException | ExecutionException e) {
896             LOG.error("Connectivity service not found in tapi context. Error:", e);
897             return null;
898         }
899     }
900
901     private void deleteConnectivityService(Uuid suuid) {
902         // First read connectivity service with service uuid and update info
903         InstanceIdentifier<ConnectivityService> connectivityServIID =
904                 InstanceIdentifier.builder(Context.class).augmentation(Context1.class)
905                         .child(org.opendaylight.yang.gen.v1.urn
906                                 .onf.otcc.yang.tapi.connectivity.rev181210.context.ConnectivityContext.class)
907                         .child(ConnectivityService.class, new ConnectivityServiceKey(suuid))
908                         .build();
909         try {
910             this.networkTransactionService.delete(LogicalDatastoreType.OPERATIONAL, connectivityServIID);
911             this.networkTransactionService.commit().get();
912         } catch (InterruptedException | ExecutionException e) {
913             LOG.error("Failed to delete TAPI connectivity service", e);
914         }
915     }
916
917     private void deleteConnection(Uuid connectionUuid) {
918         // First read connectivity service with service uuid and update info
919         InstanceIdentifier<org.opendaylight.yang.gen.v1
920                 .urn.onf.otcc.yang.tapi.connectivity.rev181210.connectivity.context.Connection> connectionIID =
921                 InstanceIdentifier.builder(Context.class).augmentation(Context1.class)
922                         .child(org.opendaylight.yang.gen.v1.urn
923                                 .onf.otcc.yang.tapi.connectivity.rev181210.context.ConnectivityContext.class)
924                         .child(org.opendaylight.yang.gen.v1.urn
925                                 .onf.otcc.yang.tapi.connectivity.rev181210.connectivity.context.Connection.class,
926                                 new org.opendaylight.yang.gen.v1.urn
927                                         .onf.otcc.yang.tapi.connectivity.rev181210.connectivity.context.ConnectionKey(
928                                                 connectionUuid))
929                         .build();
930         try {
931             this.networkTransactionService.delete(LogicalDatastoreType.OPERATIONAL, connectionIID);
932             this.networkTransactionService.commit().get();
933         } catch (InterruptedException | ExecutionException e) {
934             LOG.error("Failed to delete TAPI connection", e);
935         }
936     }
937
938     private String getIdBasedOnModelVersion(String nodeid) {
939         return nodeid.matches("[A-Z]{5}-[A-Z0-9]{2}-.*")
940             ? String.join("-", nodeid.split("-")[0], nodeid.split("-")[1]) : nodeid.split("-")[0];
941     }
942
943     public void setInput(CreateConnectivityServiceInput input) {
944         this.input = input;
945     }
946
947     public void setServiceUuid(Uuid serviceUuid) {
948         this.serviceUuid = serviceUuid;
949     }
950 }