Refactor transportpce-routing-constraint model
[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.rev220118.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.rev210915.ServiceDeleteInput
248                 serviceDeleteInput = ModelMappingUtils.createServiceDeleteInput(new ServiceInput(input));
249         org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.renderer.rev210915.ServiceDeleteOutput output =
250             this.rendererServiceWrapper.performRenderer(
251                 serviceDeleteInput, ServiceNotificationTypes.ServiceDeleteResult, service);
252
253         if (output == null) {
254             LOG.error(SERVICE_DELETE_MSG, LogMessages.RENDERER_DELETE_FAILED);
255             sendNbiNotification(new PublishNotificationProcessServiceBuilder()
256                     .setServiceName(service.getServiceName())
257                     .setServiceAEnd(new ServiceAEndBuilder(service.getServiceAEnd()).build())
258                     .setServiceZEnd(new ServiceZEndBuilder(service.getServiceZEnd()).build())
259                     .setCommonId(service.getCommonId())
260                     .setConnectionType(service.getConnectionType())
261                     .setMessage("ServiceDelete request failed ...")
262                     .setOperationalState(State.InService)
263                     .setResponseFailed(LogMessages.RENDERER_DELETE_FAILED)
264                     .setPublisherName(PUBLISHER)
265                     .build());
266             return ModelMappingUtils.createDeleteServiceReply(
267                     input, ResponseCodes.FINAL_ACK_YES,
268                     LogMessages.RENDERER_DELETE_FAILED, ResponseCodes.RESPONSE_FAILED);
269         }
270
271         LOG.debug("RPC serviceDelete in progress...");
272         ConfigurationResponseCommon common = output.getConfigurationResponseCommon();
273         return ModelMappingUtils.createDeleteServiceReply(
274                 input, common.getAckFinalIndicator(),
275                 common.getResponseMessage(), common.getResponseCode());
276     }
277
278     @Override
279     public ListenableFuture<RpcResult<ServiceFeasibilityCheckOutput>> serviceFeasibilityCheck(
280             ServiceFeasibilityCheckInput input) {
281         LOG.info("RPC serviceFeasibilityCheck received");
282         // Validation
283         ServiceInput serviceInput = new ServiceInput(input);
284         OperationResult validationResult = ServiceCreateValidation.validateServiceCreateRequest(serviceInput,
285                 RpcActions.ServiceFeasibilityCheck);
286         if (! validationResult.isSuccess()) {
287             LOG.warn(SERVICE_FEASIBILITY_CHECK_MSG, LogMessages.ABORT_VALID_FAILED);
288             return ModelMappingUtils.createCreateServiceReply(
289                     input, ResponseCodes.FINAL_ACK_YES,
290                     validationResult.getResultMessage(), ResponseCodes.RESPONSE_FAILED);
291         }
292         this.pceListenerImpl.setInput(new ServiceInput(input));
293         this.pceListenerImpl.setServiceReconfigure(false);
294         this.pceListenerImpl.setServiceFeasiblity(true);
295         this.pceListenerImpl.setserviceDataStoreOperations(this.serviceDataStoreOperations);
296         this.rendererListenerImpl.setserviceDataStoreOperations(serviceDataStoreOperations);
297         this.rendererListenerImpl.setServiceInput(new ServiceInput(input));
298         this.networkModelListenerImpl.setserviceDataStoreOperations(serviceDataStoreOperations);
299         LOG.debug(SERVICE_FEASIBILITY_CHECK_MSG, LogMessages.PCE_CALLING);
300         PathComputationRequestOutput output = this.pceServiceWrapper.performPCE(input, true);
301         if (output == null) {
302             LOG.warn(SERVICE_FEASIBILITY_CHECK_MSG, LogMessages.ABORT_PCE_FAILED);
303             return ModelMappingUtils.createCreateServiceReply(input, ResponseCodes.FINAL_ACK_YES,
304                     LogMessages.PCE_FAILED, ResponseCodes.RESPONSE_FAILED);
305         }
306         LOG.info("RPC serviceFeasibilityCheck in progress...");
307         ConfigurationResponseCommon common = output.getConfigurationResponseCommon();
308         return ModelMappingUtils.createCreateServiceReply(
309                 input, common.getAckFinalIndicator(),
310                 common.getResponseMessage(), common.getResponseCode());
311     }
312
313     @Override
314     public ListenableFuture<RpcResult<ServiceReconfigureOutput>> serviceReconfigure(ServiceReconfigureInput input) {
315         String serviceName = input.getServiceName();
316         LOG.info("RPC serviceReconfigure received for {}", serviceName);
317         Optional<Services> servicesObject = this.serviceDataStoreOperations.getService(serviceName);
318         if (servicesObject.isEmpty()) {
319             LOG.warn(SERVICE_RECONFIGURE_MSG, LogMessages.serviceNotInDS(serviceName));
320             return ModelMappingUtils.createCreateServiceReply(
321                 input,
322                 LogMessages.serviceNotInDS(serviceName), RpcStatus.Failed);
323         }
324         LOG.debug("Service '{}' found in datastore", serviceName);
325         OperationResult validationResult = ServiceCreateValidation
326                 .validateServiceCreateRequest(new ServiceInput(input), RpcActions.ServiceReconfigure);
327         if (!validationResult.isSuccess()) {
328             LOG.warn(SERVICE_RECONFIGURE_MSG, LogMessages.ABORT_VALID_FAILED);
329             return ModelMappingUtils.createCreateServiceReply(
330                     input,
331                     validationResult.getResultMessage(), RpcStatus.Failed);
332         }
333         this.pceListenerImpl.setInput(new ServiceInput(input));
334         this.pceListenerImpl.setServiceReconfigure(true);
335         this.pceListenerImpl.setserviceDataStoreOperations(this.serviceDataStoreOperations);
336         this.rendererListenerImpl.setserviceDataStoreOperations(serviceDataStoreOperations);
337         this.rendererListenerImpl.setServiceInput(new ServiceInput(input));
338         this.networkModelListenerImpl.setserviceDataStoreOperations(serviceDataStoreOperations);
339         org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.renderer.rev210915
340                 .ServiceDeleteInput serviceDeleteInput =
341                         ModelMappingUtils.createServiceDeleteInput(new ServiceInput(input));
342         org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.renderer.rev210915
343                 .ServiceDeleteOutput output = this.rendererServiceWrapper.performRenderer(serviceDeleteInput,
344                         ServiceNotificationTypes.ServiceDeleteResult, null);
345         if (output == null) {
346             LOG.error(SERVICE_RECONFIGURE_MSG, LogMessages.RENDERER_DELETE_FAILED);
347             return ModelMappingUtils.createCreateServiceReply(
348                     input,
349                     LogMessages.RENDERER_DELETE_FAILED, RpcStatus.Successful);
350                     //TODO check if RpcStatus.Successful is really expected here
351         }
352         LOG.info("RPC serviceReconfigure in progress...");
353         ConfigurationResponseCommon common = output.getConfigurationResponseCommon();
354         return ModelMappingUtils.createCreateServiceReply(
355                 input,
356                 common.getResponseMessage(), RpcStatus.Successful);
357     }
358
359     @Override
360     public ListenableFuture<RpcResult<ServiceRestorationOutput>> serviceRestoration(ServiceRestorationInput input) {
361         String serviceName = input.getServiceName();
362         LOG.info("RPC serviceRestoration received for {}", serviceName);
363         Optional<Services> servicesObject = this.serviceDataStoreOperations.getService(serviceName);
364
365         if (!servicesObject.isPresent()) {
366             LOG.warn(SERVICE_RESTORATION_MSG, LogMessages.serviceNotInDS(serviceName));
367             return ModelMappingUtils.createRestoreServiceReply(
368                     LogMessages.serviceNotInDS(serviceName), RpcStatus.Failed);
369         }
370
371         Services service = servicesObject.get();
372         State state = service.getOperationalState();
373
374         if (state == State.InService) {
375             LOG.error(SERVICE_RESTORATION_MSG, LogMessages.serviceInService(serviceName));
376             return ModelMappingUtils.createRestoreServiceReply(
377                     LogMessages.serviceInService(serviceName), RpcStatus.Failed);
378         }
379
380         DateTimeFormatter dtf = DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ssxxx");
381         OffsetDateTime offsetDateTime = OffsetDateTime.now(ZoneOffset.UTC);
382         DateAndTime datetime = new DateAndTime(dtf.format(offsetDateTime));
383         SdncRequestHeaderBuilder sdncBuilder = new SdncRequestHeaderBuilder()
384                 .setNotificationUrl(service.getSdncRequestHeader().getNotificationUrl())
385                 .setRequestId(service.getSdncRequestHeader().getRequestId())
386                 .setRequestSystemId(service.getSdncRequestHeader().getRequestSystemId())
387                 .setRpcAction(RpcActions.ServiceDelete);
388         ServiceDeleteInputBuilder deleteInputBldr = new ServiceDeleteInputBuilder()
389                 .setServiceDeleteReqInfo(new ServiceDeleteReqInfoBuilder()
390                     .setServiceName(serviceName)
391                     .setDueDate(datetime)
392                     .setTailRetention(TailRetention.No).build())
393                 .setSdncRequestHeader(sdncBuilder.build());
394         ServiceInput serviceInput = new ServiceInput(deleteInputBldr.build());
395         serviceInput.setServiceAEnd(service.getServiceAEnd());
396         serviceInput.setServiceZEnd(service.getServiceZEnd());
397         serviceInput.setConnectionType(service.getConnectionType());
398         HardConstraints hardConstraints = service.getHardConstraints();
399         if (hardConstraints == null) {
400             LOG.warn("service '{}' HardConstraints is not set !", serviceName);
401         } else {
402             SoftConstraints softConstraints = service.getSoftConstraints();
403             if (softConstraints == null) {
404                 LOG.warn("service '{}' SoftConstraints is not set !", serviceName);
405                 serviceInput.setSoftConstraints(DowngradeConstraints.convertToSoftConstraints(hardConstraints));
406             } else {
407                 LOG.info("converting hard constraints to soft constraints ...");
408                 serviceInput.setSoftConstraints(
409                         DowngradeConstraints.updateSoftConstraints(hardConstraints, softConstraints));
410             }
411             serviceInput.setHardConstraints(DowngradeConstraints.downgradeHardConstraints(hardConstraints));
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.rev210915
420             .ServiceDeleteInput serviceDeleteInput = ModelMappingUtils.createServiceDeleteInput(
421                     new ServiceInput(deleteInputBldr.build()));
422         org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.renderer.rev210915
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.isEmpty()) {
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.rev210915
487             .ServiceDeleteInput serviceDeleteInput = ModelMappingUtils.createServiceDeleteInput(
488                     new ServiceInput(deleteInputBldr.build()));
489         org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.renderer.rev210915
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 compliance 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.isEmpty()) {
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.rev210915.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(PublishNotificationProcessService 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 }