2 * Copyright © 2017 Orange, Inc. and others. All rights reserved.
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
8 package org.opendaylight.transportpce.servicehandler.listeners;
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.common.StringConstants;
14 import org.opendaylight.transportpce.networkmodel.service.NetworkModelService;
15 import org.opendaylight.transportpce.pce.service.PathComputationService;
16 import org.opendaylight.transportpce.servicehandler.ServiceInput;
17 import org.opendaylight.transportpce.servicehandler.service.PCEServiceWrapper;
18 import org.opendaylight.transportpce.servicehandler.service.ServiceDataStoreOperations;
19 import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.renderer.rev210618.RendererRpcResultSp;
20 import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.renderer.rev210618.TransportpceRendererListener;
21 import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.renderer.rev210618.renderer.rpc.result.sp.Link;
22 import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.servicehandler.rev201125.ServiceRpcResultSh;
23 import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.servicehandler.rev201125.ServiceRpcResultShBuilder;
24 import org.opendaylight.yang.gen.v1.http.org.openroadm.common.service.types.rev190531.ServiceNotificationTypes;
25 import org.opendaylight.yang.gen.v1.http.org.openroadm.common.state.types.rev191129.State;
26 import org.opendaylight.yang.gen.v1.http.org.openroadm.equipment.states.types.rev191129.AdminStates;
27 import org.opendaylight.yang.gen.v1.http.org.openroadm.service.rev190531.service.list.Services;
28 import org.opendaylight.yang.gen.v1.http.transportpce.topology.rev210511.OtnLinkType;
29 import org.opendaylight.yang.gen.v1.nbi.notifications.rev201130.PublishNotificationService;
30 import org.opendaylight.yang.gen.v1.nbi.notifications.rev201130.PublishNotificationServiceBuilder;
31 import org.opendaylight.yang.gen.v1.nbi.notifications.rev201130.notification.service.ServiceAEndBuilder;
32 import org.opendaylight.yang.gen.v1.nbi.notifications.rev201130.notification.service.ServiceZEndBuilder;
33 import org.opendaylight.yangtools.yang.common.Uint32;
34 import org.slf4j.Logger;
35 import org.slf4j.LoggerFactory;
38 * Calls to listen to Renderer notifications.
40 * @author Martial Coulibaly ( martial.coulibaly@gfi.com ) on behalf of Orange
43 public class RendererListenerImpl implements TransportpceRendererListener {
45 private static final String TOPIC = "RendererListener";
46 private static final Logger LOG = LoggerFactory.getLogger(RendererListenerImpl.class);
47 private RendererRpcResultSp serviceRpcResultSp;
48 private ServiceDataStoreOperations serviceDataStoreOperations;
49 private ServiceInput input;
50 private PCEServiceWrapper pceServiceWrapper;
51 private Boolean tempService;
52 private NotificationPublishService notificationPublishService;
53 private final NetworkModelService networkModelService;
56 public RendererListenerImpl(PathComputationService pathComputationService,
57 NotificationPublishService notificationPublishService, NetworkModelService networkModelService) {
58 this.pceServiceWrapper = new PCEServiceWrapper(pathComputationService, notificationPublishService);
59 setServiceInput(null);
60 setTempService(false);
61 this.notificationPublishService = notificationPublishService;
62 this.networkModelService = networkModelService;
66 public void onRendererRpcResultSp(RendererRpcResultSp notification) {
67 if (compareServiceRpcResultSp(notification)) {
68 LOG.warn("ServiceRpcResultSp already wired !");
71 serviceRpcResultSp = notification;
72 int notifType = serviceRpcResultSp.getNotificationType().getIntValue();
73 LOG.info("Renderer '{}' Notification received : {}", serviceRpcResultSp.getNotificationType().getName(),
76 /* service-implementation-request. */
78 onServiceImplementationResult(notification);
82 onServiceDeleteResult(notification);
90 * Process service delete result for serviceName.
91 * @param notification RendererRpcResultSp
93 private void onServiceDeleteResult(RendererRpcResultSp notification) {
94 switch (serviceRpcResultSp.getStatus()) {
96 LOG.info("Service '{}' deleted !", notification.getServiceName());
97 String serviceType = notification.getServiceType();
98 switch (serviceType) {
99 case StringConstants.SERVICE_TYPE_1GE:
100 case StringConstants.SERVICE_TYPE_10GE:
101 case StringConstants.SERVICE_TYPE_100GE_M:
102 Short tribPort = Short.valueOf(notification.getAToZDirection().getMinTribSlot().getValue()
104 Short minTribSlot = Short.valueOf(notification.getAToZDirection().getMinTribSlot().getValue()
106 updateOtnTopology(notification.getLink(), true, notification.getServiceType(),
107 notification.getAToZDirection().getRate(), tribPort, minTribSlot);
109 case StringConstants.SERVICE_TYPE_OTU4:
110 case StringConstants.SERVICE_TYPE_OTUC4:
111 case StringConstants.SERVICE_TYPE_ODU4:
112 case StringConstants.SERVICE_TYPE_ODUC4:
113 updateOtnTopology(notification.getLink(), true, notification.getServiceType(), null, null,
121 LOG.error("Renderer service delete failed !");
122 Services service = serviceDataStoreOperations.getService(input.getServiceName()).get();
123 sendNbiNotification(new PublishNotificationServiceBuilder()
124 .setServiceName(service.getServiceName())
125 .setServiceAEnd(new ServiceAEndBuilder(service.getServiceAEnd()).build())
126 .setServiceZEnd(new ServiceZEndBuilder(service.getServiceZEnd()).build())
127 .setCommonId(service.getCommonId())
128 .setConnectionType(service.getConnectionType())
129 .setResponseFailed("Renderer service delete failed !")
130 .setMessage("ServiceDelete request failed ...")
131 .setOperationalState(service.getOperationalState())
136 LOG.warn("Renderer service delete returned a Pending RpcStatusEx code!");
139 LOG.error("Renderer service delete returned an unknown RpcStatusEx code!");
142 LOG.info("Service '{}' deleted !", notification.getServiceName());
143 if (this.input == null) {
144 LOG.error("ServiceInput parameter is null !");
147 LOG.info("sending PCE cancel resource reserve for '{}'", this.input.getServiceName());
148 this.pceServiceWrapper.cancelPCEResource(this.input.getServiceName(),
149 ServiceNotificationTypes.ServiceDeleteResult);
150 sendServiceHandlerNotification(notification, ServiceNotificationTypes.ServiceDeleteResult);
154 * Process service implementation result for serviceName.
155 * @param notification RendererRpcResultSp
157 private void onServiceImplementationResult(RendererRpcResultSp notification) {
158 switch (serviceRpcResultSp.getStatus()) {
160 onSuccededServiceImplementation(notification);
163 onFailedServiceImplementation(notification.getServiceName());
166 LOG.warn("Service Implementation still pending according to RpcStatusEx");
169 LOG.warn("Service Implementation has an unknown RpcStatusEx code");
175 * Process succeeded service implementation for service.
176 * @param notification RendererRpcResultSp
178 private void onSuccededServiceImplementation(RendererRpcResultSp notification) {
179 LOG.info("Service implemented !");
180 if (serviceDataStoreOperations == null) {
181 LOG.debug("serviceDataStoreOperations is null");
184 String serviceType = notification.getServiceType();
185 switch (serviceType) {
186 case StringConstants.SERVICE_TYPE_1GE:
187 case StringConstants.SERVICE_TYPE_10GE:
188 case StringConstants.SERVICE_TYPE_100GE_M:
189 Short tribPort = Short.valueOf(notification.getAToZDirection().getMinTribSlot().getValue()
191 Short minTribSlot = Short.valueOf(notification.getAToZDirection().getMinTribSlot().getValue()
193 updateOtnTopology(notification.getLink(), false, notification.getServiceType(),
194 notification.getAToZDirection().getRate(), tribPort, minTribSlot);
196 case StringConstants.SERVICE_TYPE_OTU4:
197 case StringConstants.SERVICE_TYPE_OTUC4:
198 case StringConstants.SERVICE_TYPE_ODU4:
199 case StringConstants.SERVICE_TYPE_ODUC4:
200 updateOtnTopology(notification.getLink(), false, notification.getServiceType(), null, null, null);
205 PublishNotificationServiceBuilder nbiNotificationBuilder = new PublishNotificationServiceBuilder()
206 .setServiceName(input.getServiceName())
207 .setServiceAEnd(new ServiceAEndBuilder(input.getServiceAEnd()).build())
208 .setServiceZEnd(new ServiceZEndBuilder(input.getServiceZEnd()).build())
209 .setCommonId(input.getCommonId()).setConnectionType(input.getConnectionType())
211 OperationResult operationResult;
212 String serviceTemp = "";
214 operationResult = this.serviceDataStoreOperations.modifyTempService(
215 serviceRpcResultSp.getServiceName(), State.InService, AdminStates.InService);
216 serviceTemp = "Temp ";
218 operationResult = this.serviceDataStoreOperations.modifyService(
219 serviceRpcResultSp.getServiceName(), State.InService, AdminStates.InService);
221 if (operationResult.isSuccess()) {
222 sendNbiNotification(nbiNotificationBuilder
223 .setResponseFailed("")
224 .setMessage("Service implemented !")
225 .setOperationalState(org.opendaylight.yang.gen.v1.http
226 .org.openroadm.common.state.types.rev181130.State.InService)
229 sendServiceHandlerNotification(notification, ServiceNotificationTypes.ServiceCreateResult);
232 LOG.warn("{}Service status not updated in datastore !", serviceTemp);
233 sendNbiNotification(nbiNotificationBuilder
234 .setResponseFailed(serviceTemp + "Service status not updated in datastore !")
235 .setMessage("ServiceCreate request failed ...")
236 .setOperationalState(org.opendaylight.yang.gen.v1.http
237 .org.openroadm.common.state.types.rev181130.State.OutOfService)
243 * Create and send service handler notification.
244 * @param notification RendererRpcResultSp
245 * @param type ServiceNotificationTypes
247 private void sendServiceHandlerNotification(RendererRpcResultSp notification, ServiceNotificationTypes type) {
249 ServiceRpcResultSh serviceHandlerNotification = new ServiceRpcResultShBuilder()
250 .setAToZDirection(notification.getAToZDirection())
251 .setZToADirection(notification.getZToADirection())
252 .setServiceName(notification.getServiceName())
253 .setStatus(notification.getStatus())
254 .setStatusMessage(notification.getStatusMessage())
255 .setNotificationType(type)
257 LOG.debug("Service update in datastore OK, sending notification {}", serviceHandlerNotification);
258 notificationPublishService.putNotification(
259 serviceHandlerNotification);
260 } catch (InterruptedException e) {
261 LOG.warn("Something went wrong while sending notification for service {}",
262 serviceRpcResultSp.getServiceName(), e);
263 Thread.currentThread().interrupt();
268 * Process failed service implementation for serviceName.
269 * @param serviceName String
271 private void onFailedServiceImplementation(String serviceName) {
272 LOG.error("Renderer implementation failed !");
273 Services service = serviceDataStoreOperations.getService(input.getServiceName()).get();
274 sendNbiNotification(new PublishNotificationServiceBuilder()
275 .setServiceName(service.getServiceName())
276 .setServiceAEnd(new ServiceAEndBuilder(service.getServiceAEnd()).build())
277 .setServiceZEnd(new ServiceZEndBuilder(service.getServiceZEnd()).build())
278 .setCommonId(service.getCommonId())
279 .setConnectionType(service.getConnectionType())
280 .setResponseFailed("Renderer implementation failed !")
281 .setMessage("ServiceCreate request failed ...")
282 .setOperationalState(service.getOperationalState())
285 OperationResult deleteServicePathOperationResult =
286 this.serviceDataStoreOperations.deleteServicePath(serviceName);
287 if (!deleteServicePathOperationResult.isSuccess()) {
288 LOG.warn("Service path was not removed from datastore!");
290 OperationResult deleteServiceOperationResult;
291 String serviceType = "";
293 deleteServiceOperationResult = this.serviceDataStoreOperations.deleteTempService(serviceName);
294 serviceType = "Temp ";
296 deleteServiceOperationResult = this.serviceDataStoreOperations.deleteService(serviceName);
298 if (deleteServiceOperationResult.isSuccess()) {
299 LOG.warn("{}Service was not removed from datastore!", serviceType);
304 value = "ES_COMPARING_STRINGS_WITH_EQ",
305 justification = "false positives, not strings but real object references comparisons")
306 private Boolean compareServiceRpcResultSp(RendererRpcResultSp notification) {
307 if (serviceRpcResultSp == null) {
310 if (serviceRpcResultSp.getNotificationType() != notification.getNotificationType()) {
313 if (serviceRpcResultSp.getServiceName() != notification.getServiceName()) {
316 if (serviceRpcResultSp.getStatus() != notification.getStatus()) {
319 if (serviceRpcResultSp.getStatusMessage() != notification.getStatusMessage()) {
325 public void setServiceInput(ServiceInput serviceInput) {
326 this.input = serviceInput;
329 public void setserviceDataStoreOperations(ServiceDataStoreOperations serviceData) {
330 this.serviceDataStoreOperations = serviceData;
333 public void setTempService(Boolean tempService) {
334 this.tempService = tempService;
338 * Send notification to NBI notification in order to publish message.
339 * @param service PublishNotificationService
341 private void sendNbiNotification(PublishNotificationService service) {
343 notificationPublishService.putNotification(service);
344 } catch (InterruptedException e) {
345 LOG.warn("Cannot send notification to nbi", e);
346 Thread.currentThread().interrupt();
350 private void updateOtnTopology(Link link, boolean isDeletion, String serviceType, Uint32 rate, Short portNb,
355 OtnLinkType otnLinkType;
356 switch (serviceType) {
357 case StringConstants.SERVICE_TYPE_OTU4:
358 otnLinkType = OtnLinkType.OTU4;
360 case StringConstants.SERVICE_TYPE_OTUC4:
361 otnLinkType = OtnLinkType.OTUC4;
363 case StringConstants.SERVICE_TYPE_ODU4:
364 otnLinkType = OtnLinkType.ODTU4;
366 case StringConstants.SERVICE_TYPE_ODUC4:
367 otnLinkType = OtnLinkType.ODUC4;
371 LOG.warn("No otn-link-type corresponds to service-type {}", serviceType);
374 switch (serviceType) {
375 case StringConstants.SERVICE_TYPE_OTU4:
376 case StringConstants.SERVICE_TYPE_OTUC4:
377 case StringConstants.SERVICE_TYPE_ODU4:
378 case StringConstants.SERVICE_TYPE_ODUC4:
380 LOG.info("updating otn-topology removing links");
381 this.networkModelService.deleteOtnLinks(link.getATermination().getNodeId(),
382 link.getATermination().getTpId(), link.getZTermination().getNodeId(),
383 link.getZTermination().getTpId(), otnLinkType);
385 LOG.info("updating otn-topology adding links");
386 this.networkModelService.createOtnLinks(link.getATermination().getNodeId(),
387 link.getATermination().getTpId(), link.getZTermination().getNodeId(),
388 link.getZTermination().getTpId(), otnLinkType);
391 case StringConstants.SERVICE_TYPE_1GE:
392 case StringConstants.SERVICE_TYPE_10GE:
393 case StringConstants.SERVICE_TYPE_100GE_M:
394 LOG.info("updating otn-topology node tps -tps and tpn pools");
395 this.networkModelService.updateOtnLinks(link, rate, portNb, slotNb, isDeletion);