2 * Copyright © 2019 AT&T 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.renderer.provisiondevice;
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;
17 import java.util.Optional;
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;
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;
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);
74 //TODO Align log messages and returned results messages
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()
81 .setResult("Error - service-type and service-rate must be present")
84 List<NodeInterface> nodeInterfaces = new ArrayList<>();
85 CopyOnWriteArrayList<LinkTp> otnLinkTps = new CopyOnWriteArrayList<>();
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 ");
100 case StringConstants.SERVICE_TYPE_ODU4:
101 createHighOrderInterfaces(input, nodeInterfaces, otnLinkTps);
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);
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");
118 LOG.error("Service-type {} not managed yet", serviceType);
119 return new OtnServicePathOutputBuilder()
121 .setResult("Service-type not managed")
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);
132 //TODO check if we need to set a NodeInterface Map in the result in that case
133 return new OtnServicePathOutputBuilder()
135 .setNodeInterface(nodeInterfacesMap)
136 .setResult("Service path set-up failed")
137 .setLinkTp(otnLinkTps)
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);
149 return new OtnServicePathOutputBuilder()
151 .setNodeInterface(nodeInterfacesMap)
152 .setResult(String.join("\n", results))
153 .setLinkTp(otnLinkTps)
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")
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());
183 if (!this.deviceTransactionManager.isDeviceMounted(nodeId)) {
184 String result = nodeId + " is not mounted on the controller";
188 forkJoinPool.shutdown();
190 // TODO should deletion end here?
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");
199 case StringConstants.SERVICE_TYPE_100GE_M:
200 connectionNumber = getConnectionNumber(node, networkTp, "ODU4");
201 otnLinkTps.add(new LinkTpBuilder()
206 case StringConstants.SERVICE_TYPE_ODU4:
207 if (node.getClientTp() == null && node.getNetwork2Tp() == null) {
208 interfacesToDelete.add(networkTp + "-ODU4");
209 otnLinkTps.add(new LinkTpBuilder()
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");
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()
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);
237 case StringConstants.SERVICE_TYPE_10GE:
238 connectionNumber = getConnectionNumber(node, networkTp, "ODU2e");
239 otnLinkTps.add(new LinkTpBuilder()
244 case StringConstants.SERVICE_TYPE_1GE:
245 connectionNumber = getConnectionNumber(node, networkTp, "ODU0");
246 otnLinkTps.add(new LinkTpBuilder()
252 LOG.error("service-type {} not managed yet", serviceType);
253 String result = serviceType + " is not supported";
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) {
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);
275 for (String interfaceId : interfacesToDelete) {
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);
281 LOG.error(result, e);
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!")
295 forkJoinPool.shutdown();
296 return new OtnServicePathOutputBuilder()
297 .setSuccess(success.get())
298 .setLinkTp(otnLinkTps)
301 ? "Request processed"
302 : String.join("\n", results))
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));
319 return String.join("-", list1);
322 private Optional<String> postCrossConnect(List<String> createdOduInterfaces, Nodes node)
323 throws OpenRoadmInterfaceException {
324 return this.crossConnect.postOtnCrossConnect(createdOduInterfaces, node);
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();
335 if (input.getZEndApiInfo() != null && input.getZEndApiInfo().getNodeId().contains(node.getNodeId())) {
336 apiInfoZ = input.getZEndApiInfo();
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()) {
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,
354 createdOduInterfaces.add(
355 openRoadmInterfaceFactory.createOpenRoadmOdu0Interface(node.getNodeId(), node.getNetworkTp(),
356 input.getServiceName(), true, input.getTribPortNumber(), input.getTribSlot(), null, null,
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));
367 new LinkTpBuilder().setNodeId(node.getNodeId()).setTpId(node.getNetworkTp()).build());
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));
381 createdOduInterfaces.add(
382 // supporting interface? payload ?
383 openRoadmInterfaceFactory.createOpenRoadmOdu2eInterface(node.getNodeId(), node.getNetworkTp(),
384 input.getServiceName(), true, input.getTribPortNumber(), input.getTribSlot(), null,
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));
395 new LinkTpBuilder().setNodeId(node.getNodeId()).setTpId(node.getNetworkTp()).build());
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())).get();
404 OpucnTribSlotDef maxOpucnTs = input.getOpucnTribSlots().stream()
405 .max((ts1, ts2) -> ts1.getValue().compareTo(ts2.getValue())).get();
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,
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,
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,
430 new LinkTpBuilder().setNodeId(node.getNodeId()).setTpId(node.getNetworkTp()).build());
434 LOG.error("service rate {} not managed yet", input.getServiceRate());
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.get());
443 LOG.info("Created cross connects");
445 nodeInterfaces.add(new NodeInterfaceBuilder()
446 .withKey(new NodeInterfaceKey(node.getNodeId()))
447 .setNodeId(node.getNodeId())
448 .setConnectionId(createdConnections)
449 .setEthInterfaceId(createdEthInterfaces)
450 .setOduInterfaceId(createdOduInterfaces)
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();
463 if (input.getZEndApiInfo() != null && input.getZEndApiInfo().getNodeId().contains(node.getNodeId())) {
464 apiInfoZ = input.getZEndApiInfo();
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()) {
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())
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())
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));
498 LOG.error("service rate {} not managed yet", input.getServiceRate());
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.get());
507 LOG.info("Created cross connects");
509 nodeInterfaces.add(new NodeInterfaceBuilder()
510 .withKey(new NodeInterfaceKey(node.getNodeId()))
511 .setNodeId(node.getNodeId())
512 .setConnectionId(createdConnections)
513 .setEthInterfaceId(createdEthInterfaces)
514 .setOduInterfaceId(createdOduInterfaces)
519 private void createOducnTtpInterface(OtnServicePathInput input, List<NodeInterface> nodeInterfaces,
520 CopyOnWriteArrayList<LinkTp> linkTpList) throws OpenRoadmInterfaceException {
521 if (input.getNodes() == null) {
524 if (input.getServiceRate() == null) {
525 LOG.error("Missing service rate for ODUCn interface");
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;
535 switch (input.getServiceRate().intValue()) {
537 supportingOtuInterface += "-OTUC2";
540 supportingOtuInterface += "-OTUC3";
543 supportingOtuInterface += "-OTUC4";
546 serviceRateNotSupp = true;
549 if (serviceRateNotSupp) {
550 LOG.error("Service rate {} is not supported", input.getServiceRate());
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);
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())))
567 linkTpList.add(new LinkTpBuilder().setNodeId(node.getNodeId()).setTpId(node.getNetworkTp()).build());