Fix the misplacements of service notifications
[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         PublishNotificationService nbiNotification = new PublishNotificationServiceBuilder()
182                 .setServiceName(input.getServiceName())
183                 .setServiceAEnd(new ServiceAEndBuilder(input.getServiceAEnd()).build())
184                 .setServiceZEnd(new ServiceZEndBuilder(input.getServiceZEnd()).build())
185                 .setCommonId(input.getCommonId()).setConnectionType(input.getConnectionType())
186                 .setResponseFailed("")
187                 .setMessage("ServiceCreate request received ...")
188                 .setOperationalState(State.OutOfService)
189                 .setTopic(topic)
190                 .build();
191         sendNbiNotification(nbiNotification);
192         this.pceListenerImpl.setInput(new ServiceInput(input));
193         this.pceListenerImpl.setServiceReconfigure(false);
194         this.pceListenerImpl.setserviceDataStoreOperations(this.serviceDataStoreOperations);
195         this.rendererListenerImpl.setserviceDataStoreOperations(serviceDataStoreOperations);
196         this.rendererListenerImpl.setServiceInput(new ServiceInput(input));
197         this.networkModelListenerImpl.setserviceDataStoreOperations(serviceDataStoreOperations);
198         LOG.debug(SERVICE_CREATE_MSG, LogMessages.PCE_CALLING);
199         PathComputationRequestOutput output = this.pceServiceWrapper.performPCE(input, true);
200         if (output == null) {
201             LOG.warn(SERVICE_CREATE_MSG, LogMessages.ABORT_PCE_FAILED);
202             nbiNotification = new PublishNotificationServiceBuilder(nbiNotification)
203                     .setResponseFailed(LogMessages.ABORT_PCE_FAILED)
204                     .setMessage("ServiceCreate request failed ...")
205                     .setOperationalState(State.Degraded)
206                     .build();
207             sendNbiNotification(nbiNotification);
208             return ModelMappingUtils.createCreateServiceReply(input, ResponseCodes.FINAL_ACK_YES,
209                     LogMessages.PCE_FAILED, ResponseCodes.RESPONSE_FAILED);
210         }
211         LOG.info("RPC serviceCreate in progress...");
212         ConfigurationResponseCommon common = output.getConfigurationResponseCommon();
213         return ModelMappingUtils.createCreateServiceReply(
214                 input, common.getAckFinalIndicator(),
215                 common.getResponseMessage(), common.getResponseCode());
216     }
217
218     @Override
219     public ListenableFuture<RpcResult<ServiceDeleteOutput>> serviceDelete(ServiceDeleteInput input) {
220         String serviceName = input.getServiceDeleteReqInfo().getServiceName();
221         LOG.info("RPC serviceDelete request received for {}", serviceName);
222
223         /*
224          * Upon receipt of service-deleteService RPC, service header and sdnc-request
225          * header compliance are verified.
226          */
227         ComplianceCheckResult serviceHandlerCheckResult =
228             ServicehandlerComplianceCheck.check(
229                 input.getServiceDeleteReqInfo().getServiceName(),
230                 input.getSdncRequestHeader(), null, RpcActions.ServiceDelete, false, true);
231         if (!serviceHandlerCheckResult.hasPassed()) {
232             LOG.warn(SERVICE_DELETE_MSG, LogMessages.ABORT_SERVICE_NON_COMPLIANT);
233             return ModelMappingUtils.createDeleteServiceReply(
234                     input, ResponseCodes.FINAL_ACK_YES,
235                     LogMessages.SERVICE_NON_COMPLIANT, ResponseCodes.RESPONSE_FAILED);
236         }
237
238         //Check presence of service to be deleted
239         Optional<Services> serviceOpt = this.serviceDataStoreOperations.getService(serviceName);
240         Services service;
241         if (!serviceOpt.isPresent()) {
242             LOG.warn(SERVICE_DELETE_MSG, LogMessages.serviceNotInDS(serviceName));
243             return ModelMappingUtils.createDeleteServiceReply(
244                     input, ResponseCodes.FINAL_ACK_YES,
245                     LogMessages.serviceNotInDS(serviceName), ResponseCodes.RESPONSE_FAILED);
246         }
247         service = serviceOpt.get();
248         PublishNotificationService nbiNotification = new PublishNotificationServiceBuilder()
249                 .setServiceName(service.getServiceName())
250                 .setServiceAEnd(new ServiceAEndBuilder(service.getServiceAEnd()).build())
251                 .setServiceZEnd(new ServiceZEndBuilder(service.getServiceZEnd()).build())
252                 .setCommonId(service.getCommonId()).setConnectionType(service.getConnectionType())
253                 .setMessage("ServiceDelete request received ...")
254                 .setOperationalState(service.getOperationalState())
255                 .setResponseFailed("")
256                 .setTopic(topic)
257                 .build();
258         sendNbiNotification(nbiNotification);
259         LOG.debug("serviceDelete: Service '{}' found in datastore", serviceName);
260         this.pceListenerImpl.setInput(new ServiceInput(input));
261         this.pceListenerImpl.setServiceReconfigure(false);
262         this.pceListenerImpl.setserviceDataStoreOperations(this.serviceDataStoreOperations);
263         this.rendererListenerImpl.setserviceDataStoreOperations(serviceDataStoreOperations);
264         this.rendererListenerImpl.setServiceInput(new ServiceInput(input));
265         this.networkModelListenerImpl.setserviceDataStoreOperations(serviceDataStoreOperations);
266         org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.renderer.rev201125
267                 .ServiceDeleteInput serviceDeleteInput =
268             ModelMappingUtils.createServiceDeleteInput(new ServiceInput(input));
269         org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.renderer.rev201125.ServiceDeleteOutput output =
270             this.rendererServiceWrapper.performRenderer(
271                 serviceDeleteInput, ServiceNotificationTypes.ServiceDeleteResult, service);
272
273         if (output == null) {
274             LOG.error(SERVICE_DELETE_MSG, LogMessages.RENDERER_DELETE_FAILED);
275             nbiNotification = new PublishNotificationServiceBuilder(nbiNotification)
276                     .setMessage("ServiceDelete request failed ...")
277                     .setOperationalState(State.InService)
278                     .setResponseFailed(LogMessages.RENDERER_DELETE_FAILED)
279                     .build();
280             sendNbiNotification(nbiNotification);
281             return ModelMappingUtils.createDeleteServiceReply(
282                     input, ResponseCodes.FINAL_ACK_YES,
283                     LogMessages.RENDERER_DELETE_FAILED, ResponseCodes.RESPONSE_FAILED);
284         }
285
286         LOG.debug("RPC serviceDelete in progress...");
287         ConfigurationResponseCommon common = output.getConfigurationResponseCommon();
288         return ModelMappingUtils.createDeleteServiceReply(
289                 input, common.getAckFinalIndicator(),
290                 common.getResponseMessage(), common.getResponseCode());
291     }
292
293     @Override
294     public ListenableFuture<RpcResult<ServiceFeasibilityCheckOutput>> serviceFeasibilityCheck(
295             ServiceFeasibilityCheckInput input) {
296         LOG.info("RPC serviceFeasibilityCheck received");
297         // Validation
298         ServiceInput serviceInput = new ServiceInput(input);
299         OperationResult validationResult = ServiceCreateValidation.validateServiceCreateRequest(serviceInput,
300                 RpcActions.ServiceFeasibilityCheck);
301         if (! validationResult.isSuccess()) {
302             LOG.warn(SERVICE_FEASABILITY_CHECK_MSG, LogMessages.ABORT_VALID_FAILED);
303             return ModelMappingUtils.createCreateServiceReply(
304                     input, ResponseCodes.FINAL_ACK_YES,
305                     validationResult.getResultMessage(), ResponseCodes.RESPONSE_FAILED);
306         }
307         this.pceListenerImpl.setInput(new ServiceInput(input));
308         this.pceListenerImpl.setServiceReconfigure(false);
309         this.pceListenerImpl.setServiceFeasiblity(true);
310         this.pceListenerImpl.setserviceDataStoreOperations(this.serviceDataStoreOperations);
311         this.rendererListenerImpl.setserviceDataStoreOperations(serviceDataStoreOperations);
312         this.rendererListenerImpl.setServiceInput(new ServiceInput(input));
313         this.networkModelListenerImpl.setserviceDataStoreOperations(serviceDataStoreOperations);
314         LOG.debug(SERVICE_FEASABILITY_CHECK_MSG, LogMessages.PCE_CALLING);
315         PathComputationRequestOutput output = this.pceServiceWrapper.performPCE(input, true);
316         if (output == null) {
317             LOG.warn(SERVICE_FEASABILITY_CHECK_MSG, LogMessages.ABORT_PCE_FAILED);
318             return ModelMappingUtils.createCreateServiceReply(input, ResponseCodes.FINAL_ACK_YES,
319                     LogMessages.PCE_FAILED, ResponseCodes.RESPONSE_FAILED);
320         }
321         LOG.info("RPC serviceFeasibilityCheck in progress...");
322         ConfigurationResponseCommon common = output.getConfigurationResponseCommon();
323         return ModelMappingUtils.createCreateServiceReply(
324                 input, common.getAckFinalIndicator(),
325                 common.getResponseMessage(), common.getResponseCode());
326     }
327
328     @Override
329     public ListenableFuture<RpcResult<ServiceReconfigureOutput>> serviceReconfigure(ServiceReconfigureInput input) {
330         String serviceName = input.getServiceName();
331         LOG.info("RPC serviceReconfigure received for {}", serviceName);
332         Optional<Services> servicesObject = this.serviceDataStoreOperations.getService(serviceName);
333         if (!servicesObject.isPresent()) {
334             LOG.warn(SERVICE_RECONFIGURE_MSG, LogMessages.serviceNotInDS(serviceName));
335             return ModelMappingUtils.createCreateServiceReply(
336                 input,
337                 LogMessages.serviceNotInDS(serviceName), RpcStatus.Failed);
338         }
339         LOG.debug("Service '{}' found in datastore", serviceName);
340         OperationResult validationResult = ServiceCreateValidation
341                 .validateServiceCreateRequest(new ServiceInput(input), RpcActions.ServiceReconfigure);
342         if (!validationResult.isSuccess()) {
343             LOG.warn(SERVICE_RECONFIGURE_MSG, LogMessages.ABORT_VALID_FAILED);
344             return ModelMappingUtils.createCreateServiceReply(
345                     input,
346                     validationResult.getResultMessage(), RpcStatus.Failed);
347         }
348         this.pceListenerImpl.setInput(new ServiceInput(input));
349         this.pceListenerImpl.setServiceReconfigure(true);
350         this.pceListenerImpl.setserviceDataStoreOperations(this.serviceDataStoreOperations);
351         this.rendererListenerImpl.setserviceDataStoreOperations(serviceDataStoreOperations);
352         this.rendererListenerImpl.setServiceInput(new ServiceInput(input));
353         this.networkModelListenerImpl.setserviceDataStoreOperations(serviceDataStoreOperations);
354         org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.renderer.rev201125
355                 .ServiceDeleteInput serviceDeleteInput =
356                         ModelMappingUtils.createServiceDeleteInput(new ServiceInput(input));
357         org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.renderer.rev201125
358                 .ServiceDeleteOutput output = this.rendererServiceWrapper.performRenderer(serviceDeleteInput,
359                         ServiceNotificationTypes.ServiceDeleteResult, null);
360         if (output == null) {
361             LOG.error(SERVICE_RECONFIGURE_MSG, LogMessages.RENDERER_DELETE_FAILED);
362             return ModelMappingUtils.createCreateServiceReply(
363                     input,
364                     LogMessages.RENDERER_DELETE_FAILED, RpcStatus.Successful);
365                     //TODO check if RpcStatus.Successful is really expected here
366         }
367         LOG.info("RPC serviceReconfigure in progress...");
368         ConfigurationResponseCommon common = output.getConfigurationResponseCommon();
369         return ModelMappingUtils.createCreateServiceReply(
370                 input,
371                 common.getResponseMessage(), RpcStatus.Successful);
372     }
373
374     @Override
375     public ListenableFuture<RpcResult<ServiceRestorationOutput>> serviceRestoration(ServiceRestorationInput input) {
376         String serviceName = input.getServiceName();
377         LOG.info("RPC serviceRestoration received for {}", serviceName);
378         Optional<Services> servicesObject = this.serviceDataStoreOperations.getService(serviceName);
379
380         if (!servicesObject.isPresent()) {
381             LOG.warn(SERVICE_RESTORATION_MSG, LogMessages.serviceNotInDS(serviceName));
382             return ModelMappingUtils.createRestoreServiceReply(
383                     LogMessages.serviceNotInDS(serviceName), RpcStatus.Failed);
384         }
385
386         Services service = servicesObject.get();
387         State state = service.getOperationalState();
388
389         if (state == State.InService) {
390             LOG.error(SERVICE_RESTORATION_MSG, LogMessages.serviceInService(serviceName));
391             return ModelMappingUtils.createRestoreServiceReply(
392                     LogMessages.serviceInService(serviceName), RpcStatus.Failed);
393         }
394
395         DateTimeFormatter dtf = DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ssxxx");
396         OffsetDateTime offsetDateTime = OffsetDateTime.now(ZoneOffset.UTC);
397         DateAndTime datetime = new DateAndTime(dtf.format(offsetDateTime));
398         SdncRequestHeaderBuilder sdncBuilder = new SdncRequestHeaderBuilder()
399                 .setNotificationUrl(service.getSdncRequestHeader().getNotificationUrl())
400                 .setRequestId(service.getSdncRequestHeader().getRequestId())
401                 .setRequestSystemId(service.getSdncRequestHeader().getRequestSystemId())
402                 .setRpcAction(RpcActions.ServiceDelete);
403         ServiceDeleteInputBuilder deleteInputBldr = new ServiceDeleteInputBuilder()
404                 .setServiceDeleteReqInfo(new ServiceDeleteReqInfoBuilder()
405                     .setServiceName(serviceName)
406                     .setDueDate(datetime)
407                     .setTailRetention(TailRetention.No).build())
408                 .setSdncRequestHeader(sdncBuilder.build());
409         ServiceInput serviceInput = new ServiceInput(deleteInputBldr.build());
410         serviceInput.setServiceAEnd(service.getServiceAEnd());
411         serviceInput.setServiceZEnd(service.getServiceZEnd());
412         serviceInput.setConnectionType(service.getConnectionType());
413         HardConstraints hardConstraints = service.getHardConstraints();
414         if (hardConstraints == null) {
415             LOG.warn("service '{}' HardConstraints is not set !", serviceName);
416         } else {
417             SoftConstraints softConstraints = service.getSoftConstraints();
418             if (softConstraints == null) {
419                 LOG.warn("service '{}' SoftConstraints is not set !", serviceName);
420                 serviceInput.setSoftConstraints(DowngradeConstraints.convertToSoftConstraints(hardConstraints));
421                 serviceInput.setHardConstraints(DowngradeConstraints.downgradeHardConstraints(hardConstraints));
422             } else {
423                 LOG.info("converting hard constraints to soft constraints ...");
424                 serviceInput.setSoftConstraints(
425                         DowngradeConstraints.updateSoftConstraints(hardConstraints, softConstraints));
426                 serviceInput.setHardConstraints(DowngradeConstraints.downgradeHardConstraints(hardConstraints));
427             }
428         }
429         this.pceListenerImpl.setInput(serviceInput);
430         this.pceListenerImpl.setServiceReconfigure(true);
431         this.pceListenerImpl.setserviceDataStoreOperations(this.serviceDataStoreOperations);
432         this.rendererListenerImpl.setServiceInput(serviceInput);
433         this.rendererListenerImpl.setserviceDataStoreOperations(this.serviceDataStoreOperations);
434         this.networkModelListenerImpl.setserviceDataStoreOperations(serviceDataStoreOperations);
435         org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.renderer.rev201125
436             .ServiceDeleteInput serviceDeleteInput = ModelMappingUtils.createServiceDeleteInput(
437                     new ServiceInput(deleteInputBldr.build()));
438         org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.renderer.rev201125
439             .ServiceDeleteOutput output = this.rendererServiceWrapper.performRenderer(serviceDeleteInput,
440                 ServiceNotificationTypes.ServiceDeleteResult, null);
441         if (output == null) {
442             LOG.error(SERVICE_RESTORATION_MSG, LogMessages.RENDERER_DELETE_FAILED);
443             return ModelMappingUtils.createRestoreServiceReply(
444                      LogMessages.RENDERER_DELETE_FAILED, RpcStatus.Failed);
445         }
446         LOG.info("RPC serviceRestore in progress...");
447         ConfigurationResponseCommon common = output.getConfigurationResponseCommon();
448         return ModelMappingUtils.createRestoreServiceReply(
449                 common.getResponseMessage(), RpcStatus.Successful);
450
451     }
452
453     @Override
454     public ListenableFuture<RpcResult<EquipmentNotificationOutput>>
455             equipmentNotification(EquipmentNotificationInput input) {
456         // TODO Auto-generated method stub
457         return null;
458     }
459
460     @Override
461     public ListenableFuture<RpcResult<ServiceRerouteConfirmOutput>>
462             serviceRerouteConfirm(ServiceRerouteConfirmInput input) {
463         // TODO Auto-generated method stub
464         return null;
465     }
466
467     @Override
468     public ListenableFuture<RpcResult<ServiceRerouteOutput>> serviceReroute(ServiceRerouteInput input) {
469         String serviceName = input.getServiceName();
470         LOG.info("RPC serviceReroute received for {}", serviceName);
471         Optional<Services> servicesObject = this.serviceDataStoreOperations.getService(serviceName);
472         if (!servicesObject.isPresent()) {
473             LOG.warn("serviceReroute: {}", LogMessages.serviceNotInDS(serviceName));
474             return ModelMappingUtils.createRerouteServiceReply(
475                     input, ResponseCodes.FINAL_ACK_NO,
476                     LogMessages.serviceNotInDS(serviceName), RpcStatus.Failed);
477         }
478         Services service = servicesObject.get();
479         DateTimeFormatter dtf = DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ssxxx");
480         OffsetDateTime offsetDateTime = OffsetDateTime.now(ZoneOffset.UTC);
481         DateAndTime datetime = new DateAndTime(dtf.format(offsetDateTime));
482         SdncRequestHeaderBuilder sdncBuilder = new SdncRequestHeaderBuilder()
483                 .setNotificationUrl(service.getSdncRequestHeader().getNotificationUrl())
484                 .setRequestId(service.getSdncRequestHeader().getRequestId())
485                 .setRequestSystemId(service.getSdncRequestHeader().getRequestSystemId())
486                 .setRpcAction(RpcActions.ServiceDelete);
487         ServiceDeleteInputBuilder deleteInputBldr = new ServiceDeleteInputBuilder()
488                 .setServiceDeleteReqInfo(new ServiceDeleteReqInfoBuilder()
489                     .setServiceName(serviceName).setDueDate(datetime)
490                     .setTailRetention(TailRetention.No).build())
491                 .setSdncRequestHeader(sdncBuilder.build());
492         ServiceInput serviceInput = new ServiceInput(deleteInputBldr.build());
493         serviceInput.setServiceAEnd(service.getServiceAEnd());
494         serviceInput.setServiceZEnd(service.getServiceZEnd());
495         serviceInput.setConnectionType(service.getConnectionType());
496         this.pceListenerImpl.setInput(serviceInput);
497         this.pceListenerImpl.setServiceReconfigure(true);
498         this.pceListenerImpl.setserviceDataStoreOperations(this.serviceDataStoreOperations);
499         this.rendererListenerImpl.setServiceInput(serviceInput);
500         this.rendererListenerImpl.setserviceDataStoreOperations(this.serviceDataStoreOperations);
501         this.networkModelListenerImpl.setserviceDataStoreOperations(serviceDataStoreOperations);
502         org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.renderer.rev201125
503             .ServiceDeleteInput serviceDeleteInput = ModelMappingUtils.createServiceDeleteInput(
504                     new ServiceInput(deleteInputBldr.build()));
505         org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.renderer.rev201125
506             .ServiceDeleteOutput output = this.rendererServiceWrapper.performRenderer(serviceDeleteInput,
507                 ServiceNotificationTypes.ServiceDeleteResult, null);
508         if (output == null) {
509             LOG.error("serviceReroute: {}", LogMessages.RENDERER_DELETE_FAILED);
510             return ModelMappingUtils.createRerouteServiceReply(
511                     input, ResponseCodes.FINAL_ACK_YES,
512                     LogMessages.RENDERER_DELETE_FAILED, RpcStatus.Failed);
513         }
514         LOG.info("RPC ServiceReroute in progress...");
515         ConfigurationResponseCommon common = output.getConfigurationResponseCommon();
516         return ModelMappingUtils.createRerouteServiceReply(
517                 input, common.getAckFinalIndicator(),
518                 common.getResponseMessage(), RpcStatus.Successful);
519     }
520
521     @Override
522     public ListenableFuture<RpcResult<ServiceReversionOutput>> serviceReversion(ServiceReversionInput input) {
523         // TODO Auto-generated method stub
524         return null;
525     }
526
527     @Override
528     public ListenableFuture<RpcResult<ServiceRollOutput>> serviceRoll(ServiceRollInput input) {
529         // TODO Auto-generated method stub
530         return null;
531     }
532
533     @Override
534     public ListenableFuture<RpcResult<NetworkReOptimizationOutput>>
535             networkReOptimization(NetworkReOptimizationInput input) {
536         // TODO Auto-generated method stub
537         return null;
538     }
539
540     @Override
541     public ListenableFuture<RpcResult<TempServiceDeleteOutput>> tempServiceDelete(TempServiceDeleteInput input) {
542         String commonId = input.getCommonId();
543         LOG.info("RPC temp serviceDelete request received for {}", commonId);
544
545         /*
546          * Upon receipt of service-deleteService RPC, service header and sdnc-request
547          * header compliancy are verified.
548          */
549         LOG.debug("checking Service Compliance ...");
550         ComplianceCheckResult serviceHandlerCheckResult = ServicehandlerComplianceCheck.check(
551                 commonId, null, null, RpcActions.ServiceDelete, false, false
552             );
553         if (!serviceHandlerCheckResult.hasPassed()) {
554             LOG.warn(TEMP_SERVICE_DELETE_MSG, LogMessages.ABORT_SERVICE_NON_COMPLIANT);
555             return ModelMappingUtils.createDeleteServiceReply(
556                     input, ResponseCodes.FINAL_ACK_YES,
557                     LogMessages.SERVICE_NON_COMPLIANT, ResponseCodes.RESPONSE_FAILED);
558         }
559
560         //Check presence of service to be deleted
561         LOG.debug("service common-id '{}' is compliant", commonId);
562         Optional<org.opendaylight.yang.gen.v1.http.org.openroadm.service.rev190531.temp.service.list.Services>
563                 service =
564             this.serviceDataStoreOperations.getTempService(commonId);
565         if (!service.isPresent()) {
566             LOG.error(TEMP_SERVICE_DELETE_MSG, LogMessages.serviceNotInDS(commonId));
567             return ModelMappingUtils.createDeleteServiceReply(
568                     input, ResponseCodes.FINAL_ACK_YES,
569                     LogMessages.serviceNotInDS(commonId), ResponseCodes.RESPONSE_FAILED);
570         }
571
572         LOG.info("Service '{}' present in datastore !", commonId);
573         this.pceListenerImpl.setInput(new ServiceInput(input));
574         this.pceListenerImpl.setServiceReconfigure(false);
575         this.pceListenerImpl.setserviceDataStoreOperations(this.serviceDataStoreOperations);
576         this.rendererListenerImpl.setserviceDataStoreOperations(this.serviceDataStoreOperations);
577         this.rendererListenerImpl.setServiceInput(new ServiceInput(input));
578         this.rendererListenerImpl.setTempService(true);
579         this.networkModelListenerImpl.setserviceDataStoreOperations(serviceDataStoreOperations);
580         org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.renderer.rev201125.ServiceDeleteOutput output =
581                 this.rendererServiceWrapper.performRenderer(input, ServiceNotificationTypes.ServiceDeleteResult);
582         if (output == null) {
583             LOG.error(TEMP_SERVICE_DELETE_MSG, LogMessages.RENDERER_DELETE_FAILED);
584             return ModelMappingUtils.createDeleteServiceReply(
585                     input, ResponseCodes.FINAL_ACK_YES,
586                     LogMessages.RENDERER_DELETE_FAILED, ResponseCodes.RESPONSE_FAILED);
587         }
588         LOG.info("RPC tempServiceDelete in progress...");
589         ConfigurationResponseCommon common = output.getConfigurationResponseCommon();
590         return ModelMappingUtils.createDeleteServiceReply(
591                 input, common.getAckFinalIndicator(),
592                 common.getResponseMessage(), common.getResponseCode());
593     }
594
595     @Override
596     public ListenableFuture<RpcResult<TempServiceCreateOutput>> tempServiceCreate(TempServiceCreateInput input) {
597         LOG.info("RPC tempServiceCreate received");
598         // Validation
599         OperationResult validationResult = ServiceCreateValidation.validateServiceCreateRequest(
600                 new ServiceInput(input), RpcActions.TempServiceCreate);
601         if (! validationResult.isSuccess()) {
602             LOG.warn(TEMP_SERVICE_CREATE_MSG, LogMessages.ABORT_VALID_FAILED);
603             return ModelMappingUtils.createCreateServiceReply(
604                     input, ResponseCodes.FINAL_ACK_YES,
605                     validationResult.getResultMessage(), ResponseCodes.RESPONSE_FAILED);
606         }
607
608         // Starting service create operation
609         LOG.debug(TEMP_SERVICE_CREATE_MSG, LogMessages.PCE_CALLING);
610         this.pceListenerImpl.setInput(new ServiceInput(input));
611         this.pceListenerImpl.setServiceReconfigure(false);
612         this.pceListenerImpl.setserviceDataStoreOperations(this.serviceDataStoreOperations);
613         this.pceListenerImpl.setTempService(true);
614         this.rendererListenerImpl.setserviceDataStoreOperations(serviceDataStoreOperations);
615         this.rendererListenerImpl.setServiceInput(new ServiceInput(input));
616         this.rendererListenerImpl.setTempService(true);
617         this.networkModelListenerImpl.setserviceDataStoreOperations(serviceDataStoreOperations);
618         PathComputationRequestOutput output = this.pceServiceWrapper.performPCE(input, true);
619         if (output == null) {
620             LOG.warn(TEMP_SERVICE_CREATE_MSG, LogMessages.ABORT_PCE_FAILED);
621             return ModelMappingUtils.createCreateServiceReply(
622                     input, ResponseCodes.FINAL_ACK_YES,
623                     LogMessages.PCE_FAILED, ResponseCodes.RESPONSE_FAILED);
624         }
625         LOG.info("RPC tempServiceCreate in progress...");
626         ConfigurationResponseCommon common = output.getConfigurationResponseCommon();
627         return ModelMappingUtils.createCreateServiceReply(
628                 input, common.getAckFinalIndicator(),
629                 common.getResponseMessage(), common.getResponseCode());
630     }
631
632     @Override
633     public ListenableFuture<RpcResult<
634         ServiceDeleteComplexResultNotificationRequestOutput>> serviceDeleteComplexResultNotificationRequest(
635             ServiceDeleteComplexResultNotificationRequestInput input) {
636         // TODO Auto-generated method stub
637         return null;
638     }
639
640     @Override
641     public ListenableFuture<RpcResult<
642         ServiceCreateResultNotificationRequestOutput>> serviceCreateResultNotificationRequest(
643             ServiceCreateResultNotificationRequestInput input) {
644         // TODO Auto-generated method stub
645         return null;
646     }
647
648     @Override
649     public ListenableFuture<RpcResult<
650         ServiceDeleteResultNotificationRequestOutput>> serviceDeleteResultNotificationRequest(
651             ServiceDeleteResultNotificationRequestInput input) {
652         // TODO Auto-generated method stub
653         return null;
654     }
655
656     @Override
657     public ListenableFuture<RpcResult<
658         ServiceCreateComplexResultNotificationRequestOutput>> serviceCreateComplexResultNotificationRequest(
659             ServiceCreateComplexResultNotificationRequestInput input) {
660         // TODO Auto-generated method stub
661         return null;
662     }
663
664     @Override
665     public ListenableFuture<RpcResult<ServiceFeasibilityCheckBulkOutput>> serviceFeasibilityCheckBulk(
666         ServiceFeasibilityCheckBulkInput input) {
667         // TODO Auto-generated method stub
668         return null;
669     }
670
671     /**
672      * Send notification to NBI notification in order to publish message.
673      * @param service PublishNotificationService
674      */
675     private void sendNbiNotification(PublishNotificationService service) {
676         try {
677             notificationPublishService.putNotification(service);
678         } catch (InterruptedException e) {
679             LOG.warn("Cannot send notification to nbi", e);
680             Thread.currentThread().interrupt();
681         }
682     }
683 }