72cd2a3669bfffeb46cfc4fa0b2f3ab15b5a95d8
[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.HashMap;
12 import java.util.LinkedList;
13 import java.util.List;
14 import java.util.Map;
15 import java.util.Optional;
16 import java.util.concurrent.ConcurrentLinkedQueue;
17 import java.util.concurrent.CopyOnWriteArrayList;
18 import java.util.concurrent.ExecutionException;
19 import java.util.concurrent.ForkJoinPool;
20 import java.util.concurrent.ForkJoinTask;
21 import java.util.concurrent.atomic.AtomicBoolean;
22 import java.util.stream.Collectors;
23 import org.opendaylight.transportpce.common.crossconnect.CrossConnect;
24 import org.opendaylight.transportpce.common.device.DeviceTransactionManager;
25 import org.opendaylight.transportpce.common.openroadminterfaces.OpenRoadmInterfaceException;
26 import org.opendaylight.transportpce.common.openroadminterfaces.OpenRoadmInterfaces;
27 import org.opendaylight.transportpce.networkmodel.service.NetworkModelService;
28 import org.opendaylight.transportpce.renderer.openroadminterface.OpenRoadmInterfaceFactory;
29 import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.device.renderer.rev200128.OtnServicePathInput;
30 import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.device.renderer.rev200128.OtnServicePathOutput;
31 import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.device.renderer.rev200128.OtnServicePathOutputBuilder;
32 import org.opendaylight.yang.gen.v1.http.org.openroadm.otn.common.types.rev200327.OpucnTribSlotDef;
33 import org.opendaylight.yang.gen.v1.http.org.transportpce.common.types.rev201211.node.interfaces.NodeInterface;
34 import org.opendaylight.yang.gen.v1.http.org.transportpce.common.types.rev201211.node.interfaces.NodeInterfaceBuilder;
35 import org.opendaylight.yang.gen.v1.http.org.transportpce.common.types.rev201211.node.interfaces.NodeInterfaceKey;
36 import org.opendaylight.yang.gen.v1.http.org.transportpce.common.types.rev201211.otn.renderer.input.Nodes;
37 import org.opendaylight.yang.gen.v1.http.transportpce.topology.rev210511.OtnLinkType;
38 import org.slf4j.Logger;
39 import org.slf4j.LoggerFactory;
40
41
42 public class OtnDeviceRendererServiceImpl implements OtnDeviceRendererService {
43     private static final Logger LOG = LoggerFactory.getLogger(OtnDeviceRendererServiceImpl.class);
44     private static final String PT_03 = "03";
45     private static final String PT_07 = "07";
46     private final OpenRoadmInterfaceFactory openRoadmInterfaceFactory;
47     private final CrossConnect crossConnect;
48     private final OpenRoadmInterfaces openRoadmInterfaces;
49     private final DeviceTransactionManager deviceTransactionManager;
50     private final NetworkModelService networkModelService;
51
52     public OtnDeviceRendererServiceImpl(OpenRoadmInterfaceFactory openRoadmInterfaceFactory, CrossConnect crossConnect,
53                                         OpenRoadmInterfaces openRoadmInterfaces,
54                                         DeviceTransactionManager deviceTransactionManager,
55                                         NetworkModelService networkModelService) {
56         this.openRoadmInterfaceFactory = openRoadmInterfaceFactory;
57         this.crossConnect = crossConnect;
58         this.openRoadmInterfaces = openRoadmInterfaces;
59         this.deviceTransactionManager = deviceTransactionManager;
60         this.networkModelService = networkModelService;
61     }
62
63     @Override
64     public OtnServicePathOutput setupOtnServicePath(OtnServicePathInput input) {
65         LOG.info("Calling setup otn-service path");
66         boolean success = true;
67         List<NodeInterface> nodeInterfaces = new ArrayList<>();
68         List<String> results = new ArrayList<>();
69         if (input.getServiceType() == null || input.getServiceRate() == null) {
70             OtnServicePathOutputBuilder otnServicePathOutputBuilder = new OtnServicePathOutputBuilder()
71                 .setSuccess(false)
72                 .setResult("Error - service-type and service-rate must be presents");
73             return otnServicePathOutputBuilder.build();
74         }
75         CopyOnWriteArrayList<Nodes> otnNodesProvisioned = new CopyOnWriteArrayList<>();
76         switch (input.getServiceType()) {
77             case "Ethernet":
78                 if ("10G".equals(input.getServiceRate()) || "1G".equals(input.getServiceRate())) {
79                     try {
80                         LOG.info("Calling Node interfaces {} {} {} {} {} {} {}",
81                             input.getServiceRate(), input.getEthernetEncoding(),
82                             input.getServiceType(), input.getOperation(), input.getTribPortNumber(),
83                             input.getTribSlot(), input.getNodes());
84                         nodeInterfaces = createInterface(input);
85                         LOG.info("Node interfaces created just fine ");
86
87                         List<String> nodesToUpdate = updateOduNodes(nodeInterfaces, "ODU");
88                         updateOtnTopology(null, nodesToUpdate, input.getServiceRate(), input.getTribPortNumber(),
89                             input.getTribSlot(), false);
90                     } catch (OpenRoadmInterfaceException e) {
91                         LOG.warn("Set up service path failed", e);
92                         success = false;
93                     }
94                 } else if ("100G".equals(input.getServiceRate())) {
95                     try {
96                         LOG.info("Calling Node interfaces {} {} {} {} {} {}",
97                             input.getServiceRate(), input.getEthernetEncoding(),
98                             input.getServiceType(), input.getOperation(), input.getOpucnTribSlots(), input.getNodes());
99                         nodeInterfaces = createInterface(input);
100                         LOG.info("Node interfaces created just fine for 100G OTN ");
101                         // TODO: Update the OTN topology accordingly with Opucn-Trib-slots
102                         // List<String> nodesToUpdate = updateOduNodes(nodeInterfaces, "ODUC4");
103                         // updateOtnTopology(null, nodesToUpdate, input.getServiceRate(), input.getTribPortNumber(),
104                         //    input.getTribSlot(), false);
105                     } catch (OpenRoadmInterfaceException e) {
106                         LOG.warn("Set up service path failed", e);
107                         success = false;
108                     }
109                 } else {
110                     LOG.warn("Unsupported service-rate for service-type Ethernet");
111                 }
112                 break;
113             case "ODU":
114                 if ("100G".equals(input.getServiceRate())) {
115                     try {
116                         createODU4TtpInterface(input, nodeInterfaces, otnNodesProvisioned);
117                         updateOtnTopology(otnNodesProvisioned, null, null, null, null, false);
118                     } catch (OpenRoadmInterfaceException e) {
119                         LOG.warn("Set up service path failed", e);
120                         success = false;
121                     }
122                 } else if ("400G".equals(input.getServiceRate())) {
123                     try {
124                         createOduc4TtpInterface(input, nodeInterfaces, otnNodesProvisioned);
125                         updateOtnTopology(otnNodesProvisioned, null, null, null, null, false);
126                     } catch (OpenRoadmInterfaceException e) {
127                         LOG.warn("Set up service path failed", e);
128                         success = false;
129                     }
130                 } else {
131                     LOG.warn("Unsupported service-rate for service-type ODU");
132                 }
133                 break;
134             default:
135                 LOG.error("service-type {} not managed yet", input.getServiceType());
136                 break;
137         }
138         if (success) {
139             LOG.info("Result is success");
140             for (NodeInterface nodeInterface : nodeInterfaces) {
141                 results.add("Otn Service path was set up successfully for node :" + nodeInterface.getNodeId());
142             }
143         }
144         Map<NodeInterfaceKey,NodeInterface> nodeInterfacesMap = new HashMap<>();
145         for (NodeInterface nodeInterface : nodeInterfaces) {
146             if (nodeInterface != null) {
147                 nodeInterfacesMap.put(nodeInterface.key(), nodeInterface);
148             }
149         }
150         OtnServicePathOutputBuilder otnServicePathOutputBuilder = new OtnServicePathOutputBuilder()
151                 .setSuccess(success)
152                 .setNodeInterface(nodeInterfacesMap)
153                 .setResult(String.join("\n", results));
154         return otnServicePathOutputBuilder.build();
155     }
156
157     public OtnServicePathOutput deleteOtnServicePath(OtnServicePathInput input) {
158         if (input == null) {
159             LOG.error("Unable to delete otn service path. input = null");
160             return new OtnServicePathOutputBuilder().setResult("Unable to delete otn service path. input = null")
161                 .setSuccess(false).build();
162         }
163         List<Nodes> nodes = input.getNodes();
164         AtomicBoolean success = new AtomicBoolean(true);
165         ConcurrentLinkedQueue<String> results = new ConcurrentLinkedQueue<>();
166         List<String> nodesTpToUpdate = new ArrayList<>();
167         CopyOnWriteArrayList<Nodes> otnNodesProvisioned = new CopyOnWriteArrayList<>();
168         ForkJoinPool forkJoinPool = new ForkJoinPool();
169         ForkJoinTask forkJoinTask = forkJoinPool.submit(() -> nodes.parallelStream().forEach(node -> {
170             List<String> interfacesToDelete = new LinkedList<>();
171             String nodeId = node.getNodeId();
172             LOG.info("Deleting service setup on node {}", nodeId);
173             String networkTp = node.getNetworkTp();
174             if (networkTp == null || input.getServiceRate() == null || input.getServiceType() == null) {
175                 LOG.error("destination ({}) or service rate ({}) or service type ({}) is null.", networkTp,
176                     input.getServiceRate(), input.getServiceType());
177                 return;
178             }
179             // if the node is currently mounted then proceed.
180             if (this.deviceTransactionManager.isDeviceMounted(nodeId)) {
181                 String connectionNumber = "";
182                 switch (input.getServiceRate()) {
183                     case ("100G"):
184                         if ("ODU".equals(input.getServiceType())) {
185                             interfacesToDelete.add(networkTp + "-ODU4");
186                             otnNodesProvisioned.add(node);
187                             if (node.getNetwork2Tp() != null) {
188                                 interfacesToDelete.add(node.getNetwork2Tp() + "-ODU4");
189                             }
190                         } else if ("Ethernet".equals(input.getServiceType())) {
191                             connectionNumber = getConnectionNumber(input.getServiceName(), node, networkTp, "ODU4");
192                         }
193                         break;
194                     case ("400G"):
195                         LOG.info("Service Rate is 400G");
196                         if ("ODU".equals(input.getServiceType())) {
197                             interfacesToDelete.add(networkTp + "-ODUC4");
198                             otnNodesProvisioned.add(node);
199                             if (node.getNetwork2Tp() != null) {
200                                 interfacesToDelete.add(node.getNetwork2Tp() + "-ODUC4");
201                             }
202                         }
203                         break;
204                     case ("10G"):
205                         connectionNumber = getConnectionNumber(input.getServiceName(), node, networkTp, "ODU2e");
206                         break;
207                     case ("1G"):
208                         connectionNumber = getConnectionNumber(input.getServiceName(), node, networkTp, "ODU0");
209                         break;
210                     default:
211                         LOG.error("service rate {} not managed yet", input.getServiceRate());
212                         String result = input.getServiceRate() + " is not supported";
213                         results.add(result);
214                         success.set(false);
215                         return;
216                 }
217                 List<String> intToDelete = this.crossConnect.deleteCrossConnect(nodeId, connectionNumber, true);
218                 if (intToDelete != null) {
219                     for (String interf : intToDelete) {
220                         if (!this.openRoadmInterfaceFactory.isUsedByOtnXc(nodeId, interf, connectionNumber,
221                             this.deviceTransactionManager)) {
222
223                             interfacesToDelete.add(interf);
224                             String supportedInterface = this.openRoadmInterfaces.getSupportedInterface(nodeId, interf);
225                             if (input.getServiceRate().equals("100G")) {
226                                 if (!supportedInterface.contains("ODUC4")) {
227                                     interfacesToDelete.add(supportedInterface);
228                                 }
229                             } else {
230                                 if (!supportedInterface.contains("ODU4")) {
231                                     interfacesToDelete.add(supportedInterface);
232                                 }
233                             }
234                         }
235                     }
236                 }
237             } else {
238                 String result = nodeId + " is not mounted on the controller";
239                 results.add(result);
240                 success.set(false);
241                 LOG.warn(result);
242                 forkJoinPool.shutdown();
243                 return;
244                 // TODO should deletion end here?
245             }
246             for (String interfaceId : interfacesToDelete) {
247                 try {
248                     this.openRoadmInterfaces.deleteInterface(nodeId, interfaceId);
249                 } catch (OpenRoadmInterfaceException e) {
250                     String result = String.format("Failed to delete interface %s on node %s!", interfaceId, nodeId);
251                     success.set(false);
252                     LOG.error(result, e);
253                     results.add(result);
254                 }
255             }
256             List<String> interList = interfacesToDelete.stream().filter(ele -> ele.contains("NETWORK"))
257                 .collect(Collectors.toList());
258             if (!interList.isEmpty()) {
259                 for (String inter : interList) {
260                     String tp = inter.split("-ODU")[0];
261                     String nodeTopo = nodeId + "-" + tp.split("-")[0];
262                     nodesTpToUpdate.add(nodeTopo + "--" + tp);
263                 }
264             }
265         }));
266         try {
267             forkJoinTask.get();
268         } catch (InterruptedException | ExecutionException e) {
269             LOG.error("Error while deleting service paths!", e);
270         }
271         forkJoinPool.shutdown();
272         LOG.info("requesting otn-topology update...");
273         if (!nodesTpToUpdate.isEmpty() && !"ODU".equals(input.getServiceType())) {
274             updateOtnTopology(null, nodesTpToUpdate, input.getServiceRate(), input.getTribPortNumber(),
275                 input.getTribSlot(), true);
276         } else if (!otnNodesProvisioned.isEmpty()) {
277             updateOtnTopology(otnNodesProvisioned, null, null, null, null, true);
278         }
279
280         OtnServicePathOutputBuilder delServBldr = new OtnServicePathOutputBuilder();
281         delServBldr.setSuccess(success.get());
282         if (results.isEmpty()) {
283             return delServBldr.setResult("Request processed").build();
284         } else {
285             return delServBldr.setResult(String.join("\n", results)).build();
286         }
287     }
288
289     private String getConnectionNumber(String serviceName, Nodes node, String networkTp, String oduType) {
290         if (node.getClientTp() != null) {
291             return String.join("-", node.getClientTp(), oduType, serviceName, "x", networkTp, oduType, serviceName);
292         } else if (node.getNetwork2Tp() != null) {
293             return String.join("-", networkTp, oduType, serviceName, "x", node.getNetwork2Tp(), oduType, serviceName);
294         } else {
295             return "";
296         }
297     }
298
299     private List<String> updateOduNodes(List<NodeInterface> nodeInterfaceList, String deLimiter) {
300         List<String> nodesToUpdate = new ArrayList<>();
301         if (!(deLimiter.equals("ODU")) || !(deLimiter.equals("ODUC4"))) {
302             LOG.error("ODU node list update will be incorrect");
303         }
304
305         if (!nodeInterfaceList.isEmpty()) {
306             for (NodeInterface nodeInterf : nodeInterfaceList) {
307                 if (nodeInterf.getOduInterfaceId() != null) {
308                     List<String> interList = nodeInterf.getOduInterfaceId().stream()
309                         .filter(id -> id.contains("NETWORK")).collect(Collectors.toList());
310                     if (!interList.isEmpty()) {
311                         for (String inter : interList) {
312                             String tp = inter.split("-" + deLimiter)[0];
313                             String nodeTopo = nodeInterf.getNodeId() + "-" + tp.split("-")[0];
314                             nodesToUpdate.add(nodeTopo + "--" + tp);
315                         }
316                     }
317                 }
318             }
319         }
320
321         return nodesToUpdate;
322     }
323
324     private List<NodeInterface> createInterface(OtnServicePathInput input) throws OpenRoadmInterfaceException {
325         List<NodeInterface> nodeInterfaces = new ArrayList<>();
326         LOG.info("Calling Create Interface entry for OTN service path");
327         if (input.getServiceRate() == null
328             || !("1G".equals(input.getServiceRate()) || "10G".equals(input.getServiceRate())
329                 || "100G".equals(input.getServiceRate()))) {
330             LOG.error("Service rate {} not managed yet", input.getServiceRate());
331         } else {
332             createLowOrderInterfaces(input, nodeInterfaces);
333         }
334         return nodeInterfaces;
335     }
336
337     private Optional<String> postCrossConnect(List<String> createdOduInterfaces, Nodes node)
338             throws OpenRoadmInterfaceException {
339         return this.crossConnect.postOtnCrossConnect(createdOduInterfaces, node);
340     }
341
342     private void createLowOrderInterfaces(OtnServicePathInput input, List<NodeInterface> nodeInterfaces)
343         throws OpenRoadmInterfaceException {
344         for (Nodes node : input.getNodes()) {
345             // check if the node is mounted or not?
346             List<String> createdEthInterfaces = new ArrayList<>();
347             List<String> createdOduInterfaces = new ArrayList<>();
348             switch (input.getServiceRate()) {
349                 case ("1G"):
350                     LOG.info("Input service is 1G");
351                     if (node.getClientTp() != null) {
352                         createdEthInterfaces.add(
353                             openRoadmInterfaceFactory.createOpenRoadmEth1GInterface(node.getNodeId(),
354                                 node.getClientTp()));
355                         createdOduInterfaces.add(
356                             // suppporting interface?, payload ?
357                             openRoadmInterfaceFactory.createOpenRoadmOdu0Interface(node.getNodeId(), node.getClientTp(),
358                                 input.getServiceName(), PT_07, false, input.getTribPortNumber(), input.getTribSlot()));
359                     }
360                     createdOduInterfaces.add(
361                         openRoadmInterfaceFactory.createOpenRoadmOdu0Interface(node.getNodeId(), node.getNetworkTp(),
362                             input.getServiceName(), PT_07, true, input.getTribPortNumber(), input.getTribSlot()));
363                     if (node.getNetwork2Tp() != null) {
364                         createdOduInterfaces.add(
365                             // supporting interface? payload ?
366                             openRoadmInterfaceFactory.createOpenRoadmOdu0Interface(node.getNodeId(),
367                                 node.getNetwork2Tp(), input.getServiceName(), PT_07, true, input.getTribPortNumber(),
368                                 input.getTribSlot()));
369                     }
370                     break;
371                 case ("10G"):
372                     LOG.info("Input service is 10G");
373                     if (node.getClientTp() != null) {
374                         createdEthInterfaces.add(openRoadmInterfaceFactory.createOpenRoadmEth10GInterface(
375                             node.getNodeId(), node.getClientTp()));
376                         createdOduInterfaces.add(
377                             // suppporting interface?, payload ?
378                             openRoadmInterfaceFactory.createOpenRoadmOdu2eInterface(node.getNodeId(),
379                                 node.getClientTp(), input.getServiceName(), PT_03, false, input.getTribPortNumber(),
380                                 input.getTribSlot()));
381                     }
382                     createdOduInterfaces.add(
383                         // supporting interface? payload ?
384                         openRoadmInterfaceFactory.createOpenRoadmOdu2eInterface(node.getNodeId(), node.getNetworkTp(),
385                             input.getServiceName(), PT_03, true, input.getTribPortNumber(), input.getTribSlot()));
386                     if (node.getNetwork2Tp() != null) {
387                         createdOduInterfaces.add(
388                             // supporting interface? payload ?
389                             openRoadmInterfaceFactory.createOpenRoadmOdu2eInterface(node.getNodeId(),
390                                 node.getNetwork2Tp(), input.getServiceName(), PT_03, true, input.getTribPortNumber(),
391                                 input.getTribSlot()));
392                     }
393                     break;
394                 case ("100G"):
395                     LOG.info("Input service is 100G");
396                     // Take the first and last value in the list of OpucnTribSlot (assuming SH would provide
397                     // min and max value only, size two)
398                     OpucnTribSlotDef minOpucnTs = OpucnTribSlotDef.getDefaultInstance(
399                         input.getOpucnTribSlots().get(0).getValue());
400                     OpucnTribSlotDef maxOpucnTs = OpucnTribSlotDef.getDefaultInstance(
401                         input.getOpucnTribSlots().get(1).getValue());
402                     if (node.getClientTp() != null) {
403                         createdEthInterfaces.add(openRoadmInterfaceFactory.createOpenRoadmEth100GInterface(
404                             node.getNodeId(), node.getClientTp()));
405                         // OPUCn trib information is optional when creating ODU4 ethernet (client) interface
406                         createdOduInterfaces.add(
407                             openRoadmInterfaceFactory.createOpenRoadmOtnOdu4LoInterface(node.getNodeId(),
408                             node.getClientTp(), input.getServiceName(), PT_07, false, minOpucnTs,
409                                 maxOpucnTs));
410                     }
411                     // Here payload-type is optional and is not used for interface creation (especially for network)
412                     createdOduInterfaces.add(
413                         openRoadmInterfaceFactory.createOpenRoadmOtnOdu4LoInterface(node.getNodeId(),
414                             node.getNetworkTp(), input.getServiceName(), PT_07, true, minOpucnTs,
415                             maxOpucnTs));
416                     // Here payload-type is optional and is not used for service creation
417                     // This is needed if there is an intermediate node
418                     if (node.getNetwork2Tp() != null) {
419                         createdOduInterfaces.add(
420                             openRoadmInterfaceFactory.createOpenRoadmOtnOdu4LoInterface(node.getNodeId(),
421                                 node.getNetwork2Tp(), input.getServiceName(), PT_07, true, minOpucnTs,
422                                 maxOpucnTs));
423                     }
424                     break;
425                 default:
426                     LOG.error("service rate {} not managed yet", input.getServiceRate());
427                     return;
428             }
429
430             // implement cross connect
431             List<String> createdConnections = new ArrayList<>();
432             if (!createdOduInterfaces.isEmpty()) {
433                 Optional<String> connectionNameOpt = postCrossConnect(createdOduInterfaces, node);
434                 createdConnections.add(connectionNameOpt.get());
435                 LOG.info("Created cross connects");
436             }
437             NodeInterfaceBuilder nodeInterfaceBuilder = new NodeInterfaceBuilder()
438                 .withKey(new NodeInterfaceKey(node.getNodeId()))
439                 .setNodeId(node.getNodeId())
440                 .setConnectionId(createdConnections)
441                 .setEthInterfaceId(createdEthInterfaces)
442                 .setOduInterfaceId(createdOduInterfaces);
443             nodeInterfaces.add(nodeInterfaceBuilder.build());
444         }
445     }
446
447     private void createOduc4TtpInterface(OtnServicePathInput input, List<NodeInterface> nodeInterfaces,
448         CopyOnWriteArrayList<Nodes> otnNodesProvisioned) throws OpenRoadmInterfaceException {
449         if (input.getNodes() == null) {
450             return;
451         }
452         LOG.info("Creation of ODUC4 TTP interface in OTN service path {}", input);
453         for (int i = 0; i < input.getNodes().size(); i++) {
454             Nodes node = input.getNodes().get(i);
455             String supportingOtuInterface = node.getNetworkTp() + "-OTUC4";
456             List<String> createdOduc4Interfaces = new ArrayList<>();
457             // Adding SAPI/DAPI information to the
458             Nodes tgtNode = null;
459             if (i + 1 == input.getNodes().size()) {
460                 // For the end node, tgtNode becomes the first node in the list
461                 tgtNode = input.getNodes().get(0);
462             } else {
463                 tgtNode = input.getNodes().get(i + 1);
464             }
465             createdOduc4Interfaces.add(openRoadmInterfaceFactory.createOpenRoadmOtnOduc4Interface(node.getNodeId(),
466                 node.getNetworkTp(), supportingOtuInterface, tgtNode.getNodeId(), tgtNode.getNetworkTp()));
467
468             NodeInterfaceBuilder nodeInterfaceBuilder = new NodeInterfaceBuilder()
469                 .withKey(new NodeInterfaceKey(node.getNodeId()))
470                 .setNodeId(node.getNodeId())
471                 .setOduInterfaceId(createdOduc4Interfaces); // though this is odu, actually it has ODUC4 interfaces
472             nodeInterfaces.add(nodeInterfaceBuilder.build());
473             otnNodesProvisioned.add(node);
474         }
475     }
476
477     private void createODU4TtpInterface(OtnServicePathInput input, List<NodeInterface> nodeInterfaces,
478         CopyOnWriteArrayList<Nodes> otnNodesProvisioned) throws OpenRoadmInterfaceException {
479         if (input.getNodes() == null) {
480             return;
481         }
482         LOG.info("Creation of ODU4 tp interface {}", input);
483         for (int i = 0; i < input.getNodes().size(); i++) {
484             Nodes node = input.getNodes().get(i);
485             String supportingOtuInterface = node.getNetworkTp() + "-OTU";
486             List<String> createdOdu4Interfaces = new ArrayList<>();
487             // Adding SAPI/DAPI information to the
488             Nodes tgtNode = null;
489             if (i + 1 == input.getNodes().size()) {
490                 // For the end node, tgtNode becomes the first node in the list
491                 tgtNode = input.getNodes().get(0);
492             } else {
493                 tgtNode = input.getNodes().get(i + 1);
494             }
495             createdOdu4Interfaces.add(openRoadmInterfaceFactory.createOpenRoadmOtnOdu4Interface(node.getNodeId(),
496                 node.getNetworkTp(), supportingOtuInterface, tgtNode.getNodeId(), tgtNode.getNetworkTp()));
497             NodeInterfaceBuilder nodeInterfaceBuilder = new NodeInterfaceBuilder()
498                 .withKey(new NodeInterfaceKey(node.getNodeId()))
499                 .setNodeId(node.getNodeId())
500                 .setOduInterfaceId(createdOdu4Interfaces);
501             nodeInterfaces.add(nodeInterfaceBuilder.build());
502             otnNodesProvisioned.add(node);
503         }
504     }
505
506     private void updateOtnTopology(CopyOnWriteArrayList<Nodes> nodes, List<String> nodesTps, String serviceRate,
507         Short tribPortNb, Short tribSlotNb, boolean isDeletion) {
508         if (nodes != null && nodes.size() == 2) {
509             if (isDeletion) {
510                 LOG.info("updating otn-topology removing ODU4 links");
511                 this.networkModelService.deleteOtnLinks(nodes.get(0).getNodeId(), nodes.get(0).getNetworkTp(),
512                     nodes.get(1).getNodeId(), nodes.get(1).getNetworkTp(), OtnLinkType.ODTU4);
513             } else {
514                 LOG.info("updating otn-topology adding ODU4 links");
515                 this.networkModelService.createOtnLinks(nodes.get(0).getNodeId(), nodes.get(0).getNetworkTp(),
516                     nodes.get(1).getNodeId(), nodes.get(1).getNetworkTp(), OtnLinkType.ODTU4);
517             }
518         } else if (nodesTps != null && (nodesTps.size() % 2 == 0) && serviceRate != null && tribPortNb != null
519             && tribSlotNb != null) {
520             LOG.info("updating otn-topology node tps -tps and tpn pools");
521             this.networkModelService.updateOtnLinks(nodesTps, serviceRate, tribPortNb, tribSlotNb, isDeletion);
522         }
523     }
524
525 }