Abort power setup if setting gainloss fails
[transportpce.git] / renderer / src / main / java / org / opendaylight / transportpce / renderer / provisiondevice / OtnDeviceRendererServiceImpl.java
1 /*
2  * Copyright © 2019 AT&T 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.renderer.provisiondevice;
9
10 import java.util.ArrayList;
11 import java.util.Arrays;
12 import java.util.HashMap;
13 import java.util.HashSet;
14 import java.util.LinkedList;
15 import java.util.List;
16 import java.util.Map;
17 import java.util.Optional;
18 import java.util.Set;
19 import java.util.concurrent.ConcurrentLinkedQueue;
20 import java.util.concurrent.CopyOnWriteArrayList;
21 import java.util.concurrent.ExecutionException;
22 import java.util.concurrent.ForkJoinPool;
23 import java.util.concurrent.ForkJoinTask;
24 import java.util.concurrent.atomic.AtomicBoolean;
25 import org.opendaylight.transportpce.common.StringConstants;
26 import org.opendaylight.transportpce.common.crossconnect.CrossConnect;
27 import org.opendaylight.transportpce.common.device.DeviceTransactionManager;
28 import org.opendaylight.transportpce.common.mapping.MappingUtils;
29 import org.opendaylight.transportpce.common.mapping.PortMapping;
30 import org.opendaylight.transportpce.common.openroadminterfaces.OpenRoadmInterfaceException;
31 import org.opendaylight.transportpce.common.openroadminterfaces.OpenRoadmInterfaces;
32 import org.opendaylight.transportpce.renderer.openroadminterface.OpenRoadmInterfaceFactory;
33 import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.device.renderer.rev211004.OtnServicePathInput;
34 import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.device.renderer.rev211004.OtnServicePathOutput;
35 import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.device.renderer.rev211004.OtnServicePathOutputBuilder;
36 import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.device.renderer.rev211004.az.api.info.AEndApiInfo;
37 import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.device.renderer.rev211004.az.api.info.ZEndApiInfo;
38 import org.opendaylight.yang.gen.v1.http.org.openroadm.otn.common.types.rev210924.OpucnTribSlotDef;
39 import org.opendaylight.yang.gen.v1.http.org.transportpce.common.types.rev220926.link.tp.LinkTp;
40 import org.opendaylight.yang.gen.v1.http.org.transportpce.common.types.rev220926.link.tp.LinkTpBuilder;
41 import org.opendaylight.yang.gen.v1.http.org.transportpce.common.types.rev220926.node.interfaces.NodeInterface;
42 import org.opendaylight.yang.gen.v1.http.org.transportpce.common.types.rev220926.node.interfaces.NodeInterfaceBuilder;
43 import org.opendaylight.yang.gen.v1.http.org.transportpce.common.types.rev220926.node.interfaces.NodeInterfaceKey;
44 import org.opendaylight.yang.gen.v1.http.org.transportpce.common.types.rev220926.otn.renderer.nodes.Nodes;
45 import org.osgi.service.component.annotations.Activate;
46 import org.osgi.service.component.annotations.Component;
47 import org.osgi.service.component.annotations.Reference;
48 import org.slf4j.Logger;
49 import org.slf4j.LoggerFactory;
50
51
52 @Component
53 public class OtnDeviceRendererServiceImpl implements OtnDeviceRendererService {
54     private static final Logger LOG = LoggerFactory.getLogger(OtnDeviceRendererServiceImpl.class);
55     private static final String PT_03 = "03";
56     private static final String PT_07 = "07";
57     private final OpenRoadmInterfaceFactory openRoadmInterfaceFactory;
58     private final CrossConnect crossConnect;
59     private final OpenRoadmInterfaces openRoadmInterfaces;
60     private final DeviceTransactionManager deviceTransactionManager;
61
62     @Activate
63     public OtnDeviceRendererServiceImpl(@Reference CrossConnect crossConnect,
64             @Reference OpenRoadmInterfaces openRoadmInterfaces,
65             @Reference DeviceTransactionManager deviceTransactionManager,
66             @Reference MappingUtils mappingUtils,
67             @Reference PortMapping portMapping) {
68         this.crossConnect = crossConnect;
69         this.openRoadmInterfaces = openRoadmInterfaces;
70         this.deviceTransactionManager = deviceTransactionManager;
71         this.openRoadmInterfaceFactory = new OpenRoadmInterfaceFactory(mappingUtils, portMapping, openRoadmInterfaces);
72     }
73
74 //TODO Align log messages and returned results messages
75     @Override
76     public OtnServicePathOutput setupOtnServicePath(OtnServicePathInput input, String serviceType) {
77         LOG.info("Calling setup otn-service path");
78         if (input.getServiceFormat() == null || input.getServiceRate() == null) {
79             return new OtnServicePathOutputBuilder()
80                 .setSuccess(false)
81                 .setResult("Error - service-type and service-rate must be present")
82                 .build();
83         }
84         List<NodeInterface> nodeInterfaces = new ArrayList<>();
85         CopyOnWriteArrayList<LinkTp> otnLinkTps = new CopyOnWriteArrayList<>();
86         try {
87             switch (serviceType) {
88                 case StringConstants.SERVICE_TYPE_1GE:
89                 case StringConstants.SERVICE_TYPE_10GE:
90                 case StringConstants.SERVICE_TYPE_100GE_M:
91                     LOG.info("Calling Node interfaces {} {} {} {} {} {} {}",
92                         input.getServiceRate(), input.getEthernetEncoding(),
93                         input.getServiceFormat(), input.getOperation(), input.getTribPortNumber(),
94                         input.getTribSlot(), input.getNodes());
95                     if (input.getNodes() != null) {
96                         createLowOrderInterfaces(input, nodeInterfaces, otnLinkTps);
97                         LOG.info("Node interfaces created just fine ");
98                     }
99                     break;
100                 case StringConstants.SERVICE_TYPE_ODU4:
101                     createHighOrderInterfaces(input, nodeInterfaces, otnLinkTps);
102                     break;
103                 // For all the intermediate rates, device renderer is generalized as
104                 // ODUCnTTPinterface method
105                 case StringConstants.SERVICE_TYPE_ODUC2:
106                 case StringConstants.SERVICE_TYPE_ODUC3:
107                 case StringConstants.SERVICE_TYPE_ODUC4:
108                     createOducnTtpInterface(input, nodeInterfaces, otnLinkTps);
109                     break;
110                 case StringConstants.SERVICE_TYPE_100GE_S:
111                     LOG.info("Calling Node interface for service-type {}", serviceType);
112                     if (input.getNodes() != null) {
113                         createHighOrderInterfaces(input, nodeInterfaces, otnLinkTps);
114                         LOG.info("Node interfaces created");
115                     }
116                     break;
117                 default:
118                     LOG.error("Service-type {} not managed yet", serviceType);
119                     return new OtnServicePathOutputBuilder()
120                         .setSuccess(false)
121                         .setResult("Service-type not managed")
122                         .build();
123             }
124         } catch (OpenRoadmInterfaceException e) {
125             LOG.warn("Service path set-up failed", e);
126             Map<NodeInterfaceKey,NodeInterface> nodeInterfacesMap = new HashMap<>();
127             for (NodeInterface nodeInterface : nodeInterfaces) {
128                 if (nodeInterface != null) {
129                     nodeInterfacesMap.put(nodeInterface.key(), nodeInterface);
130                 }
131             }
132             //TODO check if we need to set a NodeInterface Map in the result in that case
133             return new OtnServicePathOutputBuilder()
134                     .setSuccess(false)
135                     .setNodeInterface(nodeInterfacesMap)
136                     .setResult("Service path set-up failed")
137                     .setLinkTp(otnLinkTps)
138                     .build();
139         }
140         LOG.info("Service path set-up succeed");
141         List<String> results = new ArrayList<>();
142         Map<NodeInterfaceKey,NodeInterface> nodeInterfacesMap = new HashMap<>();
143         for (NodeInterface nodeInterface : nodeInterfaces) {
144             if (nodeInterface != null) {
145                 results.add("Otn Service path was set up successfully for node :" + nodeInterface.getNodeId());
146                 nodeInterfacesMap.put(nodeInterface.key(), nodeInterface);
147             }
148         }
149         return new OtnServicePathOutputBuilder()
150                 .setSuccess(true)
151                 .setNodeInterface(nodeInterfacesMap)
152                 .setResult(String.join("\n", results))
153                 .setLinkTp(otnLinkTps)
154                 .build();
155     }
156
157     @SuppressWarnings("rawtypes")
158     // FIXME check if the ForkJoinTask raw type can be avoided
159     // Raw types use are discouraged since they lack type safety.
160     // Resulting Problems are observed at run time and not at compile time
161     public OtnServicePathOutput deleteOtnServicePath(OtnServicePathInput input, String serviceType) {
162         if (input.getNodes() == null) {
163             LOG.error("Unable to delete otn service path. input nodes = null");
164             return new OtnServicePathOutputBuilder()
165                 .setResult("Unable to delete otn service path. input nodes = null")
166                 .setSuccess(false)
167                 .build();
168         }
169         List<Nodes> nodes = input.getNodes();
170         AtomicBoolean success = new AtomicBoolean(true);
171         ConcurrentLinkedQueue<String> results = new ConcurrentLinkedQueue<>();
172         CopyOnWriteArrayList<LinkTp> otnLinkTps = new CopyOnWriteArrayList<>();
173         ForkJoinPool forkJoinPool = new ForkJoinPool();
174         ForkJoinTask forkJoinTask = forkJoinPool.submit(() -> nodes.parallelStream().forEach(node -> {
175             String nodeId = node.getNodeId();
176             LOG.info("Deleting service setup on node {}", nodeId);
177             String networkTp = node.getNetworkTp();
178             if (networkTp == null || input.getServiceRate() == null || input.getServiceFormat() == null) {
179                 LOG.error("destination ({}) or service-rate ({}) or service-format ({}) is null.",
180                     networkTp, input.getServiceRate(), input.getServiceFormat());
181                 return;
182             }
183             if (!this.deviceTransactionManager.isDeviceMounted(nodeId)) {
184                 String result = nodeId + " is not mounted on the controller";
185                 results.add(result);
186                 success.set(false);
187                 LOG.warn(result);
188                 forkJoinPool.shutdown();
189                 return;
190                 // TODO should deletion end here?
191             }
192             // if the node is currently mounted then proceed.
193             List<String> interfacesToDelete = new LinkedList<>();
194             String connectionNumber = "";
195             switch (serviceType) {
196                 case StringConstants.SERVICE_TYPE_100GE_S:
197                     connectionNumber = getConnectionNumber(node, networkTp, "ODU4");
198                     break;
199                 case StringConstants.SERVICE_TYPE_100GE_M:
200                     connectionNumber = getConnectionNumber(node, networkTp, "ODU4");
201                     otnLinkTps.add(new LinkTpBuilder()
202                         .setNodeId(nodeId)
203                         .setTpId(networkTp)
204                         .build());
205                     break;
206                 case StringConstants.SERVICE_TYPE_ODU4:
207                     if (node.getClientTp() == null && node.getNetwork2Tp() == null) {
208                         interfacesToDelete.add(networkTp + "-ODU4");
209                         otnLinkTps.add(new LinkTpBuilder()
210                             .setNodeId(nodeId)
211                             .setTpId(networkTp)
212                             .build());
213                     }
214                     if (node.getClientTp() == null && node.getNetwork2Tp() != null) {
215                         interfacesToDelete.add(networkTp + "-ODU4");
216                         interfacesToDelete.add(node.getNetwork2Tp() + "-ODU4");
217                         connectionNumber = getConnectionNumber(node, networkTp, "ODU4");
218                     }
219                     break;
220                 case StringConstants.SERVICE_TYPE_ODUC2:
221                 case StringConstants.SERVICE_TYPE_ODUC3:
222                 case StringConstants.SERVICE_TYPE_ODUC4:
223                     if (node.getClientTp() == null && node.getNetwork2Tp() == null) {
224                         // Service-type can be ODUC2, ODUC3, ODUC4
225                         interfacesToDelete.add(networkTp + "-" + serviceType);
226                         otnLinkTps.add(new LinkTpBuilder()
227                             .setNodeId(nodeId)
228                             .setTpId(networkTp)
229                             .build());
230                     }
231                     if (node.getClientTp() == null && node.getNetwork2Tp() != null) {
232                         interfacesToDelete.add(networkTp + "-" + serviceType);
233                         interfacesToDelete.add(node.getNetwork2Tp() + "-" + serviceType);
234                         connectionNumber = getConnectionNumber(node, networkTp, serviceType);
235                     }
236                     break;
237                 case StringConstants.SERVICE_TYPE_10GE:
238                     connectionNumber = getConnectionNumber(node, networkTp, "ODU2e");
239                     otnLinkTps.add(new LinkTpBuilder()
240                         .setNodeId(nodeId)
241                         .setTpId(networkTp)
242                         .build());
243                     break;
244                 case StringConstants.SERVICE_TYPE_1GE:
245                     connectionNumber = getConnectionNumber(node, networkTp, "ODU0");
246                     otnLinkTps.add(new LinkTpBuilder()
247                         .setNodeId(nodeId)
248                         .setTpId(networkTp)
249                         .build());
250                     break;
251                 default:
252                     LOG.error("service-type {} not managed yet", serviceType);
253                     String result = serviceType + " is not supported";
254                     results.add(result);
255                     success.set(false);
256                     return;
257             }
258             List<String> intToDelete = this.crossConnect.deleteCrossConnect(nodeId, connectionNumber, true);
259             for (String interf : intToDelete == null ? new ArrayList<String>() : intToDelete) {
260                 if (!this.openRoadmInterfaceFactory.isUsedByOtnXc(nodeId, interf, connectionNumber,
261                         this.deviceTransactionManager)) {
262                     interfacesToDelete.add(interf);
263                     String supportedInterface = this.openRoadmInterfaces.getSupportedInterface(nodeId, interf);
264                     if (supportedInterface == null) {
265                         continue;
266                     }
267                     // Here ODUC can be ODUC2, ODUC3, ODUC4
268                     if ((input.getServiceRate().intValue() == 100 && !supportedInterface.contains("ODUC"))
269                         || (input.getServiceRate().intValue() != 100 && !supportedInterface.contains("ODU4"))) {
270                         interfacesToDelete.add(supportedInterface);
271                     }
272                 }
273             }
274
275             for (String interfaceId : interfacesToDelete) {
276                 try {
277                     this.openRoadmInterfaces.deleteInterface(nodeId, interfaceId);
278                 } catch (OpenRoadmInterfaceException e) {
279                     String result = String.format("Failed to delete interface %s on node %s!", interfaceId, nodeId);
280                     success.set(false);
281                     LOG.error(result, e);
282                     results.add(result);
283                 }
284             }
285         }));
286         try {
287             forkJoinTask.get();
288         } catch (InterruptedException | ExecutionException e) {
289             LOG.error("Error while deleting service paths!", e);
290             return new OtnServicePathOutputBuilder()
291                 .setResult("Error while deleting service paths!")
292                 .setSuccess(false)
293                 .build();
294         }
295         forkJoinPool.shutdown();
296         return new OtnServicePathOutputBuilder()
297                 .setSuccess(success.get())
298                 .setLinkTp(otnLinkTps)
299                 .setResult(
300                     results.isEmpty()
301                         ? "Request processed"
302                         : String.join("\n", results))
303                 .build();
304     }
305
306     private String getConnectionNumber(Nodes node, String networkTp, String oduType) {
307         List<String> list1 = new ArrayList<>();
308         List<String> list2 = new ArrayList<>(Arrays.asList("x"));
309         if (node.getClientTp() != null) {
310             list1.addAll(Arrays.asList(node.getClientTp(), oduType));
311             list2.addAll(Arrays.asList(networkTp, oduType));
312         } else if (node.getNetwork2Tp() != null) {
313             list1.addAll(Arrays.asList(networkTp, oduType));
314             list2.addAll(Arrays.asList(node.getNetwork2Tp(), oduType));
315         } else {
316             return "";
317         }
318         list1.addAll(list2);
319         return String.join("-", list1);
320     }
321
322     private Optional<String> postCrossConnect(List<String> createdOduInterfaces, Nodes node)
323             throws OpenRoadmInterfaceException {
324         return this.crossConnect.postOtnCrossConnect(createdOduInterfaces, node);
325     }
326
327     private void createLowOrderInterfaces(OtnServicePathInput input, List<NodeInterface> nodeInterfaces,
328             CopyOnWriteArrayList<LinkTp> linkTpList) throws OpenRoadmInterfaceException {
329         for (Nodes node : input.getNodes()) {
330             AEndApiInfo apiInfoA = null;
331             ZEndApiInfo apiInfoZ = null;
332             if (input.getAEndApiInfo() != null && input.getAEndApiInfo().getNodeId().contains(node.getNodeId())) {
333                 apiInfoA = input.getAEndApiInfo();
334             }
335             if (input.getZEndApiInfo() != null && input.getZEndApiInfo().getNodeId().contains(node.getNodeId())) {
336                 apiInfoZ = input.getZEndApiInfo();
337             }
338             // check if the node is mounted or not?
339             Set<String> createdEthInterfaces = new HashSet<>();
340             Set<String> createdOduInterfaces = new HashSet<>();
341             switch (input.getServiceRate().intValue()) {
342                 case 1:
343                     LOG.info("Input service is 1G");
344                     if (node.getClientTp() != null) {
345                         createdEthInterfaces.add(
346                             openRoadmInterfaceFactory.createOpenRoadmEth1GInterface(node.getNodeId(),
347                                 node.getClientTp()));
348                         createdOduInterfaces.add(
349                             // suppporting interface?, payload ?
350                             openRoadmInterfaceFactory.createOpenRoadmOdu0Interface(node.getNodeId(), node.getClientTp(),
351                                 input.getServiceName(), false, input.getTribPortNumber(), input.getTribSlot(), apiInfoA,
352                                 apiInfoZ, PT_07));
353                     }
354                     createdOduInterfaces.add(
355                         openRoadmInterfaceFactory.createOpenRoadmOdu0Interface(node.getNodeId(), node.getNetworkTp(),
356                             input.getServiceName(), true, input.getTribPortNumber(), input.getTribSlot(), null, null,
357                             null));
358                     linkTpList.add(
359                         new LinkTpBuilder().setNodeId(node.getNodeId()).setTpId(node.getNetworkTp()).build());
360                     if (node.getNetwork2Tp() != null) {
361                         createdOduInterfaces.add(
362                             // supporting interface? payload ?
363                             openRoadmInterfaceFactory.createOpenRoadmOdu0Interface(node.getNodeId(),
364                                 node.getNetwork2Tp(), input.getServiceName(), true, input.getTribPortNumber(),
365                                 input.getTribSlot(), null, null, null));
366                         linkTpList.add(
367                             new LinkTpBuilder().setNodeId(node.getNodeId()).setTpId(node.getNetworkTp()).build());
368                     }
369                     break;
370                 case 10:
371                     LOG.info("Input service is 10G");
372                     if (node.getClientTp() != null) {
373                         createdEthInterfaces.add(openRoadmInterfaceFactory.createOpenRoadmEth10GInterface(
374                             node.getNodeId(), node.getClientTp()));
375                         createdOduInterfaces.add(
376                             // supporting interface?, payload ?
377                             openRoadmInterfaceFactory.createOpenRoadmOdu2eInterface(node.getNodeId(),
378                                 node.getClientTp(),  input.getServiceName(), false, input.getTribPortNumber(),
379                                 input.getTribSlot(), apiInfoA, apiInfoZ, PT_03));
380                     }
381                     createdOduInterfaces.add(
382                         // supporting interface? payload ?
383                         openRoadmInterfaceFactory.createOpenRoadmOdu2eInterface(node.getNodeId(), node.getNetworkTp(),
384                              input.getServiceName(), true, input.getTribPortNumber(), input.getTribSlot(), null,
385                             null, null));
386                     linkTpList.add(
387                         new LinkTpBuilder().setNodeId(node.getNodeId()).setTpId(node.getNetworkTp()).build());
388                     if (node.getNetwork2Tp() != null) {
389                         createdOduInterfaces.add(
390                             // supporting interface? payload ?
391                             openRoadmInterfaceFactory.createOpenRoadmOdu2eInterface(node.getNodeId(),
392                                 node.getNetwork2Tp(), input.getServiceName(),true, input.getTribPortNumber(),
393                                 input.getTribSlot(), null, null, null));
394                         linkTpList.add(
395                             new LinkTpBuilder().setNodeId(node.getNodeId()).setTpId(node.getNetworkTp()).build());
396                     }
397                     break;
398                 case 100:
399                     LOG.info("Input service is 100G");
400                     // Take the first and last value in the list of OpucnTribSlot (assuming SH would provide
401                     // min and max value only, size two)
402                     OpucnTribSlotDef minOpucnTs = input.getOpucnTribSlots().stream()
403                         .min((ts1, ts2) -> ts1.getValue().compareTo(ts2.getValue())).orElseThrow();
404                     OpucnTribSlotDef maxOpucnTs = input.getOpucnTribSlots().stream()
405                         .max((ts1, ts2) -> ts1.getValue().compareTo(ts2.getValue())).orElseThrow();
406                     if (node.getClientTp() != null) {
407                         createdEthInterfaces.add(openRoadmInterfaceFactory.createOpenRoadmEth100GInterface(
408                             node.getNodeId(), node.getClientTp()));
409                         // OPUCn trib information is optional when creating ODU4 ethernet (client) interface
410                         createdOduInterfaces.add(
411                             openRoadmInterfaceFactory.createOpenRoadmOtnOdu4LoInterface(node.getNodeId(),
412                             node.getClientTp(), input.getServiceName(), PT_07, false, minOpucnTs,
413                                 maxOpucnTs));
414                     }
415                     // Here payload-type is optional and is not used for interface creation (especially for network)
416                     createdOduInterfaces.add(
417                         openRoadmInterfaceFactory.createOpenRoadmOtnOdu4LoInterface(node.getNodeId(),
418                             node.getNetworkTp(), input.getServiceName(), PT_07, true, minOpucnTs,
419                             maxOpucnTs));
420                     linkTpList.add(
421                         new LinkTpBuilder().setNodeId(node.getNodeId()).setTpId(node.getNetworkTp()).build());
422                     // Here payload-type is optional and is not used for service creation
423                     // This is needed if there is an intermediate node
424                     if (node.getNetwork2Tp() != null) {
425                         createdOduInterfaces.add(
426                             openRoadmInterfaceFactory.createOpenRoadmOtnOdu4LoInterface(node.getNodeId(),
427                                 node.getNetwork2Tp(), input.getServiceName(), PT_07, true, minOpucnTs,
428                                 maxOpucnTs));
429                         linkTpList.add(
430                             new LinkTpBuilder().setNodeId(node.getNodeId()).setTpId(node.getNetworkTp()).build());
431                     }
432                     break;
433                 default:
434                     LOG.error("service rate {} not managed yet", input.getServiceRate());
435                     return;
436             }
437
438             // implement cross connect
439             Set<String> createdConnections = new HashSet<>();
440             if (!createdOduInterfaces.isEmpty()) {
441                 Optional<String> connectionNameOpt = postCrossConnect(new ArrayList<>(createdOduInterfaces), node);
442                 createdConnections.add(connectionNameOpt.orElseThrow());
443                 LOG.info("Created cross connects");
444             }
445             nodeInterfaces.add(new NodeInterfaceBuilder()
446                     .withKey(new NodeInterfaceKey(node.getNodeId()))
447                     .setNodeId(node.getNodeId())
448                     .setConnectionId(createdConnections)
449                     .setEthInterfaceId(createdEthInterfaces)
450                     .setOduInterfaceId(createdOduInterfaces)
451                     .build());
452         }
453     }
454
455     private void createHighOrderInterfaces(OtnServicePathInput input, List<NodeInterface> nodeInterfaces,
456             CopyOnWriteArrayList<LinkTp> linkTpList) throws OpenRoadmInterfaceException {
457         for (Nodes node : input.nonnullNodes()) {
458             AEndApiInfo apiInfoA = null;
459             ZEndApiInfo apiInfoZ = null;
460             if (input.getAEndApiInfo() != null && input.getAEndApiInfo().getNodeId().contains(node.getNodeId())) {
461                 apiInfoA = input.getAEndApiInfo();
462             }
463             if (input.getZEndApiInfo() != null && input.getZEndApiInfo().getNodeId().contains(node.getNodeId())) {
464                 apiInfoZ = input.getZEndApiInfo();
465             }
466             // check if the node is mounted or not?
467             Set<String> createdEthInterfaces = new HashSet<>();
468             Set<String> createdOduInterfaces = new HashSet<>();
469             switch (input.getServiceRate().intValue()) {
470                 case 100:
471                     LOG.info("Input service is 100G");
472                     if (node.getClientTp() != null && node.getNetwork2Tp() == null) {
473                         createdEthInterfaces.add(openRoadmInterfaceFactory.createOpenRoadmEth100GInterface(
474                             node.getNodeId(), node.getClientTp()));
475                         createdOduInterfaces.add(openRoadmInterfaceFactory.createOpenRoadmOdu4HOInterface(
476                                 node.getNodeId(), node.getClientTp(), false, apiInfoA, apiInfoZ, "21"));
477                         // supporting interface? payload ?
478                         createdOduInterfaces.add(openRoadmInterfaceFactory.createOpenRoadmOdu4HOInterface(
479                                 node.getNodeId(), node.getNetworkTp(), true, null, null, null));
480                         linkTpList.add(new LinkTpBuilder().setNodeId(node.getNodeId()).setTpId(node.getClientTp())
481                                 .build());
482                     }
483                     if (node.getClientTp() == null && node.getNetwork2Tp() == null) {
484                         createdOduInterfaces.add(openRoadmInterfaceFactory.createOpenRoadmOdu4HOInterface(
485                             node.getNodeId(), node.getNetworkTp(), false, apiInfoA, apiInfoZ, "21"));
486                         linkTpList.add(new LinkTpBuilder().setNodeId(node.getNodeId()).setTpId(node.getNetworkTp())
487                             .build());
488                     }
489                     if (node.getClientTp() == null && node.getNetwork2Tp() != null) {
490                         // supporting interface? payload ?
491                         createdOduInterfaces.add(openRoadmInterfaceFactory.createOpenRoadmOdu4HOInterface(
492                             node.getNodeId(), node.getNetworkTp(), true, null, null, null));
493                         createdOduInterfaces.add(openRoadmInterfaceFactory.createOpenRoadmOdu4HOInterface(
494                                 node.getNodeId(), node.getNetwork2Tp(), true, null, null, null));
495                     }
496                     break;
497                 default:
498                     LOG.error("service rate {} not managed yet", input.getServiceRate());
499                     return;
500             }
501
502             // implement cross connect
503             Set<String> createdConnections = new HashSet<>();
504             if (createdOduInterfaces.size() == 2) {
505                 Optional<String> connectionNameOpt = postCrossConnect(new ArrayList<>(createdOduInterfaces), node);
506                 createdConnections.add(connectionNameOpt.orElseThrow());
507                 LOG.info("Created cross connects");
508             }
509             nodeInterfaces.add(new NodeInterfaceBuilder()
510                     .withKey(new NodeInterfaceKey(node.getNodeId()))
511                     .setNodeId(node.getNodeId())
512                     .setConnectionId(createdConnections)
513                     .setEthInterfaceId(createdEthInterfaces)
514                     .setOduInterfaceId(createdOduInterfaces)
515                     .build());
516         }
517     }
518
519     private void createOducnTtpInterface(OtnServicePathInput input, List<NodeInterface> nodeInterfaces,
520         CopyOnWriteArrayList<LinkTp> linkTpList) throws OpenRoadmInterfaceException {
521         if (input.getNodes() == null) {
522             return;
523         }
524         if (input.getServiceRate() == null) {
525             LOG.error("Missing service rate for ODUCn interface");
526             return;
527         }
528         LOG.info("Creation of ODUCn TTP interface in OTN service path {}", input);
529         for (int i = 0; i < input.getNodes().size(); i++) {
530             Nodes node = input.getNodes().get(i);
531             // Based on the service rate, we will know if it is a OTUC4, OTUC3 or OTUC2
532             String supportingOtuInterface = node.getNetworkTp();
533             boolean serviceRateNotSupp = false;
534
535             switch (input.getServiceRate().intValue()) {
536                 case 200:
537                     supportingOtuInterface += "-OTUC2";
538                     break;
539                 case 300:
540                     supportingOtuInterface += "-OTUC3";
541                     break;
542                 case 400:
543                     supportingOtuInterface += "-OTUC4";
544                     break;
545                 default:
546                     serviceRateNotSupp = true;
547                     break;
548             }
549             if (serviceRateNotSupp) {
550                 LOG.error("Service rate {} is not supported", input.getServiceRate());
551             }
552
553             Nodes tgtNode =
554                 i + 1 == input.getNodes().size()
555                 // For the end node, tgtNode becomes the first node in the list
556                     ? input.getNodes().get(0)
557                     : input.getNodes().get(i + 1);
558
559             nodeInterfaces.add(new NodeInterfaceBuilder()
560                     .withKey(new NodeInterfaceKey(node.getNodeId()))
561                     .setNodeId(node.getNodeId())
562                     .setOduInterfaceId(Set.of(
563                         // though this is odu, actually it has ODUCn interfaces
564                         openRoadmInterfaceFactory.createOpenRoadmOtnOducnInterface(node.getNodeId(),
565                             node.getNetworkTp(), supportingOtuInterface, tgtNode.getNodeId(), tgtNode.getNetworkTp())))
566                     .build());
567             linkTpList.add(new LinkTpBuilder().setNodeId(node.getNodeId()).setTpId(node.getNetworkTp()).build());
568         }
569     }
570 }