2 * Copyright © 2017 Orange, Inc. and others. All rights reserved.
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
8 package org.opendaylight.transportpce.servicehandler.service;
10 import com.google.common.util.concurrent.FluentFuture;
11 import java.util.Optional;
12 import java.util.concurrent.ExecutionException;
13 import java.util.concurrent.TimeUnit;
14 import java.util.concurrent.TimeoutException;
15 import org.eclipse.jdt.annotation.NonNull;
16 import org.opendaylight.mdsal.binding.api.DataBroker;
17 import org.opendaylight.mdsal.binding.api.WriteTransaction;
18 import org.opendaylight.mdsal.common.api.CommitInfo;
19 import org.opendaylight.mdsal.common.api.LogicalDatastoreType;
20 import org.opendaylight.transportpce.common.OperationResult;
21 import org.opendaylight.transportpce.common.Timeouts;
22 import org.opendaylight.transportpce.servicehandler.ModelMappingUtils;
23 import org.opendaylight.transportpce.servicehandler.ServiceInput;
24 import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.pce.rev230925.PathComputationRequestOutput;
25 import org.opendaylight.yang.gen.v1.http.org.openroadm.common.state.types.rev191129.State;
26 import org.opendaylight.yang.gen.v1.http.org.openroadm.equipment.states.types.rev191129.AdminStates;
27 import org.opendaylight.yang.gen.v1.http.org.openroadm.service.rev230526.ServiceCreateInput;
28 import org.opendaylight.yang.gen.v1.http.org.openroadm.service.rev230526.ServiceList;
29 import org.opendaylight.yang.gen.v1.http.org.openroadm.service.rev230526.ServiceListBuilder;
30 import org.opendaylight.yang.gen.v1.http.org.openroadm.service.rev230526.TempServiceCreateInput;
31 import org.opendaylight.yang.gen.v1.http.org.openroadm.service.rev230526.TempServiceList;
32 import org.opendaylight.yang.gen.v1.http.org.openroadm.service.rev230526.TempServiceListBuilder;
33 import org.opendaylight.yang.gen.v1.http.org.openroadm.service.rev230526.service.list.Services;
34 import org.opendaylight.yang.gen.v1.http.org.openroadm.service.rev230526.service.list.ServicesBuilder;
35 import org.opendaylight.yang.gen.v1.http.org.openroadm.service.rev230526.service.list.ServicesKey;
36 import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.service.types.rev220118.service.path.PathDescription;
37 import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.servicepath.rev171017.ServicePathList;
38 import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.servicepath.rev171017.service.path.list.ServicePaths;
39 import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.servicepath.rev171017.service.path.list.ServicePathsBuilder;
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.osgi.service.component.annotations.Activate;
43 import org.osgi.service.component.annotations.Component;
44 import org.osgi.service.component.annotations.Reference;
45 import org.slf4j.Logger;
46 import org.slf4j.LoggerFactory;
48 @Component(immediate = true)
49 public class ServiceDataStoreOperationsImpl implements ServiceDataStoreOperations {
50 private static final Logger LOG = LoggerFactory.getLogger(ServiceDataStoreOperationsImpl.class);
51 private static final String CREATE_MSG = "create";
52 private static final String DELETING_SERVICE_MSG = "Deleting '{}' Service";
53 private DataBroker dataBroker;
55 // This is class is public so that these messages can be accessed from Junit (avoid duplications).
56 public static final class LogMessages {
58 public static final String SUCCESSFUL_MESSAGE;
59 public static final String SERVICE_NOT_FOUND;
60 public static final String SERVICE_PATH_NOT_FOUND;
62 // Static blocks are generated once and spare memory.
64 SUCCESSFUL_MESSAGE = "Successful";
65 SERVICE_NOT_FOUND = "Service not found";
66 SERVICE_PATH_NOT_FOUND = "Service path not found";
69 public static String failedTo(String action, String serviceName) {
70 return "Failed to " + action + " service " + serviceName;
73 private LogMessages() {
79 public ServiceDataStoreOperationsImpl(@Reference DataBroker dataBroker) {
80 this.dataBroker = dataBroker;
84 public void initialize() {
85 initializeServiceList();
86 initializeTempServiceList();
89 private void initializeServiceList() {
91 LOG.info("initializing service registry");
92 WriteTransaction transaction = this.dataBroker.newWriteOnlyTransaction();
94 LogicalDatastoreType.OPERATIONAL,
95 InstanceIdentifier.create(ServiceList.class),
96 new ServiceListBuilder().build());
97 FluentFuture<? extends @NonNull CommitInfo> future = transaction.commit();
98 future.get(Timeouts.DATASTORE_WRITE, TimeUnit.MILLISECONDS);
99 } catch (InterruptedException | ExecutionException | TimeoutException e) {
100 LOG.error("init failed: ", e);
104 private void initializeTempServiceList() {
106 LOG.info("initializing temp service registry");
107 WriteTransaction transaction = this.dataBroker.newWriteOnlyTransaction();
109 LogicalDatastoreType.OPERATIONAL,
110 InstanceIdentifier.create(TempServiceList.class),
111 new TempServiceListBuilder().build());
112 FluentFuture<? extends @NonNull CommitInfo> future = transaction.commit();
113 future.get(Timeouts.DATASTORE_WRITE, TimeUnit.MILLISECONDS);
114 } catch (InterruptedException | ExecutionException | TimeoutException e) {
115 LOG.error("init failed: ", e);
120 public Optional<Services> getService(String serviceName) {
122 return this.dataBroker.newReadOnlyTransaction()
124 LogicalDatastoreType.OPERATIONAL,
125 InstanceIdentifier.create(ServiceList.class)
126 .child(Services.class, new ServicesKey(serviceName))
128 .get(Timeouts.DATASTORE_READ, TimeUnit.MILLISECONDS);
129 } catch (InterruptedException | ExecutionException | TimeoutException e) {
130 LOG.warn("Reading service {} failed:", serviceName, e);
132 return Optional.empty();
136 public Optional<ServiceList> getServices() {
138 return this.dataBroker.newReadOnlyTransaction()
140 LogicalDatastoreType.OPERATIONAL,
141 InstanceIdentifier.create(ServiceList.class))
142 .get(Timeouts.DATASTORE_READ, TimeUnit.MILLISECONDS);
143 } catch (InterruptedException | ExecutionException | TimeoutException e) {
144 LOG.warn("Reading services failed:", e);
146 return Optional.empty();
150 public Optional<org.opendaylight.yang.gen.v1.http.org.openroadm.service.rev230526
151 .temp.service.list.Services> getTempService(String serviceName) {
153 return this.dataBroker.newReadOnlyTransaction()
155 LogicalDatastoreType.OPERATIONAL,
156 InstanceIdentifier.create(TempServiceList.class)
158 org.opendaylight.yang.gen.v1.http.org.openroadm.service.rev230526
159 .temp.service.list.Services.class,
160 new org.opendaylight.yang.gen.v1.http.org.openroadm.service.rev230526
161 .temp.service.list.ServicesKey(serviceName)))
162 .get(Timeouts.DATASTORE_READ, TimeUnit.MILLISECONDS);
163 } catch (InterruptedException | ExecutionException | TimeoutException e) {
164 LOG.warn("Reading service {} failed:", serviceName, e);
166 return Optional.empty();
170 public OperationResult deleteService(String serviceName) {
171 LOG.debug(DELETING_SERVICE_MSG, serviceName);
173 WriteTransaction writeTx = this.dataBroker.newWriteOnlyTransaction();
175 LogicalDatastoreType.OPERATIONAL,
176 InstanceIdentifier.create(ServiceList.class)
177 .child(Services.class, new ServicesKey(serviceName)));
178 writeTx.commit().get(Timeouts.DATASTORE_DELETE, TimeUnit.MILLISECONDS);
179 return OperationResult.ok(LogMessages.SUCCESSFUL_MESSAGE);
180 } catch (TimeoutException | InterruptedException | ExecutionException e) {
181 LOG.warn("deleteService : {}", LogMessages.failedTo("delete", serviceName), e);
182 return OperationResult.failed(LogMessages.failedTo("delete", serviceName));
187 public OperationResult deleteTempService(String commonId) {
188 LOG.debug(DELETING_SERVICE_MSG, commonId);
190 WriteTransaction writeTx = this.dataBroker.newWriteOnlyTransaction();
192 LogicalDatastoreType.OPERATIONAL,
193 InstanceIdentifier.create(TempServiceList.class)
195 org.opendaylight.yang.gen.v1.http.org.openroadm.service.rev230526
196 .temp.service.list.Services.class,
197 new org.opendaylight.yang.gen.v1.http.org.openroadm.service.rev230526
198 .temp.service.list.ServicesKey(commonId)));
199 writeTx.commit().get(Timeouts.DATASTORE_DELETE, TimeUnit.MILLISECONDS);
200 return OperationResult.ok(LogMessages.SUCCESSFUL_MESSAGE);
201 } catch (TimeoutException | InterruptedException | ExecutionException e) {
202 LOG.warn("deleteTempService : {}", LogMessages.failedTo("delete Temp", commonId), e);
203 return OperationResult.failed(LogMessages.failedTo("delete Temp", commonId));
208 public OperationResult modifyService(String serviceName, State operationalState, AdminStates administrativeState) {
209 LOG.debug("Modifying '{}' Service", serviceName);
210 Optional<Services> readService = getService(serviceName);
211 if (readService.isEmpty()) {
212 LOG.warn("modifyService: {}", LogMessages.SERVICE_NOT_FOUND);
213 return OperationResult.failed(LogMessages.SERVICE_NOT_FOUND);
216 WriteTransaction writeTx = this.dataBroker.newWriteOnlyTransaction();
218 LogicalDatastoreType.OPERATIONAL,
219 InstanceIdentifier.create(ServiceList.class)
220 .child(Services.class, new ServicesKey(serviceName)),
221 new ServicesBuilder(readService.orElseThrow())
222 .setOperationalState(operationalState)
223 .setAdministrativeState(administrativeState)
225 writeTx.commit().get(Timeouts.DATASTORE_WRITE, TimeUnit.MILLISECONDS);
226 return OperationResult.ok(LogMessages.SUCCESSFUL_MESSAGE);
227 } catch (TimeoutException | InterruptedException | ExecutionException e) {
228 LOG.warn("modifyService : {}", LogMessages.failedTo("modify", serviceName), e);
229 return OperationResult.failed(LogMessages.failedTo("modify", serviceName));
234 public OperationResult modifyTempService(
235 String serviceName, State operationalState, AdminStates administrativeState) {
236 LOG.debug("Modifying '{}' Temp Service", serviceName);
237 Optional<org.opendaylight.yang.gen.v1.http.org.openroadm.service.rev230526
238 .temp.service.list.Services> readService = getTempService(serviceName);
239 if (readService.isEmpty()) {
240 LOG.warn("modifyTempService: {}", LogMessages.SERVICE_NOT_FOUND);
241 return OperationResult.failed(LogMessages.SERVICE_NOT_FOUND);
244 WriteTransaction writeTx = this.dataBroker.newWriteOnlyTransaction();
246 LogicalDatastoreType.OPERATIONAL,
247 InstanceIdentifier.create(TempServiceList.class)
249 org.opendaylight.yang.gen.v1.http.org.openroadm.service.rev230526
250 .temp.service.list.Services.class,
251 new org.opendaylight.yang.gen.v1.http.org.openroadm.service.rev230526
252 .temp.service.list.ServicesKey(serviceName)),
253 new org.opendaylight.yang.gen.v1.http.org.openroadm.service.rev230526
254 .temp.service.list.ServicesBuilder(readService.orElseThrow())
255 .setOperationalState(operationalState)
256 .setAdministrativeState(administrativeState)
258 writeTx.commit().get(Timeouts.DATASTORE_WRITE, TimeUnit.MILLISECONDS);
259 return OperationResult.ok(LogMessages.SUCCESSFUL_MESSAGE);
260 } catch (TimeoutException | InterruptedException | ExecutionException e) {
261 LOG.warn("modifyTempService : {}", LogMessages.failedTo("modify Temp", serviceName), e);
262 return OperationResult.failed(LogMessages.failedTo("modify Temp", serviceName));
267 public OperationResult createService(ServiceCreateInput serviceCreateInput) {
268 LOG.debug("Writing '{}' Service", serviceCreateInput.getServiceName());
270 WriteTransaction writeTx = this.dataBroker.newWriteOnlyTransaction();
272 LogicalDatastoreType.OPERATIONAL,
273 InstanceIdentifier.create(ServiceList.class)
274 .child(Services.class, new ServicesKey(serviceCreateInput.getServiceName())),
275 ModelMappingUtils.mappingServices(serviceCreateInput, null));
276 writeTx.commit().get(Timeouts.DATASTORE_WRITE, TimeUnit.MILLISECONDS);
277 return OperationResult.ok(LogMessages.SUCCESSFUL_MESSAGE);
278 } catch (TimeoutException | InterruptedException | ExecutionException e) {
279 LOG.warn("createService : {}", LogMessages.failedTo(CREATE_MSG, serviceCreateInput.getServiceName()), e);
280 return OperationResult.failed(LogMessages.failedTo(CREATE_MSG, serviceCreateInput.getServiceName()));
285 public OperationResult createTempService(
286 TempServiceCreateInput tempServiceCreateInput,
287 org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.pce.rev230925
288 .service.path.rpc.result.PathDescription pathDescription) {
289 LOG.debug("Writing '{}' Temp Service", tempServiceCreateInput.getCommonId());
291 WriteTransaction writeTx = this.dataBroker.newWriteOnlyTransaction();
293 LogicalDatastoreType.OPERATIONAL,
294 InstanceIdentifier.create(TempServiceList.class)
295 .child(org.opendaylight.yang.gen.v1.http.org.openroadm.service.rev230526
296 .temp.service.list.Services.class,
297 new org.opendaylight.yang.gen.v1.http.org.openroadm.service.rev230526
298 .temp.service.list.ServicesKey(tempServiceCreateInput.getCommonId())),
299 ModelMappingUtils.mappingServices(tempServiceCreateInput, pathDescription));
300 writeTx.commit().get(Timeouts.DATASTORE_WRITE, TimeUnit.MILLISECONDS);
301 return OperationResult.ok(LogMessages.SUCCESSFUL_MESSAGE);
302 } catch (TimeoutException | InterruptedException | ExecutionException e) {
303 LOG.warn("createTempService : {}",
304 LogMessages.failedTo("create Temp", tempServiceCreateInput.getCommonId()), e);
305 return OperationResult.failed(LogMessages.failedTo("create Temp", tempServiceCreateInput.getCommonId()));
310 public Optional<ServicePathList> getServicePaths() {
311 LOG.debug("Retrieving list of ServicePath...");
313 return this.dataBroker.newReadOnlyTransaction()
315 LogicalDatastoreType.OPERATIONAL,
316 InstanceIdentifier.create(ServicePathList.class))
317 .get(Timeouts.DATASTORE_READ, TimeUnit.MILLISECONDS);
318 } catch (InterruptedException | ExecutionException | TimeoutException e) {
319 LOG.error("Reading service path list failed. Error={}", e.getMessage());
321 return Optional.empty();
325 public Optional<ServicePaths> getServicePath(String serviceName) {
326 LOG.debug("Retrieving service path of service {}", serviceName);
328 return this.dataBroker.newReadOnlyTransaction()
330 LogicalDatastoreType.OPERATIONAL,
331 InstanceIdentifier.create(ServicePathList.class)
332 .child(ServicePaths.class, new ServicePathsKey(serviceName)))
333 .get(Timeouts.DATASTORE_READ, TimeUnit.MILLISECONDS);
334 } catch (InterruptedException | ExecutionException | TimeoutException e) {
335 LOG.error("Reading service path failed. Error={}", e.getMessage());
337 return Optional.empty();
341 public OperationResult createServicePath(ServiceInput serviceInput, PathComputationRequestOutput outputFromPce) {
342 LOG.debug("Writing '{}' ServicePath ", serviceInput.getServiceName());
344 WriteTransaction writeTx = this.dataBroker.newWriteOnlyTransaction();
346 LogicalDatastoreType.OPERATIONAL,
347 InstanceIdentifier.create(ServicePathList.class)
348 .child(ServicePaths.class, new ServicePathsKey(serviceInput.getServiceName())),
349 ModelMappingUtils.mappingServicePaths(serviceInput, outputFromPce));
350 writeTx.commit().get(Timeouts.DATASTORE_WRITE, TimeUnit.MILLISECONDS);
351 return OperationResult.ok(LogMessages.SUCCESSFUL_MESSAGE);
352 } catch (TimeoutException | InterruptedException | ExecutionException e) {
353 LOG.warn("createServicePath : {}",
354 LogMessages.failedTo("create servicePath", serviceInput.getCommonId()), e);
355 return OperationResult.failed(LogMessages.failedTo("create servicePath", serviceInput.getCommonId()));
360 public OperationResult modifyServicePath(PathDescription pathDescription, String serviceName) {
361 LOG.debug("Updating servicePath because of a change in the openroadm-topology");
362 Optional<ServicePaths> readServicePath = getServicePath(serviceName);
363 if (readServicePath.isEmpty()) {
364 LOG.warn("modifyServicePath: {}", LogMessages.SERVICE_PATH_NOT_FOUND);
365 return OperationResult.failed(LogMessages.SERVICE_PATH_NOT_FOUND);
368 WriteTransaction writeTx = this.dataBroker.newWriteOnlyTransaction();
370 LogicalDatastoreType.OPERATIONAL,
371 InstanceIdentifier.create(ServicePathList.class)
372 .child(ServicePaths.class, new ServicePathsKey(serviceName)),
373 new ServicePathsBuilder()
374 .setServiceAEnd(readServicePath.orElseThrow().getServiceAEnd())
375 .setServiceHandlerHeader(readServicePath.orElseThrow().getServiceHandlerHeader())
376 .setServicePathName(readServicePath.orElseThrow().getServicePathName())
377 .setServiceZEnd(readServicePath.orElseThrow().getServiceZEnd())
378 .setSupportingServiceName(readServicePath.orElseThrow().getSupportingServiceName())
379 .setEquipmentSrgs(readServicePath.orElseThrow().getEquipmentSrgs())
380 .setFiberSpanSrlgs(readServicePath.orElseThrow().getFiberSpanSrlgs())
381 .setHardConstraints(readServicePath.orElseThrow().getHardConstraints())
382 .setLatency(readServicePath.orElseThrow().getLatency())
383 .setPathDescription(pathDescription)
384 .setPceRoutingMetric(readServicePath.orElseThrow().getPceRoutingMetric())
385 .setSoftConstraints(readServicePath.orElseThrow().getSoftConstraints())
387 writeTx.commit().get(Timeouts.DATASTORE_WRITE, TimeUnit.MILLISECONDS);
388 return OperationResult.ok(LogMessages.SUCCESSFUL_MESSAGE);
389 } catch (TimeoutException | InterruptedException | ExecutionException e) {
390 LOG.warn("modifyServicePath : {}", LogMessages.failedTo("modify service path", serviceName), e);
391 return OperationResult.failed(LogMessages.failedTo("modify service path", serviceName));
396 public OperationResult deleteServicePath(String serviceName) {
397 InstanceIdentifier<ServicePaths> servicePathsIID =
398 InstanceIdentifier.create(ServicePathList.class)
399 .child(ServicePaths.class, new ServicePathsKey(serviceName));
400 LOG.debug("Deleting service from {}", servicePathsIID);
401 WriteTransaction servicePathsWriteTx = this.dataBroker.newWriteOnlyTransaction();
402 servicePathsWriteTx.delete(LogicalDatastoreType.OPERATIONAL, servicePathsIID);
404 servicePathsWriteTx.commit().get(Timeouts.DATASTORE_DELETE, TimeUnit.MILLISECONDS);
405 return OperationResult.ok(LogMessages.SUCCESSFUL_MESSAGE);
406 } catch (InterruptedException | ExecutionException | TimeoutException e) {
407 LOG.error("deleteServicePath : {}", LogMessages.failedTo("delete servicePath", serviceName), e);
408 return OperationResult.failed(LogMessages.failedTo("delete servicePath", serviceName));
413 * Write or Modify or Delete Service from/to SreviceList.
415 * @param serviceName Name of service
417 * @param input ServiceCreateInput
419 * @param output PathComputationRequestOutput
421 * @param choice 0 - Modify 1 - Delete 2 - Write
423 * @return String operations result, null if ok or not otherwise
427 public String writeOrModifyOrDeleteServiceList(
428 String serviceName, ServiceCreateInput input, PathComputationRequestOutput output, int choice) {
429 LOG.debug("WriteOrModifyOrDeleting '{}' Service", serviceName);
430 WriteTransaction writeTx = this.dataBroker.newWriteOnlyTransaction();
431 Optional<Services> readService = getService(serviceName);
435 if (readService.isEmpty()) {
437 LOG.warn("writeOrModifyOrDeleteServiceList: {}", LogMessages.SERVICE_NOT_FOUND);
438 return LogMessages.SERVICE_NOT_FOUND;
440 LOG.debug("Writing '{}' Service", serviceName);
442 LogicalDatastoreType.OPERATIONAL,
443 InstanceIdentifier.create(ServiceList.class)
444 .child(Services.class, new ServicesKey(serviceName)),
445 ModelMappingUtils.mappingServices(input, null));
447 writeTx.commit().get(Timeouts.DATASTORE_WRITE, TimeUnit.MILLISECONDS);
449 } catch (InterruptedException | TimeoutException | ExecutionException e) {
450 LOG.error("writeOrModifyOrDeleteServiceList : {}", LogMessages.failedTo(CREATE_MSG, serviceName), e);
451 return LogMessages.failedTo(CREATE_MSG, serviceName);
456 * Modify / Delete Service.
458 InstanceIdentifier<Services> iid =
459 InstanceIdentifier.create(ServiceList.class).child(Services.class, new ServicesKey(serviceName));
460 String action = null;
462 case 0 : /* Modify. */
463 LOG.debug("Modifying '{}' Service", serviceName);
465 LogicalDatastoreType.OPERATIONAL,
467 new ServicesBuilder(readService.orElseThrow())
468 .setOperationalState(State.InService)
469 .setAdministrativeState(AdminStates.InService)
471 action = "modifyService";
473 case 1 : /* Delete */
474 LOG.debug(DELETING_SERVICE_MSG, serviceName);
475 writeTx.delete(LogicalDatastoreType.OPERATIONAL, iid);
476 action = "deleteService";
479 LOG.debug("No choice found");
483 writeTx.commit().get(Timeouts.DATASTORE_WRITE, TimeUnit.MILLISECONDS);
484 } catch (InterruptedException | ExecutionException | TimeoutException e) {
485 LOG.error("writeOrModifyOrDeleteServiceList : {}", LogMessages.failedTo(action, serviceName), e);
486 return LogMessages.failedTo(action, serviceName);