bd8897c65e6d9593de83f8a67cf43707b48da998
[transportpce.git] / servicehandler / src / main / java / org / opendaylight / transportpce / servicehandler / impl / ServicehandlerImpl.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.impl;
9
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 org.opendaylight.mdsal.binding.api.DataBroker;
16 import org.opendaylight.mdsal.binding.api.NotificationPublishService;
17 import org.opendaylight.transportpce.common.OperationResult;
18 import org.opendaylight.transportpce.common.ResponseCodes;
19 import org.opendaylight.transportpce.pce.service.PathComputationService;
20 import org.opendaylight.transportpce.renderer.provisiondevice.RendererServiceOperations;
21 import org.opendaylight.transportpce.servicehandler.DowngradeConstraints;
22 import org.opendaylight.transportpce.servicehandler.ModelMappingUtils;
23 import org.opendaylight.transportpce.servicehandler.ServiceInput;
24 import org.opendaylight.transportpce.servicehandler.listeners.NetworkModelListenerImpl;
25 import org.opendaylight.transportpce.servicehandler.listeners.PceListenerImpl;
26 import org.opendaylight.transportpce.servicehandler.listeners.RendererListenerImpl;
27 import org.opendaylight.transportpce.servicehandler.service.PCEServiceWrapper;
28 import org.opendaylight.transportpce.servicehandler.service.RendererServiceWrapper;
29 import org.opendaylight.transportpce.servicehandler.service.ServiceDataStoreOperations;
30 import org.opendaylight.transportpce.servicehandler.validation.ServiceCreateValidation;
31 import org.opendaylight.transportpce.servicehandler.validation.checks.ComplianceCheckResult;
32 import org.opendaylight.transportpce.servicehandler.validation.checks.ServicehandlerComplianceCheck;
33 import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.pce.rev200128.PathComputationRequestOutput;
34 import org.opendaylight.yang.gen.v1.http.org.openroadm.common.service.types.rev190531.RpcActions;
35 import org.opendaylight.yang.gen.v1.http.org.openroadm.common.service.types.rev190531.ServiceNotificationTypes;
36 import org.opendaylight.yang.gen.v1.http.org.openroadm.common.service.types.rev190531.configuration.response.common.ConfigurationResponseCommon;
37 import org.opendaylight.yang.gen.v1.http.org.openroadm.common.service.types.rev190531.sdnc.request.header.SdncRequestHeaderBuilder;
38 import org.opendaylight.yang.gen.v1.http.org.openroadm.common.state.types.rev181130.State;
39 import org.opendaylight.yang.gen.v1.http.org.openroadm.common.types.rev190531.RpcStatus;
40 import org.opendaylight.yang.gen.v1.http.org.openroadm.routing.constrains.rev190329.routing.constraints.HardConstraints;
41 import org.opendaylight.yang.gen.v1.http.org.openroadm.routing.constrains.rev190329.routing.constraints.SoftConstraints;
42 import org.opendaylight.yang.gen.v1.http.org.openroadm.service.rev190531.EquipmentNotificationInput;
43 import org.opendaylight.yang.gen.v1.http.org.openroadm.service.rev190531.EquipmentNotificationOutput;
44 import org.opendaylight.yang.gen.v1.http.org.openroadm.service.rev190531.NetworkReOptimizationInput;
45 import org.opendaylight.yang.gen.v1.http.org.openroadm.service.rev190531.NetworkReOptimizationOutput;
46 import org.opendaylight.yang.gen.v1.http.org.openroadm.service.rev190531.OrgOpenroadmServiceService;
47 import org.opendaylight.yang.gen.v1.http.org.openroadm.service.rev190531.ServiceCreateComplexResultNotificationRequestInput;
48 import org.opendaylight.yang.gen.v1.http.org.openroadm.service.rev190531.ServiceCreateComplexResultNotificationRequestOutput;
49 import org.opendaylight.yang.gen.v1.http.org.openroadm.service.rev190531.ServiceCreateInput;
50 import org.opendaylight.yang.gen.v1.http.org.openroadm.service.rev190531.ServiceCreateOutput;
51 import org.opendaylight.yang.gen.v1.http.org.openroadm.service.rev190531.ServiceCreateResultNotificationRequestInput;
52 import org.opendaylight.yang.gen.v1.http.org.openroadm.service.rev190531.ServiceCreateResultNotificationRequestOutput;
53 import org.opendaylight.yang.gen.v1.http.org.openroadm.service.rev190531.ServiceDeleteComplexResultNotificationRequestInput;
54 import org.opendaylight.yang.gen.v1.http.org.openroadm.service.rev190531.ServiceDeleteComplexResultNotificationRequestOutput;
55 import org.opendaylight.yang.gen.v1.http.org.openroadm.service.rev190531.ServiceDeleteInput;
56 import org.opendaylight.yang.gen.v1.http.org.openroadm.service.rev190531.ServiceDeleteInputBuilder;
57 import org.opendaylight.yang.gen.v1.http.org.openroadm.service.rev190531.ServiceDeleteOutput;
58 import org.opendaylight.yang.gen.v1.http.org.openroadm.service.rev190531.ServiceDeleteResultNotificationRequestInput;
59 import org.opendaylight.yang.gen.v1.http.org.openroadm.service.rev190531.ServiceDeleteResultNotificationRequestOutput;
60 import org.opendaylight.yang.gen.v1.http.org.openroadm.service.rev190531.ServiceFeasibilityCheckBulkInput;
61 import org.opendaylight.yang.gen.v1.http.org.openroadm.service.rev190531.ServiceFeasibilityCheckBulkOutput;
62 import org.opendaylight.yang.gen.v1.http.org.openroadm.service.rev190531.ServiceFeasibilityCheckInput;
63 import org.opendaylight.yang.gen.v1.http.org.openroadm.service.rev190531.ServiceFeasibilityCheckOutput;
64 import org.opendaylight.yang.gen.v1.http.org.openroadm.service.rev190531.ServiceReconfigureInput;
65 import org.opendaylight.yang.gen.v1.http.org.openroadm.service.rev190531.ServiceReconfigureOutput;
66 import org.opendaylight.yang.gen.v1.http.org.openroadm.service.rev190531.ServiceRerouteConfirmInput;
67 import org.opendaylight.yang.gen.v1.http.org.openroadm.service.rev190531.ServiceRerouteConfirmOutput;
68 import org.opendaylight.yang.gen.v1.http.org.openroadm.service.rev190531.ServiceRerouteInput;
69 import org.opendaylight.yang.gen.v1.http.org.openroadm.service.rev190531.ServiceRerouteOutput;
70 import org.opendaylight.yang.gen.v1.http.org.openroadm.service.rev190531.ServiceRestorationInput;
71 import org.opendaylight.yang.gen.v1.http.org.openroadm.service.rev190531.ServiceRestorationOutput;
72 import org.opendaylight.yang.gen.v1.http.org.openroadm.service.rev190531.ServiceReversionInput;
73 import org.opendaylight.yang.gen.v1.http.org.openroadm.service.rev190531.ServiceReversionOutput;
74 import org.opendaylight.yang.gen.v1.http.org.openroadm.service.rev190531.ServiceRollInput;
75 import org.opendaylight.yang.gen.v1.http.org.openroadm.service.rev190531.ServiceRollOutput;
76 import org.opendaylight.yang.gen.v1.http.org.openroadm.service.rev190531.TempServiceCreateInput;
77 import org.opendaylight.yang.gen.v1.http.org.openroadm.service.rev190531.TempServiceCreateOutput;
78 import org.opendaylight.yang.gen.v1.http.org.openroadm.service.rev190531.TempServiceDeleteInput;
79 import org.opendaylight.yang.gen.v1.http.org.openroadm.service.rev190531.TempServiceDeleteOutput;
80 import org.opendaylight.yang.gen.v1.http.org.openroadm.service.rev190531.service.delete.input.ServiceDeleteReqInfo.TailRetention;
81 import org.opendaylight.yang.gen.v1.http.org.openroadm.service.rev190531.service.delete.input.ServiceDeleteReqInfoBuilder;
82 import org.opendaylight.yang.gen.v1.http.org.openroadm.service.rev190531.service.list.Services;
83 import org.opendaylight.yang.gen.v1.nbi.notifications.rev201130.PublishNotificationService;
84 import org.opendaylight.yang.gen.v1.nbi.notifications.rev201130.PublishNotificationServiceBuilder;
85 import org.opendaylight.yang.gen.v1.nbi.notifications.rev201130.notification.service.ServiceAEndBuilder;
86 import org.opendaylight.yang.gen.v1.nbi.notifications.rev201130.notification.service.ServiceZEndBuilder;
87 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.DateAndTime;
88 import org.opendaylight.yangtools.yang.common.RpcResult;
89 import org.slf4j.Logger;
90 import org.slf4j.LoggerFactory;
91
92
93 /**
94  * Top level service interface providing main OpenROADM controller services.
95  */
96 public class ServicehandlerImpl implements OrgOpenroadmServiceService {
97     private static final Logger LOG = LoggerFactory.getLogger(ServicehandlerImpl.class);
98     private static final String TEMP_SERVICE_CREATE_MSG = "tempServiceCreate: {}";
99     private static final String TEMP_SERVICE_DELETE_MSG = "tempServiceDelete: {}";
100     private static final String SERVICE_RESTORATION_MSG = "serviceRestoration: {}";
101     private static final String SERVICE_RECONFIGURE_MSG = "serviceReconfigure: {}";
102     private static final String SERVICE_FEASABILITY_CHECK_MSG = "serviceFeasabilityCheck: {}";
103     private static final String SERVICE_DELETE_MSG = "serviceDelete: {}";
104     private static final String SERVICE_CREATE_MSG = "serviceCreate: {}";
105
106     private DataBroker db;
107     private ServiceDataStoreOperations serviceDataStoreOperations;
108     private PCEServiceWrapper pceServiceWrapper;
109     private RendererServiceWrapper rendererServiceWrapper;
110     private PceListenerImpl pceListenerImpl;
111     private RendererListenerImpl rendererListenerImpl;
112     private NetworkModelListenerImpl networkModelListenerImpl;
113     private NotificationPublishService notificationPublishService;
114     private final String topic;
115
116     //TODO: remove private request fields as they are in global scope
117
118     public ServicehandlerImpl(DataBroker databroker, PathComputationService pathComputationService,
119             RendererServiceOperations rendererServiceOperations, NotificationPublishService notificationPublishService,
120             PceListenerImpl pceListenerImpl, RendererListenerImpl rendererListenerImpl,
121             NetworkModelListenerImpl networkModelListenerImpl, ServiceDataStoreOperations serviceDataStoreOperations,
122             String topic) {
123         this.db = databroker;
124         this.serviceDataStoreOperations = serviceDataStoreOperations;
125         this.pceServiceWrapper = new PCEServiceWrapper(pathComputationService, notificationPublishService);
126         this.rendererServiceWrapper = new RendererServiceWrapper(rendererServiceOperations, notificationPublishService);
127         this.pceListenerImpl = pceListenerImpl;
128         this.rendererListenerImpl = rendererListenerImpl;
129         this.networkModelListenerImpl = networkModelListenerImpl;
130         this.notificationPublishService =  notificationPublishService;
131         this.topic = topic;
132     }
133
134
135     // This is class is public so that these messages can be accessed from Junit (avoid duplications).
136     public static final class LogMessages {
137
138         public static final String PCE_CALLING;
139         public static final String ABORT_PCE_FAILED;
140         public static final String PCE_FAILED;
141         public static final String ABORT_SERVICE_NON_COMPLIANT;
142         public static final String SERVICE_NON_COMPLIANT;
143         public static final String RENDERER_DELETE_FAILED;
144         public static final String ABORT_VALID_FAILED;
145
146         // Static blocks are generated once and spare memory.
147         static {
148             PCE_CALLING = "Calling PCE";
149             ABORT_PCE_FAILED = "Aborting: PCE calculation failed ";
150             PCE_FAILED = "PCE calculation failed";
151             ABORT_SERVICE_NON_COMPLIANT = "Aborting: non-compliant service ";
152             SERVICE_NON_COMPLIANT = "non-compliant service";
153             RENDERER_DELETE_FAILED = "Renderer service delete failed";
154             ABORT_VALID_FAILED = "Aborting: validation of service create request failed";
155         }
156
157         public static String serviceNotInDS(String serviceName) {
158             return "Service '" + serviceName + "' does not exist in datastore";
159         }
160
161         public static String serviceInService(String serviceName) {
162             return "Service '" + serviceName + "' is in 'inService' state";
163         }
164
165         private LogMessages() {
166         }
167     }
168
169     @Override
170     public ListenableFuture<RpcResult<ServiceCreateOutput>> serviceCreate(ServiceCreateInput input) {
171         LOG.info("RPC serviceCreate received");
172         // Validation
173         OperationResult validationResult = ServiceCreateValidation.validateServiceCreateRequest(
174                 new ServiceInput(input), RpcActions.ServiceCreate);
175         if (! validationResult.isSuccess()) {
176             LOG.warn(SERVICE_CREATE_MSG, LogMessages.ABORT_VALID_FAILED);
177             return ModelMappingUtils.createCreateServiceReply(
178                     input, ResponseCodes.FINAL_ACK_YES,
179                     validationResult.getResultMessage(), ResponseCodes.RESPONSE_FAILED);
180         }
181         this.pceListenerImpl.setInput(new ServiceInput(input));
182         this.pceListenerImpl.setServiceReconfigure(false);
183         this.pceListenerImpl.setserviceDataStoreOperations(this.serviceDataStoreOperations);
184         this.rendererListenerImpl.setserviceDataStoreOperations(serviceDataStoreOperations);
185         this.rendererListenerImpl.setServiceInput(new ServiceInput(input));
186         this.networkModelListenerImpl.setserviceDataStoreOperations(serviceDataStoreOperations);
187         LOG.debug(SERVICE_CREATE_MSG, LogMessages.PCE_CALLING);
188         PathComputationRequestOutput output = this.pceServiceWrapper.performPCE(input, true);
189         if (output == null) {
190             LOG.warn(SERVICE_CREATE_MSG, LogMessages.ABORT_PCE_FAILED);
191             sendNbiNotification(new PublishNotificationServiceBuilder()
192                     .setServiceName(input.getServiceName())
193                     .setServiceAEnd(new ServiceAEndBuilder(input.getServiceAEnd()).build())
194                     .setServiceZEnd(new ServiceZEndBuilder(input.getServiceZEnd()).build())
195                     .setCommonId(input.getCommonId()).setConnectionType(input.getConnectionType())
196                     .setResponseFailed(LogMessages.ABORT_PCE_FAILED)
197                     .setMessage("ServiceCreate request failed ...")
198                     .setOperationalState(State.Degraded)
199                     .build());
200             return ModelMappingUtils.createCreateServiceReply(input, ResponseCodes.FINAL_ACK_YES,
201                     LogMessages.PCE_FAILED, ResponseCodes.RESPONSE_FAILED);
202         }
203         LOG.info("RPC serviceCreate in progress...");
204         ConfigurationResponseCommon common = output.getConfigurationResponseCommon();
205         return ModelMappingUtils.createCreateServiceReply(
206                 input, common.getAckFinalIndicator(),
207                 common.getResponseMessage(), common.getResponseCode());
208     }
209
210     @Override
211     public ListenableFuture<RpcResult<ServiceDeleteOutput>> serviceDelete(ServiceDeleteInput input) {
212         String serviceName = input.getServiceDeleteReqInfo().getServiceName();
213         LOG.info("RPC serviceDelete request received for {}", serviceName);
214
215         /*
216          * Upon receipt of service-deleteService RPC, service header and sdnc-request
217          * header compliance are verified.
218          */
219         ComplianceCheckResult serviceHandlerCheckResult =
220             ServicehandlerComplianceCheck.check(
221                 input.getServiceDeleteReqInfo().getServiceName(),
222                 input.getSdncRequestHeader(), null, RpcActions.ServiceDelete, false, true);
223         if (!serviceHandlerCheckResult.hasPassed()) {
224             LOG.warn(SERVICE_DELETE_MSG, LogMessages.ABORT_SERVICE_NON_COMPLIANT);
225             return ModelMappingUtils.createDeleteServiceReply(
226                     input, ResponseCodes.FINAL_ACK_YES,
227                     LogMessages.SERVICE_NON_COMPLIANT, ResponseCodes.RESPONSE_FAILED);
228         }
229
230         //Check presence of service to be deleted
231         Optional<Services> serviceOpt = this.serviceDataStoreOperations.getService(serviceName);
232         Services service;
233         if (!serviceOpt.isPresent()) {
234             LOG.warn(SERVICE_DELETE_MSG, LogMessages.serviceNotInDS(serviceName));
235             return ModelMappingUtils.createDeleteServiceReply(
236                     input, ResponseCodes.FINAL_ACK_YES,
237                     LogMessages.serviceNotInDS(serviceName), ResponseCodes.RESPONSE_FAILED);
238         }
239         service = serviceOpt.get();
240         LOG.debug("serviceDelete: Service '{}' found in datastore", serviceName);
241         this.pceListenerImpl.setInput(new ServiceInput(input));
242         this.pceListenerImpl.setServiceReconfigure(false);
243         this.pceListenerImpl.setserviceDataStoreOperations(this.serviceDataStoreOperations);
244         this.rendererListenerImpl.setserviceDataStoreOperations(serviceDataStoreOperations);
245         this.rendererListenerImpl.setServiceInput(new ServiceInput(input));
246         this.networkModelListenerImpl.setserviceDataStoreOperations(serviceDataStoreOperations);
247         org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.renderer.rev201125
248                 .ServiceDeleteInput serviceDeleteInput =
249             ModelMappingUtils.createServiceDeleteInput(new ServiceInput(input));
250         org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.renderer.rev201125.ServiceDeleteOutput output =
251             this.rendererServiceWrapper.performRenderer(
252                 serviceDeleteInput, ServiceNotificationTypes.ServiceDeleteResult, service);
253
254         if (output == null) {
255             LOG.error(SERVICE_DELETE_MSG, LogMessages.RENDERER_DELETE_FAILED);
256             sendNbiNotification(new PublishNotificationServiceBuilder()
257                     .setServiceName(service.getServiceName())
258                     .setServiceAEnd(new ServiceAEndBuilder(service.getServiceAEnd()).build())
259                     .setServiceZEnd(new ServiceZEndBuilder(service.getServiceZEnd()).build())
260                     .setCommonId(service.getCommonId()).setConnectionType(service.getConnectionType())
261                     .setMessage("ServiceDelete request failed ...")
262                     .setOperationalState(State.InService)
263                     .setResponseFailed(LogMessages.RENDERER_DELETE_FAILED)
264                     .build());
265             return ModelMappingUtils.createDeleteServiceReply(
266                     input, ResponseCodes.FINAL_ACK_YES,
267                     LogMessages.RENDERER_DELETE_FAILED, ResponseCodes.RESPONSE_FAILED);
268         }
269
270         LOG.debug("RPC serviceDelete in progress...");
271         ConfigurationResponseCommon common = output.getConfigurationResponseCommon();
272         return ModelMappingUtils.createDeleteServiceReply(
273                 input, common.getAckFinalIndicator(),
274                 common.getResponseMessage(), common.getResponseCode());
275     }
276
277     @Override
278     public ListenableFuture<RpcResult<ServiceFeasibilityCheckOutput>> serviceFeasibilityCheck(
279             ServiceFeasibilityCheckInput input) {
280         LOG.info("RPC serviceFeasibilityCheck received");
281         // Validation
282         ServiceInput serviceInput = new ServiceInput(input);
283         OperationResult validationResult = ServiceCreateValidation.validateServiceCreateRequest(serviceInput,
284                 RpcActions.ServiceFeasibilityCheck);
285         if (! validationResult.isSuccess()) {
286             LOG.warn(SERVICE_FEASABILITY_CHECK_MSG, LogMessages.ABORT_VALID_FAILED);
287             return ModelMappingUtils.createCreateServiceReply(
288                     input, ResponseCodes.FINAL_ACK_YES,
289                     validationResult.getResultMessage(), ResponseCodes.RESPONSE_FAILED);
290         }
291         this.pceListenerImpl.setInput(new ServiceInput(input));
292         this.pceListenerImpl.setServiceReconfigure(false);
293         this.pceListenerImpl.setServiceFeasiblity(true);
294         this.pceListenerImpl.setserviceDataStoreOperations(this.serviceDataStoreOperations);
295         this.rendererListenerImpl.setserviceDataStoreOperations(serviceDataStoreOperations);
296         this.rendererListenerImpl.setServiceInput(new ServiceInput(input));
297         this.networkModelListenerImpl.setserviceDataStoreOperations(serviceDataStoreOperations);
298         LOG.debug(SERVICE_FEASABILITY_CHECK_MSG, LogMessages.PCE_CALLING);
299         PathComputationRequestOutput output = this.pceServiceWrapper.performPCE(input, true);
300         if (output == null) {
301             LOG.warn(SERVICE_FEASABILITY_CHECK_MSG, LogMessages.ABORT_PCE_FAILED);
302             return ModelMappingUtils.createCreateServiceReply(input, ResponseCodes.FINAL_ACK_YES,
303                     LogMessages.PCE_FAILED, ResponseCodes.RESPONSE_FAILED);
304         }
305         LOG.info("RPC serviceFeasibilityCheck in progress...");
306         ConfigurationResponseCommon common = output.getConfigurationResponseCommon();
307         return ModelMappingUtils.createCreateServiceReply(
308                 input, common.getAckFinalIndicator(),
309                 common.getResponseMessage(), common.getResponseCode());
310     }
311
312     @Override
313     public ListenableFuture<RpcResult<ServiceReconfigureOutput>> serviceReconfigure(ServiceReconfigureInput input) {
314         String serviceName = input.getServiceName();
315         LOG.info("RPC serviceReconfigure received for {}", serviceName);
316         Optional<Services> servicesObject = this.serviceDataStoreOperations.getService(serviceName);
317         if (!servicesObject.isPresent()) {
318             LOG.warn(SERVICE_RECONFIGURE_MSG, LogMessages.serviceNotInDS(serviceName));
319             return ModelMappingUtils.createCreateServiceReply(
320                 input,
321                 LogMessages.serviceNotInDS(serviceName), RpcStatus.Failed);
322         }
323         LOG.debug("Service '{}' found in datastore", serviceName);
324         OperationResult validationResult = ServiceCreateValidation
325                 .validateServiceCreateRequest(new ServiceInput(input), RpcActions.ServiceReconfigure);
326         if (!validationResult.isSuccess()) {
327             LOG.warn(SERVICE_RECONFIGURE_MSG, LogMessages.ABORT_VALID_FAILED);
328             return ModelMappingUtils.createCreateServiceReply(
329                     input,
330                     validationResult.getResultMessage(), RpcStatus.Failed);
331         }
332         this.pceListenerImpl.setInput(new ServiceInput(input));
333         this.pceListenerImpl.setServiceReconfigure(true);
334         this.pceListenerImpl.setserviceDataStoreOperations(this.serviceDataStoreOperations);
335         this.rendererListenerImpl.setserviceDataStoreOperations(serviceDataStoreOperations);
336         this.rendererListenerImpl.setServiceInput(new ServiceInput(input));
337         this.networkModelListenerImpl.setserviceDataStoreOperations(serviceDataStoreOperations);
338         org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.renderer.rev201125
339                 .ServiceDeleteInput serviceDeleteInput =
340                         ModelMappingUtils.createServiceDeleteInput(new ServiceInput(input));
341         org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.renderer.rev201125
342                 .ServiceDeleteOutput output = this.rendererServiceWrapper.performRenderer(serviceDeleteInput,
343                         ServiceNotificationTypes.ServiceDeleteResult, null);
344         if (output == null) {
345             LOG.error(SERVICE_RECONFIGURE_MSG, LogMessages.RENDERER_DELETE_FAILED);
346             return ModelMappingUtils.createCreateServiceReply(
347                     input,
348                     LogMessages.RENDERER_DELETE_FAILED, RpcStatus.Successful);
349                     //TODO check if RpcStatus.Successful is really expected here
350         }
351         LOG.info("RPC serviceReconfigure in progress...");
352         ConfigurationResponseCommon common = output.getConfigurationResponseCommon();
353         return ModelMappingUtils.createCreateServiceReply(
354                 input,
355                 common.getResponseMessage(), RpcStatus.Successful);
356     }
357
358     @Override
359     public ListenableFuture<RpcResult<ServiceRestorationOutput>> serviceRestoration(ServiceRestorationInput input) {
360         String serviceName = input.getServiceName();
361         LOG.info("RPC serviceRestoration received for {}", serviceName);
362         Optional<Services> servicesObject = this.serviceDataStoreOperations.getService(serviceName);
363
364         if (!servicesObject.isPresent()) {
365             LOG.warn(SERVICE_RESTORATION_MSG, LogMessages.serviceNotInDS(serviceName));
366             return ModelMappingUtils.createRestoreServiceReply(
367                     LogMessages.serviceNotInDS(serviceName), RpcStatus.Failed);
368         }
369
370         Services service = servicesObject.get();
371         State state = service.getOperationalState();
372
373         if (state == State.InService) {
374             LOG.error(SERVICE_RESTORATION_MSG, LogMessages.serviceInService(serviceName));
375             return ModelMappingUtils.createRestoreServiceReply(
376                     LogMessages.serviceInService(serviceName), RpcStatus.Failed);
377         }
378
379         DateTimeFormatter dtf = DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ssxxx");
380         OffsetDateTime offsetDateTime = OffsetDateTime.now(ZoneOffset.UTC);
381         DateAndTime datetime = new DateAndTime(dtf.format(offsetDateTime));
382         SdncRequestHeaderBuilder sdncBuilder = new SdncRequestHeaderBuilder()
383                 .setNotificationUrl(service.getSdncRequestHeader().getNotificationUrl())
384                 .setRequestId(service.getSdncRequestHeader().getRequestId())
385                 .setRequestSystemId(service.getSdncRequestHeader().getRequestSystemId())
386                 .setRpcAction(RpcActions.ServiceDelete);
387         ServiceDeleteInputBuilder deleteInputBldr = new ServiceDeleteInputBuilder()
388                 .setServiceDeleteReqInfo(new ServiceDeleteReqInfoBuilder()
389                     .setServiceName(serviceName)
390                     .setDueDate(datetime)
391                     .setTailRetention(TailRetention.No).build())
392                 .setSdncRequestHeader(sdncBuilder.build());
393         ServiceInput serviceInput = new ServiceInput(deleteInputBldr.build());
394         serviceInput.setServiceAEnd(service.getServiceAEnd());
395         serviceInput.setServiceZEnd(service.getServiceZEnd());
396         serviceInput.setConnectionType(service.getConnectionType());
397         HardConstraints hardConstraints = service.getHardConstraints();
398         if (hardConstraints == null) {
399             LOG.warn("service '{}' HardConstraints is not set !", serviceName);
400         } else {
401             SoftConstraints softConstraints = service.getSoftConstraints();
402             if (softConstraints == null) {
403                 LOG.warn("service '{}' SoftConstraints is not set !", serviceName);
404                 serviceInput.setSoftConstraints(DowngradeConstraints.convertToSoftConstraints(hardConstraints));
405                 serviceInput.setHardConstraints(DowngradeConstraints.downgradeHardConstraints(hardConstraints));
406             } else {
407                 LOG.info("converting hard constraints to soft constraints ...");
408                 serviceInput.setSoftConstraints(
409                         DowngradeConstraints.updateSoftConstraints(hardConstraints, softConstraints));
410                 serviceInput.setHardConstraints(DowngradeConstraints.downgradeHardConstraints(hardConstraints));
411             }
412         }
413         this.pceListenerImpl.setInput(serviceInput);
414         this.pceListenerImpl.setServiceReconfigure(true);
415         this.pceListenerImpl.setserviceDataStoreOperations(this.serviceDataStoreOperations);
416         this.rendererListenerImpl.setServiceInput(serviceInput);
417         this.rendererListenerImpl.setserviceDataStoreOperations(this.serviceDataStoreOperations);
418         this.networkModelListenerImpl.setserviceDataStoreOperations(serviceDataStoreOperations);
419         org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.renderer.rev201125
420             .ServiceDeleteInput serviceDeleteInput = ModelMappingUtils.createServiceDeleteInput(
421                     new ServiceInput(deleteInputBldr.build()));
422         org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.renderer.rev201125
423             .ServiceDeleteOutput output = this.rendererServiceWrapper.performRenderer(serviceDeleteInput,
424                 ServiceNotificationTypes.ServiceDeleteResult, null);
425         if (output == null) {
426             LOG.error(SERVICE_RESTORATION_MSG, LogMessages.RENDERER_DELETE_FAILED);
427             return ModelMappingUtils.createRestoreServiceReply(
428                      LogMessages.RENDERER_DELETE_FAILED, RpcStatus.Failed);
429         }
430         LOG.info("RPC serviceRestore in progress...");
431         ConfigurationResponseCommon common = output.getConfigurationResponseCommon();
432         return ModelMappingUtils.createRestoreServiceReply(
433                 common.getResponseMessage(), RpcStatus.Successful);
434
435     }
436
437     @Override
438     public ListenableFuture<RpcResult<EquipmentNotificationOutput>>
439             equipmentNotification(EquipmentNotificationInput input) {
440         // TODO Auto-generated method stub
441         return null;
442     }
443
444     @Override
445     public ListenableFuture<RpcResult<ServiceRerouteConfirmOutput>>
446             serviceRerouteConfirm(ServiceRerouteConfirmInput input) {
447         // TODO Auto-generated method stub
448         return null;
449     }
450
451     @Override
452     public ListenableFuture<RpcResult<ServiceRerouteOutput>> serviceReroute(ServiceRerouteInput input) {
453         String serviceName = input.getServiceName();
454         LOG.info("RPC serviceReroute received for {}", serviceName);
455         Optional<Services> servicesObject = this.serviceDataStoreOperations.getService(serviceName);
456         if (!servicesObject.isPresent()) {
457             LOG.warn("serviceReroute: {}", LogMessages.serviceNotInDS(serviceName));
458             return ModelMappingUtils.createRerouteServiceReply(
459                     input, ResponseCodes.FINAL_ACK_NO,
460                     LogMessages.serviceNotInDS(serviceName), RpcStatus.Failed);
461         }
462         Services service = servicesObject.get();
463         DateTimeFormatter dtf = DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ssxxx");
464         OffsetDateTime offsetDateTime = OffsetDateTime.now(ZoneOffset.UTC);
465         DateAndTime datetime = new DateAndTime(dtf.format(offsetDateTime));
466         SdncRequestHeaderBuilder sdncBuilder = new SdncRequestHeaderBuilder()
467                 .setNotificationUrl(service.getSdncRequestHeader().getNotificationUrl())
468                 .setRequestId(service.getSdncRequestHeader().getRequestId())
469                 .setRequestSystemId(service.getSdncRequestHeader().getRequestSystemId())
470                 .setRpcAction(RpcActions.ServiceDelete);
471         ServiceDeleteInputBuilder deleteInputBldr = new ServiceDeleteInputBuilder()
472                 .setServiceDeleteReqInfo(new ServiceDeleteReqInfoBuilder()
473                     .setServiceName(serviceName).setDueDate(datetime)
474                     .setTailRetention(TailRetention.No).build())
475                 .setSdncRequestHeader(sdncBuilder.build());
476         ServiceInput serviceInput = new ServiceInput(deleteInputBldr.build());
477         serviceInput.setServiceAEnd(service.getServiceAEnd());
478         serviceInput.setServiceZEnd(service.getServiceZEnd());
479         serviceInput.setConnectionType(service.getConnectionType());
480         this.pceListenerImpl.setInput(serviceInput);
481         this.pceListenerImpl.setServiceReconfigure(true);
482         this.pceListenerImpl.setserviceDataStoreOperations(this.serviceDataStoreOperations);
483         this.rendererListenerImpl.setServiceInput(serviceInput);
484         this.rendererListenerImpl.setserviceDataStoreOperations(this.serviceDataStoreOperations);
485         this.networkModelListenerImpl.setserviceDataStoreOperations(serviceDataStoreOperations);
486         org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.renderer.rev201125
487             .ServiceDeleteInput serviceDeleteInput = ModelMappingUtils.createServiceDeleteInput(
488                     new ServiceInput(deleteInputBldr.build()));
489         org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.renderer.rev201125
490             .ServiceDeleteOutput output = this.rendererServiceWrapper.performRenderer(serviceDeleteInput,
491                 ServiceNotificationTypes.ServiceDeleteResult, null);
492         if (output == null) {
493             LOG.error("serviceReroute: {}", LogMessages.RENDERER_DELETE_FAILED);
494             return ModelMappingUtils.createRerouteServiceReply(
495                     input, ResponseCodes.FINAL_ACK_YES,
496                     LogMessages.RENDERER_DELETE_FAILED, RpcStatus.Failed);
497         }
498         LOG.info("RPC ServiceReroute in progress...");
499         ConfigurationResponseCommon common = output.getConfigurationResponseCommon();
500         return ModelMappingUtils.createRerouteServiceReply(
501                 input, common.getAckFinalIndicator(),
502                 common.getResponseMessage(), RpcStatus.Successful);
503     }
504
505     @Override
506     public ListenableFuture<RpcResult<ServiceReversionOutput>> serviceReversion(ServiceReversionInput input) {
507         // TODO Auto-generated method stub
508         return null;
509     }
510
511     @Override
512     public ListenableFuture<RpcResult<ServiceRollOutput>> serviceRoll(ServiceRollInput input) {
513         // TODO Auto-generated method stub
514         return null;
515     }
516
517     @Override
518     public ListenableFuture<RpcResult<NetworkReOptimizationOutput>>
519             networkReOptimization(NetworkReOptimizationInput input) {
520         // TODO Auto-generated method stub
521         return null;
522     }
523
524     @Override
525     public ListenableFuture<RpcResult<TempServiceDeleteOutput>> tempServiceDelete(TempServiceDeleteInput input) {
526         String commonId = input.getCommonId();
527         LOG.info("RPC temp serviceDelete request received for {}", commonId);
528
529         /*
530          * Upon receipt of service-deleteService RPC, service header and sdnc-request
531          * header compliancy are verified.
532          */
533         LOG.debug("checking Service Compliance ...");
534         ComplianceCheckResult serviceHandlerCheckResult = ServicehandlerComplianceCheck.check(
535                 commonId, null, null, RpcActions.ServiceDelete, false, false
536             );
537         if (!serviceHandlerCheckResult.hasPassed()) {
538             LOG.warn(TEMP_SERVICE_DELETE_MSG, LogMessages.ABORT_SERVICE_NON_COMPLIANT);
539             return ModelMappingUtils.createDeleteServiceReply(
540                     input, ResponseCodes.FINAL_ACK_YES,
541                     LogMessages.SERVICE_NON_COMPLIANT, ResponseCodes.RESPONSE_FAILED);
542         }
543
544         //Check presence of service to be deleted
545         LOG.debug("service common-id '{}' is compliant", commonId);
546         Optional<org.opendaylight.yang.gen.v1.http.org.openroadm.service.rev190531.temp.service.list.Services>
547                 service =
548             this.serviceDataStoreOperations.getTempService(commonId);
549         if (!service.isPresent()) {
550             LOG.error(TEMP_SERVICE_DELETE_MSG, LogMessages.serviceNotInDS(commonId));
551             return ModelMappingUtils.createDeleteServiceReply(
552                     input, ResponseCodes.FINAL_ACK_YES,
553                     LogMessages.serviceNotInDS(commonId), ResponseCodes.RESPONSE_FAILED);
554         }
555
556         LOG.info("Service '{}' present in datastore !", commonId);
557         this.pceListenerImpl.setInput(new ServiceInput(input));
558         this.pceListenerImpl.setServiceReconfigure(false);
559         this.pceListenerImpl.setserviceDataStoreOperations(this.serviceDataStoreOperations);
560         this.rendererListenerImpl.setserviceDataStoreOperations(this.serviceDataStoreOperations);
561         this.rendererListenerImpl.setServiceInput(new ServiceInput(input));
562         this.rendererListenerImpl.setTempService(true);
563         this.networkModelListenerImpl.setserviceDataStoreOperations(serviceDataStoreOperations);
564         org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.renderer.rev201125.ServiceDeleteOutput output =
565                 this.rendererServiceWrapper.performRenderer(input, ServiceNotificationTypes.ServiceDeleteResult);
566         if (output == null) {
567             LOG.error(TEMP_SERVICE_DELETE_MSG, LogMessages.RENDERER_DELETE_FAILED);
568             return ModelMappingUtils.createDeleteServiceReply(
569                     input, ResponseCodes.FINAL_ACK_YES,
570                     LogMessages.RENDERER_DELETE_FAILED, ResponseCodes.RESPONSE_FAILED);
571         }
572         LOG.info("RPC tempServiceDelete in progress...");
573         ConfigurationResponseCommon common = output.getConfigurationResponseCommon();
574         return ModelMappingUtils.createDeleteServiceReply(
575                 input, common.getAckFinalIndicator(),
576                 common.getResponseMessage(), common.getResponseCode());
577     }
578
579     @Override
580     public ListenableFuture<RpcResult<TempServiceCreateOutput>> tempServiceCreate(TempServiceCreateInput input) {
581         LOG.info("RPC tempServiceCreate received");
582         // Validation
583         OperationResult validationResult = ServiceCreateValidation.validateServiceCreateRequest(
584                 new ServiceInput(input), RpcActions.TempServiceCreate);
585         if (! validationResult.isSuccess()) {
586             LOG.warn(TEMP_SERVICE_CREATE_MSG, LogMessages.ABORT_VALID_FAILED);
587             return ModelMappingUtils.createCreateServiceReply(
588                     input, ResponseCodes.FINAL_ACK_YES,
589                     validationResult.getResultMessage(), ResponseCodes.RESPONSE_FAILED);
590         }
591
592         // Starting service create operation
593         LOG.debug(TEMP_SERVICE_CREATE_MSG, LogMessages.PCE_CALLING);
594         this.pceListenerImpl.setInput(new ServiceInput(input));
595         this.pceListenerImpl.setServiceReconfigure(false);
596         this.pceListenerImpl.setserviceDataStoreOperations(this.serviceDataStoreOperations);
597         this.pceListenerImpl.setTempService(true);
598         this.rendererListenerImpl.setserviceDataStoreOperations(serviceDataStoreOperations);
599         this.rendererListenerImpl.setServiceInput(new ServiceInput(input));
600         this.rendererListenerImpl.setTempService(true);
601         this.networkModelListenerImpl.setserviceDataStoreOperations(serviceDataStoreOperations);
602         PathComputationRequestOutput output = this.pceServiceWrapper.performPCE(input, true);
603         if (output == null) {
604             LOG.warn(TEMP_SERVICE_CREATE_MSG, LogMessages.ABORT_PCE_FAILED);
605             return ModelMappingUtils.createCreateServiceReply(
606                     input, ResponseCodes.FINAL_ACK_YES,
607                     LogMessages.PCE_FAILED, ResponseCodes.RESPONSE_FAILED);
608         }
609         LOG.info("RPC tempServiceCreate in progress...");
610         ConfigurationResponseCommon common = output.getConfigurationResponseCommon();
611         return ModelMappingUtils.createCreateServiceReply(
612                 input, common.getAckFinalIndicator(),
613                 common.getResponseMessage(), common.getResponseCode());
614     }
615
616     @Override
617     public ListenableFuture<RpcResult<
618         ServiceDeleteComplexResultNotificationRequestOutput>> serviceDeleteComplexResultNotificationRequest(
619             ServiceDeleteComplexResultNotificationRequestInput input) {
620         // TODO Auto-generated method stub
621         return null;
622     }
623
624     @Override
625     public ListenableFuture<RpcResult<
626         ServiceCreateResultNotificationRequestOutput>> serviceCreateResultNotificationRequest(
627             ServiceCreateResultNotificationRequestInput input) {
628         // TODO Auto-generated method stub
629         return null;
630     }
631
632     @Override
633     public ListenableFuture<RpcResult<
634         ServiceDeleteResultNotificationRequestOutput>> serviceDeleteResultNotificationRequest(
635             ServiceDeleteResultNotificationRequestInput input) {
636         // TODO Auto-generated method stub
637         return null;
638     }
639
640     @Override
641     public ListenableFuture<RpcResult<
642         ServiceCreateComplexResultNotificationRequestOutput>> serviceCreateComplexResultNotificationRequest(
643             ServiceCreateComplexResultNotificationRequestInput input) {
644         // TODO Auto-generated method stub
645         return null;
646     }
647
648     @Override
649     public ListenableFuture<RpcResult<ServiceFeasibilityCheckBulkOutput>> serviceFeasibilityCheckBulk(
650         ServiceFeasibilityCheckBulkInput input) {
651         // TODO Auto-generated method stub
652         return null;
653     }
654
655     /**
656      * Send notification to NBI notification in order to publish message.
657      * @param service PublishNotificationService
658      */
659     private void sendNbiNotification(PublishNotificationService service) {
660         try {
661             notificationPublishService.putNotification(service);
662         } catch (InterruptedException e) {
663             LOG.warn("Cannot send notification to nbi", e);
664             Thread.currentThread().interrupt();
665         }
666     }
667 }