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.rev190624.CancelResourceReserveInput;
24 import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.pce.rev190624.CancelResourceReserveInputBuilder;
25 import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.pce.rev190624.CancelResourceReserveOutput;
26 import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.pce.rev190624.CancelResourceReserveOutputBuilder;
27 import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.pce.rev190624.PathComputationRequestInput;
28 import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.pce.rev190624.PathComputationRequestInputBuilder;
29 import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.pce.rev190624.PathComputationRequestOutput;
30 import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.pce.rev190624.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.ServiceFeasibilityCheckInput;
40 import org.opendaylight.yang.gen.v1.http.org.openroadm.service.rev161014.TempServiceCreateInput;
41 import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.routing.constraints.rev171017.RoutingConstraintsSp.PceMetric;
42 import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.routing.constraints.rev171017.routing.constraints.sp.HardConstraints;
43 import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.routing.constraints.rev171017.routing.constraints.sp.SoftConstraints;
44 import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.service.types.rev170426.RpcStatusEx;
45 import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.service.types.rev171016.response.parameters.sp.ResponseParameters;
46 import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.service.types.rev171016.response.parameters.sp.ResponseParametersBuilder;
47 import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.service.types.rev171016.service.handler.header.ServiceHandlerHeaderBuilder;
48 import org.slf4j.Logger;
49 import org.slf4j.LoggerFactory;
51 public class PCEServiceWrapper {
53 private static final Logger LOG = LoggerFactory.getLogger(PCEServiceWrapper.class);
55 private final PathComputationService pathComputationService;
56 private final NotificationPublishService notificationPublishService;
57 private ServiceRpcResultSh notification = null;
58 private final ListeningExecutorService executor;
60 public PCEServiceWrapper(PathComputationService pathComputationService,
61 NotificationPublishService notificationPublishService) {
62 this.pathComputationService = pathComputationService;
63 this.notificationPublishService = notificationPublishService;
64 executor = MoreExecutors.listeningDecorator(Executors.newFixedThreadPool(5));
67 public PathComputationRequestOutput performPCE(ServiceCreateInput serviceCreateInput, boolean reserveResource) {
68 LOG.info("performing PCE ...");
69 if (validateParams(serviceCreateInput.getServiceName(), serviceCreateInput.getSdncRequestHeader())) {
70 return performPCE(serviceCreateInput.getHardConstraints(), serviceCreateInput.getSoftConstraints(),
71 serviceCreateInput.getServiceName(), serviceCreateInput.getSdncRequestHeader(),
72 serviceCreateInput.getServiceAEnd(), serviceCreateInput.getServiceZEnd(),
73 ServiceNotificationTypes.ServiceCreateResult, reserveResource);
75 return returnPCEFailed();
79 public PathComputationRequestOutput performPCE(TempServiceCreateInput tempServiceCreateInput,
80 boolean reserveResource) {
81 LOG.info("performing PCE ...");
82 if (validateParams(tempServiceCreateInput.getCommonId(), tempServiceCreateInput.getSdncRequestHeader())) {
83 return performPCE(tempServiceCreateInput.getHardConstraints(), tempServiceCreateInput.getSoftConstraints(),
84 tempServiceCreateInput.getCommonId(), tempServiceCreateInput.getSdncRequestHeader(),
85 tempServiceCreateInput.getServiceAEnd(), tempServiceCreateInput.getServiceZEnd(),
86 ServiceNotificationTypes.ServiceCreateResult, reserveResource);
88 return returnPCEFailed();
92 public PathComputationRequestOutput performPCE(ServiceFeasibilityCheckInput serviceFeasibilityCheckInput,
93 boolean reserveResource) {
94 LOG.info("performing PCE ...");
95 if (validateParams(serviceFeasibilityCheckInput.getCommonId(),
96 serviceFeasibilityCheckInput.getSdncRequestHeader())) {
97 return performPCE(serviceFeasibilityCheckInput.getHardConstraints(),
98 serviceFeasibilityCheckInput.getSoftConstraints(), serviceFeasibilityCheckInput.getCommonId(),
99 serviceFeasibilityCheckInput.getSdncRequestHeader(), serviceFeasibilityCheckInput.getServiceAEnd(),
100 serviceFeasibilityCheckInput.getServiceZEnd(),
101 ServiceNotificationTypes.ServiceFeasibilityCheckResult, reserveResource);
103 return returnPCEFailed();
107 private PathComputationRequestOutput performPCE(org.opendaylight.yang.gen.v1.http.org.openroadm.routing.constrains
108 .rev161014.routing.constraints.HardConstraints hardConstraints, org.opendaylight.yang.gen.v1.http.org
109 .openroadm.routing.constrains.rev161014.routing.constraints.SoftConstraints softConstraints,
110 String serviceName, SdncRequestHeader sdncRequestHeader, ServiceEndpoint serviceAEnd,
111 ServiceEndpoint serviceZEnd, ServiceNotificationTypes notifType, boolean reserveResource) {
112 MappingConstraints mappingConstraints = new MappingConstraints(hardConstraints, softConstraints);
113 mappingConstraints.serviceToServicePathConstarints();
114 LOG.info("Calling path computation.");
115 notification = new ServiceRpcResultShBuilder().setNotificationType(notifType).setServiceName(serviceName)
116 .setStatus(RpcStatusEx.Pending)
117 .setStatusMessage("Service compliant, submitting PathComputation Request ...").build();
119 notificationPublishService.putNotification(notification);
120 } catch (InterruptedException e) {
121 LOG.info("notification offer rejected : " + e);
123 FutureCallback<PathComputationRequestOutput> pceCallback = new FutureCallback<PathComputationRequestOutput>() {
125 ServiceRpcResultSh notification = null;
128 public void onSuccess(PathComputationRequestOutput response) {
129 if (response != null) {
131 * If PCE reply is received before timer expiration with a positive result, a
132 * service is created with admin and operational status 'down'.
134 message = "PCE replied to PCR Request !";
135 LOG.info("PCE replied to PCR Request : {}", response);
136 notification = new ServiceRpcResultShBuilder().setNotificationType(notifType)
137 .setServiceName(serviceName)
138 .setStatus(RpcStatusEx.Successful).setStatusMessage(message).build();
140 notificationPublishService.putNotification(notification);
141 } catch (InterruptedException e) {
142 LOG.info("notification offer rejected : " + e);
145 message = "PCE failed ";
146 notification = new ServiceRpcResultShBuilder().setNotificationType(notifType).setServiceName("")
147 .setStatus(RpcStatusEx.Failed).setStatusMessage(message).build();
149 notificationPublishService.putNotification(notification);
150 } catch (InterruptedException e) {
151 LOG.info("notification offer rejected : " + e);
157 public void onFailure(Throwable arg0) {
158 LOG.error("Path not calculated..");
159 notification = new ServiceRpcResultShBuilder().setNotificationType(notifType)
160 .setServiceName(serviceName)
161 .setStatus(RpcStatusEx.Failed).setStatusMessage("PCR Request failed : " + arg0.getMessage())
164 notificationPublishService.putNotification(notification);
165 } catch (InterruptedException e) {
166 LOG.info("notification offer rejected : " + e);
170 PathComputationRequestInput pathComputationRequestInput = createPceRequestInput(serviceName, sdncRequestHeader,
171 mappingConstraints.getServicePathHardConstraints(), mappingConstraints.getServicePathSoftConstraints(),
172 reserveResource, serviceAEnd, serviceZEnd);
173 ListenableFuture<PathComputationRequestOutput> pce = this.pathComputationService
174 .pathComputationRequest(pathComputationRequestInput);
175 Futures.addCallback(pce, pceCallback, executor);
177 ConfigurationResponseCommon configurationResponseCommon = new ConfigurationResponseCommonBuilder()
178 .setAckFinalIndicator(ResponseCodes.FINAL_ACK_NO)
179 .setRequestId(sdncRequestHeader.getRequestId())
180 .setResponseCode(ResponseCodes.RESPONSE_OK)
181 .setResponseMessage("PCE calculation in progress")
183 ResponseParameters reponseParameters = new ResponseParametersBuilder().build();
184 return new PathComputationRequestOutputBuilder()
185 .setConfigurationResponseCommon(configurationResponseCommon)
186 .setResponseParameters(reponseParameters)
190 private PathComputationRequestInput createPceRequestInput(String serviceName,
191 SdncRequestHeader serviceHandler, HardConstraints hardConstraints,
192 SoftConstraints softConstraints, Boolean reserveResource, ServiceEndpoint serviceAEnd,
193 ServiceEndpoint serviceZEnd) {
194 LOG.info("Mapping ServiceCreateInput or ServiceFeasibilityCheckInput or serviceReconfigureInput to PCE"
196 ServiceHandlerHeaderBuilder serviceHandlerHeader = new ServiceHandlerHeaderBuilder();
197 if (serviceHandler != null) {
198 serviceHandlerHeader.setRequestId(serviceHandler.getRequestId());
200 return new PathComputationRequestInputBuilder()
201 .setServiceName(serviceName)
202 .setResourceReserve(reserveResource)
203 .setServiceHandlerHeader(serviceHandlerHeader.build())
204 .setHardConstraints(hardConstraints)
205 .setSoftConstraints(softConstraints)
206 .setPceMetric(PceMetric.TEMetric)
207 .setServiceAEnd(ModelMappingUtils.createServiceAEnd(serviceAEnd))
208 .setServiceZEnd(ModelMappingUtils.createServiceZEnd(serviceZEnd))
212 private CancelResourceReserveInput mappingCancelResourceReserve(String serviceName,
213 SdncRequestHeader sdncRequestHeader) {
214 LOG.info("Mapping to PCE Cancel resource request input");
215 CancelResourceReserveInputBuilder cancelResourceReserveInput = new CancelResourceReserveInputBuilder();
216 if (serviceName != null) {
217 ServiceHandlerHeaderBuilder serviceHandlerHeader = new ServiceHandlerHeaderBuilder();
218 if (sdncRequestHeader != null) {
219 serviceHandlerHeader.setRequestId(sdncRequestHeader.getRequestId());
221 cancelResourceReserveInput.setServiceName(serviceName)
222 .setServiceHandlerHeader(serviceHandlerHeader.build());
223 return cancelResourceReserveInput.build();
225 LOG.error("Service Name (common-id for Temp service) is not set");
230 public CancelResourceReserveOutput cancelPCEResource(String serviceName, ServiceNotificationTypes notifType) {
231 LOG.info("Calling cancel resource reserve computation.");
232 notification = new ServiceRpcResultShBuilder().setNotificationType(notifType).setServiceName(serviceName)
233 .setStatus(RpcStatusEx.Pending)
234 .setStatusMessage("submitting Cancel resource reserve Request ...").build();
236 notificationPublishService.putNotification(notification);
237 } catch (InterruptedException e) {
238 LOG.info("notification offer rejected : " + e);
240 FutureCallback<CancelResourceReserveOutput> pceCallback = new FutureCallback<CancelResourceReserveOutput>() {
243 ServiceRpcResultSh notification = null;
246 public void onSuccess(CancelResourceReserveOutput response) {
247 if (response != null) {
249 * If PCE reply is received before timer expiration with a positive result, a
250 * service is created with admin and operational status 'down'.
252 message = "PCE replied to CRR Request !";
253 LOG.info("PCE replied to CRR Request : {}", response);
255 new ServiceRpcResultShBuilder().setNotificationType(notifType).setServiceName(serviceName)
256 .setStatus(RpcStatusEx.Successful).setStatusMessage(message).build();
258 notificationPublishService.putNotification(notification);
259 } catch (InterruptedException e) {
260 LOG.info("notification offer rejected : " + e);
263 message = "PCE failed ";
264 notification = new ServiceRpcResultShBuilder().setNotificationType(notifType).setServiceName("")
265 .setStatus(RpcStatusEx.Failed).setStatusMessage(message).build();
267 notificationPublishService.putNotification(notification);
268 } catch (InterruptedException e) {
269 LOG.info("notification offer rejected : " + e);
275 public void onFailure(Throwable arg0) {
276 LOG.error("Cancel resource failed !");
277 notification = new ServiceRpcResultShBuilder().setNotificationType(notifType)
278 .setServiceName(serviceName).setStatus(RpcStatusEx.Failed)
279 .setStatusMessage("CRR Request failed : " + arg0.getMessage()).build();
281 notificationPublishService.putNotification(notification);
282 } catch (InterruptedException e) {
283 LOG.info("notification offer rejected : " + e);
287 CancelResourceReserveInput cancelResourceReserveInput = mappingCancelResourceReserve(serviceName, null);
288 ConfigurationResponseCommonBuilder configurationResponseCommon = new ConfigurationResponseCommonBuilder();
289 if (cancelResourceReserveInput != null) {
290 String requestId = cancelResourceReserveInput.getServiceHandlerHeader().getRequestId();
291 ListenableFuture<CancelResourceReserveOutput> pce =
292 this.pathComputationService.cancelResourceReserve(cancelResourceReserveInput);
293 Futures.addCallback(pce, pceCallback, executor);
294 if (requestId != null) {
295 configurationResponseCommon.setRequestId(requestId);
297 configurationResponseCommon.setAckFinalIndicator(ResponseCodes.FINAL_ACK_NO)
298 .setResponseCode(ResponseCodes.RESPONSE_OK).setResponseMessage("PCE calculation in progress");
299 return new CancelResourceReserveOutputBuilder()
300 .setConfigurationResponseCommon(configurationResponseCommon.build()).build();
302 configurationResponseCommon.setAckFinalIndicator(ResponseCodes.FINAL_ACK_YES)
303 .setResponseCode(ResponseCodes.RESPONSE_FAILED).setResponseMessage("PCE failed !");
304 return new CancelResourceReserveOutputBuilder()
305 .setConfigurationResponseCommon(configurationResponseCommon.build()).build();
309 private static PathComputationRequestOutput returnPCEFailed() {
310 ConfigurationResponseCommon configurationResponseCommon = new ConfigurationResponseCommonBuilder()
311 .setAckFinalIndicator(ResponseCodes.FINAL_ACK_YES).setResponseCode(ResponseCodes.RESPONSE_FAILED)
312 .setResponseMessage("PCE calculation failed").build();
313 ResponseParameters reponseParameters = new ResponseParametersBuilder().build();
314 return new PathComputationRequestOutputBuilder().setConfigurationResponseCommon(configurationResponseCommon)
315 .setResponseParameters(reponseParameters).build();
318 private Boolean validateParams(String serviceName, SdncRequestHeader sdncRequestHeader) {
319 boolean result = true;
320 if (!checkString(serviceName)) {
322 LOG.error("Service Name (common-id for Temp service) is not set");
323 } else if (sdncRequestHeader == null) {
324 LOG.error("Service sdncRequestHeader 'request-id' is not set");
330 private static boolean checkString(String value) {
331 return ((value != null) && (value.compareTo("") != 0));