Refactor network topologies listener of SH
[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.rev191129.State;
28 import org.opendaylight.yang.gen.v1.http.org.openroadm.equipment.states.types.rev191129.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.service.types.rev200128.service.path.PathDescription;
39 import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.servicepath.rev171017.ServicePathList;
40 import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.servicepath.rev171017.service.path.list.ServicePaths;
41 import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.servicepath.rev171017.service.path.list.ServicePathsBuilder;
42 import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.servicepath.rev171017.service.path.list.ServicePathsKey;
43 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
44 import org.slf4j.Logger;
45 import org.slf4j.LoggerFactory;
46
47 public class ServiceDataStoreOperationsImpl implements ServiceDataStoreOperations {
48     private static final Logger LOG = LoggerFactory.getLogger(ServiceDataStoreOperationsImpl.class);
49     private static final String CREATE_MSG = "create";
50     private static final String DELETING_SERVICE_MSG = "Deleting '{}' Service";
51     private DataBroker dataBroker;
52
53     // This is class is public so that these messages can be accessed from Junit (avoid duplications).
54     public static final class LogMessages {
55
56         public static final String SUCCESSFUL_MESSAGE;
57         public static final String SERVICE_NOT_FOUND;
58         public static final String SERVICE_PATH_NOT_FOUND;
59
60         // Static blocks are generated once and spare memory.
61         static {
62             SUCCESSFUL_MESSAGE = "Successful";
63             SERVICE_NOT_FOUND = "Service not found";
64             SERVICE_PATH_NOT_FOUND = "Service path not found";
65         }
66
67         public static String failedTo(String action, String serviceName) {
68             return  "Failed to " + action + " service " + serviceName;
69         }
70
71         private LogMessages() {
72         }
73     }
74
75
76     public ServiceDataStoreOperationsImpl(DataBroker dataBroker) {
77         this.dataBroker = dataBroker;
78     }
79
80     @Override
81     public void initialize() {
82         initializeServiceList();
83         initializeTempServiceList();
84     }
85
86     private void initializeServiceList() {
87         try {
88             LOG.info("initializing service registry");
89             WriteTransaction transaction = this.dataBroker.newWriteOnlyTransaction();
90             InstanceIdentifier<ServiceList> iid = InstanceIdentifier.create(ServiceList.class);
91             ServiceList initialRegistry = new ServiceListBuilder().build();
92             transaction.put(LogicalDatastoreType.OPERATIONAL, iid, initialRegistry);
93             FluentFuture<? extends @NonNull CommitInfo> future = transaction.commit();
94             future.get(Timeouts.DATASTORE_WRITE, TimeUnit.MILLISECONDS);
95         } catch (InterruptedException | ExecutionException | TimeoutException e) {
96             LOG.error("init failed: ", e);
97         }
98     }
99
100     private void initializeTempServiceList() {
101         try {
102             LOG.info("initializing temp service registry");
103             WriteTransaction transaction = this.dataBroker.newWriteOnlyTransaction();
104             InstanceIdentifier<TempServiceList> iid = InstanceIdentifier.create(TempServiceList.class);
105             TempServiceList initialRegistry = new TempServiceListBuilder().build();
106             transaction.put(LogicalDatastoreType.OPERATIONAL, iid, initialRegistry);
107             FluentFuture<? extends @NonNull CommitInfo> future = transaction.commit();
108             future.get(Timeouts.DATASTORE_WRITE, TimeUnit.MILLISECONDS);
109         } catch (InterruptedException | ExecutionException | TimeoutException e) {
110             LOG.error("init failed: ", e);
111         }
112     }
113
114     @Override
115     public Optional<Services> getService(String serviceName) {
116         try {
117             ReadTransaction readTx = this.dataBroker.newReadOnlyTransaction();
118             InstanceIdentifier<Services> iid =
119                     InstanceIdentifier.create(ServiceList.class).child(Services.class, new ServicesKey(serviceName));
120             Future<java.util.Optional<Services>> future =
121                     readTx.read(LogicalDatastoreType.OPERATIONAL, iid);
122             return future.get(Timeouts.DATASTORE_READ, TimeUnit.MILLISECONDS);
123         } catch (InterruptedException | ExecutionException | TimeoutException e) {
124             LOG.warn("Reading service {} failed:", serviceName, e);
125         }
126         return Optional.empty();
127     }
128
129     @Override
130     public Optional<org.opendaylight.yang.gen.v1.http.org.openroadm.service.rev190531.temp.service.list
131         .Services> getTempService(String serviceName) {
132         try {
133             ReadTransaction readTx = this.dataBroker.newReadOnlyTransaction();
134             InstanceIdentifier<org.opendaylight.yang.gen.v1.http.org.openroadm.service.rev190531.temp.service.list
135                 .Services> iid = InstanceIdentifier.create(TempServiceList.class).child(org.opendaylight.yang.gen.v1
136                         .http.org.openroadm.service.rev190531.temp.service.list.Services.class,
137                         new org.opendaylight.yang.gen.v1.http.org.openroadm.service.rev190531.temp.service.list
138                             .ServicesKey(serviceName));
139             Future<java.util.Optional<org.opendaylight.yang.gen.v1.http.org.openroadm.service.rev190531
140                 .temp.service.list.Services>> future =  readTx.read(LogicalDatastoreType.OPERATIONAL, iid);
141             return future.get(Timeouts.DATASTORE_READ, TimeUnit.MILLISECONDS);
142         } catch (InterruptedException | ExecutionException | TimeoutException e) {
143             LOG.warn("Reading service {} failed:", serviceName, e);
144         }
145         return Optional.empty();
146     }
147
148     @Override
149     public OperationResult deleteService(String serviceName) {
150         LOG.debug(DELETING_SERVICE_MSG, serviceName);
151         try {
152             WriteTransaction writeTx = this.dataBroker.newWriteOnlyTransaction();
153             InstanceIdentifier<Services> iid =
154                     InstanceIdentifier.create(ServiceList.class).child(Services.class, new ServicesKey(serviceName));
155             writeTx.delete(LogicalDatastoreType.OPERATIONAL, iid);
156             writeTx.commit().get(Timeouts.DATASTORE_DELETE, TimeUnit.MILLISECONDS);
157             return OperationResult.ok(LogMessages.SUCCESSFUL_MESSAGE);
158         } catch (TimeoutException | InterruptedException | ExecutionException e) {
159             LOG.warn("deleteService : {}", LogMessages.failedTo("delete", serviceName), e);
160             return OperationResult.failed(LogMessages.failedTo("delete", serviceName));
161         }
162     }
163
164     @Override
165     public OperationResult deleteTempService(String commonId) {
166         LOG.debug(DELETING_SERVICE_MSG, commonId);
167         try {
168             WriteTransaction writeTx = this.dataBroker.newWriteOnlyTransaction();
169             InstanceIdentifier<org.opendaylight.yang.gen.v1.http.org.openroadm.service.rev190531.temp.service.list
170                 .Services> iid = InstanceIdentifier.create(TempServiceList.class).child(org.opendaylight.yang.gen.v1
171                         .http.org.openroadm.service.rev190531.temp.service.list.Services.class,
172                         new org.opendaylight.yang.gen.v1.http.org.openroadm.service.rev190531.temp.service.list
173                             .ServicesKey(commonId));
174             writeTx.delete(LogicalDatastoreType.OPERATIONAL, iid);
175             writeTx.commit().get(Timeouts.DATASTORE_DELETE, TimeUnit.MILLISECONDS);
176             return OperationResult.ok(LogMessages.SUCCESSFUL_MESSAGE);
177         } catch (TimeoutException | InterruptedException | ExecutionException e) {
178             LOG.warn("deleteTempService : {}", LogMessages.failedTo("delete Temp", commonId), e);
179             return OperationResult.failed(LogMessages.failedTo("delete Temp", commonId));
180         }
181     }
182
183     @Override
184     public OperationResult modifyService(String serviceName, State operationalState, AdminStates administrativeState) {
185         LOG.debug("Modifying '{}' Service", serviceName);
186         Optional<Services> readService = getService(serviceName);
187         if (!readService.isPresent()) {
188             LOG.warn("modifyService: {}", LogMessages.SERVICE_NOT_FOUND);
189             return OperationResult.failed(LogMessages.SERVICE_NOT_FOUND);
190         }
191         try {
192             WriteTransaction writeTx = this.dataBroker.newWriteOnlyTransaction();
193             InstanceIdentifier<Services> iid = InstanceIdentifier.create(ServiceList.class)
194                     .child(Services.class, new ServicesKey(serviceName));
195             Services services = new ServicesBuilder(readService.get())
196                 .setOperationalState(convertOperState(operationalState))
197                 .setAdministrativeState(convertAdminState(administrativeState))
198                 .build();
199             writeTx.merge(LogicalDatastoreType.OPERATIONAL, iid, services);
200             writeTx.commit().get(Timeouts.DATASTORE_WRITE, TimeUnit.MILLISECONDS);
201             return OperationResult.ok(LogMessages.SUCCESSFUL_MESSAGE);
202         } catch (TimeoutException | InterruptedException | ExecutionException e) {
203             LOG.warn("modifyService : {}", LogMessages.failedTo("modify", serviceName), e);
204             return OperationResult.failed(LogMessages.failedTo("modify", serviceName));
205         }
206     }
207
208     @Override
209     public OperationResult modifyTempService(String serviceName, State operationalState,
210         AdminStates administrativeState) {
211         LOG.debug("Modifying '{}' Temp Service", serviceName);
212         Optional<org.opendaylight.yang.gen.v1.http.org.openroadm.service.rev190531.temp.service.list
213             .Services> readService = getTempService(serviceName);
214         if (!readService.isPresent()) {
215             LOG.warn("modifyTempService: {}", LogMessages.SERVICE_NOT_FOUND);
216             return OperationResult.failed(LogMessages.SERVICE_NOT_FOUND);
217         }
218         try {
219             WriteTransaction writeTx = this.dataBroker.newWriteOnlyTransaction();
220             InstanceIdentifier<org.opendaylight.yang.gen.v1.http.org.openroadm.service.rev190531.temp.service.list
221                 .Services> iid = InstanceIdentifier.create(TempServiceList.class)
222                     .child(org.opendaylight.yang.gen.v1.http.org.openroadm.service.rev190531.temp.service.list
223                             .Services.class, new org.opendaylight.yang.gen.v1.http.org.openroadm.service.rev190531
224                                 .temp.service.list.ServicesKey(serviceName));
225             org.opendaylight.yang.gen.v1.http.org.openroadm.service.rev190531.temp.service.list.Services services =
226                 new org.opendaylight.yang.gen.v1.http.org.openroadm.service.rev190531.temp.service.list.ServicesBuilder(
227                     readService.get())
228                 .setOperationalState(convertOperState(operationalState))
229                 .setAdministrativeState(convertAdminState(administrativeState))
230                 .build();
231             writeTx.merge(LogicalDatastoreType.OPERATIONAL, iid, services);
232             writeTx.commit().get(Timeouts.DATASTORE_WRITE, TimeUnit.MILLISECONDS);
233             return OperationResult.ok(LogMessages.SUCCESSFUL_MESSAGE);
234         } catch (TimeoutException | InterruptedException | ExecutionException e) {
235             LOG.warn("modifyTempService : {}", LogMessages.failedTo("modify Temp", serviceName), e);
236             return OperationResult.failed(LogMessages.failedTo("modify Temp", serviceName));
237         }
238     }
239
240     @Override
241     public OperationResult createService(ServiceCreateInput serviceCreateInput) {
242         LOG.debug("Writing '{}' Service", serviceCreateInput.getServiceName());
243         try {
244             InstanceIdentifier<Services> iid = InstanceIdentifier.create(ServiceList.class)
245                     .child(Services.class, new ServicesKey(serviceCreateInput.getServiceName()));
246             Services service = ModelMappingUtils.mappingServices(serviceCreateInput, null);
247             WriteTransaction writeTx = this.dataBroker.newWriteOnlyTransaction();
248             writeTx.put(LogicalDatastoreType.OPERATIONAL, iid, service);
249             writeTx.commit().get(Timeouts.DATASTORE_WRITE, TimeUnit.MILLISECONDS);
250             return OperationResult.ok(LogMessages.SUCCESSFUL_MESSAGE);
251         } catch (TimeoutException | InterruptedException | ExecutionException e) {
252             LOG.warn("createService : {}", LogMessages.failedTo(CREATE_MSG, serviceCreateInput.getServiceName()), e);
253             return OperationResult.failed(LogMessages.failedTo(CREATE_MSG, serviceCreateInput.getServiceName()));
254         }
255     }
256
257     @Override
258     public OperationResult createTempService(TempServiceCreateInput tempServiceCreateInput) {
259         LOG.debug("Writing '{}' Temp Service", tempServiceCreateInput.getCommonId());
260         try {
261             InstanceIdentifier<org.opendaylight.yang.gen.v1.http.org.openroadm.service.rev190531.temp.service.list
262                 .Services> iid = InstanceIdentifier.create(TempServiceList.class)
263                     .child(org.opendaylight.yang.gen.v1.http.org.openroadm.service.rev190531.temp.service.list
264                             .Services.class, new org.opendaylight.yang.gen.v1.http.org.openroadm.service.rev190531.temp
265                                 .service.list.ServicesKey(tempServiceCreateInput.getCommonId()));
266             org.opendaylight.yang.gen.v1.http.org.openroadm.service.rev190531.temp.service.list
267                 .Services service = ModelMappingUtils.mappingServices(tempServiceCreateInput);
268             WriteTransaction writeTx = this.dataBroker.newWriteOnlyTransaction();
269             writeTx.put(LogicalDatastoreType.OPERATIONAL, iid, service);
270             writeTx.commit().get(Timeouts.DATASTORE_WRITE, TimeUnit.MILLISECONDS);
271             return OperationResult.ok(LogMessages.SUCCESSFUL_MESSAGE);
272         } catch (TimeoutException | InterruptedException | ExecutionException e) {
273             LOG.warn("createTempService : {}",
274                     LogMessages.failedTo("create Temp", tempServiceCreateInput.getCommonId()), e);
275             return OperationResult.failed(LogMessages.failedTo("create Temp", tempServiceCreateInput.getCommonId()));
276         }
277     }
278
279     @Override
280     public Optional<ServicePathList> getServicePaths() {
281         LOG.debug("Retrieving list of ServicePath...");
282         try {
283             ReadTransaction readTx = this.dataBroker.newReadOnlyTransaction();
284             InstanceIdentifier<ServicePathList> servicePathListIID = InstanceIdentifier.create(ServicePathList.class);
285             Future<java.util.Optional<ServicePathList>> future = readTx.read(LogicalDatastoreType.OPERATIONAL,
286                     servicePathListIID);
287             return future.get(Timeouts.DATASTORE_READ, TimeUnit.MILLISECONDS);
288         } catch (InterruptedException | ExecutionException | TimeoutException e) {
289             LOG.error("Reading service path list failed. Error={}", e.getMessage());
290         }
291         return Optional.empty();
292     }
293
294     private Optional<ServicePaths> getServicePath(String serviceName) {
295         LOG.debug("Retrieving service path of service {}", serviceName);
296         try {
297             ReadTransaction readTx = this.dataBroker.newReadOnlyTransaction();
298             InstanceIdentifier<ServicePaths> servicePathsIID = InstanceIdentifier.create(ServicePathList.class)
299                     .child(ServicePaths.class, new ServicePathsKey(serviceName));
300             Future<java.util.Optional<ServicePaths>> future = readTx.read(LogicalDatastoreType.OPERATIONAL,
301                     servicePathsIID);
302             return future.get(Timeouts.DATASTORE_READ, TimeUnit.MILLISECONDS);
303         } catch (InterruptedException | ExecutionException | TimeoutException e) {
304             LOG.error("Reading service path failed. Error={}", e.getMessage());
305         }
306         return Optional.empty();
307     }
308
309     @Override
310     public OperationResult createServicePath(ServiceInput serviceInput, PathComputationRequestOutput outputFromPce) {
311         LOG.debug("Writing '{}' ServicePath ", serviceInput.getServiceName());
312         try {
313             InstanceIdentifier<ServicePaths> servicePathsIID = InstanceIdentifier.create(ServicePathList.class)
314                     .child(ServicePaths.class, new ServicePathsKey(serviceInput.getServiceName()));
315             ServicePaths servicePath = ModelMappingUtils.mappingServicePaths(serviceInput, outputFromPce);
316             WriteTransaction writeTx = this.dataBroker.newWriteOnlyTransaction();
317             writeTx.put(LogicalDatastoreType.OPERATIONAL, servicePathsIID, servicePath);
318             writeTx.commit().get(Timeouts.DATASTORE_WRITE, TimeUnit.MILLISECONDS);
319             return OperationResult.ok(LogMessages.SUCCESSFUL_MESSAGE);
320         } catch (TimeoutException | InterruptedException | ExecutionException e) {
321             LOG.warn("createServicePath : {}",
322                     LogMessages.failedTo("create servicePath", serviceInput.getCommonId()), e);
323             return OperationResult.failed(LogMessages.failedTo("create servicePath", serviceInput.getCommonId()));
324         }
325     }
326
327     @Override
328     public OperationResult modifyServicePath(PathDescription pathDescription, String serviceName) {
329         LOG.debug("Updating servicePath because of a change in the openroadm-topology");
330         Optional<ServicePaths> readServicePath = getServicePath(serviceName);
331         if (!readServicePath.isPresent()) {
332             LOG.warn("modifyServicePath: {}", LogMessages.SERVICE_PATH_NOT_FOUND);
333             return OperationResult.failed(LogMessages.SERVICE_PATH_NOT_FOUND);
334         }
335         try {
336             WriteTransaction writeTx = this.dataBroker.newWriteOnlyTransaction();
337             InstanceIdentifier<ServicePaths> iid = InstanceIdentifier.create(ServicePathList.class)
338                     .child(ServicePaths.class, new ServicePathsKey(serviceName));
339             ServicePaths servicePaths = new ServicePathsBuilder()
340                     .setServiceAEnd(readServicePath.get().getServiceAEnd())
341                     .setServiceHandlerHeader(readServicePath.get().getServiceHandlerHeader())
342                     .setServicePathName(readServicePath.get().getServicePathName())
343                     .setServiceZEnd(readServicePath.get().getServiceZEnd())
344                     .setSupportingServiceName(readServicePath.get().getSupportingServiceName())
345                     .setEquipmentSrgs(readServicePath.get().getEquipmentSrgs())
346                     .setFiberSpanSrlgs(readServicePath.get().getFiberSpanSrlgs())
347                     .setHardConstraints(readServicePath.get().getHardConstraints())
348                     .setLatency(readServicePath.get().getLatency())
349                     .setLocallyProtectedLinks(readServicePath.get().isLocallyProtectedLinks())
350                     .setPathDescription(pathDescription)
351                     .setPceMetric(readServicePath.get().getPceMetric())
352                     .setSoftConstraints(readServicePath.get().getSoftConstraints())
353                     .build();
354
355             writeTx.merge(LogicalDatastoreType.OPERATIONAL, iid, servicePaths);
356             writeTx.commit().get(Timeouts.DATASTORE_WRITE, TimeUnit.MILLISECONDS);
357             return OperationResult.ok(LogMessages.SUCCESSFUL_MESSAGE);
358         } catch (TimeoutException | InterruptedException | ExecutionException e) {
359             LOG.warn("modifyServicePath : {}", LogMessages.failedTo("modify service path", serviceName), e);
360             return OperationResult.failed(LogMessages.failedTo("modify service path", serviceName));
361         }
362     }
363
364     @Override
365     public OperationResult deleteServicePath(String serviceName) {
366         InstanceIdentifier<ServicePaths> servicePathsIID = InstanceIdentifier.create(ServicePathList.class)
367                 .child(ServicePaths.class, new ServicePathsKey(serviceName));
368         LOG.debug("Deleting service from {}", servicePathsIID);
369         WriteTransaction servicePathsWriteTx = this.dataBroker.newWriteOnlyTransaction();
370         servicePathsWriteTx.delete(LogicalDatastoreType.OPERATIONAL, servicePathsIID);
371         try {
372             servicePathsWriteTx.commit().get(Timeouts.DATASTORE_DELETE, TimeUnit.MILLISECONDS);
373             return OperationResult.ok(LogMessages.SUCCESSFUL_MESSAGE);
374         } catch (InterruptedException | ExecutionException | TimeoutException e) {
375             LOG.error("deleteServicePath : {}", LogMessages.failedTo("delete servicePath", serviceName), e);
376             return OperationResult.failed(LogMessages.failedTo("delete servicePath", serviceName));
377         }
378     }
379
380     /*
381      * Write or Modify or Delete Service from/to SreviceList.
382      *
383      * @param serviceName Name of service
384      *
385      * @param input ServiceCreateInput
386      *
387      * @param output PathComputationRequestOutput
388      *
389      * @param choice 0 - Modify 1 - Delete 2 - Write
390      *
391      * @return String operations result, null if ok or not otherwise
392      */
393     @Deprecated
394     @Override
395     public String writeOrModifyOrDeleteServiceList(String serviceName, ServiceCreateInput input,
396             PathComputationRequestOutput output, int choice) {
397         LOG.debug("WriteOrModifyOrDeleting '{}' Service", serviceName);
398         WriteTransaction writeTx = this.dataBroker.newWriteOnlyTransaction();
399         Optional<Services> readService = getService(serviceName);
400
401         /*
402          * Write Service.
403          */
404         if (!readService.isPresent()) {
405             if (choice != 2) {
406                 LOG.warn("writeOrModifyOrDeleteServiceList: {}", LogMessages.SERVICE_NOT_FOUND);
407                 return LogMessages.SERVICE_NOT_FOUND;
408             }
409
410             LOG.debug("Writing '{}' Service", serviceName);
411             InstanceIdentifier<Services> iid = InstanceIdentifier.create(ServiceList.class)
412                     .child(Services.class, new ServicesKey(serviceName));
413             Services service = ModelMappingUtils.mappingServices(input, null);
414             writeTx.put(LogicalDatastoreType.OPERATIONAL, iid, service);
415             try {
416                 writeTx.commit().get(Timeouts.DATASTORE_WRITE, TimeUnit.MILLISECONDS);
417                 return null;
418             } catch (InterruptedException | TimeoutException | ExecutionException e) {
419                 LOG.error("writeOrModifyOrDeleteServiceList : {}", LogMessages.failedTo(CREATE_MSG, serviceName), e);
420                 return LogMessages.failedTo(CREATE_MSG, serviceName);
421             }
422         }
423
424         /*
425          * Modify / Delete Service.
426          */
427         InstanceIdentifier<Services> iid =
428                 InstanceIdentifier.create(ServiceList.class).child(Services.class, new ServicesKey(serviceName));
429         ServicesBuilder service = new ServicesBuilder(readService.get());
430         String action = null;
431         switch (choice) {
432             case 0 : /* Modify. */
433                 LOG.debug("Modifying '{}' Service", serviceName);
434                 service.setOperationalState(convertOperState(State.InService))
435                     .setAdministrativeState(convertAdminState(AdminStates.InService));
436                 writeTx.merge(LogicalDatastoreType.OPERATIONAL, iid, service.build());
437                 action = "modifyService";
438                 break;
439             case 1 : /* Delete */
440                 LOG.debug(DELETING_SERVICE_MSG, serviceName);
441                 writeTx.delete(LogicalDatastoreType.OPERATIONAL, iid);
442                 action = "deleteService";
443                 break;
444             default:
445                 LOG.debug("No choice found");
446                 break;
447         }
448         try {
449             writeTx.commit().get(Timeouts.DATASTORE_WRITE, TimeUnit.MILLISECONDS);
450         } catch (InterruptedException | ExecutionException | TimeoutException e) {
451             LOG.error("writeOrModifyOrDeleteServiceList : {}", LogMessages.failedTo(action, serviceName), e);
452             return LogMessages.failedTo(action, serviceName);
453         }
454
455         return null;
456     }
457
458     private org.opendaylight.yang.gen.v1.http.org.openroadm.equipment.states.types.rev181130.AdminStates
459         convertAdminState(AdminStates adminState61) {
460         return org.opendaylight.yang.gen.v1.http.org.openroadm.equipment.states.types.rev181130.AdminStates
461             .valueOf(adminState61.name());
462     }
463
464     private org.opendaylight.yang.gen.v1.http.org.openroadm.common.state.types.rev181130.State
465         convertOperState(State operState61) {
466         return org.opendaylight.yang.gen.v1.http.org.openroadm.common.state.types.rev181130.State
467             .valueOf(operState61.name());
468     }
469 }