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