X-Git-Url: https://git.opendaylight.org/gerrit/gitweb?p=transportpce.git;a=blobdiff_plain;f=pce%2Fsrc%2Fmain%2Fjava%2Forg%2Fopendaylight%2Ftransportpce%2Fpce%2FPceSendingPceRPCs.java;h=751a7ea9873243c8c2999911ea36fef93a325126;hp=843aebfab947dfbcf181f15188121d21c1bfc0be;hb=1e2f9a502de80450411761fd2f636e2b7ee32301;hpb=f1333ba85fbbe086ab540d759a3b6a898c52a135 diff --git a/pce/src/main/java/org/opendaylight/transportpce/pce/PceSendingPceRPCs.java b/pce/src/main/java/org/opendaylight/transportpce/pce/PceSendingPceRPCs.java index 843aebfab..751a7ea98 100644 --- a/pce/src/main/java/org/opendaylight/transportpce/pce/PceSendingPceRPCs.java +++ b/pce/src/main/java/org/opendaylight/transportpce/pce/PceSendingPceRPCs.java @@ -8,13 +8,25 @@ package org.opendaylight.transportpce.pce; -import org.opendaylight.controller.md.sal.binding.api.DataBroker; -import org.opendaylight.transportpce.pce.PceResult.LocalCause; -import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.pce.rev170426.PathComputationRequestInput; -import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.pathdescription.rev170426.path.description.AToZDirection; -import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.pathdescription.rev170426.path.description.ZToADirection; -import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.routing.constraints.rev170426.RoutingConstraintsSp.PceMetric; -import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.service.types.rev170426.response.parameters.sp.response.parameters.PathDescriptionBuilder; +import org.opendaylight.transportpce.common.ResponseCodes; +import org.opendaylight.transportpce.common.mapping.PortMapping; +import org.opendaylight.transportpce.common.network.NetworkTransactionService; +import org.opendaylight.transportpce.pce.constraints.PceConstraints; +import org.opendaylight.transportpce.pce.constraints.PceConstraintsCalc; +import org.opendaylight.transportpce.pce.gnpy.GnpyException; +import org.opendaylight.transportpce.pce.gnpy.GnpyResult; +import org.opendaylight.transportpce.pce.gnpy.GnpyUtilitiesImpl; +import org.opendaylight.transportpce.pce.gnpy.consumer.GnpyConsumer; +import org.opendaylight.transportpce.pce.graph.PceGraph; +import org.opendaylight.transportpce.pce.networkanalyzer.PceCalculation; +import org.opendaylight.transportpce.pce.networkanalyzer.PceResult; +import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.pce.rev220118.PathComputationRequestInput; +import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.pce.rev220118.PathComputationRequestInputBuilder; +import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.pce.rev220118.service.path.rpc.result.PathDescriptionBuilder; +import org.opendaylight.yang.gen.v1.http.org.openroadm.routing.constrains.rev190329.routing.constraints.HardConstraints; +import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.pathdescription.rev210705.path.description.AToZDirection; +import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.pathdescription.rev210705.path.description.ZToADirection; +import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.service.types.rev220118.PceMetric; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -38,121 +50,196 @@ public class PceSendingPceRPCs { * false cancelresourcereserve . */ private PathDescriptionBuilder pathDescription; - private PathComputationRequestInput input; - private DataBroker dataBroker; - + private NetworkTransactionService networkTransaction; private PceConstraints pceHardConstraints = new PceConstraints(); private PceConstraints pceSoftConstraints = new PceConstraints(); - - public PceSendingPceRPCs() { + private GnpyResult gnpyAtoZ; + private GnpyResult gnpyZtoA; + private Boolean success; + private String message; + private String responseCode; + private final GnpyConsumer gnpyConsumer; + private PortMapping portMapping; + + public PceSendingPceRPCs(GnpyConsumer gnpyConsumer) { setPathDescription(null); - this.input = null; - this.dataBroker = null; + this.networkTransaction = null; + this.gnpyConsumer = gnpyConsumer; } - public PceSendingPceRPCs(PathComputationRequestInput input, DataBroker dataBroker) { + public PceSendingPceRPCs(PathComputationRequestInput input, + NetworkTransactionService networkTransaction, GnpyConsumer gnpyConsumer, PortMapping portMapping) { + this.gnpyConsumer = gnpyConsumer; setPathDescription(null); // TODO compliance check to check that input is not empty this.input = input; - this.dataBroker = dataBroker; + this.networkTransaction = networkTransaction; + this.portMapping = portMapping; } public void cancelResourceReserve() { + success = false; LOG.info("Wait for 10s til beginning the PCE cancelResourceReserve request"); try { - Thread.sleep(10000); // sleep for 10s + // sleep for 10s + Thread.sleep(10000); } catch (InterruptedException e) { - LOG.error(e.toString()); + LOG.error("in PCESendingPceRPC: ",e); } + success = true; LOG.info("cancelResourceReserve ..."); } - public void pathComputation() { - LOG.info("PathComputation ..."); - - PceConstraintsCalc constraints = new PceConstraintsCalc(input, dataBroker); - pceHardConstraints = constraints.getPceHardConstraints(); - pceSoftConstraints = constraints.getPceSoftConstraints(); - + public void pathComputationWithConstraints(PceConstraints hardConstraints, PceConstraints softConstraints) { - LOG.info("nwAnalizer ..."); - PceCalculation nwAnalizer = new PceCalculation(input, dataBroker, - pceHardConstraints, pceSoftConstraints, rc); - nwAnalizer.calcPath(); + PceCalculation nwAnalizer = + new PceCalculation(input, networkTransaction, hardConstraints, softConstraints, rc, portMapping); + nwAnalizer.retrievePceNetwork(); rc = nwAnalizer.getReturnStructure(); + String serviceType = nwAnalizer.getServiceType(); if (!rc.getStatus()) { - LOG.error("In pathComputation nwAnalizer: result = {}", rc.toString()); + LOG.error("In pathComputationWithConstraints, nwAnalizer: result = {}", rc); return; } - LOG.info("PceGraph ..."); - PceGraph graph = new PceGraph( - nwAnalizer.getaPceNode(), - nwAnalizer.getzPceNode(), - nwAnalizer.getAllPceNodes(), - pceHardConstraints, pceSoftConstraints, rc); + PceGraph graph = new PceGraph(nwAnalizer.getaendPceNode(), nwAnalizer.getzendPceNode(), + nwAnalizer.getAllPceNodes(), hardConstraints, softConstraints, rc, serviceType); 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() == LocalCause.TOO_HIGH_LATENCY) - && (pceHardConstraints.getPceMetrics() == PceMetric.HopCount) - && (pceHardConstraints.getMaxLatency() != (long) -1)) { + if ((rc.getLocalCause() == PceResult.LocalCause.TOO_HIGH_LATENCY) + && (hardConstraints.getPceMetrics() == PceMetric.HopCount) + && (hardConstraints.getMaxLatency() != -1)) { + hardConstraints.setPceMetrics(PceMetric.PropagationDelay); + graph = patchRerunGraph(graph); + } - pceHardConstraints.setPceMetrics(PceMetric.PropagationDelay); - graph = patchRerunGraph(graph, pceHardConstraints, pceSoftConstraints); + if (rc.getLocalCause() == PceResult.LocalCause.HD_NODE_INCLUDE) { + graph.setKpathsToBring(graph.getKpathsToBring() * 10); + graph = patchRerunGraph(graph); } if (!rc.getStatus()) { - LOG.error("In pathComputation graph.calcPath: result = {}", rc.toString()); + LOG.error("In pathComputationWithConstraints, graph.calcPath: result = {}", rc); return; } } - LOG.info("PcePathDescription ..."); - PcePathDescription description = new PcePathDescription( - graph.getPathAtoZ(), - nwAnalizer.getAllPceLinks(), rc); + PcePathDescription description = new PcePathDescription(graph.getPathAtoZ(), nwAnalizer.getAllPceLinks(), rc); description.buildDescriptions(); rc = description.getReturnStructure(); if (!rc.getStatus()) { - LOG.error("In pathComputation description: result = {}", rc.toString()); + LOG.error("In pathComputationWithConstraints, description: result = {}", rc); + } + } + + public void pathComputation() throws Exception { + + PceConstraintsCalc constraints = new PceConstraintsCalc(input, networkTransaction); + pceHardConstraints = constraints.getPceHardConstraints(); + pceSoftConstraints = constraints.getPceSoftConstraints(); + pathComputationWithConstraints(pceHardConstraints, pceSoftConstraints); + this.success = rc.getStatus(); + this.message = rc.getMessage(); + this.responseCode = rc.getResponseCode(); + + AToZDirection atoz = null; + ZToADirection ztoa = null; + if (rc.getStatus()) { + atoz = rc.getAtoZDirection(); + ztoa = rc.getZtoADirection(); + } + + //Connect to Gnpy to check path feasibility and recompute another path in case of path non-feasibility + try { + if (gnpyConsumer.isAvailable()) { + GnpyUtilitiesImpl gnpy = new GnpyUtilitiesImpl(networkTransaction, input, + gnpyConsumer); + if (rc.getStatus() && gnpyToCheckFeasiblity(atoz,ztoa,gnpy)) { + setPathDescription(new PathDescriptionBuilder().setAToZDirection(atoz).setZToADirection(ztoa)); + return; + } + callGnpyToComputeNewPath(gnpy); + } else { + setPathDescription(new PathDescriptionBuilder().setAToZDirection(atoz).setZToADirection(ztoa)); + } + } + catch (GnpyException e) { + LOG.error("Exception raised by GNPy {}",e.getMessage()); + setPathDescription(new PathDescriptionBuilder().setAToZDirection(atoz).setZToADirection(ztoa)); + } + } + + private boolean gnpyToCheckFeasiblity(AToZDirection atoz, ZToADirection ztoa, GnpyUtilitiesImpl gnpy) + throws GnpyException { + + //Call GNPy for path verification + if (gnpy.verifyComputationByGnpy(atoz, ztoa, pceHardConstraints)) { + LOG.info("In pceSendingPceRPC: the path is feasible according to Gnpy"); + gnpyAtoZ = gnpy.getGnpyAtoZ(); + gnpyZtoA = gnpy.getGnpyZtoA(); + return true; + } + return false; + } + + private void callGnpyToComputeNewPath(GnpyUtilitiesImpl gnpy) throws GnpyException { + + //Call GNPy in the case of non feasibility + LOG.info("In pceSendingPceRPC: the path is not feasible according to Gnpy"); + HardConstraints gnpyPathAsHC = null; + gnpyPathAsHC = gnpy.askNewPathFromGnpy(pceHardConstraints); + if (gnpyPathAsHC == null) { + LOG.info("In pceSendingPceRPC: GNPy failed to find another path"); + this.success = false; + this.message = "No path available by PCE and GNPy "; + this.responseCode = ResponseCodes.RESPONSE_FAILED; + gnpyAtoZ = gnpy.getGnpyAtoZ(); + gnpyZtoA = gnpy.getGnpyZtoA(); return; } - LOG.info("setPathDescription ..."); + LOG.info("In pceSendingPceRPC: GNPy succeed to find another path"); + // Compute the path + PathComputationRequestInput inputFromGnpy = new PathComputationRequestInputBuilder() + .setServiceName(input.getServiceName()) + .setHardConstraints(gnpyPathAsHC) + .setSoftConstraints(input.getSoftConstraints()) + .setPceRoutingMetric(PceMetric.HopCount) + .setServiceAEnd(input.getServiceAEnd()) + .setServiceZEnd(input.getServiceZEnd()) + .build(); + PceConstraintsCalc constraintsGnpy = new PceConstraintsCalc(inputFromGnpy, networkTransaction); + PceConstraints gnpyHardConstraints = constraintsGnpy.getPceHardConstraints(); + PceConstraints gnpySoftConstraints = constraintsGnpy.getPceSoftConstraints(); + pathComputationWithConstraints(gnpyHardConstraints, gnpySoftConstraints); AToZDirection atoz = rc.getAtoZDirection(); ZToADirection ztoa = rc.getZtoADirection(); - if (atoz == null || atoz.getAToZ() == null) { - rc.setRC("400"); - LOG.error("In pathComputation empty atoz path after description: result = {}", rc.toString()); - return; + if (gnpyToCheckFeasiblity(atoz, ztoa,gnpy)) { + LOG.info("In pceSendingPceRPC: the new path computed by GNPy is valid"); + this.success = true; + this.message = "Path is calculated by GNPy"; + this.responseCode = ResponseCodes.RESPONSE_OK; + setPathDescription(new PathDescriptionBuilder().setAToZDirection(atoz).setZToADirection(ztoa)); + } else { + LOG.info("In pceSendingPceRPC: the new path computed by GNPy is not valid"); + this.success = false; + this.message = "No path available"; + this.responseCode = ResponseCodes.RESPONSE_FAILED; + setPathDescription(new PathDescriptionBuilder().setAToZDirection(null).setZToADirection(null)); } - if (ztoa == null || ztoa.getZToA() == null) { - rc.setRC("400"); - LOG.error("In pathComputation empty ztoa path after description: result = {}", rc.toString()); - return; - } - setPathDescription(new PathDescriptionBuilder() - .setAToZDirection(atoz) - .setZToADirection(ztoa)); - LOG.info("In pathComputation Graph is Found"); } - private PceGraph patchRerunGraph(PceGraph graph, PceConstraints pceHardConstraints, - PceConstraints pceSoftConstraints) { - + private PceGraph patchRerunGraph(PceGraph graph) { LOG.info("In pathComputation patchRerunGraph : rerun Graph with metric = PROPAGATION-DELAY "); graph.setConstrains(pceHardConstraints, pceSoftConstraints); graph.calcPath(); return graph; - } public PathDescriptionBuilder getPathDescription() { @@ -164,15 +251,22 @@ public class PceSendingPceRPCs { } public Boolean getSuccess() { - return rc.getStatus(); + return this.success; } public String getMessage() { - return rc.getMessage(); + return this.message; } public String getResponseCode() { - return rc.getResponseCode(); + return this.responseCode; + } + + public GnpyResult getGnpyAtoZ() { + return gnpyAtoZ; } + public GnpyResult getGnpyZtoA() { + return gnpyZtoA; + } }