2 * Copyright © 2021 Nokia, Inc. and others. All rights reserved.
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
8 package org.opendaylight.transportpce.tapi.listeners;
10 import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
11 import java.nio.charset.Charset;
12 import java.util.ArrayList;
13 import java.util.Comparator;
14 import java.util.HashMap;
15 import java.util.List;
17 import java.util.Optional;
18 import java.util.UUID;
19 import java.util.concurrent.ExecutionException;
20 import java.util.stream.Collectors;
21 import org.opendaylight.mdsal.binding.api.DataBroker;
22 import org.opendaylight.mdsal.common.api.LogicalDatastoreType;
23 import org.opendaylight.transportpce.common.network.NetworkTransactionImpl;
24 import org.opendaylight.transportpce.common.network.NetworkTransactionService;
25 import org.opendaylight.transportpce.common.network.RequestProcessor;
26 import org.opendaylight.transportpce.tapi.TapiStringConstants;
27 import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.pce.rev210701.ServicePathRpcResult;
28 import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.pce.rev210701.TransportpcePceListener;
29 import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.pce.rev210701.service.path.rpc.result.PathDescription;
30 import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.pce.rev210701.service.path.rpc.result.PathDescriptionBuilder;
31 import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.portmapping.rev210927.Network;
32 import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.portmapping.rev210927.mapping.Mapping;
33 import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.portmapping.rev210927.mapping.MappingKey;
34 import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.portmapping.rev210927.network.Nodes;
35 import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.portmapping.rev210927.network.NodesKey;
36 import org.opendaylight.yang.gen.v1.http.org.openroadm.network.types.rev200529.OpenroadmNodeType;
37 import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.pathdescription.rev210705.path.description.atoz.direction.AToZ;
38 import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.pathdescription.rev210705.pce.resource.resource.resource.Node;
39 import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.pathdescription.rev210705.pce.resource.resource.resource.TerminationPoint;
40 import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.service.types.rev200128.RpcStatusEx;
41 import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.common.rev181210.Context;
42 import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.common.rev181210.ForwardingDirection;
43 import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.common.rev181210.LayerProtocolName;
44 import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.common.rev181210.LifecycleState;
45 import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.common.rev181210.OperationalState;
46 import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.common.rev181210.PortDirection;
47 import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.common.rev181210.PortRole;
48 import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.common.rev181210.Uuid;
49 import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.common.rev181210.global._class.Name;
50 import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.common.rev181210.global._class.NameBuilder;
51 import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.common.rev181210.global._class.NameKey;
52 import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.connectivity.rev181210.Context1;
53 import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.connectivity.rev181210.CreateConnectivityServiceInput;
54 import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.connectivity.rev181210.OwnedNodeEdgePoint1;
55 import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.connectivity.rev181210.OwnedNodeEdgePoint1Builder;
56 import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.connectivity.rev181210.cep.list.ConnectionEndPoint;
57 import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.connectivity.rev181210.cep.list.ConnectionEndPointBuilder;
58 import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.connectivity.rev181210.connection.ConnectionEndPointKey;
59 import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.connectivity.rev181210.connection.LowerConnection;
60 import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.connectivity.rev181210.connection.LowerConnectionBuilder;
61 import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.connectivity.rev181210.connection.LowerConnectionKey;
62 import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.connectivity.rev181210.connection.end.point.ClientNodeEdgePoint;
63 import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.connectivity.rev181210.connection.end.point.ClientNodeEdgePointBuilder;
64 import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.connectivity.rev181210.connectivity.context.ConnectivityService;
65 import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.connectivity.rev181210.connectivity.context.ConnectivityServiceBuilder;
66 import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.connectivity.rev181210.connectivity.context.ConnectivityServiceKey;
67 import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.connectivity.rev181210.connectivity.service.Connection;
68 import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.connectivity.rev181210.connectivity.service.ConnectionBuilder;
69 import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.connectivity.rev181210.connectivity.service.ConnectionKey;
70 import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.connectivity.rev181210.context.ConnectivityContextBuilder;
71 import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.connectivity.rev181210.context.topology.context.topology.node.owned.node.edge.point.CepList;
72 import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.connectivity.rev181210.context.topology.context.topology.node.owned.node.edge.point.CepListBuilder;
73 import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.topology.rev181210.context.TopologyContext;
74 import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.topology.rev181210.node.OwnedNodeEdgePoint;
75 import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.topology.rev181210.node.OwnedNodeEdgePointBuilder;
76 import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.topology.rev181210.node.OwnedNodeEdgePointKey;
77 import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.topology.rev181210.topology.NodeKey;
78 import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.topology.rev181210.topology.context.Topology;
79 import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.topology.rev181210.topology.context.TopologyKey;
80 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
81 import org.slf4j.Logger;
82 import org.slf4j.LoggerFactory;
84 public class TapiPceListenerImpl implements TransportpcePceListener {
86 private static final Logger LOG = LoggerFactory.getLogger(TapiPceListenerImpl.class);
88 private final Uuid tapiTopoUuid = new Uuid(UUID.nameUUIDFromBytes(TapiStringConstants.T0_FULL_MULTILAYER
89 .getBytes(Charset.forName("UTF-8"))).toString());
90 private ServicePathRpcResult servicePathRpcResult;
91 private CreateConnectivityServiceInput input;
92 private Uuid serviceUuid;
93 private final DataBroker dataBroker;
94 private final NetworkTransactionService networkTransactionService;
95 private final Map<org.opendaylight.yang.gen.v1.urn
96 .onf.otcc.yang.tapi.connectivity.rev181210.connectivity.context.ConnectionKey,
97 org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.connectivity.rev181210.connectivity.context.Connection>
98 connectionFullMap; // this variable is for complete connection objects
100 public TapiPceListenerImpl(DataBroker dataBroker) {
101 this.connectionFullMap = new HashMap<>();
102 this.dataBroker = dataBroker;
103 this.networkTransactionService = new NetworkTransactionImpl(new RequestProcessor(this.dataBroker));
107 public void onServicePathRpcResult(ServicePathRpcResult notification) {
108 if (compareServicePathRpcResult(notification)) {
109 LOG.warn("ServicePathRpcResult already wired !");
112 servicePathRpcResult = notification;
113 switch (servicePathRpcResult.getNotificationType().getIntValue()) {
114 /* path-computation-request. */
116 onPathComputationResult(notification);
118 /* cancel-resource-reserve. */
120 onCancelResourceResult(notification.getServiceName());
128 * Process path computation request result.
129 * @param notification the result notification.
131 private void onPathComputationResult(ServicePathRpcResult notification) {
132 this.connectionFullMap.clear();
133 LOG.info("PCE '{}' Notification received : {}",servicePathRpcResult.getNotificationType().getName(),
135 if (servicePathRpcResult.getStatus() == RpcStatusEx.Failed) {
136 LOG.error("PCE path computation failed !");
138 } else if (servicePathRpcResult.getStatus() == RpcStatusEx.Pending) {
139 LOG.warn("PCE path computation returned a Penging RpcStatusEx code!");
141 } else if (servicePathRpcResult.getStatus() != RpcStatusEx.Successful) {
142 LOG.error("PCE path computation returned an unknown RpcStatusEx code!");
146 LOG.info("PCE calculation done OK !");
147 if (servicePathRpcResult.getPathDescription() == null) {
148 LOG.error("'PathDescription' parameter is null ");
151 PathDescription pathDescription = new PathDescriptionBuilder()
152 .setAToZDirection(servicePathRpcResult.getPathDescription().getAToZDirection())
153 .setZToADirection(servicePathRpcResult.getPathDescription().getZToADirection())
155 LOG.info("PathDescription for TAPI gets : {}", pathDescription);
157 LOG.error("Input is null !");
160 // TODO: check kind of service: based on the device Id of the input,
161 // verify the type of XPDR and the capacity and determine if it is an OTN service or pure WDM service
162 // Create connections and ceps for the connectivity service.
163 // Connections must be with a locked stated. As the renderer hasnt implemented yet the oc's
164 Map<ConnectionKey, Connection> connectionMap = createConnectionsAndCepsForService(pathDescription,
165 input.getConnectivityConstraint().getServiceLayer());
166 // add connections to connection context and to connectivity context
167 updateConnectionContextWithConn(this.connectionFullMap, connectionMap, serviceUuid);
170 private Map<ConnectionKey, Connection> createConnectionsAndCepsForService(PathDescription pathDescription,
171 LayerProtocolName serviceProtName) {
172 Map<ConnectionKey, Connection> connectionServMap = new HashMap<>();
173 // build lists with ROADM nodes, XPDR/MUX/SWITCH nodes, ROADM DEG TTPs, ROADM SRG TTPs, XPDR CLIENT TTPs
174 // and XPDR NETWORK TTPs (if any). From the path description. This will help to build the uuid of the CEPs
175 // and the connections
177 List<String> xpdrClientTplist = new ArrayList<>();
178 List<String> xpdrNetworkTplist = new ArrayList<>();
179 List<String> rdmAddDropTplist = new ArrayList<>();
180 List<String> rdmDegTplist = new ArrayList<>();
181 List<String> rdmNodelist = new ArrayList<>();
182 List<String> xpdrNodelist = new ArrayList<>();
183 for (AToZ elem:pathDescription.getAToZDirection().getAToZ().values().stream()
184 .sorted(Comparator.comparing(AToZ::getId)).collect(Collectors.toList())) {
185 resourceType = elem.getResource().getResource().implementedInterface().getSimpleName();
186 switch (resourceType) {
187 case TapiStringConstants.TP:
188 TerminationPoint tp = (TerminationPoint) elem.getResource().getResource();
189 String tpID = tp.getTpId();
191 if (tpID.contains("CLIENT")) {
192 tpNode = tp.getTpNodeId();
193 if (!xpdrClientTplist.contains(String.join("+", tpNode, tpID))) {
194 xpdrClientTplist.add(String.join("+", tpNode, tpID));
197 if (tpID.contains("NETWORK")) {
198 tpNode = tp.getTpNodeId();
199 if (!xpdrNetworkTplist.contains(String.join("+", tpNode, tpID))) {
200 xpdrNetworkTplist.add(String.join("+", tpNode, tpID));
203 if (tpID.contains("PP")) {
204 tpNode = getIdBasedOnModelVersion(tp.getTpNodeId());
205 LOG.info("ROADM Node of tp = {}", tpNode);
206 if (!rdmAddDropTplist.contains(String.join("+", tpNode, tpID))) {
207 rdmAddDropTplist.add(String.join("+", tpNode, tpID));
210 if (tpID.contains("TTP")) {
211 tpNode = getIdBasedOnModelVersion(tp.getTpNodeId());
212 LOG.info("ROADM Node of tp = {}", tpNode);
213 if (!rdmDegTplist.contains(String.join("+", tpNode, tpID))) {
214 rdmDegTplist.add(String.join("+", tpNode, tpID));
218 case TapiStringConstants.NODE:
219 Node node = (Node) elem.getResource().getResource();
220 String nodeId = node.getNodeId();
221 if (nodeId.contains("XPDR") || nodeId.contains("SPDR") || nodeId.contains("MXPDR")) {
222 LOG.info("Node id = {}", nodeId);
223 if (!xpdrNodelist.contains(nodeId)) {
224 xpdrNodelist.add(nodeId); // should contain only 2
227 if (nodeId.contains("ROADM")) {
228 nodeId = getIdBasedOnModelVersion(nodeId);
229 LOG.info("Node id = {}", nodeId);
230 if (!rdmNodelist.contains(nodeId)) {
231 rdmNodelist.add(nodeId);
236 LOG.warn("Resource is a {}", resourceType);
239 LOG.info("ROADM node list = {}", rdmNodelist.toString());
240 LOG.info("ROADM degree list = {}", rdmDegTplist.toString());
241 LOG.info("ROADM addrop list = {}", rdmAddDropTplist.toString());
242 LOG.info("XPDR node list = {}", xpdrNodelist.toString());
243 LOG.info("XPDR network list = {}", xpdrNetworkTplist.toString());
244 LOG.info("XPDR client list = {}", xpdrClientTplist.toString());
245 // TODO -> for 10GB eth and ODU services there are no ROADMs in path description as they use the OTU link,
246 // but for 100GB eth all is created at once. Check if the roadm list is empty to determine whether we need
247 // to trigger all the steps or not
248 String edgeRoadm1 = "";
249 String edgeRoadm2 = "";
250 if (!rdmNodelist.isEmpty()) {
251 edgeRoadm1 = rdmNodelist.get(0);
252 edgeRoadm2 = rdmNodelist.get(rdmNodelist.size() - 1);
253 LOG.info("edgeRoadm1 = {}", edgeRoadm1);
254 LOG.info("edgeRoadm2 = {}", edgeRoadm2);
256 // create corresponding CEPs and Connections. Connections should be added to the corresponding context
257 // CEPs must be included in the topology context as an augmentation for each ONEP!!
258 // TODO -> Maybe we dont need to create the connections and ceps if the previous service doesnt exist??
259 // As mentioned above, for 100GbE service creation there are ROADMs in the path description.
260 // What are the configurations needed here? No OTU, ODU... what kind of cross connections is needed?
261 // this needs to be changed
263 // TODO: OpenROADM getNodeType from the NamesList to verify what needs to be created
264 OpenroadmNodeType openroadmNodeType = getOpenRoadmNodeType(xpdrNodelist);
265 switch (serviceProtName) {
267 // Identify number of ROADMs
268 // - XC Connection between MC CEPs mapped from MC NEPs (within a roadm)
269 // - XC Connection between OTSiMC CEPs mapped from OTSiMC NEPs (within a roadm)
270 // - Top Connection MC betwwen MC CEPs of different roadms
271 // - Top Connection OTSiMC betwwen OTSiMC CEPs of extreme roadms
272 connectionServMap.putAll(createRoadmCepsAndConnections(rdmAddDropTplist, rdmDegTplist, rdmNodelist,
273 edgeRoadm1, edgeRoadm2));
274 if (!pathDescription.getAToZDirection().getAToZ().values().stream().findFirst().get().getId()
275 .contains("ROADM")) {
276 // - XC Connection OTSi betwwen iOTSi y eOTSi of xpdr
277 // - Top connection OTSi between network ports of xpdrs in the Photonic media layer -> i_OTSi
278 connectionServMap.putAll(createXpdrCepsAndConnectionsPht(xpdrNetworkTplist, xpdrNodelist));
282 LOG.info("OTN ODU service");
283 // - XC Connection OTSi between iODU and eODU of xpdr
284 // - Top connection in the ODU layer, between xpdr iODU ports
285 connectionServMap.putAll(createXpdrCepsAndConnectionsOdu(xpdrNetworkTplist, xpdrNodelist));
288 LOG.info("WDM service");
289 if (openroadmNodeType.equals(OpenroadmNodeType.TPDR)) {
290 // TODO: WDM service. Only och/otu4 needed and then directly DSR top connection.
291 // Need to find the associated client ports of the network port
292 // - Same as for PHOTONIC MEDIA service
293 // - Do we nedd cross connection in the ODU layer??
294 // - Top connection DSR between client ports of the transponder
295 connectionServMap.putAll(createRoadmCepsAndConnections(rdmAddDropTplist, rdmDegTplist, rdmNodelist,
296 edgeRoadm1, edgeRoadm2));
297 connectionServMap.putAll(createXpdrCepsAndConnectionsPht(xpdrNetworkTplist, xpdrNodelist));
298 xpdrClientTplist = getAssociatedClientsPort(xpdrNetworkTplist);
299 LOG.info("Associated client ports = {}", xpdrClientTplist);
300 connectionServMap.putAll(createXpdrCepsAndConnectionsEth(xpdrClientTplist, xpdrNodelist,
305 LOG.info("OTN XGE/ODUe service");
306 // - XC connection between iODU and eODU
307 // - Top connection between eODU ports
308 // - Top connection between DSR ports
309 if (openroadmNodeType.equals(OpenroadmNodeType.SWITCH)) {
310 // TODO: We create both ODU and DSR because there is no ODU service creation for the switch
311 // - XC Connection OTSi betwwen iODU and eODU of xpdr
312 // - Top connection in the ODU layer, between xpdr eODU ports (?)
313 connectionServMap.putAll(createXpdrCepsAndConnectionsOdu(xpdrNetworkTplist, xpdrNodelist));
314 connectionServMap.putAll(createXpdrCepsAndConnectionsDsr(xpdrClientTplist, xpdrNetworkTplist,
317 if (openroadmNodeType.equals(OpenroadmNodeType.MUXPDR)) {
318 // TODO: OTN service but mux has 3 steps at rendering. Verify that things exist
319 connectionServMap.putAll(createXpdrCepsAndConnectionsDsr(xpdrClientTplist, xpdrNetworkTplist,
324 LOG.error("Service type format {} not supported", serviceProtName.getName());
326 return connectionServMap;
330 * Process cancel resource result.
331 * @param serviceName Service name to build uuid.
333 private void onCancelResourceResult(String serviceName) {
334 if (servicePathRpcResult.getStatus() == RpcStatusEx.Failed) {
335 LOG.info("PCE cancel resource failed !");
337 } else if (servicePathRpcResult.getStatus() == RpcStatusEx.Pending) {
338 LOG.warn("PCE cancel returned a Penging RpcStatusEx code!");
340 } else if (servicePathRpcResult.getStatus() != RpcStatusEx.Successful) {
341 LOG.error("PCE cancel returned an unknown RpcStatusEx code!");
344 LOG.info("PCE cancel resource done OK !");
345 Uuid suuid = new Uuid(UUID.nameUUIDFromBytes(serviceName.getBytes(Charset.forName("UTF-8")))
347 // get connections of connectivity service and remove them from tapi context and then remove
348 // service from context. The CEPs are maintained as they could be reused by another service
349 ConnectivityService connService = getConnectivityService(suuid);
350 if (connService == null) {
351 LOG.error("Service doesnt exist in tapi context");
354 for (Connection connection:connService.getConnection().values()) {
355 deleteConnection(connection.getConnectionUuid());
357 deleteConnectivityService(suuid);
361 value = "ES_COMPARING_STRINGS_WITH_EQ",
362 justification = "false positives, not strings but real object references comparisons")
363 private Boolean compareServicePathRpcResult(ServicePathRpcResult notification) {
364 if (servicePathRpcResult == null) {
367 if (servicePathRpcResult.getNotificationType() != notification.getNotificationType()) {
370 if (servicePathRpcResult.getServiceName() != notification.getServiceName()) {
373 if (servicePathRpcResult.getStatus() != notification.getStatus()) {
376 if (servicePathRpcResult.getStatusMessage() != notification.getStatusMessage()) {
382 private Map<ConnectionKey, Connection> createXpdrCepsAndConnectionsEth(List<String> xpdrClientTplist,
383 List<String> xpdrNodelist,
384 Map<ConnectionKey, Connection> lowerConn) {
385 // TODO: do we need to create cross connection between iODU and eODU??
386 // add the lower connections of the previous steps for this kind of service
387 Map<LowerConnectionKey, LowerConnection> xcMap = new HashMap<>();
388 for (Connection lowConn: lowerConn.values()) {
389 LowerConnection conn = new LowerConnectionBuilder().setConnectionUuid(lowConn.getConnectionUuid()).build();
390 xcMap.put(conn.key(), conn);
392 Map<ConnectionKey, Connection> connServMap = new HashMap<>();
393 Map<org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.connectivity.rev181210.cep.list.ConnectionEndPointKey,
394 ConnectionEndPoint> cepMapDsr = new HashMap<>();
395 // Create 1 cep per Xpdr in the CLIENT
396 // 1 top connection DSR between the CLIENT xpdrs
397 for (String xpdr:xpdrNodelist) {
398 LOG.info("Creating ceps and xc for xpdr {}", xpdr);
399 String spcXpdrClient = xpdrClientTplist.stream().filter(netp -> netp.contains(xpdr)).findFirst().get();
401 ConnectionEndPoint netCep1 = createCepXpdr(spcXpdrClient, TapiStringConstants.DSR, TapiStringConstants.DSR,
402 LayerProtocolName.DSR);
403 putXpdrCepInTopologyContext(xpdr, spcXpdrClient, TapiStringConstants.DSR, TapiStringConstants.DSR, netCep1);
405 cepMapDsr.put(netCep1.key(), netCep1);
407 String spcXpdr1 = xpdrClientTplist.stream().filter(adp -> adp.contains(xpdrNodelist
408 .get(0))).findFirst().get();
409 String spcXpdr2 = xpdrClientTplist.stream().filter(adp -> adp.contains(xpdrNodelist
410 .get(xpdrNodelist.size() - 1))).findFirst().get();
412 // DSR top connection between edge xpdr CLIENT DSR
413 org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.connectivity.rev181210.connectivity.context.Connection
414 connectionDsr = createTopConnection(spcXpdr1, spcXpdr2, cepMapDsr, TapiStringConstants.DSR,
415 LayerProtocolName.DSR, xcMap);
416 this.connectionFullMap.put(connectionDsr.key(), connectionDsr);
418 // DSR top connection that will be added to the service object
419 Connection conn1 = new ConnectionBuilder().setConnectionUuid(connectionDsr.getUuid()).build();
420 connServMap.put(conn1.key(), conn1);
425 private Map<ConnectionKey,Connection> createXpdrCepsAndConnectionsDsr(List<String> xpdrClientTplist,
426 List<String> xpdrNetworkTplist,
427 List<String> xpdrNodelist) {
428 Map<ConnectionKey, Connection> connServMap = new HashMap<>();
429 Map<org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.connectivity.rev181210.cep.list.ConnectionEndPointKey,
430 ConnectionEndPoint> cepMapDsr = new HashMap<>();
431 Map<org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.connectivity.rev181210.cep.list.ConnectionEndPointKey,
432 ConnectionEndPoint> cepMapOdu = new HashMap<>();
433 // TODO: when upgrading the models to 2.1.3, get the connection inclusion because those connections will
434 // be added to the lower connection of a top connection
435 Map<LowerConnectionKey, LowerConnection> xcMap = new HashMap<>();
437 // Create 1 cep per Xpdr in the CLIENT, 1 cep per Xpdr eODU, 1 XC between eODU and iODE,
438 // 1 top connection between eODU and a top connection DSR between the CLIENT xpdrs
439 for (String xpdr:xpdrNodelist) {
440 LOG.info("Creating ceps and xc for xpdr {}", xpdr);
441 String spcXpdrClient = xpdrClientTplist.stream().filter(netp -> netp.contains(xpdr)).findFirst().get();
443 ConnectionEndPoint netCep1 = createCepXpdr(spcXpdrClient, TapiStringConstants.DSR, TapiStringConstants.DSR,
444 LayerProtocolName.DSR);
445 putXpdrCepInTopologyContext(xpdr, spcXpdrClient, TapiStringConstants.DSR, TapiStringConstants.DSR, netCep1);
447 ConnectionEndPoint netCep2 = createCepXpdr(spcXpdrClient, TapiStringConstants.E_ODU,
448 TapiStringConstants.DSR, LayerProtocolName.ODU);
449 putXpdrCepInTopologyContext(xpdr, spcXpdrClient, TapiStringConstants.E_ODU, TapiStringConstants.DSR,
452 String spcXpdrNetwork = getAssociatedNetworkPort(spcXpdrClient, xpdrNetworkTplist);
453 ConnectionEndPoint netCep3 = getAssociatediODUCep(spcXpdrNetwork);
455 cepMapDsr.put(netCep1.key(), netCep1);
456 cepMapOdu.put(netCep2.key(), netCep2);
457 // Create x connection between I_ODU and E_ODU within xpdr
458 org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.connectivity.rev181210.connectivity.context.Connection
459 connection = createXCBetweenCeps(netCep2, netCep3, spcXpdrClient, spcXpdrNetwork,
460 TapiStringConstants.ODU, LayerProtocolName.ODU);
461 this.connectionFullMap.put(connection.key(), connection);
463 // Create X connection that will be added to the service object
464 LowerConnection conn = new LowerConnectionBuilder().setConnectionUuid(connection.getUuid()).build();
465 xcMap.put(conn.key(), conn);
468 String spcXpdr1 = xpdrClientTplist.stream().filter(adp -> adp.contains(xpdrNodelist
469 .get(0))).findFirst().get();
470 String spcXpdr2 = xpdrClientTplist.stream().filter(adp -> adp.contains(xpdrNodelist
471 .get(xpdrNodelist.size() - 1))).findFirst().get();
473 // eODU top connection between edge xpdr CLIENT eODU
474 org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.connectivity.rev181210.connectivity.context.Connection
475 connectionOdu = createTopConnection(spcXpdr1, spcXpdr2, cepMapOdu, TapiStringConstants.E_ODU,
476 LayerProtocolName.ODU, xcMap);
477 this.connectionFullMap.put(connectionOdu.key(), connectionOdu);
479 // ODU top connection that will be added to the service object and also lower connection
480 Connection conn = new ConnectionBuilder().setConnectionUuid(connectionOdu.getUuid()).build();
481 connServMap.put(conn.key(), conn);
482 LowerConnection lowerConn = new LowerConnectionBuilder().setConnectionUuid(connectionOdu.getUuid()).build();
483 xcMap.put(lowerConn.key(), lowerConn);
485 // DSR top connection between edge xpdr CLIENT DSR
486 org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.connectivity.rev181210.connectivity.context.Connection
487 connectionDsr = createTopConnection(spcXpdr1, spcXpdr2, cepMapDsr, TapiStringConstants.DSR,
488 LayerProtocolName.DSR, xcMap);
489 this.connectionFullMap.put(connectionDsr.key(), connectionDsr);
491 // DSR top connection that will be added to the service object
492 Connection conn1 = new ConnectionBuilder().setConnectionUuid(connectionDsr.getUuid()).build();
493 connServMap.put(conn1.key(), conn1);
498 private Map<ConnectionKey, Connection> createXpdrCepsAndConnectionsOdu(List<String> xpdrNetworkTplist,
499 List<String> xpdrNodelist) {
500 Map<ConnectionKey, Connection> connServMap = new HashMap<>();
501 Map<org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.connectivity.rev181210.cep.list.ConnectionEndPointKey,
502 ConnectionEndPoint> cepMap = new HashMap<>();
503 // TODO: when upgrading the models to 2.1.3, get the connection inclusion because those connections will
504 // be added to the lower connection of a top connection
505 Map<LowerConnectionKey, LowerConnection> xcMap = new HashMap<>();
506 // Create 1 cep per Xpdr in the I_ODU and a top
507 // connection iODU between the xpdrs
508 for (String xpdr:xpdrNodelist) {
509 LOG.info("Creating ceps and xc for xpdr {}", xpdr);
510 String spcXpdrNetwork = xpdrNetworkTplist.stream().filter(netp -> netp.contains(xpdr)).findFirst().get();
512 ConnectionEndPoint netCep1 = createCepXpdr(spcXpdrNetwork, TapiStringConstants.I_ODU,
513 TapiStringConstants.DSR, LayerProtocolName.ODU);
514 putXpdrCepInTopologyContext(xpdr, spcXpdrNetwork, TapiStringConstants.I_ODU, TapiStringConstants.DSR,
517 cepMap.put(netCep1.key(), netCep1);
520 // ODU top connection between edge xpdr i_ODU
521 String spcXpdr1 = xpdrNetworkTplist.stream().filter(adp -> adp.contains(xpdrNodelist
522 .get(0))).findFirst().get();
523 String spcXpdr2 = xpdrNetworkTplist.stream().filter(adp -> adp.contains(xpdrNodelist
524 .get(xpdrNodelist.size() - 1))).findFirst().get();
525 org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.connectivity.rev181210.connectivity.context.Connection
526 connection = createTopConnection(spcXpdr1, spcXpdr2, cepMap, TapiStringConstants.I_ODU,
527 LayerProtocolName.ODU, xcMap);
528 this.connectionFullMap.put(connection.key(), connection);
530 // ODU top connection that will be added to the service object
531 Connection conn = new ConnectionBuilder().setConnectionUuid(connection.getUuid()).build();
532 connServMap.put(conn.key(), conn);
537 private Map<ConnectionKey, Connection> createXpdrCepsAndConnectionsPht(List<String> xpdrNetworkTplist,
538 List<String> xpdrNodelist) {
539 Map<ConnectionKey, Connection> connServMap = new HashMap<>();
540 Map<org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.connectivity.rev181210.cep.list.ConnectionEndPointKey,
541 ConnectionEndPoint> cepMap = new HashMap<>();
542 // TODO: when upgrading the models to 2.1.3, get the connection inclusion because those connections will
543 // be added to the lower connection of a top connection
544 Map<LowerConnectionKey, LowerConnection> xcMap = new HashMap<>();
546 // create ceps and x connections within xpdr
547 for (String xpdr:xpdrNodelist) {
548 LOG.info("Creating ceps and xc for xpdr {}", xpdr);
549 String spcXpdrNetwork = xpdrNetworkTplist.stream().filter(netp -> netp.contains(xpdr)).findFirst().get();
550 // There should be 1 network tp per xpdr
551 // TODO photonic media model should be updated to have the corresponding CEPs. I will just create
552 // 3 different MC CEPs giving different IDs to show that they are different
553 // Create 3 CEPs for each xpdr otsi node and the corresponding cross connection matchin the NEPs
554 ConnectionEndPoint netCep1 = createCepXpdr(spcXpdrNetwork, TapiStringConstants.PHTNC_MEDIA,
555 TapiStringConstants.OTSI, LayerProtocolName.PHOTONICMEDIA);
556 putXpdrCepInTopologyContext(xpdr, spcXpdrNetwork, TapiStringConstants.PHTNC_MEDIA, TapiStringConstants.OTSI,
558 ConnectionEndPoint netCep2 = createCepXpdr(spcXpdrNetwork, TapiStringConstants.E_OTSI,
559 TapiStringConstants.OTSI, LayerProtocolName.PHOTONICMEDIA);
560 putXpdrCepInTopologyContext(xpdr, spcXpdrNetwork, TapiStringConstants.E_OTSI, TapiStringConstants.OTSI,
562 ConnectionEndPoint netCep3 = createCepXpdr(spcXpdrNetwork, TapiStringConstants.I_OTSI,
563 TapiStringConstants.OTSI, LayerProtocolName.PHOTONICMEDIA);
564 putXpdrCepInTopologyContext(xpdr, spcXpdrNetwork, TapiStringConstants.I_OTSI, TapiStringConstants.OTSI,
566 cepMap.put(netCep1.key(), netCep1);
567 cepMap.put(netCep2.key(), netCep2);
568 cepMap.put(netCep3.key(), netCep3);
570 // Create x connection between I_OTSi and E_OTSi within xpdr
571 org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.connectivity.rev181210.connectivity.context.Connection
572 connection = createXCBetweenCeps(netCep2, netCep3, spcXpdrNetwork, spcXpdrNetwork,
573 TapiStringConstants.OTSI, LayerProtocolName.PHOTONICMEDIA);
574 this.connectionFullMap.put(connection.key(), connection);
576 // Create X connection that will be added to the service object
577 LowerConnection conn = new LowerConnectionBuilder().setConnectionUuid(connection.getUuid()).build();
578 xcMap.put(conn.key(), conn);
580 // OTSi top connection between edge I_OTSI Xpdr
581 String spcXpdr1 = xpdrNetworkTplist.stream().filter(adp -> adp.contains(xpdrNodelist
582 .get(0))).findFirst().get();
583 String spcXpdr2 = xpdrNetworkTplist.stream().filter(adp -> adp.contains(xpdrNodelist
584 .get(xpdrNodelist.size() - 1))).findFirst().get();
585 org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.connectivity.rev181210.connectivity.context.Connection
586 connection = createTopConnection(spcXpdr1, spcXpdr2, cepMap, TapiStringConstants.I_OTSI,
587 LayerProtocolName.PHOTONICMEDIA, xcMap);
588 this.connectionFullMap.put(connection.key(), connection);
590 // OTSi top connection that will be added to the service object
591 Connection conn = new ConnectionBuilder().setConnectionUuid(connection.getUuid()).build();
592 connServMap.put(conn.key(), conn);
598 private Map<ConnectionKey, Connection> createRoadmCepsAndConnections(List<String> rdmAddDropTplist,
599 List<String> rdmDegTplist,
600 List<String> rdmNodelist,
601 String edgeRoadm1, String edgeRoadm2) {
602 // TODO: will need to check if things exist already or not
603 Map<ConnectionKey, Connection> connServMap = new HashMap<>();
604 Map<org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.connectivity.rev181210.cep.list.ConnectionEndPointKey,
605 ConnectionEndPoint> cepMap = new HashMap<>();
606 // create ceps and x connections within roadm
607 Map<LowerConnectionKey, LowerConnection> xcMap = new HashMap<>();
608 for (String roadm : rdmNodelist) {
609 LOG.info("Creating ceps and xc for roadm {}", roadm);
610 String spcRdmAD = rdmAddDropTplist.stream().filter(adp -> adp.contains(roadm)).findFirst().get();
611 LOG.info("AD port of ROADm {} = {}", roadm, spcRdmAD);
612 // There should be only 1 AD and 1 DEG per roadm
613 // TODO photonic media model should be updated to have the corresponding CEPs. I will just create
614 // 3 different MC CEPs giving different IDs to show that they are different
615 // Create 3 CEPs for each AD and DEG and the corresponding cross connections, matching the NEPs
616 // created in the topology creation
617 // add CEPs to the topology to the corresponding ONEP
618 ConnectionEndPoint adCep1 = createCepRoadm(spcRdmAD, TapiStringConstants.PHTNC_MEDIA);
619 putRdmCepInTopologyContext(roadm, spcRdmAD, TapiStringConstants.PHTNC_MEDIA, adCep1);
620 ConnectionEndPoint adCep2 = createCepRoadm(spcRdmAD, TapiStringConstants.MC);
621 putRdmCepInTopologyContext(roadm, spcRdmAD, TapiStringConstants.MC, adCep2);
622 ConnectionEndPoint adCep3 = createCepRoadm(spcRdmAD, TapiStringConstants.OTSI_MC);
623 putRdmCepInTopologyContext(roadm, spcRdmAD, TapiStringConstants.OTSI_MC, adCep3);
624 cepMap.put(adCep1.key(), adCep1);
625 cepMap.put(adCep2.key(), adCep2);
626 cepMap.put(adCep3.key(), adCep3);
628 String spcRdmDEG = rdmDegTplist.stream().filter(adp -> adp.contains(roadm)).findFirst().get();
629 LOG.info("Degree port of ROADm {} = {}", roadm, spcRdmDEG);
631 ConnectionEndPoint degCep1 = createCepRoadm(spcRdmDEG, TapiStringConstants.PHTNC_MEDIA);
632 putRdmCepInTopologyContext(roadm, spcRdmDEG, TapiStringConstants.PHTNC_MEDIA, degCep1);
633 ConnectionEndPoint degCep2 = createCepRoadm(spcRdmDEG, TapiStringConstants.MC);
634 putRdmCepInTopologyContext(roadm, spcRdmDEG, TapiStringConstants.MC, degCep2);
635 ConnectionEndPoint degCep3 = createCepRoadm(spcRdmDEG, TapiStringConstants.OTSI_MC);
636 putRdmCepInTopologyContext(roadm, spcRdmDEG, TapiStringConstants.OTSI_MC, degCep3);
637 cepMap.put(degCep1.key(), degCep1);
638 cepMap.put(degCep2.key(), degCep2);
639 cepMap.put(degCep3.key(), degCep3);
641 LOG.info("Going to create cross connections for ROADM {}", roadm);
642 // Create X connections between MC and OTSi_MC for full map
643 org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.connectivity.rev181210.connectivity.context.Connection
644 connection1 = createXCBetweenCeps(adCep2, degCep2, spcRdmAD, spcRdmDEG, TapiStringConstants.MC,
645 LayerProtocolName.PHOTONICMEDIA);
646 LOG.info("Cross connection 1 created = {}", connection1.toString());
647 org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.connectivity.rev181210.connectivity.context.Connection
648 connection2 = createXCBetweenCeps(adCep3, degCep3, spcRdmAD, spcRdmDEG, TapiStringConstants.OTSI_MC,
649 LayerProtocolName.PHOTONICMEDIA);
650 LOG.info("Cross connection 2 created = {}", connection2.toString());
651 this.connectionFullMap.put(connection1.key(), connection1);
652 this.connectionFullMap.put(connection2.key(), connection2);
654 // Create X connections that will be added to the service object
655 LowerConnection conn1 = new LowerConnectionBuilder().setConnectionUuid(connection1.getUuid()).build();
656 LowerConnection conn2 = new LowerConnectionBuilder().setConnectionUuid(connection2.getUuid()).build();
658 xcMap.put(conn1.key(), conn1);
659 xcMap.put(conn2.key(), conn2);
661 LOG.info("Going to create top connections between roadms");
662 // create top connections between roadms: MC connections between AD MC CEPs of roadms
663 for (int i = 0; i < rdmNodelist.size(); i++) {
664 if (rdmNodelist.size() <= (i + 1)) {
665 LOG.info("Reached last roadm. No more MC connections");
668 // Current roadm with roadm i + 1 --> MC
669 String roadm1 = rdmNodelist.get(i);
670 String spcRdmAD1 = rdmAddDropTplist.stream().filter(adp -> adp.contains(roadm1)).findFirst().get();
671 String roadm2 = rdmNodelist.get(i + 1);
672 String spcRdmAD2 = rdmAddDropTplist.stream().filter(adp -> adp.contains(roadm2)).findFirst().get();
673 LOG.info("Creating top connection from {} to {} between tps: {}-{}", roadm1, roadm2, spcRdmAD1, spcRdmAD2);
675 // Create top connections between MC for full map
676 org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.connectivity.rev181210.connectivity.context.Connection
677 connection = createTopConnection(spcRdmAD1, spcRdmAD2, cepMap, TapiStringConstants.MC,
678 LayerProtocolName.PHOTONICMEDIA, xcMap);
679 this.connectionFullMap.put(connection.key(), connection);
680 LOG.info("Top connection created = {}", connection.toString());
682 // Create top connections that will be added to the service object and lower
683 // connection to the next top connection
684 Connection conn = new ConnectionBuilder().setConnectionUuid(connection.getUuid()).build();
685 connServMap.put(conn.key(), conn);
686 LowerConnection conn1 = new LowerConnectionBuilder().setConnectionUuid(connection.getUuid()).build();
687 xcMap.put(conn1.key(), conn1);
690 // OTSiMC top connection between edge roadms
691 LOG.info("Going to created top connection between OTSiMC");
692 String spcRdmAD1 = rdmAddDropTplist.stream().filter(adp -> adp.contains(edgeRoadm1)).findFirst().get();
693 String spcRdmAD2 = rdmAddDropTplist.stream().filter(adp -> adp.contains(edgeRoadm2)).findFirst().get();
694 org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.connectivity.rev181210.connectivity.context.Connection
695 connection = createTopConnection(spcRdmAD1, spcRdmAD2, cepMap, TapiStringConstants.OTSI_MC,
696 LayerProtocolName.PHOTONICMEDIA, xcMap);
697 this.connectionFullMap.put(connection.key(), connection);
698 LOG.info("Top connection created = {}", connection.toString());
700 // OTSiMC top connections that will be added to the service object
701 Connection conn = new ConnectionBuilder().setConnectionUuid(connection.getUuid()).build();
702 connServMap.put(conn.key(), conn);
706 private org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.connectivity.rev181210.connectivity.context.Connection
707 createTopConnection(String tp1, String tp2,
708 Map<org.opendaylight.yang.gen.v1.urn
709 .onf.otcc.yang.tapi.connectivity.rev181210.cep.list.ConnectionEndPointKey,
710 ConnectionEndPoint> cepMap, String qual, LayerProtocolName topPortocol,
711 Map<LowerConnectionKey, LowerConnection> xcMap) {
712 // find cep for each AD MC of roadm 1 and 2
713 LOG.info("Top connection name = {}", String.join("+", "TOP", tp1, tp2, qual));
714 org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.connectivity.rev181210.ConnectionEndPoint adCep1 =
715 cepMap.get(new org.opendaylight.yang.gen.v1.urn
716 .onf.otcc.yang.tapi.connectivity.rev181210.cep.list.ConnectionEndPointKey(
717 new Uuid(UUID.nameUUIDFromBytes((String.join("+", "CEP", tp1.split("\\+")[0],
718 qual, tp1.split("\\+")[1])).getBytes(Charset.forName("UTF-8")))
720 LOG.info("ADCEP1 = {}", adCep1.toString());
721 org.opendaylight.yang.gen.v1.urn
722 .onf.otcc.yang.tapi.connectivity.rev181210.connection.ConnectionEndPoint cep1 =
723 new org.opendaylight.yang.gen.v1.urn
724 .onf.otcc.yang.tapi.connectivity.rev181210.connection.ConnectionEndPointBuilder()
725 .setNodeEdgePointUuid(adCep1.getClientNodeEdgePoint()
726 .values().stream().findFirst().get().getNodeEdgePointUuid())
727 .setTopologyUuid(adCep1.getClientNodeEdgePoint()
728 .values().stream().findFirst().get().getTopologyUuid())
729 .setNodeUuid(adCep1.getClientNodeEdgePoint()
730 .values().stream().findFirst().get().getNodeUuid())
731 .setConnectionEndPointUuid(adCep1.getUuid())
733 org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.connectivity.rev181210.ConnectionEndPoint adCep2 =
734 cepMap.get(new org.opendaylight.yang.gen.v1.urn
735 .onf.otcc.yang.tapi.connectivity.rev181210.cep.list.ConnectionEndPointKey(
736 new Uuid(UUID.nameUUIDFromBytes((String.join("+", "CEP", tp2.split("\\+")[0],
737 qual, tp2.split("\\+")[1])).getBytes(Charset.forName("UTF-8")))
739 LOG.info("ADCEP2 = {}", adCep2.toString());
740 org.opendaylight.yang.gen.v1.urn
741 .onf.otcc.yang.tapi.connectivity.rev181210.connection.ConnectionEndPoint cep2 =
742 new org.opendaylight.yang.gen.v1.urn
743 .onf.otcc.yang.tapi.connectivity.rev181210.connection.ConnectionEndPointBuilder()
744 .setNodeEdgePointUuid(adCep2.getClientNodeEdgePoint()
745 .values().stream().findFirst().get().getNodeEdgePointUuid())
746 .setTopologyUuid(adCep2.getClientNodeEdgePoint()
747 .values().stream().findFirst().get().getTopologyUuid())
748 .setNodeUuid(adCep2.getClientNodeEdgePoint()
749 .values().stream().findFirst().get().getNodeUuid())
750 .setConnectionEndPointUuid(adCep1.getUuid())
752 Map<ConnectionEndPointKey, org.opendaylight.yang.gen.v1.urn
753 .onf.otcc.yang.tapi.connectivity.rev181210.connection.ConnectionEndPoint> ceps = new HashMap<>();
754 ceps.put(cep1.key(), cep1);
755 ceps.put(cep2.key(), cep2);
756 Name connName = new NameBuilder()
757 .setValueName("Connection name")
758 .setValue(String.join("+", "TOP", tp1, tp2, qual))
760 // TODO: lower connection, supported link.......
761 return new org.opendaylight.yang.gen.v1.urn
762 .onf.otcc.yang.tapi.connectivity.rev181210.connectivity.context.ConnectionBuilder()
763 .setUuid(new Uuid(UUID.nameUUIDFromBytes((String.join("+", "TOP", tp1, tp2, qual))
764 .getBytes(Charset.forName("UTF-8"))).toString()))
765 .setName(Map.of(connName.key(), connName))
766 .setConnectionEndPoint(ceps)
767 .setOperationalState(OperationalState.DISABLED)
768 .setLayerProtocolName(topPortocol)
769 .setLifecycleState(LifecycleState.POTENTIALAVAILABLE)
770 .setDirection(ForwardingDirection.BIDIRECTIONAL)
771 .setLowerConnection(xcMap)
775 private org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.connectivity.rev181210.connectivity.context.Connection
776 createXCBetweenCeps(ConnectionEndPoint cep1, ConnectionEndPoint cep2, String tp1, String tp2, String qual,
777 LayerProtocolName xcProtocol) {
778 LOG.info("Creation cross connection between: {} and {}", tp1, tp2);
779 LOG.info("Cross connection name = {}", String.join("+", "XC", tp1, tp2, qual));
780 LOG.info("CEP1 = {}", cep1.getClientNodeEdgePoint().toString());
781 LOG.info("CEP2 = {}", cep2.getClientNodeEdgePoint().toString());
782 org.opendaylight.yang.gen.v1.urn
783 .onf.otcc.yang.tapi.connectivity.rev181210.connection.ConnectionEndPoint cepServ1 =
784 new org.opendaylight.yang.gen.v1.urn
785 .onf.otcc.yang.tapi.connectivity.rev181210.connection.ConnectionEndPointBuilder()
786 .setNodeEdgePointUuid(cep1.getClientNodeEdgePoint()
787 .values().stream().findFirst().get().getNodeEdgePointUuid())
788 .setTopologyUuid(cep1.getClientNodeEdgePoint()
789 .values().stream().findFirst().get().getTopologyUuid())
790 .setNodeUuid(cep1.getClientNodeEdgePoint()
791 .values().stream().findFirst().get().getNodeUuid())
792 .setConnectionEndPointUuid(cep1.getUuid())
794 org.opendaylight.yang.gen.v1.urn
795 .onf.otcc.yang.tapi.connectivity.rev181210.connection.ConnectionEndPoint cepServ2 =
796 new org.opendaylight.yang.gen.v1.urn
797 .onf.otcc.yang.tapi.connectivity.rev181210.connection.ConnectionEndPointBuilder()
798 .setNodeEdgePointUuid(cep2.getClientNodeEdgePoint()
799 .values().stream().findFirst().get().getNodeEdgePointUuid())
800 .setTopologyUuid(cep2.getClientNodeEdgePoint()
801 .values().stream().findFirst().get().getTopologyUuid())
802 .setNodeUuid(cep2.getClientNodeEdgePoint()
803 .values().stream().findFirst().get().getNodeUuid())
804 .setConnectionEndPointUuid(cep2.getUuid())
806 Map<ConnectionEndPointKey, org.opendaylight.yang.gen.v1.urn
807 .onf.otcc.yang.tapi.connectivity.rev181210.connection.ConnectionEndPoint> ceps = new HashMap<>();
808 ceps.put(cepServ1.key(), cepServ1);
809 ceps.put(cepServ2.key(), cepServ2);
810 Name connName = new NameBuilder()
811 .setValueName("Connection name")
812 .setValue(String.join("+", "XC", tp1, tp2, qual))
814 // TODO: lower connection, supported link.......
815 return new org.opendaylight.yang.gen.v1.urn
816 .onf.otcc.yang.tapi.connectivity.rev181210.connectivity.context.ConnectionBuilder()
817 .setUuid(new Uuid(UUID.nameUUIDFromBytes((String.join("+", "XC", tp1, tp2, qual))
818 .getBytes(Charset.forName("UTF-8"))).toString()))
819 .setName(Map.of(connName.key(), connName))
820 .setConnectionEndPoint(ceps)
821 .setOperationalState(OperationalState.ENABLED)
822 .setLayerProtocolName(xcProtocol)
823 .setLifecycleState(LifecycleState.INSTALLED)
824 .setDirection(ForwardingDirection.BIDIRECTIONAL)
828 private ConnectionEndPoint createCepRoadm(String id, String qualifier) {
829 LOG.info("NEP = {}", String.join("+", id.split("\\+")[0], qualifier, id.split("\\+")[1]));
830 Name cepName = new NameBuilder()
831 .setValueName("ConnectionEndPoint name")
832 .setValue(String.join("+", id.split("\\+")[0], qualifier,
835 ClientNodeEdgePoint cnep = new ClientNodeEdgePointBuilder()
836 .setNodeEdgePointUuid(new Uuid(UUID.nameUUIDFromBytes((String.join("+", id.split("\\+")[0],
837 qualifier, id.split("\\+")[1])).getBytes(Charset.forName("UTF-8")))
839 .setNodeUuid(new Uuid(UUID.nameUUIDFromBytes((String.join("+",id.split("\\+")[0],
840 qualifier)).getBytes(Charset.forName("UTF-8")))
842 .setTopologyUuid(new Uuid(UUID.nameUUIDFromBytes(TapiStringConstants.T0_FULL_MULTILAYER
843 .getBytes(Charset.forName("UTF-8"))).toString()))
845 // TODO: add augmentation with the corresponding cep-spec (i.e. MC, OTSiMC...)
846 // TODO: add parent ONEP??
847 ConnectionEndPointBuilder cepBldr = new ConnectionEndPointBuilder()
848 .setUuid(new Uuid(UUID.nameUUIDFromBytes((String.join("+", "CEP", id.split("\\+")[0],
849 qualifier, id.split("\\+")[1])).getBytes(Charset.forName("UTF-8")))
851 .setClientNodeEdgePoint(Map.of(cnep.key(), cnep))
852 .setName(Map.of(cepName.key(), cepName))
853 .setConnectionPortRole(PortRole.SYMMETRIC)
854 .setConnectionPortDirection(PortDirection.BIDIRECTIONAL)
855 .setOperationalState(OperationalState.ENABLED)
856 .setLifecycleState(LifecycleState.INSTALLED)
857 .setLayerProtocolName(LayerProtocolName.PHOTONICMEDIA);
858 return cepBldr.build();
861 private ConnectionEndPoint createCepXpdr(String id, String qualifier, String nodeLayer,
862 LayerProtocolName cepProtocol) {
863 Name cepName = new NameBuilder()
864 .setValueName("ConnectionEndPoint name")
865 .setValue(String.join("+", id.split("\\+")[0], qualifier,
868 ClientNodeEdgePoint cnep = new ClientNodeEdgePointBuilder()
869 .setNodeEdgePointUuid(new Uuid(UUID.nameUUIDFromBytes((String.join("+", id.split("\\+")[0],
870 qualifier, id.split("\\+")[1])).getBytes(Charset.forName("UTF-8")))
872 .setNodeUuid(new Uuid(UUID.nameUUIDFromBytes((String.join("+",id.split("\\+")[0],
873 nodeLayer)).getBytes(Charset.forName("UTF-8")))
875 .setTopologyUuid(new Uuid(UUID.nameUUIDFromBytes(TapiStringConstants.T0_FULL_MULTILAYER
876 .getBytes(Charset.forName("UTF-8"))).toString()))
878 // TODO: add augmentation with the corresponding cep-spec (i.e. MC, OTSiMC...)
879 // TODO: add parent ONEP??
880 ConnectionEndPointBuilder cepBldr = new ConnectionEndPointBuilder()
881 .setUuid(new Uuid(UUID.nameUUIDFromBytes((String.join("+", "CEP", id.split("\\+")[0],
882 qualifier, id.split("\\+")[1])).getBytes(Charset.forName("UTF-8")))
884 .setClientNodeEdgePoint(Map.of(cnep.key(), cnep))
885 .setName(Map.of(cepName.key(), cepName))
886 .setConnectionPortRole(PortRole.SYMMETRIC)
887 .setConnectionPortDirection(PortDirection.BIDIRECTIONAL)
888 .setOperationalState(OperationalState.ENABLED)
889 .setLifecycleState(LifecycleState.INSTALLED)
890 .setLayerProtocolName(cepProtocol);
891 return cepBldr.build();
894 private void putRdmCepInTopologyContext(String node, String spcRdmAD, String qual, ConnectionEndPoint cep) {
895 LOG.info("NEP id before Merge = {}", String.join("+", node, qual, spcRdmAD.split("\\+")[1]));
896 LOG.info("Node of NEP id before Merge = {}", String.join("+", node, TapiStringConstants.PHTNC_MEDIA));
897 // Give uuids so that it is easier to look for things: topology uuid, node uuid, nep uuid, cep
898 Uuid topoUuid = new Uuid(UUID.nameUUIDFromBytes(TapiStringConstants.T0_FULL_MULTILAYER
899 .getBytes(Charset.forName("UTF-8"))).toString());
900 Uuid nodeUuid = new Uuid(UUID.nameUUIDFromBytes(String.join("+", node, TapiStringConstants.PHTNC_MEDIA)
901 .getBytes(Charset.forName("UTF-8"))).toString());
902 Uuid nepUuid = new Uuid(UUID.nameUUIDFromBytes(String.join("+", node, qual, spcRdmAD.split("\\+")[1])
903 .getBytes(Charset.forName("UTF-8"))).toString());
904 updateTopologyWithCep(topoUuid, nodeUuid, nepUuid, cep);
907 private void putXpdrCepInTopologyContext(String node, String spcXpdrNet, String qual, String nodeLayer,
908 ConnectionEndPoint cep) {
909 // Give uuids so that it is easier to look for things: topology uuid, node uuid, nep uuid, cep
910 Uuid topoUuid = new Uuid(UUID.nameUUIDFromBytes(TapiStringConstants.T0_FULL_MULTILAYER
911 .getBytes(Charset.forName("UTF-8"))).toString());
912 Uuid nodeUuid = new Uuid(UUID.nameUUIDFromBytes(String.join("+", node, nodeLayer)
913 .getBytes(Charset.forName("UTF-8"))).toString());
914 Uuid nepUuid = new Uuid(UUID.nameUUIDFromBytes(String.join("+", node, qual, spcXpdrNet.split("\\+")[1])
915 .getBytes(Charset.forName("UTF-8"))).toString());
916 updateTopologyWithCep(topoUuid, nodeUuid, nepUuid, cep);
919 public void updateTopologyWithCep(Uuid topoUuid, Uuid nodeUuid, Uuid nepUuid, ConnectionEndPoint cep) {
920 // TODO: verify this is correct. Should we identify the context IID with the context UUID??
921 InstanceIdentifier<OwnedNodeEdgePoint> onepIID = InstanceIdentifier.builder(Context.class)
922 .augmentation(org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.topology.rev181210.Context1.class)
923 .child(org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.topology.rev181210.context.TopologyContext.class)
924 .child(Topology.class, new TopologyKey(topoUuid))
925 .child(org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.topology.rev181210.topology.Node.class,
926 new NodeKey(nodeUuid))
927 .child(OwnedNodeEdgePoint.class, new OwnedNodeEdgePointKey(nepUuid))
930 Optional<OwnedNodeEdgePoint> optionalOnep = this.networkTransactionService.read(
931 LogicalDatastoreType.OPERATIONAL, onepIID).get();
932 if (!optionalOnep.isPresent()) {
933 LOG.error("ONEP is not present in datastore");
936 OwnedNodeEdgePoint onep = optionalOnep.get();
937 LOG.info("ONEP found = {}", onep.toString());
938 // TODO -> If cep exists -> skip merging to datasore
939 OwnedNodeEdgePoint1 onep1 = onep.augmentation(OwnedNodeEdgePoint1.class);
940 if (onep1 != null && onep1.getCepList() != null && onep1.getCepList().getConnectionEndPoint() != null) {
941 if (onep1.getCepList().getConnectionEndPoint().containsKey(
942 new org.opendaylight.yang.gen.v1
943 .urn.onf.otcc.yang.tapi.connectivity.rev181210.cep.list.ConnectionEndPointKey(cep.key()))) {
944 LOG.info("CEP already in topology, skipping merge");
949 CepList cepList = new CepListBuilder().setConnectionEndPoint(Map.of(cep.key(), cep)).build();
950 OwnedNodeEdgePoint1 onep1Bldr = new OwnedNodeEdgePoint1Builder().setCepList(cepList).build();
951 OwnedNodeEdgePoint newOnep = new OwnedNodeEdgePointBuilder(onep)
952 .addAugmentation(onep1Bldr)
954 LOG.info("New ONEP is {}", newOnep.toString());
955 // merge in datastore
956 this.networkTransactionService.merge(LogicalDatastoreType.OPERATIONAL, onepIID,
958 this.networkTransactionService.commit().get();
959 LOG.info("CEP added successfully.");
960 } catch (InterruptedException | ExecutionException e) {
961 LOG.error("Couldnt update cep in topology", e);
965 private void updateConnectionContextWithConn(
966 Map<org.opendaylight.yang.gen.v1.urn
967 .onf.otcc.yang.tapi.connectivity.rev181210.connectivity.context.ConnectionKey,
968 org.opendaylight.yang.gen.v1.urn
969 .onf.otcc.yang.tapi.connectivity.rev181210.connectivity.context.Connection> connFullMap,
970 Map<ConnectionKey, Connection> connMap, Uuid suuid) {
971 // TODO: verify this is correct. Should we identify the context IID with the context UUID??
973 ConnectivityService connServ = getConnectivityService(suuid);
974 ConnectivityService updtConnServ = new ConnectivityServiceBuilder(connServ)
975 .setConnection(connMap)
978 // Perform the merge operation with the new conn service and the connection context updated
979 org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.connectivity.rev181210.context.ConnectivityContext
980 connectivityContext = new ConnectivityContextBuilder()
981 .setConnectivityService(Map.of(updtConnServ.key(), updtConnServ))
982 .setConnection(connFullMap)
984 InstanceIdentifier<org.opendaylight.yang.gen.v1.urn
985 .onf.otcc.yang.tapi.connectivity.rev181210.context.ConnectivityContext> connectivitycontextIID =
986 InstanceIdentifier.builder(Context.class).augmentation(Context1.class)
987 .child(org.opendaylight.yang.gen.v1.urn
988 .onf.otcc.yang.tapi.connectivity.rev181210.context.ConnectivityContext.class)
990 // merge in datastore
991 this.networkTransactionService.merge(LogicalDatastoreType.OPERATIONAL, connectivitycontextIID,
992 connectivityContext);
993 this.networkTransactionService.commit().get();
994 LOG.info("TAPI connectivity merged successfully.");
995 } catch (InterruptedException | ExecutionException e) {
996 LOG.error("Failed to merge TAPI connectivity", e);
1000 private ConnectivityService getConnectivityService(Uuid suuid) {
1002 // First read connectivity service with service uuid and update info
1003 InstanceIdentifier<ConnectivityService> connectivityServIID =
1004 InstanceIdentifier.builder(Context.class).augmentation(Context1.class)
1005 .child(org.opendaylight.yang.gen.v1.urn
1006 .onf.otcc.yang.tapi.connectivity.rev181210.context.ConnectivityContext.class)
1007 .child(ConnectivityService.class, new ConnectivityServiceKey(suuid))
1010 Optional<ConnectivityService> optConnServ =
1011 this.networkTransactionService.read(LogicalDatastoreType.OPERATIONAL, connectivityServIID).get();
1012 if (!optConnServ.isPresent()) {
1013 LOG.error("Connectivity service not found in tapi context");
1016 return optConnServ.get();
1017 } catch (InterruptedException | ExecutionException e) {
1018 LOG.error("Connectivity service not found in tapi context. Error:", e);
1023 private void deleteConnectivityService(Uuid suuid) {
1024 // First read connectivity service with service uuid and update info
1025 InstanceIdentifier<ConnectivityService> connectivityServIID =
1026 InstanceIdentifier.builder(Context.class).augmentation(Context1.class)
1027 .child(org.opendaylight.yang.gen.v1.urn
1028 .onf.otcc.yang.tapi.connectivity.rev181210.context.ConnectivityContext.class)
1029 .child(ConnectivityService.class, new ConnectivityServiceKey(suuid))
1032 this.networkTransactionService.delete(LogicalDatastoreType.OPERATIONAL, connectivityServIID);
1033 this.networkTransactionService.commit().get();
1034 } catch (InterruptedException | ExecutionException e) {
1035 LOG.error("Failed to delete TAPI connectivity service", e);
1039 private void deleteConnection(Uuid connectionUuid) {
1040 // First read connectivity service with service uuid and update info
1041 InstanceIdentifier<org.opendaylight.yang.gen.v1
1042 .urn.onf.otcc.yang.tapi.connectivity.rev181210.connectivity.context.Connection> connectionIID =
1043 InstanceIdentifier.builder(Context.class).augmentation(Context1.class)
1044 .child(org.opendaylight.yang.gen.v1.urn
1045 .onf.otcc.yang.tapi.connectivity.rev181210.context.ConnectivityContext.class)
1046 .child(org.opendaylight.yang.gen.v1.urn
1047 .onf.otcc.yang.tapi.connectivity.rev181210.connectivity.context.Connection.class,
1048 new org.opendaylight.yang.gen.v1.urn
1049 .onf.otcc.yang.tapi.connectivity.rev181210.connectivity.context.ConnectionKey(
1053 this.networkTransactionService.delete(LogicalDatastoreType.OPERATIONAL, connectionIID);
1054 this.networkTransactionService.commit().get();
1055 } catch (InterruptedException | ExecutionException e) {
1056 LOG.error("Failed to delete TAPI connection", e);
1060 private String getIdBasedOnModelVersion(String nodeid) {
1061 return nodeid.matches("[A-Z]{5}-[A-Z0-9]{2}-.*")
1062 ? String.join("-", nodeid.split("-")[0], nodeid.split("-")[1]) : nodeid.split("-")[0];
1065 private ConnectionEndPoint getAssociatediODUCep(String spcXpdrNetwork) {
1066 Uuid topoUuid = new Uuid(UUID.nameUUIDFromBytes(TapiStringConstants.T0_FULL_MULTILAYER
1067 .getBytes(Charset.forName("UTF-8"))).toString());
1068 Uuid nodeUuid = new Uuid(UUID.nameUUIDFromBytes((String.join("+", spcXpdrNetwork.split("\\+")[0],
1069 TapiStringConstants.DSR).getBytes(Charset.forName("UTF-8")))).toString());
1070 Uuid nepUuid = new Uuid(UUID.nameUUIDFromBytes((String.join("+", spcXpdrNetwork.split("\\+")[0],
1071 TapiStringConstants.I_ODU, spcXpdrNetwork.split("\\+")[1]).getBytes(Charset.forName("UTF-8"))))
1073 Uuid cepUuid = new Uuid(UUID.nameUUIDFromBytes((String.join("+", "CEP",
1074 spcXpdrNetwork.split("\\+")[0], TapiStringConstants.I_ODU, spcXpdrNetwork.split("\\+")[1]))
1075 .getBytes(Charset.forName("UTF-8"))).toString());
1076 InstanceIdentifier<OwnedNodeEdgePoint> nepIID = InstanceIdentifier.builder(Context.class)
1077 .augmentation(org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.topology.rev181210.Context1.class)
1078 .child(org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.topology.rev181210.context.TopologyContext.class)
1079 .child(Topology.class, new TopologyKey(topoUuid))
1080 .child(org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.topology.rev181210.topology.Node.class,
1081 new NodeKey(nodeUuid)).child(OwnedNodeEdgePoint.class, new OwnedNodeEdgePointKey(nepUuid)).build();
1083 Optional<OwnedNodeEdgePoint> optNode = this.networkTransactionService
1084 .read(LogicalDatastoreType.OPERATIONAL, nepIID).get();
1085 if (!optNode.isPresent()) {
1086 LOG.error("Node is not present in datastore");
1089 if (optNode.get().augmentation(OwnedNodeEdgePoint1.class) == null) {
1090 LOG.error("Node doesnt have ceps");
1093 return optNode.get().augmentation(OwnedNodeEdgePoint1.class).getCepList().getConnectionEndPoint()
1094 .get(new org.opendaylight.yang.gen.v1.urn
1095 .onf.otcc.yang.tapi.connectivity.rev181210.cep.list.ConnectionEndPointKey(cepUuid));
1096 } catch (InterruptedException | ExecutionException e) {
1097 LOG.error("Couldnt read node in topology", e);
1102 private String getAssociatedNetworkPort(String spcXpdrClient, List<String> xpdrNetworkTplist) {
1103 for (String networkPort:xpdrNetworkTplist) {
1104 if (networkPort.split("\\+")[0].equals(spcXpdrClient.split("\\+")[0])) {
1111 private OpenroadmNodeType getOpenRoadmNodeType(List<String> xpdrNodelist) {
1112 List<OpenroadmNodeType> openroadmNodeTypeList = new ArrayList<>();
1113 for (String xpdrNode:xpdrNodelist) {
1114 Uuid nodeUuid = new Uuid(UUID.nameUUIDFromBytes((String.join("+",xpdrNode, TapiStringConstants.DSR))
1115 .getBytes(Charset.forName("UTF-8"))).toString());
1116 InstanceIdentifier<org.opendaylight.yang.gen.v1.urn
1117 .onf.otcc.yang.tapi.topology.rev181210.topology.Node> nodeIID = InstanceIdentifier.builder(
1118 Context.class).augmentation(org.opendaylight.yang.gen.v1.urn
1119 .onf.otcc.yang.tapi.topology.rev181210.Context1.class).child(TopologyContext.class)
1120 .child(Topology.class, new TopologyKey(this.tapiTopoUuid))
1121 .child(org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.topology.rev181210.topology.Node.class,
1122 new NodeKey(nodeUuid)).build();
1124 Optional<org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.topology.rev181210.topology.Node> optNode
1125 = this.networkTransactionService.read(LogicalDatastoreType.OPERATIONAL, nodeIID).get();
1126 if (!optNode.isPresent()) {
1129 OpenroadmNodeType openroadmNodeType = OpenroadmNodeType.forName(optNode.get().getName().get(
1130 new NameKey("Node Type")).getValue()).get();
1131 if (!openroadmNodeTypeList.contains(openroadmNodeType)) {
1132 openroadmNodeTypeList.add(openroadmNodeType);
1134 } catch (InterruptedException | ExecutionException e) {
1135 LOG.error("Couldnt read node in topology", e);
1139 // TODO for now check that there is only one type, otherwise error
1140 if (openroadmNodeTypeList.size() != 1) {
1141 LOG.error("More than one xpdr type. List = {}", openroadmNodeTypeList);
1144 return openroadmNodeTypeList.get(0);
1147 private List<String> getAssociatedClientsPort(List<String> xpdrNetworkTplist) {
1148 List<String> clientPortList = new ArrayList<>();
1149 for (String networkPort:xpdrNetworkTplist) {
1150 String nodeId = String.join("-", networkPort.split("\\+")[0].split("-")[0],
1151 networkPort.split("\\+")[0].split("-")[1]);
1152 String tpId = networkPort.split("\\+")[1];
1153 InstanceIdentifier<Mapping> mapIID = InstanceIdentifier.builder(Network.class)
1154 .child(Nodes.class, new NodesKey(nodeId))
1155 .child(Mapping.class, new MappingKey(tpId)).build();
1157 Optional<Mapping> optMapping = this.networkTransactionService.read(LogicalDatastoreType.CONFIGURATION,
1159 if (!optMapping.isPresent()) {
1160 LOG.error("Couldnt find mapping for port {} of node {}", tpId, nodeId);
1162 Mapping mapping = optMapping.get();
1163 LOG.info("Mapping for node+port {}+{} = {}", nodeId, tpId, mapping);
1164 String key = String.join("+", String.join("-", nodeId, tpId.split("\\-")[0]),
1165 mapping.getConnectionMapLcp());
1166 LOG.info("Key to be added to list = {}", key);
1167 if (!clientPortList.contains(key)) {
1168 clientPortList.add(key);
1170 } catch (InterruptedException | ExecutionException e) {
1171 LOG.error("Couldnt read mapping from datastore", e);
1176 return clientPortList;
1179 public void setInput(CreateConnectivityServiceInput input) {
1183 public void setServiceUuid(Uuid serviceUuid) {
1184 this.serviceUuid = serviceUuid;