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());
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)
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;
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()) {
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
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 {
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();
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;
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) {
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;
/* 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
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;
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
////////////////////////// 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>();
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() {
// 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);
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 =
// 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;
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;
}
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;
// 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;
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
parseInput();
}
- public void calcPath() {
+ public void retrievePceNetwork() {
- LOG.info("In PceCalculation calcPath: ");
+ LOG.info("In PceCalculation retrieveNetwork: ");
if (!readMdSal()) {
returnStructure.setRC(ResponseCodes.RESPONSE_FAILED);
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;
/* 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;
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 ");
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());
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() {
}
public String toString() {
- return "PceLink type=" + linkType + " ID=" + linkId.getValue() + " latecy=" + latency;
+ return "PceLink type=" + linkType + " ID=" + linkId.getValue() + " latency=" + latency;
}
}
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;
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");