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