Enabled flex-grid support for 2.2.1 Roadms
[transportpce.git] / renderer / src / main / java / org / opendaylight / transportpce / renderer / provisiondevice / DeviceRendererServiceImpl.java
index bbac76c267403e688e5d8d8db68edcf1e344cd5b..783ee6c0b7385486e65be391732db02c0c8b6565 100644 (file)
@@ -9,13 +9,14 @@ package org.opendaylight.transportpce.renderer.provisiondevice;
 
 import com.google.common.collect.Sets;
 import com.google.common.util.concurrent.FluentFuture;
-
+import java.math.BigDecimal;
 import java.util.ArrayList;
 import java.util.LinkedList;
 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;
@@ -23,7 +24,6 @@ import java.util.concurrent.Future;
 import java.util.concurrent.TimeUnit;
 import java.util.concurrent.TimeoutException;
 import java.util.concurrent.atomic.AtomicBoolean;
-
 import org.eclipse.jdt.annotation.NonNull;
 import org.opendaylight.mdsal.binding.api.DataBroker;
 import org.opendaylight.mdsal.binding.api.ReadTransaction;
@@ -37,13 +37,14 @@ 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;
 import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.alarmsuppression.rev171102.ServiceNodelist;
 import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.alarmsuppression.rev171102.service.nodelist.NodelistBuilder;
 import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.alarmsuppression.rev171102.service.nodelist.NodelistKey;
-import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.portmapping.rev200128.network.nodes.Mapping;
+import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.portmapping.rev200827.network.nodes.Mapping;
 import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.renderer.device.rev200128.CreateOtsOmsInput;
 import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.renderer.device.rev200128.CreateOtsOmsOutput;
 import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.renderer.device.rev200128.CreateOtsOmsOutputBuilder;
@@ -62,16 +63,16 @@ import org.opendaylight.yang.gen.v1.http.org.openroadm.service.rev190531.Service
 import org.opendaylight.yang.gen.v1.http.org.openroadm.service.rev190531.service.list.Services;
 import org.opendaylight.yang.gen.v1.http.org.openroadm.service.rev190531.service.list.ServicesBuilder;
 import org.opendaylight.yang.gen.v1.http.org.openroadm.service.rev190531.service.list.ServicesKey;
-import org.opendaylight.yang.gen.v1.http.org.transportpce.common.types.rev200128.node.interfaces.NodeInterface;
-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.org.transportpce.common.types.rev200615.node.interfaces.NodeInterface;
+import org.opendaylight.yang.gen.v1.http.org.transportpce.common.types.rev200615.node.interfaces.NodeInterfaceBuilder;
+import org.opendaylight.yang.gen.v1.http.org.transportpce.common.types.rev200615.node.interfaces.NodeInterfaceKey;
+import org.opendaylight.yang.gen.v1.http.org.transportpce.common.types.rev200615.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 +82,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,11 +106,14 @@ 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();
         ForkJoinTask forkJoinTask = forkJoinPool.submit(() -> nodes.parallelStream().forEach(node -> {
             String nodeId = node.getNodeId();
+            // take the index of the node
+            int nodeIndex = nodes.indexOf(node);
             LOG.info("Starting provisioning for node : {}", nodeId);
             List<String> createdEthInterfaces = new ArrayList<>();
             List<String> createdOtuInterfaces = new ArrayList<>();
@@ -118,23 +124,46 @@ public class DeviceRendererServiceImpl implements DeviceRendererService {
             try {
                 // if the node is currently mounted then proceed
                 if (this.deviceTransactionManager.isDeviceMounted(nodeId)) {
+                    // TODO: In the case of flex-grid, the wave-number becomes bitmap index
+                    // TODO: need to update transportpce-common-types accordingly, to a more, generic-term
+                    Long waveNumber = input.getWaveNumber().toJava();
+                    BigDecimal centerFreq = null;
+                    BigDecimal slotWidth = null;
+                    if (input.getCenterFreq() != null) {
+                        centerFreq = input.getCenterFreq().getValue();
+                    }
+                    if (input.getSlotWidth() != null) {
+                        slotWidth = input.getSlotWidth().getValue();
+                    }
                     String srcTp = node.getSrcTp();
                     String destTp = node.getDestTp();
-                    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(
+                        String supportingOchInterface;
+                        if ((centerFreq != null) && (slotWidth != null)) {
+                            supportingOchInterface = this.openRoadmInterfaceFactory.createOpenRoadmOchInterface(
+                                nodeId, destTp, waveNumber, ModulationFormat.DpQpsk, centerFreq, slotWidth);
+                        }
+                        else {
+                            supportingOchInterface = this.openRoadmInterfaceFactory.createOpenRoadmOchInterface(
                                 nodeId, destTp, waveNumber, ModulationFormat.DpQpsk);
+                        }
                         createdOchInterfaces.add(supportingOchInterface);
+                        // Here we pass logical connection-point of z-end to set SAPI and DAPI
+                        Nodes tgtNode = null;
+                        if (nodeIndex + 1 == nodes.size()) {
+                            // For the end node, tgtNode becomes the first node in the list
+                            tgtNode = nodes.get(0);
+                        } else {
+                            tgtNode = nodes.get(nodeIndex + 1);
+                        }
+                        // tgtNode srcTp is null in this if cond
                         String supportingOtuInterface = this.openRoadmInterfaceFactory
-                                .createOpenRoadmOtu4Interface(nodeId, destTp, supportingOchInterface);
+                                .createOpenRoadmOtu4Interface(nodeId, destTp, supportingOchInterface,
+                                    tgtNode.getNodeId(), tgtNode.getDestTp());
                         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));
@@ -149,8 +178,15 @@ public class DeviceRendererServiceImpl implements DeviceRendererService {
                     if ((srcTp != null) && srcTp.contains(StringConstants.NETWORK_TOKEN)) {
                         crossConnectFlag++;
                         // create OpenRoadm Xponder Line Interfaces
-                        String supportingOchInterface = this.openRoadmInterfaceFactory.createOpenRoadmOchInterface(
+                        String supportingOchInterface;
+                        if ((centerFreq != null) && (slotWidth != null)) {
+                            supportingOchInterface = this.openRoadmInterfaceFactory.createOpenRoadmOchInterface(
+                                nodeId, srcTp, waveNumber, ModulationFormat.DpQpsk, centerFreq, slotWidth);
+                        }
+                        else {
+                            supportingOchInterface = this.openRoadmInterfaceFactory.createOpenRoadmOchInterface(
                                 nodeId, srcTp, waveNumber, ModulationFormat.DpQpsk);
+                        }
                         createdOchInterfaces.add(supportingOchInterface);
                         String supportingOtuInterface = this.openRoadmInterfaceFactory
                                 .createOpenRoadmOtu4Interface(nodeId, srcTp, supportingOchInterface);
@@ -176,15 +212,31 @@ public class DeviceRendererServiceImpl implements DeviceRendererService {
                     }
                     if ((srcTp != null) && (srcTp.contains(StringConstants.TTP_TOKEN)
                             || srcTp.contains(StringConstants.PP_TOKEN))) {
-                        createdOchInterfaces.addAll(
-                            this.openRoadmInterfaceFactory
-                                .createOpenRoadmOchInterface(nodeId, srcTp, waveNumber));
+                        if ((centerFreq != null) && (slotWidth != null)) {
+                            createdOchInterfaces.addAll(
+                                this.openRoadmInterfaceFactory
+                                    .createOpenRoadmOchInterface(nodeId, srcTp, waveNumber, centerFreq, slotWidth));
+                        }
+                        else {
+                            createdOchInterfaces.addAll(
+                                this.openRoadmInterfaceFactory
+                                    .createOpenRoadmOchInterface(nodeId, srcTp, waveNumber));
+                        }
                     }
                     if ((destTp != null) && (destTp.contains(StringConstants.TTP_TOKEN)
                             || destTp.contains(StringConstants.PP_TOKEN))) {
-                        createdOchInterfaces.addAll(
-                            this.openRoadmInterfaceFactory
-                                .createOpenRoadmOchInterface(nodeId, destTp, waveNumber));
+
+                        if ((centerFreq != null) && (slotWidth != null)) {
+                            createdOchInterfaces.addAll(
+                                this.openRoadmInterfaceFactory
+                                    .createOpenRoadmOchInterface(nodeId, destTp, waveNumber, centerFreq, slotWidth));
+                        }
+                        else {
+                            createdOchInterfaces.addAll(
+                                this.openRoadmInterfaceFactory
+                                    .createOpenRoadmOchInterface(nodeId, destTp, waveNumber));
+                        }
+
                     }
                     if (crossConnectFlag < 1) {
                         LOG.info("Creating cross connect between source {} and destination {} for node {}", srcTp,
@@ -228,19 +280,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 +313,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 +332,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 +363,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 +628,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);
+        }
+    }
 }