Adapt PCE code for OTN services 96/87496/6
authorGilles Thouenon <gilles.thouenon@orange.com>
Thu, 30 Jan 2020 07:01:50 +0000 (08:01 +0100)
committerguillaume.lambert <guillaume.lambert@orange.com>
Sun, 9 Feb 2020 15:11:29 +0000 (16:11 +0100)
Allows pce code to calculate paths for OTU4, ODU4 structured for LO-ODU,
10GE and 1GE services, provided that the otn-topology contains correct
information for links and otn-nodes/tp.

- add PceNode interface, and use PceOpticalNode and PceOtnNode as two
different implementations of PceNode interface
- review implementations of chooseTribPort, chooseTribSlots methods in
PostAlogPathValidator

JIRA: TRNSPRTPCE-162 TRNSPRTPCE-201
Signed-off-by: Gilles Thouenon <gilles.thouenon@orange.com>
Co-authored-by: Christophe Betoule <christophe.betoule@orange.com>
Change-Id: Id7105571691e9513dff6ca41cd1287f351f35de9

15 files changed:
networkmodel/src/main/java/org/opendaylight/transportpce/networkmodel/util/OpenRoadmOtnTopology.java
networkmodel/src/main/java/org/opendaylight/transportpce/networkmodel/util/OpenRoadmTopology.java
ordmodels/network/src/main/yang/transportpce-network-topology@2020-01-29.yang [moved from ordmodels/network/src/main/yang/transportpce-network-topology@2020-01-23.yang with 57% similarity]
pce/src/main/java/org/opendaylight/transportpce/pce/PcePathDescription.java
pce/src/main/java/org/opendaylight/transportpce/pce/constraints/PceConstraints.java
pce/src/main/java/org/opendaylight/transportpce/pce/graph/PceGraph.java
pce/src/main/java/org/opendaylight/transportpce/pce/graph/PostAlgoPathValidator.java
pce/src/main/java/org/opendaylight/transportpce/pce/networkanalyzer/MapUtils.java
pce/src/main/java/org/opendaylight/transportpce/pce/networkanalyzer/PceCalculation.java
pce/src/main/java/org/opendaylight/transportpce/pce/networkanalyzer/PceLink.java
pce/src/main/java/org/opendaylight/transportpce/pce/networkanalyzer/PceNode.java
pce/src/main/java/org/opendaylight/transportpce/pce/networkanalyzer/PceOpticalNode.java [new file with mode: 0644]
pce/src/main/java/org/opendaylight/transportpce/pce/networkanalyzer/PceOtnNode.java
pce/src/main/java/org/opendaylight/transportpce/pce/networkanalyzer/PceResult.java
tapi/src/main/java/org/opendaylight/transportpce/tapi/topology/TapiTopologyImpl.java

index 6e0a4f8372d42c15b3c6a9ec04786757a987313d..f649bb6fe8f6090ef1350d7c4146d6e1d994cb00 100644 (file)
@@ -336,8 +336,8 @@ public final class OpenRoadmOtnTopology {
                 .setTpSupportedInterfaces(tpSupIf)
                 .setXpdrTpPortConnectionAttributes(xtpcaBldr.build())
                 .build();
-            org.opendaylight.yang.gen.v1.http.transportpce.topology.rev200123.TerminationPoint1Builder tpceTp1Bldr =
-                new org.opendaylight.yang.gen.v1.http.transportpce.topology.rev200123.TerminationPoint1Builder();
+            org.opendaylight.yang.gen.v1.http.transportpce.topology.rev200129.TerminationPoint1Builder tpceTp1Bldr =
+                new org.opendaylight.yang.gen.v1.http.transportpce.topology.rev200129.TerminationPoint1Builder();
             if (OpenroadmTpType.XPONDERNETWORK.equals(tpType)) {
                 TpId tpId = new TpId("XPDR" + node.getXpdrNb() + "-NETWORK" + i);
                 if (node.getXpdrNetConnectionMap().get(tpId.getValue()) != null) {
@@ -401,13 +401,13 @@ public final class OpenRoadmOtnTopology {
         return suppNodeList;
     }
 
-    private static TerminationPoint buildIetfTp(org.opendaylight.yang.gen.v1.http.transportpce.topology.rev200123
+    private static TerminationPoint buildIetfTp(org.opendaylight.yang.gen.v1.http.transportpce.topology.rev200129
         .TerminationPoint1Builder tpceTp1Bldr, TerminationPoint1 otnTp1, OpenroadmTpType tpType, TpId tpId,
         List<SupportingTerminationPoint> supportTpList) {
 
         TerminationPointBuilder ietfTpBldr = new TerminationPointBuilder();
         if (tpceTp1Bldr.getAssociatedConnectionMapPort() != null) {
-            ietfTpBldr.addAugmentation(org.opendaylight.yang.gen.v1.http.transportpce.topology.rev200123
+            ietfTpBldr.addAugmentation(org.opendaylight.yang.gen.v1.http.transportpce.topology.rev200129
                 .TerminationPoint1.class, tpceTp1Bldr.build());
         }
         if (supportTpList != null) {
index 621125fb9527439b38e52a432fee131d539a2573..1f22d2b03ba4fb87681a73c3029ef5459c26ec44 100644 (file)
@@ -196,24 +196,24 @@ public final class OpenRoadmTopology {
                     .common.network.rev181130.TerminationPoint1Builder();
                 if (m.getPortQual().equals("xpdr-network")) {
                     ocnTp1Bldr.setTpType(OpenroadmTpType.XPONDERNETWORK);
-                    org.opendaylight.yang.gen.v1.http.transportpce.topology.rev200123.TerminationPoint1 tpceTp1 =
-                        new org.opendaylight.yang.gen.v1.http.transportpce.topology.rev200123
+                    org.opendaylight.yang.gen.v1.http.transportpce.topology.rev200129.TerminationPoint1 tpceTp1 =
+                        new org.opendaylight.yang.gen.v1.http.transportpce.topology.rev200129
                         .TerminationPoint1Builder().setAssociatedConnectionMapPort(m.getConnectionMapLcp()).build();
                     ietfTpBldr
                         .addAugmentation(org.opendaylight.yang.gen.v1.http.org.openroadm.common.network
                             .rev181130.TerminationPoint1.class, ocnTp1Bldr.build())
-                        .addAugmentation(org.opendaylight.yang.gen.v1.http.transportpce.topology.rev200123
+                        .addAugmentation(org.opendaylight.yang.gen.v1.http.transportpce.topology.rev200129
                             .TerminationPoint1.class, tpceTp1);
                     tpList.add(ietfTpBldr.build());
                 } else if (m.getPortQual().equals("xpdr-client")) {
                     ocnTp1Bldr.setTpType(OpenroadmTpType.XPONDERCLIENT);
-                    org.opendaylight.yang.gen.v1.http.transportpce.topology.rev200123.TerminationPoint1 tpceTp1 =
-                        new org.opendaylight.yang.gen.v1.http.transportpce.topology.rev200123
+                    org.opendaylight.yang.gen.v1.http.transportpce.topology.rev200129.TerminationPoint1 tpceTp1 =
+                        new org.opendaylight.yang.gen.v1.http.transportpce.topology.rev200129
                         .TerminationPoint1Builder().setAssociatedConnectionMapPort(m.getConnectionMapLcp()).build();
                     ietfTpBldr
                         .addAugmentation(org.opendaylight.yang.gen.v1.http.org.openroadm.common.network.rev181130
                             .TerminationPoint1.class, ocnTp1Bldr.build())
-                        .addAugmentation(org.opendaylight.yang.gen.v1.http.transportpce.topology.rev200123
+                        .addAugmentation(org.opendaylight.yang.gen.v1.http.transportpce.topology.rev200129
                             .TerminationPoint1.class, tpceTp1);
                     tpList.add(ietfTpBldr.build());
                 }
similarity index 57%
rename from ordmodels/network/src/main/yang/transportpce-network-topology@2020-01-23.yang
rename to ordmodels/network/src/main/yang/transportpce-network-topology@2020-01-29.yang
index a28ec0e9a742ef23f7964e0ec6597f8b83cecf82..9200f59628e7bcdd3609cbeed6121ac704ddaf4d 100644 (file)
@@ -20,14 +20,36 @@ module transportpce-topology {
     contact
         "TransportPCE team";
 
+    revision 2020-01-29 {
+        description "Add transportpce augmentation to manage otn-link-type in otn-topology";
+    }
     revision 2020-01-23 {
         description "Add transportpce augmentation for otn-topology";
     }
-
     revision 2019-06-25 {
         description "Initial revision";
     }
 
+    typedef otn-link-type {
+      type enumeration {
+        enum "OTU4" {
+          value 0;
+        }
+        enum "ODU4" {
+          value 1;
+        }
+        enum "ODTU4" {
+          value 2;
+        }
+        enum "ODU2e" {
+          value 3;
+        }
+        enum "ODU0" {
+          value 4;
+        }
+      }
+    }
+
     augment "/nd:networks/nd:network/nd:node/nwt:termination-point" {
         when "../../nd:network-types/cnet:openroadm-common-network/openroadm-topology or ../../nd:network-types/cnet:openroadm-common-network/otn-topology";
         description
@@ -40,4 +62,18 @@ module transportpce-topology {
             "The xpdr port connectable regarding the device connection-map";
         }
     }
+
+    augment "/nd:networks/nd:network/nwt:link" {
+        when "../nd:network-types/cnet:openroadm-common-network/otn-topology";
+        description
+          "Defines more accurate otn link types to differentiate otn links in otn-topology";
+        leaf otn-link-type {
+          when
+            "../cnet:link-type = 'OTN-LINK'";
+          type otn-link-type;
+          description
+              "type of otn link, to help link management inside transportpce";
+          }
+        }
+    }
 }
\ No newline at end of file
index 842529a5251fbccb31e68cd8a34d8f921ff64044..bb29feb6d4f49f9b474aa18c492af47f74f49943 100644 (file)
@@ -55,7 +55,7 @@ public class PcePathDescription {
     }
 
     public PceResult buildDescriptions() {
-        LOG.info("In buildDescriptions: AtoZ {}", pathAtoZ.toString());
+        LOG.info("In buildDescriptions: AtoZ =  {}", pathAtoZ.toString());
         List<AToZ> atozList = new ArrayList<AToZ>();
         if (pathAtoZ == null) {
             rc.setRC(ResponseCodes.RESPONSE_FAILED);
@@ -64,12 +64,16 @@ public class PcePathDescription {
         }
 
         buildAtoZ(atozList, pathAtoZ);
-
-        rc.setAtoZDirection(new AToZDirectionBuilder()
+        AToZDirectionBuilder atoZDirectionBldr = new AToZDirectionBuilder()
             .setRate(rc.getRate())
-            .setAToZWavelengthNumber(rc.getResultWavelength())
-            .setAToZ(atozList).build());
-
+            .setAToZ(atozList);
+        if ("100GE".equals(rc.getServiceType()) || "OTU4".equals(rc.getServiceType())) {
+            atoZDirectionBldr.setAToZWavelengthNumber(rc.getResultWavelength());
+        } else if ("10GE".equals(rc.getServiceType()) || "1GE".equals(rc.getServiceType())
+            || "ODU4".equals(rc.getServiceType())) {
+            atoZDirectionBldr.setAToZWavelengthNumber(Long.valueOf(0));
+        }
+        rc.setAtoZDirection(atoZDirectionBldr.build());
         pathZtoA = ImmutableList.copyOf(pathAtoZ).reverse();
         LOG.info("In buildDescriptions: ZtoA {}", pathZtoA.toString());
 
@@ -80,17 +84,21 @@ public class PcePathDescription {
             return rc;
         }
         buildZtoA(ztoaList, pathZtoA);
-
-        rc.setZtoADirection(new ZToADirectionBuilder()
+        ZToADirectionBuilder ztoADirectionBldr = new ZToADirectionBuilder()
             .setRate(rc.getRate())
-            .setZToAWavelengthNumber(rc.getResultWavelength())
-            .setZToA(ztoaList).build());
+            .setZToA(ztoaList);
+        if ("100GE".equals(rc.getServiceType()) || "OTU4".equals(rc.getServiceType())) {
+            ztoADirectionBldr.setZToAWavelengthNumber(rc.getResultWavelength());
+        } else if ("10GE".equals(rc.getServiceType()) || "1GE".equals(rc.getServiceType())
+            || "ODU4".equals(rc.getServiceType())) {
+            ztoADirectionBldr.setZToAWavelengthNumber(Long.valueOf(0));
+        }
+        rc.setZtoADirection(ztoADirectionBldr.build());
 
         return rc;
     }
 
     private void buildAtoZ(List<AToZ> etoeList, List<PceLink> path) {
-
         Integer index = 0;
         PceLink lastLink = null;
         AToZ lastResource = null;
index 202b42874aa28bb71a1e04aa0bb93218eadae2ff..cc05a3747d4803a97a417c6a5727bac25026c741 100644 (file)
@@ -10,7 +10,7 @@ package org.opendaylight.transportpce.pce.constraints;
 import java.util.ArrayList;
 import java.util.List;
 
-import org.opendaylight.transportpce.pce.networkanalyzer.PceNode;
+import org.opendaylight.transportpce.pce.networkanalyzer.PceOpticalNode;
 import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.routing.constraints.rev171017.RoutingConstraintsSp;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -40,7 +40,7 @@ public class PceConstraints {
 
     ///Structures related to INCLUDE constraints
     private List<String> nodesToInclude = new ArrayList<String>();
-    private List<PceNode> pceNodesToInclude = new ArrayList<PceNode>();
+    private List<PceOpticalNode> pceNodesToInclude = new ArrayList<PceOpticalNode>();
     private List<ResourcePair> listToInclude = new ArrayList<ResourcePair>();
 
     private List<String> srlgNames = new ArrayList<String>();
@@ -145,12 +145,12 @@ public class PceConstraints {
         nodesToInclude.addAll(nodes);
     }
 
-    public List<PceNode> getIncludePceNodes() {
+    public List<PceOpticalNode> getIncludePceNodes() {
         LOG.debug("in Pceconstraints getIncludePceNodes size = {}", pceNodesToInclude.size());
         return pceNodesToInclude;
     }
 
-    public void setIncludePceNode(PceNode node) {
+    public void setIncludePceNode(PceOpticalNode node) {
         LOG.info("in Pceconstraints setIncludePceNode new node = {}", node.toString());
         this.pceNodesToInclude.add(node);
     }
index c7733ddd5726f903a79cb8d54cc2e18916d48c04..279d23ef7be7748b18ad3a1b918a644db99364b3 100644 (file)
@@ -211,25 +211,13 @@ public class PceGraph {
     }
 
     private double chooseWeight(PceLink link) {
-
         // HopCount is default
         double weight = 1;
         switch (pceHardConstraints.getPceMetrics()) {
-            case IGPMetric :
-                // TODO implement IGPMetric - low priority.
-                LOG.warn("In PceGraph not implemented IGPMetric. HopCount works as a default");
-                break;
-
-            case TEMetric :
-                // TODO implement TEMetric - low priority
-                LOG.warn("In PceGraph not implemented TEMetric. HopCount works as a default");
-                break;
-
             case HopCount :
                 weight = 1;
                 LOG.debug("In PceGraph HopCount is used as a metrics. {}", link.toString());
                 break;
-
             case PropagationDelay :
                 weight = link.getLatency();
                 LOG.debug("In PceGraph PropagationDelay is used as a metrics. {}", link.toString());
@@ -239,11 +227,14 @@ public class PceGraph {
                         link.toString());
                 }
                 break;
-
+            // TODO implement IGPMetric and TEMetric - low priority.
+            case IGPMetric :
+            case TEMetric :
             default:
+                LOG.warn("In PceGraph {} not implemented. HopCount works as a default",
+                    pceHardConstraints.getPceMetrics());
                 break;
         }
-
         return weight;
     }
 
@@ -271,5 +262,4 @@ public class PceGraph {
         this.pceHardConstraints = pceHardConstraintsInput;
         this.pceSoftConstraints = pceSoftConstraintsInput;
     }
-
 }
index 1d28a2dd2c1e9a623355eb49a6b314e5bc7451f1..ce942e8cd1af31b6fa5c9433b7386aaf130cd16d 100644 (file)
@@ -9,6 +9,8 @@
 package org.opendaylight.transportpce.pce.graph;
 
 import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
 
@@ -17,7 +19,6 @@ import org.opendaylight.transportpce.common.ResponseCodes;
 import org.opendaylight.transportpce.pce.constraints.PceConstraints;
 import org.opendaylight.transportpce.pce.constraints.PceConstraints.ResourcePair;
 import org.opendaylight.transportpce.pce.networkanalyzer.PceNode;
-import org.opendaylight.transportpce.pce.networkanalyzer.PceOtnNode;
 import org.opendaylight.transportpce.pce.networkanalyzer.PceResult;
 import org.opendaylight.yang.gen.v1.http.org.openroadm.network.types.rev181130.OpenroadmLinkType;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.rev180226.NodeId;
@@ -44,73 +45,90 @@ public class PostAlgoPathValidator {
             pceResult.setRC(ResponseCodes.RESPONSE_FAILED);
             return pceResult;
         }
-        if (("100GE".equals(serviceType)) || ("OTU4".equals(serviceType))) {
-            // choose wavelength available in all nodes of the path
-            Long waveL = chooseWavelength(path, allPceNodes);
-            if (waveL < 0) {
-                pceResult.setRC(ResponseCodes.RESPONSE_FAILED);
-                pceResult.setLocalCause(PceResult.LocalCause.NO_PATH_EXISTS);
-                return pceResult;
-            }
-            pceResult.setResultWavelength(waveL);
-            LOG.info("In PostAlgoPathValidator: chooseWavelength WL found {} {}", waveL, path.toString());
 
-            // TODO here other post algo validations can be added
-            // more data can be sent to PceGraph module via PceResult structure if required
+        int tribSlotNb = 1;
+        //variable to deal wih 1GE (Nb=1) and 10GE (Nb=10) cases
+        switch (serviceType) {
 
-            // Check the OSNR
-            if (!checkOSNR(path)) {
-                pceResult.setRC(ResponseCodes.RESPONSE_FAILED);
-                pceResult.setLocalCause(PceResult.LocalCause.OUT_OF_SPEC_OSNR);
-                return pceResult;
-            }
+            case "100GE":
+            case "OTU4":
+                // choose wavelength available in all nodes of the path
+                Long waveL = chooseWavelength(path, allPceNodes);
+                pceResult.setServiceType(serviceType);
+                if (waveL < 0) {
+                    pceResult.setRC(ResponseCodes.RESPONSE_FAILED);
+                    pceResult.setLocalCause(PceResult.LocalCause.NO_PATH_EXISTS);
+                    return pceResult;
+                }
+                pceResult.setResultWavelength(waveL);
+                LOG.info("In PostAlgoPathValidator: chooseWavelength WL found {} {}", waveL, path.toString());
 
-            // Check if MaxLatency is defined in the hard constraints
-            if (pceHardConstraints.getMaxLatency() != -1) {
-                if (!checkLatency(pceHardConstraints.getMaxLatency(), path)) {
+                // TODO here other post algo validations can be added
+                // more data can be sent to PceGraph module via PceResult structure if required
+
+                // Check the OSNR
+                if (!checkOSNR(path)) {
+                    pceResult.setRC(ResponseCodes.RESPONSE_FAILED);
+                    pceResult.setLocalCause(PceResult.LocalCause.OUT_OF_SPEC_OSNR);
+                    return pceResult;
+                }
+
+                // Check if MaxLatency is defined in the hard constraints
+                if ((pceHardConstraints.getMaxLatency() != -1)
+                        && (!checkLatency(pceHardConstraints.getMaxLatency(), path))) {
                     pceResult.setRC(ResponseCodes.RESPONSE_FAILED);
                     pceResult.setLocalCause(PceResult.LocalCause.TOO_HIGH_LATENCY);
                     return pceResult;
                 }
-            }
 
-            // Check if nodes are included in the hard constraints
-            if (!checkInclude(path, pceHardConstraints)) {
+                // Check if nodes are included in the hard constraints
+                if (!checkInclude(path, pceHardConstraints)) {
+                    pceResult.setRC(ResponseCodes.RESPONSE_FAILED);
+                    pceResult.setLocalCause(PceResult.LocalCause.HD_NODE_INCLUDE);
+                    return pceResult;
+                }
+                pceResult.setRC(ResponseCodes.RESPONSE_OK);
+                break;
+
+            case "10GE":
+                tribSlotNb = 10;
+            //fallthrough
+            case "1GE":
                 pceResult.setRC(ResponseCodes.RESPONSE_FAILED);
-                pceResult.setLocalCause(PceResult.LocalCause.HD_NODE_INCLUDE);
-                return pceResult;
-            }
-            pceResult.setRC(ResponseCodes.RESPONSE_OK);
+                pceResult.setServiceType(serviceType);
+                Map<String, Integer> tribPort = chooseTribPort(path, allPceNodes);
+                Map<String, List<Integer>> tribSlot = chooseTribSlot(path, allPceNodes, tribSlotNb);
+
+                if (tribPort != null && tribSlot != null) {
+                    pceResult.setResultTribPort(tribPort);
+                    pceResult.setResultTribSlot(tribSlot);
+                    pceResult.setResultTribSlotNb(tribSlotNb);
+                    pceResult.setRC(ResponseCodes.RESPONSE_OK);
+                    LOG.info("In PostAlgoPathValidator: found TribPort {} - tribSlot {} - tribSlotNb {}",
+                        tribPort, tribSlot, tribSlotNb);
+                }
+                break;
 
-        } else if (("1GE".equals(serviceType)) || ("10GE".equals(serviceType))) {
-            // Path is at the OTN layer
-            pceResult.setRC(ResponseCodes.RESPONSE_FAILED);
-            // In a first step we select the first tribPort available on the first edge
-            // TODO : after the way to pass trib-ports and trib-slots to the renderer has
-            // been adapted to fit
-            // with multiple OTN Hops, each first available port shall be passed for each
-            // edge to Renderer
-            Integer tribPort = chooseTribPort(path, allPceNodes).get(0).get(0);
-            // TODO : Same comment apply for tribSlot
-            Integer tribSlot = chooseTribSlot(path, allPceNodes).get(0).get(0);
-
-            if (tribPort != null) {
-                // Temporarily we use wavelength-number to provide the TribPort
-                // TODO adapt the path-description
-                // TODO make the adaptation to return the first tribSlot in an intermediate
-                // phase
-                pceResult.setResultWavelength(tribPort);
+            case "ODU4":
                 pceResult.setRC(ResponseCodes.RESPONSE_OK);
-                LOG.info("In PostAlgoPathValidator: chooseTribPort TribPort found {} {}", tribPort, path.toString());
-            }
+                LOG.info("In PostAlgoPathValidator: ODU4 path found {}", path.toString());
+                break;
+
+            default:
+                pceResult.setRC(ResponseCodes.RESPONSE_FAILED);
+                LOG.warn("In PostAlgoPathValidator checkPath: unsupported serviceType {} found {}",
+                    serviceType, path.toString());
+                break;
         }
         return pceResult;
+
+        // TODO other post algo validations can be added anf if needed,
+        // more data can be sent to PceGraph module via PceResult structure
     }
 
     // Choose the first available wavelength from the source to the destination
     private Long chooseWavelength(GraphPath<String, PceGraphEdge> path, Map<NodeId, PceNode> allPceNodes) {
         Long wavelength = -1L;
-
         for (long i = 1; i <= MAX_WAWELENGTH; i++) {
             boolean completed = true;
             LOG.debug("In chooseWavelength: {} {}", path.getLength(), path.toString());
@@ -160,7 +178,7 @@ public class PostAlgoPathValidator {
         LOG.debug(" in checkInclude vertex list: [{}]", path.getVertexList());
 
         List<String> listOfElementsSubNode = new ArrayList<String>();
-        listOfElementsSubNode.add(pathEdges.get(0).link().getsourceSupNodeId());
+        listOfElementsSubNode.add(pathEdges.get(0).link().getsourceNetworkSupNodeId());
         listOfElementsSubNode.addAll(listOfElementsBuild(pathEdges, PceConstraints.ResourceType.NODE,
             pceHardConstraintsInput));
 
@@ -221,7 +239,7 @@ public class PostAlgoPathValidator {
         for (PceGraphEdge link : pathEdges) {
             switch (type) {
                 case NODE:
-                    listOfElements.add(link.link().getdestSupNodeId());
+                    listOfElements.add(link.link().getdestNetworkSupNodeId());
                     break;
                 case CLLI:
                     listOfElements.add(link.link().getdestCLLI());
@@ -231,7 +249,6 @@ public class PostAlgoPathValidator {
                         listOfElements.add("NONE");
                         break;
                     }
-
                     // srlg of link is List<Long>. But in this algo we need string representation of
                     // one SRLG
                     // this should be any SRLG mentioned in include constraints if any of them if
@@ -258,62 +275,81 @@ public class PostAlgoPathValidator {
         return listOfElements;
     }
 
-    private List<List<Integer>> chooseTribPort(GraphPath<String, PceGraphEdge> path, Map<NodeId, PceNode> allPceNodes) {
-        List<List<Integer>> tribPort = new ArrayList<>();
-        boolean statusOK = true;
-        boolean check = false;
-        Object nodeClass = allPceNodes.getClass();
-        if (nodeClass.getClass().isInstance(PceNode.class)) {
-            LOG.debug("In choosetribPort: AllPceNodes contains PceNode instance, no trib port search");
-            return tribPort;
-        } else if (nodeClass.getClass().isInstance(PceOtnNode.class)) {
-            LOG.debug("In choosetribPort: {} {}", path.getLength(), path.toString());
-            for (PceGraphEdge edge : path.getEdgeList()) {
-                LOG.debug("In chooseTribPort: source {} ", edge.link().getSourceId().toString());
-                PceNode pceNode = allPceNodes.get(edge.link().getSourceId());
-                Object tps = allPceNodes.get(edge.link().getSourceTP());
-                Object tpd = allPceNodes.get(edge.link().getDestTP());
-                if ((pceNode.getAvailableTribPorts().containsKey(tps.toString()))
-                    && (pceNode.getAvailableTribPorts().containsKey(tpd.toString()))) {
-
-                    List<Integer> tribPortEdgeSourceN = new ArrayList<>();
-                    List<Integer> tribPortEdgeDestN = new ArrayList<>();
-                    tribPortEdgeSourceN = pceNode.getAvailableTribPorts().get(tps.toString());
-                    tribPortEdgeDestN = pceNode.getAvailableTribPorts().get(tps.toString());
-                    check = false;
-                    for (int i = 0; i <= 9; i++) {
-                        if (tribPortEdgeSourceN.get(i) == null) {
-                            break;
-                        }
-                        if (tribPortEdgeSourceN.get(i) == tribPortEdgeDestN.get(i)) {
-                            check = true;
-                        } else {
-                            check = false;
-                            LOG.debug("In chooseTribPort: Misalignement of trib port between source {}  and dest {}",
-                                edge.link().getSourceId().toString(), edge.link().getDestId().toString());
-                            break;
-                        }
-                    }
-                    if (check) {
-                        tribPort.add(tribPortEdgeSourceN);
-                    }
-                } else {
-                    LOG.debug("In chooseTribPort: source {} does not have provisonned hosting HO interface ",
-                        edge.link().getSourceId().toString());
-                    statusOK = false;
+    private Map<String, Integer> chooseTribPort(GraphPath<String,
+        PceGraphEdge> path, Map<NodeId, PceNode> allPceNodes) {
+        LOG.info("In choosetribPort: edgeList = {} ", path.getEdgeList().toString());
+        Map<String, Integer> tribPortMap = new HashMap<>();
+
+        for (PceGraphEdge edge : path.getEdgeList()) {
+            NodeId linkSrcNode = edge.link().getSourceId();
+            String linkSrcTp = edge.link().getSourceTP().toString();
+            NodeId linkDestNode = edge.link().getDestId();
+            String linkDestTp = edge.link().getDestTP().toString();
+            PceNode pceOtnNodeSrc = allPceNodes.get(linkSrcNode);
+            PceNode pceOtnNodeDest = allPceNodes.get(linkDestNode);
+            List<Integer> srcTpnPool = pceOtnNodeSrc.getAvailableTribPorts().get(linkSrcTp);
+            List<Integer> destTpnPool = pceOtnNodeDest.getAvailableTribPorts().get(linkDestTp);
+            List<Integer> commonEdgeTpnPool = new ArrayList<>();
+            for (Integer integer : srcTpnPool) {
+                if (destTpnPool.contains(integer)) {
+                    commonEdgeTpnPool.add(integer);
                 }
             }
+            Collections.sort(commonEdgeTpnPool);
+            if (!commonEdgeTpnPool.isEmpty()) {
+                tribPortMap.put(edge.link().getLinkId().getValue(), commonEdgeTpnPool.get(0));
+            }
         }
-        if (statusOK && check) {
-            return tribPort;
-        } else {
-            tribPort.clear();
-            return tribPort;
-        }
+        tribPortMap.forEach((k,v) -> LOG.info("TribPortMap : k = {}, v = {}", k, v));
+        return tribPortMap;
+    }
 
+    private Map<String, List<Integer>> chooseTribSlot(GraphPath<String,
+        PceGraphEdge> path, Map<NodeId, PceNode> allPceNodes, int nbSlot) {
+        LOG.info("In choosetribSlot2: edgeList = {} ", path.getEdgeList().toString());
+        Map<String, List<Integer>> tribSlotMap = new HashMap<>();
+
+        for (PceGraphEdge edge : path.getEdgeList()) {
+            NodeId linkSrcNode = edge.link().getSourceId();
+            String linkSrcTp = edge.link().getSourceTP().toString();
+            NodeId linkDestNode = edge.link().getDestId();
+            String linkDestTp = edge.link().getDestTP().toString();
+            PceNode pceOtnNodeSrc = allPceNodes.get(linkSrcNode);
+            PceNode pceOtnNodeDest = allPceNodes.get(linkDestNode);
+            List<Integer> srcTsPool = pceOtnNodeSrc.getAvailableTribSlots().get(linkSrcTp);
+            List<Integer> destTsPool = pceOtnNodeDest.getAvailableTribSlots().get(linkDestTp);
+            List<Integer> commonEdgeTsPool = new ArrayList<>();
+            List<Integer> tribSlotList = new ArrayList<>();
+            for (Integer integer : srcTsPool) {
+                if (destTsPool.contains(integer)) {
+                    commonEdgeTsPool.add(integer);
+                }
+            }
+            Collections.sort(commonEdgeTsPool);
+            boolean discontinue = true;
+            int index = 0;
+            while (discontinue && (commonEdgeTsPool.size() - index >= nbSlot)) {
+                discontinue = false;
+                Integer val = commonEdgeTsPool.get(index);
+                for (int i = 0; i < nbSlot; i++) {
+                    if (commonEdgeTsPool.get(index + i).equals(val + i)) {
+                        tribSlotList.add(commonEdgeTsPool.get(index + i));
+                    } else {
+                        discontinue = true;
+                        tribSlotList.clear();
+                        index += i;
+                        break;
+                    }
+                }
+            }
+            tribSlotMap.put(edge.link().getLinkId().getValue(), tribSlotList);
+        }
+        tribSlotMap.forEach((k,v) -> LOG.info("TribSlotMap : k = {}, v = {}", k, v));
+        return tribSlotMap;
     }
 
-    private List<List<Integer>> chooseTribSlot(GraphPath<String, PceGraphEdge> path, Map<NodeId, PceNode> allPceNodes) {
+    private List<List<Integer>> chooseTribSlot3(GraphPath<String, PceGraphEdge> path,
+        Map<NodeId, PceNode> allPceNodes) {
         List<List<Integer>> tribSlot = new ArrayList<>();
         boolean statusOK = true;
         boolean check = false;
@@ -321,45 +357,44 @@ public class PostAlgoPathValidator {
         if (nodeClass.getClass().isInstance(PceNode.class)) {
             LOG.debug("In choosetribSlot: AllPceNodes contains PceNode instance, no trib port search");
             return tribSlot;
-        } else if (nodeClass.getClass().isInstance(PceOtnNode.class)) {
+        } else if (nodeClass.getClass().isInstance(PceNode.class)) {
             LOG.debug("In choosetribPort: {} {}", path.getLength(), path.toString());
-            for (PceGraphEdge edge : path.getEdgeList()) {
-                LOG.debug("In chooseTribSlot: source {} ", edge.link().getSourceId().toString());
-                PceNode pceNode = allPceNodes.get(edge.link().getSourceId());
-                Object tps = allPceNodes.get(edge.link().getSourceTP());
-                Object tpd = allPceNodes.get(edge.link().getDestTP());
-                if ((pceNode.getAvailableTribSlots().containsKey(tps.toString()))
-                    && (pceNode.getAvailableTribSlots().containsKey(tpd.toString()))) {
-
-                    List<Integer> tribSlotEdgeSourceN = new ArrayList<>();
-                    List<Integer> tribSlotEdgeDestN = new ArrayList<>();
-                    tribSlotEdgeSourceN = pceNode.getAvailableTribSlots().get(tps.toString());
-                    tribSlotEdgeDestN = pceNode.getAvailableTribSlots().get(tps.toString());
-                    check = false;
-                    for (int i = 0; i <= 79; i++) {
-                        if (tribSlotEdgeSourceN.get(i) == null) {
-                            break;
-                        }
-                        // TODO This will need to be modified as soon as the trib-slots allocation per
-                        // trib-port
-                        // policy applied by the different manufacturer is known
-                        if (tribSlotEdgeSourceN.get(i) == tribSlotEdgeDestN.get(i)) {
-                            check = true;
-                        } else {
-                            check = false;
-                            LOG.debug("In chooseTribSlot: Misalignement of trib slots between source {}  and dest {}",
-                                edge.link().getSourceId().toString(), edge.link().getDestId().toString());
-                            break;
-                        }
+        }
+        for (PceGraphEdge edge : path.getEdgeList()) {
+            LOG.debug("In chooseTribSlot: source {} ", edge.link().getSourceId().toString());
+            PceNode pceNode = allPceNodes.get(edge.link().getSourceId());
+            Object tps = allPceNodes.get(edge.link().getSourceTP());
+            Object tpd = allPceNodes.get(edge.link().getDestTP());
+            if ((pceNode.getAvailableTribSlots().containsKey(tps.toString()))
+                && (pceNode.getAvailableTribSlots().containsKey(tpd.toString()))) {
+                List<Integer> tribSlotEdgeSourceN = new ArrayList<>();
+                List<Integer> tribSlotEdgeDestN = new ArrayList<>();
+                tribSlotEdgeSourceN = pceNode.getAvailableTribSlots().get(tps.toString());
+                tribSlotEdgeDestN = pceNode.getAvailableTribSlots().get(tps.toString());
+                check = false;
+                for (int i = 0; i <= 79; i++) {
+                    if (tribSlotEdgeSourceN.get(i) == null) {
+                        break;
                     }
-                    if (check) {
-                        tribSlot.add(tribSlotEdgeSourceN);
+                    // TODO This will need to be modified as soon as the trib-slots allocation per
+                    // trib-port
+                    // policy applied by the different manufacturer is known
+                    if (tribSlotEdgeSourceN.get(i) == tribSlotEdgeDestN.get(i)) {
+                        check = true;
+                    } else {
+                        check = false;
+                        LOG.debug("In chooseTribSlot: Misalignement of trib slots between source {} and dest {}",
+                            edge.link().getSourceId().toString(), edge.link().getDestId().toString());
+                        break;
                     }
-                } else {
-                    LOG.debug("In chooseTribSlot: source {} does not have provisonned hosting HO interface ",
-                        edge.link().getSourceId().toString());
-                    statusOK = false;
                 }
+                if (check) {
+                    tribSlot.add(tribSlotEdgeSourceN);
+                }
+            } else {
+                LOG.debug("In chooseTribSlot: source {} does not have provisonned hosting HO interface ",
+                    edge.link().getSourceId().toString());
+                statusOK = false;
             }
         }
         if (statusOK && check) {
@@ -368,7 +403,6 @@ public class PostAlgoPathValidator {
             tribSlot.clear();
             return tribSlot;
         }
-
     }
 
     // Check the path OSNR
index 54868a35ecf4d43305a4a91c800f45e1f104587c..4db6dbb5baed4b59cdbd8c4a9c97d55279d15a31 100644 (file)
@@ -48,7 +48,7 @@ public final class MapUtils {
 
             if (excNodes.contains(node.getNodeId().getValue())) {
                 LOG.debug("mapDiversityConstraints setExcludeSupNodes for node {}", node.getNodeId().getValue());
-                pceHardConstraints.setExcludeSupNodes(Arrays.asList(getSupNode(node)));
+                pceHardConstraints.setExcludeSupNodes(Arrays.asList(getSupNetworkNode(node)));
             }
         }
 
@@ -116,7 +116,7 @@ public final class MapUtils {
         return srlgList;
     }
 
-    public static String getSupNode(Node node) {
+    public static String getSupNetworkNode(Node node) {
         List<SupportingNode> supNodes = node.getSupportingNode();
         for (SupportingNode snode : supNodes) {
             if (NetworkUtils.UNDERLAY_NETWORK_ID.equals(snode.getNetworkRef().getValue())) {
@@ -126,6 +126,16 @@ public final class MapUtils {
         return null;
     }
 
+    public static String getSupClliNode(Node node) {
+        List<SupportingNode> supNodes = node.getSupportingNode();
+        for (SupportingNode snode : supNodes) {
+            if (NetworkUtils.CLLI_NETWORK_ID.equals(snode.getNetworkRef().getValue())) {
+                return snode.getNodeRef().getValue();
+            }
+        }
+        return null;
+    }
+
     public static TreeMap<String, String> getAllSupNode(Node node) {
         TreeMap<String, String> allSupNodes = new TreeMap<String, String>();
         List<SupportingNode> supNodes = new ArrayList<SupportingNode>();
@@ -153,38 +163,29 @@ public final class MapUtils {
 
 
     public static Long getAvailableBandwidth(Link link) {
-        Link1 link1 = null;
-        Long availableBW  = 0L;
-        // ID and type
-        link1 = link.augmentation(Link1.class);
-        if (link1 == null) {
-            LOG.error("MapUtils: No Link augmentation available. {}", link.getLinkId().getValue());
-            return availableBW;
+        if (link.augmentation(org.opendaylight.yang.gen.v1.http.org.openroadm.otn.network.topology.rev181130
+            .Link1.class) != null
+            && link.augmentation(org.opendaylight.yang.gen.v1.http.org.openroadm.otn.network.topology.rev181130
+                .Link1.class).getAvailableBandwidth() != null) {
+            return link.augmentation(org.opendaylight.yang.gen.v1.http.org.openroadm.otn.network.topology.rev181130
+                .Link1.class).getAvailableBandwidth();
         } else {
-            OpenroadmLinkType tmplType = null;
-            tmplType = link1.getLinkType();
-            if (tmplType == null) {
-                LOG.error("MapUtils: No Link type available. {}", link.getLinkId().getValue());
-                return null;
-            } else if (tmplType == OpenroadmLinkType.OTNLINK) {
-                org.opendaylight.yang.gen.v1.http.org.openroadm.otn.network.topology.rev181130.Link1 link11 =
-                    link.augmentation(
-                        org.opendaylight.yang.gen.v1.http.org.openroadm.otn.network.topology.rev181130.Link1.class);
-                if (link11 == null) {
-                    LOG.error("MapUtils: No Link augmentation available for {}", link.getLinkId().getValue());
-                    return availableBW;
-                } else {
-                    availableBW = link11.getAvailableBandwidth();
-                    return availableBW;
-                }
-
-            } else {
-                LOG.error("MapUtils: Evaluated Link is not of OTN Type");
-            }
+            LOG.warn("MapUtils: no Available Bandwidth available for link {}", link.getLinkId());
+            return 0L;
         }
+    }
 
-
-        return 0L;
+    public static Long getUsedBandwidth(Link link) {
+        if (link.augmentation(org.opendaylight.yang.gen.v1.http.org.openroadm.otn.network.topology.rev181130
+            .Link1.class) != null
+            && link.augmentation(org.opendaylight.yang.gen.v1.http.org.openroadm.otn.network.topology.rev181130
+                .Link1.class).getUsedBandwidth() != null) {
+            return link.augmentation(org.opendaylight.yang.gen.v1.http.org.openroadm.otn.network.topology.rev181130
+                .Link1.class).getUsedBandwidth();
+        } else {
+            LOG.warn("MapUtils: no Available Bandwidth available for link {}", link.getLinkId());
+            return 0L;
+        }
     }
 
     public static OpenroadmLinkType calcType(Link link) {
index 61f288e00e26e0183d7862808509f82fa2b99f0e..0ec90b7c81b2c609c711a2c199b711e79ee15a99 100644 (file)
@@ -114,6 +114,11 @@ public class PceCalculation {
     private boolean parseInput() {
         anodeId = input.getServiceAEnd().getNodeId();
         znodeId = input.getServiceZEnd().getNodeId();
+        if (input.getServiceAEnd().getServiceFormat() == null || input.getServiceZEnd().getServiceFormat() == null
+            || input.getServiceAEnd().getServiceRate() == null) {
+            LOG.error("Service Format and Service Rate are required for a path calculation");
+            return false;
+        }
         serviceFormatA = input.getServiceAEnd().getServiceFormat().getName();
         serviceFormatZ = input.getServiceZEnd().getServiceFormat().getName();
         serviceRate = input.getServiceAEnd().getServiceRate();
@@ -170,7 +175,8 @@ public class PceCalculation {
             LOG.info("readMdSal: network {}", NetworkUtils.OVERLAY_NETWORK_ID);
             nwInstanceIdentifier = InstanceIdentifier.builder(Networks.class)
                 .child(Network.class, new NetworkKey(new NetworkId(NetworkUtils.OVERLAY_NETWORK_ID))).build();
-        } else if ("ODU".equals(serviceFormatA)) {
+        } else if ("ODU".equals(serviceFormatA) || ("Ethernet".equals(serviceFormatA) && serviceRate == 10L)
+            || ("Ethernet".equals(serviceFormatA) && serviceRate == 1L)) {
             LOG.info("readMdSal: network {}", NetworkUtils.OTN_NETWORK_ID);
             nwInstanceIdentifier = InstanceIdentifier.builder(Networks.class)
                 .child(Network.class, new NetworkKey(new NetworkId(NetworkUtils.OTN_NETWORK_ID))).build();
@@ -202,9 +208,12 @@ public class PceCalculation {
         allNodes = nw.getNode().stream().sorted((n1, n2) -> n1.getNodeId().getValue().compareTo(n2.getNodeId()
             .getValue())).collect(Collectors.toList());
         Network1 nw1 = nw.augmentation(Network1.class);
-
-        allLinks = nw1.getLink().stream().sorted((l1, l2) -> l1.getSource().getSourceTp().toString().compareTo(l2
-            .getSource().getSourceTp().toString())).collect(Collectors.toList());
+        if (nw1 != null) {
+            allLinks = nw1.getLink().stream().sorted((l1, l2) -> l1.getSource().getSourceTp().toString().compareTo(l2
+                .getSource().getSourceTp().toString())).collect(Collectors.toList());
+        } else {
+            LOG.warn("no otn links in otn-topology");
+        }
         if (allNodes == null || allNodes.isEmpty()) {
             LOG.error("readMdSal: no nodes ");
             return false;
@@ -258,31 +267,17 @@ public class PceCalculation {
 
         } else {
             // ODU4, 10GE/ODU2e or 1GE/ODU0 services are handled at openroadm-otn layer
-            OpenroadmNodeType typeOfNode = null;
+
             for (Node node : allNodes) {
-                String nodeId = node.getNodeId().getValue();
-                if (this.anodeId.equals(nodeId) || (this.znodeId.equals(nodeId))) {
-                    typeOfNode = validateOtnNode(node, "AZ");
-                }
+                validateOtnNode(node);
             }
-            if (typeOfNode == null) {
+
+            LOG.info("analyzeNw: allPceNodes {}", allPceNodes.toString());
+
+            if (aendPceNode == null || zendPceNode == null) {
                 LOG.error("analyzeNw: Error in reading nodes: A or Z do not present in the network");
-            } else if (typeOfNode == OpenroadmNodeType.MUXPDR) {
-                LOG.debug("analyzeNw: A/Z end node are of muxponder type, no intermediate switch allowed on the path");
-            } else {
-                LOG.debug("analyzeNw: A/Z end node are of switch type, searching for potential intermediate switch");
-                for (Node node : allNodes) {
-                    String nodeId = node.getNodeId().getValue();
-                    if (!(this.anodeId.equals(nodeId) || (this.znodeId.equals(nodeId)))) {
-                        // A and Z node have been validated, then if A and Z end nodes are not muxponders
-                        // we allow intermediate switch on the path
-                        typeOfNode = validateOtnNode(node, "intermediate");
-                    }
-                    // else : typeOfNode is MUXPDR and we do not authorize any intermediate switch on the path
-                    // TODO : handle regens and authorize them on the path if needed
-                }
+                return false;
             }
-
             for (Link link : allLinks) {
                 validateLink(link);
             }
@@ -337,13 +332,7 @@ public class PceCalculation {
     }
 
     private boolean validateLink(Link link) {
-
-        LOG.debug("validateLink: link {} ", link.toString());
-
-        if (linksToExclude.contains(link.getLinkId())) {
-            LOG.info("validateLink: Link is ignored due opposite link problem - {}", link.getLinkId().getValue());
-            return false;
-        }
+        LOG.info("validateLink: link {} ", link.toString());
 
         NodeId sourceId = link.getSource().getSourceNode();
         NodeId destId = link.getDestination().getDestNode();
@@ -387,12 +376,12 @@ public class PceCalculation {
                         pcelink.getlinkType(), pcelink.toString());
                     break;
                 case ADDLINK:
-                    pcelink.setClient(source.getRdmSrgClient(pcelink.getSourceTP().toString(), true));
+                    pcelink.setClient(source.getRdmSrgClient(pcelink.getSourceTP().toString()));
                     addLinks.add(pcelink);
                     LOG.debug("validateLink: ADD-LINK saved  {}", pcelink.toString());
                     break;
                 case DROPLINK:
-                    pcelink.setClient(dest.getRdmSrgClient(pcelink.getDestTP().toString(), false));
+                    pcelink.setClient(dest.getRdmSrgClient(pcelink.getDestTP().toString()));
                     dropLinks.add(pcelink);
                     LOG.debug("validateLink: DROP-LINK saved  {}", pcelink.toString());
                     break;
@@ -405,7 +394,9 @@ public class PceCalculation {
                             "validateLink: XPONDER-INPUT is rejected as NW port is busy - {} ", pcelink.toString());
                         return false;
                     }
-                    pcelink.setClient(dest.getClient(pcelink.getDestTP().toString()));
+                    if (dest.getXpdrClient(pcelink.getDestTP().toString()) != null) {
+                        pcelink.setClient(dest.getXpdrClient(pcelink.getDestTP().toString()));
+                    }
                     allPceLinks.put(linkId, pcelink);
                     source.addOutgoingLink(pcelink);
                     LOG.debug("validateLink: XPONDER-INPUT link added to allPceLinks {}", pcelink.toString());
@@ -420,7 +411,9 @@ public class PceCalculation {
                             "validateLink: XPONDER-OUTPUT is rejected as NW port is busy - {} ", pcelink.toString());
                         return false;
                     }
-                    pcelink.setClient(source.getClient(pcelink.getSourceTP().toString()));
+                    if (source.getXpdrClient(pcelink.getSourceTP().toString()) != null) {
+                        pcelink.setClient(source.getXpdrClient(pcelink.getSourceTP().toString()));
+                    }
                     allPceLinks.put(linkId, pcelink);
                     source.addOutgoingLink(pcelink);
                     LOG.debug("validateLink: XPONDER-OUTPUT link added to allPceLinks {}", pcelink.toString());
@@ -451,9 +444,13 @@ public class PceCalculation {
             }
             switch (pceOtnLink.getlinkType()) {
                 case OTNLINK:
+                    if (dest.getXpdrClient(pceOtnLink.getDestTP().toString()) != null) {
+                        pceOtnLink.setClient(dest.getXpdrClient(pceOtnLink.getDestTP().toString()));
+                    }
+
                     allPceLinks.put(linkId, pceOtnLink);
                     source.addOutgoingLink(pceOtnLink);
-                    LOG.debug("validateLink: OTN-LINK added to allPceLinks {}", pceOtnLink.toString());
+                    LOG.info("validateLink: OTN-LINK added to allPceLinks {}", pceOtnLink.toString());
                     break;
                 default:
                     LOG.warn("validateLink: link type is not supported {}", pceOtnLink.toString());
@@ -477,7 +474,8 @@ public class PceCalculation {
         }
         OpenroadmNodeType nodeType = node1.getNodeType();
 
-        PceNode pceNode = new PceNode(node, nodeType, node.getNodeId());
+        PceOpticalNode pceNode = new PceOpticalNode(node, nodeType, node.getNodeId(),
+            input.getServiceAEnd().getServiceFormat(), "optical");
         pceNode.validateAZxponder(anodeId, znodeId);
         pceNode.initWLlist();
 
@@ -493,11 +491,11 @@ public class PceCalculation {
             default:
                 break;
         }
-        if ((pceNode.getSupNetworkNodeIdPceNode().equals(anodeId) && (this.aendPceNode == null))
+        if ((pceNode.getSupNetworkNodeId().equals(anodeId) && (this.aendPceNode == null))
             && (endPceNode(nodeType, pceNode.getNodeId(), pceNode))) {
             this.aendPceNode = pceNode;
         }
-        if ((pceNode.getSupNetworkNodeIdPceNode().equals(znodeId) && (this.zendPceNode == null))
+        if ((pceNode.getSupNetworkNodeId().equals(znodeId) && (this.zendPceNode == null))
             && (endPceNode(nodeType, pceNode.getNodeId(), pceNode))) {
             this.zendPceNode = pceNode;
         }
@@ -507,66 +505,62 @@ public class PceCalculation {
         return true;
     }
 
-    private OpenroadmNodeType validateOtnNode(Node node, String mode) {
+    private boolean validateOtnNode(Node node) {
 
-        LOG.debug("validateNode: node {} ", node.toString());
+        LOG.info("validateOtnNode: {} ", node.getNodeId().getValue());
         // PceOtnNode will be used in Graph algorithm
-        Node1 node1 = node.augmentation(Node1.class);
-        if (node1 == null) {
-            LOG.error("getNodeType: no Node1 (type) Augmentation for node: [{}]. Node is ignored", node.getNodeId());
-        }
-        OpenroadmNodeType nodeType = node1.getNodeType();
+        if (node.augmentation(Node1.class) != null) {
+            OpenroadmNodeType nodeType = node.augmentation(Node1.class).getNodeType();
 
-        PceOtnNode pceOtnNode = new PceOtnNode(node, nodeType, node.getNodeId(), serviceType);
-        if (mode == "AZ") {
-            pceOtnNode.validateAZxponder(anodeId, znodeId);
-        } else if (mode == "intermediate") {
-            pceOtnNode.validateIntermediateSwitch();
-        } else {
-            LOG.error("validateOtnNode: unproper mode passed to the method : {} not supported", mode);
-            return null;
-        }
-
-        if (!pceOtnNode.isValid()) {
-            LOG.warn(" validateNode: Node is ignored");
-            return null;
-        }
-
-        switch (validateNodeConstraints(pceOtnNode)) {
-            case HARD_EXCLUDE:
-                return null;
-
-            default:
-                break;
-        }
+            PceOtnNode pceOtnNode = new PceOtnNode(node, nodeType, node.getNodeId(), "otn", serviceType);
+            pceOtnNode.validateXponder(anodeId, znodeId);
 
-        if ((pceOtnNode.getNodeId().equals(anodeId))) {
-            this.aendPceNode = pceOtnNode;
-        }
-        if ((pceOtnNode.getNodeId().equals(znodeId))) {
-            this.zendPceNode = pceOtnNode;
+            if (!pceOtnNode.isValid()) {
+                LOG.warn(" validateOtnNode: Node {} is ignored", node.getNodeId().getValue());
+                return false;
+            }
+            switch (validateNodeConstraints(pceOtnNode)) {
+                case HARD_EXCLUDE:
+                    return false;
+                default:
+                    break;
+            }
+            if (pceOtnNode.getNodeId().getValue().equals(anodeId) && this.aendPceNode == null) {
+                this.aendPceNode = pceOtnNode;
+            }
+            if (pceOtnNode.getNodeId().getValue().equals(znodeId) && this.zendPceNode == null) {
+                this.zendPceNode = pceOtnNode;
+            }
+            allPceNodes.put(pceOtnNode.getNodeId(), pceOtnNode);
+            LOG.info("validateOtnNode: node {} is saved", node.getNodeId().getValue());
+            return true;
+        } else {
+            LOG.error("ValidateOtnNode: no node-type augmentation. Node {} is ignored", node.getNodeId().getValue());
+            return false;
         }
 
-        allPceNodes.put(pceOtnNode.getNodeId(), pceOtnNode);
-        LOG.debug("validateNode: node is saved {}", pceOtnNode.getNodeId().getValue());
-        return nodeType;
+//        if (mode == "AZ") {
+//            pceOtnNode.validateAZxponder(anodeId, znodeId);
+//        } else if (mode == "intermediate") {
+//            pceOtnNode.validateIntermediateSwitch();
+//        } else {
+//            LOG.error("validateOtnNode: unproper mode passed to the method : {} not supported", mode);
+//            return null;
+//        }
     }
 
     private ConstraintTypes validateNodeConstraints(PceNode pcenode) {
-
         if (pceHardConstraints.getExcludeSupNodes().isEmpty() && pceHardConstraints.getExcludeCLLI().isEmpty()) {
             return ConstraintTypes.NONE;
         }
-
-        if (pceHardConstraints.getExcludeSupNodes().contains(pcenode.getSupNetworkNodeIdPceNode())) {
+        if (pceHardConstraints.getExcludeSupNodes().contains(pcenode.getSupNetworkNodeId())) {
             LOG.info("validateNodeConstraints: {}", pcenode.getNodeId().getValue());
             return ConstraintTypes.HARD_EXCLUDE;
         }
-        if (pceHardConstraints.getExcludeCLLI().contains(pcenode.getCLLI())) {
+        if (pceHardConstraints.getExcludeCLLI().contains(pcenode.getSupClliNodeId())) {
             LOG.info("validateNodeConstraints: {}", pcenode.getNodeId().getValue());
             return ConstraintTypes.HARD_EXCLUDE;
         }
-
         return ConstraintTypes.NONE;
     }
 
@@ -601,7 +595,7 @@ public class PceCalculation {
         }
     }
 
-    private Boolean endPceNode(OpenroadmNodeType openroadmNodeType, NodeId nodeId, PceNode pceNode) {
+    private Boolean endPceNode(OpenroadmNodeType openroadmNodeType, NodeId nodeId, PceOpticalNode pceNode) {
         switch (openroadmNodeType) {
             case SRG:
                 pceNode.initSrgTps();
@@ -654,5 +648,4 @@ public class PceCalculation {
             LOG.info("In printNodes in node {} : outgoing links {} ", pcenode.getNodeId().getValue(), links.toString());
         }
     }
-
 }
index 9929b4dc02ba90e0e6052372056dc41b2ca33c8e..0a2159484e271882bfef084c2be86b14381ff4bb 100644 (file)
@@ -14,6 +14,7 @@ import org.opendaylight.yang.gen.v1.http.org.openroadm.common.network.rev181130.
 import org.opendaylight.yang.gen.v1.http.org.openroadm.link.rev181130.span.attributes.LinkConcatenation.FiberType;
 import org.opendaylight.yang.gen.v1.http.org.openroadm.network.topology.rev181130.networks.network.link.oms.attributes.Span;
 import org.opendaylight.yang.gen.v1.http.org.openroadm.network.types.rev181130.OpenroadmLinkType;
+import org.opendaylight.yang.gen.v1.http.transportpce.topology.rev200129.OtnLinkType;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.rev180226.NodeId;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.topology.rev180226.LinkId;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.topology.rev180226.networks.network.Link;
@@ -41,8 +42,6 @@ public class PceLink {
     private final NodeId destId;
     private final Object sourceTP;
     private final Object destTP;
-    private final String sourceSupNodeId;
-    private final String destSupNodeId;
     private final String sourceNetworkSupNodeId;
     private final String destNetworkSupNodeId;
     private final String sourceCLLI;
@@ -50,6 +49,7 @@ public class PceLink {
     private final LinkId oppositeLink;
     private final Long latency;
     private final Long availableBandwidth;
+    private final Long usedBandwidth;
     private final List<Long> srlgList;
     private final double osnr;
     private final Span omsAttributesSpan;
@@ -60,7 +60,7 @@ public class PceLink {
     private static final double LOWER_BOUND_OSNR = 0.1;
 
     public PceLink(Link link, PceNode source, PceNode dest) {
-        LOG.debug("PceLink: : PceLink start ");
+        LOG.info("PceLink: : PceLink start ");
 
         this.linkId = link.getLinkId();
 
@@ -70,13 +70,11 @@ public class PceLink {
         this.sourceTP = link.getSource().getSourceTp();
         this.destTP = link.getDestination().getDestTp();
 
-        this.sourceSupNodeId = source.getSupNodeIdPceNode();
-        this.destSupNodeId = dest.getSupNodeIdPceNode();
-        this.sourceNetworkSupNodeId = source.getSupNetworkNodeIdPceNode();
-        this.destNetworkSupNodeId = dest.getSupNetworkNodeIdPceNode();
+        this.sourceNetworkSupNodeId = source.getSupNetworkNodeId();
+        this.destNetworkSupNodeId = dest.getSupNetworkNodeId();
 
-        this.sourceCLLI = source.getClliSupNodeId();
-        this.destCLLI = dest.getClliSupNodeId();
+        this.sourceCLLI = source.getSupClliNodeId();
+        this.destCLLI = dest.getSupClliNodeId();
 
         this.linkType = MapUtils.calcType(link);
 
@@ -88,8 +86,10 @@ public class PceLink {
             this.latency = calcLatency(link);
             this.osnr = calcSpanOSNR();
             this.availableBandwidth = 0L;
+            this.usedBandwidth = 0L;
         } else if (this.linkType == OpenroadmLinkType.OTNLINK) {
             this.availableBandwidth = MapUtils.getAvailableBandwidth(link);
+            this.usedBandwidth = MapUtils.getUsedBandwidth(link);
             this.srlgList = MapUtils.getSRLGfromLink(link);
             this.osnr = 0.0;
             this.latency = 0L;
@@ -100,6 +100,7 @@ public class PceLink {
             this.latency = 0L;
             this.osnr = 100L; //infinite OSNR in DB
             this.availableBandwidth = 0L;
+            this.usedBandwidth = 0L;
         }
         LOG.debug("PceLink: created PceLink  {}", toString());
     }
@@ -228,19 +229,14 @@ public class PceLink {
         return availableBandwidth;
     }
 
-
-    public String getsourceSupNodeId() {
-        return sourceSupNodeId;
+    public Long getUsedBandwidth() {
+        return availableBandwidth;
     }
 
     public String getsourceNetworkSupNodeId() {
         return sourceNetworkSupNodeId;
     }
 
-    public String getdestSupNodeId() {
-        return destSupNodeId;
-    }
-
     public String getdestNetworkSupNodeId() {
         return destNetworkSupNodeId;
     }
@@ -262,17 +258,15 @@ public class PceLink {
     }
 
     public boolean isValid() {
-        if ((this.linkId == null) || (this.linkType == null)
-                || (this.oppositeLink == null)) {
+        if ((this.linkId == null) || (this.linkType == null) || (this.oppositeLink == null)) {
             isValid = false;
             LOG.error("PceLink: No Link type or opposite link is available. Link is ignored {}", linkId);
         }
-        if ((this.sourceId == null) || (this.destId == null)
-                || (this.sourceTP == null) || (this.destTP == null)) {
+        if ((this.sourceId == null) || (this.destId == null) || (this.sourceTP == null) || (this.destTP == null)) {
             isValid = false;
             LOG.error("PceLink: No Link source or destination is available. Link is ignored {}", linkId);
         }
-        if ((this.sourceSupNodeId.equals("")) || (this.destSupNodeId.equals(""))) {
+        if ((this.sourceNetworkSupNodeId.equals("")) || (this.destNetworkSupNodeId.equals(""))) {
             isValid = false;
             LOG.error("PceLink: No Link source SuppNodeID or destination SuppNodeID is available. Link is ignored {}",
                 linkId);
@@ -292,60 +286,80 @@ public class PceLink {
         return isValid;
     }
 
-    public boolean isOtnValid(Link link, String oduType) {
-        if (this.linkType == OpenroadmLinkType.OTNLINK) {
-            isOtnValid = false;
-            Long availableBW = MapUtils.getAvailableBandwidth(link);
-            if ((availableBW == 0L) || (availableBW == null)) {
-                LOG.error("PceLink: No bandwidth available or not valid OTN Link, Link {}  is ignored ", linkId);
-            } else if (("ODU4".equals(oduType)) && (availableBW == 100000L)) {
-                isOtnValid = true;
-                LOG.debug("PceLink: Selected OTU4 Link {} is eligible for ODU creation OTN Link", linkId);
-            } else if (("ODU2".equals(oduType)) || ("ODU2e".equals(oduType)) && (availableBW >= 12500L)) {
-                isOtnValid = true;
-                LOG.debug("PceLink: Selected ODU4 Link {} has available bandwidth and is eligible for {} creation ",
-                    linkId, oduType);
-            } else if (("ODU0".equals(oduType)) && (availableBW >= 1250L)) {
-                isOtnValid = true;
-                LOG.debug("PceLink: Selected ODU4 Link {} has available bandwidth and is eligible for {} creation ",
-                    linkId, oduType);
-            } else if (("ODU1".equals(oduType)) && (availableBW >= 2500L)) {
-                isOtnValid = true;
-                LOG.debug("PceLink: Selected ODU4 Link {} has available bandwidth and is eligible for {} creation ",
-                    linkId, oduType);
-            } else {
-                isOtnValid = false;
-                LOG.error(
-                    "PceLink: Selected OTN Link {} is not eligible for ODU creation: not enough available bandwidth",
-                    linkId);
-            }
+    public boolean isOtnValid(Link link, String serviceType) {
 
-        } else {
-            isOtnValid = false;
+        if (this.linkType != OpenroadmLinkType.OTNLINK) {
             LOG.error("PceLink: Not an OTN link. Link is ignored {}", linkId);
+            return false;
+        }
+
+        OtnLinkType otnLinkType = link
+            .augmentation(org.opendaylight.yang.gen.v1.http.transportpce.topology.rev200129.Link1.class)
+            .getOtnLinkType();
+        if (this.availableBandwidth == 0L) {
+            LOG.error("PceLink: No bandwidth available for OTN Link, link {}  is ignored ", linkId);
+            return false;
+        }
+
+        long neededBW = 0L;
+        OtnLinkType neededType = null;
+        switch (serviceType) {
+
+            case "ODU4":
+                if (this.usedBandwidth != 0L) {
+                    return false;
+                }
+                neededBW = 100000L;
+                neededType = OtnLinkType.OTU4;
+                break;
+            case "ODU2":
+            case "ODU2e":
+                neededBW = 12500L;
+                break;
+            case "ODU0":
+                neededBW = 1250L;
+                break;
+            case "ODU1":
+                neededBW = 2500L;
+                break;
+            case "10GE":
+                neededBW = 10000L;
+                neededType = OtnLinkType.ODTU4;
+                break;
+            case "1GE":
+                neededBW = 1000L;
+                neededType = OtnLinkType.ODTU4;
+                break;
+            default:
+                LOG.error("PceLink: isOtnValid Link {} unsupported serviceType {} ", linkId, serviceType);
+                return false;
+        }
+
+        if ((this.availableBandwidth >= neededBW)
+            && ((neededType == null) || (neededType.equals(otnLinkType)))) {
+            LOG.info("PceLink: Selected Link {} has available bandwidth and is eligible for {} creation ",
+                linkId, serviceType);
         }
 
-        if ((this.linkId == null) || (this.linkType == null)
-                || (this.oppositeLink == null)) {
-            isOtnValid = false;
+        if ((this.linkId == null) || (this.linkType == null) || (this.oppositeLink == null)) {
             LOG.error("PceLink: No Link type or opposite link is available. Link is ignored {}", linkId);
+            return false;
         }
-        if ((this.sourceId == null) || (this.destId == null)
-                || (this.sourceTP == null) || (this.destTP == null)) {
-            isOtnValid = false;
+        if ((this.sourceId == null) || (this.destId == null) || (this.sourceTP == null) || (this.destTP == null)) {
             LOG.error("PceLink: No Link source or destination is available. Link is ignored {}", linkId);
+            return false;
         }
         if ((this.sourceNetworkSupNodeId.equals("")) || (this.destNetworkSupNodeId.equals(""))) {
-            isOtnValid = false;
             LOG.error("PceLink: No Link source SuppNodeID or destination SuppNodeID is available. Link is ignored {}",
                 linkId);
+            return false;
         }
         if ((this.sourceCLLI.equals("")) || (this.destCLLI.equals(""))) {
-            isOtnValid = false;
             LOG.error("PceLink: No Link source CLLI or destination CLLI is available. Link is ignored {}", linkId);
+            return false;
         }
 
-        return isOtnValid;
+        return true;
     }
 
     public String toString() {
index 52e01056ac19ec6af2a7aa5c992528536922b1a8..74d71bd68bccad06540fce7f9007703a00342fe4 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright Â© 2017 AT&T, Inc. and others.  All rights reserved.
+ * Copyright Â© 2020 Orange, Inc. and others.  All rights reserved.
  *
  * This program and the accompanying materials are made available under the
  * terms of the Eclipse Public License v1.0 which accompanies this distribution,
 
 package org.opendaylight.transportpce.pce.networkanalyzer;
 
-import java.util.ArrayList;
-import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
-import java.util.Optional;
-import java.util.TreeMap;
 
-import org.opendaylight.transportpce.common.NetworkUtils;
-import org.opendaylight.transportpce.pce.SortPortsByName;
-import org.opendaylight.yang.gen.v1.http.org.openroadm.common.network.rev181130.TerminationPoint1;
-import org.opendaylight.yang.gen.v1.http.org.openroadm.network.topology.rev181130.Node1;
-import org.opendaylight.yang.gen.v1.http.org.openroadm.network.topology.rev181130.networks.network.node.termination.point.pp.attributes.UsedWavelength;
-import org.opendaylight.yang.gen.v1.http.org.openroadm.network.types.rev181130.OpenroadmNodeType;
-import org.opendaylight.yang.gen.v1.http.org.openroadm.network.types.rev181130.OpenroadmTpType;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.rev180226.NodeId;
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.rev180226.networks.network.Node;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
 
-public class PceNode {
-    /* Logging. */
-    private static final Logger LOG = LoggerFactory.getLogger(PceCalculation.class);
-    ////////////////////////// NODES ///////////////////////////
-    /*
-     */
+public interface PceNode {
+    String getPceNodeType();
 
-    private boolean valid = true;
+    String getSupNetworkNodeId();
 
-    protected final Node node;
-    protected final NodeId nodeId;
-    protected final OpenroadmNodeType nodeType;
-    private final String supNodeId;
-    private final String supNetworkNodeId;
-    private final String clli;
+    String getSupClliNodeId();
 
-    // wavelength calculation per node type
-    private List<Long> availableWLindex = new ArrayList<Long>();
-    private Map<String, OpenroadmTpType> availableSrgPp = new TreeMap<String, OpenroadmTpType>();
-    private Map<String, OpenroadmTpType> availableSrgCp = new TreeMap<String, OpenroadmTpType>();
-    private List<String> usedXpndrNWTps = new ArrayList<String>();
-    private List<PceLink> outgoingLinks = new ArrayList<PceLink>();
-    private Map<String, String> clientPerNwTp = new HashMap<String, String>();
-    private Map<String,List<Integer>> tpAvailableTribPort = new TreeMap<String,List<Integer>>();
-    private Map<String,List<Integer>> tpAvailableTribSlot = new TreeMap<String,List<Integer>>();
+    void addOutgoingLink(PceLink outLink);
 
-    public PceNode(Node node, OpenroadmNodeType nodeType, NodeId nodeId) {
-        this.node = node;
-        this.nodeId = nodeId;
-        this.nodeType = nodeType;
-        this.supNodeId = getSupNodeId(node);
-        this.supNetworkNodeId = getNetworkSupNodeId(node);
-        //this.clli = MapUtils.getCLLI(node);
-        this.clli = getClliSupNodeId(node);
-        this.tpAvailableTribPort.clear();
-        this.tpAvailableTribSlot.clear();
+    String getRdmSrgClient(String tp);
 
-        if ((node == null) || (nodeId == null) || (nodeType == null)) {
-            LOG.error("PceNode: one of parameters is not populated : nodeId, node type");
-            this.valid = false;
-        }
-    }
+    String getXpdrClient(String tp);
 
-    public void initSrgTps() {
-        this.availableSrgPp.clear();
-        this.availableSrgCp.clear();
-        if (!isValid()) {
-            return;
-        }
-        LOG.info("initSrgTpList: getting SRG tps from ROADM node {}", this.nodeId);
-        org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.topology.rev180226.Node1 nodeTp =
-                this.node.augmentation(org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.topology
-                                .rev180226.Node1.class);
-        List<org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.topology.rev180226.networks.network
-            .node.TerminationPoint> allTps =
-                nodeTp.getTerminationPoint();
-        if (allTps == null) {
-            LOG.error("initSrgTpList: ROADM TerminationPoint list is empty for node {}", this.toString());
-            this.valid = false;
-            return;
-        }
-        for (org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.topology.rev180226.networks.network
-            .node.TerminationPoint tp : allTps) {
-            TerminationPoint1 cntp1 = tp.augmentation(TerminationPoint1.class);
-            org.opendaylight.yang.gen.v1.http.org.openroadm.network.topology.rev181130.TerminationPoint1 nttp1 = tp
-                .augmentation(org.opendaylight.yang.gen.v1.http.org.openroadm.network.topology.rev181130
-                .TerminationPoint1.class);
-            OpenroadmTpType type = cntp1.getTpType();
-            LOG.info("type = {} for tp {}", type.getName(), tp.toString());
+    boolean checkTP(String tp);
 
-            switch (type) {
-                case SRGTXRXCP:
-                case SRGRXCP:
-                case SRGTXCP:
-                    LOG.info("initSrgTpList: adding SRG-CP tp = {} ", tp.getTpId().getValue());
-                    this.availableSrgCp.put(tp.getTpId().getValue(), cntp1.getTpType());
-                    break;
-                case SRGRXPP:
-                case SRGTXPP:
-                case SRGTXRXPP:
-                    boolean used = true;
-                    LOG.info("initSrgTpList: SRG-PP tp = {} found", tp.getTpId().getValue());
-                    try {
-                        List<UsedWavelength> usedWavelengths = nttp1.getPpAttributes().getUsedWavelength();
-                        if (usedWavelengths.isEmpty()) {
-                            used = false;
-                        }
-                    } catch (NullPointerException e) {
-                        LOG.warn("initSrgTpList: 'usedWavelengths' for tp={} is null !", tp.getTpId().getValue());
-                        used = false;
-                    }
-                    if (!used) {
-                        LOG.info("initSrgTpList: adding SRG-PP tp '{}'", tp.getTpId().getValue());
-                        this.availableSrgPp.put(tp.getTpId().getValue(), cntp1.getTpType());
-                    } else {
-                        LOG.warn("initSrgTpList: SRG-PP tp = {} found is busy !!");
-                    }
-                    break;
-                default:
-                    break;
-            }
-        }
-        if (this.availableSrgPp.isEmpty() && this.availableSrgCp.isEmpty()) {
-            LOG.error("initSrgTpList: ROADM SRG TerminationPoint list is empty for node {}", this.toString());
-            this.valid = false;
-            return;
-        }
-        LOG.info("initSrgTpList: availableSrgPp size = {} && availableSrgCp size = {} in {}", this.availableSrgPp
-                .size(), this.availableSrgCp.size(), this.toString());
-        return;
-    }
+    List<PceLink> getOutgoingLinks();
 
-    public void initWLlist() {
-        this.availableWLindex.clear();
-        if (!isValid()) {
-            return;
-        }
-        Node1 node1 = this.node.augmentation(Node1.class);
-        switch (this.nodeType) {
-            case SRG :
-                List<org.opendaylight.yang.gen.v1.http.org.openroadm.srg.rev181130.srg.node.attributes
-                    .AvailableWavelengths> srgAvailableWL =
-                        node1.getSrgAttributes().getAvailableWavelengths();
-                if (srgAvailableWL == null) {
-                    this.valid = false;
-                    LOG.error("initWLlist: SRG AvailableWavelengths is empty for node  {}", this.toString());
-                    return;
-                }
-                for (org.opendaylight.yang.gen.v1.http.org.openroadm.srg.rev181130.srg.node.attributes
-                        .AvailableWavelengths awl : srgAvailableWL) {
-                    this.availableWLindex.add(awl.getIndex());
-                    LOG.debug("initWLlist: SRG next = {} in {}", awl.getIndex(), this.toString());
-                }
-                break;
-            case DEGREE :
-                List<org.opendaylight.yang.gen.v1.http.org.openroadm.degree.rev181130.degree.node.attributes
-                    .AvailableWavelengths> degAvailableWL = node1.getDegreeAttributes().getAvailableWavelengths();
-                if (degAvailableWL == null) {
-                    this.valid = false;
-                    LOG.error("initWLlist: DEG AvailableWavelengths is empty for node  {}", this.toString());
-                    return;
-                }
-                for (org.opendaylight.yang.gen.v1.http.org.openroadm.degree.rev181130.degree.node.attributes
-                            .AvailableWavelengths awl : degAvailableWL) {
-                    this.availableWLindex.add(awl.getIndex());
-                    LOG.debug("initWLlist: DEGREE next = {} in {}", awl.getIndex(), this.toString());
-                }
-                break;
-            case XPONDER :
-                // HARD CODED 96
-                for (long i = 1; i <= 96; i++) {
-                    this.availableWLindex.add(i);
-                }
-                break;
-            default:
-                LOG.error("initWLlist: unsupported node type {} in node {}", this.nodeType, this.toString());
-                break;
-        }
-        if (this.availableWLindex.size() == 0) {
-            LOG.debug("initWLlist: There are no available wavelengths in node {}", this.toString());
-            this.valid = false;
-        }
-        LOG.debug("initWLlist: availableWLindex size = {} in {}", this.availableWLindex.size(), this.toString());
-        return;
-    }
+    NodeId getNodeId();
 
-    public void initXndrTps() {
-        LOG.info("initXndrTps for node : {}", this.nodeId);
-        if (!isValid()) {
-            return;
-        }
-        org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.topology.rev180226.Node1 nodeTp =
-                this.node.augmentation(org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.topology
-                        .rev180226.Node1.class);
-        List<org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.topology.rev180226.networks.network
-            .node.TerminationPoint> allTps = nodeTp.getTerminationPoint();
-        if (allTps == null) {
-            this.valid = false;
-            LOG.error("initXndrTps: XPONDER TerminationPoint list is empty for node {}", this.toString());
-            return;
-        }
-        this.valid = false;
-        for (org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.topology.rev180226.networks.network
-            .node.TerminationPoint tp : allTps) {
-            TerminationPoint1 cntp1 = tp.augmentation(TerminationPoint1.class);
-            org.opendaylight.yang.gen.v1.http.org.openroadm.network.topology.rev181130.TerminationPoint1 nttp1 = tp
-                .augmentation(org.opendaylight.yang.gen.v1.http.org.openroadm.network.topology.rev181130
-                .TerminationPoint1.class);
-            if (cntp1.getTpType() == OpenroadmTpType.XPONDERNETWORK) {
-                if (nttp1 != null && nttp1.getXpdrNetworkAttributes().getWavelength() != null) {
-                    this.usedXpndrNWTps.add(tp.getTpId().getValue());
-                    LOG.info("initXndrTps: XPONDER tp = {} is used", tp.getTpId().getValue());
-                } else {
-                    this.valid = true;
-                }
-                // find Client of this network TP
-                org.opendaylight.yang.gen.v1.http.transportpce.topology.rev200123.TerminationPoint1 tpceTp1 =
-                    tp.augmentation(org.opendaylight.yang.gen.v1.http.transportpce.topology.rev200123
-                        .TerminationPoint1.class);
-                String client = tpceTp1.getAssociatedConnectionMapPort();
-                if ((client.equals("")) || (client == null)) {
-                    LOG.error("initXndrTps: XPONDER {} NW TP doesn't have defined Client {}", this.toString(), tp
-                            .getTpId().getValue());
-                    this.valid = false;
-                }
-                this.clientPerNwTp.put(tp.getTpId().getValue(), client);
-            }
-        }
-        if (!isValid()) {
-            LOG.error("initXndrTps: XPONDER doesn't have available wavelengths for node  {}", this.toString());
-            return;
-        }
-    }
+    boolean checkWL(long index);
 
-    public String getRdmSrgClient(String tp, Boolean aend) {
-        LOG.info("getRdmSrgClient: Getting PP client for tp '{}' on node : {}", tp, this.nodeId);
-        OpenroadmTpType srgType = null;
-        OpenroadmTpType cpType = this.availableSrgCp.get(tp);
-        if (cpType == null) {
-            LOG.error("getRdmSrgClient: tp {} not existed in SRG CPterminationPoint list");
-            return null;
-        }
-        switch (cpType) {
-            case SRGTXRXCP:
-                LOG.info("getRdmSrgClient: Getting BI Directional PP port ...");
-                srgType = OpenroadmTpType.SRGTXRXPP;
-                break;
-            case SRGTXCP:
-                LOG.info("getRdmSrgClient: Getting UNI Rx PP port ...");
-                srgType = OpenroadmTpType.SRGRXPP;
-                break;
-            case SRGRXCP:
-                LOG.info("getRdmSrgClient: Getting UNI Tx PP port ...");
-                srgType = OpenroadmTpType.SRGTXPP;
-                break;
-            default:
-                break;
-        }
-        LOG.info("getRdmSrgClient:  Getting client PP for CP '{}'", tp);
-        if (!this.availableSrgPp.isEmpty()) {
-            Optional<String> client = null;
-            final OpenroadmTpType openType = srgType;
-            client = this.availableSrgPp.entrySet()
-                    .stream().filter(pp -> pp.getValue().getName().equals(openType.getName()))
-                    .map(Map.Entry::getKey)
-                    .sorted(new SortPortsByName())
-                    .findFirst();
-            if (!client.isPresent()) {
-                LOG.error("getRdmSrgClient: ROADM {} doesn't have PP Client for CP {}", this.toString(), tp);
-                return null;
-            }
-            LOG.info("getRdmSrgClient: client PP {} for CP {} found !", client, tp);
-            return client.get();
-        } else {
-            LOG.error("getRdmSrgClient: SRG TerminationPoint PP list is not available for node {}", this.toString());
-            return null;
-        }
-    }
-
-    private String getSupNodeId(Node inputNode) {
-        // TODO: supporting IDs exist as a List. this code takes just the
-        // first element
-        if (MapUtils.getSupNode(inputNode) != null) {
-            return MapUtils.getSupNode(inputNode);
-        } else {
-            LOG.error("getSupNodeId: Empty Supporting node for node: [{}]. Node is ignored", inputNode.getNodeId());
-            return "";
-        }
-    }
-
-    private String getClliSupNodeId(Node inputNode) {
-        TreeMap<String, String> allSupNodes = new TreeMap<String, String>();
-        String tempNetworkSupNodeId = "";
-        allSupNodes = MapUtils.getAllSupNode(inputNode);
-        if (allSupNodes.get(NetworkUtils.CLLI_NETWORK_ID) == null) {
-            LOG.error("getClliSupNodeId: No Supporting node at CLLI layer for node: [{}].", inputNode.getNodeId());
-        } else {
-            tempNetworkSupNodeId = allSupNodes.get(NetworkUtils.CLLI_NETWORK_ID);
-        }
-        return tempNetworkSupNodeId;
-    }
-
-    public String getClliSupNodeId() {
-        return clli;
-    }
-
-    private String getNetworkSupNodeId(Node inputNode) {
-        TreeMap<String, String> allSupNodes = new TreeMap<String, String>();
-        String tempNetworkSupNodeId = "";
-        allSupNodes = MapUtils.getAllSupNode(inputNode);
-        if (allSupNodes.get(NetworkUtils.UNDERLAY_NETWORK_ID) == null) {
-            LOG.error(
-                "getNetworkSupNodeId: No Supporting node at NETWORK layer for node: [{}].", inputNode.getNodeId());
-        } else {
-            tempNetworkSupNodeId = allSupNodes.get(NetworkUtils.UNDERLAY_NETWORK_ID);
-        }
-        return tempNetworkSupNodeId;
-    }
-
-
-    public void validateAZxponder(String anodeId, String znodeId) {
-        if (!isValid()) {
-            return;
-        }
-        if (this.nodeType != OpenroadmNodeType.XPONDER) {
-            return;
-        }
-        // Detect A and Z
-        if (this.supNetworkNodeId.equals(anodeId) || (this.supNetworkNodeId.equals(znodeId))) {
-            LOG.info("validateAZxponder: A or Z node detected == {}", nodeId.getValue());
-            initXndrTps();
-            return;
-        }
-        LOG.debug("validateAZxponder: XPONDER is ignored == {}", nodeId.getValue());
-        valid = false;
-    }
-
-    public String getXpdrClient(String tp) {
-        return this.clientPerNwTp.get(tp);
-    }
-
-    public boolean checkTP(String tp) {
-        return !(this.usedXpndrNWTps.contains(tp));
-    }
-
-    public boolean checkWL(long index) {
-        return (this.availableWLindex.contains(index));
-    }
-
-    public boolean isValid() {
-        if ((node == null) || (nodeId == null) || (nodeType == null) || (supNetworkNodeId == null) || (clli == null)) {
-            LOG.error("PceNode: one of parameters is not populated : nodeId, node type, supporting nodeId");
-            valid = false;
-        }
-        return valid;
-    }
-
-    public List<Long> getAvailableWLs() {
-        return availableWLindex;
-    }
-
-    public void addOutgoingLink(PceLink outLink) {
-        this.outgoingLinks.add(outLink);
-    }
-
-    public List<PceLink> getOutgoingLinks() {
-        return outgoingLinks;
-    }
-
-    public String getClient(String tp) {
-        return clientPerNwTp.get(tp);
-    }
-
-    public NodeId getNodeId() {
-        return nodeId;
-    }
-
-    public String getSupNodeIdPceNode() {
-        return supNodeId;
-    }
-
-    public String getSupNetworkNodeIdPceNode() {
-        return supNetworkNodeId;
-    }
-
-    public String getCLLI() {
-        return clli;
-    }
-
-    public String toString() {
-        return "PceNode type=" + nodeType + " ID=" + nodeId.getValue() + " CLLI=" + clli;
-    }
-
-    public void printLinksOfNode() {
-        LOG.info(" outgoing links of node {} : {} ", nodeId.getValue(), this.getOutgoingLinks().toString());
-    }
-
-    public Map<String,List<Integer>> getAvailableTribPorts() {
-        return tpAvailableTribPort;
-    }
-
-    public Map<String,List<Integer>> getAvailableTribSlots() {
-        return tpAvailableTribSlot;
-    }
+    Map<String, List<Integer>> getAvailableTribPorts();
 
+    Map<String, List<Integer>> getAvailableTribSlots();
 }
diff --git a/pce/src/main/java/org/opendaylight/transportpce/pce/networkanalyzer/PceOpticalNode.java b/pce/src/main/java/org/opendaylight/transportpce/pce/networkanalyzer/PceOpticalNode.java
new file mode 100644 (file)
index 0000000..e8b70cc
--- /dev/null
@@ -0,0 +1,375 @@
+/*
+ * Copyright Â© 2020 Orange, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.transportpce.pce.networkanalyzer;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Optional;
+import java.util.TreeMap;
+
+import org.opendaylight.transportpce.pce.SortPortsByName;
+import org.opendaylight.yang.gen.v1.http.org.openroadm.common.network.rev181130.TerminationPoint1;
+import org.opendaylight.yang.gen.v1.http.org.openroadm.network.topology.rev181130.Node1;
+import org.opendaylight.yang.gen.v1.http.org.openroadm.network.topology.rev181130.networks.network.node.termination.point.pp.attributes.UsedWavelength;
+import org.opendaylight.yang.gen.v1.http.org.openroadm.network.types.rev181130.OpenroadmNodeType;
+import org.opendaylight.yang.gen.v1.http.org.openroadm.network.types.rev181130.OpenroadmTpType;
+import org.opendaylight.yang.gen.v1.http.org.openroadm.service.format.rev190531.ServiceFormat;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.rev180226.NodeId;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.rev180226.networks.network.Node;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class PceOpticalNode implements PceNode {
+    private static final Logger LOG = LoggerFactory.getLogger(PceCalculation.class);
+
+    private boolean valid = true;
+
+    private final Node node;
+    private final NodeId nodeId;
+    private final OpenroadmNodeType nodeType;
+    private final ServiceFormat serviceFormat;
+    private final String pceNodeType;
+
+    // wavelength calculation per node type
+    private List<Long> availableWLindex = new ArrayList<Long>();
+    private Map<String, OpenroadmTpType> availableSrgPp = new TreeMap<String, OpenroadmTpType>();
+    private Map<String, OpenroadmTpType> availableSrgCp = new TreeMap<String, OpenroadmTpType>();
+    private List<String> usedXpndrNWTps = new ArrayList<String>();
+    private List<PceLink> outgoingLinks = new ArrayList<PceLink>();
+    private Map<String, String> clientPerNwTp = new HashMap<String, String>();
+
+    public PceOpticalNode(Node node, OpenroadmNodeType nodeType, NodeId nodeId, ServiceFormat serviceFormat,
+        String pceNodeType) {
+        this.node = node;
+        this.nodeId = nodeId;
+        this.nodeType = nodeType;
+        this.serviceFormat = serviceFormat;
+        this.pceNodeType = pceNodeType;
+
+        if ((node == null) || (nodeId == null) || (nodeType == null)) {
+            LOG.error("PceNode: one of parameters is not populated : nodeId, node type");
+            this.valid = false;
+        }
+    }
+
+    public void initSrgTps() {
+        this.availableSrgPp.clear();
+        this.availableSrgCp.clear();
+        if (!isValid()) {
+            return;
+        }
+        LOG.info("initSrgTpList: getting SRG tps from ROADM node {}", this.nodeId);
+        org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.topology.rev180226.Node1 nodeTp =
+                this.node.augmentation(org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang
+                    .ietf.network.topology.rev180226.Node1.class);
+        List<org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.topology.rev180226.networks.network
+            .node.TerminationPoint> allTps = nodeTp.getTerminationPoint();
+        if (allTps == null) {
+            LOG.error("initSrgTpList: ROADM TerminationPoint list is empty for node {}", this.toString());
+            this.valid = false;
+            return;
+        }
+        for (org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.topology.rev180226.networks.network
+            .node.TerminationPoint tp : allTps) {
+            TerminationPoint1 cntp1 = tp.augmentation(TerminationPoint1.class);
+            org.opendaylight.yang.gen.v1.http.org.openroadm.network.topology.rev181130.TerminationPoint1 nttp1 = tp
+                .augmentation(org.opendaylight.yang.gen.v1.http.org.openroadm.network.topology.rev181130
+                .TerminationPoint1.class);
+            OpenroadmTpType type = cntp1.getTpType();
+            LOG.info("type = {} for tp {}", type.getName(), tp.toString());
+
+            switch (type) {
+                case SRGTXRXCP:
+                case SRGRXCP:
+                case SRGTXCP:
+                    LOG.info("initSrgTpList: adding SRG-CP tp = {} ", tp.getTpId().getValue());
+                    this.availableSrgCp.put(tp.getTpId().getValue(), cntp1.getTpType());
+                    break;
+                case SRGRXPP:
+                case SRGTXPP:
+                case SRGTXRXPP:
+                    boolean used = true;
+                    LOG.info("initSrgTpList: SRG-PP tp = {} found", tp.getTpId().getValue());
+                    try {
+                        List<UsedWavelength> usedWavelengths = nttp1.getPpAttributes().getUsedWavelength();
+                        if (usedWavelengths.isEmpty()) {
+                            used = false;
+                        }
+                    } catch (NullPointerException e) {
+                        LOG.warn("initSrgTpList: 'usedWavelengths' for tp={} is null !", tp.getTpId().getValue());
+                        used = false;
+                    }
+                    if (!used) {
+                        LOG.info("initSrgTpList: adding SRG-PP tp '{}'", tp.getTpId().getValue());
+                        this.availableSrgPp.put(tp.getTpId().getValue(), cntp1.getTpType());
+                    } else {
+                        LOG.warn("initSrgTpList: SRG-PP tp = {} found is busy !!");
+                    }
+                    break;
+                default:
+                    break;
+            }
+        }
+        if (this.availableSrgPp.isEmpty() && this.availableSrgCp.isEmpty()) {
+            LOG.error("initSrgTpList: ROADM SRG TerminationPoint list is empty for node {}", this.toString());
+            this.valid = false;
+            return;
+        }
+        LOG.info("initSrgTpList: availableSrgPp size = {} && availableSrgCp size = {} in {}",
+            this.availableSrgPp.size(), this.availableSrgCp.size(), this.toString());
+        return;
+    }
+
+    public void initWLlist() {
+        this.availableWLindex.clear();
+        if (!isValid()) {
+            return;
+        }
+        Node1 node1 = this.node.augmentation(Node1.class);
+        switch (this.nodeType) {
+            case SRG :
+                List<org.opendaylight.yang.gen.v1.http.org.openroadm.srg.rev181130.srg.node.attributes
+                    .AvailableWavelengths> srgAvailableWL =
+                        node1.getSrgAttributes().getAvailableWavelengths();
+                if (srgAvailableWL == null) {
+                    this.valid = false;
+                    LOG.error("initWLlist: SRG AvailableWavelengths is empty for node  {}", this.toString());
+                    return;
+                }
+                for (org.opendaylight.yang.gen.v1.http.org.openroadm.srg.rev181130.srg.node.attributes
+                        .AvailableWavelengths awl : srgAvailableWL) {
+                    this.availableWLindex.add(awl.getIndex());
+                    LOG.debug("initWLlist: SRG next = {} in {}", awl.getIndex(), this.toString());
+                }
+                break;
+            case DEGREE :
+                List<org.opendaylight.yang.gen.v1.http.org.openroadm.degree.rev181130.degree.node.attributes
+                    .AvailableWavelengths> degAvailableWL = node1.getDegreeAttributes().getAvailableWavelengths();
+                if (degAvailableWL == null) {
+                    this.valid = false;
+                    LOG.error("initWLlist: DEG AvailableWavelengths is empty for node  {}", this.toString());
+                    return;
+                }
+                for (org.opendaylight.yang.gen.v1.http.org.openroadm.degree.rev181130.degree.node.attributes
+                            .AvailableWavelengths awl : degAvailableWL) {
+                    this.availableWLindex.add(awl.getIndex());
+                    LOG.debug("initWLlist: DEGREE next = {} in {}", awl.getIndex(), this.toString());
+                }
+                break;
+            case XPONDER :
+                // HARD CODED 96
+                for (long i = 1; i <= 96; i++) {
+                    this.availableWLindex.add(i);
+                }
+                break;
+            default:
+                LOG.error("initWLlist: unsupported node type {} in node {}", this.nodeType, this.toString());
+                break;
+        }
+        if (this.availableWLindex.size() == 0) {
+            LOG.debug("initWLlist: There are no available wavelengths in node {}", this.toString());
+            this.valid = false;
+        }
+        LOG.debug("initWLlist: availableWLindex size = {} in {}", this.availableWLindex.size(), this.toString());
+        return;
+    }
+
+    public void initXndrTps() {
+        LOG.info("PceNod: initXndrTps for node : {}", this.nodeId);
+        if (!isValid()) {
+            return;
+        }
+        org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.topology.rev180226.Node1 nodeTp =
+                this.node.augmentation(org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang
+                    .ietf.network.topology.rev180226.Node1.class);
+        List<org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.topology.rev180226.networks.network
+            .node.TerminationPoint> allTps = nodeTp.getTerminationPoint();
+        if (allTps == null) {
+            this.valid = false;
+            LOG.error("initXndrTps: XPONDER TerminationPoint list is empty for node {}", this.toString());
+            return;
+        }
+        this.valid = false;
+        for (org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.topology.rev180226.networks.network
+            .node.TerminationPoint tp : allTps) {
+            TerminationPoint1 cntp1 = tp.augmentation(TerminationPoint1.class);
+            org.opendaylight.yang.gen.v1.http.org.openroadm.network.topology.rev181130.TerminationPoint1 nttp1 = tp
+                .augmentation(org.opendaylight.yang.gen.v1.http.org.openroadm.network.topology.rev181130
+                .TerminationPoint1.class);
+            if (cntp1.getTpType() == OpenroadmTpType.XPONDERNETWORK) {
+                if (nttp1 != null && nttp1.getXpdrNetworkAttributes().getWavelength() != null) {
+                    this.usedXpndrNWTps.add(tp.getTpId().getValue());
+                    LOG.info("initXndrTps: XPONDER tp = {} is used", tp.getTpId().getValue());
+                } else {
+                    this.valid = true;
+                }
+                // find Client of this network TP
+                String client;
+                org.opendaylight.yang.gen.v1.http.transportpce.topology.rev200129.TerminationPoint1 tpceTp1 =
+                    tp.augmentation(org.opendaylight.yang.gen.v1.http.transportpce.topology.rev200129
+                        .TerminationPoint1.class);
+                if (tpceTp1 != null) {
+                    client = tpceTp1.getAssociatedConnectionMapPort();
+                    if (client != null) {
+                        this.clientPerNwTp.put(tp.getTpId().getValue(), client);
+                        this.valid = true;
+                    } else {
+                        LOG.error("initXndrTps: XPONDER {} NW TP doesn't have defined Client {}", this.toString(),
+                            tp.getTpId().getValue());
+                    }
+                } else if (ServiceFormat.OTU.equals(this.serviceFormat)) {
+                    LOG.info("Infrastructure OTU4 connection");
+                    this.valid = true;
+                } else {
+                    LOG.error("Service Format {} not managed yet", this.serviceFormat.getName());
+                }
+            }
+        }
+        if (!isValid()) {
+            LOG.error("initXndrTps: XPONDER doesn't have available wavelengths for node  {}", this.toString());
+            return;
+        }
+    }
+
+    @Override
+    public String getRdmSrgClient(String tp) {
+        LOG.info("getRdmSrgClient: Getting PP client for tp '{}' on node : {}", tp, this.nodeId);
+        OpenroadmTpType srgType = null;
+        OpenroadmTpType cpType = this.availableSrgCp.get(tp);
+        if (cpType == null) {
+            LOG.error("getRdmSrgClient: tp {} not existed in SRG CPterminationPoint list");
+            return null;
+        }
+        switch (cpType) {
+            case SRGTXRXCP:
+                LOG.info("getRdmSrgClient: Getting BI Directional PP port ...");
+                srgType = OpenroadmTpType.SRGTXRXPP;
+                break;
+            case SRGTXCP:
+                LOG.info("getRdmSrgClient: Getting UNI Rx PP port ...");
+                srgType = OpenroadmTpType.SRGRXPP;
+                break;
+            case SRGRXCP:
+                LOG.info("getRdmSrgClient: Getting UNI Tx PP port ...");
+                srgType = OpenroadmTpType.SRGTXPP;
+                break;
+            default:
+                break;
+        }
+        LOG.info("getRdmSrgClient:  Getting client PP for CP '{}'", tp);
+        if (!this.availableSrgPp.isEmpty()) {
+            Optional<String> client = null;
+            final OpenroadmTpType openType = srgType;
+            client = this.availableSrgPp.entrySet()
+                    .stream().filter(pp -> pp.getValue().getName().equals(openType.getName()))
+                    .map(Map.Entry::getKey)
+                    .sorted(new SortPortsByName())
+                    .findFirst();
+            if (!client.isPresent()) {
+                LOG.error("getRdmSrgClient: ROADM {} doesn't have PP Client for CP {}", this.toString(), tp);
+                return null;
+            }
+            LOG.info("getRdmSrgClient: client PP {} for CP {} found !", client, tp);
+            return client.get();
+        } else {
+            LOG.error("getRdmSrgClient: SRG TerminationPoint PP list is not available for node {}", this.toString());
+            return null;
+        }
+    }
+
+
+    public void validateAZxponder(String anodeId, String znodeId) {
+        if (!isValid()) {
+            return;
+        }
+        if (this.nodeType != OpenroadmNodeType.XPONDER) {
+            return;
+        }
+        // Detect A and Z
+        if (this.getSupNetworkNodeId().equals(anodeId) || (this.getSupNetworkNodeId().equals(znodeId))) {
+            LOG.info("validateAZxponder: A or Z node detected == {}", nodeId.getValue());
+            initXndrTps();
+            return;
+        }
+        LOG.debug("validateAZxponder: XPONDER is ignored == {}", nodeId.getValue());
+        valid = false;
+    }
+
+    @Override
+    public boolean checkTP(String tp) {
+        return !this.usedXpndrNWTps.contains(tp);
+    }
+
+    @Override
+    public boolean checkWL(long index) {
+        return (this.availableWLindex.contains(index));
+    }
+
+    public boolean isValid() {
+        if (node == null || nodeId == null || nodeType == null || this.getSupNetworkNodeId() == null
+            || this.getSupClliNodeId() == null) {
+            LOG.error("PceNode: one of parameters is not populated : nodeId, node type, supporting nodeId");
+            valid = false;
+        }
+        return valid;
+    }
+
+    @Override
+    public List<PceLink> getOutgoingLinks() {
+        return outgoingLinks;
+    }
+
+    @Override
+    public NodeId getNodeId() {
+        return nodeId;
+    }
+
+    public String toString() {
+        return "PceNode type=" + nodeType + " ID=" + nodeId.getValue() + " CLLI=" + this.getSupClliNodeId();
+    }
+
+    @Override
+    public String getPceNodeType() {
+        return this.pceNodeType;
+    }
+
+    @Override
+    public String getSupNetworkNodeId() {
+        return MapUtils.getSupNetworkNode(this.node);
+    }
+
+    @Override
+    public String getSupClliNodeId() {
+        return MapUtils.getSupClliNode(this.node);
+    }
+
+    @Override
+    public void addOutgoingLink(PceLink outLink) {
+        this.outgoingLinks.add(outLink);
+    }
+
+    @Override
+    public String getXpdrClient(String tp) {
+        return this.clientPerNwTp.get(tp);
+    }
+
+    @Override
+    public Map<String, List<Integer>> getAvailableTribPorts() {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public Map<String, List<Integer>> getAvailableTribSlots() {
+        // TODO Auto-generated method stub
+        return null;
+    }
+}
index 9da697f99961a5a519c6d9f137c79b55989c6d1f..65f17b78e97bc6c63e157c258e4a006aa8aedd25 100644 (file)
@@ -9,38 +9,35 @@
 package org.opendaylight.transportpce.pce.networkanalyzer;
 
 import java.util.ArrayList;
+import java.util.Comparator;
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
-//import java.util.Optional;
 import java.util.TreeMap;
+import java.util.stream.Collectors;
 
-//import org.eclipse.jdt.annotation.Nullable;
-import org.opendaylight.transportpce.common.NetworkUtils;
-//import org.opendaylight.transportpce.pce.SortPortsByName;
-//import org.opendaylight.yang.gen.v1.http.org.openroadm.network.topology.rev181130.Node1;
-//import org.opendaylight.yang.gen.v1.http.org.openroadm.network.topology.rev181130.TerminationPoint1;
-//import org.opendaylight.yang.gen.v1.http.org.openroadm.network.topology.rev181130.networks
-//.network.node.termination.point.pp.attributes.UsedWavelength;
+import org.eclipse.jdt.annotation.Nullable;
 import org.opendaylight.yang.gen.v1.http.org.openroadm.network.topology.types.rev181130.xpdr.odu.switching.pools.OduSwitchingPools;
 import org.opendaylight.yang.gen.v1.http.org.openroadm.network.topology.types.rev181130.xpdr.odu.switching.pools.odu.switching.pools.NonBlockingList;
 import org.opendaylight.yang.gen.v1.http.org.openroadm.network.types.rev181130.OpenroadmNodeType;
 import org.opendaylight.yang.gen.v1.http.org.openroadm.network.types.rev181130.OpenroadmTpType;
 import org.opendaylight.yang.gen.v1.http.org.openroadm.network.types.rev181130.xpdr.tp.supported.interfaces.SupportedInterfaceCapability;
 import org.opendaylight.yang.gen.v1.http.org.openroadm.otn.common.types.rev181130.ODTU4TsAllocated;
+import org.opendaylight.yang.gen.v1.http.org.openroadm.otn.network.topology.rev181130.Node1;
 import org.opendaylight.yang.gen.v1.http.org.openroadm.otn.network.topology.rev181130.TerminationPoint1;
 import org.opendaylight.yang.gen.v1.http.org.openroadm.otn.network.topology.rev181130.networks.network.node.SwitchingPools;
-//import org.opendaylight.yang.gen.v1.http.org.openroadm.port.types.rev181130.If100GEODU4;
-//import org.opendaylight.yang.gen.v1.http.org.openroadm.port.types.rev181130.If10GEODU2e;
-//import org.opendaylight.yang.gen.v1.http.org.openroadm.port.types.rev181130.If1GEODU0;
-import org.opendaylight.yang.gen.v1.http.org.openroadm.xponder.rev181130.xpdr.otn.tp.attributes.OdtuTpnPool;
+import org.opendaylight.yang.gen.v1.http.org.openroadm.port.types.rev181130.If100GEODU4;
+import org.opendaylight.yang.gen.v1.http.org.openroadm.port.types.rev181130.If10GEODU2e;
+import org.opendaylight.yang.gen.v1.http.org.openroadm.port.types.rev181130.If1GEODU0;
+import org.opendaylight.yang.gen.v1.http.org.openroadm.port.types.rev181130.IfOCHOTU4ODU4;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.rev180226.NodeId;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.rev180226.networks.network.Node;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.topology.rev180226.TpId;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.topology.rev180226.networks.network.node.TerminationPoint;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-public class PceOtnNode extends PceNode {
+public class PceOtnNode implements PceNode {
     /* Logging. */
     private static final Logger LOG = LoggerFactory.getLogger(PceCalculation.class);
     ////////////////////////// OTN NODES ///////////////////////////
@@ -50,160 +47,235 @@ public class PceOtnNode extends PceNode {
 
     private boolean valid = true;
 
-    private final String supNetworkNodeId;
-    private final String supTopoNodeId;
-    private final String clli;
+    private final Node node;
+    private final NodeId nodeId;
+    private final OpenroadmNodeType nodeType;
+    private final String pceNodeType;
     private final String otnServiceType;
 
     private Map<String, List<Integer>> tpAvailableTribPort = new TreeMap<String, List<Integer>>();
     private Map<String, List<Integer>> tpAvailableTribSlot = new TreeMap<String, List<Integer>>();
     private Map<String, OpenroadmTpType> availableXponderTp = new TreeMap<String, OpenroadmTpType>();
     private List<String> usedXpdrNWTps = new ArrayList<String>();
-    private List<String> unusableXpdrNWTps = new ArrayList<String>();
+    private List<TpId> availableXpdrNWTps;
+    private List<TpId> usableXpdrNWTps;
     private List<String> usedXpdrClientTps = new ArrayList<String>();
-    private List<String> unusableXpdrClientTps = new ArrayList<String>();
+    private List<TpId> availableXpdrClientTps;
+    private List<TpId> usableXpdrClientTps;
+
     private List<PceLink> outgoingLinks = new ArrayList<PceLink>();
     private Map<String, String> clientPerNwTp = new HashMap<String, String>();
 
-    public PceOtnNode(Node node, OpenroadmNodeType nodeType, NodeId nodeId, String serviceType) {
-        super(node, nodeType, nodeId);
-        this.supNetworkNodeId = getNetworkSupNodeId(node);
-        this.supTopoNodeId = getTopoSupNodeId(node);
-        this.clli = getClliSupNodeId(node);
+    public PceOtnNode(Node node, OpenroadmNodeType nodeType, NodeId nodeId, String pceNodeType, String serviceType) {
+        this.node = node;
+        this.nodeId = nodeId;
+        this.nodeType = nodeType;
+        this.pceNodeType = pceNodeType;
         this.otnServiceType = serviceType;
-        this.tpAvailableTribPort.clear();
         this.tpAvailableTribSlot.clear();
         this.usedXpdrNWTps.clear();
-        this.unusableXpdrNWTps.clear();
+        this.availableXpdrNWTps = new ArrayList<TpId>();
+        this.usableXpdrNWTps = new ArrayList<TpId>();
         this.usedXpdrClientTps.clear();
-        this.unusableXpdrClientTps.clear();
-
-        if ((node == null) || (nodeId == null) || (nodeType == null)) {
+        this.availableXpdrClientTps = new ArrayList<TpId>();
+        this.usableXpdrClientTps = new ArrayList<TpId>();
+        this.tpAvailableTribPort.clear();
+        checkAvailableTribPort();
+        this.tpAvailableTribSlot.clear();
+        checkAvailableTribSlot();
+        if ((node == null) || (nodeId == null) || (nodeType != OpenroadmNodeType.MUXPDR)
+            && (nodeType != OpenroadmNodeType.SWITCH) && (nodeType != OpenroadmNodeType.TPDR)) {
             LOG.error("PceOtnNode: one of parameters is not populated : nodeId, node type");
             this.valid = false;
         }
     }
 
     public void initXndrTps(String mode) {
-        LOG.info("initXndrTps for node : {}", this.nodeId);
-        int availableNetworkTpNumber = 0;
-        int availableClientTpNumber = 0;
-
+        LOG.info("PceOtnNode: initXndrTps for node {}", this.nodeId.getValue());
         this.availableXponderTp.clear();
 
-        if (!isValid()) {
-            return;
-        }
-        org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.topology.rev180226.Node1 nodeTp =
-            this.node.augmentation(
-                org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.topology.rev180226.Node1.class);
-        List<org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.topology.rev180226.networks
-            .network.node.TerminationPoint> allTps = nodeTp.getTerminationPoint();
+        org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.topology.rev180226.Node1 nodeTp
+            = this.node.augmentation(org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang
+                .ietf.network.topology.rev180226.Node1.class);
+        List<org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.topology.rev180226.networks.network
+            .node.TerminationPoint> allTps = nodeTp.getTerminationPoint();
         this.valid = false;
         if (allTps == null) {
-            LOG.error("initXndrTps: XPONDER TerminationPoint list is empty for node {}", this.toString());
+            LOG.error("PceOtnNode: initXndrTps: XPONDER TerminationPoint list is empty for node {}", this.toString());
             return;
         }
 
-        for (org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.topology.rev180226.networks
-                .network.node.TerminationPoint tp : allTps) {
-            TerminationPoint1 otnTp1 = tp.augmentation(TerminationPoint1.class);
+        for (org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.topology.rev180226.networks.network
+            .node.TerminationPoint tp : allTps) {
+            org.opendaylight.yang.gen.v1.http.org.openroadm.common.network.rev181130.@Nullable TerminationPoint1 ocnTp1
+                = tp.augmentation(org.opendaylight.yang.gen.v1.http.org.openroadm.common.network.rev181130
+                .TerminationPoint1.class);
             //TODO many nested if-structures below, this needs to be reworked
-            if (otnTp1.getTpType() == OpenroadmTpType.XPONDERNETWORK) {
-                if (otnTp1.getXpdrTpPortConnectionAttributes().getWavelength() != null) {
-                    this.usedXpdrNWTps.add(tp.getTpId().getValue());
+            if (OpenroadmTpType.XPONDERNETWORK.equals(ocnTp1.getTpType()) && this.otnServiceType.equals("ODU4")) {
+                TerminationPoint1 ontTp1;
+                if (tp.augmentation(TerminationPoint1.class) != null) {
+                    ontTp1 = tp.augmentation(TerminationPoint1.class);
+                } else {
+                    continue;
+                }
+                if (checkTpForOdtuTermination(ontTp1)) {
+                    LOG.info("TP {} of XPONDER {} is validated", tp.getTpId(), node.getNodeId().getValue());
+                    this.availableXpdrNWTps.add(tp.getTpId());
+                } else {
+                    LOG.error("TP {} of {} does not allow ODU4 termination creation", tp.getTpId().getValue(),
+                        node.getNodeId().getValue());
+                }
+            } else if (OpenroadmTpType.XPONDERNETWORK.equals(ocnTp1.getTpType())
+                && (this.otnServiceType.equals("10GE") || this.otnServiceType.equals("1GE"))) {
+                TerminationPoint1 ontTp1;
+                if (tp.augmentation(TerminationPoint1.class) != null) {
+                    ontTp1 = tp.augmentation(TerminationPoint1.class);
+                } else {
+                    continue;
+                }
+                if ("10GE".equals(otnServiceType) && checkOdtuTTPforLoOduCreation(ontTp1, 10)
+                    || "1GE".equals(otnServiceType) && checkOdtuTTPforLoOduCreation(ontTp1, 1)) {
+                    LOG.info("TP {} of XPONDER {} is validated", tp.getTpId(), node.getNodeId().getValue());
+                    this.availableXpdrNWTps.add(tp.getTpId());
                 } else {
-                    // find server of this network TP
-                    String server = otnTp1.getXpdrTpPortConnectionAttributes().getTailEquipmentId();
-                    if ((server.equals("")) || (server == null)) {
-                        this.unusableXpdrNWTps.add(tp.getTpId().getValue());
+                    if ("10GE".equals(otnServiceType)) {
+                        LOG.error("TP {} of {} does not allow OD2e termination creation", tp.getTpId().getValue(),
+                            node.getNodeId().getValue());
+                    } else if ("1GE".equals(otnServiceType)) {
+                        LOG.error("TP {} of {} does not allow ODU0 termination creation", tp.getTpId().getValue(),
+                            node.getNodeId().getValue());
                     } else {
-                        // tp is not used and as a tail to server WDM layer
-                        if (("10GE".equals(this.otnServiceType)) || ("1GE".equals(this.otnServiceType))) {
-                            // LO-ODU needs to be created on a parent HO-ODU
-                            // interface
-                            List<OdtuTpnPool> presenceOdtu =
-                                otnTp1.getXpdrTpPortConnectionAttributes().getOdtuTpnPool();
-                            if (presenceOdtu == null) {
-                                this.unusableXpdrNWTps.add(tp.getTpId().getValue());
-                            } else {
-                                List<SupportedInterfaceCapability> sic =
-                                    otnTp1.getTpSupportedInterfaces().getSupportedInterfaceCapability();
-                                if ((findNetworkCompliantInterface(sic)) & (checkAvailableTribPort(tp))
-                                    & (checkAvailableTribSlot(tp))) {
-                                    this.availableXponderTp.put(tp.getTpId().getValue(),
-                                        OpenroadmTpType.XPONDERNETWORK);
-                                    availableNetworkTpNumber++;
-                                }
-                                /*
-                                 * Add the retrieval of outgoing ingoing links
-                                 * through an external function
-                                 */
-                            }
-                        } else {
-                            // service is HO service
-                            List<SupportedInterfaceCapability> sic =
-                                otnTp1.getTpSupportedInterfaces().getSupportedInterfaceCapability();
-                            if (findNetworkCompliantInterface(sic)) {
-                                this.availableXponderTp.put(tp.getTpId().getValue(), OpenroadmTpType.XPONDERNETWORK);
-                                availableNetworkTpNumber++;
-                                /*
-                                 * Add the retrieval of outgoing ingoing links
-                                 * through an external function
-                                 */
-                            } else {
-                                this.unusableXpdrNWTps.add(tp.getTpId().getValue());
-
-                            }
+                        LOG.error("TP {} of {} does not allow any termination creation", tp.getTpId().getValue(),
+                            node.getNodeId().getValue());
+                    }
+                }
+            } else if (OpenroadmTpType.XPONDERCLIENT.equals(ocnTp1.getTpType())
+                && (this.otnServiceType.equals("10GE") || this.otnServiceType.equals("1GE"))) {
+                TerminationPoint1 ontTp1;
+                if (tp.augmentation(TerminationPoint1.class) != null) {
+                    ontTp1 = tp.augmentation(TerminationPoint1.class);
+                } else {
+                    continue;
+                }
+                if (checkClientTp(ontTp1)) {
+                    LOG.info("TP {} of XPONDER {} is validated", tp.getTpId(), node.getNodeId().getValue());
+                    this.availableXpdrClientTps.add(tp.getTpId());
+                } else {
+                    LOG.error("TP {} of {} does not allow lo-ODU (ODU2e or ODU0) termination creation",
+                        tp.getTpId().getValue(), node.getNodeId().getValue());
+                }
+            }
+        }
 
-                        }
+        if ((this.otnServiceType.equals("ODU4") && mode.equals("AZ"))
+            || ((this.otnServiceType.equals("10GE") || this.otnServiceType.equals("1GE"))
+                && mode.equals("AZ") && checkSwPool(availableXpdrClientTps, availableXpdrNWTps, 1, 1))
+            || ((this.otnServiceType.equals("10GE") || this.otnServiceType.equals("1GE"))
+                && mode.equals("intermediate") && checkSwPool(null, availableXpdrNWTps, 0, 2))) {
+            this.valid = true;
+        } else {
+            this.valid = false;
+        }
+    }
 
+    private boolean checkSwPool(List<TpId> clientTps, List<TpId> netwTps, int nbClient, int nbNetw) {
+        if (clientTps != null && netwTps != null && nbClient == 1 && nbNetw == 1) {
+            clientTps.sort(Comparator.comparing(TpId::getValue));
+            netwTps.sort(Comparator.comparing(TpId::getValue));
+            for (TpId nwTp : netwTps) {
+                for (TpId clTp : clientTps) {
+                    @Nullable
+                    List<NonBlockingList> nblList = node.augmentation(Node1.class).getSwitchingPools()
+                        .getOduSwitchingPools().get(0).getNonBlockingList();
+                    for (NonBlockingList nbl : nblList) {
+                        if (nbl.getTpList().contains(clTp) && nbl.getTpList().contains(nwTp)) {
+                            usableXpdrClientTps.add(clTp);
+                            usableXpdrNWTps.add(nwTp);
+                        }
+                        if (usableXpdrClientTps.size() >= nbClient && usableXpdrNWTps.size() >= nbNetw) {
+                            clientPerNwTp.put(nwTp.getValue(), clTp.getValue());
+                            return true;
+                        }
                     }
-
                 }
+            }
 
-                // The port is not a network port
-            } else if (otnTp1.getTpType() == OpenroadmTpType.XPONDERCLIENT) {
-                // For Client port we verify that it supports needed interfaces
-                // TBD : How shall we check a client port is available and not
-                // in use?
-                List<SupportedInterfaceCapability> sic =
-                    otnTp1.getTpSupportedInterfaces().getSupportedInterfaceCapability();
-                if (findClientCompliantInterface(sic)) {
-                    this.availableXponderTp.put(tp.getTpId().getValue(), OpenroadmTpType.XPONDERCLIENT);
-                    availableClientTpNumber++;
+        }
+        if (clientTps == null && netwTps != null && nbClient == 0 && nbNetw == 2) {
+            netwTps.sort(Comparator.comparing(TpId::getValue));
+            @Nullable
+            List<NonBlockingList> nblList = node.augmentation(Node1.class).getSwitchingPools().getOduSwitchingPools()
+                .get(0).getNonBlockingList();
+            for (NonBlockingList nbl : nblList) {
+                for (TpId nwTp : netwTps) {
+                    if (nbl.getTpList().contains(nwTp)) {
+                        usableXpdrNWTps.add(nwTp);
+                    }
+                    if (usableXpdrNWTps.size() >= nbNetw) {
+                        return true;
+                    }
                 }
             }
-            LOG.debug("initXndrTps: XPONDER tp = {} is used", tp.getTpId().getValue());
-            LOG.error("initXndrTps: XPONDER {} NW TP doesn't have defined server ROADM SRG {}", this.toString(), tp
-                .getTpId().getValue());
         }
-        if ("AZ".equals(mode)) {
-            if ((availableClientTpNumber >= 1) || (availableNetworkTpNumber >= 1)) {
-                // for A and Z node we need to have one valid client port & one
-                // valid network port
-                this.valid = true;
-            }
-        } else if ("intermediate".equals(mode)) {
-            if ((availableNetworkTpNumber >= 2)) {
-                // for OTN switching node used in transit we need to have two
-                // valid network ports
-                this.valid = true;
+        return false;
+    }
+
+    private boolean checkTpForOdtuTermination(TerminationPoint1 ontTp1) {
+        for (SupportedInterfaceCapability sic : ontTp1.getTpSupportedInterfaces().getSupportedInterfaceCapability()) {
+            LOG.debug("in checkTpForOduTermination - sic = {}", sic.getIfCapType());
+            if (sic.getIfCapType().equals(IfOCHOTU4ODU4.class)
+                && ontTp1.getXpdrTpPortConnectionAttributes().getTsPool() == null) {
+                return true;
             }
         }
+        return false;
+    }
 
-        if (!isValid()) {
-            LOG.debug("initXndrTps: XPONDER doesn't have the required ports available  {}", this.toString());
-            return;
+    private boolean checkOdtuTTPforLoOduCreation(TerminationPoint1 ontTp1, int tsNb) {
+        if (ontTp1.getXpdrTpPortConnectionAttributes() != null
+            && ontTp1.getXpdrTpPortConnectionAttributes().getTsPool() != null
+            && ontTp1.getXpdrTpPortConnectionAttributes().getOdtuTpnPool() != null
+            && ontTp1.getXpdrTpPortConnectionAttributes().getOdtuTpnPool().get(0).getOdtuType()
+                .equals(ODTU4TsAllocated.class)
+            && ontTp1.getXpdrTpPortConnectionAttributes().getOdtuTpnPool().get(0).getTpnPool().size() >= 1
+            && ontTp1.getXpdrTpPortConnectionAttributes().getTsPool().size() >= tsNb) {
+            return true;
         } else {
-            LOG.debug("initXndrTps: XPONDER {} is elligible", this.toString());
+            return false;
+        }
+    }
+
+    private boolean checkClientTp(TerminationPoint1 ontTp1) {
+        for (SupportedInterfaceCapability sic : ontTp1.getTpSupportedInterfaces().getSupportedInterfaceCapability()) {
+            LOG.debug("in checkTpForOduTermination - sic = {}", sic.getIfCapType());
+            switch (otnServiceType) {
+                case "1GE":
+                // we could also check the administrative status of the tp
+                    if (sic.getIfCapType().equals(If1GEODU0.class)) {
+                        return true;
+                    }
+                    break;
+                case "10GE":
+                    if (sic.getIfCapType().equals(If10GEODU2e.class)) {
+                        return true;
+                    }
+                    break;
+                case "100GE":
+                    if (sic.getIfCapType().equals(If100GEODU4.class)) {
+                        return true;
+                    }
+                    break;
+                default:
+                    break;
+            }
         }
+        return false;
     }
 
     private Boolean findClientCompliantInterface(List<SupportedInterfaceCapability> sic) {
         boolean compliant = false;
         for (SupportedInterfaceCapability sit : sic) {
-            String interfacetype = sit.getIfCapType().toString();
+            String interfacetype = sit.getIfCapType().getName();
             switch (interfacetype) {
                 case "If1GEODU0":
                 case "If1GE":
@@ -225,7 +297,7 @@ public class PceOtnNode extends PceNode {
                     break;
                 case "IfOTU4ODU4":
                 case "IfOCHOTU4ODU4":
-                    if (("OTU4".equals(this.otnServiceType)) || ("ODU4".equals(this.otnServiceType))) {
+                    if ("OTU4".equals(this.otnServiceType) || "ODU4".equals(this.otnServiceType)) {
                         compliant = true;
                     }
                     break;
@@ -233,7 +305,6 @@ public class PceOtnNode extends PceNode {
                     compliant = false;
                     break;
             }
-
         }
         return compliant;
     }
@@ -258,82 +329,31 @@ public class PceOtnNode extends PceNode {
                     compliant = false;
                     break;
             }
-
         }
         return compliant;
     }
 
-    private String getClliSupNodeId(Node inputNode) {
-        TreeMap<String, String> allSupNodes = new TreeMap<String, String>();
-        String tempNetworkSupNodeId = "";
-        allSupNodes = MapUtils.getAllSupNode(inputNode);
-        if (allSupNodes.get(NetworkUtils.CLLI_NETWORK_ID) == null) {
-            LOG.error("getClliSupNodeId: No Supporting node at CLLI layer for node: [{}].", inputNode.getNodeId());
-        } else {
-            tempNetworkSupNodeId = allSupNodes.get(NetworkUtils.CLLI_NETWORK_ID);
-        }
-        return tempNetworkSupNodeId;
-    }
-
-    private String getNetworkSupNodeId(Node inputNode) {
-        TreeMap<String, String> allSupNodes = new TreeMap<String, String>();
-        String tempNetworkSupNodeId = "";
-        allSupNodes = MapUtils.getAllSupNode(inputNode);
-        if (allSupNodes.get(NetworkUtils.UNDERLAY_NETWORK_ID) == null) {
-            LOG.error(
-                "getNetworkSupNodeId: No Supporting node at NETWORK layer for node: [{}].", inputNode.getNodeId());
-        } else {
-            tempNetworkSupNodeId = allSupNodes.get(NetworkUtils.UNDERLAY_NETWORK_ID);
-        }
-        return tempNetworkSupNodeId;
-    }
-
-    private String getTopoSupNodeId(Node inputNode) {
-        TreeMap<String, String> allSupNodes = new TreeMap<String, String>();
-        String tempTopoSupNodeId = "";
-        allSupNodes = MapUtils.getAllSupNode(inputNode);
-        if (allSupNodes.get(NetworkUtils.OVERLAY_NETWORK_ID) == null) {
-            LOG.error(
-                "getTopologySupNodeId: No Supporting node at TOPOLOGY layer for node: [{}].", inputNode.getNodeId());
-        } else {
-            tempTopoSupNodeId = allSupNodes.get(NetworkUtils.OVERLAY_NETWORK_ID);
-        }
-        return tempTopoSupNodeId;
-    }
-
-    public void validateAZxponder(String anodeId, String znodeId) {
+    public void validateXponder(String anodeId, String znodeId) {
         if (!isValid()) {
             return;
         }
-        if ((this.nodeType != OpenroadmNodeType.MUXPDR) & (this.nodeType != OpenroadmNodeType.SWITCH)
-            & (this.nodeType != OpenroadmNodeType.TPDR)) {
-            return;
+        if (OpenroadmNodeType.SWITCH.equals(this.nodeType)) {
+            initXndrTps("intermediate");
         }
-        // Detect A and Z, a/znodeId correspond to otn layer, supporting node
-        // might be of Network or Topology layer
-        if (this.nodeId.equals(anodeId) || (this.nodeId.equals(znodeId))) {
+        if (this.nodeId.getValue().equals(anodeId) || (this.nodeId.getValue().equals(znodeId))) {
             initXndrTps("AZ");
-            if (!this.valid) {
-                LOG.debug("validateAZxponder: XPONDER unusable for A or Z == {}", nodeId.getValue());
-            } else {
-                LOG.info("validateAZxponder: A or Z node detected and validated == {}", nodeId.getValue());
-            }
-            return;
         } else {
-            LOG.debug("validateAZxponder: XPONDER is ignored == {}", nodeId.getValue());
+            LOG.info("validateAZxponder: XPONDER is ignored == {}", nodeId.getValue());
             valid = false;
         }
-
     }
 
     public boolean validateSwitchingPoolBandwidth(
-            Node node,
-            org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.topology.rev180226.networks
-                .network.node.TerminationPoint tp1,
-            org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.topology.rev180226.networks
-                .network.node.TerminationPoint tp2,
+            org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang
+                .ietf.network.topology.rev180226.networks.network.node.TerminationPoint tp1,
+            org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang
+                .ietf.network.topology.rev180226.networks.network.node.TerminationPoint tp2,
             Long neededBW) {
-        Long availableBW = 0L;
         if (this.nodeType != OpenroadmNodeType.TPDR) {
             return true;
         } else {
@@ -355,13 +375,11 @@ public class PceOtnNode extends PceNode {
                         }
                     }
                 }
-
             }
             LOG.debug("validateSwitchingPoolBandwidth: No valid Switching pool for crossconnecting tp {} and {}",
                 tp1.getTpId().toString(), tp2.getTpId().toString());
             return false;
         }
-
     }
 
     public void validateIntermediateSwitch() {
@@ -379,90 +397,61 @@ public class PceOtnNode extends PceNode {
             LOG.info("validateIntermediateSwitch: Switch usable for transit == {}", nodeId.getValue());
         }
         return;
-
     }
 
-    public boolean checkAvailableTribPort(
-                org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.topology.rev180226.networks
-                    .network.node.TerminationPoint tp) {
-        boolean compatibleSupInt = false;
-        TerminationPoint1 otnTp1 = tp.augmentation(TerminationPoint1.class);
-        if (otnTp1.getTpType() == OpenroadmTpType.XPONDERNETWORK) {
-            try {
-                List<OdtuTpnPool> otpp = otnTp1.getXpdrTpPortConnectionAttributes().getOdtuTpnPool();
-
-                for (OdtuTpnPool otppi : otpp) {
-                    if (otppi.getOdtuType().getClass().equals(ODTU4TsAllocated.class)) {
-                        this.tpAvailableTribPort.put(tp.getTpId().getValue(), otppi.getTpnPool());
-                        LOG.debug("checkAvailableTribPort: tp {} and his trib Ports have been added to "
-                            + "tpAvailableTribPortMap", tp.getTpId().getValue());
-                        compatibleSupInt = true;
-
-                    }
+    public void checkAvailableTribPort() {
+        List<TerminationPoint> networkTpList = node.augmentation(
+            org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.topology.rev180226.Node1.class)
+            .getTerminationPoint().stream()
+            .filter(type -> type
+                .augmentation(
+                    org.opendaylight.yang.gen.v1.http.org.openroadm.common.network.rev181130.TerminationPoint1.class)
+                .getTpType().equals(OpenroadmTpType.XPONDERNETWORK))
+            .collect(Collectors.toList());
+
+        for (TerminationPoint tp : networkTpList) {
+            if (tp.augmentation(TerminationPoint1.class).getXpdrTpPortConnectionAttributes().getOdtuTpnPool() != null
+                && tp.augmentation(TerminationPoint1.class).getXpdrTpPortConnectionAttributes().getOdtuTpnPool().get(0)
+                    .getOdtuType().equals(ODTU4TsAllocated.class)) {
+                @Nullable
+                List<Integer> tpnPool = tp.augmentation(TerminationPoint1.class).getXpdrTpPortConnectionAttributes()
+                    .getOdtuTpnPool().get(0).getTpnPool();
+                if (tpnPool != null) {
+                    tpAvailableTribPort.put(tp.getTpId().getValue(), tpnPool);
                 }
-            } catch (NullPointerException e) {
-                LOG.debug("checkAvailableTribPort: OdtuTpnPool not present for tp {} ", tp.getTpId().toString());
             }
-
-        } else {
-            LOG.debug("checkAvailableTribPort: tp {} has no odtu tpn Pool", tp.getTpId().getValue());
         }
-        return compatibleSupInt;
     }
 
-    public boolean checkAvailableTribSlot(
-            org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.topology.rev180226.networks
-                .network.node.TerminationPoint tp) {
-        boolean compatibleSupInt = false;
-        TerminationPoint1 otnTp1 = tp.augmentation(TerminationPoint1.class);
-        if (otnTp1.getTpType() == OpenroadmTpType.XPONDERNETWORK) {
-            List<OdtuTpnPool> otpp;
-            try {
-                otpp = otnTp1.getXpdrTpPortConnectionAttributes().getOdtuTpnPool();
-
-                for (OdtuTpnPool otppi : otpp) {
-                    if (otppi.getOdtuType().getClass().equals(ODTU4TsAllocated.class)) {
-                        this.tpAvailableTribSlot.put(
-                            tp.getTpId().getValue(),
-                            otnTp1.getXpdrTpPortConnectionAttributes().getTsPool());
-                        LOG.debug(
-                            "checkAvailableTribPort: tp {} and its trib Slots were added to tpAvailableTribSlotMap",
-                            tp.getTpId().getValue());
-                        compatibleSupInt = true;
-
-                    }
-                }
-
-            } catch (NullPointerException e) {
-                LOG.debug("checkAvailableTribSlot: OdtuTpnPool not present for tp {} ", tp.getTpId().toString());
+    public void checkAvailableTribSlot() {
+        List<TerminationPoint> networkTpList = node.augmentation(
+            org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.topology.rev180226.Node1.class)
+            .getTerminationPoint().stream()
+            .filter(type -> type
+                .augmentation(
+                    org.opendaylight.yang.gen.v1.http.org.openroadm.common.network.rev181130.TerminationPoint1.class)
+                .getTpType().equals(OpenroadmTpType.XPONDERNETWORK))
+            .collect(Collectors.toList());
+
+        for (TerminationPoint tp : networkTpList) {
+            if (tp.augmentation(TerminationPoint1.class).getXpdrTpPortConnectionAttributes().getTsPool() != null) {
+                @Nullable
+                List<Integer> tsPool = tp.augmentation(TerminationPoint1.class).getXpdrTpPortConnectionAttributes()
+                    .getTsPool();
+                tpAvailableTribSlot.put(tp.getTpId().getValue(), tsPool);
             }
-        } else {
-            LOG.debug("checkAvailableTribPort: tp {} is not a network Port", tp.getTpId().getValue());
         }
-        return compatibleSupInt;
-    }
-
-    public String getXpdrClient(String tp) {
-        return this.clientPerNwTp.get(tp);
-    }
-
-    public boolean checkTP(String tp) {
-        return !((this.usedXpdrNWTps.contains(tp)) || (this.usedXpdrClientTps.contains(tp))
-            || (this.unusableXpdrNWTps.contains(tp)) || (this.unusableXpdrClientTps.contains(tp)));
     }
 
     public boolean isValid() {
-        if ((node == null) || (nodeId == null) || (nodeType == null) || (supNetworkNodeId == null) || (clli == null)) {
+        if ((node == null) || (nodeId == null) || (nodeType == null) || (this.getSupNetworkNodeId() == null)
+            || (this.getSupClliNodeId() == null)) {
             LOG.error("PceNode: one of parameters is not populated : nodeId, node type, supporting nodeId");
             valid = false;
         }
         return valid;
     }
 
-    public Map<String, OpenroadmTpType> getAvailableTps() {
-        return availableXponderTp;
-    }
-
     public void addOutgoingLink(PceLink outLink) {
         this.outgoingLinks.add(outLink);
     }
@@ -471,36 +460,72 @@ public class PceOtnNode extends PceNode {
         return outgoingLinks;
     }
 
-    public String getClient(String tp) {
-        return clientPerNwTp.get(tp);
-    }
-
-    public String getTopoSupNodeIdPceNode() {
-        return supTopoNodeId;
-    }
-
-    public String getNetworkSupNodeIdPceNode() {
-        return supNetworkNodeId;
-    }
-
-    public String getCLLI() {
-        return clli;
+    @Override
+    public String getXpdrClient(String tp) {
+        return this.clientPerNwTp.get(tp);
     }
 
     public String toString() {
-        return "PceNode type=" + nodeType + " ID=" + nodeId.getValue() + " CLLI=" + clli;
+        return "PceNode type=" + nodeType + " ID=" + nodeId.getValue() + " CLLI=" + this.getSupClliNodeId();
     }
 
     public void printLinksOfNode() {
         LOG.info(" outgoing links of node {} : {} ", nodeId.getValue(), this.getOutgoingLinks().toString());
     }
 
+    @Override
     public Map<String, List<Integer>> getAvailableTribPorts() {
         return tpAvailableTribPort;
     }
 
+    @Override
     public Map<String, List<Integer>> getAvailableTribSlots() {
         return tpAvailableTribSlot;
     }
 
+    public List<TpId> getUsableXpdrNWTps() {
+        return usableXpdrNWTps;
+    }
+
+    public List<TpId> getUsableXpdrClientTps() {
+        return usableXpdrClientTps;
+    }
+
+    @Override
+    public String getPceNodeType() {
+        return this.pceNodeType;
+    }
+
+    @Override
+    public String getSupNetworkNodeId() {
+        return MapUtils.getSupNetworkNode(this.node);
+    }
+
+    @Override
+    public String getSupClliNodeId() {
+        return MapUtils.getSupClliNode(this.node);
+    }
+
+    @Override
+    public String getRdmSrgClient(String tp) {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public NodeId getNodeId() {
+        return nodeId;
+    }
+
+    @Override
+    public boolean checkTP(String tp) {
+        // TODO Auto-generated method stub
+        return false;
+    }
+
+    @Override
+    public boolean checkWL(long index) {
+        // TODO Auto-generated method stub
+        return false;
+    }
 }
index aea19299ff1f855c71e3e8e67347f0c5ad330f62..d3139777564c600c498e36715acf630f6591052f 100644 (file)
@@ -8,6 +8,9 @@
 
 package org.opendaylight.transportpce.pce.networkanalyzer;
 
+import java.util.List;
+import java.util.Map;
+
 import org.opendaylight.transportpce.common.ResponseCodes;
 import org.opendaylight.yang.gen.v1.http.org.openroadm.service.format.rev190531.ServiceFormat;
 import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.pathdescription.rev171017.path.description.AToZDirection;
@@ -22,6 +25,12 @@ public class PceResult {
     private boolean calcStatus = false;
     private String responseCode = ResponseCodes.RESPONSE_FAILED;
     private long resultWavelength = -1;
+    private Map<String, Integer> resultTribPort;
+    private Map<String, List<Integer>> resultTribSlot;
+    private Integer resultTribSlotNb = -1;
+    private String serviceType = "";
+
+    // for now it is constant returned as received from A-end
     private long rate = -1;
     private  ServiceFormat serviceFormat = ServiceFormat.OC;
 
@@ -55,9 +64,8 @@ public class PceResult {
     }
 
     public String toString() {
-        return ("[" + calcMessage + "] code:[" + responseCode + "] wavelength="
-                + resultWavelength + " localCause=" + localCause + " rate="
-                + rate);
+        return ("[" + calcMessage + "] code:[" + responseCode + "] wavelength=" + resultWavelength + " localCause="
+                + localCause + " rate=" + rate + " serviceType = " + serviceType);
     }
 
     public boolean getStatus() {
@@ -129,4 +137,36 @@ public class PceResult {
         this.calcMessage = calcMessage;
     }
 
+    public Map<String, Integer> getResultTribPort() {
+        return resultTribPort;
+    }
+
+    public void setResultTribPort(Map<String, Integer> resultTribPort) {
+        this.resultTribPort = resultTribPort;
+    }
+
+    public Map<String, List<Integer>> getResultTribSlot() {
+        return resultTribSlot;
+    }
+
+    public void setResultTribSlot(Map<String, List<Integer>> resultTribSlot) {
+        this.resultTribSlot = resultTribSlot;
+    }
+
+    public int getResultTribSlotNb() {
+        return resultTribSlotNb;
+    }
+
+    public void setResultTribSlotNb(int resultTribSlotNb) {
+        this.resultTribSlotNb = resultTribSlotNb;
+    }
+
+    public String getServiceType() {
+        return serviceType;
+    }
+
+    public void setServiceType(String serviceType) {
+        this.serviceType = serviceType;
+    }
+
 }
index e42ae9f730b42583b83588b93882bd481241de96..2eae636cbf3f790aa1c268f2aa09e3efd0488c5a 100644 (file)
@@ -282,7 +282,7 @@ public class TapiTopologyImpl implements TapiTopologyService {
         Link> xpdIn) {
         @Nullable
         String networkLcp = tp.augmentation(
-            org.opendaylight.yang.gen.v1.http.transportpce.topology.rev200123.TerminationPoint1.class)
+            org.opendaylight.yang.gen.v1.http.transportpce.topology.rev200129.TerminationPoint1.class)
             .getAssociatedConnectionMapPort();
         @NonNull
         KeyedInstanceIdentifier<Mapping, MappingKey> pmIID = InstanceIdentifier.create(