Fix CI Cent OS 8 configuration issue (workaround)
[transportpce.git] / servicehandler / src / main / java / org / opendaylight / transportpce / servicehandler / service / RendererServiceWrapper.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.renderer.provisiondevice.RendererServiceOperations;
19 import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.renderer.rev210915.ServiceDeleteInput;
20 import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.renderer.rev210915.ServiceDeleteInputBuilder;
21 import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.renderer.rev210915.ServiceDeleteOutput;
22 import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.renderer.rev210915.ServiceDeleteOutputBuilder;
23 import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.servicehandler.rev201125.ServiceRpcResultSh;
24 import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.servicehandler.rev201125.ServiceRpcResultShBuilder;
25 import org.opendaylight.yang.gen.v1.http.org.openroadm.common.service.types.rev230526.ServiceNotificationTypes;
26 import org.opendaylight.yang.gen.v1.http.org.openroadm.common.service.types.rev230526.configuration.response.common.ConfigurationResponseCommon;
27 import org.opendaylight.yang.gen.v1.http.org.openroadm.common.service.types.rev230526.configuration.response.common.ConfigurationResponseCommonBuilder;
28 import org.opendaylight.yang.gen.v1.http.org.openroadm.common.service.types.rev230526.service.ServiceAEndBuilder;
29 import org.opendaylight.yang.gen.v1.http.org.openroadm.common.service.types.rev230526.service.ServiceZEndBuilder;
30 import org.opendaylight.yang.gen.v1.http.org.openroadm.service.rev230526.TempServiceDeleteInput;
31 import org.opendaylight.yang.gen.v1.http.org.openroadm.service.rev230526.service.list.Services;
32 import org.opendaylight.yang.gen.v1.http.org.openroadm.service.rev230526.service.list.ServicesBuilder;
33 import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.service.types.rev220118.RpcStatusEx;
34 import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.service.types.rev220118.service.handler.header.ServiceHandlerHeader;
35 import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.service.types.rev220118.service.handler.header.ServiceHandlerHeaderBuilder;
36 import org.slf4j.Logger;
37 import org.slf4j.LoggerFactory;
38
39 /**
40  * Class to call RendererServiceOperations.
41  *
42  * @author Martial Coulibaly ( martial.coulibaly@gfi.com ) on behalf of Orange
43  *
44  */
45 public class RendererServiceWrapper {
46
47     private static final Logger LOG = LoggerFactory.getLogger(RendererServiceWrapper.class);
48     private final RendererServiceOperations rendererServiceOperations;
49     private final NotificationPublishService notificationPublishService;
50     private ServiceRpcResultSh notification = null;
51     private final ListeningExecutorService executor;
52
53     public RendererServiceWrapper(RendererServiceOperations rendererServiceOperations,
54             NotificationPublishService notificationPublishService) {
55         this.rendererServiceOperations = rendererServiceOperations;
56         this.notificationPublishService = notificationPublishService;
57         this.executor = MoreExecutors.listeningDecorator(Executors.newFixedThreadPool(5));
58     }
59
60     private void sendNotifications(ServiceRpcResultSh notif) {
61         try {
62             notificationPublishService.putNotification(notif);
63         } catch (InterruptedException e) {
64             LOG.info("notification offer rejected : ", e);
65         }
66     }
67
68     public ServiceDeleteOutput performRenderer(ServiceDeleteInput serviceDeleteInput,
69             ServiceNotificationTypes notifType, Services service) {
70         if (validateParams(serviceDeleteInput.getServiceName(), serviceDeleteInput.getServiceHandlerHeader(), false)) {
71             return performRenderer(serviceDeleteInput.getServiceName(), serviceDeleteInput.getServiceHandlerHeader(),
72                     ServiceNotificationTypes.ServiceDeleteResult, service);
73         } else {
74             return returnRendererFailed();
75         }
76     }
77
78
79     // TODO: Here is where the  we are sending null values for the service and that is causing issues
80     // We are performing renderer using null values
81     public ServiceDeleteOutput performRenderer(
82             TempServiceDeleteInput tempServiceDeleteInput,
83             ServiceNotificationTypes notifType,
84             org.opendaylight.yang.gen.v1.http.org.openroadm.service.rev230526
85                     .temp.service.list.Services tempService) {
86         String commonId = tempServiceDeleteInput.getCommonId();
87         return validateParams(commonId, null, true)
88             ? performRenderer(tempServiceDeleteInput,
89                 new ServiceHandlerHeaderBuilder().setRequestId(commonId).build(),
90                 ServiceNotificationTypes.ServiceDeleteResult,
91                 tempService)
92             : returnRendererFailed();
93     }
94
95     private ServiceDeleteOutput performRenderer(
96             TempServiceDeleteInput tempServiceDeleteInput,
97             ServiceHandlerHeader serviceHandlerHeader,
98             ServiceNotificationTypes notifType,
99             org.opendaylight.yang.gen.v1.http.org.openroadm.service.rev230526
100                     .temp.service.list.Services tempService) {
101         String commonId = tempServiceDeleteInput.getCommonId();
102         notification = new ServiceRpcResultShBuilder()
103                 .setNotificationType(notifType)
104                 .setServiceName(commonId)
105                 .setStatus(RpcStatusEx.Pending)
106                 .setStatusMessage("Service compliant, submitting temp service delete Request ...")
107                 .build();
108         sendNotifications(notification);
109         FutureCallback<ServiceDeleteOutput> rendererCallback =
110                 new ServiceDeleteOutputFutureCallback(notifType, commonId);
111         ServiceDeleteInput serviceDeleteInput = createRendererRequestInput(commonId, serviceHandlerHeader);
112         // Here build the regular service-list container from the temp-service-list
113         ListenableFuture<ServiceDeleteOutput> renderer =
114                 this.rendererServiceOperations.serviceDelete(serviceDeleteInput,
115                         new ServicesBuilder()
116                                 .setServiceName(commonId)
117                                 .setServiceAEnd(new ServiceAEndBuilder(tempService.getServiceAEnd()).build())
118                                 .setServiceZEnd(new ServiceZEndBuilder(tempService.getServiceZEnd()).build())
119                                 .setCommonId(commonId)
120                                 .build());
121         Futures.addCallback(renderer, rendererCallback, executor);
122         return new ServiceDeleteOutputBuilder()
123                 .setConfigurationResponseCommon(
124                         new ConfigurationResponseCommonBuilder()
125                                 .setAckFinalIndicator(ResponseCodes.FINAL_ACK_NO)
126                                 .setRequestId(serviceDeleteInput
127                                         .getServiceHandlerHeader()
128                                         .getRequestId())
129                                 .setResponseCode(ResponseCodes.RESPONSE_OK)
130                                 .setResponseMessage("Renderer temp-service delete in progress")
131                                 .build())
132                 .build();
133     }
134
135     private ServiceDeleteOutput performRenderer(String serviceName, ServiceHandlerHeader serviceHandlerHeader,
136             ServiceNotificationTypes notifType, Services service) {
137         notification = new ServiceRpcResultShBuilder().setNotificationType(notifType).setServiceName(serviceName)
138                 .setStatus(RpcStatusEx.Pending)
139                 .setStatusMessage("Service compliant, submitting temp service delete Request ...").build();
140         sendNotifications(notification);
141         FutureCallback<ServiceDeleteOutput> rendererCallback =
142                 new ServiceDeleteOutputFutureCallback(notifType, serviceName);
143         ServiceDeleteInput serviceDeleteInput = createRendererRequestInput(serviceName, serviceHandlerHeader);
144         ListenableFuture<ServiceDeleteOutput> renderer =
145                 this.rendererServiceOperations.serviceDelete(serviceDeleteInput, service);
146         Futures.addCallback(renderer, rendererCallback, executor);
147         ConfigurationResponseCommon value =
148                 new ConfigurationResponseCommonBuilder().setAckFinalIndicator(ResponseCodes.FINAL_ACK_NO)
149                         .setRequestId(serviceDeleteInput.getServiceHandlerHeader().getRequestId())
150                         .setResponseCode(ResponseCodes.RESPONSE_OK)
151                         .setResponseMessage("Renderer service delete in progress").build();
152         return new ServiceDeleteOutputBuilder().setConfigurationResponseCommon(value).build();
153     }
154
155     private ServiceDeleteInput createRendererRequestInput(String serviceName,
156             ServiceHandlerHeader serviceHandlerHeader) {
157         LOG.info("Mapping ServiceDeleteInput or TempServiceDelete to Renderer requests");
158         return new ServiceDeleteInputBuilder().setServiceHandlerHeader(serviceHandlerHeader).setServiceName(serviceName)
159                 .build();
160     }
161
162     private static ServiceDeleteOutput returnRendererFailed() {
163         ConfigurationResponseCommon configurationResponseCommon = new ConfigurationResponseCommonBuilder()
164                 .setAckFinalIndicator(ResponseCodes.FINAL_ACK_YES).setResponseCode(ResponseCodes.RESPONSE_FAILED)
165                 .setResponseMessage("Renderer service delete failed !").build();
166         return new ServiceDeleteOutputBuilder().setConfigurationResponseCommon(configurationResponseCommon).build();
167     }
168
169     private Boolean validateParams(String serviceName, ServiceHandlerHeader serviceHandlerHeader, boolean temp) {
170         boolean result = true;
171         if (!checkString(serviceName)) {
172             result = false;
173             LOG.error("Service Name (common-id for Temp service) is not set");
174         } else if (!temp && (serviceHandlerHeader == null)) {
175             LOG.error("Service serviceHandlerHeader 'request-id' is not set");
176             result = false;
177         }
178         return result;
179     }
180
181     private static boolean checkString(String value) {
182         return ((value != null) && (value.compareTo("") != 0));
183     }
184
185     private final class ServiceDeleteOutputFutureCallback implements FutureCallback<ServiceDeleteOutput> {
186         private final ServiceNotificationTypes notifType;
187         private final String serviceName;
188         String message = "";
189         ServiceRpcResultSh notification = null;
190
191         private ServiceDeleteOutputFutureCallback(ServiceNotificationTypes notifType, String serviceName) {
192             this.notifType = notifType;
193             this.serviceName = serviceName;
194         }
195
196         @Override
197         public void onSuccess(ServiceDeleteOutput response) {
198             if (response != null) {
199                 /**
200                  * If PCE reply is received before timer expiration with a positive result, a
201                  * service is created with admin and operational status 'down'.
202                  */
203                 message = "Renderer replied to service delete Request !";
204                 LOG.info("Renderer replied to service delete Request : {}", response);
205                 notification = new ServiceRpcResultShBuilder().setNotificationType(notifType)
206                         .setServiceName(serviceName).setStatus(RpcStatusEx.Successful).setStatusMessage(message)
207                         .build();
208                 sendNotifications(notification);
209             } else {
210                 message = "Renderer service delete failed ";
211                 notification = new ServiceRpcResultShBuilder().setNotificationType(notifType).setServiceName("")
212                         .setStatus(RpcStatusEx.Failed).setStatusMessage(message).build();
213                 sendNotifications(notification);
214             }
215         }
216
217         @Override
218         public void onFailure(Throwable arg0) {
219             LOG.error("Renderer service delete failed !");
220             notification = new ServiceRpcResultShBuilder().setNotificationType(notifType).setServiceName(serviceName)
221                     .setStatus(RpcStatusEx.Failed)
222                     .setStatusMessage("Renderer service delete request failed  : " + arg0.getMessage()).build();
223             sendNotifications(notification);
224         }
225     }
226 }
227