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