Technical debt - Service handler Sonar issues
[transportpce.git] / servicehandler / src / main / java / org / opendaylight / transportpce / servicehandler / service / ServiceDataStoreOperationsImpl.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.FluentFuture;
11 import java.util.Optional;
12 import java.util.concurrent.ExecutionException;
13 import java.util.concurrent.Future;
14 import java.util.concurrent.TimeUnit;
15 import java.util.concurrent.TimeoutException;
16 import org.eclipse.jdt.annotation.NonNull;
17 import org.opendaylight.mdsal.binding.api.DataBroker;
18 import org.opendaylight.mdsal.binding.api.ReadTransaction;
19 import org.opendaylight.mdsal.binding.api.WriteTransaction;
20 import org.opendaylight.mdsal.common.api.CommitInfo;
21 import org.opendaylight.mdsal.common.api.LogicalDatastoreType;
22 import org.opendaylight.transportpce.common.OperationResult;
23 import org.opendaylight.transportpce.common.Timeouts;
24 import org.opendaylight.transportpce.servicehandler.ModelMappingUtils;
25 import org.opendaylight.transportpce.servicehandler.ServiceInput;
26 import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.pce.rev200128.PathComputationRequestOutput;
27 import org.opendaylight.yang.gen.v1.http.org.openroadm.common.state.types.rev181130.State;
28 import org.opendaylight.yang.gen.v1.http.org.openroadm.equipment.states.types.rev181130.AdminStates;
29 import org.opendaylight.yang.gen.v1.http.org.openroadm.service.rev190531.ServiceCreateInput;
30 import org.opendaylight.yang.gen.v1.http.org.openroadm.service.rev190531.ServiceList;
31 import org.opendaylight.yang.gen.v1.http.org.openroadm.service.rev190531.ServiceListBuilder;
32 import org.opendaylight.yang.gen.v1.http.org.openroadm.service.rev190531.TempServiceCreateInput;
33 import org.opendaylight.yang.gen.v1.http.org.openroadm.service.rev190531.TempServiceList;
34 import org.opendaylight.yang.gen.v1.http.org.openroadm.service.rev190531.TempServiceListBuilder;
35 import org.opendaylight.yang.gen.v1.http.org.openroadm.service.rev190531.service.list.Services;
36 import org.opendaylight.yang.gen.v1.http.org.openroadm.service.rev190531.service.list.ServicesBuilder;
37 import org.opendaylight.yang.gen.v1.http.org.openroadm.service.rev190531.service.list.ServicesKey;
38 import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.servicepath.rev171017.ServicePathList;
39 import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.servicepath.rev171017.service.path.list.ServicePaths;
40 import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.servicepath.rev171017.service.path.list.ServicePathsKey;
41 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
42 import org.slf4j.Logger;
43 import org.slf4j.LoggerFactory;
44
45 public class ServiceDataStoreOperationsImpl implements ServiceDataStoreOperations {
46     private static final Logger LOG = LoggerFactory.getLogger(ServiceDataStoreOperationsImpl.class);
47     private static final String CREATE_MSG = "create";
48     private static final String DELETING_SERVICE_MSG = "Deleting '{}' Service";
49     private DataBroker dataBroker;
50
51     // This is class is public so that these messages can be accessed from Junit (avoid duplications).
52     public static final class LogMessages {
53
54         public static final String SUCCESSFUL_MESSAGE;
55         public static final String SERVICE_NOT_FOUND;
56
57         // Static blocks are generated once and spare memory.
58         static {
59             SUCCESSFUL_MESSAGE = "Successful";
60             SERVICE_NOT_FOUND = "Service not found";
61         }
62
63         public static String failedTo(String action, String serviceName) {
64             return  "Failed to " + action + " service " + serviceName;
65         }
66
67         private LogMessages() {
68         }
69     }
70
71
72     public ServiceDataStoreOperationsImpl(DataBroker dataBroker) {
73         this.dataBroker = dataBroker;
74     }
75
76     @Override
77     public void initialize() {
78         initializeServiceList();
79         initializeTempServiceList();
80     }
81
82     private void initializeServiceList() {
83         try {
84             LOG.info("initializing service registry");
85             WriteTransaction transaction = this.dataBroker.newWriteOnlyTransaction();
86             InstanceIdentifier<ServiceList> iid = InstanceIdentifier.create(ServiceList.class);
87             ServiceList initialRegistry = new ServiceListBuilder().build();
88             transaction.put(LogicalDatastoreType.OPERATIONAL, iid, initialRegistry);
89             FluentFuture<? extends @NonNull CommitInfo> future = transaction.commit();
90             future.get(Timeouts.DATASTORE_WRITE, TimeUnit.MILLISECONDS);
91         } catch (InterruptedException | ExecutionException | TimeoutException e) {
92             LOG.error("init failed: ", e);
93         }
94     }
95
96     private void initializeTempServiceList() {
97         try {
98             LOG.info("initializing temp service registry");
99             WriteTransaction transaction = this.dataBroker.newWriteOnlyTransaction();
100             InstanceIdentifier<TempServiceList> iid = InstanceIdentifier.create(TempServiceList.class);
101             TempServiceList initialRegistry = new TempServiceListBuilder().build();
102             transaction.put(LogicalDatastoreType.OPERATIONAL, iid, initialRegistry);
103             FluentFuture<? extends @NonNull CommitInfo> future = transaction.commit();
104             future.get(Timeouts.DATASTORE_WRITE, TimeUnit.MILLISECONDS);
105         } catch (InterruptedException | ExecutionException | TimeoutException e) {
106             LOG.error("init failed: ", e);
107         }
108     }
109
110     @Override
111     public Optional<Services> getService(String serviceName) {
112         try {
113             ReadTransaction readTx = this.dataBroker.newReadOnlyTransaction();
114             InstanceIdentifier<Services> iid =
115                     InstanceIdentifier.create(ServiceList.class).child(Services.class, new ServicesKey(serviceName));
116             Future<java.util.Optional<Services>> future =
117                     readTx.read(LogicalDatastoreType.OPERATIONAL, iid);
118             return future.get(Timeouts.DATASTORE_READ, TimeUnit.MILLISECONDS);
119         } catch (InterruptedException | ExecutionException | TimeoutException e) {
120             LOG.warn("Reading service {} failed:", serviceName, e);
121         }
122         return Optional.empty();
123     }
124
125     @Override
126     public Optional<org.opendaylight.yang.gen.v1.http.org.openroadm.service.rev190531.temp.service.list
127         .Services> getTempService(String serviceName) {
128         try {
129             ReadTransaction readTx = this.dataBroker.newReadOnlyTransaction();
130             InstanceIdentifier<org.opendaylight.yang.gen.v1.http.org.openroadm.service.rev190531.temp.service.list
131                 .Services> iid = InstanceIdentifier.create(TempServiceList.class).child(org.opendaylight.yang.gen.v1
132                         .http.org.openroadm.service.rev190531.temp.service.list.Services.class,
133                         new org.opendaylight.yang.gen.v1.http.org.openroadm.service.rev190531.temp.service.list
134                             .ServicesKey(serviceName));
135             Future<java.util.Optional<org.opendaylight.yang.gen.v1.http.org.openroadm.service.rev190531
136                 .temp.service.list.Services>> future =  readTx.read(LogicalDatastoreType.OPERATIONAL, iid);
137             return future.get(Timeouts.DATASTORE_READ, TimeUnit.MILLISECONDS);
138         } catch (InterruptedException | ExecutionException | TimeoutException e) {
139             LOG.warn("Reading service {} failed:", serviceName, e);
140         }
141         return Optional.empty();
142     }
143
144     @Override
145     public OperationResult deleteService(String serviceName) {
146         LOG.debug(DELETING_SERVICE_MSG, serviceName);
147         try {
148             WriteTransaction writeTx = this.dataBroker.newWriteOnlyTransaction();
149             InstanceIdentifier<Services> iid =
150                     InstanceIdentifier.create(ServiceList.class).child(Services.class, new ServicesKey(serviceName));
151             writeTx.delete(LogicalDatastoreType.OPERATIONAL, iid);
152             writeTx.commit().get(Timeouts.DATASTORE_DELETE, TimeUnit.MILLISECONDS);
153             return OperationResult.ok(LogMessages.SUCCESSFUL_MESSAGE);
154         } catch (TimeoutException | InterruptedException | ExecutionException e) {
155             LOG.warn("deleteService : {}", LogMessages.failedTo("delete", serviceName), e);
156             return OperationResult.failed(LogMessages.failedTo("delete", serviceName));
157         }
158     }
159
160     @Override
161     public OperationResult deleteTempService(String commonId) {
162         LOG.debug(DELETING_SERVICE_MSG, commonId);
163         try {
164             WriteTransaction writeTx = this.dataBroker.newWriteOnlyTransaction();
165             InstanceIdentifier<org.opendaylight.yang.gen.v1.http.org.openroadm.service.rev190531.temp.service.list
166                 .Services> iid = InstanceIdentifier.create(TempServiceList.class).child(org.opendaylight.yang.gen.v1
167                         .http.org.openroadm.service.rev190531.temp.service.list.Services.class,
168                         new org.opendaylight.yang.gen.v1.http.org.openroadm.service.rev190531.temp.service.list
169                             .ServicesKey(commonId));
170             writeTx.delete(LogicalDatastoreType.OPERATIONAL, iid);
171             writeTx.commit().get(Timeouts.DATASTORE_DELETE, TimeUnit.MILLISECONDS);
172             return OperationResult.ok(LogMessages.SUCCESSFUL_MESSAGE);
173         } catch (TimeoutException | InterruptedException | ExecutionException e) {
174             LOG.warn("deleteTempService : {}", LogMessages.failedTo("delete Temp", commonId), e);
175             return OperationResult.failed(LogMessages.failedTo("delete Temp", commonId));
176         }
177     }
178
179     @Override
180     public OperationResult modifyService(String serviceName, State operationalState, AdminStates administrativeState) {
181         LOG.debug("Modifying '{}' Service", serviceName);
182         Optional<Services> readService = getService(serviceName);
183         if (!readService.isPresent()) {
184             LOG.warn("modifyService: {}", LogMessages.SERVICE_NOT_FOUND);
185             return OperationResult.failed(LogMessages.SERVICE_NOT_FOUND);
186         }
187         try {
188             WriteTransaction writeTx = this.dataBroker.newWriteOnlyTransaction();
189             InstanceIdentifier<Services> iid = InstanceIdentifier.create(ServiceList.class)
190                     .child(Services.class, new ServicesKey(serviceName));
191             Services services = new ServicesBuilder(readService.get()).setOperationalState(operationalState)
192                     .setAdministrativeState(administrativeState)
193                     .build();
194             writeTx.merge(LogicalDatastoreType.OPERATIONAL, iid, services);
195             writeTx.commit().get(Timeouts.DATASTORE_WRITE, TimeUnit.MILLISECONDS);
196             return OperationResult.ok(LogMessages.SUCCESSFUL_MESSAGE);
197         } catch (TimeoutException | InterruptedException | ExecutionException e) {
198             LOG.warn("modifyService : {}", LogMessages.failedTo("modify", serviceName), e);
199             return OperationResult.failed(LogMessages.failedTo("modify", serviceName));
200         }
201     }
202
203     @Override
204     public OperationResult modifyTempService(String serviceName, State operationalState,
205         AdminStates administrativeState) {
206         LOG.debug("Modifying '{}' Temp Service", serviceName);
207         Optional<org.opendaylight.yang.gen.v1.http.org.openroadm.service.rev190531.temp.service.list
208             .Services> readService = getTempService(serviceName);
209         if (!readService.isPresent()) {
210             LOG.warn("modifyTempService: {}", LogMessages.SERVICE_NOT_FOUND);
211             return OperationResult.failed(LogMessages.SERVICE_NOT_FOUND);
212         }
213         try {
214             WriteTransaction writeTx = this.dataBroker.newWriteOnlyTransaction();
215             InstanceIdentifier<org.opendaylight.yang.gen.v1.http.org.openroadm.service.rev190531.temp.service.list
216                 .Services> iid = InstanceIdentifier.create(TempServiceList.class)
217                     .child(org.opendaylight.yang.gen.v1.http.org.openroadm.service.rev190531.temp.service.list
218                             .Services.class, new org.opendaylight.yang.gen.v1.http.org.openroadm.service.rev190531
219                                 .temp.service.list.ServicesKey(serviceName));
220             org.opendaylight.yang.gen.v1.http.org.openroadm.service.rev190531.temp.service.list
221                 .Services services = new org.opendaylight.yang.gen.v1.http.org.openroadm.service.rev190531.temp
222                     .service.list.ServicesBuilder(readService.get()).setOperationalState(operationalState)
223                         .setAdministrativeState(administrativeState)
224                         .build();
225             writeTx.merge(LogicalDatastoreType.OPERATIONAL, iid, services);
226             writeTx.commit().get(Timeouts.DATASTORE_WRITE, TimeUnit.MILLISECONDS);
227             return OperationResult.ok(LogMessages.SUCCESSFUL_MESSAGE);
228         } catch (TimeoutException | InterruptedException | ExecutionException e) {
229             LOG.warn("modifyTempService : {}", LogMessages.failedTo("modify Temp", serviceName), e);
230             return OperationResult.failed(LogMessages.failedTo("modify Temp", serviceName));
231         }
232     }
233
234     @Override
235     public OperationResult createService(ServiceCreateInput serviceCreateInput) {
236         LOG.debug("Writing '{}' Service", serviceCreateInput.getServiceName());
237         try {
238             InstanceIdentifier<Services> iid = InstanceIdentifier.create(ServiceList.class)
239                     .child(Services.class, new ServicesKey(serviceCreateInput.getServiceName()));
240             Services service = ModelMappingUtils.mappingServices(serviceCreateInput, null);
241             WriteTransaction writeTx = this.dataBroker.newWriteOnlyTransaction();
242             writeTx.put(LogicalDatastoreType.OPERATIONAL, iid, service);
243             writeTx.commit().get(Timeouts.DATASTORE_WRITE, TimeUnit.MILLISECONDS);
244             return OperationResult.ok(LogMessages.SUCCESSFUL_MESSAGE);
245         } catch (TimeoutException | InterruptedException | ExecutionException e) {
246             LOG.warn("createService : {}", LogMessages.failedTo(CREATE_MSG, serviceCreateInput.getServiceName()), e);
247             return OperationResult.failed(LogMessages.failedTo(CREATE_MSG, serviceCreateInput.getServiceName()));
248         }
249     }
250
251     @Override
252     public OperationResult createTempService(TempServiceCreateInput tempServiceCreateInput) {
253         LOG.debug("Writing '{}' Temp Service", tempServiceCreateInput.getCommonId());
254         try {
255             InstanceIdentifier<org.opendaylight.yang.gen.v1.http.org.openroadm.service.rev190531.temp.service.list
256                 .Services> iid = InstanceIdentifier.create(TempServiceList.class)
257                     .child(org.opendaylight.yang.gen.v1.http.org.openroadm.service.rev190531.temp.service.list
258                             .Services.class, new org.opendaylight.yang.gen.v1.http.org.openroadm.service.rev190531.temp
259                                 .service.list.ServicesKey(tempServiceCreateInput.getCommonId()));
260             org.opendaylight.yang.gen.v1.http.org.openroadm.service.rev190531.temp.service.list
261                 .Services service = ModelMappingUtils.mappingServices(tempServiceCreateInput);
262             WriteTransaction writeTx = this.dataBroker.newWriteOnlyTransaction();
263             writeTx.put(LogicalDatastoreType.OPERATIONAL, iid, service);
264             writeTx.commit().get(Timeouts.DATASTORE_WRITE, TimeUnit.MILLISECONDS);
265             return OperationResult.ok(LogMessages.SUCCESSFUL_MESSAGE);
266         } catch (TimeoutException | InterruptedException | ExecutionException e) {
267             LOG.warn("createTempService : {}",
268                     LogMessages.failedTo("create Temp", tempServiceCreateInput.getCommonId()), e);
269             return OperationResult.failed(LogMessages.failedTo("create Temp", tempServiceCreateInput.getCommonId()));
270         }
271     }
272
273     @Override
274     public OperationResult createServicePath(ServiceInput serviceInput, PathComputationRequestOutput outputFromPce) {
275         LOG.debug("Writing '{}' ServicePath ", serviceInput.getServiceName());
276         try {
277             InstanceIdentifier<ServicePaths> servicePathsIID = InstanceIdentifier.create(ServicePathList.class)
278                     .child(ServicePaths.class, new ServicePathsKey(serviceInput.getServiceName()));
279             ServicePaths servicePath = ModelMappingUtils.mappingServicePaths(serviceInput, outputFromPce);
280             WriteTransaction writeTx = this.dataBroker.newWriteOnlyTransaction();
281             writeTx.put(LogicalDatastoreType.OPERATIONAL, servicePathsIID, servicePath);
282             writeTx.commit().get(Timeouts.DATASTORE_WRITE, TimeUnit.MILLISECONDS);
283             return OperationResult.ok(LogMessages.SUCCESSFUL_MESSAGE);
284         } catch (TimeoutException | InterruptedException | ExecutionException e) {
285             LOG.warn("createServicePath : {}",
286                     LogMessages.failedTo("create servicePath", serviceInput.getCommonId()), e);
287             return OperationResult.failed(LogMessages.failedTo("create servicePath", serviceInput.getCommonId()));
288         }
289     }
290
291     @Override
292     public OperationResult deleteServicePath(String serviceName) {
293         InstanceIdentifier<ServicePaths> servicePathsIID = InstanceIdentifier.create(ServicePathList.class)
294                 .child(ServicePaths.class, new ServicePathsKey(serviceName));
295         LOG.debug("Deleting service from {}", servicePathsIID);
296         WriteTransaction servicePathsWriteTx = this.dataBroker.newWriteOnlyTransaction();
297         servicePathsWriteTx.delete(LogicalDatastoreType.OPERATIONAL, servicePathsIID);
298         try {
299             servicePathsWriteTx.commit().get(Timeouts.DATASTORE_DELETE, TimeUnit.MILLISECONDS);
300             return OperationResult.ok(LogMessages.SUCCESSFUL_MESSAGE);
301         } catch (InterruptedException | ExecutionException | TimeoutException e) {
302             LOG.error("deleteServicePath : {}", LogMessages.failedTo("delete servicePath", serviceName), e);
303             return OperationResult.failed(LogMessages.failedTo("delete servicePath", serviceName));
304         }
305     }
306
307     /*
308      * Write or Modify or Delete Service from/to SreviceList.
309      *
310      * @param serviceName Name of service
311      *
312      * @param input ServiceCreateInput
313      *
314      * @param output PathComputationRequestOutput
315      *
316      * @param choice 0 - Modify 1 - Delete 2 - Write
317      *
318      * @return String operations result, null if ok or not otherwise
319      */
320     @Deprecated
321     @Override
322     public String writeOrModifyOrDeleteServiceList(String serviceName, ServiceCreateInput input,
323             PathComputationRequestOutput output, int choice) {
324         LOG.debug("WriteOrModifyOrDeleting '{}' Service", serviceName);
325         WriteTransaction writeTx = this.dataBroker.newWriteOnlyTransaction();
326         Optional<Services> readService = getService(serviceName);
327
328         /*
329          * Write Service.
330          */
331         if (!readService.isPresent()) {
332             if (choice != 2) {
333                 LOG.warn("writeOrModifyOrDeleteServiceList: {}", LogMessages.SERVICE_NOT_FOUND);
334                 return LogMessages.SERVICE_NOT_FOUND;
335             }
336
337             LOG.debug("Writing '{}' Service", serviceName);
338             InstanceIdentifier<Services> iid = InstanceIdentifier.create(ServiceList.class)
339                     .child(Services.class, new ServicesKey(serviceName));
340             Services service = ModelMappingUtils.mappingServices(input, null);
341             writeTx.put(LogicalDatastoreType.OPERATIONAL, iid, service);
342             try {
343                 writeTx.commit().get(Timeouts.DATASTORE_WRITE, TimeUnit.MILLISECONDS);
344                 return null;
345             } catch (InterruptedException | TimeoutException | ExecutionException e) {
346                 LOG.error("writeOrModifyOrDeleteServiceList : {}", LogMessages.failedTo(CREATE_MSG, serviceName), e);
347                 return LogMessages.failedTo(CREATE_MSG, serviceName);
348             }
349         }
350
351         /*
352          * Modify / Delete Service.
353          */
354         InstanceIdentifier<Services> iid =
355                 InstanceIdentifier.create(ServiceList.class).child(Services.class, new ServicesKey(serviceName));
356         ServicesBuilder service = new ServicesBuilder(readService.get());
357         String action = null;
358         switch (choice) {
359             case 0 : /* Modify. */
360                 LOG.debug("Modifying '{}' Service", serviceName);
361                 service.setOperationalState(State.InService).setAdministrativeState(AdminStates.InService);
362                 writeTx.merge(LogicalDatastoreType.OPERATIONAL, iid, service.build());
363                 action = "modifyService";
364                 break;
365             case 1 : /* Delete */
366                 LOG.debug(DELETING_SERVICE_MSG, serviceName);
367                 writeTx.delete(LogicalDatastoreType.OPERATIONAL, iid);
368                 action = "deleteService";
369                 break;
370             default:
371                 LOG.debug("No choice found");
372                 break;
373         }
374         try {
375             writeTx.commit().get(Timeouts.DATASTORE_WRITE, TimeUnit.MILLISECONDS);
376         } catch (InterruptedException | ExecutionException | TimeoutException e) {
377             LOG.error("writeOrModifyOrDeleteServiceList : {}", LogMessages.failedTo(action, serviceName), e);
378             return LogMessages.failedTo(action, serviceName);
379         }
380
381         return null;
382     }
383 }