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;
16 import java.util.concurrent.Executors;
18 import org.opendaylight.controller.md.sal.binding.api.NotificationPublishService;
19 import org.opendaylight.transportpce.common.ResponseCodes;
20 import org.opendaylight.transportpce.pce.service.PathComputationService;
21 import org.opendaylight.transportpce.servicehandler.MappingConstraints;
22 import org.opendaylight.transportpce.servicehandler.ModelMappingUtils;
23 import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.pce.rev171017.CancelResourceReserveInput;
24 import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.pce.rev171017.CancelResourceReserveInputBuilder;
25 import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.pce.rev171017.CancelResourceReserveOutput;
26 import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.pce.rev171017.CancelResourceReserveOutputBuilder;
27 import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.pce.rev171017.PathComputationRequestInput;
28 import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.pce.rev171017.PathComputationRequestInputBuilder;
29 import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.pce.rev171017.PathComputationRequestOutput;
30 import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.pce.rev171017.PathComputationRequestOutputBuilder;
31 import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.servicehandler.rev170930.ServiceRpcResultSh;
32 import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.servicehandler.rev170930.ServiceRpcResultShBuilder;
33 import org.opendaylight.yang.gen.v1.http.org.openroadm.common.service.types.rev161014.ServiceEndpoint;
34 import org.opendaylight.yang.gen.v1.http.org.openroadm.common.service.types.rev161014.ServiceNotificationTypes;
35 import org.opendaylight.yang.gen.v1.http.org.openroadm.common.service.types.rev161014.configuration.response.common.ConfigurationResponseCommon;
36 import org.opendaylight.yang.gen.v1.http.org.openroadm.common.service.types.rev161014.configuration.response.common.ConfigurationResponseCommonBuilder;
37 import org.opendaylight.yang.gen.v1.http.org.openroadm.common.service.types.rev161014.sdnc.request.header.SdncRequestHeader;
38 import org.opendaylight.yang.gen.v1.http.org.openroadm.service.rev161014.ServiceCreateInput;
39 import org.opendaylight.yang.gen.v1.http.org.openroadm.service.rev161014.TempServiceCreateInput;
40 import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.routing.constraints.rev171017.RoutingConstraintsSp.PceMetric;
41 import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.routing.constraints.rev171017.routing.constraints.sp.HardConstraints;
42 import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.routing.constraints.rev171017.routing.constraints.sp.SoftConstraints;
43 import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.service.types.rev170426.RpcStatusEx;
44 import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.service.types.rev171016.response.parameters.sp.ResponseParameters;
45 import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.service.types.rev171016.response.parameters.sp.ResponseParametersBuilder;
46 import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.service.types.rev171016.service.handler.header.ServiceHandlerHeaderBuilder;
47 import org.slf4j.Logger;
48 import org.slf4j.LoggerFactory;
50 public class PCEServiceWrapper {
52 private static final Logger LOG = LoggerFactory.getLogger(PCEServiceWrapper.class);
54 private final PathComputationService pathComputationService;
55 private final NotificationPublishService notificationPublishService;
56 private ServiceRpcResultSh notification = null;
57 private final ListeningExecutorService executor;
59 public PCEServiceWrapper(PathComputationService pathComputationService,
60 NotificationPublishService notificationPublishService) {
61 this.pathComputationService = pathComputationService;
62 this.notificationPublishService = notificationPublishService;
63 executor = MoreExecutors.listeningDecorator(Executors.newFixedThreadPool(5));
66 public PathComputationRequestOutput performPCE(ServiceCreateInput serviceCreateInput, boolean reserveResource) {
67 LOG.info("performing PCE ...");
68 if (validateParams(serviceCreateInput.getServiceName(), serviceCreateInput.getSdncRequestHeader())) {
69 return performPCE(serviceCreateInput.getHardConstraints(), serviceCreateInput.getSoftConstraints(),
70 serviceCreateInput.getServiceName(), serviceCreateInput.getSdncRequestHeader(),
71 serviceCreateInput.getServiceAEnd(), serviceCreateInput.getServiceZEnd(),
72 ServiceNotificationTypes.ServiceCreateResult, reserveResource);
74 return returnPCEFailed();
78 public PathComputationRequestOutput performPCE(TempServiceCreateInput tempServiceCreateInput,
79 boolean reserveResource) {
80 LOG.info("performing PCE ...");
81 if (validateParams(tempServiceCreateInput.getCommonId(), tempServiceCreateInput.getSdncRequestHeader())) {
82 return performPCE(tempServiceCreateInput.getHardConstraints(), tempServiceCreateInput.getSoftConstraints(),
83 tempServiceCreateInput.getCommonId(), tempServiceCreateInput.getSdncRequestHeader(),
84 tempServiceCreateInput.getServiceAEnd(), tempServiceCreateInput.getServiceZEnd(),
85 ServiceNotificationTypes.ServiceCreateResult, reserveResource);
87 return returnPCEFailed();
91 private PathComputationRequestOutput performPCE(org.opendaylight.yang.gen.v1.http.org.openroadm.routing.constrains
92 .rev161014.routing.constraints.HardConstraints hardConstraints, org.opendaylight.yang.gen.v1.http.org
93 .openroadm.routing.constrains.rev161014.routing.constraints.SoftConstraints softConstraints,
94 String serviceName, SdncRequestHeader sdncRequestHeader, ServiceEndpoint serviceAEnd,
95 ServiceEndpoint serviceZEnd, ServiceNotificationTypes notifType, boolean reserveResource) {
96 MappingConstraints mappingConstraints = new MappingConstraints(hardConstraints, softConstraints);
97 mappingConstraints.serviceToServicePathConstarints();
98 LOG.info("Calling path computation.");
99 notification = new ServiceRpcResultShBuilder().setNotificationType(notifType).setServiceName(serviceName)
100 .setStatus(RpcStatusEx.Pending)
101 .setStatusMessage("Service compliant, submitting PathComputation Request ...").build();
103 notificationPublishService.putNotification(notification);
104 } catch (InterruptedException e) {
105 LOG.info("notification offer rejected : " + e);
107 FutureCallback<PathComputationRequestOutput> pceCallback = new FutureCallback<PathComputationRequestOutput>() {
109 ServiceRpcResultSh notification = null;
112 public void onSuccess(PathComputationRequestOutput response) {
113 if (response != null) {
115 * If PCE reply is received before timer expiration with a positive result, a
116 * service is created with admin and operational status 'down'.
118 message = "PCE replied to PCR Request !";
119 LOG.info("PCE replied to PCR Request : {}", response);
120 notification = new ServiceRpcResultShBuilder().setNotificationType(notifType)
121 .setServiceName(serviceName)
122 .setStatus(RpcStatusEx.Successful).setStatusMessage(message).build();
124 notificationPublishService.putNotification(notification);
125 } catch (InterruptedException e) {
126 LOG.info("notification offer rejected : " + e);
129 message = "PCE failed ";
130 notification = new ServiceRpcResultShBuilder().setNotificationType(notifType).setServiceName("")
131 .setStatus(RpcStatusEx.Failed).setStatusMessage(message).build();
133 notificationPublishService.putNotification(notification);
134 } catch (InterruptedException e) {
135 LOG.info("notification offer rejected : " + e);
141 public void onFailure(Throwable arg0) {
142 LOG.error("Path not calculated..");
143 notification = new ServiceRpcResultShBuilder().setNotificationType(notifType)
144 .setServiceName(serviceName)
145 .setStatus(RpcStatusEx.Failed).setStatusMessage("PCR Request failed : " + arg0.getMessage())
148 notificationPublishService.putNotification(notification);
149 } catch (InterruptedException e) {
150 LOG.info("notification offer rejected : " + e);
154 PathComputationRequestInput pathComputationRequestInput = createPceRequestInput(serviceName, sdncRequestHeader,
155 mappingConstraints.getServicePathHardConstraints(), mappingConstraints.getServicePathSoftConstraints(),
156 reserveResource, serviceAEnd, serviceZEnd);
157 ListenableFuture<PathComputationRequestOutput> pce = this.pathComputationService
158 .pathComputationRequest(pathComputationRequestInput);
159 Futures.addCallback(pce, pceCallback, executor);
161 ConfigurationResponseCommon configurationResponseCommon = new ConfigurationResponseCommonBuilder()
162 .setAckFinalIndicator(ResponseCodes.FINAL_ACK_NO)
163 .setRequestId(sdncRequestHeader.getRequestId())
164 .setResponseCode(ResponseCodes.RESPONSE_OK)
165 .setResponseMessage("PCE calculation in progress")
167 ResponseParameters reponseParameters = new ResponseParametersBuilder().build();
168 return new PathComputationRequestOutputBuilder()
169 .setConfigurationResponseCommon(configurationResponseCommon)
170 .setResponseParameters(reponseParameters)
174 private PathComputationRequestInput createPceRequestInput(String serviceName,
175 SdncRequestHeader serviceHandler, HardConstraints hardConstraints,
176 SoftConstraints softConstraints, Boolean reserveResource, ServiceEndpoint serviceAEnd,
177 ServiceEndpoint serviceZEnd) {
178 LOG.info("Mapping ServiceCreateInput or ServiceFeasibilityCheckInput or serviceReconfigureInput to PCE"
180 ServiceHandlerHeaderBuilder serviceHandlerHeader = new ServiceHandlerHeaderBuilder();
181 if (serviceHandler != null) {
182 serviceHandlerHeader.setRequestId(serviceHandler.getRequestId());
184 return new PathComputationRequestInputBuilder()
185 .setServiceName(serviceName)
186 .setResourceReserve(reserveResource)
187 .setServiceHandlerHeader(serviceHandlerHeader.build())
188 .setHardConstraints(hardConstraints)
189 .setSoftConstraints(softConstraints)
190 .setPceMetric(PceMetric.TEMetric)
191 .setServiceAEnd(ModelMappingUtils.createServiceAEnd(serviceAEnd))
192 .setServiceZEnd(ModelMappingUtils.createServiceZEnd(serviceZEnd))
196 private CancelResourceReserveInput mappingCancelResourceReserve(String serviceName,
197 SdncRequestHeader sdncRequestHeader) {
198 LOG.info("Mapping to PCE Cancel resource request input");
199 CancelResourceReserveInputBuilder cancelResourceReserveInput = new CancelResourceReserveInputBuilder();
200 if (serviceName != null) {
201 ServiceHandlerHeaderBuilder serviceHandlerHeader = new ServiceHandlerHeaderBuilder();
202 if (sdncRequestHeader != null) {
203 serviceHandlerHeader.setRequestId(sdncRequestHeader.getRequestId());
205 cancelResourceReserveInput.setServiceName(serviceName)
206 .setServiceHandlerHeader(serviceHandlerHeader.build());
207 return cancelResourceReserveInput.build();
209 LOG.error("Service Name (common-id for Temp service) is not set");
214 public CancelResourceReserveOutput cancelPCEResource(String serviceName, ServiceNotificationTypes notifType) {
215 LOG.info("Calling cancel resource reserve computation.");
216 notification = new ServiceRpcResultShBuilder().setNotificationType(notifType).setServiceName(serviceName)
217 .setStatus(RpcStatusEx.Pending)
218 .setStatusMessage("submitting Cancel resource reserve Request ...").build();
220 notificationPublishService.putNotification(notification);
221 } catch (InterruptedException e) {
222 LOG.info("notification offer rejected : " + e);
224 FutureCallback<CancelResourceReserveOutput> pceCallback = new FutureCallback<CancelResourceReserveOutput>() {
227 ServiceRpcResultSh notification = null;
230 public void onSuccess(CancelResourceReserveOutput response) {
231 if (response != null) {
233 * If PCE reply is received before timer expiration with a positive result, a
234 * service is created with admin and operational status 'down'.
236 message = "PCE replied to CRR Request !";
237 LOG.info("PCE replied to CRR Request : {}", response);
239 new ServiceRpcResultShBuilder().setNotificationType(notifType).setServiceName(serviceName)
240 .setStatus(RpcStatusEx.Successful).setStatusMessage(message).build();
242 notificationPublishService.putNotification(notification);
243 } catch (InterruptedException e) {
244 LOG.info("notification offer rejected : " + e);
247 message = "PCE failed ";
248 notification = new ServiceRpcResultShBuilder().setNotificationType(notifType).setServiceName("")
249 .setStatus(RpcStatusEx.Failed).setStatusMessage(message).build();
251 notificationPublishService.putNotification(notification);
252 } catch (InterruptedException e) {
253 LOG.info("notification offer rejected : " + e);
259 public void onFailure(Throwable arg0) {
260 LOG.error("Cancel resource failed !");
261 notification = new ServiceRpcResultShBuilder().setNotificationType(notifType)
262 .setServiceName(serviceName).setStatus(RpcStatusEx.Failed)
263 .setStatusMessage("CRR Request failed : " + arg0.getMessage()).build();
265 notificationPublishService.putNotification(notification);
266 } catch (InterruptedException e) {
267 LOG.info("notification offer rejected : " + e);
271 CancelResourceReserveInput cancelResourceReserveInput = mappingCancelResourceReserve(serviceName, null);
272 ConfigurationResponseCommonBuilder configurationResponseCommon = new ConfigurationResponseCommonBuilder();
273 if (cancelResourceReserveInput != null) {
274 String requestId = cancelResourceReserveInput.getServiceHandlerHeader().getRequestId();
275 ListenableFuture<CancelResourceReserveOutput> pce =
276 this.pathComputationService.cancelResourceReserve(cancelResourceReserveInput);
277 Futures.addCallback(pce, pceCallback, executor);
278 if (requestId != null) {
279 configurationResponseCommon.setRequestId(requestId);
281 configurationResponseCommon.setAckFinalIndicator(ResponseCodes.FINAL_ACK_NO)
282 .setResponseCode(ResponseCodes.RESPONSE_OK).setResponseMessage("PCE calculation in progress");
283 return new CancelResourceReserveOutputBuilder()
284 .setConfigurationResponseCommon(configurationResponseCommon.build()).build();
286 configurationResponseCommon.setAckFinalIndicator(ResponseCodes.FINAL_ACK_YES)
287 .setResponseCode(ResponseCodes.RESPONSE_FAILED).setResponseMessage("PCE failed !");
288 return new CancelResourceReserveOutputBuilder()
289 .setConfigurationResponseCommon(configurationResponseCommon.build()).build();
293 private static PathComputationRequestOutput returnPCEFailed() {
294 ConfigurationResponseCommon configurationResponseCommon = new ConfigurationResponseCommonBuilder()
295 .setAckFinalIndicator(ResponseCodes.FINAL_ACK_YES).setResponseCode(ResponseCodes.RESPONSE_FAILED)
296 .setResponseMessage("PCE calculation failed").build();
297 ResponseParameters reponseParameters = new ResponseParametersBuilder().build();
298 return new PathComputationRequestOutputBuilder().setConfigurationResponseCommon(configurationResponseCommon)
299 .setResponseParameters(reponseParameters).build();
302 private Boolean validateParams(String serviceName, SdncRequestHeader sdncRequestHeader) {
303 boolean result = true;
304 if (!checkString(serviceName)) {
306 LOG.error("Service Name (common-id for Temp service) is not set");
307 } else if (sdncRequestHeader == null) {
308 LOG.error("Service sdncRequestHeader 'request-id' is not set");
314 private static boolean checkString(String value) {
315 return ((value != null) && (value.compareTo("") != 0));