2 * Copyright © 2017 AT&T and others. All rights reserved.
4 * This program and the accompanying materials are made available under the
5 * terms of the Eclipse Public License v1.0 which accompanies this distribution,
6 * and is available at http://www.eclipse.org/legal/epl-v10.html
9 package org.opendaylight.transportpce.pce;
11 import org.opendaylight.transportpce.common.ResponseCodes;
12 import org.opendaylight.transportpce.common.network.NetworkTransactionService;
13 import org.opendaylight.transportpce.pce.constraints.PceConstraints;
14 import org.opendaylight.transportpce.pce.constraints.PceConstraintsCalc;
15 import org.opendaylight.transportpce.pce.gnpy.ConnectToGnpyServer;
16 import org.opendaylight.transportpce.pce.gnpy.GnpyException;
17 import org.opendaylight.transportpce.pce.gnpy.GnpyResult;
18 import org.opendaylight.transportpce.pce.gnpy.GnpyUtilitiesImpl;
19 import org.opendaylight.transportpce.pce.graph.PceGraph;
20 import org.opendaylight.transportpce.pce.networkanalyzer.PceCalculation;
21 import org.opendaylight.transportpce.pce.networkanalyzer.PceResult;
22 import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.pce.rev190624.PathComputationRequestInput;
23 import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.pce.rev190624.PathComputationRequestInputBuilder;
24 import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.pce.rev190624.service.path.rpc.result.PathDescriptionBuilder;
25 import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.pathdescription.rev171017.path.description.AToZDirection;
26 import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.pathdescription.rev171017.path.description.ZToADirection;
27 import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.routing.constraints.rev171017.RoutingConstraintsSp.PceMetric;
28 import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.routing.constraints.rev171017.routing.constraints.sp.HardConstraints;
29 import org.slf4j.Logger;
30 import org.slf4j.LoggerFactory;
35 * - path-computation-request
36 * - cancel-resource-reserve.
37 * @author Martial Coulibaly ( martial.coulibaly@gfi.com ) on behalf of Orange
40 public class PceSendingPceRPCs {
43 private static final Logger LOG = LoggerFactory.getLogger(PceSendingPceRPCs.class);
44 /* define procedure success (or not ). */
45 private PceResult rc = new PceResult();
48 * define type of request<br> <code>true</code> pathcomputation <br>
49 * <code>false</code> cancelresourcereserve .
51 private PathDescriptionBuilder pathDescription;
52 private PathComputationRequestInput input;
53 private NetworkTransactionService networkTransaction;
54 private PceConstraints pceHardConstraints = new PceConstraints();
55 private PceConstraints pceSoftConstraints = new PceConstraints();
56 private GnpyResult gnpyAtoZ;
57 private GnpyResult gnpyZtoA;
58 private Boolean success;
59 private String message;
60 private String responseCode;
62 public PceSendingPceRPCs() {
63 setPathDescription(null);
65 this.networkTransaction = null;
68 public PceSendingPceRPCs(PathComputationRequestInput input,
69 NetworkTransactionService networkTransaction) {
70 setPathDescription(null);
72 // TODO compliance check to check that input is not empty
74 this.networkTransaction = networkTransaction;
77 public void cancelResourceReserve() {
79 LOG.info("Wait for 10s til beginning the PCE cancelResourceReserve request");
83 } catch (InterruptedException e) {
84 LOG.error(e.toString());
87 LOG.info("cancelResourceReserve ...");
90 public void pathComputationWithConstraints(PceConstraints hardConstraints, PceConstraints softConstraints) {
92 PceCalculation nwAnalizer =
93 new PceCalculation(input, networkTransaction, hardConstraints, softConstraints, rc);
94 nwAnalizer.calcPath();
95 rc = nwAnalizer.getReturnStructure();
96 if (!rc.getStatus()) {
97 LOG.error("In pathComputationWithConstraints, nwAnalizer: result = {}", rc.toString());
100 LOG.info("PceGraph ...");
101 PceGraph graph = new PceGraph(nwAnalizer.getaendPceNode(),
102 nwAnalizer.getzendPceNode(), nwAnalizer.getAllPceNodes(),
103 hardConstraints, softConstraints, rc);
105 rc = graph.getReturnStructure();
106 if (!rc.getStatus()) {
107 LOG.warn("In pathComputation : Graph return without Path ");
108 // TODO fix. This is quick workaround for algorithm problem
109 if ((rc.getLocalCause() == PceResult.LocalCause.TOO_HIGH_LATENCY)
110 && (hardConstraints.getPceMetrics() == PceMetric.HopCount)
111 && (hardConstraints.getMaxLatency() != -1)) {
112 hardConstraints.setPceMetrics(PceMetric.PropagationDelay);
113 graph = patchRerunGraph(graph);
115 if (!rc.getStatus()) {
116 LOG.error("In pathComputationWithConstraints, graph.calcPath: result = {}", rc.toString());
120 LOG.info("PcePathDescription ...");
121 PcePathDescription description = new PcePathDescription(graph.getPathAtoZ(), nwAnalizer.getAllPceLinks(), rc);
122 description.buildDescriptions();
123 rc = description.getReturnStructure();
124 if (!rc.getStatus()) {
125 LOG.error("In pathComputationWithConstraints, description: result = {}", rc.toString());
130 public void pathComputation() throws Exception {
132 PceConstraintsCalc constraints = new PceConstraintsCalc(input, networkTransaction);
133 pceHardConstraints = constraints.getPceHardConstraints();
134 pceSoftConstraints = constraints.getPceSoftConstraints();
135 pathComputationWithConstraints(pceHardConstraints, pceSoftConstraints);
136 this.success = rc.getStatus();
137 this.message = rc.getMessage();
138 this.responseCode = rc.getResponseCode();
140 AToZDirection atoz = null;
141 ZToADirection ztoa = null;
142 if (rc.getStatus()) {
143 atoz = rc.getAtoZDirection();
144 ztoa = rc.getZtoADirection();
148 ConnectToGnpyServer connectToGnpy = new ConnectToGnpyServer();
149 if (connectToGnpy.isGnpyURLExist()) {
150 GnpyUtilitiesImpl gnpy = new GnpyUtilitiesImpl(networkTransaction, input);
151 if (rc.getStatus() && gnpyToCheckFeasiblity(atoz,ztoa,gnpy)) {
152 setPathDescription(new PathDescriptionBuilder().setAToZDirection(atoz).setZToADirection(ztoa));
155 callGnpyToComputeNewPath(gnpy);
157 setPathDescription(new PathDescriptionBuilder().setAToZDirection(atoz).setZToADirection(ztoa));
161 catch (GnpyException e) {
162 LOG.error("Exception raised by GNPy {}",e.getMessage());
163 setPathDescription(new PathDescriptionBuilder().setAToZDirection(atoz).setZToADirection(ztoa));
169 private boolean gnpyToCheckFeasiblity(AToZDirection atoz, ZToADirection ztoa, GnpyUtilitiesImpl gnpy)
170 throws GnpyException, Exception {
172 //Call GNPy for path verification
173 if (gnpy.verifyComputationByGnpy(atoz, ztoa, pceHardConstraints)) {
174 LOG.info("In pceSendingPceRPC: the path is feasible according to Gnpy");
175 gnpyAtoZ = gnpy.getGnpyAtoZ();
176 gnpyZtoA = gnpy.getGnpyZtoA();
182 private void callGnpyToComputeNewPath(GnpyUtilitiesImpl gnpy) throws GnpyException, Exception {
184 //Call GNPy in the case of non feasibility
185 LOG.info("In pceSendingPceRPC: the path is not feasible according to Gnpy");
186 HardConstraints gnpyPathAsHC = null;
187 gnpyPathAsHC = gnpy.askNewPathFromGnpy(gnpyPathAsHC, pceHardConstraints);
188 if (gnpyPathAsHC == null) {
189 LOG.info("In pceSendingPceRPC: GNPy failed to find another path");
190 this.success = false;
191 this.message = "No path available by PCE and GNPy ";
192 this.responseCode = ResponseCodes.RESPONSE_FAILED;
193 gnpyAtoZ = gnpy.getGnpyAtoZ();
194 gnpyZtoA = gnpy.getGnpyZtoA();
198 LOG.info("In pceSendingPceRPC: GNPy succeed to find another path");
200 PathComputationRequestInput inputFromGnpy = new PathComputationRequestInputBuilder()
201 .setServiceName(input.getServiceName()).setHardConstraints(gnpyPathAsHC)
202 .setSoftConstraints(input.getSoftConstraints()).setPceMetric(PceMetric.HopCount)
203 .setServiceAEnd(input.getServiceAEnd()).setServiceZEnd(input.getServiceZEnd()).build();
204 PceConstraintsCalc constraintsGnpy = new PceConstraintsCalc(inputFromGnpy, networkTransaction);
205 PceConstraints gnpyHardConstraints = constraintsGnpy.getPceHardConstraints();
206 PceConstraints gnpySoftConstraints = constraintsGnpy.getPceSoftConstraints();
207 pathComputationWithConstraints(gnpyHardConstraints, gnpySoftConstraints);
208 AToZDirection atoz = rc.getAtoZDirection();
209 ZToADirection ztoa = rc.getZtoADirection();
210 if (gnpyToCheckFeasiblity(atoz, ztoa,gnpy)) {
211 LOG.info("In pceSendingPceRPC: the new path computed by GNPy is valid");
213 this.message = "Path is calculated by GNPy";
214 this.responseCode = ResponseCodes.RESPONSE_OK;
215 setPathDescription(new PathDescriptionBuilder().setAToZDirection(atoz).setZToADirection(ztoa));
217 LOG.info("In pceSendingPceRPC: the new path computed by GNPy is not valid");
218 this.success = false;
219 this.message = "No path available";
220 this.responseCode = ResponseCodes.RESPONSE_FAILED;
221 setPathDescription(new PathDescriptionBuilder().setAToZDirection(null).setZToADirection(null));
225 private PceGraph patchRerunGraph(PceGraph graph) {
226 LOG.info("In pathComputation patchRerunGraph : rerun Graph with metric = PROPAGATION-DELAY ");
227 graph.setConstrains(pceHardConstraints, pceSoftConstraints);
232 public PathDescriptionBuilder getPathDescription() {
233 return pathDescription;
236 private void setPathDescription(PathDescriptionBuilder pathDescription) {
237 this.pathDescription = pathDescription;
240 public Boolean getSuccess() {
244 public String getMessage() {
248 public String getResponseCode() {
249 return this.responseCode;
252 public GnpyResult getGnpyAtoZ() {
256 public GnpyResult getGnpyZtoA() {