Merge "Updated OLM module to support 7.1 devices"
[transportpce.git] / servicehandler / src / main / java / org / opendaylight / transportpce / servicehandler / listeners / RendererListenerImpl.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.listeners;
9
10 import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
11 import org.opendaylight.mdsal.binding.api.NotificationPublishService;
12 import org.opendaylight.transportpce.common.OperationResult;
13 import org.opendaylight.transportpce.pce.service.PathComputationService;
14 import org.opendaylight.transportpce.servicehandler.ServiceInput;
15 import org.opendaylight.transportpce.servicehandler.service.PCEServiceWrapper;
16 import org.opendaylight.transportpce.servicehandler.service.ServiceDataStoreOperations;
17 import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.renderer.rev201125.RendererRpcResultSp;
18 import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.renderer.rev201125.TransportpceRendererListener;
19 import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.servicehandler.rev201125.ServiceRpcResultSh;
20 import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.servicehandler.rev201125.ServiceRpcResultShBuilder;
21 import org.opendaylight.yang.gen.v1.http.org.openroadm.common.service.types.rev190531.ServiceNotificationTypes;
22 import org.opendaylight.yang.gen.v1.http.org.openroadm.common.state.types.rev181130.State;
23 import org.opendaylight.yang.gen.v1.http.org.openroadm.equipment.states.types.rev181130.AdminStates;
24 import org.opendaylight.yang.gen.v1.http.org.openroadm.service.rev190531.service.list.Services;
25 import org.opendaylight.yang.gen.v1.nbi.notifications.rev201130.PublishNotificationService;
26 import org.opendaylight.yang.gen.v1.nbi.notifications.rev201130.PublishNotificationServiceBuilder;
27 import org.opendaylight.yang.gen.v1.nbi.notifications.rev201130.notification.service.ServiceAEndBuilder;
28 import org.opendaylight.yang.gen.v1.nbi.notifications.rev201130.notification.service.ServiceZEndBuilder;
29 import org.slf4j.Logger;
30 import org.slf4j.LoggerFactory;
31
32 /**
33  * Calls to listen to Renderer notifications.
34  *
35  * @author Martial Coulibaly ( martial.coulibaly@gfi.com ) on behalf of Orange
36  *
37  */
38 public class RendererListenerImpl implements TransportpceRendererListener {
39
40     private static final String TOPIC = "RendererListener";
41     private static final Logger LOG = LoggerFactory.getLogger(RendererListenerImpl.class);
42     private RendererRpcResultSp serviceRpcResultSp;
43     private ServiceDataStoreOperations serviceDataStoreOperations;
44     private ServiceInput input;
45     private PCEServiceWrapper pceServiceWrapper;
46     private Boolean tempService;
47     private NotificationPublishService notificationPublishService;
48
49     public RendererListenerImpl(PathComputationService pathComputationService,
50             NotificationPublishService notificationPublishService) {
51         this.pceServiceWrapper = new PCEServiceWrapper(pathComputationService, notificationPublishService);
52         setServiceInput(null);
53         setTempService(false);
54         this.notificationPublishService = notificationPublishService;
55     }
56
57     @Override
58     public void onRendererRpcResultSp(RendererRpcResultSp notification) {
59         if (compareServiceRpcResultSp(notification)) {
60             LOG.warn("ServiceRpcResultSp already wired !");
61             return;
62         }
63         serviceRpcResultSp = notification;
64         int notifType = serviceRpcResultSp.getNotificationType().getIntValue();
65         LOG.info("Renderer '{}' Notification received : {}", serviceRpcResultSp.getNotificationType().getName(),
66                 notification);
67         switch (notifType) {
68             /* service-implementation-request. */
69             case 3 :
70                 onServiceImplementationResult(notification);
71                 break;
72             /* service-delete. */
73             case 4 :
74                 onServiceDeleteResult(notification);
75                 break;
76             default:
77                 break;
78         }
79     }
80
81     /**
82      * Process service delete result for serviceName.
83      * @param notification RendererRpcResultSp
84      */
85     private void onServiceDeleteResult(RendererRpcResultSp notification) {
86         switch (serviceRpcResultSp.getStatus()) {
87             case Successful:
88                 LOG.info("Service '{}' deleted !", notification.getServiceName());
89                 break;
90             case Failed:
91                 LOG.error("Renderer service delete failed !");
92                 return;
93             case  Pending:
94                 LOG.warn("Renderer service delete returned a Penging RpcStatusEx code!");
95                 return;
96             default:
97                 LOG.error("Renderer service delete returned an unknown RpcStatusEx code!");
98                 return;
99         }
100         Services service = serviceDataStoreOperations.getService(notification.getServiceName()).get();
101         PublishNotificationService nbiNotification = new PublishNotificationServiceBuilder()
102                 .setServiceName(service.getServiceName())
103                 .setServiceAEnd(new ServiceAEndBuilder(service.getServiceAEnd()).build())
104                 .setServiceZEnd(new ServiceZEndBuilder(service.getServiceZEnd()).build())
105                 .setCommonId(service.getCommonId())
106                 .setConnectionType(service.getConnectionType())
107                 .setResponseFailed("")
108                 .setMessage("Service deleted !")
109                 .setOperationalState(org.opendaylight.yang.gen.v1.http
110                         .org.openroadm.common.state.types.rev181130.State.Degraded)
111                 .setTopic(TOPIC)
112                 .build();
113         sendNbiNotification(nbiNotification);
114         LOG.info("Service '{}' deleted !", notification.getServiceName());
115         if (this.input == null) {
116             LOG.error("ServiceInput parameter is null !");
117             return;
118         }
119         LOG.info("sending PCE cancel resource reserve for '{}'",  this.input.getServiceName());
120         this.pceServiceWrapper.cancelPCEResource(this.input.getServiceName(),
121                 ServiceNotificationTypes.ServiceDeleteResult);
122         sendServiceHandlerNotification(notification, ServiceNotificationTypes.ServiceDeleteResult);
123     }
124
125     /**
126      * Process service implementation result for serviceName.
127      * @param notification RendererRpcResultSp
128      */
129     private void onServiceImplementationResult(RendererRpcResultSp notification) {
130         switch (serviceRpcResultSp.getStatus()) {
131             case Successful:
132                 onSuccededServiceImplementation(notification);
133                 break;
134             case Failed:
135                 onFailedServiceImplementation(notification.getServiceName());
136                 break;
137             case  Pending:
138                 LOG.warn("Service Implementation still pending according to RpcStatusEx");
139                 break;
140             default:
141                 LOG.warn("Service Implementation has an unknown RpcStatusEx code");
142                 break;
143         }
144     }
145
146     /**
147      * Process succeeded service implementation for service.
148      * @param notification RendererRpcResultSp
149      */
150     private void onSuccededServiceImplementation(RendererRpcResultSp notification) {
151         LOG.info("Service implemented !");
152         PublishNotificationService nbiNotification = new PublishNotificationServiceBuilder()
153                 .setServiceName(input.getServiceName())
154                 .setServiceAEnd(new ServiceAEndBuilder(input.getServiceAEnd()).build())
155                 .setServiceZEnd(new ServiceZEndBuilder(input.getServiceZEnd()).build())
156                 .setCommonId(input.getCommonId()).setConnectionType(input.getConnectionType())
157                 .setResponseFailed("")
158                 .setMessage("Service implemented !")
159                 .setOperationalState(org.opendaylight.yang.gen.v1.http
160                         .org.openroadm.common.state.types.rev181130.State.InService)
161                 .setTopic(TOPIC)
162                 .build();
163         sendNbiNotification(nbiNotification);
164         if (serviceDataStoreOperations == null) {
165             LOG.debug("serviceDataStoreOperations is null");
166             return;
167         }
168         OperationResult operationResult = null;
169         if (tempService) {
170             operationResult = this.serviceDataStoreOperations.modifyTempService(
171                     serviceRpcResultSp.getServiceName(), State.InService, AdminStates.InService);
172             if (!operationResult.isSuccess()) {
173                 LOG.warn("Temp Service status not updated in datastore !");
174             }
175         } else {
176             operationResult = this.serviceDataStoreOperations.modifyService(
177                     serviceRpcResultSp.getServiceName(), State.InService, AdminStates.InService);
178             if (!operationResult.isSuccess()) {
179                 LOG.warn("Service status not updated in datastore !");
180             } else {
181                 sendServiceHandlerNotification(notification, ServiceNotificationTypes.ServiceCreateResult);
182             }
183         }
184     }
185
186     /**
187      * Create and send service handler notification.
188      * @param notification RendererRpcResultSp
189      * @param type ServiceNotificationTypes
190      */
191     private void sendServiceHandlerNotification(RendererRpcResultSp notification, ServiceNotificationTypes type) {
192         try {
193             ServiceRpcResultSh serviceHandlerNotification = new ServiceRpcResultShBuilder()
194                     .setAToZDirection(notification.getAToZDirection())
195                     .setZToADirection(notification.getZToADirection())
196                     .setServiceName(notification.getServiceName())
197                     .setStatus(notification.getStatus())
198                     .setStatusMessage(notification.getStatusMessage())
199                     .setNotificationType(type)
200                     .build();
201             LOG.debug("Service update in datastore OK, sending notification {}", serviceHandlerNotification);
202             notificationPublishService.putNotification(
203                     serviceHandlerNotification);
204         } catch (InterruptedException e) {
205             LOG.warn("Something went wrong while sending notification for sevice {}",
206                     serviceRpcResultSp.getServiceName(), e);
207             Thread.currentThread().interrupt();
208         }
209     }
210
211     /**
212      * Process failed service implementation for serviceName.
213      * @param serviceName String
214      */
215     private void onFailedServiceImplementation(String serviceName) {
216         LOG.error("Renderer implementation failed !");
217         OperationResult deleteServicePathOperationResult =
218                 this.serviceDataStoreOperations.deleteServicePath(serviceName);
219         if (!deleteServicePathOperationResult.isSuccess()) {
220             LOG.warn("Service path was not removed from datastore!");
221         }
222         if (tempService) {
223             OperationResult deleteServiceOperationResult =
224                     this.serviceDataStoreOperations.deleteTempService(serviceName);
225             if (!deleteServiceOperationResult.isSuccess()) {
226                 LOG.warn("Temp Service was not removed from datastore!");
227             }
228         } else {
229             OperationResult deleteServiceOperationResult =
230                     this.serviceDataStoreOperations.deleteService(serviceName);
231             if (!deleteServiceOperationResult.isSuccess()) {
232                 LOG.warn("Service was not removed from datastore!");
233             }
234         }
235     }
236
237     @SuppressFBWarnings(
238         value = "ES_COMPARING_STRINGS_WITH_EQ",
239         justification = "false positives, not strings but real object references comparisons")
240     private Boolean compareServiceRpcResultSp(RendererRpcResultSp notification) {
241         if (serviceRpcResultSp == null) {
242             return false;
243         }
244         if (serviceRpcResultSp.getNotificationType() != notification.getNotificationType()) {
245             return false;
246         }
247         if (serviceRpcResultSp.getServiceName() != notification.getServiceName()) {
248             return false;
249         }
250         if (serviceRpcResultSp.getStatus() != notification.getStatus()) {
251             return false;
252         }
253         if (serviceRpcResultSp.getStatusMessage() != notification.getStatusMessage()) {
254             return false;
255         }
256         return true;
257     }
258
259     public void setServiceInput(ServiceInput serviceInput) {
260         this.input = serviceInput;
261     }
262
263     public void setserviceDataStoreOperations(ServiceDataStoreOperations serviceData) {
264         this.serviceDataStoreOperations = serviceData;
265     }
266
267     public void setTempService(Boolean tempService) {
268         this.tempService = tempService;
269     }
270
271     /**
272      * Send notification to NBI notification in order to publish message.
273      * @param service PublishNotificationService
274      */
275     private void sendNbiNotification(PublishNotificationService service) {
276         try {
277             notificationPublishService.putNotification(service);
278         } catch (InterruptedException e) {
279             LOG.warn("Cannot send notification to nbi", e);
280             Thread.currentThread().interrupt();
281         }
282     }
283 }