Allow the client to specify ROADM service SRG port 69/109369/12
authorJoakim Törnqvist <joakim.tornqvist@smartoptics.com>
Thu, 7 Dec 2023 15:03:53 +0000 (15:03 +0000)
committerJoakim Törnqvist <joakim.tornqvist@smartoptics.com>
Thu, 29 Feb 2024 15:04:01 +0000 (15:04 +0000)
Allows the client to specifiy port with 'port-device-name' and
'port-name' (see example down below).

The feature is implemented in PceOpticalNode. The rest are
classes being updated since there is a new argument in
the method PceOpticalNode.initSrgTps():

    initSrgTps(Preference portPreference) {...}

Feature implementation overview

The feature uses the classes in package:
org.opendaylight.transportpce.pce.networkanalyzer.port

* PceCalculation instantiates an instance of Preference using
  PreferenceFactory and passing it on to the constructor in
  PceOpticalNode.
* PreferenceFactory in turn uses PathComputationRequestInput
  to return either 'NoPreference' or 'ClientPreference'.
* Returning an instance of 'NoPreference' is the backwards compatible
  approach. The class 'NoPreference' is currently implemented as
  the equivalent of 'port-device-name' and 'port-name' being absent
  from the client request.
* If the client uses 'port-device-name' and 'port-name' an instance
  of ClientPreference is returned.
* PceOpticalNode uses the method preferredPort(...) defined by
  the interface Preference (implemented by NoPreference/
  ClientPreference) when building a list of avilable ports.
  If a port is not in the preferred list, it's treated as
  unavailable by PceOpticalNode.

APIImpact

POST /rests/operations/org-openroadm-service:service-create
{
  "input": {
...
    "port": {
      "port-device-name": "ROADM-B-SRG1",
      "port-name":        "SRG1-PP2-TXRX",
    }
...
  }
}

The above will result in port SRG1-PP2-TXRX on node ROADM-B-SRG1
being used in the service. All other ports on ROADM-B-SRG1
will be treated as "unavailable".

JIRA: TRNSPRTPCE-176
Change-Id: I453a92fda2977ac86c5c5ff47e1a7f6cd322334d
Signed-off-by: Joakim Törnqvist <joakim.tornqvist@smartoptics.com>
pce/src/main/java/org/opendaylight/transportpce/pce/networkanalyzer/PceCalculation.java
pce/src/main/java/org/opendaylight/transportpce/pce/networkanalyzer/PceOpticalNode.java
pce/src/test/java/org/opendaylight/transportpce/pce/networkanalyzer/PceOpticalNodeTest.java

index 8bac0a20993faf532ceebdb35c40dbe6977033c3..0afc9bca8a196d40f9d2821c215f31b8ec8d6d54 100644 (file)
@@ -29,6 +29,9 @@ import org.opendaylight.transportpce.common.network.NetworkTransactionService;
 import org.opendaylight.transportpce.common.service.ServiceTypes;
 import org.opendaylight.transportpce.pce.PceComplianceCheck;
 import org.opendaylight.transportpce.pce.constraints.PceConstraints;
+import org.opendaylight.transportpce.pce.networkanalyzer.port.Factory;
+import org.opendaylight.transportpce.pce.networkanalyzer.port.Preference;
+import org.opendaylight.transportpce.pce.networkanalyzer.port.PreferenceFactory;
 import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.pce.rev240205.PathComputationRequestInput;
 import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.pce.rev240205.path.computation.reroute.request.input.Endpoints;
 import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.portmapping.rev231221.mc.capabilities.McCapabilities;
@@ -293,9 +296,11 @@ public class PceCalculation {
             case StringConstants.SERVICE_TYPE_OTUC2:
             case StringConstants.SERVICE_TYPE_OTUC3:
             case  StringConstants.SERVICE_TYPE_OTUC4:
+                Factory portPreferenceFactory = new PreferenceFactory();
+                Preference portPreference = portPreferenceFactory.portPreference(input);
                 // 100GE service and OTU4 service are handled at the openroadm-topology layer
                 for (Node node : allNodes) {
-                    validateNode(node);
+                    validateNode(node, portPreference);
                 }
 
                 LOG.debug("analyzeNw: allPceNodes size {}", allPceNodes.size());
@@ -439,7 +444,7 @@ public class PceCalculation {
         }
     }
 
-    private void validateNode(Node node) {
+    private void validateNode(Node node, Preference portPreference) {
         LOG.debug("validateNode: node {} ", node);
         // PceNode will be used in Graph algorithm
         Node1 node1 = node.augmentation(Node1.class);
@@ -478,7 +483,7 @@ public class PceCalculation {
             return;
         }
 
-        if (endPceNode(nodeType, pceNode.getNodeId(), pceNode)) {
+        if (endPceNode(nodeType, pceNode.getNodeId(), pceNode, portPreference)) {
             if (this.aendPceNode == null && isAZendPceNode(this.serviceFormatA, pceNode, anodeId, "A")) {
                 // Added to ensure A-node has a addlink in the topology
                 List<Link> links = this.allLinks.stream()
@@ -625,10 +630,11 @@ public class PceCalculation {
         }
     }
 
-    private Boolean endPceNode(OpenroadmNodeType openroadmNodeType, NodeId nodeId, PceOpticalNode pceNode) {
+    private Boolean endPceNode(OpenroadmNodeType openroadmNodeType, NodeId nodeId, PceOpticalNode pceNode,
+                               Preference portPreference) {
         switch (openroadmNodeType) {
             case SRG:
-                pceNode.initSrgTps();
+                pceNode.initSrgTps(portPreference);
                 this.azSrgs.add(nodeId);
                 break;
             case XPONDER:
index 395693ff9487bb92b0a0d45cd7fc31fecaabdd90..611263d68a3f43e490abc0af1ab034a9146faa65 100644 (file)
@@ -21,6 +21,7 @@ import org.opendaylight.transportpce.common.StringConstants;
 import org.opendaylight.transportpce.common.fixedflex.GridConstant;
 import org.opendaylight.transportpce.common.mapping.PortMapping;
 import org.opendaylight.transportpce.pce.SortPortsByName;
+import org.opendaylight.transportpce.pce.networkanalyzer.port.Preference;
 import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.pce.rev240205.path.computation.reroute.request.input.Endpoints;
 import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.portmapping.rev231221.mapping.Mapping;
 import org.opendaylight.yang.gen.v1.http.org.openroadm.common.network.rev230526.TerminationPoint1;
@@ -102,7 +103,7 @@ public class PceOpticalNode implements PceNode {
         }
     }
 
-    public void initSrgTps() {
+    public void initSrgTps(Preference portPreference) {
         this.availableSrgPp.clear();
         this.availableSrgCp.clear();
         if (!isValid()) {
@@ -141,6 +142,10 @@ public class PceOpticalNode implements PceNode {
                 case SRGTXPP:
                 case SRGTXRXPP:
                     LOG.debug("initSrgTpList: SRG-PP tp = {} found", tp.getTpId().getValue());
+                    if (!portPreference.isPreferredPort(nodeId.getValue(), tp.getTpId().getValue())) {
+                        LOG.warn("initSrgTpList: SRG-PP tp = {} is rejected by the client", tp.getTpId().getValue());
+                        break;
+                    }
                     if (isTerminationPointAvailable(nttp1)) {
                         LOG.debug("initSrgTpList: adding SRG-PP tp '{}'", tp.getTpId().getValue());
                         this.availableSrgPp.put(tp.getTpId().getValue(), cntp1.getTpType());
index 733ba20885a41253c1ccd37521321efe096e96af..876dcd9d8dbcd1d5e381ed2e3dd01aeca055118a 100644 (file)
@@ -26,6 +26,8 @@ import org.opendaylight.transportpce.common.StringConstants;
 import org.opendaylight.transportpce.common.fixedflex.GridConstant;
 import org.opendaylight.transportpce.common.fixedflex.GridUtils;
 import org.opendaylight.transportpce.common.mapping.PortMapping;
+import org.opendaylight.transportpce.pce.networkanalyzer.port.NoPreference;
+import org.opendaylight.transportpce.pce.networkanalyzer.port.Preference;
 import org.opendaylight.transportpce.test.AbstractTest;
 import org.opendaylight.yang.gen.v1.http.org.openroadm.common.network.rev230526.Node1;
 import org.opendaylight.yang.gen.v1.http.org.openroadm.common.network.rev230526.TerminationPoint1Builder;
@@ -76,6 +78,7 @@ public class PceOpticalNodeTest extends AbstractTest {
     private String serviceType = "100GE";
     @Mock
     private PortMapping portMapping;
+    private final Preference portPreference = new NoPreference();
 
     @BeforeEach
     void setUp() {
@@ -100,7 +103,7 @@ public class PceOpticalNodeTest extends AbstractTest {
         pceOpticalNode = new PceOpticalNode(deviceNodeId, serviceType, portMapping, node,
                 OpenroadmNodeType.ROADM, StringConstants.OPENROADM_DEVICE_VERSION_2_2_1,
                 GridConstant.SLOT_WIDTH_50, GridConstant.SLOT_WIDTH_50);
-        pceOpticalNode.initSrgTps();
+        pceOpticalNode.initSrgTps(portPreference);
         pceOpticalNode.initXndrTps(ServiceFormat.OMS);
         pceOpticalNode.initFrequenciesBitSet();
         assertFalse(pceOpticalNode.isValid());
@@ -163,7 +166,7 @@ public class PceOpticalNodeTest extends AbstractTest {
         pceOpticalNode = new PceOpticalNode(null, null, null, node,
                 OpenroadmNodeType.ROADM, StringConstants.OPENROADM_DEVICE_VERSION_2_2_1,
                 GridConstant.SLOT_WIDTH_50, GridConstant.SLOT_WIDTH_50);
-        pceOpticalNode.initSrgTps();
+        pceOpticalNode.initSrgTps(portPreference);
         assertNull(pceOpticalNode.getRdmSrgClient("7", StringConstants.SERVICE_DIRECTION_AZ));
         assertFalse(pceOpticalNode.isValid());
         assertNull(pceOpticalNode.getBitSetData());
@@ -177,7 +180,7 @@ public class PceOpticalNodeTest extends AbstractTest {
         pceOpticalNode = new PceOpticalNode(null, null, null, specificNode,
                 OpenroadmNodeType.ROADM, StringConstants.OPENROADM_DEVICE_VERSION_2_2_1,
                 GridConstant.SLOT_WIDTH_50, GridConstant.SLOT_WIDTH_50);
-        pceOpticalNode.initSrgTps();
+        pceOpticalNode.initSrgTps(portPreference);
         pceOpticalNode.initFrequenciesBitSet();
         pceOpticalNode.initXndrTps(ServiceFormat.OMS);
         assertNull(pceOpticalNode.getRdmSrgClient("7" ,StringConstants.SERVICE_DIRECTION_AZ));
@@ -191,7 +194,7 @@ public class PceOpticalNodeTest extends AbstractTest {
         pceOpticalNode = new PceOpticalNode(null, null, null, node,
                 OpenroadmNodeType.DEGREE, StringConstants.OPENROADM_DEVICE_VERSION_2_2_1,
                 GridConstant.SLOT_WIDTH_50, GridConstant.SLOT_WIDTH_50);
-        pceOpticalNode.initSrgTps();
+        pceOpticalNode.initSrgTps(portPreference);
         assertNull(pceOpticalNode.getRdmSrgClient("7" ,StringConstants.SERVICE_DIRECTION_AZ));
         assertFalse(pceOpticalNode.isValid());
         assertNull(pceOpticalNode.getBitSetData());
@@ -205,7 +208,7 @@ public class PceOpticalNodeTest extends AbstractTest {
         pceOpticalNode = new PceOpticalNode(null, null, null, specificNode,
                 OpenroadmNodeType.ROADM, StringConstants.OPENROADM_DEVICE_VERSION_2_2_1,
                 GridConstant.SLOT_WIDTH_50, GridConstant.SLOT_WIDTH_50);
-        pceOpticalNode.initSrgTps();
+        pceOpticalNode.initSrgTps(portPreference);
         assertFalse(pceOpticalNode.isValid());
         assertNull(pceOpticalNode.getBitSetData());
         assertTrue(pceOpticalNode.checkTP("testTP"));
@@ -219,7 +222,7 @@ public class PceOpticalNodeTest extends AbstractTest {
         pceOpticalNode = new PceOpticalNode(null, null, null, node,
                 OpenroadmNodeType.ROADM, StringConstants.OPENROADM_DEVICE_VERSION_2_2_1,
                 GridConstant.SLOT_WIDTH_50, GridConstant.SLOT_WIDTH_50);
-        pceOpticalNode.initSrgTps();
+        pceOpticalNode.initSrgTps(portPreference);
         assertNull(pceOpticalNode.getRdmSrgClient("2" ,StringConstants.SERVICE_DIRECTION_AZ));
         assertFalse(pceOpticalNode.isValid());
         assertNull(pceOpticalNode.getBitSetData());