Service-notification handling for serviceHandler
[transportpce.git] / servicehandler / src / main / java / org / opendaylight / transportpce / servicehandler / stub / StubRendererServiceOperations.java
1 /*
2  * Copyright © 2018 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.stub;
9
10 import com.google.common.base.Optional;
11 import com.google.common.util.concurrent.ListenableFuture;
12 import com.google.common.util.concurrent.ListeningExecutorService;
13 import com.google.common.util.concurrent.MoreExecutors;
14
15 import java.util.concurrent.Callable;
16 import java.util.concurrent.ExecutionException;
17 import java.util.concurrent.Executors;
18 import java.util.concurrent.TimeUnit;
19 import java.util.concurrent.TimeoutException;
20
21 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
22 import org.opendaylight.controller.md.sal.binding.api.NotificationPublishService;
23 import org.opendaylight.controller.md.sal.binding.api.ReadOnlyTransaction;
24 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
25 import org.opendaylight.transportpce.common.ResponseCodes;
26 import org.opendaylight.transportpce.common.Timeouts;
27 import org.opendaylight.transportpce.renderer.NetworkModelWavelengthService;
28 import org.opendaylight.transportpce.renderer.provisiondevice.RendererServiceOperations;
29 import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.renderer.rev171017.ServiceDeleteInput;
30 import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.renderer.rev171017.ServiceDeleteOutput;
31 import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.renderer.rev171017.ServiceDeleteOutputBuilder;
32 import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.renderer.rev171017.ServiceImplementationRequestInput;
33 import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.renderer.rev171017.ServiceImplementationRequestOutput;
34 import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.renderer.rev171017.ServiceImplementationRequestOutputBuilder;
35 import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.renderer.rev171017.ServiceRpcResultSp;
36 import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.renderer.rev171017.ServiceRpcResultSpBuilder;
37 import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.renderer.rev171017.service.rpc.result.sp.PathTopology;
38 import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.renderer.rev171017.service.rpc.result.sp.PathTopologyBuilder;
39 import org.opendaylight.yang.gen.v1.http.org.openroadm.common.service.types.rev161014.configuration.response.common.ConfigurationResponseCommonBuilder;
40 import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.service.types.rev171016.RpcStatusEx;
41 import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.service.types.rev171016.ServicePathNotificationTypes;
42 import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.service.types.rev171016.service.path.PathDescription;
43 import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.servicepath.rev171017.ServicePathList;
44 import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.servicepath.rev171017.service.path.list.ServicePaths;
45 import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.servicepath.rev171017.service.path.list.ServicePathsKey;
46 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
47 import org.opendaylight.yangtools.yang.binding.Notification;
48 import org.slf4j.Logger;
49 import org.slf4j.LoggerFactory;
50
51 public class StubRendererServiceOperations implements RendererServiceOperations {
52     private static final Logger LOG = LoggerFactory.getLogger(StubRendererServiceOperations.class);
53     private final ListeningExecutorService executor;
54     private final NotificationPublishService notificationPublishService;
55     private final NetworkModelWavelengthService networkModelWavelengthService;
56     private final DataBroker dataBroker;
57     private Boolean rendererFailed;
58     private Boolean isnetworkModelWlService;
59
60     public StubRendererServiceOperations(NetworkModelWavelengthService networkModelWavelengthService,
61             DataBroker dataBroker, NotificationPublishService notificationPublishService) {
62         this.notificationPublishService = notificationPublishService;
63         this.networkModelWavelengthService = networkModelWavelengthService;
64         this.dataBroker = dataBroker;
65         this.rendererFailed = false;
66         this.isnetworkModelWlService = true;
67         executor = MoreExecutors.listeningDecorator(Executors.newFixedThreadPool(2));
68     }
69
70     private void sendNotifications(Notification notif) {
71         try {
72             LOG.info("putting notification : {}", notif);
73             notificationPublishService.putNotification(notif);
74         } catch (InterruptedException e) {
75             LOG.info("notification offer rejected : ", e.getMessage());
76         }
77     }
78
79     @Override
80     public ListenableFuture<ServiceImplementationRequestOutput>
81             serviceImplementation(ServiceImplementationRequestInput input) {
82         return executor.submit(new Callable<ServiceImplementationRequestOutput>() {
83             @Override
84             public ServiceImplementationRequestOutput call() {
85                 LOG.info("serviceImplementation request ...");
86                 String serviceName = input.getServiceName();
87                 RpcStatusEx rpcStatusEx = RpcStatusEx.Pending;
88                 ServiceRpcResultSp notification = new ServiceRpcResultSpBuilder()
89                         .setNotificationType(ServicePathNotificationTypes.ServiceImplementationRequest)
90                         .setServiceName(serviceName).setStatus(rpcStatusEx)
91                         .setStatusMessage("Service compliant, submitting serviceImplementation Request ...").build();
92                 sendNotifications(notification);
93                 String message = "";
94                 String responseCode = null;
95                 ConfigurationResponseCommonBuilder configurationResponseCommon = null;
96                 ServiceImplementationRequestOutput output = null;
97                 try {
98                     LOG.info("Wait for 5s til beginning the Renderer serviceImplementation request");
99                     Thread.sleep(5000); // sleep for 1s
100                 } catch (InterruptedException e) {
101                     message = "renderer failed !";
102                     rpcStatusEx = RpcStatusEx.Failed;
103                     responseCode = ResponseCodes.RESPONSE_FAILED;
104                     LOG.error(message);
105                     notification = new ServiceRpcResultSpBuilder()
106                             .setNotificationType(ServicePathNotificationTypes.ServiceImplementationRequest)
107                             .setServiceName(serviceName).setStatus(rpcStatusEx).setStatusMessage(message).build();
108                     sendNotifications(notification);
109                     configurationResponseCommon =
110                             new ConfigurationResponseCommonBuilder().setAckFinalIndicator(ResponseCodes.FINAL_ACK_YES)
111                                     .setRequestId(input.getServiceHandlerHeader().getRequestId())
112                                     .setResponseCode(responseCode).setResponseMessage(message);
113                     output = new ServiceImplementationRequestOutputBuilder()
114                             .setConfigurationResponseCommon(configurationResponseCommon.build()).build();
115                     return output;
116                 }
117                 if (rendererFailed) {
118                     LOG.info("forcing renderer to fail");
119                     message = "renderer failed !";
120                     rpcStatusEx = RpcStatusEx.Failed;
121                     LOG.error(message);
122                     responseCode = ResponseCodes.RESPONSE_FAILED;
123                 } else {
124                     if (isnetworkModelWlService) {
125                         networkModelWavelengthService.useWavelengths(input.getPathDescription());
126                     } else {
127                         LOG.warn("No need to execute networkModelWavelengthService...");
128                     }
129                     message = "service implemented !";
130                     rpcStatusEx = RpcStatusEx.Successful;
131                     LOG.info(message);
132                     responseCode = ResponseCodes.RESPONSE_OK;
133                 }
134                 PathTopology pathTopology = new PathTopologyBuilder().build();
135                 notification = new ServiceRpcResultSpBuilder()
136                         .setNotificationType(ServicePathNotificationTypes.ServiceImplementationRequest)
137                         .setServiceName(serviceName).setStatus(rpcStatusEx)
138                         .setStatusMessage(message).setPathTopology(pathTopology).build();
139                 sendNotifications(notification);
140                 responseCode = ResponseCodes.RESPONSE_OK;
141                 configurationResponseCommon = new ConfigurationResponseCommonBuilder()
142                         .setAckFinalIndicator(ResponseCodes.FINAL_ACK_YES)
143                         .setRequestId(input.getServiceHandlerHeader().getRequestId())
144                         .setResponseCode(responseCode)
145                         .setResponseMessage(message);
146                 output = new ServiceImplementationRequestOutputBuilder()
147                         .setConfigurationResponseCommon(configurationResponseCommon.build())
148                         .build();
149                 return output;
150             }
151         });
152     }
153
154     @Override
155     public ListenableFuture<ServiceDeleteOutput> serviceDelete(ServiceDeleteInput input) {
156         return executor.submit(new Callable<ServiceDeleteOutput>() {
157             @Override
158             public ServiceDeleteOutput call() {
159                 LOG.info("ServiceDelete request ...");
160                 String serviceName = input.getServiceName();
161                 RpcStatusEx rpcStatusEx = RpcStatusEx.Pending;
162                 ServiceRpcResultSp notification =
163                         new ServiceRpcResultSpBuilder().setNotificationType(ServicePathNotificationTypes.ServiceDelete)
164                                 .setServiceName(serviceName).setStatus(rpcStatusEx)
165                         .setStatusMessage("Service compliant, submitting serviceDelete Request ...").build();
166                 sendNotifications(notification);
167                 String message = "";
168                 String responseCode = null;
169                 ConfigurationResponseCommonBuilder configurationResponseCommon = null;
170                 ServiceDeleteOutput output = null;
171                 try {
172                     LOG.info("Wait for 5s til beginning the Renderer serviceDelete request");
173                     Thread.sleep(5000); // sleep for 1s
174                 } catch (InterruptedException e) {
175                     message = "deleting service failed !";
176                     LOG.error("deleting service failed !", e);
177                     responseCode = ResponseCodes.RESPONSE_FAILED;
178                     rpcStatusEx = RpcStatusEx.Failed;
179                     notification = new ServiceRpcResultSpBuilder()
180                             .setNotificationType(ServicePathNotificationTypes.ServiceDelete).setServiceName(serviceName)
181                             .setStatus(rpcStatusEx).setStatusMessage(message).build();
182                     sendNotifications(notification);
183                     configurationResponseCommon =
184                             new ConfigurationResponseCommonBuilder().setAckFinalIndicator(ResponseCodes.FINAL_ACK_YES)
185                                     .setRequestId(input.getServiceHandlerHeader().getRequestId())
186                                     .setResponseCode(responseCode).setResponseMessage(message);
187                     output = new ServiceDeleteOutputBuilder()
188                             .setConfigurationResponseCommon(configurationResponseCommon.build()).build();
189                 }
190                 if (rendererFailed) {
191                     LOG.info("forcing renderer to fail");
192                     message = "renderer failed !";
193                     rpcStatusEx = RpcStatusEx.Failed;
194                     LOG.error(message);
195                     responseCode = ResponseCodes.RESPONSE_FAILED;
196                 } else {
197                     if (isnetworkModelWlService) {
198                         // Obtain path description
199                         Optional<PathDescription> pathDescriptionOpt = getPathDescriptionFromDatastore(serviceName);
200                         PathDescription pathDescription;
201                         if (pathDescriptionOpt.isPresent()) {
202                             pathDescription = pathDescriptionOpt.get();
203                             networkModelWavelengthService.freeWavelengths(pathDescription);
204                         } else {
205                             LOG.warn("failed to get pathDescription for service : {}", serviceName);
206                         }
207                     } else {
208                         LOG.warn("No need to execute networkModelWavelengthService...");
209                     }
210                     message = "service deleted !";
211                     rpcStatusEx = RpcStatusEx.Successful;
212                     LOG.info(message);
213                     responseCode = ResponseCodes.RESPONSE_OK;
214                 }
215                 notification = new ServiceRpcResultSpBuilder()
216                         .setNotificationType(ServicePathNotificationTypes.ServiceDelete)
217                         .setServiceName(serviceName).setStatus(rpcStatusEx)
218                         .setStatusMessage(message).build();
219                 sendNotifications(notification);
220                 responseCode = ResponseCodes.RESPONSE_OK;
221                 configurationResponseCommon = new ConfigurationResponseCommonBuilder()
222                         .setAckFinalIndicator(ResponseCodes.FINAL_ACK_YES)
223                         .setRequestId(input.getServiceHandlerHeader().getRequestId())
224                         .setResponseCode(responseCode)
225                         .setResponseMessage(message);
226                 output = new ServiceDeleteOutputBuilder()
227                         .setConfigurationResponseCommon(configurationResponseCommon.build())
228                         .build();
229                 return output;
230             }
231         });
232     }
233
234     private Optional<PathDescription> getPathDescriptionFromDatastore(String serviceName) {
235         InstanceIdentifier<PathDescription> pathDescriptionIID = InstanceIdentifier.create(ServicePathList.class)
236                 .child(ServicePaths.class, new ServicePathsKey(serviceName)).child(PathDescription.class);
237         ReadOnlyTransaction pathDescReadTx = this.dataBroker.newReadOnlyTransaction();
238         try {
239             LOG.debug("Getting path description for service {}", serviceName);
240             return pathDescReadTx.read(LogicalDatastoreType.OPERATIONAL, pathDescriptionIID)
241                     .get(Timeouts.DATASTORE_READ, TimeUnit.MILLISECONDS);
242         } catch (InterruptedException | ExecutionException | TimeoutException e) {
243             LOG.warn("Exception while getting path description from datastore {} for service {}!", pathDescriptionIID,
244                     serviceName, e);
245             return Optional.absent();
246         }
247     }
248
249     public void setRendererFailed(Boolean rendererFailed) {
250         this.rendererFailed = rendererFailed;
251     }
252
253     public void setIsnetworkModelWlService(Boolean isnetworkModelWlService) {
254         this.isnetworkModelWlService = isnetworkModelWlService;
255     }
256 }