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