X-Git-Url: https://git.opendaylight.org/gerrit/gitweb?a=blobdiff_plain;f=pce%2Fsrc%2Fmain%2Fjava%2Forg%2Fopendaylight%2Ftransportpce%2Fpce%2Fgraph%2FPostAlgoPathValidator.java;h=047d248a99022ee2d8facd93c388a0ae5f3be9a2;hb=90d8a03124584b62a3ba094d709ea0618ddb344e;hp=1d28a2dd2c1e9a623355eb49a6b314e5bc7451f1;hpb=aafa2ea596dc9ea93b5ce5a7156ae68acf4b403f;p=transportpce.git diff --git a/pce/src/main/java/org/opendaylight/transportpce/pce/graph/PostAlgoPathValidator.java b/pce/src/main/java/org/opendaylight/transportpce/pce/graph/PostAlgoPathValidator.java index 1d28a2dd2..047d248a9 100644 --- a/pce/src/main/java/org/opendaylight/transportpce/pce/graph/PostAlgoPathValidator.java +++ b/pce/src/main/java/org/opendaylight/transportpce/pce/graph/PostAlgoPathValidator.java @@ -8,27 +8,29 @@ package org.opendaylight.transportpce.pce.graph; +import edu.umd.cs.findbugs.annotations.SuppressFBWarnings; import java.util.ArrayList; +import java.util.Collections; +import java.util.HashMap; import java.util.List; import java.util.Map; - import org.jgrapht.GraphPath; import org.opendaylight.transportpce.common.ResponseCodes; +import org.opendaylight.transportpce.common.StringConstants; 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.http.org.openroadm.network.types.rev200529.OpenroadmLinkType; import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.rev180226.NodeId; +import org.opendaylight.yangtools.yang.common.Uint16; import org.slf4j.Logger; import org.slf4j.LoggerFactory; public class PostAlgoPathValidator { /* Logging. */ - private static final Logger LOG = LoggerFactory.getLogger(PceGraph.class); + private static final Logger LOG = LoggerFactory.getLogger(PostAlgoPathValidator.class); - // 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; @@ -36,86 +38,107 @@ public class PostAlgoPathValidator { public static final Long CONST_OSNR = 1L; public static final double SYS_MARGIN = 0; + @SuppressFBWarnings( + value = "SF_SWITCH_FALLTHROUGH", + justification = "intentional fallthrough") public PceResult checkPath(GraphPath path, Map allPceNodes, PceResult pceResult, PceConstraints pceHardConstraints, String serviceType) { // check if the path is empty - if (path.getEdgeList().size() == 0) { + if (path.getEdgeList().isEmpty()) { 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 with 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 StringConstants.SERVICE_TYPE_100GE: + case StringConstants.SERVICE_TYPE_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); - // Check if MaxLatency is defined in the hard constraints - if (pceHardConstraints.getMaxLatency() != -1) { - if (!checkLatency(pceHardConstraints.getMaxLatency(), path)) { + // 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; + } + + // TODO here other post algo validations can be added + // more data can be sent to PceGraph module via PceResult structure if required + + pceResult.setRC(ResponseCodes.RESPONSE_OK); + pceResult.setLocalCause(PceResult.LocalCause.NONE); + + break; + + case StringConstants.SERVICE_TYPE_10GE: + tribSlotNb = 8; + //fallthrough + case StringConstants.SERVICE_TYPE_1GE: pceResult.setRC(ResponseCodes.RESPONSE_FAILED); - pceResult.setLocalCause(PceResult.LocalCause.HD_NODE_INCLUDE); - return pceResult; - } - pceResult.setRC(ResponseCodes.RESPONSE_OK); + pceResult.setServiceType(serviceType); + Map tribPort = chooseTribPort(path, allPceNodes); + Map> 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 StringConstants.SERVICE_TYPE_ODU4: pceResult.setRC(ResponseCodes.RESPONSE_OK); - LOG.info("In PostAlgoPathValidator: chooseTribPort TribPort found {} {}", tribPort, path.toString()); - } + LOG.info("In PostAlgoPathValidator: ODU4 path found {}", path); + break; + + default: + pceResult.setRC(ResponseCodes.RESPONSE_FAILED); + LOG.warn("In PostAlgoPathValidator checkPath: unsupported serviceType {} found {}", + serviceType, path); + break; } + return pceResult; } // Choose the first available wavelength from the source to the destination private Long chooseWavelength(GraphPath path, Map allPceNodes) { Long wavelength = -1L; - for (long i = 1; i <= MAX_WAWELENGTH; i++) { boolean completed = true; - LOG.debug("In chooseWavelength: {} {}", path.getLength(), path.toString()); + LOG.debug("In chooseWavelength: {} {}", path.getLength(), path); for (PceGraphEdge edge : path.getEdgeList()) { - LOG.debug("In chooseWavelength: source {} ", edge.link().getSourceId().toString()); + LOG.debug("In chooseWavelength: source {} ", edge.link().getSourceId()); PceNode pceNode = allPceNodes.get(edge.link().getSourceId()); if (!pceNode.checkWL(i)) { completed = false; @@ -143,10 +166,7 @@ public class PostAlgoPathValidator { edge.link().getLinkId().getValue()); } } - if (latency > maxLatency) { - return false; - } - return true; + return (latency < maxLatency); } // Check the inclusion if it is defined in the hard constraints @@ -159,17 +179,17 @@ public class PostAlgoPathValidator { List pathEdges = path.getEdgeList(); LOG.debug(" in checkInclude vertex list: [{}]", path.getVertexList()); - List listOfElementsSubNode = new ArrayList(); - listOfElementsSubNode.add(pathEdges.get(0).link().getsourceSupNodeId()); + List listOfElementsSubNode = new ArrayList<>(); + listOfElementsSubNode.add(pathEdges.get(0).link().getsourceNetworkSupNodeId()); listOfElementsSubNode.addAll(listOfElementsBuild(pathEdges, PceConstraints.ResourceType.NODE, pceHardConstraintsInput)); - List listOfElementsCLLI = new ArrayList(); + List listOfElementsCLLI = new ArrayList<>(); listOfElementsCLLI.add(pathEdges.get(0).link().getsourceCLLI()); listOfElementsCLLI.addAll(listOfElementsBuild(pathEdges, PceConstraints.ResourceType.CLLI, pceHardConstraintsInput)); - List listOfElementsSRLG = new ArrayList(); + List listOfElementsSRLG = new ArrayList<>(); // first link is XPONDEROUTPUT, no SRLG for it listOfElementsSRLG.add("NONE"); listOfElementsSRLG.addAll(listOfElementsBuild(pathEdges, PceConstraints.ResourceType.SRLG, @@ -217,11 +237,11 @@ public class PostAlgoPathValidator { private List listOfElementsBuild(List pathEdges, PceConstraints.ResourceType type, PceConstraints pceHardConstraints) { - List listOfElements = new ArrayList(); + List listOfElements = new ArrayList<>(); 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 +251,6 @@ public class PostAlgoPathValidator { listOfElements.add("NONE"); break; } - // srlg of link is List. 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 @@ -243,7 +262,6 @@ public class PostAlgoPathValidator { listOfElements.add(srlgStr); LOG.info("listOfElementsBuild. FOUND SRLG {} in link {}", srlgStr, link.link()); found = true; - continue; } } if (!found) { @@ -258,117 +276,77 @@ public class PostAlgoPathValidator { return listOfElements; } - private List> chooseTribPort(GraphPath path, Map allPceNodes) { - List> 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 tribPortEdgeSourceN = new ArrayList<>(); - List 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 chooseTribPort(GraphPath path, Map allPceNodes) { + LOG.info("In choosetribPort: edgeList = {} ", path.getEdgeList()); + Map 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 srcTpnPool = pceOtnNodeSrc.getAvailableTribPorts().get(linkSrcTp); + List destTpnPool = pceOtnNodeDest.getAvailableTribPorts().get(linkDestTp); + List commonEdgeTpnPool = new ArrayList<>(); + for (Uint16 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 List> chooseTribSlot(GraphPath path, Map allPceNodes) { - List> tribSlot = new ArrayList<>(); - boolean statusOK = true; - boolean check = false; - Object nodeClass = allPceNodes.getClass(); - 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)) { - 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 tribSlotEdgeSourceN = new ArrayList<>(); - List 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; - } - } - if (check) { - tribSlot.add(tribSlotEdgeSourceN); + private Map> chooseTribSlot(GraphPath path, Map allPceNodes, int nbSlot) { + LOG.info("In choosetribSlot: edgeList = {} ", path.getEdgeList()); + Map> 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 srcTsPool = pceOtnNodeSrc.getAvailableTribSlots().get(linkSrcTp); + List destTsPool = pceOtnNodeDest.getAvailableTribSlots().get(linkDestTp); + List commonEdgeTsPool = new ArrayList<>(); + List tribSlotList = new ArrayList<>(); + for (Uint16 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).toJava(); + for (int i = 0; i < nbSlot; i++) { + if (commonEdgeTsPool.get(index + i).equals(Uint16.valueOf(val + i))) { + tribSlotList.add(commonEdgeTsPool.get(index + i)); + } else { + discontinue = true; + tribSlotList.clear(); + index += i; + break; } - } else { - LOG.debug("In chooseTribSlot: source {} does not have provisonned hosting HO interface ", - edge.link().getSourceId().toString()); - statusOK = false; } } + tribSlotMap.put(edge.link().getLinkId().getValue(), tribSlotList); } - if (statusOK && check) { - return tribSlot; - } else { - tribSlot.clear(); - return tribSlot; - } - + tribSlotMap.forEach((k,v) -> LOG.info("TribSlotMap : k = {}, v = {}", k, v)); + return tribSlotMap; } // Check the path OSNR @@ -394,13 +372,7 @@ public class PostAlgoPathValidator { return false; } LOG.info("In checkOSNR: OSNR of the path is {} dB", osnrDb); - if ((osnrDb + SYS_MARGIN) < MIN_OSNR_W100G) { - return false; - } - double localOsnr = 0L; - LOG.info("In OSNR Stub: {}", localOsnr); - // TODO : change this to return OSNR value and validate or invalidate the path - return true; + return ((osnrDb + SYS_MARGIN) > MIN_OSNR_W100G); } private double getOsnrDb(double osnrLu) {