Modify spectrum assignment management in PCE
[transportpce.git] / pce / src / main / java / org / opendaylight / transportpce / pce / PceSendingPceRPCs.java
old mode 100755 (executable)
new mode 100644 (file)
index 3ca6b94..7f3ce50
@@ -9,20 +9,22 @@
 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;
@@ -57,20 +59,25 @@ public class PceSendingPceRPCs {
     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() {
@@ -80,31 +87,30 @@ public class PceSendingPceRPCs {
             // 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)
@@ -112,8 +118,14 @@ public class PceSendingPceRPCs {
                 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;
             }
         }
@@ -122,8 +134,7 @@ public class PceSendingPceRPCs {
         description.buildDescriptions();
         rc = description.getReturnStructure();
         if (!rc.getStatus()) {
-            LOG.error("In pathComputationWithConstraints, description: result = {}", rc.toString());
-            return;
+            LOG.error("In pathComputationWithConstraints, description: result = {}", rc);
         }
     }
 
@@ -137,71 +148,86 @@ public class PceSendingPceRPCs {
         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));
         }
     }