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.ModelMappingUtils;
20 import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.pce.rev220118.CancelResourceReserveInput;
21 import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.pce.rev220118.CancelResourceReserveInputBuilder;
22 import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.pce.rev220118.CancelResourceReserveOutput;
23 import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.pce.rev220118.CancelResourceReserveOutputBuilder;
24 import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.pce.rev220118.PathComputationRequestInput;
25 import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.pce.rev220118.PathComputationRequestInputBuilder;
26 import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.pce.rev220118.PathComputationRequestOutput;
27 import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.pce.rev220118.PathComputationRequestOutputBuilder;
28 import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.servicehandler.rev201125.ServiceRpcResultSh;
29 import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.servicehandler.rev201125.ServiceRpcResultShBuilder;
30 import org.opendaylight.yang.gen.v1.http.org.openroadm.common.service.types.rev211210.ServiceEndpoint;
31 import org.opendaylight.yang.gen.v1.http.org.openroadm.common.service.types.rev211210.ServiceNotificationTypes;
32 import org.opendaylight.yang.gen.v1.http.org.openroadm.common.service.types.rev211210.configuration.response.common.ConfigurationResponseCommon;
33 import org.opendaylight.yang.gen.v1.http.org.openroadm.common.service.types.rev211210.configuration.response.common.ConfigurationResponseCommonBuilder;
34 import org.opendaylight.yang.gen.v1.http.org.openroadm.common.service.types.rev211210.sdnc.request.header.SdncRequestHeader;
35 import org.opendaylight.yang.gen.v1.http.org.openroadm.routing.constraints.rev211210.routing.constraints.HardConstraints;
36 import org.opendaylight.yang.gen.v1.http.org.openroadm.routing.constraints.rev211210.routing.constraints.SoftConstraints;
37 import org.opendaylight.yang.gen.v1.http.org.openroadm.service.rev211210.ServiceCreateInput;
38 import org.opendaylight.yang.gen.v1.http.org.openroadm.service.rev211210.ServiceFeasibilityCheckInput;
39 import org.opendaylight.yang.gen.v1.http.org.openroadm.service.rev211210.TempServiceCreateInput;
40 import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.service.types.rev220118.PceMetric;
41 import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.service.types.rev220118.RpcStatusEx;
42 import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.service.types.rev220118.response.parameters.sp.ResponseParameters;
43 import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.service.types.rev220118.response.parameters.sp.ResponseParametersBuilder;
44 import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.service.types.rev220118.service.handler.header.ServiceHandlerHeaderBuilder;
45 import org.slf4j.Logger;
46 import org.slf4j.LoggerFactory;
48 public class PCEServiceWrapper {
50 private static final String NOTIFICATION_OFFER_REJECTED_MSG = "notification offer rejected : ";
52 private static final String PERFORMING_PCE_MSG = "performing PCE ...";
54 private static final Logger LOG = LoggerFactory.getLogger(PCEServiceWrapper.class);
56 private final PathComputationService pathComputationService;
57 private final NotificationPublishService notificationPublishService;
58 private ServiceRpcResultSh notification = null;
59 private final ListeningExecutorService executor;
61 public PCEServiceWrapper(PathComputationService pathComputationService,
62 NotificationPublishService notificationPublishService) {
63 this.pathComputationService = pathComputationService;
64 this.notificationPublishService = notificationPublishService;
65 executor = MoreExecutors.listeningDecorator(Executors.newFixedThreadPool(5));
68 public PathComputationRequestOutput performPCE(ServiceCreateInput serviceCreateInput, boolean reserveResource) {
69 LOG.info(PERFORMING_PCE_MSG);
70 if (validateParams(serviceCreateInput.getServiceName(), serviceCreateInput.getSdncRequestHeader())) {
71 return performPCE(serviceCreateInput.getHardConstraints(), serviceCreateInput.getSoftConstraints(),
72 serviceCreateInput.getServiceName(), serviceCreateInput.getSdncRequestHeader(),
73 serviceCreateInput.getServiceAEnd(), serviceCreateInput.getServiceZEnd(),
74 ServiceNotificationTypes.ServiceCreateResult, reserveResource);
76 return returnPCEFailed();
80 public PathComputationRequestOutput performPCE(TempServiceCreateInput tempServiceCreateInput,
81 boolean reserveResource) {
82 LOG.info(PERFORMING_PCE_MSG);
83 if (validateParams(tempServiceCreateInput.getCommonId(), tempServiceCreateInput.getSdncRequestHeader())) {
84 return performPCE(tempServiceCreateInput.getHardConstraints(), tempServiceCreateInput.getSoftConstraints(),
85 tempServiceCreateInput.getCommonId(), tempServiceCreateInput.getSdncRequestHeader(),
86 tempServiceCreateInput.getServiceAEnd(), tempServiceCreateInput.getServiceZEnd(),
87 ServiceNotificationTypes.ServiceCreateResult, reserveResource);
89 return returnPCEFailed();
93 public PathComputationRequestOutput performPCE(ServiceFeasibilityCheckInput serviceFeasibilityCheckInput,
94 boolean reserveResource) {
95 LOG.info(PERFORMING_PCE_MSG);
96 if (validateParams(serviceFeasibilityCheckInput.getCommonId(),
97 serviceFeasibilityCheckInput.getSdncRequestHeader())) {
98 return performPCE(serviceFeasibilityCheckInput.getHardConstraints(),
99 serviceFeasibilityCheckInput.getSoftConstraints(), serviceFeasibilityCheckInput.getCommonId(),
100 serviceFeasibilityCheckInput.getSdncRequestHeader(), serviceFeasibilityCheckInput.getServiceAEnd(),
101 serviceFeasibilityCheckInput.getServiceZEnd(),
102 ServiceNotificationTypes.ServiceCreateResult, reserveResource);
104 return returnPCEFailed();
108 private PathComputationRequestOutput performPCE(HardConstraints hardConstraints, SoftConstraints softConstraints,
109 String serviceName, SdncRequestHeader sdncRequestHeader, ServiceEndpoint serviceAEnd,
110 ServiceEndpoint serviceZEnd, ServiceNotificationTypes notifType, boolean reserveResource) {
111 LOG.info("Calling path computation.");
112 notification = new ServiceRpcResultShBuilder().setNotificationType(notifType).setServiceName(serviceName)
113 .setStatus(RpcStatusEx.Pending)
114 .setStatusMessage("Service compliant, submitting PathComputation Request ...").build();
116 notificationPublishService.putNotification(notification);
117 } catch (InterruptedException e) {
118 LOG.info(NOTIFICATION_OFFER_REJECTED_MSG, e);
120 FutureCallback<PathComputationRequestOutput> pceCallback =
121 new PathComputationRequestOutputCallback(notifType, serviceName);
122 PathComputationRequestInput pathComputationRequestInput = createPceRequestInput(serviceName, sdncRequestHeader,
123 hardConstraints, softConstraints, reserveResource, serviceAEnd, serviceZEnd);
124 ListenableFuture<PathComputationRequestOutput> pce = this.pathComputationService
125 .pathComputationRequest(pathComputationRequestInput);
126 Futures.addCallback(pce, pceCallback, executor);
128 ConfigurationResponseCommon configurationResponseCommon = new ConfigurationResponseCommonBuilder()
129 .setAckFinalIndicator(ResponseCodes.FINAL_ACK_NO)
130 .setRequestId(sdncRequestHeader.getRequestId())
131 .setResponseCode(ResponseCodes.RESPONSE_OK)
132 .setResponseMessage("PCE calculation in progress")
134 ResponseParameters reponseParameters = new ResponseParametersBuilder().build();
135 return new PathComputationRequestOutputBuilder()
136 .setConfigurationResponseCommon(configurationResponseCommon)
137 .setResponseParameters(reponseParameters)
141 private PathComputationRequestInput createPceRequestInput(String serviceName,
142 SdncRequestHeader serviceHandler, HardConstraints hardConstraints,
143 SoftConstraints softConstraints, Boolean reserveResource, ServiceEndpoint serviceAEnd,
144 ServiceEndpoint serviceZEnd) {
145 LOG.info("Mapping ServiceCreateInput or ServiceFeasibilityCheckInput or serviceReconfigureInput to PCE"
147 ServiceHandlerHeaderBuilder serviceHandlerHeader = new ServiceHandlerHeaderBuilder();
148 if (serviceHandler != null) {
149 serviceHandlerHeader.setRequestId(serviceHandler.getRequestId());
151 return new PathComputationRequestInputBuilder()
152 .setServiceName(serviceName)
153 .setResourceReserve(reserveResource)
154 .setServiceHandlerHeader(serviceHandlerHeader.build())
155 .setHardConstraints(hardConstraints)
156 .setSoftConstraints(softConstraints)
157 .setPceRoutingMetric(PceMetric.TEMetric)
158 .setServiceAEnd(ModelMappingUtils.createServiceAEnd(serviceAEnd))
159 .setServiceZEnd(ModelMappingUtils.createServiceZEnd(serviceZEnd))
163 private CancelResourceReserveInput mappingCancelResourceReserve(String serviceName,
164 SdncRequestHeader sdncRequestHeader) {
165 LOG.info("Mapping to PCE Cancel resource request input");
166 CancelResourceReserveInputBuilder cancelResourceReserveInput = new CancelResourceReserveInputBuilder();
167 if (serviceName != null) {
168 ServiceHandlerHeaderBuilder serviceHandlerHeader = new ServiceHandlerHeaderBuilder();
169 if (sdncRequestHeader != null) {
170 serviceHandlerHeader.setRequestId(sdncRequestHeader.getRequestId());
172 cancelResourceReserveInput.setServiceName(serviceName)
173 .setServiceHandlerHeader(serviceHandlerHeader.build());
174 return cancelResourceReserveInput.build();
176 LOG.error("Service Name (common-id for Temp service) is not set");
181 public CancelResourceReserveOutput cancelPCEResource(String serviceName, ServiceNotificationTypes notifType) {
182 LOG.info("Calling cancel resource reserve computation.");
183 notification = new ServiceRpcResultShBuilder().setNotificationType(notifType).setServiceName(serviceName)
184 .setStatus(RpcStatusEx.Pending)
185 .setStatusMessage("submitting Cancel resource reserve Request ...").build();
187 notificationPublishService.putNotification(notification);
188 } catch (InterruptedException e) {
189 LOG.info(NOTIFICATION_OFFER_REJECTED_MSG, e);
191 FutureCallback<CancelResourceReserveOutput> pceCallback =
192 new CancelResourceReserveOutputFutureCallback(notifType, serviceName);
193 CancelResourceReserveInput cancelResourceReserveInput = mappingCancelResourceReserve(serviceName, null);
194 ConfigurationResponseCommonBuilder configurationResponseCommon = new ConfigurationResponseCommonBuilder();
195 if (cancelResourceReserveInput != null) {
196 String requestId = cancelResourceReserveInput.getServiceHandlerHeader().getRequestId();
197 ListenableFuture<CancelResourceReserveOutput> pce =
198 this.pathComputationService.cancelResourceReserve(cancelResourceReserveInput);
199 Futures.addCallback(pce, pceCallback, executor);
200 if (requestId != null) {
201 configurationResponseCommon.setRequestId(requestId);
203 configurationResponseCommon.setAckFinalIndicator(ResponseCodes.FINAL_ACK_NO)
204 .setResponseCode(ResponseCodes.RESPONSE_OK).setResponseMessage("PCE calculation in progress");
205 return new CancelResourceReserveOutputBuilder()
206 .setConfigurationResponseCommon(configurationResponseCommon.build()).build();
208 configurationResponseCommon.setAckFinalIndicator(ResponseCodes.FINAL_ACK_YES)
209 .setResponseCode(ResponseCodes.RESPONSE_FAILED).setResponseMessage("PCE failed !");
210 return new CancelResourceReserveOutputBuilder()
211 .setConfigurationResponseCommon(configurationResponseCommon.build()).build();
215 private static PathComputationRequestOutput returnPCEFailed() {
216 ConfigurationResponseCommon configurationResponseCommon = new ConfigurationResponseCommonBuilder()
217 .setAckFinalIndicator(ResponseCodes.FINAL_ACK_YES).setResponseCode(ResponseCodes.RESPONSE_FAILED)
218 .setResponseMessage("PCE calculation failed").build();
219 ResponseParameters reponseParameters = new ResponseParametersBuilder().build();
220 return new PathComputationRequestOutputBuilder().setConfigurationResponseCommon(configurationResponseCommon)
221 .setResponseParameters(reponseParameters).build();
224 private Boolean validateParams(String serviceName, SdncRequestHeader sdncRequestHeader) {
225 boolean result = true;
226 if (!checkString(serviceName)) {
228 LOG.error("Service Name (common-id for Temp service) is not set");
229 } else if (sdncRequestHeader == null) {
230 LOG.error("Service sdncRequestHeader 'request-id' is not set");
236 private static boolean checkString(String value) {
237 return ((value != null) && (value.compareTo("") != 0));
240 private final class CancelResourceReserveOutputFutureCallback
241 implements FutureCallback<CancelResourceReserveOutput> {
242 private final ServiceNotificationTypes notifType;
243 private final String serviceName;
245 ServiceRpcResultSh notification = null;
247 private CancelResourceReserveOutputFutureCallback(ServiceNotificationTypes notifType, String serviceName) {
248 this.notifType = notifType;
249 this.serviceName = serviceName;
253 public void onSuccess(CancelResourceReserveOutput response) {
254 if (response != null) {
256 * If PCE reply is received before timer expiration with a positive result, a
257 * service is created with admin and operational status 'down'.
259 message = "PCE replied to CRR Request !";
260 LOG.info("PCE replied to CRR Request : {}", response);
262 new ServiceRpcResultShBuilder().setNotificationType(notifType).setServiceName(serviceName)
263 .setStatus(RpcStatusEx.Successful).setStatusMessage(message).build();
265 notificationPublishService.putNotification(notification);
266 } catch (InterruptedException e) {
267 LOG.info(NOTIFICATION_OFFER_REJECTED_MSG, e);
270 message = "PCE failed ";
271 notification = new ServiceRpcResultShBuilder().setNotificationType(notifType).setServiceName("")
272 .setStatus(RpcStatusEx.Failed).setStatusMessage(message).build();
274 notificationPublishService.putNotification(notification);
275 } catch (InterruptedException e) {
276 LOG.info(NOTIFICATION_OFFER_REJECTED_MSG, e);
282 public void onFailure(Throwable arg0) {
283 LOG.error("Cancel resource failed !");
284 notification = new ServiceRpcResultShBuilder().setNotificationType(notifType)
285 .setServiceName(serviceName).setStatus(RpcStatusEx.Failed)
286 .setStatusMessage("CRR Request failed : " + arg0.getMessage()).build();
288 notificationPublishService.putNotification(notification);
289 } catch (InterruptedException e) {
290 LOG.info(NOTIFICATION_OFFER_REJECTED_MSG, e);
295 private final class PathComputationRequestOutputCallback implements FutureCallback<PathComputationRequestOutput> {
296 private final ServiceNotificationTypes notifType;
297 private final String serviceName;
299 ServiceRpcResultSh notification = null;
301 private PathComputationRequestOutputCallback(ServiceNotificationTypes notifType, String serviceName) {
302 this.notifType = notifType;
303 this.serviceName = serviceName;
307 public void onSuccess(PathComputationRequestOutput response) {
308 if (response != null) {
310 * If PCE reply is received before timer expiration with a positive result, a
311 * service is created with admin and operational status 'down'.
313 message = "PCE replied to PCR Request !";
314 LOG.info("PCE replied to PCR Request : {}", response);
315 notification = new ServiceRpcResultShBuilder().setNotificationType(notifType)
316 .setServiceName(serviceName)
317 .setStatus(RpcStatusEx.Successful).setStatusMessage(message).build();
319 notificationPublishService.putNotification(notification);
320 } catch (InterruptedException e) {
321 LOG.info(NOTIFICATION_OFFER_REJECTED_MSG, e);
324 message = "PCE failed ";
325 notification = new ServiceRpcResultShBuilder().setNotificationType(notifType).setServiceName("")
326 .setStatus(RpcStatusEx.Failed).setStatusMessage(message).build();
328 notificationPublishService.putNotification(notification);
329 } catch (InterruptedException e) {
330 LOG.info(NOTIFICATION_OFFER_REJECTED_MSG, e);
336 public void onFailure(Throwable arg0) {
337 LOG.error("Path not calculated..");
338 notification = new ServiceRpcResultShBuilder().setNotificationType(notifType)
339 .setServiceName(serviceName)
340 .setStatus(RpcStatusEx.Failed).setStatusMessage("PCR Request failed : " + arg0.getMessage())
343 notificationPublishService.putNotification(notification);
344 } catch (InterruptedException e) {
345 LOG.info(NOTIFICATION_OFFER_REJECTED_MSG, e);