d0f7880415068e409b62648192b31ea24c501478
[transportpce.git] / tapi / src / main / java / org / opendaylight / transportpce / tapi / connectivity / ConnectivityUtils.java
1 /*
2  * Copyright © 2018 Orange & 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.connectivity;
9
10 import java.math.BigDecimal;
11 import java.nio.charset.StandardCharsets;
12 import java.util.ArrayList;
13 import java.util.Collection;
14 import java.util.Comparator;
15 import java.util.HashMap;
16 import java.util.List;
17 import java.util.Map;
18 import java.util.Optional;
19 import java.util.UUID;
20 import java.util.concurrent.ExecutionException;
21 import java.util.stream.Collectors;
22 import org.opendaylight.mdsal.common.api.LogicalDatastoreType;
23 import org.opendaylight.transportpce.common.network.NetworkTransactionService;
24 import org.opendaylight.transportpce.servicehandler.service.ServiceDataStoreOperations;
25 import org.opendaylight.transportpce.tapi.TapiStringConstants;
26 import org.opendaylight.transportpce.tapi.utils.GenericServiceEndpoint;
27 import org.opendaylight.transportpce.tapi.utils.ServiceEndpointType;
28 import org.opendaylight.transportpce.tapi.utils.TapiContext;
29 import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.portmapping.rev220922.Network;
30 import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.portmapping.rev220922.mapping.Mapping;
31 import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.portmapping.rev220922.mapping.MappingKey;
32 import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.portmapping.rev220922.network.Nodes;
33 import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.portmapping.rev220922.network.NodesKey;
34 import org.opendaylight.yang.gen.v1.http.org.openroadm.common.equipment.types.rev191129.OpticTypes;
35 import org.opendaylight.yang.gen.v1.http.org.openroadm.common.node.types.rev210528.NodeIdType;
36 import org.opendaylight.yang.gen.v1.http.org.openroadm.common.service.types.rev230526.ConnectionType;
37 import org.opendaylight.yang.gen.v1.http.org.openroadm.common.service.types.rev230526.RpcActions;
38 import org.opendaylight.yang.gen.v1.http.org.openroadm.common.service.types.rev230526.Service;
39 import org.opendaylight.yang.gen.v1.http.org.openroadm.common.service.types.rev230526.ethernet.subrate.attributes.grp.EthernetAttributesBuilder;
40 import org.opendaylight.yang.gen.v1.http.org.openroadm.common.service.types.rev230526.sdnc.request.header.SdncRequestHeaderBuilder;
41 import org.opendaylight.yang.gen.v1.http.org.openroadm.common.service.types.rev230526.service.endpoint.RxDirectionBuilder;
42 import org.opendaylight.yang.gen.v1.http.org.openroadm.common.service.types.rev230526.service.endpoint.RxDirectionKey;
43 import org.opendaylight.yang.gen.v1.http.org.openroadm.common.service.types.rev230526.service.endpoint.TxDirectionBuilder;
44 import org.opendaylight.yang.gen.v1.http.org.openroadm.common.service.types.rev230526.service.endpoint.TxDirectionKey;
45 import org.opendaylight.yang.gen.v1.http.org.openroadm.common.service.types.rev230526.service.lgx.LgxBuilder;
46 import org.opendaylight.yang.gen.v1.http.org.openroadm.common.service.types.rev230526.service.port.PortBuilder;
47 import org.opendaylight.yang.gen.v1.http.org.openroadm.common.service.types.rev230526.subrate.eth.sla.SubrateEthSlaBuilder;
48 import org.opendaylight.yang.gen.v1.http.org.openroadm.network.types.rev230526.OpenroadmNodeType;
49 import org.opendaylight.yang.gen.v1.http.org.openroadm.otn.common.types.rev210924.ODU4;
50 import org.opendaylight.yang.gen.v1.http.org.openroadm.otn.common.types.rev210924.OTU4;
51 import org.opendaylight.yang.gen.v1.http.org.openroadm.service.format.rev191129.ServiceFormat;
52 import org.opendaylight.yang.gen.v1.http.org.openroadm.service.rev230526.ServiceCreateInput;
53 import org.opendaylight.yang.gen.v1.http.org.openroadm.service.rev230526.ServiceCreateInputBuilder;
54 import org.opendaylight.yang.gen.v1.http.org.openroadm.service.rev230526.service.create.input.ServiceAEnd;
55 import org.opendaylight.yang.gen.v1.http.org.openroadm.service.rev230526.service.create.input.ServiceAEndBuilder;
56 import org.opendaylight.yang.gen.v1.http.org.openroadm.service.rev230526.service.create.input.ServiceZEnd;
57 import org.opendaylight.yang.gen.v1.http.org.openroadm.service.rev230526.service.create.input.ServiceZEndBuilder;
58 import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.pathdescription.rev230501.PathDescription;
59 import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.pathdescription.rev230501.path.description.atoz.direction.AToZ;
60 import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.pathdescription.rev230501.path.description.atoz.direction.AToZKey;
61 import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.pathdescription.rev230501.path.description.ztoa.direction.ZToA;
62 import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.pathdescription.rev230501.path.description.ztoa.direction.ZToAKey;
63 import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.pathdescription.rev230501.pce.resource.resource.resource.Node;
64 import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.pathdescription.rev230501.pce.resource.resource.resource.TerminationPoint;
65 import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.servicepath.rev171017.service.path.list.ServicePaths;
66 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.DateAndTime;
67 import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.common.rev221121.AdministrativeState;
68 import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.common.rev221121.CAPACITYUNITGBPS;
69 import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.common.rev221121.Context;
70 import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.common.rev221121.Direction;
71 import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.common.rev221121.ForwardingDirection;
72 import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.common.rev221121.LayerProtocolName;
73 import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.common.rev221121.LifecycleState;
74 import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.common.rev221121.OperationalState;
75 import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.common.rev221121.PortRole;
76 import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.common.rev221121.Uuid;
77 import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.common.rev221121.capacity.TotalSizeBuilder;
78 import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.common.rev221121.global._class.Name;
79 import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.common.rev221121.global._class.NameBuilder;
80 import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.common.rev221121.global._class.NameKey;
81 import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.common.rev221121.tapi.context.ServiceInterfacePoint;
82 import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.common.rev221121.tapi.context.ServiceInterfacePointKey;
83 import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.connectivity.rev221121.CreateConnectivityServiceInput;
84 import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.connectivity.rev221121.ProtectionRole;
85 import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.connectivity.rev221121.ServiceType;
86 import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.connectivity.rev221121.cep.list.ConnectionEndPoint;
87 import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.connectivity.rev221121.cep.list.ConnectionEndPointBuilder;
88 import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.connectivity.rev221121.connection.ConnectionEndPointKey;
89 import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.connectivity.rev221121.connection.LowerConnection;
90 import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.connectivity.rev221121.connection.LowerConnectionBuilder;
91 import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.connectivity.rev221121.connection.LowerConnectionKey;
92 import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.connectivity.rev221121.connection.end.point.ClientNodeEdgePoint;
93 import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.connectivity.rev221121.connection.end.point.ClientNodeEdgePointBuilder;
94 import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.connectivity.rev221121.connectivity.context.ConnectivityService;
95 import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.connectivity.rev221121.connectivity.context.ConnectivityServiceBuilder;
96 import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.connectivity.rev221121.connectivity.service.Connection;
97 import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.connectivity.rev221121.connectivity.service.ConnectionBuilder;
98 import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.connectivity.rev221121.connectivity.service.ConnectionKey;
99 import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.connectivity.rev221121.connectivity.service.ConnectivityConstraint;
100 import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.connectivity.rev221121.connectivity.service.ConnectivityConstraintBuilder;
101 import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.connectivity.rev221121.connectivity.service.EndPoint;
102 import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.connectivity.rev221121.connectivity.service.EndPointBuilder;
103 import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.connectivity.rev221121.connectivity.service.EndPointKey;
104 import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.connectivity.rev221121.connectivity.service.end.point.CapacityBuilder;
105 import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.connectivity.rev221121.connectivity.service.end.point.ServiceInterfacePointBuilder;
106 import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.topology.rev221121.context.TopologyContext;
107 import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.topology.rev221121.node.OwnedNodeEdgePoint;
108 import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.topology.rev221121.node.edge.point.MappedServiceInterfacePointKey;
109 import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.topology.rev221121.topology.NodeKey;
110 import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.topology.rev221121.topology.context.Topology;
111 import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.topology.rev221121.topology.context.TopologyKey;
112 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
113 import org.opendaylight.yangtools.yang.common.Decimal64;
114 import org.opendaylight.yangtools.yang.common.Uint16;
115 import org.opendaylight.yangtools.yang.common.Uint32;
116 import org.opendaylight.yangtools.yang.common.Uint64;
117 import org.opendaylight.yangtools.yang.common.Uint8;
118 import org.slf4j.Logger;
119 import org.slf4j.LoggerFactory;
120
121 public final class ConnectivityUtils {
122
123     private final Uuid tapiTopoUuid = new Uuid(UUID.nameUUIDFromBytes(TapiStringConstants.T0_FULL_MULTILAYER
124         .getBytes(StandardCharsets.UTF_8)).toString());
125     private static final Logger LOG = LoggerFactory.getLogger(ConnectivityUtils.class);
126
127     private final ServiceDataStoreOperations serviceDataStoreOperations;
128     private final TapiContext tapiContext;
129     private Map<ServiceInterfacePointKey, ServiceInterfacePoint> sipMap;
130     private final Map<org.opendaylight.yang.gen.v1.urn
131         .onf.otcc.yang.tapi.connectivity.rev221121.connectivity.context.ConnectionKey,
132         org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.connectivity.rev221121.connectivity.context.Connection>
133         connectionFullMap; // this variable is for complete connection objects
134     private final NetworkTransactionService networkTransactionService;
135     private Connection topConnRdmRdm;
136     private Connection topConnXpdrXpdrPhtn;
137     private Connection topConnXpdrXpdrOdu;
138
139     // TODO -> handle cases for which node id is ROADM-A1 and not ROADMA01 or XPDR-A1 and not XPDRA01
140     public ConnectivityUtils(ServiceDataStoreOperations serviceDataStoreOperations,
141                              Map<ServiceInterfacePointKey, ServiceInterfacePoint> sipMap, TapiContext tapiContext,
142                              NetworkTransactionService networkTransactionService) {
143         this.serviceDataStoreOperations = serviceDataStoreOperations;
144         this.tapiContext = tapiContext;
145         this.sipMap = sipMap;
146         this.connectionFullMap = new HashMap<>();
147         this.networkTransactionService = networkTransactionService;
148         this.topConnRdmRdm = null;
149         this.topConnXpdrXpdrPhtn = null;
150         this.topConnXpdrXpdrOdu = null;
151     }
152
153     public static ServiceCreateInput buildServiceCreateInput(GenericServiceEndpoint sepA, GenericServiceEndpoint sepZ) {
154         ServiceAEnd serviceAEnd = getServiceAEnd(sepA, sepZ);
155         ServiceZEnd serviceZEnd = getServiceZEnd(sepA, sepZ);
156         if (serviceAEnd == null || serviceZEnd == null) {
157             LOG.warn("One of the endpoints could not be identified");
158             return null;
159         }
160         return new ServiceCreateInputBuilder()
161             .setCommonId("commonId")
162             .setConnectionType(ConnectionType.Service)
163             .setCustomer("Customer")
164             .setServiceName("service test")
165             .setServiceAEnd(serviceAEnd)
166             .setServiceZEnd(serviceZEnd)
167             .setSdncRequestHeader(new SdncRequestHeaderBuilder().setRequestId("request-1")
168                 .setRpcAction(RpcActions.ServiceCreate).setNotificationUrl("notification url").setRequestSystemId(
169                     "appname")
170                 .build())
171             .build();
172     }
173
174     public static ServiceAEnd buildServiceAEnd(String nodeid, String clli, String txPortDeviceName,
175                                                String txPortName, String rxPortDeviceName, String rxPortName) {
176         return new ServiceAEndBuilder()
177             .setClli(clli)
178             .setNodeId(new NodeIdType(nodeid))
179             .setOpticType(OpticTypes.Gray)
180             .setServiceFormat(ServiceFormat.Ethernet)
181             .setServiceRate(Uint32.valueOf(100))
182             .setTxDirection(Map.of(new TxDirectionKey(Uint8.ZERO), new TxDirectionBuilder()
183                 .setPort(new PortBuilder()
184                     .setPortDeviceName(txPortDeviceName)
185                     .setPortName(txPortName)
186                     .setPortRack(TapiStringConstants.PORT_RACK_VALUE)
187                     .setPortShelf("00")
188                     .setPortType(TapiStringConstants.PORT_TYPE)
189                     .build())
190                 .setLgx(new LgxBuilder()
191                     .setLgxDeviceName(TapiStringConstants.LGX_DEVICE_NAME)
192                     .setLgxPortName(TapiStringConstants.LGX_PORT_NAME)
193                     .setLgxPortRack(TapiStringConstants.PORT_RACK_VALUE)
194                     .setLgxPortShelf("00")
195                     .build())
196                 .build()))
197             .setRxDirection(Map.of(new RxDirectionKey(Uint8.ZERO), new RxDirectionBuilder()
198                 .setPort(new PortBuilder()
199                     .setPortDeviceName(rxPortDeviceName)
200                     .setPortName(rxPortName)
201                     .setPortRack(TapiStringConstants.PORT_RACK_VALUE)
202                     .setPortShelf("00")
203                     .setPortType(TapiStringConstants.PORT_TYPE)
204                     .build())
205                 .setLgx(new LgxBuilder()
206                     .setLgxDeviceName(TapiStringConstants.LGX_DEVICE_NAME)
207                     .setLgxPortName(TapiStringConstants.LGX_PORT_NAME)
208                     .setLgxPortRack(TapiStringConstants.PORT_RACK_VALUE)
209                     .setLgxPortShelf("00")
210                     .build())
211                 .build()))
212             .build();
213     }
214
215     public static ServiceZEnd buildServiceZEnd(String nodeid, String clli, String txPortDeviceName,
216                                                String txPortName, String rxPortDeviceName, String rxPortName) {
217         return  new ServiceZEndBuilder().setClli(clli).setNodeId(new NodeIdType(nodeid))
218             .setOpticType(OpticTypes.Gray)
219             .setServiceFormat(ServiceFormat.Ethernet)
220             .setServiceRate(Uint32.valueOf(100))
221             .setTxDirection(Map.of(new TxDirectionKey(Uint8.ZERO), new TxDirectionBuilder()
222                 .setPort(new PortBuilder()
223                     .setPortDeviceName(txPortDeviceName)
224                     .setPortName(txPortName)
225                     .setPortRack(TapiStringConstants.PORT_RACK_VALUE)
226                     .setPortShelf("00")
227                     .setPortType(TapiStringConstants.PORT_TYPE)
228                     .build())
229                 .setLgx(new LgxBuilder()
230                     .setLgxDeviceName(TapiStringConstants.LGX_DEVICE_NAME)
231                     .setLgxPortName(TapiStringConstants.LGX_PORT_NAME)
232                     .setLgxPortRack(TapiStringConstants.PORT_RACK_VALUE)
233                     .setLgxPortShelf("00")
234                     .build())
235                 .build()))
236             .setRxDirection(Map.of(new RxDirectionKey(Uint8.ZERO), new RxDirectionBuilder()
237                 .setPort(new PortBuilder()
238                     .setPortDeviceName(rxPortDeviceName)
239                     .setPortName(rxPortName)
240                     .setPortRack(TapiStringConstants.PORT_RACK_VALUE)
241                     .setPortShelf("00")
242                     .setPortType(TapiStringConstants.PORT_TYPE)
243                     .build())
244                 .setLgx(new LgxBuilder()
245                     .setLgxDeviceName(TapiStringConstants.LGX_DEVICE_NAME)
246                     .setLgxPortName(TapiStringConstants.LGX_PORT_NAME)
247                     .setLgxPortRack(TapiStringConstants.PORT_RACK_VALUE)
248                     .setLgxPortShelf("00")
249                     .build())
250                 .build()))
251             .build();
252     }
253
254     private static ServiceAEnd getServiceAEnd(GenericServiceEndpoint sepA, GenericServiceEndpoint sepZ) {
255         if (sepA.getType().equals(ServiceEndpointType.SERVICEAEND)) {
256             return new ServiceAEndBuilder(sepA.getValue()).build();
257         } else if (sepZ.getType().equals(ServiceEndpointType.SERVICEAEND)) {
258             return new ServiceAEndBuilder(sepZ.getValue()).build();
259         } else {
260             return null;
261         }
262     }
263
264     private static ServiceZEnd getServiceZEnd(GenericServiceEndpoint sepA, GenericServiceEndpoint sepZ) {
265         if (sepA.getType().equals(ServiceEndpointType.SERVICEZEND)) {
266             return new ServiceZEndBuilder(sepA.getValue()).build();
267         } else if (sepZ.getType().equals(ServiceEndpointType.SERVICEZEND)) {
268             return new ServiceZEndBuilder(sepZ.getValue()).build();
269         } else {
270             return null;
271         }
272     }
273
274     public void setSipMap(Map<ServiceInterfacePointKey, ServiceInterfacePoint> sips) {
275         this.sipMap = sips;
276     }
277
278     public ConnectivityService mapORServiceToTapiConnectivity(Service service) {
279         // Get service path with the description in OR based models.
280         LOG.info("Service = {}", service);
281         Optional<ServicePaths> optServicePaths =
282             this.serviceDataStoreOperations.getServicePath(service.getServiceName());
283         if (!optServicePaths.isPresent()) {
284             LOG.error("No service path found for service {}", service.getServiceName());
285             return null;
286         }
287         ServicePaths servicePaths = optServicePaths.orElseThrow();
288         PathDescription pathDescription = servicePaths.getPathDescription();
289         LOG.info("Path description of service = {}", pathDescription);
290         org.opendaylight.yang.gen.v1.http.org.openroadm.common.service.types.rev230526.service.ServiceAEnd serviceAEnd
291             = service.getServiceAEnd();
292         // Endpoint creation
293         EndPoint endPoint1 = mapServiceAEndPoint(serviceAEnd, pathDescription);
294         org.opendaylight.yang.gen.v1.http.org.openroadm.common.service.types.rev230526.service.ServiceZEnd serviceZEnd
295             = service.getServiceZEnd();
296         EndPoint endPoint2 = mapServiceZEndPoint(serviceZEnd, pathDescription);
297         Map<EndPointKey, EndPoint> endPointMap = new HashMap<>();
298         endPointMap.put(endPoint1.key(), endPoint1);
299         endPointMap.put(endPoint2.key(), endPoint2);
300         LOG.info("EndPoints of connectivity services = {}", endPointMap);
301         // Services Names
302         Name name = new NameBuilder().setValueName("Connectivity Service Name").setValue(service.getServiceName())
303             .build();
304         // Connection creation
305         Map<ConnectionKey, Connection> connMap =
306             createConnectionsFromService(serviceAEnd, serviceZEnd, pathDescription);
307         ConnectivityConstraint conConstr = new ConnectivityConstraintBuilder()
308             .setServiceType(ServiceType.POINTTOPOINTCONNECTIVITY).build();
309         // TODO: full connectivity service?? With constraints and the rest of fields...
310         return new ConnectivityServiceBuilder()
311             .setAdministrativeState(AdministrativeState.UNLOCKED)
312             .setOperationalState(OperationalState.ENABLED)
313             .setLifecycleState(LifecycleState.INSTALLED)
314             .setUuid(new Uuid(UUID.nameUUIDFromBytes(service.getServiceName().getBytes(StandardCharsets.UTF_8))
315                 .toString()))
316             .setLayerProtocolName(mapServiceLayer(serviceAEnd.getServiceFormat(), endPoint1, endPoint2))
317             .setConnectivityConstraint(conConstr)
318             .setDirection(ForwardingDirection.BIDIRECTIONAL)
319             .setName(Map.of(name.key(), name))
320             .setConnection(connMap)
321             .setEndPoint(endPointMap)
322             .build();
323     }
324
325     private LayerProtocolName mapServiceLayer(ServiceFormat serviceFormat, EndPoint endPoint1, EndPoint endPoint2) {
326         switch (serviceFormat) {
327             case OC:
328             case OTU:
329                 return LayerProtocolName.PHOTONICMEDIA;
330             case ODU:
331                 return LayerProtocolName.ODU;
332             case Ethernet:
333                 String node1 = endPoint1.getLocalId();
334                 String node2 = endPoint2.getLocalId();
335                 if (getOpenroadmType(node1).equals(OpenroadmNodeType.TPDR)
336                         && getOpenroadmType(node2).equals(OpenroadmNodeType.TPDR)) {
337                     return LayerProtocolName.ETH;
338                 }
339                 return LayerProtocolName.DSR;
340             default:
341                 LOG.info("Service layer mapping not supported for {}", serviceFormat.getName());
342         }
343         return null;
344     }
345
346     private OpenroadmNodeType getOpenroadmType(String nodeName) {
347         LOG.info("Node name = {}", nodeName);
348         Uuid nodeUuid = new Uuid(UUID.nameUUIDFromBytes((String.join("+",nodeName, TapiStringConstants.DSR))
349             .getBytes(StandardCharsets.UTF_8)).toString());
350         org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.topology.rev221121.topology.Node tapiNode
351             = this.tapiContext.getTapiNode(this.tapiTopoUuid, nodeUuid);
352         if (tapiNode != null) {
353             return OpenroadmNodeType.forName(tapiNode.getName().get(new NameKey("Node Type"))
354                 .getValue());
355         }
356         return null;
357     }
358
359     private Map<ConnectionKey, Connection> createConnectionsFromService(
360             org.opendaylight.yang.gen.v1.http.org.openroadm.common.service.types.rev230526.service.ServiceAEnd
361                     serviceAEnd,
362             org.opendaylight.yang.gen.v1.http.org.openroadm.common.service.types.rev230526.service.ServiceZEnd
363                     serviceZEnd,
364             PathDescription pathDescription) {
365         Map<ConnectionKey, Connection> connectionServMap = new HashMap<>();
366         // build lists with ROADM nodes, XPDR/MUX/SWITCH nodes, ROADM DEG TTPs, ROADM SRG TTPs, XPDR CLIENT TTPs
367         //  and XPDR NETWORK TTPs (if any). From the path description. This will help to build the uuid of the CEPs
368         //  and the connections
369         String resourceType;
370         List<String> xpdrClientTplist = new ArrayList<>();
371         List<String> xpdrNetworkTplist = new ArrayList<>();
372         List<String> rdmAddDropTplist = new ArrayList<>();
373         List<String> rdmDegTplist = new ArrayList<>();
374         List<String> rdmNodelist = new ArrayList<>();
375         List<String> xpdrNodelist = new ArrayList<>();
376         for (AToZ elem:pathDescription.getAToZDirection().getAToZ().values().stream()
377             .sorted((Comparator.comparing(atoz -> Integer.valueOf(atoz.getId())))).collect(Collectors.toList())) {
378             resourceType = elem.getResource().getResource().implementedInterface().getSimpleName();
379             switch (resourceType) {
380                 case TapiStringConstants.TP:
381                     TerminationPoint tp = (TerminationPoint) elem.getResource().getResource();
382                     String tpID = tp.getTpId();
383                     String tpNode;
384                     if (tpID.contains("CLIENT")) {
385                         tpNode = tp.getTpNodeId();
386                         if (!xpdrClientTplist.contains(String.join("+", tpNode, tpID))) {
387                             xpdrClientTplist.add(String.join("+", tpNode, tpID));
388                         }
389                     }
390                     if (tpID.contains("NETWORK")) {
391                         tpNode = tp.getTpNodeId();
392                         if (!xpdrNetworkTplist.contains(String.join("+", tpNode, tpID))) {
393                             xpdrNetworkTplist.add(String.join("+", tpNode, tpID));
394                         }
395                     }
396                     if (tpID.contains("PP")) {
397                         tpNode = getIdBasedOnModelVersion(tp.getTpNodeId());
398                         LOG.info("ROADM Node of tp = {}", tpNode);
399                         if (!rdmAddDropTplist.contains(String.join("+", tpNode, tpID))) {
400                             rdmAddDropTplist.add(String.join("+", tpNode, tpID));
401                         }
402                     }
403                     if (tpID.contains("TTP")) {
404                         tpNode = getIdBasedOnModelVersion(tp.getTpNodeId());
405                         LOG.info("ROADM Node of tp = {}", tpNode);
406                         if (!rdmDegTplist.contains(String.join("+", tpNode, tpID))) {
407                             rdmDegTplist.add(String.join("+", tpNode, tpID));
408                         }
409                     }
410                     break;
411                 case TapiStringConstants.NODE:
412                     Node node = (Node) elem.getResource().getResource();
413                     String nodeId = node.getNodeId();
414                     if (nodeId.contains("XPDR") || nodeId.contains("SPDR") || nodeId.contains("MXPDR")) {
415                         LOG.info("Node id = {}", nodeId);
416                         if (!xpdrNodelist.contains(nodeId)) {
417                             xpdrNodelist.add(nodeId); // should contain only 2
418                         }
419                     }
420                     if (nodeId.contains("ROADM")) {
421                         nodeId = getIdBasedOnModelVersion(nodeId);
422                         LOG.info("Node id = {}", nodeId);
423                         if (!rdmNodelist.contains(nodeId)) {
424                             rdmNodelist.add(nodeId);
425                         }
426                     }
427                     break;
428                 default:
429                     LOG.warn("Resource is a {}", resourceType);
430             }
431         }
432         LOG.info("ROADM node list = {}", rdmNodelist);
433         LOG.info("ROADM degree list = {}", rdmDegTplist);
434         LOG.info("ROADM addrop list = {}", rdmAddDropTplist);
435         LOG.info("XPDR node list = {}", xpdrNodelist);
436         LOG.info("XPDR network list = {}", xpdrNetworkTplist);
437         LOG.info("XPDR client list = {}", xpdrClientTplist);
438         // TODO -> for 10GB eth and ODU services there are no ROADMs in path description as they use the OTU link,
439         //  but for 100GB eth all is created at once. Check if the roadm list is empty to determine whether we need
440         //  to trigger all the steps or not
441         String edgeRoadm1 = "";
442         String edgeRoadm2 = "";
443         if (!rdmNodelist.isEmpty()) {
444             edgeRoadm1 = rdmNodelist.get(0);
445             edgeRoadm2 = rdmNodelist.get(rdmNodelist.size() - 1);
446             LOG.info("edgeRoadm1 = {}", edgeRoadm1);
447             LOG.info("edgeRoadm2 = {}", edgeRoadm2);
448         }
449         // create corresponding CEPs and Connections. Connections should be added to the corresponding context
450         // CEPs must be included in the topology context as an augmentation for each ONEP!!
451         ServiceFormat serviceFormat = serviceAEnd.getServiceFormat(); // should be equal to serviceZEnd
452         // TODO -> Maybe we dont need to create the connections and ceps if the previous service doesnt exist??
453         //  As mentioned above, for 100GbE service creation there are ROADMs in the path description.
454         //  What are the configurations needed here? No OTU, ODU... what kind of cross connections is needed?
455         //  this needs to be changed
456         // TODO: OpenROADM getNodeType from the NamesList to verify what needs to be created
457         OpenroadmNodeType openroadmNodeType = getOpenRoadmNodeType(xpdrNodelist);
458         switch (serviceFormat) {
459             case OC:
460                 // Identify number of ROADMs
461                 // - XC Connection between MC CEPs mapped from MC NEPs (within a roadm)
462                 // - XC Connection between OTSiMC CEPs mapped from OTSiMC NEPs (within a roadm)
463                 // - Top Connection MC betwwen MC CEPs of different roadms
464                 // - Top Connection OTSiMC betwwen OTSiMC CEPs of extreme roadms
465                 connectionServMap.putAll(createRoadmCepsAndConnections(rdmAddDropTplist, rdmDegTplist, rdmNodelist,
466                     edgeRoadm1, edgeRoadm2));
467                 break;
468             case OTU:
469                 // Identify number of ROADMs between XPDRs and check if OC is created
470                 // - XC Connection between MC CEPs mapped from MC NEPs (within a roadm)
471                 // - Top Connection MC betwwen MC CEPs of different roadms
472                 // - XC Connection between OTSiMC CEPs mapped from OTSiMC NEPs (within a roadm)
473                 // - Top Connection OTSiMC betwwen OTSiMC CEPs of different roadms
474                 connectionServMap.putAll(createRoadmCepsAndConnections(rdmAddDropTplist, rdmDegTplist, rdmNodelist,
475                     edgeRoadm1, edgeRoadm2));
476                 // - XC Connection OTSi betwwen iOTSi y eOTSi of xpdr
477                 // - Top connection OTSi between network ports of xpdrs in the Photonic media layer -> i_OTSi
478                 connectionServMap.putAll(createXpdrCepsAndConnectionsPht(xpdrNetworkTplist, xpdrNodelist));
479                 this.topConnRdmRdm = null;
480                 break;
481             case ODU:
482                 // TODO: verify if this is correct
483                 // - XC Connection OTSi betwwen iODU and eODU of xpdr
484                 // - Top connection in the ODU layer, between xpdr eODU ports (?)
485                 if (openroadmNodeType.equals(OpenroadmNodeType.MUXPDR)) {
486                     connectionServMap.putAll(createXpdrCepsAndConnectionsOdu(xpdrNetworkTplist, xpdrNodelist));
487                     this.topConnXpdrXpdrPhtn = null;
488                 }
489                 break;
490             case Ethernet:
491                 // Check if OC, OTU and ODU are created
492                 if (openroadmNodeType.equals(OpenroadmNodeType.TPDR)) {
493                     LOG.info("WDM ETH service");
494                     connectionServMap.putAll(createRoadmCepsAndConnections(rdmAddDropTplist, rdmDegTplist, rdmNodelist,
495                         edgeRoadm1, edgeRoadm2));
496                     connectionServMap.putAll(createXpdrCepsAndConnectionsPht(xpdrNetworkTplist, xpdrNodelist));
497                     this.topConnRdmRdm = null;
498                     xpdrClientTplist = getAssociatedClientsPort(xpdrNetworkTplist);
499                     LOG.info("Associated client ports = {}", xpdrClientTplist);
500                     connectionServMap.putAll(createXpdrCepsAndConnectionsEth(xpdrClientTplist, xpdrNodelist,
501                         connectionServMap));
502                     this.topConnXpdrXpdrPhtn = null;
503                 }
504                 if (openroadmNodeType.equals(OpenroadmNodeType.SWITCH)) {
505                     // TODO: We create both ODU and DSR because there is no ODU service creation for the switch
506                     // - XC Connection OTSi betwwen iODU and eODU of xpdr
507                     // - Top connection in the ODU layer, between xpdr eODU ports (?)
508                     connectionServMap.putAll(createXpdrCepsAndConnectionsDsr(xpdrClientTplist, xpdrNetworkTplist,
509                         xpdrNodelist));
510                     this.topConnXpdrXpdrPhtn = null;
511                 }
512                 if (openroadmNodeType.equals(OpenroadmNodeType.MUXPDR)) {
513                     // TODO: OTN service but mux has 3 steps at rendering. Verify that things exist
514                     connectionServMap.putAll(createXpdrCepsAndConnectionsDsr(xpdrClientTplist, xpdrNetworkTplist,
515                         xpdrNodelist));
516                     this.topConnXpdrXpdrOdu = null;
517                 }
518                 break;
519             default:
520                 LOG.error("Service type format not supported");
521         }
522         return connectionServMap;
523     }
524
525     private Map<ConnectionKey, Connection> createXpdrCepsAndConnectionsEth(List<String> xpdrClientTplist,
526                                                                            List<String> xpdrNodelist,
527                                                                            Map<ConnectionKey, Connection> lowerConn) {
528         // TODO: do we need to create cross connection between iODU and eODU??
529         // add the lower connections of the previous steps for this kind of service
530         Map<LowerConnectionKey, LowerConnection> xcMap = new HashMap<>();
531         for (Connection lowConn: lowerConn.values()) {
532             LowerConnection conn = new LowerConnectionBuilder().setConnectionUuid(lowConn.getConnectionUuid()).build();
533             xcMap.put(conn.key(), conn);
534         }
535         Map<ConnectionKey, Connection> connServMap = new HashMap<>();
536         Map<org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.connectivity.rev221121.cep.list.ConnectionEndPointKey,
537             ConnectionEndPoint> cepMapDsr = new HashMap<>();
538         // Create 1 cep per Xpdr in the CLIENT
539         // 1 top connection DSR between the CLIENT xpdrs
540         for (String xpdr:xpdrNodelist) {
541             LOG.info("Creating ceps and xc for xpdr {}", xpdr);
542             String spcXpdrClient = xpdrClientTplist.stream().filter(netp -> netp.contains(xpdr)).findFirst()
543                 .orElseThrow();
544             ConnectionEndPoint netCep1 = createCepXpdr(spcXpdrClient, TapiStringConstants.DSR, TapiStringConstants.DSR,
545                 LayerProtocolName.DSR);
546             putXpdrCepInTopologyContext(xpdr, spcXpdrClient, TapiStringConstants.DSR, TapiStringConstants.DSR, netCep1);
547
548             cepMapDsr.put(netCep1.key(), netCep1);
549         }
550         String spcXpdr1 = xpdrClientTplist.stream().filter(adp -> adp.contains(xpdrNodelist
551             .get(0))).findFirst().orElseThrow();
552         String spcXpdr2 = xpdrClientTplist.stream().filter(adp -> adp.contains(xpdrNodelist
553             .get(xpdrNodelist.size() - 1))).findFirst().orElseThrow();
554
555         // DSR top connection between edge xpdr CLIENT DSR
556         org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.connectivity.rev221121.connectivity.context.Connection
557             connectionDsr = createTopConnection(spcXpdr1, spcXpdr2, cepMapDsr, TapiStringConstants.DSR,
558             LayerProtocolName.DSR, xcMap, this.topConnXpdrXpdrPhtn);
559         this.connectionFullMap.put(connectionDsr.key(), connectionDsr);
560
561         // DSR top connection that will be added to the service object
562         Connection conn1 = new ConnectionBuilder().setConnectionUuid(connectionDsr.getUuid()).build();
563         connServMap.put(conn1.key(), conn1);
564
565         return connServMap;
566     }
567
568     private Map<ConnectionKey,Connection> createXpdrCepsAndConnectionsDsr(List<String> xpdrClientTplist,
569                                                                           List<String> xpdrNetworkTplist,
570                                                                           List<String> xpdrNodelist) {
571         Map<ConnectionKey, Connection> connServMap = new HashMap<>();
572         Map<org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.connectivity.rev221121.cep.list.ConnectionEndPointKey,
573             ConnectionEndPoint> cepMapDsr = new HashMap<>();
574         Map<org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.connectivity.rev221121.cep.list.ConnectionEndPointKey,
575             ConnectionEndPoint> cepMapOdu = new HashMap<>();
576         // TODO: when upgrading the models to 2.1.3, get the connection inclusion because those connections will
577         //  be added to the lower connection of a top connection
578         Map<LowerConnectionKey, LowerConnection> xcMap = new HashMap<>();
579
580         // Create 1 cep per Xpdr in the CLIENT, 1 cep per Xpdr eODU, 1 XC between eODU and iODE,
581         // 1 top connection between eODU and a top connection DSR between the CLIENT xpdrs
582         for (String xpdr:xpdrNodelist) {
583             LOG.info("Creating ceps and xc for xpdr {}", xpdr);
584             String spcXpdrClient = xpdrClientTplist.stream().filter(netp -> netp.contains(xpdr)).findFirst()
585                 .orElseThrow();
586             ConnectionEndPoint netCep1 = createCepXpdr(spcXpdrClient, TapiStringConstants.DSR, TapiStringConstants.DSR,
587                 LayerProtocolName.DSR);
588             putXpdrCepInTopologyContext(xpdr, spcXpdrClient, TapiStringConstants.DSR, TapiStringConstants.DSR, netCep1);
589
590             ConnectionEndPoint netCep2 = createCepXpdr(spcXpdrClient, TapiStringConstants.E_ODU,
591                 TapiStringConstants.DSR, LayerProtocolName.ODU);
592             putXpdrCepInTopologyContext(xpdr, spcXpdrClient, TapiStringConstants.E_ODU, TapiStringConstants.DSR,
593                 netCep2);
594
595             String spcXpdrNetwork = getAssociatedNetworkPort(spcXpdrClient, xpdrNetworkTplist);
596             ConnectionEndPoint netCep3 = getAssociatediODUCep(spcXpdrNetwork);
597
598             cepMapDsr.put(netCep1.key(), netCep1);
599             cepMapOdu.put(netCep2.key(), netCep2);
600             // Create x connection between I_ODU and E_ODU within xpdr
601             org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.connectivity.rev221121.connectivity.context.Connection
602                 connection = createXCBetweenCeps(netCep2, netCep3, spcXpdrClient, spcXpdrNetwork,
603                 TapiStringConstants.ODU, LayerProtocolName.ODU);
604             this.connectionFullMap.put(connection.key(), connection);
605
606             // Create X connection that will be added to the service object
607             LowerConnection conn = new LowerConnectionBuilder().setConnectionUuid(connection.getUuid()).build();
608             xcMap.put(conn.key(), conn);
609         }
610
611         // DSR top connection between edge xpdr CLIENT DSR
612         String spcXpdr1 = xpdrClientTplist.stream().filter(adp -> adp.contains(xpdrNodelist
613             .get(0))).findFirst().orElseThrow();
614         String spcXpdr2 = xpdrClientTplist.stream().filter(adp -> adp.contains(xpdrNodelist
615             .get(xpdrNodelist.size() - 1))).findFirst().orElseThrow();
616
617         org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.connectivity.rev221121.connectivity.context.Connection
618             connectionOdu = createTopConnection(spcXpdr1, spcXpdr2, cepMapOdu, TapiStringConstants.E_ODU,
619             LayerProtocolName.ODU, xcMap, this.topConnXpdrXpdrOdu);
620         this.connectionFullMap.put(connectionOdu.key(), connectionOdu);
621
622         // ODU top connection that will be added to the service object
623         Connection conn = new ConnectionBuilder().setConnectionUuid(connectionOdu.getUuid()).build();
624         connServMap.put(conn.key(), conn);
625         LowerConnection lowerConn = new LowerConnectionBuilder().setConnectionUuid(connectionOdu.getUuid()).build();
626         xcMap.put(lowerConn.key(), lowerConn);
627
628         org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.connectivity.rev221121.connectivity.context.Connection
629             connectionDsr = createTopConnection(spcXpdr1, spcXpdr2, cepMapDsr, TapiStringConstants.DSR,
630             LayerProtocolName.DSR, xcMap, this.topConnXpdrXpdrPhtn);
631         this.connectionFullMap.put(connectionDsr.key(), connectionDsr);
632
633         // DSR top connection that will be added to the service object
634         Connection conn1 = new ConnectionBuilder().setConnectionUuid(connectionDsr.getUuid()).build();
635         connServMap.put(conn1.key(), conn1);
636
637         return connServMap;
638     }
639
640     private Map<ConnectionKey, Connection> createXpdrCepsAndConnectionsOdu(List<String> xpdrNetworkTplist,
641                                                                            List<String> xpdrNodelist) {
642         Map<ConnectionKey, Connection> connServMap = new HashMap<>();
643         Map<org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.connectivity.rev221121.cep.list.ConnectionEndPointKey,
644             ConnectionEndPoint> cepMap = new HashMap<>();
645         // TODO: when upgrading the models to 2.1.3, get the connection inclusion because those connections will
646         //  be added to the lower connection of a top connection
647         Map<LowerConnectionKey, LowerConnection> xcMap = new HashMap<>();
648
649         // Create 1 cep per Xpdr in the I_ODU and a top
650         // connection iODU between the xpdrs
651         for (String xpdr:xpdrNodelist) {
652             LOG.info("Creating ceps and xc for xpdr {}", xpdr);
653             String spcXpdrNetwork = xpdrNetworkTplist.stream().filter(netp -> netp.contains(xpdr)).findFirst()
654                 .orElseThrow();
655             ConnectionEndPoint netCep1 = createCepXpdr(spcXpdrNetwork, TapiStringConstants.I_ODU,
656                 TapiStringConstants.DSR, LayerProtocolName.ODU);
657             putXpdrCepInTopologyContext(xpdr, spcXpdrNetwork, TapiStringConstants.I_ODU, TapiStringConstants.DSR,
658                 netCep1);
659
660             cepMap.put(netCep1.key(), netCep1);
661         }
662
663         // ODU top connection between edge xpdr i_ODU
664         String spcXpdr1 = xpdrNetworkTplist.stream().filter(adp -> adp.contains(xpdrNodelist
665             .get(0))).findFirst().orElseThrow();
666         String spcXpdr2 = xpdrNetworkTplist.stream().filter(adp -> adp.contains(xpdrNodelist
667             .get(xpdrNodelist.size() - 1))).findFirst().orElseThrow();
668         org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.connectivity.rev221121.connectivity.context.Connection
669             connection = createTopConnection(spcXpdr1, spcXpdr2, cepMap, TapiStringConstants.I_ODU,
670             LayerProtocolName.ODU, xcMap, this.topConnXpdrXpdrPhtn);
671         this.connectionFullMap.put(connection.key(), connection);
672
673         // ODU top connection that will be added to the service object
674         Connection conn = new ConnectionBuilder().setConnectionUuid(connection.getUuid()).build();
675         connServMap.put(conn.key(), conn);
676         this.topConnXpdrXpdrOdu = conn;
677
678         return connServMap;
679     }
680
681     private Map<ConnectionKey, Connection> createXpdrCepsAndConnectionsPht(List<String> xpdrNetworkTplist,
682                                                                            List<String> xpdrNodelist) {
683         Map<ConnectionKey, Connection> connServMap = new HashMap<>();
684         Map<org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.connectivity.rev221121.cep.list.ConnectionEndPointKey,
685             ConnectionEndPoint> cepMap = new HashMap<>();
686         // TODO: when upgrading the models to 2.1.3, get the connection inclusion because those connections will
687         //  be added to the lower connection of a top connection
688         Map<LowerConnectionKey, LowerConnection> xcMap = new HashMap<>();
689
690         // create ceps and x connections within xpdr
691         for (String xpdr:xpdrNodelist) {
692             LOG.info("Creating ceps and xc for xpdr {}", xpdr);
693             String spcXpdrNetwork = xpdrNetworkTplist.stream().filter(netp -> netp.contains(xpdr)).findFirst()
694                 .orElseThrow();
695             // There should be 1 network tp per xpdr
696             // TODO photonic media model should be updated to have the corresponding CEPs. I will just create
697             //  3 different MC CEPs giving different IDs to show that they are different
698             // Create 3 CEPs for each xpdr otsi node and the corresponding cross connection matchin the NEPs
699             ConnectionEndPoint netCep1 = createCepXpdr(spcXpdrNetwork, TapiStringConstants.PHTNC_MEDIA,
700                 TapiStringConstants.OTSI, LayerProtocolName.PHOTONICMEDIA);
701             putXpdrCepInTopologyContext(xpdr, spcXpdrNetwork, TapiStringConstants.PHTNC_MEDIA, TapiStringConstants.OTSI,
702                 netCep1);
703             ConnectionEndPoint netCep2 = createCepXpdr(spcXpdrNetwork, TapiStringConstants.E_OTSI,
704                 TapiStringConstants.OTSI, LayerProtocolName.PHOTONICMEDIA);
705             putXpdrCepInTopologyContext(xpdr, spcXpdrNetwork, TapiStringConstants.E_OTSI, TapiStringConstants.OTSI,
706                 netCep2);
707             ConnectionEndPoint netCep3 = createCepXpdr(spcXpdrNetwork, TapiStringConstants.I_OTSI,
708                 TapiStringConstants.OTSI, LayerProtocolName.PHOTONICMEDIA);
709             putXpdrCepInTopologyContext(xpdr, spcXpdrNetwork, TapiStringConstants.I_OTSI, TapiStringConstants.OTSI,
710                 netCep3);
711             cepMap.put(netCep1.key(), netCep1);
712             cepMap.put(netCep2.key(), netCep2);
713             cepMap.put(netCep3.key(), netCep3);
714
715             // Create x connection between I_OTSi and E_OTSi within xpdr
716             org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.connectivity.rev221121.connectivity.context.Connection
717                 connection = createXCBetweenCeps(netCep2, netCep3, spcXpdrNetwork, spcXpdrNetwork,
718                 TapiStringConstants.OTSI, LayerProtocolName.PHOTONICMEDIA);
719             this.connectionFullMap.put(connection.key(), connection);
720
721             // Create X connection that will be added to the service object
722             LowerConnection conn = new LowerConnectionBuilder().setConnectionUuid(connection.getUuid()).build();
723             xcMap.put(conn.key(), conn);
724         }
725         // OTSi top connection between edge I_OTSI Xpdr
726         String spcXpdr1 = xpdrNetworkTplist.stream().filter(adp -> adp.contains(xpdrNodelist
727             .get(0))).findFirst().orElseThrow();
728         String spcXpdr2 = xpdrNetworkTplist.stream().filter(adp -> adp.contains(xpdrNodelist
729             .get(xpdrNodelist.size() - 1))).findFirst().orElseThrow();
730         org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.connectivity.rev221121.connectivity.context.Connection
731             connection = createTopConnection(spcXpdr1, spcXpdr2, cepMap, TapiStringConstants.I_OTSI,
732             LayerProtocolName.PHOTONICMEDIA, xcMap, this.topConnRdmRdm);
733         this.connectionFullMap.put(connection.key(), connection);
734
735         // OTSi top connection that will be added to the service object
736         Connection conn = new ConnectionBuilder().setConnectionUuid(connection.getUuid()).build();
737         connServMap.put(conn.key(), conn);
738         this.topConnXpdrXpdrPhtn = conn;
739
740         return connServMap;
741     }
742
743     private Map<ConnectionKey, Connection> createRoadmCepsAndConnections(List<String> rdmAddDropTplist,
744                                                                          List<String> rdmDegTplist,
745                                                                          List<String> rdmNodelist,
746                                                                          String edgeRoadm1, String edgeRoadm2) {
747         // TODO: will need to check if things exist already or not
748         Map<org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.connectivity.rev221121.cep.list.ConnectionEndPointKey,
749             ConnectionEndPoint> cepMap = new HashMap<>();
750         // create ceps and x connections within roadm
751         Map<LowerConnectionKey, LowerConnection> xcLowerMap = new HashMap<>();
752         for (String roadm : rdmNodelist) {
753             LOG.info("Creating ceps and xc for roadm {}", roadm);
754             if (roadm.equals(edgeRoadm1) || roadm.equals(edgeRoadm2)) {
755                 LOG.info("EDGE ROADM, cross connections needed between SRG and DEG");
756                 String spcRdmAD = rdmAddDropTplist.stream().filter(adp -> adp.contains(roadm)).findFirst()
757                     .orElseThrow();
758                 LOG.info("AD port of ROADm {} = {}", roadm, spcRdmAD);
759                 // There should be only 1 AD and 1 DEG per roadm
760                 // TODO photonic media model should be updated to have the corresponding CEPs. I will just create
761                 //  3 different MC CEPs giving different IDs to show that they are different
762                 // Create 3 CEPs for each AD and DEG and the corresponding cross connections, matching the NEPs
763                 // created in the topology creation
764                 // add CEPs to the topology to the corresponding ONEP
765                 ConnectionEndPoint adCep1 = createCepRoadm(spcRdmAD, TapiStringConstants.PHTNC_MEDIA);
766                 putRdmCepInTopologyContext(roadm, spcRdmAD, TapiStringConstants.PHTNC_MEDIA, adCep1);
767                 ConnectionEndPoint adCep2 = createCepRoadm(spcRdmAD, TapiStringConstants.MC);
768                 putRdmCepInTopologyContext(roadm, spcRdmAD, TapiStringConstants.MC, adCep2);
769                 ConnectionEndPoint adCep3 = createCepRoadm(spcRdmAD, TapiStringConstants.OTSI_MC);
770                 putRdmCepInTopologyContext(roadm, spcRdmAD, TapiStringConstants.OTSI_MC, adCep3);
771                 cepMap.put(adCep1.key(), adCep1);
772                 cepMap.put(adCep2.key(), adCep2);
773                 cepMap.put(adCep3.key(), adCep3);
774
775                 String spcRdmDEG = rdmDegTplist.stream().filter(adp -> adp.contains(roadm)).findFirst().orElseThrow();
776                 LOG.info("Degree port of ROADm {} = {}", roadm, spcRdmDEG);
777
778                 ConnectionEndPoint degCep1 = createCepRoadm(spcRdmDEG, TapiStringConstants.PHTNC_MEDIA);
779                 putRdmCepInTopologyContext(roadm, spcRdmDEG, TapiStringConstants.PHTNC_MEDIA, degCep1);
780                 ConnectionEndPoint degCep2 = createCepRoadm(spcRdmDEG, TapiStringConstants.MC);
781                 putRdmCepInTopologyContext(roadm, spcRdmDEG, TapiStringConstants.MC, degCep2);
782                 ConnectionEndPoint degCep3 = createCepRoadm(spcRdmDEG, TapiStringConstants.OTSI_MC);
783                 putRdmCepInTopologyContext(roadm, spcRdmDEG, TapiStringConstants.OTSI_MC, degCep3);
784                 cepMap.put(degCep1.key(), degCep1);
785                 cepMap.put(degCep2.key(), degCep2);
786                 cepMap.put(degCep3.key(), degCep3);
787
788                 LOG.info("Going to create cross connections for ROADM {}", roadm);
789                 // Create X connections between MC and OTSi_MC for full map
790                 org.opendaylight.yang.gen.v1.urn
791                         .onf.otcc.yang.tapi.connectivity.rev221121.connectivity.context.Connection connection1
792                     = createXCBetweenCeps(adCep2, degCep2, spcRdmAD, spcRdmDEG, TapiStringConstants.MC,
793                         LayerProtocolName.PHOTONICMEDIA);
794                 LOG.info("Cross connection 1 created = {}", connection1.toString());
795                 org.opendaylight.yang.gen.v1.urn
796                     .onf.otcc.yang.tapi.connectivity.rev221121.connectivity.context.Connection connection2
797                     = createXCBetweenCeps(adCep3, degCep3, spcRdmAD, spcRdmDEG, TapiStringConstants.OTSI_MC,
798                     LayerProtocolName.PHOTONICMEDIA);
799                 LOG.info("Cross connection 2 created = {}", connection2.toString());
800                 this.connectionFullMap.put(connection1.key(), connection1);
801                 this.connectionFullMap.put(connection2.key(), connection2);
802
803                 // Create X connections that will be added to the service object
804                 LowerConnection conn1 = new LowerConnectionBuilder().setConnectionUuid(connection1.getUuid()).build();
805                 LowerConnection conn2 = new LowerConnectionBuilder().setConnectionUuid(connection2.getUuid()).build();
806
807                 xcLowerMap.put(conn1.key(), conn1);
808                 xcLowerMap.put(conn2.key(), conn2);
809             } else {
810                 LOG.info("MIDDLE ROADM, cross connections needed between DEG and DEG");
811                 String spcRdmDEG1 = rdmDegTplist.stream().filter(adp -> adp.contains(roadm)).findFirst().orElseThrow();
812                 LOG.info("Degree 1 port of ROADm {} = {}", roadm, spcRdmDEG1);
813
814                 ConnectionEndPoint deg1Cep1 = createCepRoadm(spcRdmDEG1, TapiStringConstants.PHTNC_MEDIA);
815                 putRdmCepInTopologyContext(roadm, spcRdmDEG1, TapiStringConstants.PHTNC_MEDIA, deg1Cep1);
816                 ConnectionEndPoint deg1Cep2 = createCepRoadm(spcRdmDEG1, TapiStringConstants.MC);
817                 putRdmCepInTopologyContext(roadm, spcRdmDEG1, TapiStringConstants.MC, deg1Cep2);
818                 ConnectionEndPoint deg1Cep3 = createCepRoadm(spcRdmDEG1, TapiStringConstants.OTSI_MC);
819                 putRdmCepInTopologyContext(roadm, spcRdmDEG1, TapiStringConstants.OTSI_MC, deg1Cep3);
820                 cepMap.put(deg1Cep1.key(), deg1Cep1);
821                 cepMap.put(deg1Cep2.key(), deg1Cep2);
822                 cepMap.put(deg1Cep3.key(), deg1Cep3);
823
824                 String spcRdmDEG2 = rdmDegTplist.stream().filter(adp -> adp.contains(roadm)).skip(1).findFirst()
825                     .orElseThrow();
826                 LOG.info("Degree 2 port of ROADm {} = {}", roadm, spcRdmDEG2);
827
828                 ConnectionEndPoint deg2Cep1 = createCepRoadm(spcRdmDEG2, TapiStringConstants.PHTNC_MEDIA);
829                 putRdmCepInTopologyContext(roadm, spcRdmDEG2, TapiStringConstants.PHTNC_MEDIA, deg2Cep1);
830                 ConnectionEndPoint deg2Cep2 = createCepRoadm(spcRdmDEG2, TapiStringConstants.MC);
831                 putRdmCepInTopologyContext(roadm, spcRdmDEG2, TapiStringConstants.MC, deg2Cep2);
832                 ConnectionEndPoint deg2Cep3 = createCepRoadm(spcRdmDEG2, TapiStringConstants.OTSI_MC);
833                 putRdmCepInTopologyContext(roadm, spcRdmDEG2, TapiStringConstants.OTSI_MC, deg2Cep3);
834                 cepMap.put(deg2Cep1.key(), deg2Cep1);
835                 cepMap.put(deg2Cep2.key(), deg2Cep2);
836                 cepMap.put(deg2Cep3.key(), deg2Cep3);
837
838                 LOG.info("Going to create cross connections for ROADM {}", roadm);
839                 // Create X connections between MC and OTSi_MC for full map
840                 org.opendaylight.yang.gen.v1.urn
841                     .onf.otcc.yang.tapi.connectivity.rev221121.connectivity.context.Connection connection1
842                     = createXCBetweenCeps(deg1Cep2, deg2Cep2, spcRdmDEG1, spcRdmDEG2,
843                     TapiStringConstants.MC, LayerProtocolName.PHOTONICMEDIA);
844                 LOG.info("Cross connection 1 created = {}", connection1.toString());
845                 org.opendaylight.yang.gen.v1.urn
846                     .onf.otcc.yang.tapi.connectivity.rev221121.connectivity.context.Connection connection2
847                     = createXCBetweenCeps(deg1Cep3, deg2Cep3, spcRdmDEG1, spcRdmDEG2,
848                     TapiStringConstants.OTSI_MC, LayerProtocolName.PHOTONICMEDIA);
849                 LOG.info("Cross connection 2 created = {}", connection2.toString());
850                 this.connectionFullMap.put(connection1.key(), connection1);
851                 this.connectionFullMap.put(connection2.key(), connection2);
852
853                 // Create X connections that will be added to the service object
854                 LowerConnection conn1 = new LowerConnectionBuilder().setConnectionUuid(connection1.getUuid()).build();
855                 LowerConnection conn2 = new LowerConnectionBuilder().setConnectionUuid(connection2.getUuid()).build();
856
857                 xcLowerMap.put(conn1.key(), conn1);
858                 xcLowerMap.put(conn2.key(), conn2);
859             }
860         }
861         LOG.info("Going to create top connections between roadms");
862         String spcRdmAD1 = rdmAddDropTplist.stream().filter(adp -> adp.contains(edgeRoadm1)).findFirst().orElseThrow();
863         String spcRdmAD2 = rdmAddDropTplist.stream().filter(adp -> adp.contains(edgeRoadm2)).findFirst().orElseThrow();
864         // MC top connection between edge roadms
865         LOG.info("Going to created top connection between MC");
866         org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.connectivity.rev221121.connectivity.context.Connection
867             connection = createTopConnection(spcRdmAD1, spcRdmAD2, cepMap, TapiStringConstants.MC,
868             LayerProtocolName.PHOTONICMEDIA, xcLowerMap, null);
869         this.connectionFullMap.put(connection.key(), connection);
870         LOG.info("Top connection created = {}", connection.toString());
871
872         Map<ConnectionKey, Connection> connServMap = new HashMap<>();
873         // OTSiMC top connections that will be added to the service object
874         Connection conn = new ConnectionBuilder().setConnectionUuid(connection.getUuid()).build();
875         connServMap.put(conn.key(), conn);
876         LowerConnection conn1 = new LowerConnectionBuilder().setConnectionUuid(connection.getUuid()).build();
877         Map<LowerConnectionKey, LowerConnection> topLowerMap = new HashMap<>();
878         topLowerMap.put(conn1.key(), conn1);
879
880         // OTSiMC top connection between edge roadms
881         LOG.info("Going to created top connection between OTSiMC");
882         org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.connectivity.rev221121.connectivity.context.Connection
883             connection1 = createTopConnection(spcRdmAD1, spcRdmAD2, cepMap, TapiStringConstants.OTSI_MC,
884             LayerProtocolName.PHOTONICMEDIA, topLowerMap, null);
885         this.connectionFullMap.put(connection1.key(), connection1);
886         LOG.info("Top connection created = {}", connection1.toString());
887
888         // OTSiMC top connections that will be added to the service object
889         Connection conn2 = new ConnectionBuilder().setConnectionUuid(connection1.getUuid()).build();
890         connServMap.put(conn2.key(), conn2);
891         this.topConnRdmRdm = conn2;
892         return connServMap;
893     }
894
895     private org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.connectivity.rev221121.connectivity.context.Connection
896             createTopConnection(String tp1, String tp2,
897                         Map<org.opendaylight.yang.gen.v1.urn
898                             .onf.otcc.yang.tapi.connectivity.rev221121.cep.list.ConnectionEndPointKey,
899                             ConnectionEndPoint> cepMap, String qual, LayerProtocolName topPortocol,
900                         Map<LowerConnectionKey, LowerConnection> xcMap, Connection additionalLowerConn) {
901         // find cep for each AD MC of roadm 1 and 2
902         LOG.info("Top connection name = {}", String.join("+", "TOP", tp1, tp2, qual));
903         org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.connectivity.rev221121.ConnectionEndPoint adCep1 =
904             cepMap.get(new org.opendaylight.yang.gen.v1.urn
905                 .onf.otcc.yang.tapi.connectivity.rev221121.cep.list.ConnectionEndPointKey(
906                 new Uuid(UUID.nameUUIDFromBytes((String.join("+", "CEP", tp1.split("\\+")[0],
907                         qual, tp1.split("\\+")[1])).getBytes(StandardCharsets.UTF_8))
908                     .toString())));
909         LOG.info("ADCEP1 = {}", adCep1);
910         org.opendaylight.yang.gen.v1.urn
911             .onf.otcc.yang.tapi.connectivity.rev221121.connection.ConnectionEndPoint cep1 =
912             new org.opendaylight.yang.gen.v1.urn
913                 .onf.otcc.yang.tapi.connectivity.rev221121.connection.ConnectionEndPointBuilder()
914                 .setNodeEdgePointUuid(adCep1.getClientNodeEdgePoint()
915                     .values().stream().findFirst().orElseThrow().getNodeEdgePointUuid())
916                 .setTopologyUuid(adCep1.getClientNodeEdgePoint()
917                     .values().stream().findFirst().orElseThrow().getTopologyUuid())
918                 .setNodeUuid(adCep1.getClientNodeEdgePoint()
919                     .values().stream().findFirst().orElseThrow().getNodeUuid())
920                 .setConnectionEndPointUuid(adCep1.getUuid())
921                 .build();
922         org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.connectivity.rev221121.ConnectionEndPoint adCep2 =
923             cepMap.get(new org.opendaylight.yang.gen.v1.urn
924                 .onf.otcc.yang.tapi.connectivity.rev221121.cep.list.ConnectionEndPointKey(
925                 new Uuid(UUID.nameUUIDFromBytes((String.join("+", "CEP", tp2.split("\\+")[0],
926                         qual, tp2.split("\\+")[1])).getBytes(StandardCharsets.UTF_8))
927                     .toString())));
928         LOG.info("ADCEP2 = {}", adCep2);
929         org.opendaylight.yang.gen.v1.urn
930             .onf.otcc.yang.tapi.connectivity.rev221121.connection.ConnectionEndPoint cep2 =
931             new org.opendaylight.yang.gen.v1.urn
932                 .onf.otcc.yang.tapi.connectivity.rev221121.connection.ConnectionEndPointBuilder()
933                 .setNodeEdgePointUuid(adCep2.getClientNodeEdgePoint()
934                     .values().stream().findFirst().orElseThrow().getNodeEdgePointUuid())
935                 .setTopologyUuid(adCep2.getClientNodeEdgePoint()
936                     .values().stream().findFirst().orElseThrow().getTopologyUuid())
937                 .setNodeUuid(adCep2.getClientNodeEdgePoint()
938                     .values().stream().findFirst().orElseThrow().getNodeUuid())
939                 .setConnectionEndPointUuid(adCep1.getUuid())
940                 .build();
941         Map<ConnectionEndPointKey, org.opendaylight.yang.gen.v1.urn
942             .onf.otcc.yang.tapi.connectivity.rev221121.connection.ConnectionEndPoint> ceps = new HashMap<>();
943         ceps.put(cep1.key(), cep1);
944         ceps.put(cep2.key(), cep2);
945         Name connName = new NameBuilder()
946             .setValueName("Connection name")
947             .setValue(String.join("+", "TOP", tp1, tp2, qual))
948             .build();
949         // TODO: lower connection, supported link.......
950         if (additionalLowerConn != null) {
951             xcMap.putIfAbsent(new LowerConnectionKey(additionalLowerConn.getConnectionUuid()),
952                 new LowerConnectionBuilder().setConnectionUuid(additionalLowerConn.getConnectionUuid()).build());
953         }
954         return new org.opendaylight.yang.gen.v1.urn
955                 .onf.otcc.yang.tapi.connectivity.rev221121.connectivity.context.ConnectionBuilder()
956             .setUuid(new Uuid(UUID.nameUUIDFromBytes((String.join("+", "TOP", tp1, tp2, qual))
957                 .getBytes(StandardCharsets.UTF_8)).toString()))
958             .setName(Map.of(connName.key(), connName))
959             .setConnectionEndPoint(ceps)
960             .setOperationalState(OperationalState.ENABLED)
961             .setLayerProtocolName(topPortocol)
962             .setLifecycleState(LifecycleState.INSTALLED)
963             .setDirection(ForwardingDirection.BIDIRECTIONAL)
964             .setLowerConnection(xcMap)
965             .build();
966     }
967
968     private org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.connectivity.rev221121.connectivity.context.Connection
969             createXCBetweenCeps(ConnectionEndPoint cep1, ConnectionEndPoint cep2, String tp1, String tp2, String qual,
970                         LayerProtocolName xcProtocol) {
971         LOG.info("Creation cross connection between: {} and {}", tp1, tp2);
972         LOG.info("Cross connection name = {}", String.join("+", "XC", tp1, tp2, qual));
973         LOG.info("CEP1 = {}", cep1.getClientNodeEdgePoint());
974         LOG.info("CEP2 = {}", cep2.getClientNodeEdgePoint());
975         org.opendaylight.yang.gen.v1.urn
976             .onf.otcc.yang.tapi.connectivity.rev221121.connection.ConnectionEndPoint cepServ1 =
977             new org.opendaylight.yang.gen.v1.urn
978                     .onf.otcc.yang.tapi.connectivity.rev221121.connection.ConnectionEndPointBuilder()
979                 .setNodeEdgePointUuid(cep1.getClientNodeEdgePoint()
980                     .values().stream().findFirst().orElseThrow().getNodeEdgePointUuid())
981                 .setTopologyUuid(cep1.getClientNodeEdgePoint()
982                     .values().stream().findFirst().orElseThrow().getTopologyUuid())
983                 .setNodeUuid(cep1.getClientNodeEdgePoint()
984                     .values().stream().findFirst().orElseThrow().getNodeUuid())
985                 .setConnectionEndPointUuid(cep1.getUuid())
986                 .build();
987         org.opendaylight.yang.gen.v1.urn
988                 .onf.otcc.yang.tapi.connectivity.rev221121.connection.ConnectionEndPoint cepServ2 =
989             new org.opendaylight.yang.gen.v1.urn
990                 .onf.otcc.yang.tapi.connectivity.rev221121.connection.ConnectionEndPointBuilder()
991                 .setNodeEdgePointUuid(cep2.getClientNodeEdgePoint()
992                     .values().stream().findFirst().orElseThrow().getNodeEdgePointUuid())
993                 .setTopologyUuid(cep2.getClientNodeEdgePoint()
994                     .values().stream().findFirst().orElseThrow().getTopologyUuid())
995                 .setNodeUuid(cep2.getClientNodeEdgePoint()
996                     .values().stream().findFirst().orElseThrow().getNodeUuid())
997                 .setConnectionEndPointUuid(cep2.getUuid())
998                 .build();
999         Map<ConnectionEndPointKey, org.opendaylight.yang.gen.v1.urn
1000             .onf.otcc.yang.tapi.connectivity.rev221121.connection.ConnectionEndPoint> ceps = new HashMap<>();
1001         ceps.put(cepServ1.key(), cepServ1);
1002         ceps.put(cepServ2.key(), cepServ2);
1003         Name connName = new NameBuilder()
1004             .setValueName("Connection name")
1005             .setValue(String.join("+", "XC", tp1, tp2, qual))
1006             .build();
1007         // TODO: lower connection, supported link.......
1008         return new org.opendaylight.yang.gen.v1.urn
1009                 .onf.otcc.yang.tapi.connectivity.rev221121.connectivity.context.ConnectionBuilder()
1010             .setUuid(new Uuid(UUID.nameUUIDFromBytes((String.join("+", "XC", tp1, tp2, qual))
1011                 .getBytes(StandardCharsets.UTF_8)).toString()))
1012             .setName(Map.of(connName.key(), connName))
1013             .setConnectionEndPoint(ceps)
1014             .setOperationalState(OperationalState.ENABLED)
1015             .setLayerProtocolName(xcProtocol)
1016             .setLifecycleState(LifecycleState.INSTALLED)
1017             .setDirection(ForwardingDirection.BIDIRECTIONAL)
1018             .build();
1019     }
1020
1021     private ConnectionEndPoint createCepRoadm(String id, String qualifier) {
1022         LOG.info("NEP = {}", String.join("+", id.split("\\+")[0], qualifier, id.split("\\+")[1]));
1023         Name cepName = new NameBuilder()
1024             .setValueName("ConnectionEndPoint name")
1025             .setValue(String.join("+", id.split("\\+")[0], qualifier,
1026                 id.split("\\+")[1]))
1027             .build();
1028         ClientNodeEdgePoint cnep = new ClientNodeEdgePointBuilder()
1029             .setNodeEdgePointUuid(new Uuid(UUID.nameUUIDFromBytes((String.join("+", id.split("\\+")[0],
1030                     qualifier, id.split("\\+")[1])).getBytes(StandardCharsets.UTF_8))
1031                 .toString()))
1032             .setNodeUuid(new Uuid(UUID.nameUUIDFromBytes((String.join("+",id.split("\\+")[0],
1033                     qualifier)).getBytes(StandardCharsets.UTF_8))
1034                 .toString()))
1035             .setTopologyUuid(new Uuid(UUID.nameUUIDFromBytes(TapiStringConstants.T0_FULL_MULTILAYER
1036                 .getBytes(StandardCharsets.UTF_8)).toString()))
1037             .build();
1038         // TODO: add augmentation with the corresponding cep-spec (i.e. MC, OTSiMC...)
1039         // TODO: add parent ONEP??
1040         ConnectionEndPointBuilder cepBldr = new ConnectionEndPointBuilder()
1041             .setUuid(new Uuid(UUID.nameUUIDFromBytes((String.join("+", "CEP", id.split("\\+")[0],
1042                     qualifier, id.split("\\+")[1])).getBytes(StandardCharsets.UTF_8))
1043                 .toString()))
1044             .setClientNodeEdgePoint(Map.of(cnep.key(), cnep))
1045             .setName(Map.of(cepName.key(), cepName))
1046             .setConnectionPortRole(PortRole.SYMMETRIC)
1047             .setDirection(Direction.BIDIRECTIONAL)
1048             .setOperationalState(OperationalState.ENABLED)
1049             .setLifecycleState(LifecycleState.INSTALLED)
1050             .setLayerProtocolName(LayerProtocolName.PHOTONICMEDIA);
1051         return cepBldr.build();
1052     }
1053
1054     private ConnectionEndPoint createCepXpdr(String id, String qualifier, String nodeLayer,
1055                                              LayerProtocolName cepProtocol) {
1056         Name cepName = new NameBuilder()
1057             .setValueName("ConnectionEndPoint name")
1058             .setValue(String.join("+", id.split("\\+")[0], qualifier,
1059                 id.split("\\+")[1]))
1060             .build();
1061         ClientNodeEdgePoint cnep = new ClientNodeEdgePointBuilder()
1062             .setNodeEdgePointUuid(new Uuid(UUID.nameUUIDFromBytes((String.join("+", id.split("\\+")[0],
1063                     qualifier, id.split("\\+")[1])).getBytes(StandardCharsets.UTF_8))
1064                 .toString()))
1065             .setNodeUuid(new Uuid(UUID.nameUUIDFromBytes((String.join("+",id.split("\\+")[0],
1066                     nodeLayer)).getBytes(StandardCharsets.UTF_8))
1067                 .toString()))
1068             .setTopologyUuid(new Uuid(UUID.nameUUIDFromBytes(TapiStringConstants.T0_FULL_MULTILAYER
1069                 .getBytes(StandardCharsets.UTF_8)).toString()))
1070             .build();
1071         // TODO: add augmentation with the corresponding cep-spec (i.e. MC, OTSiMC...)
1072         // TODO: add parent ONEP??
1073         ConnectionEndPointBuilder cepBldr = new ConnectionEndPointBuilder()
1074             .setUuid(new Uuid(UUID.nameUUIDFromBytes((String.join("+", "CEP", id.split("\\+")[0],
1075                     qualifier, id.split("\\+")[1])).getBytes(StandardCharsets.UTF_8))
1076                 .toString()))
1077             .setClientNodeEdgePoint(Map.of(cnep.key(), cnep))
1078             .setName(Map.of(cepName.key(), cepName))
1079             .setConnectionPortRole(PortRole.SYMMETRIC)
1080             .setDirection(Direction.BIDIRECTIONAL)
1081             .setOperationalState(OperationalState.ENABLED)
1082             .setLifecycleState(LifecycleState.INSTALLED)
1083             .setLayerProtocolName(cepProtocol);
1084         return cepBldr.build();
1085     }
1086
1087     private EndPoint mapServiceZEndPoint(
1088         org.opendaylight.yang.gen.v1.http.org.openroadm.common.service.types.rev230526.service.ServiceZEnd
1089             serviceZEnd, PathDescription pathDescription) {
1090         EndPointBuilder endPointBuilder = new EndPointBuilder();
1091         // 1. Service Format: ODU, OTU, ETH
1092         ServiceFormat serviceFormat = serviceZEnd.getServiceFormat();
1093         String serviceNodeId = serviceZEnd.getNodeId().getValue();
1094         // Identify SIP name
1095         Uuid sipUuid = getSipIdFromZend(pathDescription.getZToADirection().getZToA(), serviceNodeId, serviceFormat);
1096         LOG.info("Uuid of z end {}", sipUuid);
1097         LayerProtocolName layerProtocols = null;
1098         // Layer protocol name
1099         switch (serviceFormat) {
1100             case Ethernet:
1101                 layerProtocols = LayerProtocolName.DSR;
1102                 break;
1103             case OTU:
1104             case OC:
1105                 layerProtocols = LayerProtocolName.PHOTONICMEDIA;
1106                 break;
1107             case ODU:
1108                 layerProtocols = LayerProtocolName.ODU;
1109                 break;
1110             default:
1111                 LOG.error("Service Format not supported");
1112         }
1113         org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.common.rev221121.local._class.Name name =
1114             new org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.common.rev221121.local._class.NameBuilder()
1115                 .setValueName("OpenROADM info")
1116                 .setValue(String.join("-", serviceZEnd.getClli(),
1117                     serviceZEnd.getTxDirection().values().stream().findFirst().orElseThrow().getPort()
1118                         .getPortDeviceName(),
1119                     serviceZEnd.getTxDirection().values().stream().findFirst().orElseThrow().getPort().getPortName()))
1120                 .build();
1121         return endPointBuilder
1122             .setServiceInterfacePoint(new ServiceInterfacePointBuilder()
1123                 .setServiceInterfacePointUuid(sipUuid)
1124                 .build())
1125             .setName(Map.of(name.key(), name))
1126             .setAdministrativeState(AdministrativeState.UNLOCKED)
1127             .setDirection(Direction.BIDIRECTIONAL)
1128             .setLifecycleState(LifecycleState.INSTALLED)
1129             .setOperationalState(OperationalState.ENABLED)
1130             .setLayerProtocolName(layerProtocols)
1131             .setCapacity(new CapacityBuilder()
1132                 .setTotalSize(new TotalSizeBuilder()
1133                     .setValue(Decimal64.valueOf(BigDecimal.valueOf(serviceZEnd.getServiceRate().doubleValue())))
1134                     .setUnit(CAPACITYUNITGBPS.VALUE)
1135                     .build())
1136 //                .setBandwidthProfile(new BandwidthProfileBuilder().build())
1137                 .build())
1138             .setProtectionRole(ProtectionRole.WORK)
1139             .setRole(PortRole.SYMMETRIC)
1140             .setLocalId(serviceZEnd.getTxDirection().values().stream().findFirst().orElseThrow()
1141                 .getPort().getPortDeviceName())
1142             .build();
1143     }
1144
1145     private EndPoint mapServiceAEndPoint(
1146         org.opendaylight.yang.gen.v1.http.org.openroadm.common.service.types.rev230526.service.ServiceAEnd
1147             serviceAEnd, PathDescription pathDescription) {
1148         EndPointBuilder endPointBuilder = new EndPointBuilder();
1149         // 1. Service Format: ODU, OTU, ETH
1150         ServiceFormat serviceFormat = serviceAEnd.getServiceFormat();
1151         String serviceNodeId = serviceAEnd.getNodeId().getValue();
1152         // Identify SIP name
1153         Uuid sipUuid = getSipIdFromAend(pathDescription.getAToZDirection().getAToZ(), serviceNodeId, serviceFormat);
1154         LOG.info("Uuid of a end {}", sipUuid);
1155         LayerProtocolName layerProtocols = null;
1156         // Layer protocol name
1157         switch (serviceFormat) {
1158             case Ethernet:
1159                 layerProtocols = LayerProtocolName.DSR;
1160                 break;
1161             case OTU:
1162             case OC:
1163                 layerProtocols = LayerProtocolName.PHOTONICMEDIA;
1164                 break;
1165             case ODU:
1166                 layerProtocols = LayerProtocolName.ODU;
1167                 break;
1168             default:
1169                 LOG.error("Service Format not supported");
1170         }
1171         org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.common.rev221121.local._class.Name name =
1172             new org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.common.rev221121.local._class.NameBuilder()
1173                 .setValueName("OpenROADM info")
1174                 .setValue(String.join("-", serviceAEnd.getClli(),
1175                     serviceAEnd.getTxDirection().values().stream().findFirst().orElseThrow().getPort()
1176                         .getPortDeviceName(),
1177                     serviceAEnd.getTxDirection().values().stream().findFirst().orElseThrow().getPort().getPortName()))
1178                 .build();
1179         return endPointBuilder
1180             .setServiceInterfacePoint(new ServiceInterfacePointBuilder()
1181                 .setServiceInterfacePointUuid(sipUuid)
1182                 .build())
1183             .setName(Map.of(name.key(), name))
1184             .setAdministrativeState(AdministrativeState.UNLOCKED)
1185             .setDirection(Direction.BIDIRECTIONAL)
1186             .setLifecycleState(LifecycleState.INSTALLED)
1187             .setOperationalState(OperationalState.ENABLED)
1188             .setLayerProtocolName(layerProtocols)
1189             .setCapacity(new CapacityBuilder()
1190                 .setTotalSize(new TotalSizeBuilder()
1191                     .setValue(Decimal64.valueOf(BigDecimal.valueOf(serviceAEnd.getServiceRate().doubleValue())))
1192                     .setUnit(CAPACITYUNITGBPS.VALUE)
1193                     .build())
1194 //                .setBandwidthProfile(new BandwidthProfileBuilder().build()) // TODO: implement bandwidth profile
1195                 .build())
1196             .setProtectionRole(ProtectionRole.WORK)
1197             .setRole(PortRole.SYMMETRIC)
1198             .setLocalId(serviceAEnd.getTxDirection().values().stream().findFirst().orElseThrow().getPort()
1199                     .getPortDeviceName())
1200             .build();
1201     }
1202
1203     private Uuid getSipIdFromZend(Map<ZToAKey, ZToA> mapztoa, String serviceNodeId, ServiceFormat serviceFormat) {
1204         Uuid zendUuid = null;
1205         if (serviceNodeId.contains("ROADM")) {
1206             // Service from ROADM to ROADM
1207             // AddDrop-AddDrop ports --> MC layer SIPs
1208             ZToA firstElement = mapztoa.values().stream().filter(ztoa -> ztoa.getId().equals("0")).findFirst()
1209                     .orElseThrow();
1210             TerminationPoint tp = (TerminationPoint) firstElement.getResource().getResource();
1211             Uuid sipUuid = new Uuid(UUID.nameUUIDFromBytes((String.join("+", "SIP",
1212                     tp.getTpNodeId(), TapiStringConstants.MC, tp.getTpId())).getBytes(StandardCharsets.UTF_8))
1213                 .toString());
1214             LOG.info("SIP name = {}", String.join("+", tp.getTpNodeId(), TapiStringConstants.MC, tp.getTpId()));
1215             for (ServiceInterfacePoint sip:this.sipMap.values()) {
1216                 if (!sip.getUuid().equals(sipUuid)) {
1217                     LOG.info("SIP {} doesn match sipname {}", sip.getUuid().getValue(), sipUuid.getValue());
1218                     continue;
1219                 }
1220                 zendUuid = sip.getUuid();
1221                 break;
1222             }
1223         } else {
1224             // Service from XPDR to XPDR
1225             ZToA firstElement;
1226             TerminationPoint tp;
1227             Uuid sipUuid;
1228             switch (serviceFormat) {
1229                 case ODU:
1230                     firstElement = mapztoa.values().stream().filter(ztoa -> ztoa.getId().equals("2")).findFirst()
1231                             .orElseThrow();
1232                     tp = (TerminationPoint) firstElement.getResource().getResource();
1233                     // Network-Network ports --> iODU layer SIPs TODO --> updated to E_ODU
1234                     sipUuid = new Uuid(UUID.nameUUIDFromBytes((String.join("+", "SIP", tp.getTpNodeId(),
1235                             TapiStringConstants.I_ODU, tp.getTpId())).getBytes(StandardCharsets.UTF_8)).toString());
1236                     LOG.info("SIP name = {}", String.join("+", tp.getTpNodeId(), TapiStringConstants.I_ODU,
1237                         tp.getTpId()));
1238                     break;
1239                 case OTU:
1240                     firstElement = mapztoa.values().stream().filter(ztoa -> ztoa.getId().equals("2")).findFirst()
1241                             .orElseThrow();
1242                     tp = (TerminationPoint) firstElement.getResource().getResource();
1243                     // Network-Network ports --> iOTSi layer SIPs
1244                     sipUuid = new Uuid(UUID.nameUUIDFromBytes((String.join("+", "SIP", tp.getTpNodeId(),
1245                             TapiStringConstants.I_OTSI, tp.getTpId())).getBytes(StandardCharsets.UTF_8)).toString());
1246                     LOG.info("SIP name = {}", String.join("+", tp.getTpNodeId(), TapiStringConstants.I_OTSI,
1247                         tp.getTpId()));
1248                     break;
1249                 case Ethernet:
1250                     LOG.info("Elements ZA = {}", mapztoa.values().toString());
1251                     firstElement = mapztoa.values().stream().filter(ztoa -> ztoa.getId().equals("0")).findFirst()
1252                             .orElseThrow();
1253                     tp = (TerminationPoint) firstElement.getResource().getResource();
1254                     // Client-client ports --> DSR layer SIPs
1255                     sipUuid = new Uuid(UUID.nameUUIDFromBytes((String.join("+", "SIP", tp.getTpNodeId(),
1256                             TapiStringConstants.DSR, tp.getTpId())).getBytes(StandardCharsets.UTF_8)).toString());
1257                     LOG.info("SIP name = {}", String.join("+", tp.getTpNodeId(), TapiStringConstants.DSR,
1258                         tp.getTpId()));
1259                     break;
1260                 default:
1261                     sipUuid = null;
1262                     LOG.warn("Service format {} not supported (?)", serviceFormat.getName());
1263             }
1264             for (ServiceInterfacePoint sip:this.sipMap.values()) {
1265                 if (!sip.getUuid().equals(sipUuid)) {
1266                     LOG.info("SIP {} doesn match sipname {}", sip.getUuid().getValue(), sipUuid.getValue());
1267                     continue;
1268                 }
1269                 zendUuid = sip.getUuid();
1270                 break;
1271             }
1272         }
1273         return zendUuid;
1274     }
1275
1276     private Uuid getSipIdFromAend(Map<AToZKey, AToZ> mapatoz, String serviceNodeId, ServiceFormat serviceFormat) {
1277         Uuid aendUuid = null;
1278         LOG.info("ServiceNode = {} and ServiceFormat = {}", serviceNodeId, serviceFormat.getName());
1279         LOG.info("Map a to z = {}", mapatoz);
1280         if (serviceNodeId.contains("ROADM")) {
1281             // Service from ROADM to ROADM
1282             // AddDrop-AddDrop ports --> MC layer SIPs
1283             AToZ firstElement = mapatoz.values().stream().filter(atoz -> atoz.getId().equals("0")).findFirst()
1284                     .orElseThrow();
1285             LOG.info("First element of service path = {}", firstElement.getResource().getResource());
1286             TerminationPoint tp = (TerminationPoint) firstElement.getResource().getResource();
1287             Uuid sipUuid = new Uuid(UUID.nameUUIDFromBytes((String.join("+", "SIP",
1288                     tp.getTpNodeId(), TapiStringConstants.MC, tp.getTpId())).getBytes(StandardCharsets.UTF_8))
1289                 .toString());
1290             LOG.info("ROADM SIP name = {}", String.join("+", tp.getTpNodeId(), TapiStringConstants.MC,
1291                 tp.getTpId()));
1292             for (ServiceInterfacePoint sip:this.sipMap.values()) {
1293                 if (!sip.getUuid().equals(sipUuid)) {
1294                     LOG.info("SIP {} doesn match sipname {}", sip.getUuid().getValue(), sipUuid.getValue());
1295                     continue;
1296                 }
1297                 aendUuid = sip.getUuid();
1298                 break;
1299             }
1300         } else {
1301             // Service from XPDR to XPDR
1302             AToZ firstElement;
1303             TerminationPoint tp;
1304             Uuid sipUuid;
1305             switch (serviceFormat) {
1306                 case ODU:
1307                     firstElement = mapatoz.values().stream().filter(atoz -> atoz.getId().equals("2")).findFirst()
1308                             .orElseThrow();
1309                     tp = (TerminationPoint) firstElement.getResource().getResource();
1310                     // Network-Network ports --> iODU layer SIPs. TODO -> updated to eODU
1311                     sipUuid = new Uuid(UUID.nameUUIDFromBytes((String.join("+", "SIP", tp.getTpNodeId(),
1312                             TapiStringConstants.I_ODU, tp.getTpId())).getBytes(StandardCharsets.UTF_8)).toString());
1313                     LOG.info("ODU XPDR SIP name = {}", String.join("+", tp.getTpNodeId(),
1314                         TapiStringConstants.I_ODU, tp.getTpId()));
1315                     break;
1316                 case OTU:
1317                     firstElement = mapatoz.values().stream().filter(atoz -> atoz.getId().equals("2")).findFirst()
1318                             .orElseThrow();
1319                     tp = (TerminationPoint) firstElement.getResource().getResource();
1320                     // Network-Network ports --> iOTSi layer SIPs
1321                     sipUuid = new Uuid(UUID.nameUUIDFromBytes((String.join("+", "SIP", tp.getTpNodeId(),
1322                             TapiStringConstants.I_OTSI, tp.getTpId())).getBytes(StandardCharsets.UTF_8)).toString());
1323                     LOG.info("OTU XPDR SIP name = {}", String.join("+", tp.getTpNodeId(),
1324                         TapiStringConstants.I_OTSI, tp.getTpId()));
1325                     break;
1326                 case Ethernet:
1327                     LOG.info("Elements AZ = {}", mapatoz.values().toString());
1328                     firstElement = mapatoz.values().stream().filter(atoz -> atoz.getId().equals("0")).findFirst()
1329                             .orElseThrow();
1330                     tp = (TerminationPoint) firstElement.getResource().getResource();
1331                     // Client-client ports --> DSR layer SIPs
1332                     sipUuid = new Uuid(UUID.nameUUIDFromBytes((String.join("+", "SIP", tp.getTpNodeId(),
1333                             TapiStringConstants.DSR, tp.getTpId())).getBytes(StandardCharsets.UTF_8)).toString());
1334                     LOG.info("DSR XPDR SIP name = {}", String.join("+", tp.getTpNodeId(),
1335                         TapiStringConstants.DSR, tp.getTpId()));
1336                     break;
1337                 default:
1338                     sipUuid = null;
1339                     LOG.warn("Service format {} not supported (?)", serviceFormat.getName());
1340             }
1341             for (ServiceInterfacePoint sip:this.sipMap.values()) {
1342                 if (!sip.getUuid().equals(sipUuid)) {
1343                     LOG.info("SIP {} doesn match sipname {}", sip.getUuid().getValue(), sipUuid.getValue());
1344                     continue;
1345                 }
1346                 aendUuid = sip.getUuid();
1347                 break;
1348             }
1349         }
1350         return aendUuid;
1351     }
1352
1353     private void putRdmCepInTopologyContext(String node, String spcRdmAD, String qual, ConnectionEndPoint cep) {
1354         LOG.info("NEP id before Merge = {}", String.join("+", node, qual, spcRdmAD.split("\\+")[1]));
1355         LOG.info("Node of NEP id before Merge = {}", String.join("+", node, TapiStringConstants.PHTNC_MEDIA));
1356         // Give uuids so that it is easier to look for things: topology uuid, node uuid, nep uuid, cep
1357         Uuid topoUuid = new Uuid(UUID.nameUUIDFromBytes(TapiStringConstants.T0_FULL_MULTILAYER
1358             .getBytes(StandardCharsets.UTF_8)).toString());
1359         Uuid nodeUuid = new Uuid(UUID.nameUUIDFromBytes(String.join("+", node, TapiStringConstants.PHTNC_MEDIA)
1360             .getBytes(StandardCharsets.UTF_8)).toString());
1361         Uuid nepUuid = new Uuid(UUID.nameUUIDFromBytes(String.join("+", node, qual, spcRdmAD.split("\\+")[1])
1362             .getBytes(StandardCharsets.UTF_8)).toString());
1363         this.tapiContext.updateTopologyWithCep(topoUuid, nodeUuid, nepUuid, cep);
1364     }
1365
1366     private void putXpdrCepInTopologyContext(String node, String spcXpdrNet, String qual, String nodeLayer,
1367                                              ConnectionEndPoint cep) {
1368         // Give uuids so that it is easier to look for things: topology uuid, node uuid, nep uuid, cep
1369         Uuid topoUuid = new Uuid(UUID.nameUUIDFromBytes(TapiStringConstants.T0_FULL_MULTILAYER
1370             .getBytes(StandardCharsets.UTF_8)).toString());
1371         Uuid nodeUuid = new Uuid(UUID.nameUUIDFromBytes(String.join("+", node, nodeLayer)
1372             .getBytes(StandardCharsets.UTF_8)).toString());
1373         Uuid nepUuid = new Uuid(UUID.nameUUIDFromBytes(String.join("+", node, qual, spcXpdrNet.split("\\+")[1])
1374             .getBytes(StandardCharsets.UTF_8)).toString());
1375         this.tapiContext.updateTopologyWithCep(topoUuid, nodeUuid, nepUuid, cep);
1376     }
1377
1378     public Map<org.opendaylight.yang.gen.v1.urn
1379         .onf.otcc.yang.tapi.connectivity.rev221121.connectivity.context.ConnectionKey,
1380         org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.connectivity.rev221121.connectivity.context.Connection>
1381             getConnectionFullMap() {
1382         return this.connectionFullMap;
1383     }
1384
1385     private String getIdBasedOnModelVersion(String nodeid) {
1386         return nodeid.matches("[A-Z]{5}-[A-Z0-9]{2}-.*") ? String.join("-", nodeid.split("-")[0],
1387             nodeid.split("-")[1]) : nodeid.split("-")[0];
1388     }
1389
1390     public ServiceCreateInput createORServiceInput(CreateConnectivityServiceInput input, Uuid serviceUuid) {
1391         // TODO: not taking into account all the constraints. Only using EndPoints and Connectivity Constraint.
1392         Map<org.opendaylight.yang.gen.v1.urn
1393             .onf.otcc.yang.tapi.connectivity.rev221121.create.connectivity.service.input.EndPointKey,
1394             org.opendaylight.yang.gen.v1.urn
1395                 .onf.otcc.yang.tapi.connectivity.rev221121.create.connectivity.service.input.EndPoint>
1396             endPointMap = input.getEndPoint();
1397         ConnectionType connType = null;
1398         ServiceFormat serviceFormat = null;
1399         String nodeAid = String.join("+", endPointMap.values().stream().findFirst().orElseThrow().getLocalId(),
1400             TapiStringConstants.DSR);
1401         String nodeZid = String.join("+", endPointMap.values().stream().skip(1).findFirst().orElseThrow().getLocalId(),
1402             TapiStringConstants.DSR);
1403         LOG.debug("Node a = {}", nodeAid);
1404         LOG.debug("Node z = {}", nodeZid);
1405         //switch (constraint.getServiceLayer().getIntValue()) {
1406         switch (input.getLayerProtocolName().getIntValue()) {
1407             case 0:
1408                 LOG.info("ODU");
1409                 connType = ConnectionType.Infrastructure;
1410                 serviceFormat = ServiceFormat.ODU;
1411                 break;
1412             case 1:
1413                 LOG.info("ETH, no need to create OTU and ODU");
1414                 connType = ConnectionType.Service;
1415                 serviceFormat = ServiceFormat.Ethernet;
1416                 break;
1417             case 2:
1418                 LOG.info("DSR, need to create OTU and ODU");
1419                 connType = ConnectionType.Service;
1420                 serviceFormat = ServiceFormat.Ethernet;
1421                 break;
1422             case 3:
1423                 LOG.info("PHOTONIC");
1424                 connType = getConnectionTypePhtnc(endPointMap.values());
1425                 serviceFormat = getServiceFormatPhtnc(endPointMap.values());
1426                 if (serviceFormat.equals(ServiceFormat.OC)) {
1427                     nodeAid = String.join("+", endPointMap.values().stream().findFirst().orElseThrow().getLocalId(),
1428                         TapiStringConstants.PHTNC_MEDIA);
1429                     nodeZid = String.join("+", endPointMap.values().stream().skip(1).findFirst().orElseThrow()
1430                             .getLocalId(), TapiStringConstants.PHTNC_MEDIA);
1431                 } else {
1432                     nodeAid = String.join("+", endPointMap.values().stream().findFirst().orElseThrow().getLocalId(),
1433                         TapiStringConstants.OTSI);
1434                     nodeZid = String.join("+", endPointMap.values().stream().skip(1).findFirst().orElseThrow()
1435                             .getLocalId(), TapiStringConstants.OTSI);
1436                 }
1437                 LOG.debug("Node a photonic = {}", nodeAid);
1438                 LOG.debug("Node z photonic = {}", nodeZid);
1439                 break;
1440             default:
1441                 LOG.info("Service type {} not supported", input.getLayerProtocolName().getName());
1442         }
1443         // Requested Capacity for connectivity service
1444         Uint64 capacity = Uint64.valueOf(Math.abs(
1445             input.getConnectivityConstraint().getRequestedCapacity().getTotalSize().getValue().intValue()));
1446         // map endpoints into service end points. Map the type of service from TAPI to OR
1447         ServiceAEnd serviceAEnd = tapiEndPointToServiceAPoint(endPointMap.values().stream().findFirst().orElseThrow(),
1448             serviceFormat, nodeAid, capacity, input.getLayerProtocolName());
1449         ServiceZEnd serviceZEnd = tapiEndPointToServiceZPoint(endPointMap.values().stream().skip(1).findFirst()
1450                 .orElseThrow(), serviceFormat, nodeZid, capacity, input.getLayerProtocolName());
1451         if (serviceAEnd == null || serviceZEnd == null) {
1452             LOG.error("Couldnt map endpoints to service end");
1453             return null;
1454         }
1455         LOG.info("Service a end = {}", serviceAEnd);
1456         LOG.info("Service z end = {}", serviceZEnd);
1457         return new ServiceCreateInputBuilder()
1458             .setServiceAEnd(serviceAEnd)
1459             .setServiceZEnd(serviceZEnd)
1460             .setConnectionType(connType)
1461             .setServiceName(serviceUuid.getValue())
1462             .setCommonId("common id")
1463             .setSdncRequestHeader(new SdncRequestHeaderBuilder().setRequestId("request-1")
1464                 .setRpcAction(RpcActions.ServiceCreate).setNotificationUrl("notification url")
1465                 .setRequestSystemId("appname")
1466                 .build())
1467             .setCustomer("customer")
1468             .setDueDate(DateAndTime.getDefaultInstance("2018-06-15T00:00:01Z"))
1469             .setOperatorContact("pw1234")
1470             .build();
1471     }
1472
1473     private ServiceZEnd tapiEndPointToServiceZPoint(
1474         org.opendaylight.yang.gen.v1.urn
1475             .onf.otcc.yang.tapi.connectivity.rev221121.create.connectivity.service.input.EndPoint endPoint,
1476         ServiceFormat serviceFormat, String nodeZid, Uint64 capacity, LayerProtocolName serviceLayer) {
1477         // TODO -> change way this is being created. The name includes only SPDR-SA1-XPDR1.
1478         //  Not the rest which is needed in the txPortDeviceName.
1479         //  It could be obtained from the SIP which has the NEP and includes all the OR name.
1480         Uuid sipUuid = endPoint.getServiceInterfacePoint().getServiceInterfacePointUuid();
1481         // Todo -> need to find the NEP associated to that SIP
1482         Uuid nodeUuid = new Uuid(UUID.nameUUIDFromBytes(nodeZid.getBytes(StandardCharsets.UTF_8)).toString());
1483         org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.topology.rev221121.topology.Node node =
1484             this.tapiContext.getTapiNode(this.tapiTopoUuid, nodeUuid);
1485         if (node == null) {
1486             LOG.error("Node not found in datastore");
1487             return null;
1488         }
1489         // TODO -> in case of a DSR service, for some requests we need the NETWORK PORT and not the CLIENT although the
1490         //  connection is between 2 CLIENT ports. Otherwise it will not work...
1491         OwnedNodeEdgePoint nep = null;
1492         for (OwnedNodeEdgePoint onep : node.getOwnedNodeEdgePoint().values()) {
1493             if (onep.getMappedServiceInterfacePoint() == null) {
1494                 continue;
1495             }
1496             if (onep.getMappedServiceInterfacePoint().containsKey(new MappedServiceInterfacePointKey(sipUuid))) {
1497                 nep = onep;
1498                 break;
1499             }
1500         }
1501         if (nep == null) {
1502             LOG.error("Nep not found in datastore");
1503             return null;
1504         }
1505         String nodeName = endPoint.getName().values().stream().findFirst().orElseThrow().getValue();
1506         String nodeid = String.join("-", nodeName.split("-")[0], nodeName.split("-")[1]);
1507         String nepName = nep.getName().values().stream().findFirst().orElseThrow().getValue();
1508         String txPortDeviceName = nepName.split("\\+")[0];
1509         String txPortName = nepName.split("\\+")[2];
1510         String rxPortDeviceName = txPortDeviceName;
1511         String rxPortName = txPortName;
1512         LOG.debug("Node z id = {}, txportDeviceName = {}, txPortName = {}", nodeid, txPortDeviceName, txPortName);
1513         LOG.debug("Node z id = {}, rxportDeviceName = {}, rxPortName = {}", nodeid, rxPortDeviceName, rxPortName);
1514         // TODO --> get clli from datastore?
1515         String clli = "NodeSC";
1516         LOG.info("Node z id = {}, txportDeviceName = {}, txPortName = {}", nodeid, txPortDeviceName, txPortName);
1517         LOG.info("Node z id = {}, rxportDeviceName = {}, rxPortName = {}", nodeid, rxPortDeviceName, rxPortName);
1518         ServiceZEndBuilder serviceZEndBuilder = new ServiceZEndBuilder()
1519             .setClli(clli)
1520             .setNodeId(new NodeIdType(nodeid))
1521             .setOpticType(OpticTypes.Gray)
1522             .setServiceFormat(serviceFormat)
1523             .setServiceRate(Uint32.valueOf(capacity))
1524             .setEthernetAttributes(new EthernetAttributesBuilder().setSubrateEthSla(new SubrateEthSlaBuilder()
1525                     .setCommittedBurstSize(Uint16.valueOf(64))
1526                     .setCommittedInfoRate(Uint32.valueOf(100000))
1527                     .build())
1528                 .build())
1529             .setTxDirection(Map.of(new TxDirectionKey(Uint8.ZERO), new TxDirectionBuilder()
1530                 .setPort(new PortBuilder()
1531                     .setPortDeviceName(txPortDeviceName)
1532                     .setPortName(txPortName)
1533                     .setPortRack(TapiStringConstants.PORT_RACK_VALUE)
1534                     .setPortShelf("00")
1535                     .setPortType(TapiStringConstants.PORT_TYPE)
1536                     .build())
1537                 .setLgx(new LgxBuilder()
1538                     .setLgxDeviceName(TapiStringConstants.LGX_DEVICE_NAME)
1539                     .setLgxPortName(TapiStringConstants.LGX_PORT_NAME)
1540                     .setLgxPortRack(TapiStringConstants.PORT_RACK_VALUE)
1541                     .setLgxPortShelf("00")
1542                     .build())
1543                 .setIndex(Uint8.ZERO)
1544                 .build()))
1545             .setRxDirection(Map.of(new RxDirectionKey(Uint8.ZERO), new RxDirectionBuilder()
1546                 .setPort(new PortBuilder()
1547                     .setPortDeviceName(rxPortDeviceName)
1548                     .setPortName(rxPortName)
1549                     .setPortRack(TapiStringConstants.PORT_RACK_VALUE)
1550                     .setPortShelf("00")
1551                     .setPortType(TapiStringConstants.PORT_TYPE)
1552                     .build())
1553                 .setLgx(new LgxBuilder()
1554                     .setLgxDeviceName(TapiStringConstants.LGX_DEVICE_NAME)
1555                     .setLgxPortName(TapiStringConstants.LGX_PORT_NAME)
1556                     .setLgxPortRack(TapiStringConstants.PORT_RACK_VALUE)
1557                     .setLgxPortShelf("00")
1558                     .build())
1559                 .setIndex(Uint8.ZERO)
1560                 .build()));
1561         if (serviceFormat.equals(ServiceFormat.ODU)) {
1562             serviceZEndBuilder.setOduServiceRate(ODU4.VALUE);
1563         }
1564         if (serviceFormat.equals(ServiceFormat.OTU)) {
1565             serviceZEndBuilder.setOtuServiceRate(OTU4.VALUE);
1566         }
1567         if (!serviceLayer.equals(LayerProtocolName.ETH)) {
1568             serviceZEndBuilder
1569                 .setEthernetAttributes(new EthernetAttributesBuilder().setSubrateEthSla(new SubrateEthSlaBuilder()
1570                         .setCommittedBurstSize(Uint16.valueOf(64))
1571                         .setCommittedInfoRate(Uint32.valueOf(100000))
1572                         .build())
1573                     .build());
1574         }
1575         return serviceZEndBuilder.build();
1576     }
1577
1578     private ServiceAEnd tapiEndPointToServiceAPoint(
1579         org.opendaylight.yang.gen.v1.urn
1580             .onf.otcc.yang.tapi.connectivity.rev221121.create.connectivity.service.input.EndPoint endPoint,
1581         ServiceFormat serviceFormat, String nodeAid, Uint64 capacity, LayerProtocolName serviceLayer) {
1582         // TODO -> change way this is being created. The name includes only SPDR-SA1-XPDR1.
1583         //  Not the rest which is needed in the txPortDeviceName.
1584         //  It could be obtained from the SIP which has the NEP and includes all the OR name.
1585         Uuid sipUuid = endPoint.getServiceInterfacePoint().getServiceInterfacePointUuid();
1586         // Todo -> need to find the NEP associated to that SIP
1587         Uuid nodeUuid = new Uuid(UUID.nameUUIDFromBytes(nodeAid.getBytes(StandardCharsets.UTF_8)).toString());
1588         org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.topology.rev221121.topology.Node node =
1589             this.tapiContext.getTapiNode(this.tapiTopoUuid, nodeUuid);
1590         if (node == null) {
1591             LOG.error("Node not found in datastore");
1592             return null;
1593         }
1594         // TODO -> in case of a DSR service, for some requests we need the NETWORK PORT and not the CLIENT although the
1595         //  connection is between 2 CLIENT ports. Otherwise it will not work...
1596         OwnedNodeEdgePoint nep = null;
1597         for (OwnedNodeEdgePoint onep : node.getOwnedNodeEdgePoint().values()) {
1598             if (onep.getMappedServiceInterfacePoint() == null) {
1599                 continue;
1600             }
1601             if (onep.getMappedServiceInterfacePoint().containsKey(new MappedServiceInterfacePointKey(sipUuid))) {
1602                 nep = onep;
1603                 break;
1604             }
1605         }
1606         if (nep == null) {
1607             LOG.error("Nep not found in datastore");
1608             return null;
1609         }
1610         String nodeName = endPoint.getName().values().stream().findFirst().orElseThrow().getValue();
1611         String nodeid = String.join("-", nodeName.split("-")[0], nodeName.split("-")[1]);
1612         String nepName = nep.getName().values().stream().findFirst().orElseThrow().getValue();
1613         String txPortDeviceName = nepName.split("\\+")[0];
1614         String txPortName = nepName.split("\\+")[2];
1615         String rxPortDeviceName = txPortDeviceName;
1616         String rxPortName = txPortName;
1617         LOG.debug("Node a id = {}, txportDeviceName = {}, txPortName = {}", nodeid, txPortDeviceName, txPortName);
1618         LOG.debug("Node a id = {}, rxportDeviceName = {}, rxPortName = {}", nodeid, rxPortDeviceName, rxPortName);
1619         // TODO --> get clli from datastore?
1620         String clli = "NodeSA";
1621         LOG.info("Node a id = {}, txportDeviceName = {}, txPortName = {}", nodeid, txPortDeviceName, txPortName);
1622         LOG.info("Node a id = {}, rxportDeviceName = {}, rxPortName = {}", nodeid, rxPortDeviceName, rxPortName);
1623         ServiceAEndBuilder serviceAEndBuilder = new ServiceAEndBuilder()
1624             .setClli(clli)
1625             .setNodeId(new NodeIdType(nodeid))
1626             .setOpticType(OpticTypes.Gray)
1627             .setServiceFormat(serviceFormat)
1628             .setServiceRate(Uint32.valueOf(capacity))
1629             .setEthernetAttributes(new EthernetAttributesBuilder().setSubrateEthSla(
1630                     new org.opendaylight.yang.gen.v1.http.org.openroadm.common.service.types.rev230526.subrate.eth
1631                         .sla.SubrateEthSlaBuilder()
1632                         .setCommittedBurstSize(Uint16.valueOf(64))
1633                         .setCommittedInfoRate(Uint32.valueOf(100000))
1634                         .build())
1635                 .build())
1636             .setTxDirection(Map.of(new TxDirectionKey(Uint8.ZERO), new TxDirectionBuilder()
1637                 .setPort(new PortBuilder()
1638                     .setPortDeviceName(txPortDeviceName)
1639                     .setPortName(txPortName)
1640                     .setPortRack(TapiStringConstants.PORT_RACK_VALUE)
1641                     .setPortShelf("00")
1642                     .setPortType(TapiStringConstants.PORT_TYPE)
1643                     .build())
1644                 .setLgx(new LgxBuilder()
1645                     .setLgxDeviceName(TapiStringConstants.LGX_DEVICE_NAME)
1646                     .setLgxPortName(TapiStringConstants.LGX_PORT_NAME)
1647                     .setLgxPortRack(TapiStringConstants.PORT_RACK_VALUE)
1648                     .setLgxPortShelf("00")
1649                     .build())
1650                 .setIndex(Uint8.ZERO)
1651                 .build()))
1652             .setRxDirection(Map.of(new RxDirectionKey(Uint8.ZERO), new RxDirectionBuilder()
1653                 .setPort(new PortBuilder()
1654                     .setPortDeviceName(rxPortDeviceName)
1655                     .setPortName(rxPortName)
1656                     .setPortRack(TapiStringConstants.PORT_RACK_VALUE)
1657                     .setPortShelf("00")
1658                     .setPortType(TapiStringConstants.PORT_TYPE)
1659                     .build())
1660                 .setLgx(new LgxBuilder()
1661                     .setLgxDeviceName(TapiStringConstants.LGX_DEVICE_NAME)
1662                     .setLgxPortName(TapiStringConstants.LGX_PORT_NAME)
1663                     .setLgxPortRack(TapiStringConstants.PORT_RACK_VALUE)
1664                     .setLgxPortShelf("00")
1665                     .build())
1666                 .setIndex(Uint8.ZERO)
1667                 .build()));
1668         if (serviceFormat.equals(ServiceFormat.ODU)) {
1669             serviceAEndBuilder.setOduServiceRate(ODU4.VALUE);
1670         } else if (serviceFormat.equals(ServiceFormat.OTU)) {
1671             serviceAEndBuilder.setOtuServiceRate(OTU4.VALUE);
1672         }
1673         if (!serviceLayer.equals(LayerProtocolName.ETH)) {
1674             serviceAEndBuilder
1675                 .setEthernetAttributes(new EthernetAttributesBuilder().setSubrateEthSla(new SubrateEthSlaBuilder()
1676                         .setCommittedBurstSize(Uint16.valueOf(64))
1677                         .setCommittedInfoRate(Uint32.valueOf(100000))
1678                         .build())
1679                     .build());
1680         }
1681         return serviceAEndBuilder.build();
1682     }
1683
1684     private ConnectionType getConnectionTypePhtnc(Collection<org.opendaylight.yang.gen.v1.urn
1685             .onf.otcc.yang.tapi.connectivity.rev221121.create.connectivity.service.input.EndPoint> endPoints) {
1686         if (endPoints.stream().anyMatch(ep -> ep.getName().values().stream()
1687                 .anyMatch(name -> name.getValue().contains("ROADM")))) {
1688             // EndPoints are ROADMs
1689             return ConnectionType.RoadmLine;
1690         }
1691         // EndPoints ar not ROADMs -> XPDR, MUXPDR, SWTICHPDR
1692         return ConnectionType.Infrastructure;
1693     }
1694
1695     private ServiceFormat getServiceFormatPhtnc(Collection<org.opendaylight.yang.gen.v1.urn
1696             .onf.otcc.yang.tapi.connectivity.rev221121.create.connectivity.service.input.EndPoint> endPoints) {
1697         if (endPoints.stream().anyMatch(ep -> ep.getName().values().stream()
1698                 .anyMatch(name -> name.getValue().contains("ROADM")))) {
1699             // EndPoints are ROADMs
1700             return ServiceFormat.OC;
1701         }
1702         // EndPoints ar not ROADMs -> XPDR, MUXPDR, SWTICHPDR
1703         return ServiceFormat.OTU;
1704     }
1705
1706     private ConnectionEndPoint getAssociatediODUCep(String spcXpdrNetwork) {
1707         Uuid nodeUuid = new Uuid(UUID.nameUUIDFromBytes((String.join("+", spcXpdrNetwork.split("\\+")[0],
1708             TapiStringConstants.DSR).getBytes(StandardCharsets.UTF_8))).toString());
1709         Uuid nepUuid = new Uuid(UUID.nameUUIDFromBytes((String.join("+", spcXpdrNetwork.split("\\+")[0],
1710                 TapiStringConstants.I_ODU, spcXpdrNetwork.split("\\+")[1]).getBytes(StandardCharsets.UTF_8)))
1711             .toString());
1712         Uuid cepUuid = new Uuid(UUID.nameUUIDFromBytes((String.join("+", "CEP",
1713             spcXpdrNetwork.split("\\+")[0], TapiStringConstants.I_ODU, spcXpdrNetwork.split("\\+")[1]))
1714             .getBytes(StandardCharsets.UTF_8)).toString());
1715         return this.tapiContext.getTapiCEP(this.tapiTopoUuid, nodeUuid, nepUuid, cepUuid);
1716     }
1717
1718     private String getAssociatedNetworkPort(String spcXpdrClient, List<String> xpdrNetworkTplist) {
1719         for (String networkPort:xpdrNetworkTplist) {
1720             if (networkPort.split("\\+")[0].equals(spcXpdrClient.split("\\+")[0])) {
1721                 return networkPort;
1722             }
1723         }
1724         return null;
1725     }
1726
1727     private List<String> getAssociatedClientsPort(List<String> xpdrNetworkTplist) {
1728         List<String> clientPortList = new ArrayList<>();
1729         for (String networkPort:xpdrNetworkTplist) {
1730             String nodeId = String.join("-", networkPort.split("\\+")[0].split("-")[0],
1731                 networkPort.split("\\+")[0].split("-")[1]);
1732             String tpId = networkPort.split("\\+")[1];
1733             InstanceIdentifier<Mapping> mapIID = InstanceIdentifier.builder(Network.class)
1734                 .child(Nodes.class, new NodesKey(nodeId))
1735                 .child(Mapping.class, new MappingKey(tpId)).build();
1736             try {
1737                 Optional<Mapping> optMapping = this.networkTransactionService.read(LogicalDatastoreType.CONFIGURATION,
1738                     mapIID).get();
1739                 if (!optMapping.isPresent()) {
1740                     LOG.error("Couldnt find mapping for port {} of node {}", tpId, nodeId);
1741                 }
1742                 Mapping mapping = optMapping.orElseThrow();
1743                 LOG.info("Mapping for node+port {}+{} = {}", nodeId, tpId, mapping);
1744                 String key = String.join("+", String.join("-", nodeId, tpId.split("\\-")[0]),
1745                     mapping.getConnectionMapLcp());
1746                 LOG.info("Key to be added to list = {}", key);
1747                 if (!clientPortList.contains(key)) {
1748                     clientPortList.add(key);
1749                 }
1750             } catch (InterruptedException | ExecutionException e) {
1751                 LOG.error("Couldnt read mapping from datastore", e);
1752                 return null;
1753             }
1754
1755         }
1756         return clientPortList;
1757     }
1758
1759     private OpenroadmNodeType getOpenRoadmNodeType(List<String> xpdrNodelist) {
1760         List<OpenroadmNodeType> openroadmNodeTypeList = new ArrayList<>();
1761         for (String xpdrNode:xpdrNodelist) {
1762             Uuid nodeUuid = new Uuid(UUID.nameUUIDFromBytes((String.join("+",xpdrNode, TapiStringConstants.DSR))
1763                 .getBytes(StandardCharsets.UTF_8)).toString());
1764             InstanceIdentifier<org.opendaylight.yang.gen.v1.urn
1765                 .onf.otcc.yang.tapi.topology.rev221121.topology.Node> nodeIID = InstanceIdentifier.builder(
1766                     Context.class).augmentation(org.opendaylight.yang.gen.v1.urn
1767                     .onf.otcc.yang.tapi.topology.rev221121.Context1.class).child(TopologyContext.class)
1768                 .child(Topology.class, new TopologyKey(this.tapiTopoUuid))
1769                 .child(org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.topology.rev221121.topology.Node.class,
1770                     new NodeKey(nodeUuid)).build();
1771             try {
1772                 Optional<org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.topology.rev221121.topology.Node> optNode
1773                     = this.networkTransactionService.read(LogicalDatastoreType.OPERATIONAL, nodeIID).get();
1774                 if (optNode.isEmpty()) {
1775                     return null;
1776                 }
1777                 OpenroadmNodeType openroadmNodeType = OpenroadmNodeType.forName(optNode.orElseThrow().getName().get(
1778                     new NameKey("Node Type")).getValue());
1779                 if (!openroadmNodeTypeList.contains(openroadmNodeType)) {
1780                     openroadmNodeTypeList.add(openroadmNodeType);
1781                 }
1782             } catch (InterruptedException | ExecutionException e) {
1783                 LOG.error("Couldnt read node in topology", e);
1784                 return null;
1785             }
1786         }
1787         // TODO for now check that there is only one type, otherwise error
1788         if (openroadmNodeTypeList.size() != 1) {
1789             LOG.error("More than one xpdr type. List = {}", openroadmNodeTypeList);
1790             return null;
1791         }
1792         return openroadmNodeTypeList.get(0);
1793     }
1794 }