Consolidation of the PCE 31/86431/8
authoratriki <ahmed.triki.tn@gmail.com>
Thu, 12 Dec 2019 14:27:36 +0000 (15:27 +0100)
committeratriki <ahmed.triki.tn@gmail.com>
Wed, 5 Feb 2020 14:35:22 +0000 (15:35 +0100)
- change k from 10 to 100 in the case of nodes inclusion in the hard
constraints and in the case when a first execution of k-shortest-path
failed
- conslidate the osnr calculation
- add the OUT_OF_SPEC_OSNR as a cause of path computation failure
- add the HD_NODE_INCLUDE as a cause of path computation failure
- detect TOO_HIGH_LATENCY in the case where the MaxLatency is exceeded
- Verfication of MaxLatency and node inclusion violation in
postAlgoPathValidator instead of inAlgoPathValidator
- change the name of the method calcPath() of PceCalculation to
retrievePceNetwork()

JIRA: TRNSPRTPCE-146, TRNSPRTPCE-147, TRNSPRTPCE-93
Change-Id: Ie2f8bf502af81de857dadbdc5a879f5c4b10c96b
Signed-off-by: atriki <ahmed.triki.tn@gmail.com>
pce/src/main/java/org/opendaylight/transportpce/pce/PceSendingPceRPCs.java
pce/src/main/java/org/opendaylight/transportpce/pce/constraints/PceConstraints.java
pce/src/main/java/org/opendaylight/transportpce/pce/gnpy/ServiceDataStoreOperationsImpl.java
pce/src/main/java/org/opendaylight/transportpce/pce/graph/InAlgoPathValidator.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/PceCalculation.java
pce/src/main/java/org/opendaylight/transportpce/pce/networkanalyzer/PceLink.java
pce/src/main/java/org/opendaylight/transportpce/pce/networkanalyzer/PceResult.java

index 4b6b05133d6e20ca7980abbdd31530dfffe380f8..e8f0f9aaca300146f0baf8b2b4773e3284c8d218 100755 (executable)
@@ -91,7 +91,7 @@ public class PceSendingPceRPCs {
 
         PceCalculation nwAnalizer =
             new PceCalculation(input, networkTransaction, hardConstraints, softConstraints, rc);
-        nwAnalizer.calcPath();
+        nwAnalizer.retrievePceNetwork();
         rc = nwAnalizer.getReturnStructure();
         if (!rc.getStatus()) {
             LOG.error("In pathComputationWithConstraints, nwAnalizer: result = {}", rc.toString());
@@ -104,7 +104,7 @@ public class PceSendingPceRPCs {
         graph.calcPath();
         rc = graph.getReturnStructure();
         if (!rc.getStatus()) {
-            LOG.warn("In pathComputation : Graph return without Path ");
+            LOG.warn("In pathComputationWithConstraints : Graph return without Path ");
             // TODO fix. This is quick workaround for algorithm problem
             if ((rc.getLocalCause() == PceResult.LocalCause.TOO_HIGH_LATENCY)
                 && (hardConstraints.getPceMetrics() == PceMetric.HopCount)
@@ -112,6 +112,12 @@ public class PceSendingPceRPCs {
                 hardConstraints.setPceMetrics(PceMetric.PropagationDelay);
                 graph = patchRerunGraph(graph);
             }
+
+            if (rc.getLocalCause() == PceResult.LocalCause.HD_NODE_INCLUDE) {
+                graph.setKpathsToBring(graph.getKpathsToBring() * 10);
+                graph = patchRerunGraph(graph);
+            }
+
             if (!rc.getStatus()) {
                 LOG.error("In pathComputationWithConstraints, graph.calcPath: result = {}", rc.toString());
                 return;
@@ -144,6 +150,7 @@ public class PceSendingPceRPCs {
             ztoa = rc.getZtoADirection();
         }
 
+        //Connect to Gnpy to check path feasibility and recompute another path in case of path non-feasibility
         try {
             ConnectToGnpyServer connectToGnpy = new ConnectToGnpyServer();
             if (connectToGnpy.isGnpyURLExist()) {
index 5b79cb9a9fef98f8315ef079deaf710d162e507c..202b42874aa28bb71a1e04aa0bb93218eadae2ff 100644 (file)
@@ -24,7 +24,7 @@ public class PceConstraints {
     private RoutingConstraintsSp.PceMetric pceMetrics = RoutingConstraintsSp.PceMetric.HopCount;
     private Long maxLatency = (long) -1;
 
-    /////////////// EXCLUDE ///////////////////
+    // Structure related to  EXCLUDE constraints
     // Nodes/CLLI/SRLG lists might consist of two types of elements : (1)from diversity constraints (2)from exclude list
     // e.g.: nodesToExclude - topo-level nodes IDs - comes from diversity constraints
     //     : supNodesToExclude - supporting nodes IDs - comes from exclude list
@@ -37,16 +37,12 @@ public class PceConstraints {
 
     private List<String> clliToExclude = new ArrayList<String>();
     private List<String> clliNodesToExclude = new ArrayList<String>();
+
+    ///Structures related to INCLUDE constraints
     private List<String> nodesToInclude = new ArrayList<String>();
     private List<PceNode> pceNodesToInclude = new ArrayList<PceNode>();
-
-    public static final Long CONST_OSNR = 1L;
-    private double maxOSNR = (CONST_OSNR / (Math.pow(10, (24 / 10.0))));
-
-    /**.
-     * /////////////// INCLUDE CONSTRAINTS.///////////////////
-     */
     private List<ResourcePair> listToInclude = new ArrayList<ResourcePair>();
+
     private List<String> srlgNames = new ArrayList<String>();
 
     public enum ResourceType {
@@ -159,11 +155,6 @@ public class PceConstraints {
         this.pceNodesToInclude.add(node);
     }
 
-    public Double getMaxOSNR() {
-        LOG.debug("in Pceconstraints getMaxOSNR = {}", maxOSNR);
-        return maxOSNR;
-    }
-
     public class ResourcePair {
         public ResourcePair(ResourceType type, String name) {
             super();
index 5d813a83c230ce069ac55e58af730713c8cedd87..5342387afa0008c5539f2b8e0b6669a168a2a45b 100644 (file)
@@ -27,7 +27,6 @@ import org.opendaylight.transportpce.common.DataStoreContext;
 import org.opendaylight.transportpce.common.converter.XMLDataObjectConverter;
 import org.opendaylight.transportpce.common.network.NetworkTransactionService;
 import org.opendaylight.yang.gen.v1.http.org.openroadm.device.rev170206.org.openroadm.device.container.OrgOpenroadmDevice;
-import org.opendaylight.yangtools.yang.binding.BindingStreamEventWriter;
 import org.opendaylight.yangtools.yang.binding.DataObject;
 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier.PathArgument;
@@ -113,8 +112,7 @@ public class ServiceDataStoreOperationsImpl implements ServiceDataStoreOperation
                 scPath.getParent(), scPath.getLastComponent().getNamespace(),
                 JsonWriterFactory.createJsonWriter(writer, 2));
             // The write part
-            final BindingStreamEventWriter bindingWriter = codecRegistry.newWriter(id, domWriter);
-            codecRegistry.getSerializer(id.getTargetType()).serialize(object, bindingWriter);
+            codecRegistry.getSerializer(id.getTargetType()).serialize(object, codecRegistry.newWriter(id, domWriter));
             domWriter.close();
             writer.close();
         } catch (IOException | YangSyntaxErrorException | ReactorException e) {
index 768fb41f84c370bb0893663a0522083338bb76b4..963ce456413e58fa0ec5b49bd7c8acf222ec61f1 100644 (file)
@@ -8,14 +8,8 @@
 
 package org.opendaylight.transportpce.pce.graph;
 
-import java.util.ArrayList;
-import java.util.List;
-
 import org.jgrapht.GraphPath;
 import org.jgrapht.alg.shortestpath.PathValidator;
-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.yang.gen.v1.http.org.openroadm.network.types.rev181130.OpenroadmLinkType;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -24,13 +18,8 @@ public class InAlgoPathValidator implements PathValidator<String, PceGraphEdge>
     /* Logging. */
     private static final Logger LOG = LoggerFactory.getLogger(PceGraph.class);
 
-    private PceConstraints pceHardConstraints = null;
-    private PceNode zendNode = null;
-
-    public InAlgoPathValidator(PceConstraints pceHardConstraints, PceNode zendNode) {
+    public InAlgoPathValidator() {
         super();
-        this.pceHardConstraints = pceHardConstraints;
-        this.zendNode = zendNode;
     }
 
     @Override
@@ -42,9 +31,7 @@ public class InAlgoPathValidator implements PathValidator<String, PceGraphEdge>
         LOG.debug("InAlgoPathValidator: partialPath size: {} prev edge {} new edge {}",
             size, edge.link().getlinkType(), partialPath.getEdgeList().get(size - 1).link().getlinkType());
 
-        if ((!checkTurn(partialPath.getEdgeList().get(size - 1).link().getlinkType(), edge.link().getlinkType()))
-            || (!checkLimits(partialPath, edge, pceHardConstraints))
-            || (!checkInclude(partialPath, edge, zendNode, pceHardConstraints))) {
+        if ((!checkTurn(partialPath.getEdgeList().get(size - 1).link().getlinkType(), edge.link().getlinkType()))) {
             return false;
         } else {
             return true;
@@ -86,147 +73,4 @@ public class InAlgoPathValidator implements PathValidator<String, PceGraphEdge>
         return true;
     }
 
-    /*
-     * this method should be added to JgraphT as accumulated values inside path
-     * (RankingPathElementList)
-     */
-    private boolean checkLimits(GraphPath<String, PceGraphEdge> partialPath,
-                                PceGraphEdge edge, PceConstraints pceHardConstraintsInput) {
-
-        Long latencyConstraint = pceHardConstraintsInput.getMaxLatency();
-        if (latencyConstraint > 0) {
-            long newLatency = Math.round(calcLatency(partialPath) + edge.link().getLatency());
-            if (newLatency > latencyConstraint) {
-                LOG.warn("In validateLatency: AtoZ path is dropped because of MAX LATENCY {} > {}",
-                    newLatency, latencyConstraint);
-                return false;
-            }
-        }
-
-        return true;
-    }
-
-    private double calcLatency(GraphPath<String, PceGraphEdge> path) {
-        double latency = 0;
-        for (PceGraphEdge edge : path.getEdgeList()) {
-            latency = latency + edge.link().getLatency();
-        }
-        return latency;
-    }
-
-    /*
-     * checkInclude this method ensures the path is going over path elements
-     * to be included, alway check target node in the new edge
-     *
-     */
-    private boolean checkInclude(GraphPath<String, PceGraphEdge> partialPath,
-                                 PceGraphEdge edge, PceNode zendNodeInput,
-                                 PceConstraints pceHardConstraintsInput) {
-
-        List<ResourcePair> listToInclude = pceHardConstraintsInput.getListToInclude();
-        if (listToInclude.isEmpty()) {
-            return true;
-        }
-
-        // run this check only for the last edge of path
-        if (!edge.link().getDestId().getValue().equals(zendNodeInput.getNodeId().getValue())) {
-            return true;
-        }
-        List<PceGraphEdge> pathEdges = partialPath.getEdgeList();
-        pathEdges.add(edge);
-        LOG.info(" in checkInclude vertex list: [{}]", partialPath.getVertexList());
-
-        List<String> listOfElementsSubNode = new ArrayList<String>();
-        listOfElementsSubNode.add(pathEdges.get(0).link().getsourceSupNodeId());
-        listOfElementsSubNode.addAll(listOfElementsBuild(pathEdges, PceConstraints.ResourceType.NODE));
-
-        List<String> listOfElementsCLLI = new ArrayList<String>();
-        listOfElementsCLLI.add(pathEdges.get(0).link().getsourceCLLI());
-        listOfElementsCLLI.addAll(listOfElementsBuild(pathEdges, PceConstraints.ResourceType.CLLI));
-
-        List<String> listOfElementsSRLG = new ArrayList<String>();
-        // first link is XPONDEROUTPUT, no SRLG for it
-        listOfElementsSRLG.add("NONE");
-        listOfElementsSRLG.addAll(listOfElementsBuild(pathEdges, PceConstraints.ResourceType.SRLG));
-
-        // validation: check each type for each element
-        for (ResourcePair next : listToInclude) {
-            int indx = -1;
-            switch (next.getType()) {
-                case NODE:
-                    if (listOfElementsSubNode.contains(next.getName())) {
-                        indx = listOfElementsSubNode.indexOf(next.getName());
-                    }
-                    break;
-                case SRLG:
-                    if (listOfElementsSRLG.contains(next.getName())) {
-                        indx = listOfElementsSRLG.indexOf(next.getName());
-                    }
-                    break;
-                case CLLI:
-                    if (listOfElementsCLLI.contains(next.getName())) {
-                        indx = listOfElementsCLLI.indexOf(next.getName());
-                    }
-                    break;
-                default:
-                    LOG.warn(" in checkInclude vertex list unsupported resource type: [{}]", next.getType());
-            }
-
-            if (indx < 0) {
-                LOG.debug(" in checkInclude stopped : {} ", next.getName());
-                return false;
-            }
-
-            LOG.debug(" in checkInclude next found {} in {}", next.getName(), partialPath.getVertexList());
-
-            listOfElementsSubNode.subList(0, indx).clear();
-            listOfElementsCLLI.subList(0, indx).clear();
-            listOfElementsSRLG.subList(0, indx).clear();
-        }
-
-        LOG.info(" in checkInclude passed : {} ", partialPath.getVertexList());
-        return true;
-    }
-
-    private List<String> listOfElementsBuild(List<PceGraphEdge> pathEdges, PceConstraints.ResourceType type) {
-        List<String> listOfElements = new ArrayList<String>();
-
-        for (PceGraphEdge link: pathEdges) {
-            switch (type) {
-                case NODE:
-                    listOfElements.add(link.link().getdestSupNodeId());
-                    break;
-                case CLLI:
-                    listOfElements.add(link.link().getdestCLLI());
-                    break;
-                case SRLG:
-                    if (link.link().getlinkType() != OpenroadmLinkType.ROADMTOROADM) {
-                        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 mentioned
-                    boolean found = false;
-                    for (Long srlg : link.link().getsrlgList()) {
-                        String srlgStr = String.valueOf(srlg);
-                        if (pceHardConstraints.getSRLGnames().contains(srlgStr)) {
-                            listOfElements.add(srlgStr);
-                            LOG.info("listOfElementsBuild. FOUND SRLG {} in link {}", srlgStr, link.link().toString());
-                            found = true;
-                            continue;
-                        }
-                    }
-                    if (!found) {
-                        // there is no specific srlg to include. thus add to list just the first one
-                        listOfElements.add("NONE");
-                    }
-                    break;
-                default:
-                    LOG.debug("listOfElementsBuild unsupported resource type");
-            }
-        }
-
-        return listOfElements;
-    }
-}
+}
\ No newline at end of file
index f4132e04cc37ba2efac2b76e09faf5a829e5d3d9..3f2210b530a8b0c9874a29f4049d7c892f4a796d 100644 (file)
@@ -35,9 +35,10 @@ public class PceGraph {
 
     ////////////////////////// for Graph ///////////////////////////
     // how many paths to bring
-    int kpathsToBring = 10;
+    private int kpathsToBring = 10;
+
     // max #hops
-    int mhopsPerPath = 50;
+    private int mhopsPerPath = 50;
 
     // input
     private Map<NodeId, PceNode> allPceNodes = new HashMap<NodeId, PceNode>();
@@ -68,7 +69,6 @@ public class PceGraph {
 
         LOG.info("In GraphCalculator: A and Z = {} / {} ", aendNode.toString(), zendNode.toString());
         LOG.debug("In GraphCalculator: allPceNodes size {}, nodes {} ", allPceNodes.size(), allPceNodes.toString());
-
     }
 
     public boolean calcPath() {
@@ -88,9 +88,8 @@ public class PceGraph {
         // validate found paths
         pceResult.setRC(ResponseCodes.RESPONSE_FAILED);
         for (GraphPath<String, PceGraphEdge> path : allWPaths) {
-
             PostAlgoPathValidator papv = new PostAlgoPathValidator();
-            pceResult = papv.checkPath(path, allPceNodes, pceResult);
+            pceResult = papv.checkPath(path, allPceNodes, pceResult, pceHardConstraints);
             LOG.info("In calcPath after PostAlgoPathValidator {} {}",
                     pceResult.getResponseCode(), ResponseCodes.RESPONSE_OK);
 
@@ -124,16 +123,7 @@ public class PceGraph {
         if (weightedGraph.edgeSet().isEmpty() || weightedGraph.vertexSet().isEmpty()) {
             return false;
         }
-
-        PathValidator<String, PceGraphEdge> wpv = new InAlgoPathValidator(pceHardConstraints, zpceNode);
-
-        // local optimization. if 'include' constraint exists then increase amount of paths to return.
-        // it's because this constraint is checked at the last step when part of good paths
-        // are dropped by other constraints
-        if (!pceHardConstraints.getListToInclude().isEmpty()) {
-            kpathsToBring = kpathsToBring * 10;
-            LOG.info("k = {}",kpathsToBring);
-        }
+        PathValidator<String, PceGraphEdge> wpv = new InAlgoPathValidator();
 
         // KShortestPaths on weightedGraph
         KShortestSimplePaths<String, PceGraphEdge> swp =
@@ -149,7 +139,7 @@ public class PceGraph {
 
         // debug print
         for (GraphPath<String, PceGraphEdge> path : allWPaths) {
-            LOG.info("path Weight: {} : {}", path.getWeight(), path.getVertexList().toString());
+            LOG.debug("path Weight: {} : {}", path.getWeight(), path.getVertexList().toString());
         }
 
         return true;
@@ -241,7 +231,18 @@ public class PceGraph {
         return weight;
     }
 
-    ////////////////////////////////////////////////////////////////////////////////////////////////////////////
+    public int getKpathsToBring() {
+        return kpathsToBring;
+    }
+
+    public void setKpathsToBring(int kpathsToBring) {
+        this.kpathsToBring = kpathsToBring;
+    }
+
+    public void setMhopsPerPath(int mhopsPerPath) {
+        this.mhopsPerPath = mhopsPerPath;
+    }
+
     public List<PceLink> getPathAtoZ() {
         return shortestPathAtoZ;
     }
index 55ea21b5fe418fadb2606753cec25edf5ed3350c..626895fd181b71486e0241f5569870f955e58a23 100644 (file)
@@ -8,12 +8,17 @@
 
 package org.opendaylight.transportpce.pce.graph;
 
+import java.util.ArrayList;
+import java.util.List;
 import java.util.Map;
 
 import org.jgrapht.GraphPath;
 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.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;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -24,32 +29,62 @@ public class PostAlgoPathValidator {
 
     // TODO hard-coded 96
     private static final int MAX_WAWELENGTH = 96;
+    private static final double MIN_OSNR_W100G = 17;
+    private static final double TRX_OSNR = 33;
+    private static final double ADD_OSNR = 30;
+    public static final Long CONST_OSNR = 1L;
+    public static final double SYS_MARGIN = 0;
 
     public PceResult checkPath(GraphPath<String, PceGraphEdge> path,
-            Map<NodeId, PceNode> allPceNodes, PceResult pceResult) {
+            Map<NodeId, PceNode> allPceNodes, PceResult pceResult, PceConstraints pceHardConstraints) {
 
+        //check if the path is empty
         if (path.getEdgeList().size() == 0) {
             pceResult.setRC(ResponseCodes.RESPONSE_FAILED);
             return pceResult;
         }
 
-        // choose wavelength available in all nodes of the path
-        pceResult.setRC(ResponseCodes.RESPONSE_FAILED);
+        //Choose wavelength available in all nodes of the path
         Long waveL = chooseWavelength(path, allPceNodes);
-        if (waveL > 0) {
-            pceResult.setResultWavelength(waveL);
-            pceResult.setRC(ResponseCodes.RESPONSE_OK);
-            LOG.info("In PostAlgoPathValidator: chooseWavelength WL found {} {}", waveL, path.toString());
+        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
-        stubCheckOSNR(path);
+        // 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) {
+            if (!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)) {
+            pceResult.setRC(ResponseCodes.RESPONSE_FAILED);
+            pceResult.setLocalCause(PceResult.LocalCause.HD_NODE_INCLUDE);
+            return pceResult;
+        }
+
+        pceResult.setRC(ResponseCodes.RESPONSE_OK);
         return pceResult;
     }
 
+    //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;
 
@@ -72,12 +107,174 @@ public class PostAlgoPathValidator {
         return wavelength;
     }
 
-    private boolean stubCheckOSNR(GraphPath<String, PceGraphEdge> path) {
-        double localOsnr = 0L;
+    //Check the latency
+    private boolean checkLatency(Long maxLatency, GraphPath<String, PceGraphEdge> path) {
+        double latency = 0;
+
+        for (PceGraphEdge edge : path.getEdgeList()) {
+            try {
+                latency += edge.link().getLatency();
+                LOG.debug("- In checkLatency: latency of {} = {} units", edge.link().getLinkId().getValue(),latency);
+            } catch (NullPointerException e) {
+                LOG.warn("- In checkLatency: the link {} does not contain latency field",
+                    edge.link().getLinkId().getValue());
+            }
+        }
+        if (latency > maxLatency) {
+            return false;
+        }
+        return true;
+    }
+
+    //Check the inclusion if it is defined in the hard constraints
+    private boolean checkInclude(GraphPath<String, PceGraphEdge> path, PceConstraints pceHardConstraintsInput) {
+        List<ResourcePair> listToInclude = pceHardConstraintsInput.getListToInclude();
+        if (listToInclude.isEmpty()) {
+            return true;
+        }
+
+        List<PceGraphEdge> pathEdges = path.getEdgeList();
+        LOG.debug(" in checkInclude vertex list: [{}]", path.getVertexList());
+
+        List<String> listOfElementsSubNode = new ArrayList<String>();
+        listOfElementsSubNode.add(pathEdges.get(0).link().getsourceSupNodeId());
+        listOfElementsSubNode.addAll(listOfElementsBuild(pathEdges, PceConstraints.ResourceType.NODE,
+            pceHardConstraintsInput));
+
+        List<String> listOfElementsCLLI = new ArrayList<String>();
+        listOfElementsCLLI.add(pathEdges.get(0).link().getsourceCLLI());
+        listOfElementsCLLI.addAll(listOfElementsBuild(pathEdges, PceConstraints.ResourceType.CLLI,
+            pceHardConstraintsInput));
+
+        List<String> listOfElementsSRLG = new ArrayList<String>();
+        // first link is XPONDEROUTPUT, no SRLG for it
+        listOfElementsSRLG.add("NONE");
+        listOfElementsSRLG.addAll(listOfElementsBuild(pathEdges, PceConstraints.ResourceType.SRLG,
+            pceHardConstraintsInput));
+
+        // validation: check each type for each element
+        for (ResourcePair next : listToInclude) {
+            int indx = -1;
+            switch (next.getType()) {
+                case NODE:
+                    if (listOfElementsSubNode.contains(next.getName())) {
+                        indx = listOfElementsSubNode.indexOf(next.getName());
+                    }
+                    break;
+                case SRLG:
+                    if (listOfElementsSRLG.contains(next.getName())) {
+                        indx = listOfElementsSRLG.indexOf(next.getName());
+                    }
+                    break;
+                case CLLI:
+                    if (listOfElementsCLLI.contains(next.getName())) {
+                        indx = listOfElementsCLLI.indexOf(next.getName());
+                    }
+                    break;
+                default:
+                    LOG.warn(" in checkInclude vertex list unsupported resource type: [{}]", next.getType());
+            }
+
+            if (indx < 0) {
+                LOG.debug(" in checkInclude stopped : {} ", next.getName());
+                return false;
+            }
+
+            LOG.debug(" in checkInclude next found {} in {}", next.getName(), path.getVertexList());
+
+            listOfElementsSubNode.subList(0, indx).clear();
+            listOfElementsCLLI.subList(0, indx).clear();
+            listOfElementsSRLG.subList(0, indx).clear();
+        }
+
+        LOG.info(" in checkInclude passed : {} ", path.getVertexList());
+        return true;
+    }
+
+    private List<String> listOfElementsBuild(List<PceGraphEdge> pathEdges, PceConstraints.ResourceType type,
+        PceConstraints pceHardConstraints) {
+
+        List<String> listOfElements = new ArrayList<String>();
+        for (PceGraphEdge link: pathEdges) {
+            switch (type) {
+                case NODE:
+                    listOfElements.add(link.link().getdestSupNodeId());
+                    break;
+                case CLLI:
+                    listOfElements.add(link.link().getdestCLLI());
+                    break;
+                case SRLG:
+                    if (link.link().getlinkType() != OpenroadmLinkType.ROADMTOROADM) {
+                        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 mentioned
+                    boolean found = false;
+                    for (Long srlg : link.link().getsrlgList()) {
+                        String srlgStr = String.valueOf(srlg);
+                        if (pceHardConstraints.getSRLGnames().contains(srlgStr)) {
+                            listOfElements.add(srlgStr);
+                            LOG.info("listOfElementsBuild. FOUND SRLG {} in link {}", srlgStr, link.link().toString());
+                            found = true;
+                            continue;
+                        }
+                    }
+                    if (!found) {
+                        // there is no specific srlg to include. thus add to list just the first one
+                        listOfElements.add("NONE");
+                    }
+                    break;
+                default:
+                    LOG.debug("listOfElementsBuild unsupported resource type");
+            }
+        }
+        return listOfElements;
+    }
+
+    //Check the path OSNR
+    private boolean checkOSNR(GraphPath<String, PceGraphEdge> path) {
+        double linkOsnrDb;
+        double osnrDb = 0;
+        LOG.info("- In checkOSNR: OSNR of the transmitter = {} dB", TRX_OSNR);
+        LOG.info("- In checkOSNR: add-path incremental OSNR = {} dB", ADD_OSNR);
+        double inverseLocalOsnr = getInverseOsnrLinkLu(TRX_OSNR) + getInverseOsnrLinkLu(ADD_OSNR);
         for (PceGraphEdge edge : path.getEdgeList()) {
-            localOsnr = localOsnr + edge.link().getosnr();
+            if (edge.link().getlinkType() == OpenroadmLinkType.ROADMTOROADM) {
+                // link OSNR in dB
+                linkOsnrDb = edge.link().getosnr();
+                LOG.info("- In checkOSNR: OSNR of {} = {} dB", edge.link().getLinkId().getValue(), linkOsnrDb);
+                // 1 over the local OSNR, in linear units
+                inverseLocalOsnr += getInverseOsnrLinkLu(linkOsnrDb);
+            }
+        }
+        try {
+            osnrDb = getOsnrDb(1 / inverseLocalOsnr);
+        }
+        catch (ArithmeticException e) {
+            LOG.debug("In checkOSNR: OSNR is equal to 0 and the number of links is: {}", path.getEdgeList().size());
+            return false;
+        }
+        LOG.info("In checkOSNR: OSNR of the path is {} dB", osnrDb);
+        if ((osnrDb + SYS_MARGIN) < MIN_OSNR_W100G) {
+            return false;
         }
-        LOG.info("In OSNR Stub: {}", localOsnr);
         return true;
     }
-}
+
+    private double getOsnrDb(double osnrLu) {
+        double osnrDb;
+        osnrDb = 10 * Math.log10(osnrLu);
+        return osnrDb;
+    }
+
+    private double getInverseOsnrLinkLu(double linkOsnrDb) {
+        // 1 over the link OSNR, in linear units
+        double linkOsnrLu;
+        linkOsnrLu = Math.pow(10, (linkOsnrDb / 10.0));
+        LOG.debug("In retrieveosnr: the inverse of link osnr is {} (Linear Unit)", linkOsnrLu);
+        return (CONST_OSNR / linkOsnrLu);
+    }
+
+}
\ No newline at end of file
index 4c5688439f04545dbdf1c5a7ddbd1b9f48d0a923..7217b0c3a90142b720a281a7c26e431a78bb764a 100644 (file)
@@ -86,9 +86,9 @@ public class PceCalculation {
         parseInput();
     }
 
-    public void calcPath() {
+    public void retrievePceNetwork() {
 
-        LOG.info("In PceCalculation calcPath: ");
+        LOG.info("In PceCalculation retrieveNetwork: ");
 
         if (!readMdSal()) {
             returnStructure.setRC(ResponseCodes.RESPONSE_FAILED);
index 3dc56b225c2172ea2ba9ad4e913d32bb4c309a3c..58215e8f29513d170fe34ed6c1ef8c934869ef8d 100644 (file)
@@ -10,8 +10,8 @@ package org.opendaylight.transportpce.pce.networkanalyzer;
 
 import java.util.List;
 
-import org.opendaylight.transportpce.pce.constraints.PceConstraints;
 import org.opendaylight.yang.gen.v1.http.org.openroadm.common.network.rev181130.Link1;
+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.urn.ietf.params.xml.ns.yang.ietf.network.rev180226.NodeId;
@@ -24,20 +24,15 @@ public class PceLink {
 
     /* Logging. */
     private static final Logger LOG = LoggerFactory.getLogger(PceLink.class);
-
     ///////////////////////// LINKS ////////////////////
     /*
      * extension of Link to include constraints and Graph weight
      */
-
     double weight = 0;
-
     private boolean isValid = true;
-
     // this member is for XPONDER INPUT/OUTPUT links.
-    // it keeps name of client correcponding to NETWORK TP
+    // it keeps name of client corresponding to NETWORK TP
     private String client = "";
-
     private final LinkId linkId;
     private final OpenroadmLinkType linkType;
     private final NodeId sourceId;
@@ -53,6 +48,11 @@ public class PceLink {
     private final List<Long> srlgList;
     private final double osnr;
     private final Span omsAttributesSpan;
+    private static final double CELERITY = 2.99792458 * 1e5; //meter per ms
+    private static final double NOISE_MASK_A = 0.571429;
+    private static final double NOISE_MASK_B = 39.285714;
+    private static final double UPPER_BOUND_OSNR = 33;
+    private static final double LOWER_BOUND_OSNR = 0.1;
 
     public PceLink(Link link, PceNode source, PceNode dest) {
         LOG.debug("PceLink: : PceLink start ");
@@ -74,47 +74,24 @@ public class PceLink {
         this.linkType = MapUtils.calcType(link);
 
         this.oppositeLink = calcOpposite(link);
-        this.latency = calcLatency(link);
 
         if (this.linkType == OpenroadmLinkType.ROADMTOROADM) {
             this.omsAttributesSpan = MapUtils.getOmsAttributesSpan(link);
             this.srlgList = MapUtils.getSRLG(link);
-            this.osnr = retrieveOSNR();
+            this.latency = calcLatency(link);
+            this.osnr = calcSpanOSNR();
         } else {
             this.omsAttributesSpan = null;
             this.srlgList = null;
-            this.osnr = 0.0;
+            this.latency = 0L;
+            this.osnr = 100L; //infinite OSNR in DB
         }
 
-
         LOG.debug("PceLink: created PceLink  {}", toString());
     }
 
-    /*private OpenroadmLinkType calcType(Link link) {
-        org.opendaylight.yang.gen.v1.http.org.openroadm.network.topology.rev181130.@Nullable Link1 link1 = null;
-        OpenroadmLinkType tmplinkType = null;
-
-        // ID and type
-        link1 = link.augmentation(org.opendaylight.yang.gen.v1.http.org.openroadm.network.topology.rev181130
-            .Link1.class);
-        if (link1 == null) {
-            this.isValid = false;
-            LOG.error("PceLink: No Link augmentation available. Link is ignored {}", this.linkId);
-            return null;
-        }
-
-        tmplinkType = link1.getLinkType();
-        if (tmplinkType == null) {
-            this.isValid = false;
-            LOG.error("PceLink: No Link type available. Link is ignored {}", this.linkId);
-            return null;
-        }
-        return tmplinkType;
-    }*/
-
+    //Retrieve the opposite link
     private LinkId calcOpposite(Link link) {
-        // opposite link
-
         LinkId tmpoppositeLink = MapUtils.extractOppositeLink(link);
         if (tmpoppositeLink == null) {
             LOG.error("PceLink: Error calcOpposite. Link is ignored {}", link.getLinkId().getValue());
@@ -123,97 +100,73 @@ public class PceLink {
         return tmpoppositeLink;
     }
 
+    //Compute the link latency : if the latency is not defined, the latency it is computed from the omsAttributesSpan
     private Long calcLatency(Link link) {
-        Long tmplatency = 1L;
         Link1 link1 = null;
-        // latency
         link1 = link.augmentation(Link1.class);
+        Long tmplatency = link1.getLinkLatency();
+        if (tmplatency != null) {
+            return tmplatency;
+        }
+
         try {
-            tmplatency = link1.getLinkLatency();
+            double tmp = 0;
+            for (int i = 0; i < this.omsAttributesSpan.getLinkConcatenation().size(); i++) {
+                //Length is expressed in meter and latency is expressed in ms according to OpenROADM MSA
+                tmp += this.omsAttributesSpan.getLinkConcatenation().get(i).getSRLGLength() / CELERITY;
+                LOG.info("In PceLink: The latency of link {} == {}",link.getLinkId(),tmplatency);
+            }
+            tmplatency = (long) Math.ceil(tmp);
         } catch (NullPointerException e) {
-            LOG.debug("the latency does not exist for this link");
+            LOG.debug("In PceLink: cannot compute the latency for the link {}",link.getLinkId().getValue());
+            tmplatency = 1L;
         }
         return tmplatency;
     }
 
-    @SuppressWarnings("checkstyle:VariableDeclarationUsageDistance")
-    public double retrieveOSNR() {
-        // sum of 1 over the span OSNRs (linear units)
-        double sum = 0;
-        // link OSNR, in dB
-        //double linkOsnrDb;
-        // link OSNR, in dB
-        double linkOsnrLu;
-        // span OSNR, in dB
-        double spanOsnrDb;
-        // span OSNR, in linear units
-        double spanOsnrLu;
-        // default amplifier noise value, in dB
-        //double ampNoise = 5.5;
-        // fiber span measured loss, in dB
-        double loss;
-        // launch power, in dB
-        double power;
-        double constantA = 38.97293;
-        double constantB = 0.72782;
-        double constantC = -0.532331;
-        double constactD = -0.019549;
-        double upperBoundosnr = 33;
-        double lowerBoundosnr = 0.1;
-
-        if (omsAttributesSpan ==  null) {
-            // indicates no data or N/A
+    //Compute the OSNR of a span
+    public double calcSpanOSNR() {
+        try {
+            double pout; //power on the output of the previous ROADM (dBm)
+            pout = retrievePower(this.omsAttributesSpan.getLinkConcatenation().get(0).getFiberType());
+            double spanLoss = this.omsAttributesSpan.getSpanlossCurrent().getValue().doubleValue(); // span loss (dB)
+            double pin = pout - spanLoss; //power on the input of the current ROADM (dBm)
+            double spanOsnrDb;
+            spanOsnrDb = NOISE_MASK_A * pin + NOISE_MASK_B;
+            if (spanOsnrDb > UPPER_BOUND_OSNR) {
+                spanOsnrDb =  UPPER_BOUND_OSNR;
+            } else if (spanOsnrDb < LOWER_BOUND_OSNR) {
+                spanOsnrDb = LOWER_BOUND_OSNR;
+            }
+            return spanOsnrDb;
+        } catch (NullPointerException e) {
+            LOG.error("in PceLink : Null field in the OmsAttrubtesSpan");
             return 0L;
         }
-        loss = omsAttributesSpan.getSpanlossCurrent().getValue().doubleValue();
-        switch (omsAttributesSpan.getLinkConcatenation().get(0).getFiberType()) {
+    }
+
+    private double retrievePower(FiberType fiberType) {
+        double power;
+        switch (fiberType) {
             case Smf:
                 power = 2;
                 break;
-
             case Eleaf:
                 power = 1;
                 break;
-
-            case Oleaf:
-                power = 0;
-                break;
-
-            case Dsf:
-                power = 0;
-                break;
-
-            case Truewave:
-                power = 0;
-                break;
-
             case Truewavec:
                 power = -1;
                 break;
-
+            case Oleaf:
+            case Dsf:
+            case Truewave:
             case NzDsf:
-                power = 0;
-                break;
-
             case Ull:
-                power = 0;
-                break;
-
             default:
                 power = 0;
                 break;
         }
-        spanOsnrDb = constantA + constantB * power + constantC * loss + constactD * power * loss;
-        if (spanOsnrDb > upperBoundosnr) {
-            spanOsnrDb =  upperBoundosnr;
-        } else if (spanOsnrDb < lowerBoundosnr) {
-            spanOsnrDb = lowerBoundosnr;
-        }
-        spanOsnrLu = Math.pow(10, (spanOsnrDb / 10.0));
-        sum = PceConstraints.CONST_OSNR / spanOsnrLu;
-        linkOsnrLu = sum;
-        LOG.debug("In retrieveosnr: link osnr is {} dB", linkOsnrLu);
-        return linkOsnrLu;
+        return power;
     }
 
     public LinkId getOppositeLink() {
@@ -313,7 +266,7 @@ public class PceLink {
     }
 
     public String toString() {
-        return "PceLink type=" + linkType + " ID=" + linkId.getValue() + " latecy=" + latency;
+        return "PceLink type=" + linkType + " ID=" + linkId.getValue() + " latency=" + latency;
     }
 
 }
index 233d785d86222f79357bb1338b10b418fb229fef..abce70280999dc79d203304105e8ecfc8daebaa3 100644 (file)
@@ -21,11 +21,10 @@ public class PceResult {
     private boolean calcStatus = false;
     private String responseCode = ResponseCodes.RESPONSE_FAILED;
     private long resultWavelength = -1;
-    // for now it is constant returned as received from A-end
     private long rate = -1;
 
     public enum LocalCause {
-        NONE, TOO_HIGH_LATENCY, NO_PATH_EXISTS, INT_PROBLEM;
+        NONE, TOO_HIGH_LATENCY, OUT_OF_SPEC_OSNR, NO_PATH_EXISTS, INT_PROBLEM, HD_NODE_INCLUDE;
     }
 
     private LocalCause localCause = LocalCause.NONE;
@@ -39,14 +38,14 @@ public class PceResult {
     public void setRC(String rc) {
         switch (rc) {
             case ResponseCodes.RESPONSE_OK :
-                calcMessage = "Path is calculated";
+                calcMessage = "Path is calculated by PCE";
                 calcStatus = true;
                 responseCode = ResponseCodes.RESPONSE_OK;
                 break;
             case ResponseCodes.RESPONSE_FAILED :
                 responseCode = ResponseCodes.RESPONSE_FAILED;
                 calcStatus = false;
-                calcMessage = "No path available";
+                calcMessage = "No path available by PCE";
                 break;
             default:
                 LOG.error("setRC: RespondeCodes unknown");