fix import extra separations
[transportpce.git] / servicehandler / src / main / java / org / opendaylight / transportpce / servicehandler / service / PCEServiceWrapper.java
1 /*
2  * Copyright © 2017 Orange, Inc. and others.  All rights reserved.
3  *
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
7  */
8 package org.opendaylight.transportpce.servicehandler.service;
9
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;
48
49 public class PCEServiceWrapper {
50
51     private static final Logger LOG = LoggerFactory.getLogger(PCEServiceWrapper.class);
52
53     private final PathComputationService pathComputationService;
54     private final NotificationPublishService notificationPublishService;
55     private ServiceRpcResultSh notification = null;
56     private final ListeningExecutorService executor;
57
58     public PCEServiceWrapper(PathComputationService pathComputationService,
59             NotificationPublishService notificationPublishService) {
60         this.pathComputationService = pathComputationService;
61         this.notificationPublishService = notificationPublishService;
62         executor = MoreExecutors.listeningDecorator(Executors.newFixedThreadPool(5));
63     }
64
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);
72         } else {
73             return returnPCEFailed();
74         }
75     }
76
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);
85         } else {
86             return returnPCEFailed();
87         }
88     }
89
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);
100         } else {
101             return returnPCEFailed();
102         }
103     }
104
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();
116         try {
117             notificationPublishService.putNotification(notification);
118         } catch (InterruptedException e) {
119             LOG.info("notification offer rejected : ", e);
120         }
121         FutureCallback<PathComputationRequestOutput> pceCallback = new FutureCallback<PathComputationRequestOutput>() {
122             String message = "";
123             ServiceRpcResultSh notification = null;
124
125             @Override
126             public void onSuccess(PathComputationRequestOutput response) {
127                 if (response != null) {
128                     /**
129                      * If PCE reply is received before timer expiration with a positive result, a
130                      * service is created with admin and operational status 'down'.
131                      */
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();
137                     try {
138                         notificationPublishService.putNotification(notification);
139                     } catch (InterruptedException e) {
140                         LOG.info("notification offer rejected : ", e);
141                     }
142                 } else {
143                     message = "PCE failed ";
144                     notification = new ServiceRpcResultShBuilder().setNotificationType(notifType).setServiceName("")
145                             .setStatus(RpcStatusEx.Failed).setStatusMessage(message).build();
146                     try {
147                         notificationPublishService.putNotification(notification);
148                     } catch (InterruptedException e) {
149                         LOG.info("notification offer rejected : ", e);
150                     }
151                 }
152             }
153
154             @Override
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())
160                         .build();
161                 try {
162                     notificationPublishService.putNotification(notification);
163                 } catch (InterruptedException e) {
164                     LOG.info("notification offer rejected : ", e);
165                 }
166             }
167         };
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);
174
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")
180                 .build();
181         ResponseParameters reponseParameters = new ResponseParametersBuilder().build();
182         return new PathComputationRequestOutputBuilder()
183                 .setConfigurationResponseCommon(configurationResponseCommon)
184                 .setResponseParameters(reponseParameters)
185                 .build();
186     }
187
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"
193                 + "requests");
194         ServiceHandlerHeaderBuilder serviceHandlerHeader = new ServiceHandlerHeaderBuilder();
195         if (serviceHandler != null) {
196             serviceHandlerHeader.setRequestId(serviceHandler.getRequestId());
197         }
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))
207             .build();
208     }
209
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());
218             }
219             cancelResourceReserveInput.setServiceName(serviceName)
220                     .setServiceHandlerHeader(serviceHandlerHeader.build());
221             return cancelResourceReserveInput.build();
222         } else {
223             LOG.error("Service Name (common-id for Temp service) is not set");
224             return null;
225         }
226     }
227
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();
233         try {
234             notificationPublishService.putNotification(notification);
235         } catch (InterruptedException e) {
236             LOG.info("notification offer rejected : ", e);
237         }
238         FutureCallback<CancelResourceReserveOutput> pceCallback = new FutureCallback<CancelResourceReserveOutput>() {
239
240             String message = "";
241             ServiceRpcResultSh notification = null;
242
243             @Override
244             public void onSuccess(CancelResourceReserveOutput response) {
245                 if (response != null) {
246                     /**
247                      * If PCE reply is received before timer expiration with a positive result, a
248                      * service is created with admin and operational status 'down'.
249                      */
250                     message = "PCE replied to CRR Request !";
251                     LOG.info("PCE replied to CRR Request : {}", response);
252                     notification =
253                             new ServiceRpcResultShBuilder().setNotificationType(notifType).setServiceName(serviceName)
254                                     .setStatus(RpcStatusEx.Successful).setStatusMessage(message).build();
255                     try {
256                         notificationPublishService.putNotification(notification);
257                     } catch (InterruptedException e) {
258                         LOG.info("notification offer rejected : ", e);
259                     }
260                 } else {
261                     message = "PCE failed ";
262                     notification = new ServiceRpcResultShBuilder().setNotificationType(notifType).setServiceName("")
263                             .setStatus(RpcStatusEx.Failed).setStatusMessage(message).build();
264                     try {
265                         notificationPublishService.putNotification(notification);
266                     } catch (InterruptedException e) {
267                         LOG.info("notification offer rejected : ", e);
268                     }
269                 }
270             }
271
272             @Override
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();
278                 try {
279                     notificationPublishService.putNotification(notification);
280                 } catch (InterruptedException e) {
281                     LOG.info("notification offer rejected : ", e);
282                 }
283             }
284         };
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);
294             }
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();
299         } else {
300             configurationResponseCommon.setAckFinalIndicator(ResponseCodes.FINAL_ACK_YES)
301                     .setResponseCode(ResponseCodes.RESPONSE_FAILED).setResponseMessage("PCE failed !");
302             return new CancelResourceReserveOutputBuilder()
303                     .setConfigurationResponseCommon(configurationResponseCommon.build()).build();
304         }
305     }
306
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();
314     }
315
316     private Boolean validateParams(String serviceName, SdncRequestHeader sdncRequestHeader) {
317         boolean result = true;
318         if (!checkString(serviceName)) {
319             result = false;
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");
323             result = false;
324         }
325         return result;
326     }
327
328     private static boolean checkString(String value) {
329         return ((value != null) && (value.compareTo("") != 0));
330     }
331 }