Align OTN renderer on OTN PCE and update otn-topo 54/89354/1
authorGilles Thouenon <gilles.thouenon@orange.com>
Thu, 2 Apr 2020 11:46:57 +0000 (13:46 +0200)
committerChristophe Betoule <christophe.betoule@orange.com>
Fri, 24 Apr 2020 12:49:59 +0000 (14:49 +0200)
- add dependency towards network module to request NetworkModelService
methods
- service-path rpc allows creation/deletion of OCH and OTU4 interfaces
and updates otn-topology with OTU4 links
- otn-service-path rpc allows creation/deletion of ODU4 interfaces,
structured for otn low order service, and creation/deletion of otn low
order services. Moreover, it creates/updates/deletes consequently otn
links and ODU4 termination points in otn-topology (bandwidth
parameters, tributary slot and tributary port availabilities...)
- adapt otn-renderer functional tests to take into account new behavior

JIRA: TRNSPRTPCE-218
Signed-off-by: Gilles Thouenon <gilles.thouenon@orange.com>
Change-Id: I85020faf75fa53be1f965becccdf2787f6c743bb

renderer/pom.xml
renderer/src/main/java/org/opendaylight/transportpce/renderer/provisiondevice/DeviceRendererServiceImpl.java
renderer/src/main/java/org/opendaylight/transportpce/renderer/provisiondevice/OtnDeviceRendererServiceImpl.java
renderer/src/main/resources/OSGI-INF/blueprint/renderer-blueprint.xml
renderer/src/test/java/org/opendaylight/transportpce/renderer/provisiondevice/DeviceRendererServiceImplCreateOtsOmsTest.java
renderer/src/test/java/org/opendaylight/transportpce/renderer/provisiondevice/RendererServiceOperationsImplDeleteTest.java
renderer/src/test/java/org/opendaylight/transportpce/renderer/provisiondevice/RendererServiceOperationsImplTest.java
tests/transportpce_tests/2.2.1/test_otn_renderer.py

index b4838f218f568e41cfff408bff40e5b3a45c6ba2..60eb255d00e91210d751920228f8ab0c9227350d 100644 (file)
@@ -28,6 +28,11 @@ and is available at http://www.eclipse.org/legal/epl-v10.html
       <artifactId>transportpce-common</artifactId>
       <version>${project.version}</version>
     </dependency>
+    <dependency>
+      <groupId>${project.groupId}</groupId>
+      <artifactId>transportpce-networkmodel</artifactId>
+      <version>${project.version}</version>
+    </dependency>
 
     <!-- Testing Dependencies -->
     <dependency>
index bbac76c267403e688e5d8d8db68edcf1e344cd5b..b2c6edc01a6d69beb23bb89c56a96e609ef26132 100644 (file)
@@ -16,6 +16,7 @@ import java.util.List;
 import java.util.Optional;
 import java.util.Set;
 import java.util.concurrent.ConcurrentLinkedQueue;
+import java.util.concurrent.CopyOnWriteArrayList;
 import java.util.concurrent.ExecutionException;
 import java.util.concurrent.ForkJoinPool;
 import java.util.concurrent.ForkJoinTask;
@@ -37,6 +38,7 @@ import org.opendaylight.transportpce.common.device.DeviceTransactionManager;
 import org.opendaylight.transportpce.common.mapping.PortMapping;
 import org.opendaylight.transportpce.common.openroadminterfaces.OpenRoadmInterfaceException;
 import org.opendaylight.transportpce.common.openroadminterfaces.OpenRoadmInterfaces;
+import org.opendaylight.transportpce.networkmodel.service.NetworkModelService;
 import org.opendaylight.transportpce.renderer.openroadminterface.OpenRoadmInterfaceFactory;
 import org.opendaylight.transportpce.renderer.provisiondevice.servicepath.ServiceListTopology;
 import org.opendaylight.transportpce.renderer.provisiondevice.servicepath.ServicePathDirection;
@@ -66,12 +68,12 @@ import org.opendaylight.yang.gen.v1.http.org.transportpce.common.types.rev200128
 import org.opendaylight.yang.gen.v1.http.org.transportpce.common.types.rev200128.node.interfaces.NodeInterfaceBuilder;
 import org.opendaylight.yang.gen.v1.http.org.transportpce.common.types.rev200128.node.interfaces.NodeInterfaceKey;
 import org.opendaylight.yang.gen.v1.http.org.transportpce.common.types.rev200128.olm.renderer.input.Nodes;
+import org.opendaylight.yang.gen.v1.http.transportpce.topology.rev200129.OtnLinkType;
 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
 
-
 public class DeviceRendererServiceImpl implements DeviceRendererService {
     private static final String ODU4 = "-ODU4";
     private static final Logger LOG = LoggerFactory.getLogger(DeviceRendererServiceImpl.class);
@@ -81,16 +83,18 @@ public class DeviceRendererServiceImpl implements DeviceRendererService {
     private final OpenRoadmInterfaces openRoadmInterfaces;
     private final CrossConnect crossConnect;
     private final PortMapping portMapping;
+    private final NetworkModelService networkModelService;
 
     public DeviceRendererServiceImpl(DataBroker dataBroker, DeviceTransactionManager deviceTransactionManager,
             OpenRoadmInterfaceFactory openRoadmInterfaceFactory, OpenRoadmInterfaces openRoadmInterfaces,
-            CrossConnect crossConnect, PortMapping portMapping) {
+            CrossConnect crossConnect, PortMapping portMapping, NetworkModelService networkModelService) {
         this.dataBroker = dataBroker;
         this.deviceTransactionManager = deviceTransactionManager;
         this.openRoadmInterfaceFactory = openRoadmInterfaceFactory;
         this.openRoadmInterfaces = openRoadmInterfaces;
         this.crossConnect = crossConnect;
         this.portMapping = portMapping;
+        this.networkModelService = networkModelService;
     }
 
     @Override
@@ -103,6 +107,7 @@ public class DeviceRendererServiceImpl implements DeviceRendererService {
         ConcurrentLinkedQueue<String> results = new ConcurrentLinkedQueue<>();
         Set<NodeInterface> nodeInterfaces = Sets.newConcurrentHashSet();
         Set<String> nodesProvisioned = Sets.newConcurrentHashSet();
+        CopyOnWriteArrayList<Nodes> otnNodesProvisioned = new CopyOnWriteArrayList<>();
         ServiceListTopology topology = new ServiceListTopology();
         AtomicBoolean success = new AtomicBoolean(true);
         ForkJoinPool forkJoinPool = new ForkJoinPool();
@@ -123,18 +128,14 @@ public class DeviceRendererServiceImpl implements DeviceRendererService {
                     Long waveNumber = input.getWaveNumber().toJava();
                     if ((destTp != null) && destTp.contains(StringConstants.NETWORK_TOKEN)) {
                         crossConnectFlag++;
-                        Mapping mapping = this.portMapping.getMapping(nodeId,destTp);
                         String supportingOchInterface = this.openRoadmInterfaceFactory.createOpenRoadmOchInterface(
                                 nodeId, destTp, waveNumber, ModulationFormat.DpQpsk);
                         createdOchInterfaces.add(supportingOchInterface);
                         String supportingOtuInterface = this.openRoadmInterfaceFactory
                                 .createOpenRoadmOtu4Interface(nodeId, destTp, supportingOchInterface);
                         createdOtuInterfaces.add(supportingOtuInterface);
-                        if (mapping != null && mapping.getXponderType() != null
-                            && (mapping.getXponderType().getIntValue() == 3
-                            || mapping.getXponderType().getIntValue() == 2)) {
-                            createdOduInterfaces.add(this.openRoadmInterfaceFactory
-                                .createOpenRoadmOtnOdu4Interface(nodeId,destTp, supportingOtuInterface));
+                        if (srcTp == null) {
+                            otnNodesProvisioned.add(node);
                         } else {
                             createdOduInterfaces.add(this.openRoadmInterfaceFactory.createOpenRoadmOdu4Interface(nodeId,
                                     destTp, supportingOtuInterface));
@@ -228,19 +229,20 @@ public class DeviceRendererServiceImpl implements DeviceRendererService {
         if (success.get()) {
             results.add("Roadm-connection successfully created for nodes: " + String.join(", ", nodesProvisioned));
         }
-        ServicePathOutputBuilder setServBldr = new ServicePathOutputBuilder()
-            .setNodeInterface(new ArrayList<>(nodeInterfaces))
-            .setSuccess(success.get())
-            .setResult(String.join("\n", results));
         // setting topology in the service list data store
         try {
             setTopologyForService(input.getServiceName(), topology.getTopology());
+            updateOtnTopology(otnNodesProvisioned, false);
         } catch (InterruptedException | TimeoutException | ExecutionException e) {
             LOG.warn("Failed to write topologies for service {}.", input.getServiceName(), e);
         }
         if (!alarmSuppressionNodeRemoval(input.getServiceName())) {
             LOG.error("Alarm suppresion node removal failed!!!!");
         }
+        ServicePathOutputBuilder setServBldr = new ServicePathOutputBuilder()
+            .setNodeInterface(new ArrayList<>(nodeInterfaces))
+            .setSuccess(success.get())
+            .setResult(String.join("\n", results));
         return setServBldr.build();
     }
 
@@ -260,6 +262,7 @@ public class DeviceRendererServiceImpl implements DeviceRendererService {
         if (!alarmSuppressionNodeRegistration(input)) {
             LOG.warn("Alarm suppresion node registraion failed!!!!");
         }
+        CopyOnWriteArrayList<Nodes> otnNodesProvisioned = new CopyOnWriteArrayList<>();
         ForkJoinPool forkJoinPool = new ForkJoinPool();
         ForkJoinTask forkJoinTask = forkJoinPool.submit(() -> nodes.parallelStream().forEach(node -> {
             List<String> interfacesToDelete = new LinkedList<>();
@@ -278,6 +281,7 @@ public class DeviceRendererServiceImpl implements DeviceRendererService {
                 srcTp = node.getSrcTp();
             } else {
                 srcTp = "";
+                otnNodesProvisioned.add(node);
             }
             // if the node is currently mounted then proceed.
             if (this.deviceTransactionManager.isDeviceMounted(nodeId)) {
@@ -308,6 +312,7 @@ public class DeviceRendererServiceImpl implements DeviceRendererService {
             LOG.error("Error while deleting service paths!", e);
         }
         forkJoinPool.shutdown();
+        updateOtnTopology(otnNodesProvisioned, true);
         if (!alarmSuppressionNodeRemoval(input.getServiceName())) {
             LOG.error("Alarm suppresion node removal failed!!!!");
         }
@@ -572,4 +577,20 @@ public class DeviceRendererServiceImpl implements DeviceRendererService {
         }
         return result;
     }
+
+    private void updateOtnTopology(CopyOnWriteArrayList<Nodes> nodes, boolean isDeletion) {
+        if (nodes.size() != 2) {
+            LOG.error("Error with OTU4 links to update in otn-topology");
+            return;
+        }
+        if (isDeletion) {
+            LOG.info("updating otn-topology removing OTU4 links");
+            this.networkModelService.deleteOtnLinks(nodes.get(0).getNodeId(), nodes.get(0).getDestTp(),
+                nodes.get(1).getNodeId(), nodes.get(1).getDestTp(), OtnLinkType.OTU4);
+        } else {
+            LOG.info("updating otn-topology adding OTU4 links");
+            this.networkModelService.createOtnLinks(nodes.get(0).getNodeId(), nodes.get(0).getDestTp(),
+                nodes.get(1).getNodeId(), nodes.get(1).getDestTp(), OtnLinkType.OTU4);
+        }
+    }
 }
index 191b1998a7540808c02083786908236426e964a3..1713764f941e450d0158323e48cf364cce121bfa 100644 (file)
@@ -12,15 +12,18 @@ import java.util.LinkedList;
 import java.util.List;
 import java.util.Optional;
 import java.util.concurrent.ConcurrentLinkedQueue;
+import java.util.concurrent.CopyOnWriteArrayList;
 import java.util.concurrent.ExecutionException;
 import java.util.concurrent.ForkJoinPool;
 import java.util.concurrent.ForkJoinTask;
 import java.util.concurrent.atomic.AtomicBoolean;
+import java.util.stream.Collectors;
 
 import org.opendaylight.transportpce.common.crossconnect.CrossConnect;
 import org.opendaylight.transportpce.common.device.DeviceTransactionManager;
 import org.opendaylight.transportpce.common.openroadminterfaces.OpenRoadmInterfaceException;
 import org.opendaylight.transportpce.common.openroadminterfaces.OpenRoadmInterfaces;
+import org.opendaylight.transportpce.networkmodel.service.NetworkModelService;
 import org.opendaylight.transportpce.renderer.openroadminterface.OpenRoadmInterfaceFactory;
 import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.renderer.device.rev200128.OtnServicePathInput;
 import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.renderer.device.rev200128.OtnServicePathOutput;
@@ -30,25 +33,30 @@ import org.opendaylight.yang.gen.v1.http.org.transportpce.common.types.rev200128
 import org.opendaylight.yang.gen.v1.http.org.transportpce.common.types.rev200128.node.interfaces.NodeInterfaceBuilder;
 import org.opendaylight.yang.gen.v1.http.org.transportpce.common.types.rev200128.node.interfaces.NodeInterfaceKey;
 import org.opendaylight.yang.gen.v1.http.org.transportpce.common.types.rev200128.otn.renderer.input.Nodes;
+import org.opendaylight.yang.gen.v1.http.transportpce.topology.rev200129.OtnLinkType;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
+
 public class OtnDeviceRendererServiceImpl implements OtnDeviceRendererService {
-    private static final String ODU2E = "-ODU2e-";
     private static final Logger LOG = LoggerFactory.getLogger(OtnDeviceRendererServiceImpl.class);
+    private static final String PT_03 = "03";
+    private static final String PT_07 = "07";
     private final OpenRoadmInterfaceFactory openRoadmInterfaceFactory;
     private final CrossConnect crossConnect;
     private final OpenRoadmInterfaces openRoadmInterfaces;
     private final DeviceTransactionManager deviceTransactionManager;
-
+    private final NetworkModelService networkModelService;
 
     public OtnDeviceRendererServiceImpl(OpenRoadmInterfaceFactory openRoadmInterfaceFactory, CrossConnect crossConnect,
                                         OpenRoadmInterfaces openRoadmInterfaces,
-                                        DeviceTransactionManager deviceTransactionManager) {
+                                        DeviceTransactionManager deviceTransactionManager,
+                                        NetworkModelService networkModelService) {
         this.openRoadmInterfaceFactory = openRoadmInterfaceFactory;
         this.crossConnect = crossConnect;
         this.openRoadmInterfaces = openRoadmInterfaces;
         this.deviceTransactionManager = deviceTransactionManager;
+        this.networkModelService = networkModelService;
     }
 
     @Override
@@ -57,28 +65,72 @@ public class OtnDeviceRendererServiceImpl implements OtnDeviceRendererService {
         boolean success = true;
         List<NodeInterface> nodeInterfaces = new ArrayList<>();
         List<String> results = new ArrayList<>();
-        if (input.getServiceType().equals("Ethernet")) {
-            try {
-                LOG.info("Calling Node interfaces {} {} {} {} {} {} {}",
-                        input.getServiceRate(),input.getEthernetEncoding(),
-                        input.getServiceType(),input.getOperation(),input.getTribPortNumber(),
-                        input.getTribSlot(),input.getNodes());
-                nodeInterfaces = createInterface(input);
-                LOG.info("Node interfaces created just fine ");
-            }
-            catch (OpenRoadmInterfaceException e) {
-                //handle exception
-                LOG.warn("Set up service path failed {}", e.toString());
-                success = false;
-            }
+        if (input.getServiceType() == null || input.getServiceRate() == null) {
+            OtnServicePathOutputBuilder otnServicePathOutputBuilder = new OtnServicePathOutputBuilder()
+                .setSuccess(false)
+                .setResult("Error - service-type and service-rate must be presents");
+            return otnServicePathOutputBuilder.build();
+        }
+        CopyOnWriteArrayList<Nodes> otnNodesProvisioned = new CopyOnWriteArrayList<>();
+        switch (input.getServiceType()) {
+            case "Ethernet":
+                if ("10G".equals(input.getServiceRate()) || "1G".equals(input.getServiceRate())) {
+                    try {
+                        LOG.info("Calling Node interfaces {} {} {} {} {} {} {}",
+                            input.getServiceRate(), input.getEthernetEncoding(),
+                            input.getServiceType(), input.getOperation(), input.getTribPortNumber(),
+                            input.getTribSlot(), input.getNodes());
+                        nodeInterfaces = createInterface(input);
+                        LOG.info("Node interfaces created just fine ");
 
+                        List<String> nodesToUpdate = new ArrayList<>();
+                        if (!nodeInterfaces.isEmpty()) {
+                            for (NodeInterface nodeInterf : nodeInterfaces) {
+                                if (nodeInterf.getOduInterfaceId() != null) {
+                                    List<String> interList = nodeInterf.getOduInterfaceId().stream()
+                                        .filter(id -> id.contains("NETWORK")).collect(Collectors.toList());
+                                    if (!interList.isEmpty()) {
+                                        for (String inter : interList) {
+                                            String tp = inter.split("-ODU")[0];
+                                            String nodeTopo = nodeInterf.getNodeId() + "-" + tp.split("-")[0];
+                                            nodesToUpdate.add(nodeTopo + "--" + tp);
+                                        }
+                                    }
+                                }
+                            }
+                        }
+                        updateOtnTopology(null, nodesToUpdate, input.getServiceRate(), input.getTribPortNumber(),
+                            input.getTribSlot(), false);
+                    } catch (OpenRoadmInterfaceException e) {
+                        LOG.warn("Set up service path failed", e);
+                        success = false;
+                    }
+                } else {
+                    LOG.warn("Unsupported serivce-rate for service-type Ethernet");
+                }
+                break;
+            case "ODU":
+                if ("100G".equals(input.getServiceRate())) {
+                    try {
+                        createODU4TtpInterface(input, nodeInterfaces, otnNodesProvisioned);
+                        updateOtnTopology(otnNodesProvisioned, null, null, null, null, false);
+                    } catch (OpenRoadmInterfaceException e) {
+                        LOG.warn("Set up service path failed", e);
+                        success = false;
+                    }
+                } else {
+                    LOG.warn("Unsupported serivce-rate for service-type ODU");
+                }
+                break;
+            default:
+                LOG.error("service-type {} not managet yet", input.getServiceType());
+                break;
         }
         if (success) {
             LOG.info("Result is success");
-            for (NodeInterface nodeInterface: nodeInterfaces) {
+            for (NodeInterface nodeInterface : nodeInterfaces) {
                 results.add("Otn Service path was set up successfully for node :" + nodeInterface.getNodeId());
             }
-            //TODO Add otn topology links
         }
         OtnServicePathOutputBuilder otnServicePathOutputBuilder = new OtnServicePathOutputBuilder()
                 .setSuccess(success)
@@ -87,33 +139,41 @@ public class OtnDeviceRendererServiceImpl implements OtnDeviceRendererService {
         return otnServicePathOutputBuilder.build();
     }
 
-    @Override
     public OtnServicePathOutput deleteOtnServicePath(OtnServicePathInput input) {
         List<Nodes> nodes = input.getNodes();
         AtomicBoolean success = new AtomicBoolean(true);
         ConcurrentLinkedQueue<String> results = new ConcurrentLinkedQueue<>();
+        List<String> nodesTpToUpdate = new ArrayList<>();
+        CopyOnWriteArrayList<Nodes> otnNodesProvisioned = new CopyOnWriteArrayList<>();
         ForkJoinPool forkJoinPool = new ForkJoinPool();
         ForkJoinTask forkJoinTask = forkJoinPool.submit(() -> nodes.parallelStream().forEach(node -> {
             List<String> interfacesToDelete = new LinkedList<>();
             String nodeId = node.getNodeId();
             LOG.info("Deleting service setup on node {}", nodeId);
-            String srcTp = node.getClientTp();
-            String destTp = node.getNetworkTp();
-            if ((srcTp == null) || (destTp == null) || input.getServiceRate() == null) {
-                LOG.error("Source ({}) or destination ({}) termination point is null.", srcTp, destTp);
+            String networkTp = node.getNetworkTp();
+            if (networkTp == null || input.getServiceRate() == null || input.getServiceType() == null) {
+                LOG.error("destination ({}) or service rate ({}) or service type ({}) is null.", networkTp,
+                    input.getServiceRate(), input.getServiceType());
                 return;
             }
             // if the node is currently mounted then proceed.
             if (this.deviceTransactionManager.isDeviceMounted(nodeId)) {
                 String connectionNumber = "";
                 switch (input.getServiceRate()) {
-                    case("10G"):
-                        connectionNumber = srcTp + ODU2E + input.getServiceName() + "-x-" + destTp
-                            + ODU2E + input.getServiceName();
+                    case ("100G"):
+                        if ("ODU".equals(input.getServiceType())) {
+                            interfacesToDelete.add(networkTp + "-ODU4");
+                            otnNodesProvisioned.add(node);
+                            if (node.getNetwork2Tp() != null) {
+                                interfacesToDelete.add(node.getNetwork2Tp() + "-ODU4");
+                            }
+                        }
+                        break;
+                    case ("10G"):
+                        connectionNumber = getConnectionNumber(input.getServiceName(), node, networkTp, "ODU2e");
                         break;
-                    case("1G"):
-                        connectionNumber = srcTp + "-ODU0-" + input.getServiceName() + "-x-" + destTp
-                            + ODU2E + input.getServiceName();
+                    case ("1G"):
+                        connectionNumber = getConnectionNumber(input.getServiceName(), node, networkTp, "ODU0");
                         break;
                     default:
                         LOG.error("service rate {} not managed yet", input.getServiceRate());
@@ -141,7 +201,7 @@ public class OtnDeviceRendererServiceImpl implements OtnDeviceRendererService {
                 LOG.warn(result);
                 forkJoinPool.shutdown();
                 return;
-                //TODO should deletion end here?
+                // TODO should deletion end here?
             }
             for (String interfaceId : interfacesToDelete) {
                 try {
@@ -153,6 +213,15 @@ public class OtnDeviceRendererServiceImpl implements OtnDeviceRendererService {
                     results.add(result);
                 }
             }
+            List<String> interList = interfacesToDelete.stream().filter(ele -> ele.contains("NETWORK"))
+                .collect(Collectors.toList());
+            if (!interList.isEmpty()) {
+                for (String inter : interList) {
+                    String tp = inter.split("-ODU")[0];
+                    String nodeTopo = nodeId + "-" + tp.split("-")[0];
+                    nodesTpToUpdate.add(nodeTopo + "--" + tp);
+                }
+            }
         }));
         try {
             forkJoinTask.get();
@@ -160,6 +229,14 @@ public class OtnDeviceRendererServiceImpl implements OtnDeviceRendererService {
             LOG.error("Error while deleting service paths!", e);
         }
         forkJoinPool.shutdown();
+        LOG.info("requesting otn-topology update...");
+        if (!nodesTpToUpdate.isEmpty() && !"ODU".equals(input.getServiceType())) {
+            updateOtnTopology(null, nodesTpToUpdate, input.getServiceRate(), input.getTribPortNumber(),
+                input.getTribSlot(), true);
+        } else if (!otnNodesProvisioned.isEmpty()) {
+            updateOtnTopology(otnNodesProvisioned, null, null, null, null, true);
+        }
+
         OtnServicePathOutputBuilder delServBldr = new OtnServicePathOutputBuilder();
         delServBldr.setSuccess(success.get());
         if (results.isEmpty()) {
@@ -167,7 +244,16 @@ public class OtnDeviceRendererServiceImpl implements OtnDeviceRendererService {
         } else {
             return delServBldr.setResult(String.join("\n", results)).build();
         }
+    }
 
+    private String getConnectionNumber(String serviceName, Nodes node, String networkTp, String oduType) {
+        if (node.getClientTp() != null) {
+            return String.join("-", node.getClientTp(), oduType, serviceName, "x", networkTp, oduType, serviceName);
+        } else if (node.getNetwork2Tp() != null) {
+            return String.join("-", networkTp, oduType, serviceName, "x", node.getNetwork2Tp(), oduType, serviceName);
+        } else {
+            return "";
+        }
     }
 
     private String getSupportedInterface(String nodeId, String interf) {
@@ -199,47 +285,67 @@ public class OtnDeviceRendererServiceImpl implements OtnDeviceRendererService {
 
     private Optional<String> postCrossConnect(List<String> createdOduInterfaces, Nodes node)
             throws OpenRoadmInterfaceException {
-        return this.crossConnect.postOtnCrossConnect(createdOduInterfaces,node);
+        return this.crossConnect.postOtnCrossConnect(createdOduInterfaces, node);
     }
 
     private void createLowOrderInterfaces(OtnServicePathInput input, List<NodeInterface> nodeInterfaces)
         throws OpenRoadmInterfaceException {
-        for (Nodes node: input.getNodes()) {
-            //check if the node is mounted or not?
+        for (Nodes node : input.getNodes()) {
+            // check if the node is mounted or not?
             List<String> createdEthInterfaces = new ArrayList<>();
             List<String> createdOduInterfaces = new ArrayList<>();
             switch (input.getServiceRate()) {
-                case("1G"):
+                case ("1G"):
                     LOG.info("Input service is 1G");
-                    createdEthInterfaces.add(
-                        openRoadmInterfaceFactory.createOpenRoadmEth1GInterface(node.getNodeId(), node.getClientTp()));
-                    createdOduInterfaces.add(
-                        //suppporting interface?, payload ?
-                        openRoadmInterfaceFactory.createOpenRoadmOdu0Interface(node.getNodeId(), node.getClientTp(),
-                            input.getServiceName(), "07", false, input.getTribPortNumber(), input.getTribSlot()));
+                    if (node.getClientTp() != null) {
+                        createdEthInterfaces.add(
+                            openRoadmInterfaceFactory.createOpenRoadmEth1GInterface(node.getNodeId(),
+                                node.getClientTp()));
+                        createdOduInterfaces.add(
+                            // suppporting interface?, payload ?
+                            openRoadmInterfaceFactory.createOpenRoadmOdu0Interface(node.getNodeId(), node.getClientTp(),
+                                input.getServiceName(), PT_07, false, input.getTribPortNumber(), input.getTribSlot()));
+                    }
                     createdOduInterfaces.add(
                         openRoadmInterfaceFactory.createOpenRoadmOdu0Interface(node.getNodeId(), node.getNetworkTp(),
-                            input.getServiceName(), "07", true, input.getTribPortNumber(), input.getTribSlot()));
+                            input.getServiceName(), PT_07, true, input.getTribPortNumber(), input.getTribSlot()));
+                    if (node.getNetwork2Tp() != null) {
+                        createdOduInterfaces.add(
+                            // supporting interface? payload ?
+                            openRoadmInterfaceFactory.createOpenRoadmOdu0Interface(node.getNodeId(),
+                                node.getNetwork2Tp(), input.getServiceName(), PT_07, true, input.getTribPortNumber(),
+                                input.getTribSlot()));
+                    }
                     break;
-                case("10G"):
+                case ("10G"):
                     LOG.info("Input service is 10G");
-                    createdEthInterfaces.add(
-                        openRoadmInterfaceFactory.createOpenRoadmEth10GInterface(node.getNodeId(), node.getClientTp()));
-                    createdOduInterfaces.add(
-                        //suppporting interface?, payload ?
-                        openRoadmInterfaceFactory.createOpenRoadmOdu2eInterface(node.getNodeId(), node.getClientTp(),
-                            input.getServiceName(),"03", false ,input.getTribPortNumber(),input.getTribSlot()));
+                    if (node.getClientTp() != null) {
+                        createdEthInterfaces.add(openRoadmInterfaceFactory.createOpenRoadmEth10GInterface(
+                            node.getNodeId(), node.getClientTp()));
+                        createdOduInterfaces.add(
+                            // suppporting interface?, payload ?
+                            openRoadmInterfaceFactory.createOpenRoadmOdu2eInterface(node.getNodeId(),
+                                node.getClientTp(), input.getServiceName(), PT_03, false, input.getTribPortNumber(),
+                                input.getTribSlot()));
+                    }
                     createdOduInterfaces.add(
                         // supporting interface? payload ?
                         openRoadmInterfaceFactory.createOpenRoadmOdu2eInterface(node.getNodeId(), node.getNetworkTp(),
-                            input.getServiceName(),"03" , true ,input.getTribPortNumber(),input.getTribSlot()));
+                            input.getServiceName(), PT_03, true, input.getTribPortNumber(), input.getTribSlot()));
+                    if (node.getNetwork2Tp() != null) {
+                        createdOduInterfaces.add(
+                            // supporting interface? payload ?
+                            openRoadmInterfaceFactory.createOpenRoadmOdu2eInterface(node.getNodeId(),
+                                node.getNetwork2Tp(), input.getServiceName(), PT_03, true, input.getTribPortNumber(),
+                                input.getTribSlot()));
+                    }
                     break;
                 default:
                     LOG.error("service rate {} not managed yet", input.getServiceRate());
                     return;
             }
 
-            //implement cross connect
+            // implement cross connect
             List<String> createdConnections = new ArrayList<>();
             if (!createdOduInterfaces.isEmpty()) {
                 Optional<String> connectionNameOpt = postCrossConnect(createdOduInterfaces, node);
@@ -247,12 +353,48 @@ public class OtnDeviceRendererServiceImpl implements OtnDeviceRendererService {
                 LOG.info("Created cross connects");
             }
             NodeInterfaceBuilder nodeInterfaceBuilder = new NodeInterfaceBuilder()
-                    .withKey(new NodeInterfaceKey(input.getServiceName() + "-" + node.getNodeId()))
-                    .setNodeId(input.getServiceName() + "-" + node.getNodeId())
-                    .setConnectionId(createdConnections)
-                    .setEthInterfaceId(createdEthInterfaces)
-                    .setOduInterfaceId(createdOduInterfaces);
+                .withKey(new NodeInterfaceKey(node.getNodeId()))
+                .setNodeId(node.getNodeId())
+                .setConnectionId(createdConnections)
+                .setEthInterfaceId(createdEthInterfaces)
+                .setOduInterfaceId(createdOduInterfaces);
             nodeInterfaces.add(nodeInterfaceBuilder.build());
         }
     }
+
+    private void createODU4TtpInterface(OtnServicePathInput input, List<NodeInterface> nodeInterfaces,
+        CopyOnWriteArrayList<Nodes> otnNodesProvisioned) throws OpenRoadmInterfaceException {
+        for (Nodes node : input.getNodes()) {
+            String supportingOtuInterface = node.getNetworkTp() + "-OTU";
+            List<String> createdOdu4Interfaces = new ArrayList<>();
+            createdOdu4Interfaces.add(openRoadmInterfaceFactory.createOpenRoadmOtnOdu4Interface(node.getNodeId(),
+                node.getNetworkTp(), supportingOtuInterface));
+            NodeInterfaceBuilder nodeInterfaceBuilder = new NodeInterfaceBuilder()
+                .withKey(new NodeInterfaceKey(node.getNodeId()))
+                .setNodeId(node.getNodeId())
+                .setOduInterfaceId(createdOdu4Interfaces);
+            nodeInterfaces.add(nodeInterfaceBuilder.build());
+            otnNodesProvisioned.add(node);
+        }
+    }
+
+    private void updateOtnTopology(CopyOnWriteArrayList<Nodes> nodes, List<String> nodesTps, String serviceRate,
+        Short tribPortNb, Short tribSlotNb, boolean isDeletion) {
+        if (nodes != null && nodes.size() == 2) {
+            if (isDeletion) {
+                LOG.info("updating otn-topology removing ODU4 links");
+                this.networkModelService.deleteOtnLinks(nodes.get(0).getNodeId(), nodes.get(0).getNetworkTp(),
+                    nodes.get(1).getNodeId(), nodes.get(1).getNetworkTp(), OtnLinkType.ODTU4);
+            } else {
+                LOG.info("updating otn-topology adding ODU4 links");
+                this.networkModelService.createOtnLinks(nodes.get(0).getNodeId(), nodes.get(0).getNetworkTp(),
+                    nodes.get(1).getNodeId(), nodes.get(1).getNetworkTp(), OtnLinkType.ODTU4);
+            }
+        } else if (nodesTps != null && (nodesTps.size() % 2 == 0) && serviceRate != null && tribPortNb != null
+            && tribSlotNb != null) {
+            LOG.info("updating otn-topology node tps -tps and tpn pools");
+            this.networkModelService.updateOtnLinks(nodesTps, serviceRate, tribPortNb, tribSlotNb, isDeletion);
+        }
+    }
+
 }
index 94ca0af794a29ac82a868ea86d7405bdcae3d50c..198ddb1b20fec05005dc6bfad637ed9f89545036 100644 (file)
@@ -23,6 +23,7 @@ and is available at http://www.eclipse.org/legal/epl-v10.html
   <reference id="crossConnect" interface="org.opendaylight.transportpce.common.crossconnect.CrossConnect" />
   <reference id="mappingUtils" interface="org.opendaylight.transportpce.common.mapping.MappingUtils"/>
   <reference id="FixedFlexImpl" interface="org.opendaylight.transportpce.common.fixedflex.FixedFlexInterface"/>
+  <reference id="networkModelService" interface="org.opendaylight.transportpce.networkmodel.service.NetworkModelService"/>
 
   <odl:rpc-service id="olmService"
       interface="org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.olm.rev170418.TransportpceOlmService"/>
@@ -61,6 +62,7 @@ and is available at http://www.eclipse.org/legal/epl-v10.html
     <argument ref="openRoadmInterfaces" />
     <argument ref="crossConnect" />
     <argument ref="portMapping" />
+    <argument ref="networkModelService" />
   </bean>
 
   <bean id="otnDeviceRenderer" class="org.opendaylight.transportpce.renderer.provisiondevice.OtnDeviceRendererServiceImpl" >
@@ -68,6 +70,7 @@ and is available at http://www.eclipse.org/legal/epl-v10.html
     <argument ref="crossConnect" />
     <argument ref="openRoadmInterfaces" />
     <argument ref="deviceTransactionManager" />
+    <argument ref="networkModelService" />
   </bean>
 
     <bean id="deviceRendererRPCImpl" class="org.opendaylight.transportpce.renderer.rpcs.DeviceRendererRPCImpl" >
index 0f94cd9c09fe75b7ea40fb4b38f571341c257bc5..cab783017c37b327d85907764ca714c08feb7873 100644 (file)
@@ -95,7 +95,7 @@ public class DeviceRendererServiceImplCreateOtsOmsTest extends AbstractTest {
         this.crossConnect = Mockito.spy(this.crossConnect);
         this.deviceRendererService = new DeviceRendererServiceImpl(this.getDataBroker(),
             this.deviceTransactionManager, this.openRoadmInterfaceFactory, this.openRoadmInterfaces,
-            this.crossConnect, portMapping);
+            this.crossConnect, portMapping, null);
     }
 
     @Test
index e788fc9be6a2ab24e190b8124569d9a7a9d9f357..62937348459851c378d72141b95b88d29be0fa77 100644 (file)
@@ -117,7 +117,7 @@ public class RendererServiceOperationsImplDeleteTest extends AbstractTest {
 
         this.deviceRenderer = new DeviceRendererServiceImpl(this.getDataBroker(),
             this.deviceTransactionManager, openRoadmInterfaceFactory, openRoadmInterfaces, crossConnect,
-            this.portMapping);
+            this.portMapping, null);
     }
 
     @Before
index 8fcbed63f0401f7466bd4629ec27d6d9d0d403ee..ce1b7fcb10a4fbd47da614b3964b75846198a8f9 100644 (file)
@@ -120,8 +120,8 @@ public class RendererServiceOperationsImplTest extends AbstractTest {
         setMountPoint(new MountPointStub(getDataBroker()));
         this.olmService = new OlmServiceStub();
         this.networkModelWavelengthService = new NetworkModelWavelengthServiceImpl(getDataBroker());
-        this.deviceRenderer = new DeviceRendererServiceImpl(this.getDataBroker(),
-            this.deviceTransactionManager, openRoadmInterfaceFactory, openRoadmInterfaces, crossConnect, portMapping);
+        this.deviceRenderer = new DeviceRendererServiceImpl(this.getDataBroker(), this.deviceTransactionManager,
+            openRoadmInterfaceFactory, openRoadmInterfaces, crossConnect, portMapping, null);
         Mockito.doNothing().when(this.openRoadmInterfaces).postEquipmentState(Mockito.anyString(),
             Mockito.anyString(), Mockito.anyBoolean());
         NotificationPublishService notificationPublishService = new NotificationPublishServiceMock();
index 476f146b69d5b845d795864f03275218b61c94fa..cfd90383010295a8e6a6e0eef401baa1e4be68d3 100644 (file)
@@ -125,7 +125,7 @@ class TransportPCEtesting(unittest.TestCase):
                 "xponder-type": "mpdr"},
             res['mapping'])
 
-    def test_04_service_path_create_ODU4(self):
+    def test_04_service_path_create_OCH_OTU4(self):
         url = "{}/operations/transportpce-device-renderer:service-path".format(self.restconf_baseurl)
         data = {"renderer:input": {
             "service-name": "service_ODU4",
@@ -147,7 +147,6 @@ class TransportPCEtesting(unittest.TestCase):
         self.assertIn(
             {'node-id': 'SPDR-SA1',
              'otu-interface-id': ['XPDR1-NETWORK1-OTU'],
-             'odu-interface-id': ['XPDR1-NETWORK1-ODU4'],
              'och-interface-id': ['XPDR1-NETWORK1-1']}, res["output"]['node-interface'])
 
     def test_05_get_portmapping_NETWORK1(self):
@@ -168,8 +167,7 @@ class TransportPCEtesting(unittest.TestCase):
                 "port-direction": "bidirectional",
                 "port-qual": "xpdr-network",
                 "supporting-circuit-pack-name": "CP1-CFP0",
-                "xponder-type": "mpdr",
-                "supporting-odu4": "XPDR1-NETWORK1-ODU4"},
+                "xponder-type": "mpdr"},
             res['mapping'])
 
     def test_06_check_interface_och(self):
@@ -210,7 +208,52 @@ class TransportPCEtesting(unittest.TestCase):
              u'fec': u'scfec'},
             res['interface'][0]['org-openroadm-otn-otu-interfaces:otu'])
 
-    def test_08_check_interface_ODU4(self):
+    def test_08_otn_service_path_create_ODU4(self):
+        url = "{}/operations/transportpce-device-renderer:otn-service-path".format(self.restconf_baseurl)
+        data = {"renderer:input": {
+            "service-name": "service_ODU4",
+            "operation": "create",
+            "service-rate": "100G",
+            "service-type": "ODU",
+            "nodes": [
+                {"node-id": "SPDR-SA1",
+                 "network-tp": "XPDR1-NETWORK1"}]}}
+        headers = {'content-type': 'application/json'}
+        response = requests.request(
+            "POST", url, data=json.dumps(data),
+            headers=headers, auth=('admin', 'admin'))
+        time.sleep(3)
+        self.assertEqual(response.status_code, requests.codes.ok)
+        res = response.json()
+        self.assertIn('Otn Service path was set up successfully for node :SPDR-SA1', res["output"]["result"])
+        self.assertTrue(res["output"]["success"])
+        self.assertIn(
+            {'node-id': 'SPDR-SA1',
+             'odu-interface-id': ['XPDR1-NETWORK1-ODU4']}, res["output"]['node-interface'])
+
+    def test_09_get_portmapping_NETWORK1(self):
+        url = ("{}/config/transportpce-portmapping:network/"
+               "nodes/SPDR-SA1/mapping/XPDR1-NETWORK1"
+               .format(self.restconf_baseurl))
+        headers = {'content-type': 'application/json'}
+        response = requests.request(
+            "GET", url, headers=headers, auth=('admin', 'admin'))
+        self.assertEqual(response.status_code, requests.codes.ok)
+        res = response.json()
+        self.assertIn(
+            {"logical-connection-point": "XPDR1-NETWORK1",
+            "supporting-port": "CP1-CFP0-P1",
+            "supported-interface-capability": [
+                "org-openroadm-port-types:if-OCH-OTU4-ODU4"
+            ],
+            "port-direction": "bidirectional",
+            "port-qual": "xpdr-network",
+            "supporting-circuit-pack-name": "CP1-CFP0",
+            "xponder-type": "mpdr",
+            "supporting-odu4": "XPDR1-NETWORK1-ODU4"},
+            res['mapping'])
+
+    def test_10_check_interface_ODU4(self):
         url = ("{}/config/network-topology:network-topology/topology/topology-netconf/"
                "node/SPDR-SA1/yang-ext:mount/org-openroadm-device:org-openroadm-device/"
                "interface/XPDR1-NETWORK1-ODU4"
@@ -232,7 +275,7 @@ class TransportPCEtesting(unittest.TestCase):
             {u'payload-type': u'21', u'exp-payload-type': u'21'},
             res['interface'][0]['org-openroadm-otn-odu-interfaces:odu']['opu'])
 
-    def test_09_otn_service_path_create_10GE(self):
+    def test_11_otn_service_path_create_10GE(self):
         url = "{}/operations/transportpce-device-renderer:otn-service-path".format(self.restconf_baseurl)
         data = {"renderer:input": {
             "service-name": "service1",
@@ -242,7 +285,6 @@ class TransportPCEtesting(unittest.TestCase):
             "ethernet-encoding": "eth encode",
             "trib-slot": ["1"],
             "trib-port-number": "1",
-            "opucn-trib-slots": ["1"],
             "nodes": [
                 {"node-id": "SPDR-SA1",
                  "client-tp": "XPDR1-CLIENT1",
@@ -251,12 +293,18 @@ class TransportPCEtesting(unittest.TestCase):
         response = requests.request(
             "POST", url, data=json.dumps(data),
             headers=headers, auth=('admin', 'admin'))
+        time.sleep(3)
         self.assertEqual(response.status_code, requests.codes.ok)
         res = response.json()
-        self.assertIn('Otn Service path was set up successfully for node :service1-SPDR-SA1', res["output"]["result"])
+        self.assertIn('Otn Service path was set up successfully for node :SPDR-SA1', res["output"]["result"])
         self.assertTrue(res["output"]["success"])
+        self.assertIn(
+            {'node-id': 'SPDR-SA1',
+             'connection-id': ['XPDR1-CLIENT1-ODU2e-service1-x-XPDR1-NETWORK1-ODU2e-service1'],
+             'odu-interface-id': ['XPDR1-NETWORK1-ODU2e-service1', 'XPDR1-CLIENT1-ODU2e-service1'],
+             'eth-interface-id': ['XPDR1-CLIENT1-ETHERNET10G']}, res["output"]['node-interface'])
 
-    def test_10_check_interface_10GE_CLIENT(self):
+    def test_12_check_interface_10GE_CLIENT(self):
         url = ("{}/config/network-topology:network-topology/topology/topology-netconf/"
                "node/SPDR-SA1/yang-ext:mount/org-openroadm-device:org-openroadm-device/"
                "interface/XPDR1-CLIENT1-ETHERNET10G"
@@ -274,7 +322,7 @@ class TransportPCEtesting(unittest.TestCase):
             {u'speed': 10000},
             res['interface'][0]['org-openroadm-ethernet-interfaces:ethernet'])
 
-    def test_11_check_interface_ODU2E_CLIENT(self):
+    def test_13_check_interface_ODU2E_CLIENT(self):
         url = ("{}/config/network-topology:network-topology/topology/topology-netconf/"
                "node/SPDR-SA1/yang-ext:mount/org-openroadm-device:org-openroadm-device/"
                "interface/XPDR1-CLIENT1-ODU2e-service1"
@@ -297,7 +345,7 @@ class TransportPCEtesting(unittest.TestCase):
             {u'payload-type': u'03', u'exp-payload-type': u'03'},
             res['interface'][0]['org-openroadm-otn-odu-interfaces:odu']['opu'])
 
-    def test_12_check_interface_ODU2E_NETWORK(self):
+    def test_14_check_interface_ODU2E_NETWORK(self):
         url = ("{}/config/network-topology:network-topology/topology/topology-netconf/"
                "node/SPDR-SA1/yang-ext:mount/org-openroadm-device:org-openroadm-device/"
                "interface/XPDR1-NETWORK1-ODU2e-service1"
@@ -322,7 +370,7 @@ class TransportPCEtesting(unittest.TestCase):
         self.assertIn(1,
                       res['interface'][0]['org-openroadm-otn-odu-interfaces:odu']['parent-odu-allocation']['trib-slots'])
 
-    def test_13_check_ODU2E_connection(self):
+    def test_15_check_ODU2E_connection(self):
         url = ("{}/config/network-topology:network-topology/topology/topology-netconf/"
                "node/SPDR-SA1/yang-ext:mount/org-openroadm-device:org-openroadm-device/"
                "odu-connection/XPDR1-CLIENT1-ODU2e-service1-x-XPDR1-NETWORK1-ODU2e-service1"
@@ -341,7 +389,7 @@ class TransportPCEtesting(unittest.TestCase):
         self.assertDictEqual({u'src-if': u'XPDR1-CLIENT1-ODU2e-service1'},
                              res['odu-connection'][0]['source'])
 
-    def test_14_otn_service_path_delete_10GE(self):
+    def test_16_otn_service_path_delete_10GE(self):
         url = "{}/operations/transportpce-device-renderer:otn-service-path".format(self.restconf_baseurl)
         data = {"renderer:input": {
             "service-name": "service1",
@@ -351,7 +399,6 @@ class TransportPCEtesting(unittest.TestCase):
             "ethernet-encoding": "eth encode",
             "trib-slot": ["1"],
             "trib-port-number": "1",
-            "opucn-trib-slots": ["1"],
             "nodes": [
                 {"node-id": "SPDR-SA1",
                  "client-tp": "XPDR1-CLIENT1",
@@ -360,12 +407,13 @@ class TransportPCEtesting(unittest.TestCase):
         response = requests.request(
             "POST", url, data=json.dumps(data),
             headers=headers, auth=('admin', 'admin'))
+        time.sleep(3)
         self.assertEqual(response.status_code, requests.codes.ok)
         res = response.json()
         self.assertIn('Request processed', res["output"]["result"])
         self.assertTrue(res["output"]["success"])
 
-    def test_15_check_no_ODU2E_connection(self):
+    def test_17_check_no_ODU2E_connection(self):
         url = ("{}/config/network-topology:network-topology/topology/topology-netconf/"
                "node/SPDR-SA1/yang-ext:mount/org-openroadm-device:org-openroadm-device/"
                "odu-connection/XPDR1-CLIENT1-ODU2e-service1-x-XPDR1-NETWORK1-ODU2e-service1"
@@ -375,7 +423,7 @@ class TransportPCEtesting(unittest.TestCase):
             "GET", url, headers=headers, auth=('admin', 'admin'))
         self.assertEqual(response.status_code, requests.codes.not_found)
 
-    def test_16_check_no_interface_ODU2E_NETWORK(self):
+    def test_18_check_no_interface_ODU2E_NETWORK(self):
         url = ("{}/config/network-topology:network-topology/topology/topology-netconf/"
                "node/SPDR-SA1/yang-ext:mount/org-openroadm-device:org-openroadm-device/"
                "interface/XPDR1-NETWORK1-ODU2e-service1"
@@ -385,7 +433,7 @@ class TransportPCEtesting(unittest.TestCase):
             "GET", url, headers=headers, auth=('admin', 'admin'))
         self.assertEqual(response.status_code, requests.codes.not_found)
 
-    def test_17_check_no_interface_ODU2E_CLIENT(self):
+    def test_19_check_no_interface_ODU2E_CLIENT(self):
         url = ("{}/config/network-topology:network-topology/topology/topology-netconf/"
                "node/SPDR-SA1/yang-ext:mount/org-openroadm-device:org-openroadm-device/"
                "interface/XPDR1-CLIENT1-ODU2e-service1"
@@ -395,7 +443,7 @@ class TransportPCEtesting(unittest.TestCase):
             "GET", url, headers=headers, auth=('admin', 'admin'))
         self.assertEqual(response.status_code, requests.codes.not_found)
 
-    def test_18_check_no_interface_10GE_CLIENT(self):
+    def test_20_check_no_interface_10GE_CLIENT(self):
         url = ("{}/config/network-topology:network-topology/topology/topology-netconf/"
                "node/SPDR-SA1/yang-ext:mount/org-openroadm-device:org-openroadm-device/"
                "interface/XPDR1-CLIENT1-ETHERNET10G"
@@ -405,16 +453,16 @@ class TransportPCEtesting(unittest.TestCase):
             "GET", url, headers=headers, auth=('admin', 'admin'))
         self.assertEqual(response.status_code, requests.codes.not_found)
 
-    def test_19_service_path_delete_ODU4(self):
-        url = "{}/operations/transportpce-device-renderer:service-path".format(self.restconf_baseurl)
+    def test_21_otn_service_path_delete_ODU4(self):
+        url = "{}/operations/transportpce-device-renderer:otn-service-path".format(self.restconf_baseurl)
         data = {"renderer:input": {
             "service-name": "service_ODU4",
-            "wave-number": "1",
-            "modulation-format": "qpsk",
             "operation": "delete",
+            "service-rate": "100G",
+            "service-type": "ODU",
             "nodes": [
                 {"node-id": "SPDR-SA1",
-                 "dest-tp": "XPDR1-NETWORK1"}]}}
+                 "network-tp": "XPDR1-NETWORK1"}]}}
         headers = {'content-type': 'application/json'}
         response = requests.request(
             "POST", url, data=json.dumps(data),
@@ -425,7 +473,7 @@ class TransportPCEtesting(unittest.TestCase):
         self.assertIn('Request processed', res["output"]["result"])
         self.assertTrue(res["output"]["success"])
 
-    def test_20_check_no_interface_ODU4(self):
+    def test_22_check_no_interface_ODU4(self):
         url = ("{}/config/network-topology:network-topology/topology/topology-netconf/"
                "node/SPDR-SA1/yang-ext:mount/org-openroadm-device:org-openroadm-device/"
                "interface/XPDR1-NETWORK1-ODU4"
@@ -435,7 +483,27 @@ class TransportPCEtesting(unittest.TestCase):
             "GET", url, headers=headers, auth=('admin', 'admin'))
         self.assertEqual(response.status_code, requests.codes.not_found)
 
-    def test_21_check_no_interface_OTU(self):
+    def test_23_service_path_delete_OCH_OTU4(self):
+        url = "{}/operations/transportpce-device-renderer:service-path".format(self.restconf_baseurl)
+        data = {"renderer:input": {
+            "service-name": "service_OTU4",
+            "wave-number": "1",
+            "modulation-format": "qpsk",
+            "operation": "delete",
+            "nodes": [
+                {"node-id": "SPDR-SA1",
+                 "dest-tp": "XPDR1-NETWORK1"}]}}
+        headers = {'content-type': 'application/json'}
+        response = requests.request(
+            "POST", url, data=json.dumps(data),
+            headers=headers, auth=('admin', 'admin'))
+        time.sleep(3)
+        self.assertEqual(response.status_code, requests.codes.ok)
+        res = response.json()
+        self.assertIn('Request processed', res["output"]["result"])
+        self.assertTrue(res["output"]["success"])
+
+    def test_24_check_no_interface_OTU4(self):
         url = ("{}/config/network-topology:network-topology/topology/topology-netconf/"
                "node/SPDR-SA1/yang-ext:mount/org-openroadm-device:org-openroadm-device/"
                "interface/XPDR1-NETWORK1-OTU"
@@ -445,7 +513,7 @@ class TransportPCEtesting(unittest.TestCase):
             "GET", url, headers=headers, auth=('admin', 'admin'))
         self.assertEqual(response.status_code, requests.codes.not_found)
 
-    def test_22_check_no_interface_och(self):
+    def test_25_check_no_interface_OCH(self):
         url = ("{}/config/network-topology:network-topology/topology/topology-netconf/"
                "node/SPDR-SA1/yang-ext:mount/org-openroadm-device:org-openroadm-device/"
                "interface/XPDR1-NETWORK1-1"
@@ -455,7 +523,7 @@ class TransportPCEtesting(unittest.TestCase):
             "GET", url, headers=headers, auth=('admin', 'admin'))
         self.assertEqual(response.status_code, requests.codes.not_found)
 
-    def test_23_disconnect_SPDR_SA1(self):
+    def test_26_disconnect_SPDR_SA1(self):
         url = ("{}/config/network-topology:"
                "network-topology/topology/topology-netconf/node/SPDR-SA1"
                .format(self.restconf_baseurl))