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.impl;
10 import com.google.common.util.concurrent.ListenableFuture;
11 import java.time.OffsetDateTime;
12 import java.time.ZoneOffset;
13 import java.time.format.DateTimeFormatter;
14 import java.util.Optional;
15 import java.util.concurrent.ExecutionException;
16 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
17 import org.opendaylight.controller.md.sal.binding.api.ReadOnlyTransaction;
18 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
19 import org.opendaylight.transportpce.common.OperationResult;
20 import org.opendaylight.transportpce.common.ResponseCodes;
21 import org.opendaylight.transportpce.pce.service.PathComputationService;
22 import org.opendaylight.transportpce.renderer.provisiondevice.RendererServiceOperations;
23 import org.opendaylight.transportpce.servicehandler.ModelMappingUtils;
24 import org.opendaylight.transportpce.servicehandler.service.PCEServiceWrapper;
25 import org.opendaylight.transportpce.servicehandler.service.ServiceDataStoreOperations;
26 import org.opendaylight.transportpce.servicehandler.service.ServiceDataStoreOperationsImpl;
27 import org.opendaylight.transportpce.servicehandler.validation.ServiceCreateValidation;
28 import org.opendaylight.transportpce.servicehandler.validation.checks.ComplianceCheckResult;
29 import org.opendaylight.transportpce.servicehandler.validation.checks.ServicehandlerCompliancyCheck;
30 import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.pce.rev170426.PathComputationRequestOutput;
31 import org.opendaylight.yang.gen.v1.http.org.openroadm.common.service.types.rev161014.RpcActions;
32 import org.opendaylight.yang.gen.v1.http.org.openroadm.common.service.types.rev161014.sdnc.request.header.SdncRequestHeaderBuilder;
33 import org.opendaylight.yang.gen.v1.http.org.openroadm.common.types.rev161014.RpcStatus;
34 import org.opendaylight.yang.gen.v1.http.org.openroadm.common.types.rev161014.State;
35 import org.opendaylight.yang.gen.v1.http.org.openroadm.service.rev161014.EquipmentNotificationInput;
36 import org.opendaylight.yang.gen.v1.http.org.openroadm.service.rev161014.EquipmentNotificationOutput;
37 import org.opendaylight.yang.gen.v1.http.org.openroadm.service.rev161014.NetworkReOptimizationInput;
38 import org.opendaylight.yang.gen.v1.http.org.openroadm.service.rev161014.NetworkReOptimizationOutput;
39 import org.opendaylight.yang.gen.v1.http.org.openroadm.service.rev161014.OrgOpenroadmServiceService;
40 import org.opendaylight.yang.gen.v1.http.org.openroadm.service.rev161014.ServiceCreateInput;
41 import org.opendaylight.yang.gen.v1.http.org.openroadm.service.rev161014.ServiceCreateInputBuilder;
42 import org.opendaylight.yang.gen.v1.http.org.openroadm.service.rev161014.ServiceCreateOutput;
43 import org.opendaylight.yang.gen.v1.http.org.openroadm.service.rev161014.ServiceDeleteInput;
44 import org.opendaylight.yang.gen.v1.http.org.openroadm.service.rev161014.ServiceDeleteInputBuilder;
45 import org.opendaylight.yang.gen.v1.http.org.openroadm.service.rev161014.ServiceDeleteOutput;
46 import org.opendaylight.yang.gen.v1.http.org.openroadm.service.rev161014.ServiceFeasibilityCheckInput;
47 import org.opendaylight.yang.gen.v1.http.org.openroadm.service.rev161014.ServiceFeasibilityCheckOutput;
48 import org.opendaylight.yang.gen.v1.http.org.openroadm.service.rev161014.ServiceList;
49 import org.opendaylight.yang.gen.v1.http.org.openroadm.service.rev161014.ServiceReconfigureInput;
50 import org.opendaylight.yang.gen.v1.http.org.openroadm.service.rev161014.ServiceReconfigureOutput;
51 import org.opendaylight.yang.gen.v1.http.org.openroadm.service.rev161014.ServiceRerouteConfirmInput;
52 import org.opendaylight.yang.gen.v1.http.org.openroadm.service.rev161014.ServiceRerouteConfirmOutput;
53 import org.opendaylight.yang.gen.v1.http.org.openroadm.service.rev161014.ServiceRerouteInput;
54 import org.opendaylight.yang.gen.v1.http.org.openroadm.service.rev161014.ServiceRerouteOutput;
55 import org.opendaylight.yang.gen.v1.http.org.openroadm.service.rev161014.ServiceRerouteOutputBuilder;
56 import org.opendaylight.yang.gen.v1.http.org.openroadm.service.rev161014.ServiceRestorationInput;
57 import org.opendaylight.yang.gen.v1.http.org.openroadm.service.rev161014.ServiceRestorationOutput;
58 import org.opendaylight.yang.gen.v1.http.org.openroadm.service.rev161014.ServiceReversionInput;
59 import org.opendaylight.yang.gen.v1.http.org.openroadm.service.rev161014.ServiceReversionOutput;
60 import org.opendaylight.yang.gen.v1.http.org.openroadm.service.rev161014.ServiceRollInput;
61 import org.opendaylight.yang.gen.v1.http.org.openroadm.service.rev161014.ServiceRollOutput;
62 import org.opendaylight.yang.gen.v1.http.org.openroadm.service.rev161014.TempServiceCreateInput;
63 import org.opendaylight.yang.gen.v1.http.org.openroadm.service.rev161014.TempServiceCreateOutput;
64 import org.opendaylight.yang.gen.v1.http.org.openroadm.service.rev161014.TempServiceDeleteInput;
65 import org.opendaylight.yang.gen.v1.http.org.openroadm.service.rev161014.TempServiceDeleteOutput;
66 import org.opendaylight.yang.gen.v1.http.org.openroadm.service.rev161014.service.create.input.ServiceAEndBuilder;
67 import org.opendaylight.yang.gen.v1.http.org.openroadm.service.rev161014.service.create.input.ServiceZEndBuilder;
68 import org.opendaylight.yang.gen.v1.http.org.openroadm.service.rev161014.service.delete.input.ServiceDeleteReqInfo.TailRetention;
69 import org.opendaylight.yang.gen.v1.http.org.openroadm.service.rev161014.service.delete.input.ServiceDeleteReqInfoBuilder;
70 import org.opendaylight.yang.gen.v1.http.org.openroadm.service.rev161014.service.list.Services;
71 import org.opendaylight.yang.gen.v1.http.org.openroadm.service.rev161014.service.list.ServicesKey;
72 import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.servicepath.rev170426.ServiceImplementationRequestInput;
73 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.DateAndTime;
74 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
75 import org.opendaylight.yangtools.yang.common.RpcResult;
76 import org.opendaylight.yangtools.yang.common.RpcResultBuilder;
77 import org.slf4j.Logger;
78 import org.slf4j.LoggerFactory;
82 * Top level service interface providing main OpenROADM controller services.
84 public class ServicehandlerImpl implements OrgOpenroadmServiceService {
86 private static final Logger LOG = LoggerFactory.getLogger(ServicehandlerImpl.class);
88 private DataBroker db;
89 private ServiceDataStoreOperations serviceDataStoreOperations;
90 private RendererServiceOperations rendererServiceOperations;
91 private PCEServiceWrapper pceServiceWrapper;
93 //TODO: remove private request fields as they are in global scope
95 public ServicehandlerImpl(DataBroker databroker, PathComputationService pathComputationService,
96 RendererServiceOperations rendererServiceOperations) {
98 this.rendererServiceOperations = rendererServiceOperations;
99 this.serviceDataStoreOperations = new ServiceDataStoreOperationsImpl(this.db);
100 this.serviceDataStoreOperations.initialize();
101 this.pceServiceWrapper = new PCEServiceWrapper(pathComputationService);
105 public ListenableFuture<RpcResult<ServiceCreateOutput>> serviceCreate(ServiceCreateInput input) {
106 LOG.info("RPC service creation received");
108 OperationResult validationResult = ServiceCreateValidation.validateServiceCreateRequest(input);
109 if (! validationResult.isSuccess()) {
110 LOG.warn("Aborting service create because validation of service create request failed: {}",
111 validationResult.getResultMessage());
112 return ModelMappingUtils.createCreateServiceReply(input, ResponseCodes.FINAL_ACK_YES,
113 validationResult.getResultMessage(), ResponseCodes.RESPONSE_FAILED);
116 // Starting service create operation
117 LOG.info("Commencing PCE");
118 //TODO: createService service status into datastore
119 PathComputationRequestOutput pceResponse = this.pceServiceWrapper.performPCE(input, true);
120 String pceResponseCode = pceResponse.getConfigurationResponseCommon().getResponseCode();
121 if (!ResponseCodes.RESPONSE_OK.equals(pceResponseCode)) {
122 LOG.info("PCE calculation failed {}", pceResponseCode);
123 return ModelMappingUtils.createCreateServiceReply(input, ResponseCodes.FINAL_ACK_YES,
124 pceResponse.getConfigurationResponseCommon().getResponseMessage(), ResponseCodes.RESPONSE_FAILED);
127 LOG.info("PCE calculation done OK {}", pceResponseCode);
129 OperationResult operationResult = this.serviceDataStoreOperations.createService(input, pceResponse);
130 if (!operationResult.isSuccess()) {
131 String message = "Service status not updated in datastore !";
133 return ModelMappingUtils.createCreateServiceReply(input, ResponseCodes.FINAL_ACK_YES, message,
134 ResponseCodes.RESPONSE_FAILED);
137 OperationResult operationServicePathSaveResult = this.serviceDataStoreOperations.createServicePath(input,
139 if (!operationServicePathSaveResult.isSuccess()) {
140 String message = "Service Path not updated in datastore !";
142 return ModelMappingUtils.createCreateServiceReply(input, ResponseCodes.FINAL_ACK_YES, message,
143 ResponseCodes.RESPONSE_FAILED);
146 ServiceImplementationRequestInput serviceImplementationRequest =
147 ModelMappingUtils.createServiceImplementationRequest(input, pceResponse);
148 org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.servicepath.rev170426
149 .ServiceImplementationRequestOutput serviceImplementationRequestOutput = this.rendererServiceOperations
150 .serviceImplementation(serviceImplementationRequest);
151 if (ResponseCodes.RESPONSE_OK
152 .equals(serviceImplementationRequestOutput.getConfigurationResponseCommon().getResponseCode())) {
153 String message = "Service rendered successfully !";
155 operationResult = this.serviceDataStoreOperations.modifyService(input.getServiceName(), State.InService,
157 if (!operationResult.isSuccess()) {
158 LOG.warn("Service status not updated in datastore !");
160 return ModelMappingUtils.createCreateServiceReply(input, ResponseCodes.FINAL_ACK_YES, message,
161 ResponseCodes.RESPONSE_OK);
163 String message = "Service rendering has failed !";
166 OperationResult deleteServicePathOperationResult =
167 this.serviceDataStoreOperations.deleteServicePath(input.getServiceName());
168 if (!deleteServicePathOperationResult.isSuccess()) {
169 LOG.warn("Service path was not removed from datastore!");
172 OperationResult deleteServiceOperationResult =
173 this.serviceDataStoreOperations.deleteService(input.getServiceName());
174 if (!deleteServiceOperationResult.isSuccess()) {
175 LOG.warn("Service was not removed from datastore!");
178 return ModelMappingUtils.createCreateServiceReply(input, ResponseCodes.FINAL_ACK_YES, message,
179 ResponseCodes.RESPONSE_FAILED);
184 public ListenableFuture<RpcResult<ServiceDeleteOutput>> serviceDelete(ServiceDeleteInput input) {
185 LOG.info("RPC serviceDelete request received for {}", input.getServiceDeleteReqInfo().getServiceName());
189 * Upon receipt of service-deleteService RPC, service header and sdnc-request
190 * header compliancy are verified.
192 LOG.info("checking Service Compliancy ...");
193 ComplianceCheckResult serviceHandlerCheckResult = ServicehandlerCompliancyCheck.check(
194 input.getServiceDeleteReqInfo().getServiceName(),
195 input.getSdncRequestHeader(), null, RpcActions.ServiceDelete, false, true);
196 if (serviceHandlerCheckResult.hasPassed()) {
197 LOG.info("Service compliant !");
199 LOG.info("Service is not compliant !");
200 return ModelMappingUtils
201 .createDeleteServiceReply(input, ResponseCodes.FINAL_ACK_YES,
202 "Service not compliant !", ResponseCodes.RESPONSE_FAILED);
205 //Check presence of service to be deleted
206 String serviceName = input.getServiceDeleteReqInfo().getServiceName();
207 Optional<Services> service = this.serviceDataStoreOperations.getService(serviceName);
208 if (!service.isPresent()) {
209 message = "Service '" + serviceName + "' does not exist in datastore";
211 return ModelMappingUtils.createDeleteServiceReply(input, ResponseCodes.FINAL_ACK_YES,
212 message, ResponseCodes.RESPONSE_FAILED);
215 LOG.debug("Service '{}' present in datastore !", serviceName);
216 org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.servicepath.rev170426.ServiceDeleteInput
217 serviceDeleteInput = ModelMappingUtils.createServiceDeleteInput(input);
218 org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.servicepath.rev170426
219 .ServiceDeleteOutput output = this.rendererServiceOperations.serviceDelete(serviceDeleteInput);
221 if (!ResponseCodes.RESPONSE_OK
222 .equals(output.getConfigurationResponseCommon().getResponseCode())) {
223 message = "Service delete failed!";
224 return ModelMappingUtils.createDeleteServiceReply(input, ResponseCodes.FINAL_ACK_YES, message,
225 ResponseCodes.RESPONSE_FAILED);
228 OperationResult deleteServicePathOperationResult =
229 this.serviceDataStoreOperations.deleteServicePath(input.getServiceDeleteReqInfo().getServiceName());
230 if (!deleteServicePathOperationResult.isSuccess()) {
231 LOG.warn("Service path was not removed from datastore!");
234 OperationResult deleteServiceOperationResult =
235 this.serviceDataStoreOperations.deleteService(input.getServiceDeleteReqInfo().getServiceName());
236 if (!deleteServiceOperationResult.isSuccess()) {
237 LOG.warn("Service was not removed from datastore!");
240 return ModelMappingUtils.createDeleteServiceReply(input, ResponseCodes.FINAL_ACK_YES,
241 "Service delete was successful!", ResponseCodes.RESPONSE_OK);
245 public ListenableFuture<RpcResult<ServiceFeasibilityCheckOutput>> serviceFeasibilityCheck(
246 ServiceFeasibilityCheckInput input) {
247 throw new UnsupportedOperationException("Not implemented yet");
251 public ListenableFuture<RpcResult<ServiceReconfigureOutput>> serviceReconfigure(ServiceReconfigureInput input) {
252 throw new UnsupportedOperationException("Not implemented yet");
256 public ListenableFuture<RpcResult<ServiceRestorationOutput>> serviceRestoration(ServiceRestorationInput input) {
257 throw new UnsupportedOperationException("Not implemented yet");
261 public ListenableFuture<RpcResult<EquipmentNotificationOutput>> equipmentNotification(EquipmentNotificationInput input) {
262 // TODO Auto-generated method stub
267 public ListenableFuture<RpcResult<ServiceRerouteConfirmOutput>> serviceRerouteConfirm(ServiceRerouteConfirmInput input) {
268 // TODO Auto-generated method stub
273 public ListenableFuture<RpcResult<ServiceRerouteOutput>> serviceReroute(ServiceRerouteInput input) {
274 InstanceIdentifier<Services> servicesIID = InstanceIdentifier.create(ServiceList.class)
275 .child(Services.class, new ServicesKey(input.getServiceName()));
276 ReadOnlyTransaction rtx = this.db.newReadOnlyTransaction();
277 Optional<Services> servicesObject;
279 servicesObject = rtx.read(LogicalDatastoreType.OPERATIONAL, servicesIID).get().toJavaUtil();
280 if (servicesObject.isPresent()) {
281 ServiceDeleteInputBuilder deleteInputBldr = new ServiceDeleteInputBuilder();
282 DateTimeFormatter dtf = DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ssxxx");
283 OffsetDateTime offsetDateTime = OffsetDateTime.now(ZoneOffset.UTC);
284 DateAndTime datetime = new DateAndTime(dtf.format(offsetDateTime));
285 deleteInputBldr.setServiceDeleteReqInfo(new ServiceDeleteReqInfoBuilder()
286 .setServiceName(input.getServiceName()).setDueDate(datetime)
287 .setTailRetention(TailRetention.No).build());
288 SdncRequestHeaderBuilder sdncBuilder = new SdncRequestHeaderBuilder();
289 sdncBuilder.setNotificationUrl(servicesObject.get().getSdncRequestHeader().getNotificationUrl());
290 sdncBuilder.setRequestId(servicesObject.get().getSdncRequestHeader().getRequestId());
291 sdncBuilder.setRequestSystemId(servicesObject.get().getSdncRequestHeader().getRequestSystemId());
292 sdncBuilder.setRpcAction(RpcActions.ServiceDelete);
293 deleteInputBldr.setSdncRequestHeader(sdncBuilder.build());
294 // Calling delete service
295 serviceDelete(deleteInputBldr.build());
296 // Calling create request now
297 ServiceCreateInputBuilder serviceCreateBldr = new ServiceCreateInputBuilder();
298 serviceCreateBldr.setServiceName(input.getServiceName() + 2);
299 serviceCreateBldr.setCommonId(servicesObject.get().getCommonId());
300 serviceCreateBldr.setConnectionType(servicesObject.get().getConnectionType());
301 serviceCreateBldr.setCustomer(servicesObject.get().getCustomer());
302 serviceCreateBldr.setCustomerContact(servicesObject.get().getCustomerContact());
303 serviceCreateBldr.setDueDate(servicesObject.get().getDueDate());
304 serviceCreateBldr.setEndDate(servicesObject.get().getEndDate());
305 serviceCreateBldr.setHardConstraints(servicesObject.get().getHardConstraints());
306 serviceCreateBldr.setNcCode(servicesObject.get().getNcCode());
307 serviceCreateBldr.setNciCode(servicesObject.get().getNciCode());
308 serviceCreateBldr.setOperatorContact(servicesObject.get().getOperatorContact());
309 serviceCreateBldr.setSdncRequestHeader(servicesObject.get().getSdncRequestHeader());
310 serviceCreateBldr.setSecondaryNciCode(servicesObject.get().getSecondaryNciCode());
311 ServiceAEndBuilder serviceAendBuilder = new ServiceAEndBuilder(servicesObject.get().getServiceAEnd());
312 serviceCreateBldr.setServiceAEnd(serviceAendBuilder.build());
313 ServiceZEndBuilder serviceZendBuilder = new ServiceZEndBuilder(servicesObject.get().getServiceZEnd());
314 serviceCreateBldr.setServiceZEnd(serviceZendBuilder.build());
315 serviceCreateBldr.setSoftConstraints(servicesObject.get().getSoftConstraints());
316 serviceCreate(serviceCreateBldr.build());
317 ServiceRerouteOutputBuilder output = new ServiceRerouteOutputBuilder()
318 .setHardConstraints(null).setSoftConstraints(null).setStatus(
319 org.opendaylight.yang.gen.v1.http.org.openroadm.common.types.rev161014.RpcStatus.Successful)
320 .setStatusMessage("Success");
321 return RpcResultBuilder.success(output).buildFuture();
323 } catch (InterruptedException | ExecutionException e) {
324 LOG.info("Exception caught" , e);
326 ServiceRerouteOutputBuilder output = new ServiceRerouteOutputBuilder()
327 .setHardConstraints(null).setSoftConstraints(null).setStatus(RpcStatus.Failed).setStatusMessage("Failure");
329 return RpcResultBuilder.success(output).buildFuture();
333 public ListenableFuture<RpcResult<ServiceReversionOutput>> serviceReversion(ServiceReversionInput input) {
334 // TODO Auto-generated method stub
339 public ListenableFuture<RpcResult<ServiceRollOutput>> serviceRoll(ServiceRollInput input) {
340 // TODO Auto-generated method stub
345 public ListenableFuture<RpcResult<NetworkReOptimizationOutput>> networkReOptimization(NetworkReOptimizationInput input) {
346 // TODO Auto-generated method stub
351 public ListenableFuture<RpcResult<TempServiceDeleteOutput>> tempServiceDelete(TempServiceDeleteInput input) {
352 // TODO Auto-generated method stub
357 public ListenableFuture<RpcResult<TempServiceCreateOutput>> tempServiceCreate(TempServiceCreateInput input) {
358 // TODO Auto-generated method stub