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