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.LinkedList;
14 import java.util.List;
16 import java.util.Optional;
17 import java.util.concurrent.ConcurrentLinkedQueue;
18 import java.util.concurrent.CopyOnWriteArrayList;
19 import java.util.concurrent.ExecutionException;
20 import java.util.concurrent.ForkJoinPool;
21 import java.util.concurrent.ForkJoinTask;
22 import java.util.concurrent.atomic.AtomicBoolean;
23 import org.opendaylight.transportpce.common.StringConstants;
24 import org.opendaylight.transportpce.common.crossconnect.CrossConnect;
25 import org.opendaylight.transportpce.common.device.DeviceTransactionManager;
26 import org.opendaylight.transportpce.common.openroadminterfaces.OpenRoadmInterfaceException;
27 import org.opendaylight.transportpce.common.openroadminterfaces.OpenRoadmInterfaces;
28 import org.opendaylight.transportpce.networkmodel.service.NetworkModelService;
29 import org.opendaylight.transportpce.renderer.openroadminterface.OpenRoadmInterfaceFactory;
30 import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.device.renderer.rev211004.OtnServicePathInput;
31 import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.device.renderer.rev211004.OtnServicePathOutput;
32 import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.device.renderer.rev211004.OtnServicePathOutputBuilder;
33 import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.device.renderer.rev211004.az.api.info.AEndApiInfo;
34 import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.device.renderer.rev211004.az.api.info.ZEndApiInfo;
35 import org.opendaylight.yang.gen.v1.http.org.openroadm.otn.common.types.rev200327.OpucnTribSlotDef;
36 import org.opendaylight.yang.gen.v1.http.org.transportpce.common.types.rev210618.link.tp.LinkTp;
37 import org.opendaylight.yang.gen.v1.http.org.transportpce.common.types.rev210618.link.tp.LinkTpBuilder;
38 import org.opendaylight.yang.gen.v1.http.org.transportpce.common.types.rev210618.node.interfaces.NodeInterface;
39 import org.opendaylight.yang.gen.v1.http.org.transportpce.common.types.rev210618.node.interfaces.NodeInterfaceBuilder;
40 import org.opendaylight.yang.gen.v1.http.org.transportpce.common.types.rev210618.node.interfaces.NodeInterfaceKey;
41 import org.opendaylight.yang.gen.v1.http.org.transportpce.common.types.rev210618.otn.renderer.nodes.Nodes;
42 import org.slf4j.Logger;
43 import org.slf4j.LoggerFactory;
46 public class OtnDeviceRendererServiceImpl implements OtnDeviceRendererService {
47 private static final Logger LOG = LoggerFactory.getLogger(OtnDeviceRendererServiceImpl.class);
48 private static final String PT_03 = "03";
49 private static final String PT_07 = "07";
50 private final OpenRoadmInterfaceFactory openRoadmInterfaceFactory;
51 private final CrossConnect crossConnect;
52 private final OpenRoadmInterfaces openRoadmInterfaces;
53 private final DeviceTransactionManager deviceTransactionManager;
54 private final NetworkModelService networkModelService;
56 public OtnDeviceRendererServiceImpl(OpenRoadmInterfaceFactory openRoadmInterfaceFactory, CrossConnect crossConnect,
57 OpenRoadmInterfaces openRoadmInterfaces,
58 DeviceTransactionManager deviceTransactionManager,
59 NetworkModelService networkModelService) {
60 this.openRoadmInterfaceFactory = openRoadmInterfaceFactory;
61 this.crossConnect = crossConnect;
62 this.openRoadmInterfaces = openRoadmInterfaces;
63 this.deviceTransactionManager = deviceTransactionManager;
64 this.networkModelService = networkModelService;
67 //TODO Align log messages and returned results messages
69 public OtnServicePathOutput setupOtnServicePath(OtnServicePathInput input, String serviceType) {
70 LOG.info("Calling setup otn-service path");
71 if (input.getServiceFormat() == null || input.getServiceRate() == null) {
72 return new OtnServicePathOutputBuilder()
74 .setResult("Error - service-type and service-rate must be present")
77 List<NodeInterface> nodeInterfaces = new ArrayList<>();
78 CopyOnWriteArrayList<LinkTp> otnLinkTps = new CopyOnWriteArrayList<>();
80 switch (serviceType) {
81 case StringConstants.SERVICE_TYPE_1GE:
82 case StringConstants.SERVICE_TYPE_10GE:
83 case StringConstants.SERVICE_TYPE_100GE_M:
84 LOG.info("Calling Node interfaces {} {} {} {} {} {} {}",
85 input.getServiceRate(), input.getEthernetEncoding(),
86 input.getServiceFormat(), input.getOperation(), input.getTribPortNumber(),
87 input.getTribSlot(), input.getNodes());
88 if (input.getNodes() != null) {
89 createLowOrderInterfaces(input, nodeInterfaces, otnLinkTps);
90 LOG.info("Node interfaces created just fine ");
93 case StringConstants.SERVICE_TYPE_ODU4:
94 createHighOrderInterfaces(input, nodeInterfaces, otnLinkTps);
96 case StringConstants.SERVICE_TYPE_ODUC4:
97 createOduc4TtpInterface(input, nodeInterfaces, otnLinkTps);
99 case StringConstants.SERVICE_TYPE_100GE_S:
100 LOG.info("Calling Node interface for service-type {}", serviceType);
101 if (input.getNodes() != null) {
102 createHighOrderInterfaces(input, nodeInterfaces, otnLinkTps);
103 LOG.info("Node interfaces created");
107 LOG.error("Service-type {} not managed yet", serviceType);
108 return new OtnServicePathOutputBuilder()
110 .setResult("Service-type not managed")
113 } catch (OpenRoadmInterfaceException e) {
114 LOG.warn("Service path set-up failed", e);
115 Map<NodeInterfaceKey,NodeInterface> nodeInterfacesMap = new HashMap<>();
116 for (NodeInterface nodeInterface : nodeInterfaces) {
117 if (nodeInterface != null) {
118 nodeInterfacesMap.put(nodeInterface.key(), nodeInterface);
121 //TODO check if we need to set a NodeInterface Map in the result in that case
122 return new OtnServicePathOutputBuilder()
124 .setNodeInterface(nodeInterfacesMap)
125 .setResult("Service path set-up failed")
126 .setLinkTp(otnLinkTps)
129 LOG.info("Service path set-up succeed");
130 List<String> results = new ArrayList<>();
131 Map<NodeInterfaceKey,NodeInterface> nodeInterfacesMap = new HashMap<>();
132 for (NodeInterface nodeInterface : nodeInterfaces) {
133 if (nodeInterface != null) {
134 results.add("Otn Service path was set up successfully for node :" + nodeInterface.getNodeId());
135 nodeInterfacesMap.put(nodeInterface.key(), nodeInterface);
138 return new OtnServicePathOutputBuilder()
140 .setNodeInterface(nodeInterfacesMap)
141 .setResult(String.join("\n", results))
142 .setLinkTp(otnLinkTps)
146 @SuppressWarnings("rawtypes")
147 // FIXME check if the ForkJoinTask raw type can be avoided
148 // Raw types use are discouraged since they lack type safety.
149 // Resulting Problems are observed at run time and not at compile time
150 public OtnServicePathOutput deleteOtnServicePath(OtnServicePathInput input, String serviceType) {
151 if (input.getNodes() == null) {
152 LOG.error("Unable to delete otn service path. input nodes = null");
153 return new OtnServicePathOutputBuilder()
154 .setResult("Unable to delete otn service path. input nodes = null")
158 List<Nodes> nodes = input.getNodes();
159 AtomicBoolean success = new AtomicBoolean(true);
160 ConcurrentLinkedQueue<String> results = new ConcurrentLinkedQueue<>();
161 CopyOnWriteArrayList<LinkTp> otnLinkTps = new CopyOnWriteArrayList<>();
162 ForkJoinPool forkJoinPool = new ForkJoinPool();
163 ForkJoinTask forkJoinTask = forkJoinPool.submit(() -> nodes.parallelStream().forEach(node -> {
164 String nodeId = node.getNodeId();
165 LOG.info("Deleting service setup on node {}", nodeId);
166 String networkTp = node.getNetworkTp();
167 if (networkTp == null || input.getServiceRate() == null || input.getServiceFormat() == null) {
168 LOG.error("destination ({}) or service-rate ({}) or service-format ({}) is null.",
169 networkTp, input.getServiceRate(), input.getServiceFormat());
172 if (!this.deviceTransactionManager.isDeviceMounted(nodeId)) {
173 String result = nodeId + " is not mounted on the controller";
177 forkJoinPool.shutdown();
179 // TODO should deletion end here?
181 // if the node is currently mounted then proceed.
182 List<String> interfacesToDelete = new LinkedList<>();
183 String connectionNumber = "";
184 switch (serviceType) {
185 case StringConstants.SERVICE_TYPE_100GE_S:
186 connectionNumber = getConnectionNumber(null, node, networkTp, "ODU4");
188 case StringConstants.SERVICE_TYPE_100GE_M:
189 connectionNumber = getConnectionNumber(input.getServiceName(), node, networkTp, "ODU4");
190 otnLinkTps.add(new LinkTpBuilder()
195 case StringConstants.SERVICE_TYPE_ODU4:
196 if (node.getClientTp() == null && node.getNetwork2Tp() == null) {
197 interfacesToDelete.add(networkTp + "-ODU4");
198 otnLinkTps.add(new LinkTpBuilder()
203 if (node.getClientTp() == null && node.getNetwork2Tp() != null) {
204 interfacesToDelete.add(networkTp + "-ODU4");
205 interfacesToDelete.add(node.getNetwork2Tp() + "-ODU4");
206 connectionNumber = getConnectionNumber(null, node, networkTp, "ODU4");
209 case StringConstants.SERVICE_TYPE_ODUC4:
210 if (node.getClientTp() == null && node.getNetwork2Tp() == null) {
211 interfacesToDelete.add(networkTp + "-ODUC4");
212 otnLinkTps.add(new LinkTpBuilder()
217 if (node.getClientTp() == null && node.getNetwork2Tp() != null) {
218 interfacesToDelete.add(networkTp + "-ODUC4");
219 interfacesToDelete.add(node.getNetwork2Tp() + "-ODUC4");
220 connectionNumber = getConnectionNumber(null, node, networkTp, "ODUC4");
223 case StringConstants.SERVICE_TYPE_10GE:
224 connectionNumber = getConnectionNumber(input.getServiceName(), node, networkTp, "ODU2e");
225 otnLinkTps.add(new LinkTpBuilder()
230 case StringConstants.SERVICE_TYPE_1GE:
231 connectionNumber = getConnectionNumber(input.getServiceName(), node, networkTp, "ODU0");
232 otnLinkTps.add(new LinkTpBuilder()
238 LOG.error("service-type {} not managed yet", serviceType);
239 String result = serviceType + " is not supported";
244 List<String> intToDelete = this.crossConnect.deleteCrossConnect(nodeId, connectionNumber, true);
245 for (String interf : intToDelete == null ? new ArrayList<String>() : intToDelete) {
246 if (!this.openRoadmInterfaceFactory.isUsedByOtnXc(nodeId, interf, connectionNumber,
247 this.deviceTransactionManager)) {
248 interfacesToDelete.add(interf);
249 String supportedInterface = this.openRoadmInterfaces.getSupportedInterface(nodeId, interf);
250 if (supportedInterface == null) {
253 if ((input.getServiceRate().intValue() == 100 && !supportedInterface.contains("ODUC4"))
254 || (input.getServiceRate().intValue() != 100 && !supportedInterface.contains("ODU4"))) {
255 interfacesToDelete.add(supportedInterface);
260 for (String interfaceId : interfacesToDelete) {
262 this.openRoadmInterfaces.deleteInterface(nodeId, interfaceId);
263 } catch (OpenRoadmInterfaceException e) {
264 String result = String.format("Failed to delete interface %s on node %s!", interfaceId, nodeId);
266 LOG.error(result, e);
273 } catch (InterruptedException | ExecutionException e) {
274 LOG.error("Error while deleting service paths!", e);
275 return new OtnServicePathOutputBuilder()
276 .setResult("Error while deleting service paths!")
280 forkJoinPool.shutdown();
281 return new OtnServicePathOutputBuilder()
282 .setSuccess(success.get())
283 .setLinkTp(otnLinkTps)
286 ? "Request processed"
287 : String.join("\n", results))
291 private String getConnectionNumber(String serviceName, Nodes node, String networkTp, String oduType) {
292 List<String> list1 = new ArrayList<>();
293 List<String> list2 = new ArrayList<>(Arrays.asList("x"));
294 if (node.getClientTp() != null) {
295 list1.addAll(Arrays.asList(node.getClientTp(), oduType));
296 list2.addAll(Arrays.asList(networkTp, oduType));
297 } else if (node.getNetwork2Tp() != null) {
298 list1.addAll(Arrays.asList(networkTp, oduType));
299 list2.addAll(Arrays.asList(node.getNetwork2Tp(), oduType));
303 if (serviceName != null) {
304 list1.add(serviceName);
305 list2.add(serviceName);
308 return String.join("-", list1);
311 private Optional<String> postCrossConnect(List<String> createdOduInterfaces, Nodes node)
312 throws OpenRoadmInterfaceException {
313 return this.crossConnect.postOtnCrossConnect(createdOduInterfaces, node);
316 private void createLowOrderInterfaces(OtnServicePathInput input, List<NodeInterface> nodeInterfaces,
317 CopyOnWriteArrayList<LinkTp> linkTpList) throws OpenRoadmInterfaceException {
318 for (Nodes node : input.getNodes()) {
319 AEndApiInfo apiInfoA = null;
320 ZEndApiInfo apiInfoZ = null;
321 if (input.getAEndApiInfo() != null && input.getAEndApiInfo().getNodeId().contains(node.getNodeId())) {
322 apiInfoA = input.getAEndApiInfo();
324 if (input.getZEndApiInfo() != null && input.getZEndApiInfo().getNodeId().contains(node.getNodeId())) {
325 apiInfoZ = input.getZEndApiInfo();
327 // check if the node is mounted or not?
328 List<String> createdEthInterfaces = new ArrayList<>();
329 List<String> createdOduInterfaces = new ArrayList<>();
330 switch (input.getServiceRate().intValue()) {
332 LOG.info("Input service is 1G");
333 if (node.getClientTp() != null) {
334 createdEthInterfaces.add(
335 openRoadmInterfaceFactory.createOpenRoadmEth1GInterface(node.getNodeId(),
336 node.getClientTp()));
337 createdOduInterfaces.add(
338 // suppporting interface?, payload ?
339 openRoadmInterfaceFactory.createOpenRoadmOdu0Interface(node.getNodeId(), node.getClientTp(),
340 input.getServiceName(), PT_07, false, input.getTribPortNumber(), input.getTribSlot()));
342 createdOduInterfaces.add(
343 openRoadmInterfaceFactory.createOpenRoadmOdu0Interface(node.getNodeId(), node.getNetworkTp(),
344 input.getServiceName(), PT_07, true, input.getTribPortNumber(), input.getTribSlot()));
346 new LinkTpBuilder().setNodeId(node.getNodeId()).setTpId(node.getNetworkTp()).build());
347 if (node.getNetwork2Tp() != null) {
348 createdOduInterfaces.add(
349 // supporting interface? payload ?
350 openRoadmInterfaceFactory.createOpenRoadmOdu0Interface(node.getNodeId(),
351 node.getNetwork2Tp(), input.getServiceName(), PT_07, true, input.getTribPortNumber(),
352 input.getTribSlot()));
354 new LinkTpBuilder().setNodeId(node.getNodeId()).setTpId(node.getNetworkTp()).build());
358 LOG.info("Input service is 10G");
359 if (node.getClientTp() != null) {
360 createdEthInterfaces.add(openRoadmInterfaceFactory.createOpenRoadmEth10GInterface(
361 node.getNodeId(), node.getClientTp()));
362 createdOduInterfaces.add(
363 // suppporting interface?, payload ?
364 openRoadmInterfaceFactory.createOpenRoadmOdu2eInterface(node.getNodeId(),
365 node.getClientTp(), input.getServiceName(), false, input.getTribPortNumber(),
366 input.getTribSlot(), apiInfoA, apiInfoZ));
368 createdOduInterfaces.add(
369 // supporting interface? payload ?
370 openRoadmInterfaceFactory.createOpenRoadmOdu2eInterface(node.getNodeId(), node.getNetworkTp(),
371 input.getServiceName(), true, input.getTribPortNumber(), input.getTribSlot(), apiInfoA,
374 new LinkTpBuilder().setNodeId(node.getNodeId()).setTpId(node.getNetworkTp()).build());
375 if (node.getNetwork2Tp() != null) {
376 createdOduInterfaces.add(
377 // supporting interface? payload ?
378 openRoadmInterfaceFactory.createOpenRoadmOdu2eInterface(node.getNodeId(),
379 node.getNetwork2Tp(), input.getServiceName(), true, input.getTribPortNumber(),
380 input.getTribSlot(), apiInfoA, apiInfoZ));
382 new LinkTpBuilder().setNodeId(node.getNodeId()).setTpId(node.getNetworkTp()).build());
386 LOG.info("Input service is 100G");
387 // Take the first and last value in the list of OpucnTribSlot (assuming SH would provide
388 // min and max value only, size two)
389 OpucnTribSlotDef minOpucnTs = OpucnTribSlotDef.getDefaultInstance(
390 input.getOpucnTribSlots().get(0).getValue());
391 OpucnTribSlotDef maxOpucnTs = OpucnTribSlotDef.getDefaultInstance(
392 input.getOpucnTribSlots().get(1).getValue());
393 if (node.getClientTp() != null) {
394 createdEthInterfaces.add(openRoadmInterfaceFactory.createOpenRoadmEth100GInterface(
395 node.getNodeId(), node.getClientTp()));
396 // OPUCn trib information is optional when creating ODU4 ethernet (client) interface
397 createdOduInterfaces.add(
398 openRoadmInterfaceFactory.createOpenRoadmOtnOdu4LoInterface(node.getNodeId(),
399 node.getClientTp(), input.getServiceName(), PT_07, false, minOpucnTs,
402 // Here payload-type is optional and is not used for interface creation (especially for network)
403 createdOduInterfaces.add(
404 openRoadmInterfaceFactory.createOpenRoadmOtnOdu4LoInterface(node.getNodeId(),
405 node.getNetworkTp(), input.getServiceName(), PT_07, true, minOpucnTs,
408 new LinkTpBuilder().setNodeId(node.getNodeId()).setTpId(node.getNetworkTp()).build());
409 // Here payload-type is optional and is not used for service creation
410 // This is needed if there is an intermediate node
411 if (node.getNetwork2Tp() != null) {
412 createdOduInterfaces.add(
413 openRoadmInterfaceFactory.createOpenRoadmOtnOdu4LoInterface(node.getNodeId(),
414 node.getNetwork2Tp(), input.getServiceName(), PT_07, true, minOpucnTs,
417 new LinkTpBuilder().setNodeId(node.getNodeId()).setTpId(node.getNetworkTp()).build());
421 LOG.error("service rate {} not managed yet", input.getServiceRate());
425 // implement cross connect
426 List<String> createdConnections = new ArrayList<>();
427 if (!createdOduInterfaces.isEmpty()) {
428 Optional<String> connectionNameOpt = postCrossConnect(createdOduInterfaces, node);
429 createdConnections.add(connectionNameOpt.get());
430 LOG.info("Created cross connects");
432 nodeInterfaces.add(new NodeInterfaceBuilder()
433 .withKey(new NodeInterfaceKey(node.getNodeId()))
434 .setNodeId(node.getNodeId())
435 .setConnectionId(createdConnections)
436 .setEthInterfaceId(createdEthInterfaces)
437 .setOduInterfaceId(createdOduInterfaces)
442 private void createHighOrderInterfaces(OtnServicePathInput input, List<NodeInterface> nodeInterfaces,
443 CopyOnWriteArrayList<LinkTp> linkTpList) throws OpenRoadmInterfaceException {
444 for (Nodes node : input.nonnullNodes()) {
445 AEndApiInfo apiInfoA = null;
446 ZEndApiInfo apiInfoZ = null;
447 if (input.getAEndApiInfo() != null && input.getAEndApiInfo().getNodeId().contains(node.getNodeId())) {
448 apiInfoA = input.getAEndApiInfo();
450 if (input.getZEndApiInfo() != null && input.getZEndApiInfo().getNodeId().contains(node.getNodeId())) {
451 apiInfoZ = input.getZEndApiInfo();
453 // check if the node is mounted or not?
454 List<String> createdEthInterfaces = new ArrayList<>();
455 List<String> createdOduInterfaces = new ArrayList<>();
456 switch (input.getServiceRate().intValue()) {
458 LOG.info("Input service is 100G");
459 if (node.getClientTp() != null && node.getNetwork2Tp() == null) {
460 createdEthInterfaces.add(openRoadmInterfaceFactory.createOpenRoadmEth100GInterface(
461 node.getNodeId(), node.getClientTp()));
462 createdOduInterfaces.add(openRoadmInterfaceFactory.createOpenRoadmOdu4HOInterface(
463 node.getNodeId(), node.getClientTp(), false, apiInfoA, apiInfoZ, "21"));
464 // supporting interface? payload ?
465 createdOduInterfaces.add(openRoadmInterfaceFactory.createOpenRoadmOdu4HOInterface(
466 node.getNodeId(), node.getNetworkTp(), true, null, null, "21"));
467 linkTpList.add(new LinkTpBuilder().setNodeId(node.getNodeId()).setTpId(node.getClientTp())
470 if (node.getClientTp() == null && node.getNetwork2Tp() == null) {
471 createdOduInterfaces.add(openRoadmInterfaceFactory.createOpenRoadmOdu4HOInterface(
472 node.getNodeId(), node.getNetworkTp(), false, apiInfoA, apiInfoZ, "21"));
473 linkTpList.add(new LinkTpBuilder().setNodeId(node.getNodeId()).setTpId(node.getNetworkTp())
476 if (node.getClientTp() == null && node.getNetwork2Tp() != null) {
477 // supporting interface? payload ?
478 createdOduInterfaces.add(openRoadmInterfaceFactory.createOpenRoadmOdu4HOInterface(
479 node.getNodeId(), node.getNetworkTp(), true, null, null, "21"));
480 createdOduInterfaces.add(openRoadmInterfaceFactory.createOpenRoadmOdu4HOInterface(
481 node.getNodeId(), node.getNetwork2Tp(), true, null, null, "21"));
485 LOG.error("service rate {} not managed yet", input.getServiceRate());
489 // implement cross connect
490 List<String> createdConnections = new ArrayList<>();
491 if (createdOduInterfaces.size() == 2) {
492 Optional<String> connectionNameOpt = postCrossConnect(createdOduInterfaces, node);
493 createdConnections.add(connectionNameOpt.get());
494 LOG.info("Created cross connects");
496 nodeInterfaces.add(new NodeInterfaceBuilder()
497 .withKey(new NodeInterfaceKey(node.getNodeId()))
498 .setNodeId(node.getNodeId())
499 .setConnectionId(createdConnections)
500 .setEthInterfaceId(createdEthInterfaces)
501 .setOduInterfaceId(createdOduInterfaces)
506 private void createOduc4TtpInterface(OtnServicePathInput input, List<NodeInterface> nodeInterfaces,
507 CopyOnWriteArrayList<LinkTp> linkTpList) throws OpenRoadmInterfaceException {
508 if (input.getNodes() == null) {
511 LOG.info("Creation of ODUC4 TTP interface in OTN service path {}", input);
512 for (int i = 0; i < input.getNodes().size(); i++) {
513 Nodes node = input.getNodes().get(i);
514 String supportingOtuInterface = node.getNetworkTp() + "-OTUC4";
517 i + 1 == input.getNodes().size()
518 // For the end node, tgtNode becomes the first node in the list
519 ? input.getNodes().get(0)
520 : input.getNodes().get(i + 1);
522 nodeInterfaces.add(new NodeInterfaceBuilder()
523 .withKey(new NodeInterfaceKey(node.getNodeId()))
524 .setNodeId(node.getNodeId())
525 .setOduInterfaceId(List.of(
526 // though this is odu, actually it has ODUC4 interfaces
527 openRoadmInterfaceFactory.createOpenRoadmOtnOduc4Interface(node.getNodeId(),
528 node.getNetworkTp(), supportingOtuInterface, tgtNode.getNodeId(), tgtNode.getNetworkTp())))
530 linkTpList.add(new LinkTpBuilder().setNodeId(node.getNodeId()).setTpId(node.getNetworkTp()).build());