2 * Copyright © 2017 Orange, Inc. 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
8 package org.opendaylight.transportpce.servicehandler.service;
10 import com.google.common.util.concurrent.FutureCallback;
11 import com.google.common.util.concurrent.Futures;
12 import com.google.common.util.concurrent.ListenableFuture;
13 import com.google.common.util.concurrent.ListeningExecutorService;
14 import com.google.common.util.concurrent.MoreExecutors;
15 import java.util.concurrent.Executors;
16 import org.opendaylight.mdsal.binding.api.NotificationPublishService;
17 import org.opendaylight.transportpce.common.ResponseCodes;
18 import org.opendaylight.transportpce.pce.service.PathComputationService;
19 import org.opendaylight.transportpce.servicehandler.MappingConstraints;
20 import org.opendaylight.transportpce.servicehandler.ModelMappingUtils;
21 import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.pce.rev200128.CancelResourceReserveInput;
22 import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.pce.rev200128.CancelResourceReserveInputBuilder;
23 import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.pce.rev200128.CancelResourceReserveOutput;
24 import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.pce.rev200128.CancelResourceReserveOutputBuilder;
25 import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.pce.rev200128.PathComputationRequestInput;
26 import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.pce.rev200128.PathComputationRequestInputBuilder;
27 import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.pce.rev200128.PathComputationRequestOutput;
28 import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.pce.rev200128.PathComputationRequestOutputBuilder;
29 import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.servicehandler.rev171017.ServiceRpcResultSh;
30 import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.servicehandler.rev171017.ServiceRpcResultShBuilder;
31 import org.opendaylight.yang.gen.v1.http.org.openroadm.common.service.types.rev190531.ServiceEndpoint;
32 import org.opendaylight.yang.gen.v1.http.org.openroadm.common.service.types.rev190531.ServiceNotificationTypes;
33 import org.opendaylight.yang.gen.v1.http.org.openroadm.common.service.types.rev190531.configuration.response.common.ConfigurationResponseCommon;
34 import org.opendaylight.yang.gen.v1.http.org.openroadm.common.service.types.rev190531.configuration.response.common.ConfigurationResponseCommonBuilder;
35 import org.opendaylight.yang.gen.v1.http.org.openroadm.common.service.types.rev190531.sdnc.request.header.SdncRequestHeader;
36 import org.opendaylight.yang.gen.v1.http.org.openroadm.service.rev190531.ServiceCreateInput;
37 import org.opendaylight.yang.gen.v1.http.org.openroadm.service.rev190531.ServiceFeasibilityCheckInput;
38 import org.opendaylight.yang.gen.v1.http.org.openroadm.service.rev190531.TempServiceCreateInput;
39 import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.routing.constraints.rev171017.RoutingConstraintsSp.PceMetric;
40 import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.routing.constraints.rev171017.routing.constraints.sp.HardConstraints;
41 import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.routing.constraints.rev171017.routing.constraints.sp.SoftConstraints;
42 import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.service.types.rev200128.RpcStatusEx;
43 import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.service.types.rev200128.response.parameters.sp.ResponseParameters;
44 import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.service.types.rev200128.response.parameters.sp.ResponseParametersBuilder;
45 import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.service.types.rev200128.service.handler.header.ServiceHandlerHeaderBuilder;
46 import org.slf4j.Logger;
47 import org.slf4j.LoggerFactory;
49 public class PCEServiceWrapper {
51 private static final Logger LOG = LoggerFactory.getLogger(PCEServiceWrapper.class);
53 private final PathComputationService pathComputationService;
54 private final NotificationPublishService notificationPublishService;
55 private ServiceRpcResultSh notification = null;
56 private final ListeningExecutorService executor;
58 public PCEServiceWrapper(PathComputationService pathComputationService,
59 NotificationPublishService notificationPublishService) {
60 this.pathComputationService = pathComputationService;
61 this.notificationPublishService = notificationPublishService;
62 executor = MoreExecutors.listeningDecorator(Executors.newFixedThreadPool(5));
65 public PathComputationRequestOutput performPCE(ServiceCreateInput serviceCreateInput, boolean reserveResource) {
66 LOG.info("performing PCE ...");
67 if (validateParams(serviceCreateInput.getServiceName(), serviceCreateInput.getSdncRequestHeader())) {
68 return performPCE(serviceCreateInput.getHardConstraints(), serviceCreateInput.getSoftConstraints(),
69 serviceCreateInput.getServiceName(), serviceCreateInput.getSdncRequestHeader(),
70 serviceCreateInput.getServiceAEnd(), serviceCreateInput.getServiceZEnd(),
71 ServiceNotificationTypes.ServiceCreateResult, reserveResource);
73 return returnPCEFailed();
77 public PathComputationRequestOutput performPCE(TempServiceCreateInput tempServiceCreateInput,
78 boolean reserveResource) {
79 LOG.info("performing PCE ...");
80 if (validateParams(tempServiceCreateInput.getCommonId(), tempServiceCreateInput.getSdncRequestHeader())) {
81 return performPCE(tempServiceCreateInput.getHardConstraints(), tempServiceCreateInput.getSoftConstraints(),
82 tempServiceCreateInput.getCommonId(), tempServiceCreateInput.getSdncRequestHeader(),
83 tempServiceCreateInput.getServiceAEnd(), tempServiceCreateInput.getServiceZEnd(),
84 ServiceNotificationTypes.ServiceCreateResult, reserveResource);
86 return returnPCEFailed();
90 public PathComputationRequestOutput performPCE(ServiceFeasibilityCheckInput serviceFeasibilityCheckInput,
91 boolean reserveResource) {
92 LOG.info("performing PCE ...");
93 if (validateParams(serviceFeasibilityCheckInput.getCommonId(),
94 serviceFeasibilityCheckInput.getSdncRequestHeader())) {
95 return performPCE(serviceFeasibilityCheckInput.getHardConstraints(),
96 serviceFeasibilityCheckInput.getSoftConstraints(), serviceFeasibilityCheckInput.getCommonId(),
97 serviceFeasibilityCheckInput.getSdncRequestHeader(), serviceFeasibilityCheckInput.getServiceAEnd(),
98 serviceFeasibilityCheckInput.getServiceZEnd(),
99 ServiceNotificationTypes.ServiceCreateResult, reserveResource);
101 return returnPCEFailed();
105 private PathComputationRequestOutput performPCE(org.opendaylight.yang.gen.v1.http.org.openroadm.routing.constrains
106 .rev190329.routing.constraints.HardConstraints hardConstraints, org.opendaylight.yang.gen.v1.http.org
107 .openroadm.routing.constrains.rev190329.routing.constraints.SoftConstraints softConstraints,
108 String serviceName, SdncRequestHeader sdncRequestHeader, ServiceEndpoint serviceAEnd,
109 ServiceEndpoint serviceZEnd, ServiceNotificationTypes notifType, boolean reserveResource) {
110 MappingConstraints mappingConstraints = new MappingConstraints(hardConstraints, softConstraints);
111 mappingConstraints.serviceToServicePathConstarints();
112 LOG.info("Calling path computation.");
113 notification = new ServiceRpcResultShBuilder().setNotificationType(notifType).setServiceName(serviceName)
114 .setStatus(RpcStatusEx.Pending)
115 .setStatusMessage("Service compliant, submitting PathComputation Request ...").build();
117 notificationPublishService.putNotification(notification);
118 } catch (InterruptedException e) {
119 LOG.info("notification offer rejected : ", e);
121 FutureCallback<PathComputationRequestOutput> pceCallback = new FutureCallback<PathComputationRequestOutput>() {
123 ServiceRpcResultSh notification = null;
126 public void onSuccess(PathComputationRequestOutput response) {
127 if (response != null) {
129 * If PCE reply is received before timer expiration with a positive result, a
130 * service is created with admin and operational status 'down'.
132 message = "PCE replied to PCR Request !";
133 LOG.info("PCE replied to PCR Request : {}", response);
134 notification = new ServiceRpcResultShBuilder().setNotificationType(notifType)
135 .setServiceName(serviceName)
136 .setStatus(RpcStatusEx.Successful).setStatusMessage(message).build();
138 notificationPublishService.putNotification(notification);
139 } catch (InterruptedException e) {
140 LOG.info("notification offer rejected : ", e);
143 message = "PCE failed ";
144 notification = new ServiceRpcResultShBuilder().setNotificationType(notifType).setServiceName("")
145 .setStatus(RpcStatusEx.Failed).setStatusMessage(message).build();
147 notificationPublishService.putNotification(notification);
148 } catch (InterruptedException e) {
149 LOG.info("notification offer rejected : ", e);
155 public void onFailure(Throwable arg0) {
156 LOG.error("Path not calculated..");
157 notification = new ServiceRpcResultShBuilder().setNotificationType(notifType)
158 .setServiceName(serviceName)
159 .setStatus(RpcStatusEx.Failed).setStatusMessage("PCR Request failed : " + arg0.getMessage())
162 notificationPublishService.putNotification(notification);
163 } catch (InterruptedException e) {
164 LOG.info("notification offer rejected : ", e);
168 PathComputationRequestInput pathComputationRequestInput = createPceRequestInput(serviceName, sdncRequestHeader,
169 mappingConstraints.getServicePathHardConstraints(), mappingConstraints.getServicePathSoftConstraints(),
170 reserveResource, serviceAEnd, serviceZEnd);
171 ListenableFuture<PathComputationRequestOutput> pce = this.pathComputationService
172 .pathComputationRequest(pathComputationRequestInput);
173 Futures.addCallback(pce, pceCallback, executor);
175 ConfigurationResponseCommon configurationResponseCommon = new ConfigurationResponseCommonBuilder()
176 .setAckFinalIndicator(ResponseCodes.FINAL_ACK_NO)
177 .setRequestId(sdncRequestHeader.getRequestId())
178 .setResponseCode(ResponseCodes.RESPONSE_OK)
179 .setResponseMessage("PCE calculation in progress")
181 ResponseParameters reponseParameters = new ResponseParametersBuilder().build();
182 return new PathComputationRequestOutputBuilder()
183 .setConfigurationResponseCommon(configurationResponseCommon)
184 .setResponseParameters(reponseParameters)
188 private PathComputationRequestInput createPceRequestInput(String serviceName,
189 SdncRequestHeader serviceHandler, HardConstraints hardConstraints,
190 SoftConstraints softConstraints, Boolean reserveResource, ServiceEndpoint serviceAEnd,
191 ServiceEndpoint serviceZEnd) {
192 LOG.info("Mapping ServiceCreateInput or ServiceFeasibilityCheckInput or serviceReconfigureInput to PCE"
194 ServiceHandlerHeaderBuilder serviceHandlerHeader = new ServiceHandlerHeaderBuilder();
195 if (serviceHandler != null) {
196 serviceHandlerHeader.setRequestId(serviceHandler.getRequestId());
198 return new PathComputationRequestInputBuilder()
199 .setServiceName(serviceName)
200 .setResourceReserve(reserveResource)
201 .setServiceHandlerHeader(serviceHandlerHeader.build())
202 .setHardConstraints(hardConstraints)
203 .setSoftConstraints(softConstraints)
204 .setPceMetric(PceMetric.TEMetric)
205 .setServiceAEnd(ModelMappingUtils.createServiceAEnd(serviceAEnd))
206 .setServiceZEnd(ModelMappingUtils.createServiceZEnd(serviceZEnd))
210 private CancelResourceReserveInput mappingCancelResourceReserve(String serviceName,
211 SdncRequestHeader sdncRequestHeader) {
212 LOG.info("Mapping to PCE Cancel resource request input");
213 CancelResourceReserveInputBuilder cancelResourceReserveInput = new CancelResourceReserveInputBuilder();
214 if (serviceName != null) {
215 ServiceHandlerHeaderBuilder serviceHandlerHeader = new ServiceHandlerHeaderBuilder();
216 if (sdncRequestHeader != null) {
217 serviceHandlerHeader.setRequestId(sdncRequestHeader.getRequestId());
219 cancelResourceReserveInput.setServiceName(serviceName)
220 .setServiceHandlerHeader(serviceHandlerHeader.build());
221 return cancelResourceReserveInput.build();
223 LOG.error("Service Name (common-id for Temp service) is not set");
228 public CancelResourceReserveOutput cancelPCEResource(String serviceName, ServiceNotificationTypes notifType) {
229 LOG.info("Calling cancel resource reserve computation.");
230 notification = new ServiceRpcResultShBuilder().setNotificationType(notifType).setServiceName(serviceName)
231 .setStatus(RpcStatusEx.Pending)
232 .setStatusMessage("submitting Cancel resource reserve Request ...").build();
234 notificationPublishService.putNotification(notification);
235 } catch (InterruptedException e) {
236 LOG.info("notification offer rejected : ", e);
238 FutureCallback<CancelResourceReserveOutput> pceCallback = new FutureCallback<CancelResourceReserveOutput>() {
241 ServiceRpcResultSh notification = null;
244 public void onSuccess(CancelResourceReserveOutput response) {
245 if (response != null) {
247 * If PCE reply is received before timer expiration with a positive result, a
248 * service is created with admin and operational status 'down'.
250 message = "PCE replied to CRR Request !";
251 LOG.info("PCE replied to CRR Request : {}", response);
253 new ServiceRpcResultShBuilder().setNotificationType(notifType).setServiceName(serviceName)
254 .setStatus(RpcStatusEx.Successful).setStatusMessage(message).build();
256 notificationPublishService.putNotification(notification);
257 } catch (InterruptedException e) {
258 LOG.info("notification offer rejected : ", e);
261 message = "PCE failed ";
262 notification = new ServiceRpcResultShBuilder().setNotificationType(notifType).setServiceName("")
263 .setStatus(RpcStatusEx.Failed).setStatusMessage(message).build();
265 notificationPublishService.putNotification(notification);
266 } catch (InterruptedException e) {
267 LOG.info("notification offer rejected : ", e);
273 public void onFailure(Throwable arg0) {
274 LOG.error("Cancel resource failed !");
275 notification = new ServiceRpcResultShBuilder().setNotificationType(notifType)
276 .setServiceName(serviceName).setStatus(RpcStatusEx.Failed)
277 .setStatusMessage("CRR Request failed : " + arg0.getMessage()).build();
279 notificationPublishService.putNotification(notification);
280 } catch (InterruptedException e) {
281 LOG.info("notification offer rejected : ", e);
285 CancelResourceReserveInput cancelResourceReserveInput = mappingCancelResourceReserve(serviceName, null);
286 ConfigurationResponseCommonBuilder configurationResponseCommon = new ConfigurationResponseCommonBuilder();
287 if (cancelResourceReserveInput != null) {
288 String requestId = cancelResourceReserveInput.getServiceHandlerHeader().getRequestId();
289 ListenableFuture<CancelResourceReserveOutput> pce =
290 this.pathComputationService.cancelResourceReserve(cancelResourceReserveInput);
291 Futures.addCallback(pce, pceCallback, executor);
292 if (requestId != null) {
293 configurationResponseCommon.setRequestId(requestId);
295 configurationResponseCommon.setAckFinalIndicator(ResponseCodes.FINAL_ACK_NO)
296 .setResponseCode(ResponseCodes.RESPONSE_OK).setResponseMessage("PCE calculation in progress");
297 return new CancelResourceReserveOutputBuilder()
298 .setConfigurationResponseCommon(configurationResponseCommon.build()).build();
300 configurationResponseCommon.setAckFinalIndicator(ResponseCodes.FINAL_ACK_YES)
301 .setResponseCode(ResponseCodes.RESPONSE_FAILED).setResponseMessage("PCE failed !");
302 return new CancelResourceReserveOutputBuilder()
303 .setConfigurationResponseCommon(configurationResponseCommon.build()).build();
307 private static PathComputationRequestOutput returnPCEFailed() {
308 ConfigurationResponseCommon configurationResponseCommon = new ConfigurationResponseCommonBuilder()
309 .setAckFinalIndicator(ResponseCodes.FINAL_ACK_YES).setResponseCode(ResponseCodes.RESPONSE_FAILED)
310 .setResponseMessage("PCE calculation failed").build();
311 ResponseParameters reponseParameters = new ResponseParametersBuilder().build();
312 return new PathComputationRequestOutputBuilder().setConfigurationResponseCommon(configurationResponseCommon)
313 .setResponseParameters(reponseParameters).build();
316 private Boolean validateParams(String serviceName, SdncRequestHeader sdncRequestHeader) {
317 boolean result = true;
318 if (!checkString(serviceName)) {
320 LOG.error("Service Name (common-id for Temp service) is not set");
321 } else if (sdncRequestHeader == null) {
322 LOG.error("Service sdncRequestHeader 'request-id' is not set");
328 private static boolean checkString(String value) {
329 return ((value != null) && (value.compareTo("") != 0));