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.mapping.PortMapping;
13 import org.opendaylight.transportpce.common.network.NetworkTransactionService;
14 import org.opendaylight.transportpce.pce.constraints.PceConstraints;
15 import org.opendaylight.transportpce.pce.constraints.PceConstraintsCalc;
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.gnpy.consumer.GnpyConsumer;
20 import org.opendaylight.transportpce.pce.graph.PceGraph;
21 import org.opendaylight.transportpce.pce.networkanalyzer.PceCalculation;
22 import org.opendaylight.transportpce.pce.networkanalyzer.PceResult;
23 import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.pce.rev220118.PathComputationRequestInput;
24 import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.pce.rev220118.PathComputationRequestInputBuilder;
25 import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.pce.rev220118.service.path.rpc.result.PathDescriptionBuilder;
26 import org.opendaylight.yang.gen.v1.http.org.openroadm.routing.constraints.rev211210.routing.constraints.HardConstraints;
27 import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.pathdescription.rev210705.path.description.AToZDirection;
28 import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.pathdescription.rev210705.path.description.ZToADirection;
29 import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.service.types.rev220118.PceMetric;
30 import org.slf4j.Logger;
31 import org.slf4j.LoggerFactory;
36 * - path-computation-request
37 * - cancel-resource-reserve.
38 * @author Martial Coulibaly ( martial.coulibaly@gfi.com ) on behalf of Orange
41 public class PceSendingPceRPCs {
44 private static final Logger LOG = LoggerFactory.getLogger(PceSendingPceRPCs.class);
45 /* define procedure success (or not ). */
46 private PceResult rc = new PceResult();
49 * define type of request<br> <code>true</code> pathcomputation <br>
50 * <code>false</code> cancelresourcereserve .
52 private PathDescriptionBuilder pathDescription;
53 private PathComputationRequestInput input;
54 private NetworkTransactionService networkTransaction;
55 private PceConstraints pceHardConstraints = new PceConstraints();
56 private PceConstraints pceSoftConstraints = new PceConstraints();
57 private GnpyResult gnpyAtoZ;
58 private GnpyResult gnpyZtoA;
59 private Boolean success;
60 private String message;
61 private String responseCode;
62 private final GnpyConsumer gnpyConsumer;
63 private PortMapping portMapping;
65 public PceSendingPceRPCs(GnpyConsumer gnpyConsumer) {
66 setPathDescription(null);
68 this.networkTransaction = null;
69 this.gnpyConsumer = gnpyConsumer;
72 public PceSendingPceRPCs(PathComputationRequestInput input,
73 NetworkTransactionService networkTransaction, GnpyConsumer gnpyConsumer, PortMapping portMapping) {
74 this.gnpyConsumer = gnpyConsumer;
75 setPathDescription(null);
77 // TODO compliance check to check that input is not empty
79 this.networkTransaction = networkTransaction;
80 this.portMapping = portMapping;
83 public void cancelResourceReserve() {
85 LOG.info("Wait for 10s til beginning the PCE cancelResourceReserve request");
89 } catch (InterruptedException e) {
90 LOG.error("in PCESendingPceRPC: ",e);
93 LOG.info("cancelResourceReserve ...");
96 public void pathComputationWithConstraints(PceConstraints hardConstraints, PceConstraints softConstraints) {
98 PceCalculation nwAnalizer =
99 new PceCalculation(input, networkTransaction, hardConstraints, softConstraints, rc, portMapping);
100 nwAnalizer.retrievePceNetwork();
101 rc = nwAnalizer.getReturnStructure();
102 String serviceType = nwAnalizer.getServiceType();
103 if (!rc.getStatus()) {
104 LOG.error("In pathComputationWithConstraints, nwAnalizer: result = {}", rc);
107 LOG.info("PceGraph ...");
108 PceGraph graph = new PceGraph(nwAnalizer.getaendPceNode(), nwAnalizer.getzendPceNode(),
109 nwAnalizer.getAllPceNodes(), hardConstraints, softConstraints, rc, serviceType);
111 rc = graph.getReturnStructure();
112 if (!rc.getStatus()) {
113 LOG.warn("In pathComputationWithConstraints : Graph return without Path ");
114 // TODO fix. This is quick workaround for algorithm problem
115 if ((rc.getLocalCause() == PceResult.LocalCause.TOO_HIGH_LATENCY)
116 && (hardConstraints.getPceMetrics() == PceMetric.HopCount)
117 && (hardConstraints.getMaxLatency() != -1)) {
118 hardConstraints.setPceMetrics(PceMetric.PropagationDelay);
119 graph = patchRerunGraph(graph);
122 if (rc.getLocalCause() == PceResult.LocalCause.HD_NODE_INCLUDE) {
123 graph.setKpathsToBring(graph.getKpathsToBring() * 10);
124 graph = patchRerunGraph(graph);
127 if (!rc.getStatus()) {
128 LOG.error("In pathComputationWithConstraints, graph.calcPath: result = {}", rc);
132 LOG.info("PcePathDescription ...");
133 PcePathDescription description = new PcePathDescription(graph.getPathAtoZ(), nwAnalizer.getAllPceLinks(), rc);
134 description.buildDescriptions();
135 rc = description.getReturnStructure();
136 if (!rc.getStatus()) {
137 LOG.error("In pathComputationWithConstraints, description: result = {}", rc);
141 public void pathComputation() throws Exception {
143 PceConstraintsCalc constraints = new PceConstraintsCalc(input, networkTransaction);
144 pceHardConstraints = constraints.getPceHardConstraints();
145 pceSoftConstraints = constraints.getPceSoftConstraints();
146 pathComputationWithConstraints(pceHardConstraints, pceSoftConstraints);
147 this.success = rc.getStatus();
148 this.message = rc.getMessage();
149 this.responseCode = rc.getResponseCode();
151 AToZDirection atoz = null;
152 ZToADirection ztoa = null;
153 if (rc.getStatus()) {
154 atoz = rc.getAtoZDirection();
155 ztoa = rc.getZtoADirection();
158 //Connect to Gnpy to check path feasibility and recompute another path in case of path non-feasibility
160 if (gnpyConsumer.isAvailable()) {
161 GnpyUtilitiesImpl gnpy = new GnpyUtilitiesImpl(networkTransaction, input,
163 if (rc.getStatus() && gnpyToCheckFeasiblity(atoz,ztoa,gnpy)) {
164 setPathDescription(new PathDescriptionBuilder().setAToZDirection(atoz).setZToADirection(ztoa));
167 callGnpyToComputeNewPath(gnpy);
169 setPathDescription(new PathDescriptionBuilder().setAToZDirection(atoz).setZToADirection(ztoa));
172 catch (GnpyException e) {
173 LOG.error("Exception raised by GNPy {}",e.getMessage());
174 setPathDescription(new PathDescriptionBuilder().setAToZDirection(atoz).setZToADirection(ztoa));
178 private boolean gnpyToCheckFeasiblity(AToZDirection atoz, ZToADirection ztoa, GnpyUtilitiesImpl gnpy)
179 throws GnpyException {
181 //Call GNPy for path verification
182 if (gnpy.verifyComputationByGnpy(atoz, ztoa, pceHardConstraints)) {
183 LOG.info("In pceSendingPceRPC: the path is feasible according to Gnpy");
184 gnpyAtoZ = gnpy.getGnpyAtoZ();
185 gnpyZtoA = gnpy.getGnpyZtoA();
191 private void callGnpyToComputeNewPath(GnpyUtilitiesImpl gnpy) throws GnpyException {
193 //Call GNPy in the case of non feasibility
194 LOG.info("In pceSendingPceRPC: the path is not feasible according to Gnpy");
195 HardConstraints gnpyPathAsHC = null;
196 gnpyPathAsHC = gnpy.askNewPathFromGnpy(pceHardConstraints);
197 if (gnpyPathAsHC == null) {
198 LOG.info("In pceSendingPceRPC: GNPy failed to find another path");
199 this.success = false;
200 this.message = "No path available by PCE and GNPy ";
201 this.responseCode = ResponseCodes.RESPONSE_FAILED;
202 gnpyAtoZ = gnpy.getGnpyAtoZ();
203 gnpyZtoA = gnpy.getGnpyZtoA();
207 LOG.info("In pceSendingPceRPC: GNPy succeed to find another path");
209 PathComputationRequestInput inputFromGnpy = new PathComputationRequestInputBuilder()
210 .setServiceName(input.getServiceName())
211 .setHardConstraints(gnpyPathAsHC)
212 .setSoftConstraints(input.getSoftConstraints())
213 .setPceRoutingMetric(PceMetric.HopCount)
214 .setServiceAEnd(input.getServiceAEnd())
215 .setServiceZEnd(input.getServiceZEnd())
217 PceConstraintsCalc constraintsGnpy = new PceConstraintsCalc(inputFromGnpy, networkTransaction);
218 PceConstraints gnpyHardConstraints = constraintsGnpy.getPceHardConstraints();
219 PceConstraints gnpySoftConstraints = constraintsGnpy.getPceSoftConstraints();
220 pathComputationWithConstraints(gnpyHardConstraints, gnpySoftConstraints);
221 AToZDirection atoz = rc.getAtoZDirection();
222 ZToADirection ztoa = rc.getZtoADirection();
223 if (gnpyToCheckFeasiblity(atoz, ztoa,gnpy)) {
224 LOG.info("In pceSendingPceRPC: the new path computed by GNPy is valid");
226 this.message = "Path is calculated by GNPy";
227 this.responseCode = ResponseCodes.RESPONSE_OK;
228 setPathDescription(new PathDescriptionBuilder().setAToZDirection(atoz).setZToADirection(ztoa));
230 LOG.info("In pceSendingPceRPC: the new path computed by GNPy is not valid");
231 this.success = false;
232 this.message = "No path available";
233 this.responseCode = ResponseCodes.RESPONSE_FAILED;
234 setPathDescription(new PathDescriptionBuilder().setAToZDirection(null).setZToADirection(null));
238 private PceGraph patchRerunGraph(PceGraph graph) {
239 LOG.info("In pathComputation patchRerunGraph : rerun Graph with metric = PROPAGATION-DELAY ");
240 graph.setConstrains(pceHardConstraints, pceSoftConstraints);
245 public PathDescriptionBuilder getPathDescription() {
246 return pathDescription;
249 private void setPathDescription(PathDescriptionBuilder pathDescription) {
250 this.pathDescription = pathDescription;
253 public Boolean getSuccess() {
257 public String getMessage() {
261 public String getResponseCode() {
262 return this.responseCode;
265 public GnpyResult getGnpyAtoZ() {
269 public GnpyResult getGnpyZtoA() {