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=eaafcb6a49a44c096f87859752dfde6193f9cf0f;hb=2a29f9ab006d8806f77b1a1e073b478e5351cc5f;hp=ce942e8cd1af31b6fa5c9433b7386aaf130cd16d;hpb=62fc6625966276207a38955eaf07988f77f6984f;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 ce942e8cd..eaafcb6a4 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,63 +8,85 @@ package org.opendaylight.transportpce.pce.graph; +import edu.umd.cs.findbugs.annotations.SuppressFBWarnings; import java.util.ArrayList; +import java.util.Arrays; +import java.util.BitSet; 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.common.fixedflex.GridConstant; +import org.opendaylight.transportpce.common.fixedflex.GridUtils; 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.http.org.opendaylight.transportpce.pce.rev210701.SpectrumAssignment; +import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.pce.rev210701.SpectrumAssignmentBuilder; +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; private static final double ADD_OSNR = 30; 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; } - int tribSlotNb = 1; - //variable to deal wih 1GE (Nb=1) and 10GE (Nb=10) cases + int spectralWidthSlotNumber = GridConstant.SPECTRAL_WIDTH_SLOT_NUMBER_MAP + .getOrDefault(serviceType, GridConstant.NB_SLOTS_100G); + SpectrumAssignment spectrumAssignment = null; + //variable to deal with 1GE (Nb=1) and 10GE (Nb=10) cases switch (serviceType) { - - case "100GE": - case "OTU4": - // choose wavelength available in all nodes of the path - Long waveL = chooseWavelength(path, allPceNodes); + case StringConstants.SERVICE_TYPE_OTUC4: + case StringConstants.SERVICE_TYPE_400GE: + spectralWidthSlotNumber = GridConstant.SPECTRAL_WIDTH_SLOT_NUMBER_MAP + .getOrDefault(serviceType, GridConstant.NB_SLOTS_400G); + //fallthrough + case StringConstants.SERVICE_TYPE_100GE_T: + case StringConstants.SERVICE_TYPE_OTU4: + spectrumAssignment = getSpectrumAssignment(path, allPceNodes, spectralWidthSlotNumber); pceResult.setServiceType(serviceType); - if (waveL < 0) { + if (spectrumAssignment.getBeginIndex().equals(Uint16.valueOf(0)) + && spectrumAssignment.getStopIndex().equals(Uint16.valueOf(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 + if (spectrumAssignment.getFlexGrid()) { + LOG.info("Spectrum assignment flexgrid mode"); + pceResult.setResultWavelength(GridConstant.IRRELEVANT_WAVELENGTH_NUMBER); + } else { + LOG.info("Spectrum assignment fixedgrid mode"); + pceResult.setResultWavelength( + GridUtils.getWaveLengthIndexFromSpectrumAssigment(spectrumAssignment.getBeginIndex() + .toJava())); + } + pceResult.setMinFreq(GridUtils.getStartFrequencyFromIndex(spectrumAssignment.getBeginIndex().toJava())); + pceResult.setMaxFreq(GridUtils.getStopFrequencyFromIndex(spectrumAssignment.getStopIndex().toJava())); + LOG.info("In PostAlgoPathValidator: spectrum assignment found {} {}", spectrumAssignment, path); // Check the OSNR if (!checkOSNR(path)) { @@ -87,17 +109,22 @@ public class PostAlgoPathValidator { 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 "10GE": - tribSlotNb = 10; + case StringConstants.SERVICE_TYPE_100GE_M: + case StringConstants.SERVICE_TYPE_10GE: + tribSlotNb = StringConstants.SERVICE_TYPE_10GE.equals(serviceType) ? 8 : 20; //fallthrough - case "1GE": + case StringConstants.SERVICE_TYPE_1GE: pceResult.setRC(ResponseCodes.RESPONSE_FAILED); pceResult.setServiceType(serviceType); - Map tribPort = chooseTribPort(path, allPceNodes); - Map> tribSlot = chooseTribSlot(path, allPceNodes, tribSlotNb); + Map tribPort = chooseTribPort(path, allPceNodes); + Map> tribSlot = chooseTribSlot(path, allPceNodes, tribSlotNb); if (tribPort != null && tribSlot != null) { pceResult.setResultTribPort(tribPort); @@ -108,44 +135,18 @@ public class PostAlgoPathValidator { tribPort, tribSlot, tribSlotNb); } break; - - case "ODU4": + case StringConstants.SERVICE_TYPE_ODU4: + case StringConstants.SERVICE_TYPE_ODUC4: pceResult.setRC(ResponseCodes.RESPONSE_OK); - LOG.info("In PostAlgoPathValidator: ODU4 path found {}", path.toString()); + LOG.info("In PostAlgoPathValidator: ODU4/ODUC4 path found {}", path); break; - default: pceResult.setRC(ResponseCodes.RESPONSE_FAILED); LOG.warn("In PostAlgoPathValidator checkPath: unsupported serviceType {} found {}", - serviceType, path.toString()); + serviceType, path); 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 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()); - for (PceGraphEdge edge : path.getEdgeList()) { - LOG.debug("In chooseWavelength: source {} ", edge.link().getSourceId().toString()); - PceNode pceNode = allPceNodes.get(edge.link().getSourceId()); - if (!pceNode.checkWL(i)) { - completed = false; - break; - } - } - if (completed) { - wavelength = i; - break; - } - } - return wavelength; } // Check the latency @@ -161,10 +162,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 @@ -177,17 +175,17 @@ public class PostAlgoPathValidator { List pathEdges = path.getEdgeList(); LOG.debug(" in checkInclude vertex list: [{}]", path.getVertexList()); - List listOfElementsSubNode = new ArrayList(); + 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, @@ -235,7 +233,7 @@ 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: @@ -260,7 +258,6 @@ public class PostAlgoPathValidator { listOfElements.add(srlgStr); LOG.info("listOfElementsBuild. FOUND SRLG {} in link {}", srlgStr, link.link()); found = true; - continue; } } if (!found) { @@ -275,10 +272,10 @@ public class PostAlgoPathValidator { return listOfElements; } - private Map chooseTribPort(GraphPath chooseTribPort(GraphPath path, Map allPceNodes) { - LOG.info("In choosetribPort: edgeList = {} ", path.getEdgeList().toString()); - Map tribPortMap = new HashMap<>(); + LOG.info("In choosetribPort: edgeList = {} ", path.getEdgeList()); + Map tribPortMap = new HashMap<>(); for (PceGraphEdge edge : path.getEdgeList()) { NodeId linkSrcNode = edge.link().getSourceId(); @@ -287,10 +284,10 @@ public class PostAlgoPathValidator { 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 (Integer integer : srcTpnPool) { + 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); } @@ -304,10 +301,10 @@ public class PostAlgoPathValidator { return tribPortMap; } - private Map> chooseTribSlot(GraphPath> chooseTribSlot(GraphPath path, Map allPceNodes, int nbSlot) { - LOG.info("In choosetribSlot2: edgeList = {} ", path.getEdgeList().toString()); - Map> tribSlotMap = new HashMap<>(); + LOG.info("In choosetribSlot: edgeList = {} ", path.getEdgeList()); + Map> tribSlotMap = new HashMap<>(); for (PceGraphEdge edge : path.getEdgeList()) { NodeId linkSrcNode = edge.link().getSourceId(); @@ -316,11 +313,11 @@ public class PostAlgoPathValidator { 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 (Integer integer : srcTsPool) { + 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); } @@ -330,9 +327,9 @@ public class PostAlgoPathValidator { int index = 0; while (discontinue && (commonEdgeTsPool.size() - index >= nbSlot)) { discontinue = false; - Integer val = commonEdgeTsPool.get(index); + Integer val = commonEdgeTsPool.get(index).toJava(); for (int i = 0; i < nbSlot; i++) { - if (commonEdgeTsPool.get(index + i).equals(val + i)) { + if (commonEdgeTsPool.get(index + i).equals(Uint16.valueOf(val + i))) { tribSlotList.add(commonEdgeTsPool.get(index + i)); } else { discontinue = true; @@ -348,63 +345,6 @@ public class PostAlgoPathValidator { return tribSlotMap; } - private List> chooseTribSlot3(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(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 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); - } - } else { - LOG.debug("In chooseTribSlot: source {} does not have provisonned hosting HO interface ", - edge.link().getSourceId().toString()); - statusOK = false; - } - } - if (statusOK && check) { - return tribSlot; - } else { - tribSlot.clear(); - return tribSlot; - } - } - // Check the path OSNR private boolean checkOSNR(GraphPath path) { double linkOsnrDb; @@ -428,13 +368,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) { @@ -451,4 +385,85 @@ public class PostAlgoPathValidator { return (CONST_OSNR / linkOsnrLu); } -} + /** + * Get spectrum assignment for path. + * + * @param path the path for which we get spectrum assignment. + * @param allPceNodes all optical nodes. + * @param spectralWidthSlotNumber number of slot for spectral width. Depends on + * service type. + * @return a spectrum assignment object which contains begin and end index. If + * no spectrum assignment found, beginIndex = stopIndex = 0 + */ + private SpectrumAssignment getSpectrumAssignment(GraphPath path, + Map allPceNodes, int spectralWidthSlotNumber) { + byte[] freqMap = new byte[GridConstant.NB_OCTECTS]; + Arrays.fill(freqMap, (byte) GridConstant.AVAILABLE_SLOT_VALUE); + BitSet result = BitSet.valueOf(freqMap); + boolean isFlexGrid = true; + LOG.info("Processing path {} with length {}", path, path.getLength()); + BitSet pceNodeFreqMap; + for (PceGraphEdge edge : path.getEdgeList()) { + LOG.info("Processing source {} ", edge.link().getSourceId()); + if (allPceNodes.containsKey(edge.link().getSourceId())) { + PceNode pceNode = allPceNodes.get(edge.link().getSourceId()); + LOG.info("Processing PCE node {}", pceNode); + if (StringConstants.OPENROADM_DEVICE_VERSION_1_2_1.equals(pceNode.getVersion())) { + LOG.info("Node {}: version is {} and slot width granularity is {} -> fixed grid mode", + pceNode.getNodeId(), pceNode.getVersion(), pceNode.getSlotWidthGranularity()); + isFlexGrid = false; + } + if ((pceNode.getSlotWidthGranularity().equals(GridConstant.SLOT_WIDTH_50)) + && (pceNode.getCentralFreqGranularity().equals(GridConstant.SLOT_WIDTH_50))) { + LOG.info("Node {}: version is {} with slot width granularity {} and central " + + "frequency granularity is {} -> fixed grid mode", + pceNode.getNodeId(), pceNode.getVersion(), pceNode.getSlotWidthGranularity(), + pceNode.getCentralFreqGranularity()); + isFlexGrid = false; + } + pceNodeFreqMap = pceNode.getBitSetData(); + LOG.debug("Pce node bitset {}", pceNodeFreqMap); + if (pceNodeFreqMap != null) { + result.and(pceNodeFreqMap); + LOG.debug("intermediate bitset {}", result); + } + } + } + LOG.debug("Bitset result {}", result); + return computeBestSpectrumAssignment(result, spectralWidthSlotNumber, isFlexGrid); + } + + /** + * Compute spectrum assignment from spectrum occupation for spectral width. + * + * @param spectrumOccupation the spectrum occupation BitSet. + * @param spectralWidthSlotNumber the nb slots for spectral width. + * @param isFlexGrid true if flexible grid, false otherwise. + * @return a spectrum assignment object which contains begin and stop index. If + * no spectrum assignment found, beginIndex = stopIndex = 0 + */ + private SpectrumAssignment computeBestSpectrumAssignment(BitSet spectrumOccupation, int spectralWidthSlotNumber, + boolean isFlexGrid) { + SpectrumAssignmentBuilder spectrumAssignmentBldr = new SpectrumAssignmentBuilder() + .setBeginIndex(Uint16.valueOf(0)) + .setStopIndex(Uint16.valueOf(0)) + .setFlexGrid(isFlexGrid); + BitSet referenceBitSet = new BitSet(spectralWidthSlotNumber); + referenceBitSet.set(0, spectralWidthSlotNumber); + int nbSteps = 1; + if (isFlexGrid) { + nbSteps = spectralWidthSlotNumber; + } + //higher is the frequency, smallest is the wavelength number + //in operational, the allocation is done through wavelength starting from the smallest + //so we have to loop from the last element of the spectrum occupation + for (int i = spectrumOccupation.size(); i >= spectralWidthSlotNumber; i -= nbSteps) { + if (spectrumOccupation.get(i - spectralWidthSlotNumber, i).equals(referenceBitSet)) { + spectrumAssignmentBldr.setBeginIndex(Uint16.valueOf(i - spectralWidthSlotNumber)); + spectrumAssignmentBldr.setStopIndex(Uint16.valueOf(i - 1)); + break; + } + } + return spectrumAssignmentBldr.build(); + } +} \ No newline at end of file