package org.opendaylight.transportpce.pce;
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.ConnectToGnpyServer;
+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.rev190624.PathComputationRequestInput;
-import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.pce.rev190624.PathComputationRequestInputBuilder;
-import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.pce.rev190624.service.path.rpc.result.PathDescriptionBuilder;
-import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.pathdescription.rev171017.path.description.AToZDirection;
-import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.pathdescription.rev171017.path.description.ZToADirection;
+import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.pce.rev210701.PathComputationRequestInput;
+import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.pce.rev210701.PathComputationRequestInputBuilder;
+import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.pce.rev210701.service.path.rpc.result.PathDescriptionBuilder;
+import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.pathdescription.rev201210.path.description.AToZDirection;
+import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.pathdescription.rev201210.path.description.ZToADirection;
import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.routing.constraints.rev171017.RoutingConstraintsSp.PceMetric;
import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.routing.constraints.rev171017.routing.constraints.sp.HardConstraints;
import org.slf4j.Logger;
private Boolean success;
private String message;
private String responseCode;
+ private final GnpyConsumer gnpyConsumer;
+ private PortMapping portMapping;
- public PceSendingPceRPCs() {
+ public PceSendingPceRPCs(GnpyConsumer gnpyConsumer) {
setPathDescription(null);
this.input = null;
this.networkTransaction = null;
+ this.gnpyConsumer = gnpyConsumer;
}
public PceSendingPceRPCs(PathComputationRequestInput input,
- NetworkTransactionService networkTransaction) {
+ 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.networkTransaction = networkTransaction;
+ this.portMapping = portMapping;
}
public void cancelResourceReserve() {
// 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 pathComputationWithConstraints(PceConstraints hardConstraints, PceConstraints softConstraints)
- throws Exception {
+ public void pathComputationWithConstraints(PceConstraints hardConstraints, PceConstraints softConstraints) {
PceCalculation nwAnalizer =
- new PceCalculation(input, networkTransaction, hardConstraints, softConstraints, rc);
- nwAnalizer.calcPath();
+ new PceCalculation(input, networkTransaction, hardConstraints, softConstraints, rc, portMapping);
+ nwAnalizer.retrievePceNetwork();
rc = nwAnalizer.getReturnStructure();
+ String serviceType = nwAnalizer.getServiceType();
if (!rc.getStatus()) {
- LOG.error("In pathComputationWithConstraints, nwAnalizer: result = {}", rc.toString());
+ LOG.error("In pathComputationWithConstraints, nwAnalizer: result = {}", rc);
return;
}
LOG.info("PceGraph ...");
- PceGraph graph = new PceGraph(nwAnalizer.getaendPceNode(),
- nwAnalizer.getzendPceNode(), nwAnalizer.getAllPceNodes(),
- hardConstraints, softConstraints, 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() == 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());
+ LOG.error("In pathComputationWithConstraints, graph.calcPath: result = {}", rc);
return;
}
}
description.buildDescriptions();
rc = description.getReturnStructure();
if (!rc.getStatus()) {
- LOG.error("In pathComputationWithConstraints, description: result = {}", rc.toString());
- return;
+ LOG.error("In pathComputationWithConstraints, description: result = {}", rc);
}
}
this.message = rc.getMessage();
this.responseCode = rc.getResponseCode();
- if (!rc.getStatus()) {
- LOG.error("In pathComputation, pathComputationWithConstraints: result = {}", rc.toString());
- return;
+ AToZDirection atoz = null;
+ ZToADirection ztoa = null;
+ if (rc.getStatus()) {
+ atoz = rc.getAtoZDirection();
+ ztoa = rc.getZtoADirection();
}
- // Verify the path with GNPy
- AToZDirection atoz = rc.getAtoZDirection();
- ZToADirection ztoa = rc.getZtoADirection();
- ConnectToGnpyServer connectToGnpy = new ConnectToGnpyServer();
-
- // Verify that the GNPy server exists
- if (connectToGnpy.isGnpyURLExist()) {
- LOG.info("Gnpy instance is connected T-PCE");
- GnpyUtilitiesImpl gnpy = new GnpyUtilitiesImpl(networkTransaction, input);
- if (gnpy.verifyComputationByGnpy(atoz, ztoa, pceHardConstraints)) {
- LOG.info("The path is feasible according to Gnpy");
- setPathDescription(new PathDescriptionBuilder().setAToZDirection(atoz).setZToADirection(ztoa));
- }
- else {
- LOG.info("The path is not feasible according to Gnpy");
- HardConstraints gnpyPathAsHC = null;
- gnpyPathAsHC = gnpy.askNewPathFromGnpy(atoz, ztoa, gnpyPathAsHC, pceHardConstraints);
- if (gnpyPathAsHC != null) {
- LOG.info("GNPy succeed to find another path");
- // Compute the path
- PathComputationRequestInput inputFromGnpy = new PathComputationRequestInputBuilder()
- .setServiceName(input.getServiceName())
- .setHardConstraints(gnpyPathAsHC)
- .setSoftConstraints(input.getSoftConstraints())
- .setPceMetric(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);
- 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));
- if (gnpy.verifyComputationByGnpy(atoz, ztoa, pceHardConstraints)) {
- LOG.info("In pathComputation: the new path computed by GNPy is valid");
- setPathDescription(new PathDescriptionBuilder().setAToZDirection(atoz).setZToADirection(ztoa));
- this.success = true;
- this.message = "Path is calculated by GNPy ";
- this.responseCode = ResponseCodes.RESPONSE_OK;
- } else {
- LOG.info("In pathComputation: the new path computed by GNPy is not valid");
- this.success = false;
- this.message = "No path available ";
- this.responseCode = ResponseCodes.RESPONSE_FAILED;
- }
- } else {
- LOG.info("GNPy failed to find another path");
- this.success = false;
- this.message = "No path available by PCE and GNPy ";
- this.responseCode = ResponseCodes.RESPONSE_FAILED;
+ 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();
- } else {
- LOG.info("in PCESendingPceRPCs: Cannot connect to GNPy!!");
+ 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("In pceSendingPceRPC: GNPy succeed to find another path");
+ // Compute the path
+ PathComputationRequestInput inputFromGnpy = new PathComputationRequestInputBuilder()
+ .setServiceName(input.getServiceName()).setHardConstraints(gnpyPathAsHC)
+ .setSoftConstraints(input.getSoftConstraints()).setPceMetric(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 (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));
- LOG.info("In pathComputation Graph is Found");
+ } 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));
}
}