NetworkModelListener: handling TopologyUpdates
[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.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()).setOperationalState(operationalState)
196                     .setAdministrativeState(administrativeState)
197                     .build();
198             writeTx.merge(LogicalDatastoreType.OPERATIONAL, iid, services);
199             writeTx.commit().get(Timeouts.DATASTORE_WRITE, TimeUnit.MILLISECONDS);
200             return OperationResult.ok(LogMessages.SUCCESSFUL_MESSAGE);
201         } catch (TimeoutException | InterruptedException | ExecutionException e) {
202             LOG.warn("modifyService : {}", LogMessages.failedTo("modify", serviceName), e);
203             return OperationResult.failed(LogMessages.failedTo("modify", serviceName));
204         }
205     }
206
207     @Override
208     public OperationResult modifyTempService(String serviceName, State operationalState,
209         AdminStates administrativeState) {
210         LOG.debug("Modifying '{}' Temp Service", serviceName);
211         Optional<org.opendaylight.yang.gen.v1.http.org.openroadm.service.rev190531.temp.service.list
212             .Services> readService = getTempService(serviceName);
213         if (!readService.isPresent()) {
214             LOG.warn("modifyTempService: {}", LogMessages.SERVICE_NOT_FOUND);
215             return OperationResult.failed(LogMessages.SERVICE_NOT_FOUND);
216         }
217         try {
218             WriteTransaction writeTx = this.dataBroker.newWriteOnlyTransaction();
219             InstanceIdentifier<org.opendaylight.yang.gen.v1.http.org.openroadm.service.rev190531.temp.service.list
220                 .Services> iid = InstanceIdentifier.create(TempServiceList.class)
221                     .child(org.opendaylight.yang.gen.v1.http.org.openroadm.service.rev190531.temp.service.list
222                             .Services.class, new org.opendaylight.yang.gen.v1.http.org.openroadm.service.rev190531
223                                 .temp.service.list.ServicesKey(serviceName));
224             org.opendaylight.yang.gen.v1.http.org.openroadm.service.rev190531.temp.service.list
225                 .Services services = new org.opendaylight.yang.gen.v1.http.org.openroadm.service.rev190531.temp
226                     .service.list.ServicesBuilder(readService.get()).setOperationalState(operationalState)
227                         .setAdministrativeState(administrativeState)
228                         .build();
229             writeTx.merge(LogicalDatastoreType.OPERATIONAL, iid, services);
230             writeTx.commit().get(Timeouts.DATASTORE_WRITE, TimeUnit.MILLISECONDS);
231             return OperationResult.ok(LogMessages.SUCCESSFUL_MESSAGE);
232         } catch (TimeoutException | InterruptedException | ExecutionException e) {
233             LOG.warn("modifyTempService : {}", LogMessages.failedTo("modify Temp", serviceName), e);
234             return OperationResult.failed(LogMessages.failedTo("modify Temp", serviceName));
235         }
236     }
237
238     @Override
239     public OperationResult createService(ServiceCreateInput serviceCreateInput) {
240         LOG.debug("Writing '{}' Service", serviceCreateInput.getServiceName());
241         try {
242             InstanceIdentifier<Services> iid = InstanceIdentifier.create(ServiceList.class)
243                     .child(Services.class, new ServicesKey(serviceCreateInput.getServiceName()));
244             Services service = ModelMappingUtils.mappingServices(serviceCreateInput, null);
245             WriteTransaction writeTx = this.dataBroker.newWriteOnlyTransaction();
246             writeTx.put(LogicalDatastoreType.OPERATIONAL, iid, service);
247             writeTx.commit().get(Timeouts.DATASTORE_WRITE, TimeUnit.MILLISECONDS);
248             return OperationResult.ok(LogMessages.SUCCESSFUL_MESSAGE);
249         } catch (TimeoutException | InterruptedException | ExecutionException e) {
250             LOG.warn("createService : {}", LogMessages.failedTo(CREATE_MSG, serviceCreateInput.getServiceName()), e);
251             return OperationResult.failed(LogMessages.failedTo(CREATE_MSG, serviceCreateInput.getServiceName()));
252         }
253     }
254
255     @Override
256     public OperationResult createTempService(TempServiceCreateInput tempServiceCreateInput) {
257         LOG.debug("Writing '{}' Temp Service", tempServiceCreateInput.getCommonId());
258         try {
259             InstanceIdentifier<org.opendaylight.yang.gen.v1.http.org.openroadm.service.rev190531.temp.service.list
260                 .Services> iid = InstanceIdentifier.create(TempServiceList.class)
261                     .child(org.opendaylight.yang.gen.v1.http.org.openroadm.service.rev190531.temp.service.list
262                             .Services.class, new org.opendaylight.yang.gen.v1.http.org.openroadm.service.rev190531.temp
263                                 .service.list.ServicesKey(tempServiceCreateInput.getCommonId()));
264             org.opendaylight.yang.gen.v1.http.org.openroadm.service.rev190531.temp.service.list
265                 .Services service = ModelMappingUtils.mappingServices(tempServiceCreateInput);
266             WriteTransaction writeTx = this.dataBroker.newWriteOnlyTransaction();
267             writeTx.put(LogicalDatastoreType.OPERATIONAL, iid, service);
268             writeTx.commit().get(Timeouts.DATASTORE_WRITE, TimeUnit.MILLISECONDS);
269             return OperationResult.ok(LogMessages.SUCCESSFUL_MESSAGE);
270         } catch (TimeoutException | InterruptedException | ExecutionException e) {
271             LOG.warn("createTempService : {}",
272                     LogMessages.failedTo("create Temp", tempServiceCreateInput.getCommonId()), e);
273             return OperationResult.failed(LogMessages.failedTo("create Temp", tempServiceCreateInput.getCommonId()));
274         }
275     }
276
277     @Override
278     public Optional<ServicePathList> getServicePaths() {
279         LOG.debug("Retrieving list of ServicePath...");
280         try {
281             ReadTransaction readTx = this.dataBroker.newReadOnlyTransaction();
282             InstanceIdentifier<ServicePathList> servicePathListIID = InstanceIdentifier.create(ServicePathList.class);
283             Future<java.util.Optional<ServicePathList>> future = readTx.read(LogicalDatastoreType.OPERATIONAL,
284                     servicePathListIID);
285             return future.get(Timeouts.DATASTORE_READ, TimeUnit.MILLISECONDS);
286         } catch (InterruptedException | ExecutionException | TimeoutException e) {
287             LOG.error("Reading service path list failed. Error={}", e.getMessage());
288         }
289         return Optional.empty();
290     }
291
292     private Optional<ServicePaths> getServicePath(String serviceName) {
293         LOG.debug("Retrieving service path of service {}", serviceName);
294         try {
295             ReadTransaction readTx = this.dataBroker.newReadOnlyTransaction();
296             InstanceIdentifier<ServicePaths> servicePathsIID = InstanceIdentifier.create(ServicePathList.class)
297                     .child(ServicePaths.class, new ServicePathsKey(serviceName));
298             Future<java.util.Optional<ServicePaths>> future = readTx.read(LogicalDatastoreType.OPERATIONAL,
299                     servicePathsIID);
300             return future.get(Timeouts.DATASTORE_READ, TimeUnit.MILLISECONDS);
301         } catch (InterruptedException | ExecutionException | TimeoutException e) {
302             LOG.error("Reading service path failed. Error={}", e.getMessage());
303         }
304         return Optional.empty();
305     }
306
307     @Override
308     public OperationResult createServicePath(ServiceInput serviceInput, PathComputationRequestOutput outputFromPce) {
309         LOG.debug("Writing '{}' ServicePath ", serviceInput.getServiceName());
310         try {
311             InstanceIdentifier<ServicePaths> servicePathsIID = InstanceIdentifier.create(ServicePathList.class)
312                     .child(ServicePaths.class, new ServicePathsKey(serviceInput.getServiceName()));
313             ServicePaths servicePath = ModelMappingUtils.mappingServicePaths(serviceInput, outputFromPce);
314             WriteTransaction writeTx = this.dataBroker.newWriteOnlyTransaction();
315             writeTx.put(LogicalDatastoreType.OPERATIONAL, servicePathsIID, servicePath);
316             writeTx.commit().get(Timeouts.DATASTORE_WRITE, TimeUnit.MILLISECONDS);
317             return OperationResult.ok(LogMessages.SUCCESSFUL_MESSAGE);
318         } catch (TimeoutException | InterruptedException | ExecutionException e) {
319             LOG.warn("createServicePath : {}",
320                     LogMessages.failedTo("create servicePath", serviceInput.getCommonId()), e);
321             return OperationResult.failed(LogMessages.failedTo("create servicePath", serviceInput.getCommonId()));
322         }
323     }
324
325     @Override
326     public OperationResult modifyServicePath(PathDescription pathDescription, String serviceName) {
327         LOG.debug("Updating servicePath because of a change in the openroadm-topology");
328         Optional<ServicePaths> readServicePath = getServicePath(serviceName);
329         if (!readServicePath.isPresent()) {
330             LOG.warn("modifyServicePath: {}", LogMessages.SERVICE_PATH_NOT_FOUND);
331             return OperationResult.failed(LogMessages.SERVICE_PATH_NOT_FOUND);
332         }
333         try {
334             WriteTransaction writeTx = this.dataBroker.newWriteOnlyTransaction();
335             InstanceIdentifier<ServicePaths> iid = InstanceIdentifier.create(ServicePathList.class)
336                     .child(ServicePaths.class, new ServicePathsKey(serviceName));
337             ServicePaths servicePaths = new ServicePathsBuilder()
338                     .setServiceAEnd(readServicePath.get().getServiceAEnd())
339                     .setServiceHandlerHeader(readServicePath.get().getServiceHandlerHeader())
340                     .setServicePathName(readServicePath.get().getServicePathName())
341                     .setServiceZEnd(readServicePath.get().getServiceZEnd())
342                     .setSupportingServiceName(readServicePath.get().getSupportingServiceName())
343                     .setEquipmentSrgs(readServicePath.get().getEquipmentSrgs())
344                     .setFiberSpanSrlgs(readServicePath.get().getFiberSpanSrlgs())
345                     .setHardConstraints(readServicePath.get().getHardConstraints())
346                     .setLatency(readServicePath.get().getLatency())
347                     .setLocallyProtectedLinks(readServicePath.get().isLocallyProtectedLinks())
348                     .setPathDescription(pathDescription)
349                     .setPceMetric(readServicePath.get().getPceMetric())
350                     .setSoftConstraints(readServicePath.get().getSoftConstraints())
351                     .build();
352
353             writeTx.merge(LogicalDatastoreType.OPERATIONAL, iid, servicePaths);
354             writeTx.commit().get(Timeouts.DATASTORE_WRITE, TimeUnit.MILLISECONDS);
355             return OperationResult.ok(LogMessages.SUCCESSFUL_MESSAGE);
356         } catch (TimeoutException | InterruptedException | ExecutionException e) {
357             LOG.warn("modifyServicePath : {}", LogMessages.failedTo("modify service path", serviceName), e);
358             return OperationResult.failed(LogMessages.failedTo("modify service path", serviceName));
359         }
360     }
361
362     @Override
363     public OperationResult deleteServicePath(String serviceName) {
364         InstanceIdentifier<ServicePaths> servicePathsIID = InstanceIdentifier.create(ServicePathList.class)
365                 .child(ServicePaths.class, new ServicePathsKey(serviceName));
366         LOG.debug("Deleting service from {}", servicePathsIID);
367         WriteTransaction servicePathsWriteTx = this.dataBroker.newWriteOnlyTransaction();
368         servicePathsWriteTx.delete(LogicalDatastoreType.OPERATIONAL, servicePathsIID);
369         try {
370             servicePathsWriteTx.commit().get(Timeouts.DATASTORE_DELETE, TimeUnit.MILLISECONDS);
371             return OperationResult.ok(LogMessages.SUCCESSFUL_MESSAGE);
372         } catch (InterruptedException | ExecutionException | TimeoutException e) {
373             LOG.error("deleteServicePath : {}", LogMessages.failedTo("delete servicePath", serviceName), e);
374             return OperationResult.failed(LogMessages.failedTo("delete servicePath", serviceName));
375         }
376     }
377
378     /*
379      * Write or Modify or Delete Service from/to SreviceList.
380      *
381      * @param serviceName Name of service
382      *
383      * @param input ServiceCreateInput
384      *
385      * @param output PathComputationRequestOutput
386      *
387      * @param choice 0 - Modify 1 - Delete 2 - Write
388      *
389      * @return String operations result, null if ok or not otherwise
390      */
391     @Deprecated
392     @Override
393     public String writeOrModifyOrDeleteServiceList(String serviceName, ServiceCreateInput input,
394             PathComputationRequestOutput output, int choice) {
395         LOG.debug("WriteOrModifyOrDeleting '{}' Service", serviceName);
396         WriteTransaction writeTx = this.dataBroker.newWriteOnlyTransaction();
397         Optional<Services> readService = getService(serviceName);
398
399         /*
400          * Write Service.
401          */
402         if (!readService.isPresent()) {
403             if (choice != 2) {
404                 LOG.warn("writeOrModifyOrDeleteServiceList: {}", LogMessages.SERVICE_NOT_FOUND);
405                 return LogMessages.SERVICE_NOT_FOUND;
406             }
407
408             LOG.debug("Writing '{}' Service", serviceName);
409             InstanceIdentifier<Services> iid = InstanceIdentifier.create(ServiceList.class)
410                     .child(Services.class, new ServicesKey(serviceName));
411             Services service = ModelMappingUtils.mappingServices(input, null);
412             writeTx.put(LogicalDatastoreType.OPERATIONAL, iid, service);
413             try {
414                 writeTx.commit().get(Timeouts.DATASTORE_WRITE, TimeUnit.MILLISECONDS);
415                 return null;
416             } catch (InterruptedException | TimeoutException | ExecutionException e) {
417                 LOG.error("writeOrModifyOrDeleteServiceList : {}", LogMessages.failedTo(CREATE_MSG, serviceName), e);
418                 return LogMessages.failedTo(CREATE_MSG, serviceName);
419             }
420         }
421
422         /*
423          * Modify / Delete Service.
424          */
425         InstanceIdentifier<Services> iid =
426                 InstanceIdentifier.create(ServiceList.class).child(Services.class, new ServicesKey(serviceName));
427         ServicesBuilder service = new ServicesBuilder(readService.get());
428         String action = null;
429         switch (choice) {
430             case 0 : /* Modify. */
431                 LOG.debug("Modifying '{}' Service", serviceName);
432                 service.setOperationalState(State.InService).setAdministrativeState(AdminStates.InService);
433                 writeTx.merge(LogicalDatastoreType.OPERATIONAL, iid, service.build());
434                 action = "modifyService";
435                 break;
436             case 1 : /* Delete */
437                 LOG.debug(DELETING_SERVICE_MSG, serviceName);
438                 writeTx.delete(LogicalDatastoreType.OPERATIONAL, iid);
439                 action = "deleteService";
440                 break;
441             default:
442                 LOG.debug("No choice found");
443                 break;
444         }
445         try {
446             writeTx.commit().get(Timeouts.DATASTORE_WRITE, TimeUnit.MILLISECONDS);
447         } catch (InterruptedException | ExecutionException | TimeoutException e) {
448             LOG.error("writeOrModifyOrDeleteServiceList : {}", LogMessages.failedTo(action, serviceName), e);
449             return LogMessages.failedTo(action, serviceName);
450         }
451
452         return null;
453     }
454 }