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 java.util.List;
13 import org.opendaylight.mdsal.binding.api.NotificationPublishService;
14 import org.opendaylight.transportpce.common.OperationResult;
15 import org.opendaylight.transportpce.common.StringConstants;
16 import org.opendaylight.transportpce.networkmodel.service.NetworkModelService;
17 import org.opendaylight.transportpce.pce.service.PathComputationService;
18 import org.opendaylight.transportpce.servicehandler.ServiceInput;
19 import org.opendaylight.transportpce.servicehandler.service.PCEServiceWrapper;
20 import org.opendaylight.transportpce.servicehandler.service.ServiceDataStoreOperations;
21 import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.renderer.rev210915.RendererRpcResultSp;
22 import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.renderer.rev210915.TransportpceRendererListener;
23 import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.renderer.rev210915.renderer.rpc.result.sp.Link;
24 import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.servicehandler.rev201125.ServiceRpcResultSh;
25 import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.servicehandler.rev201125.ServiceRpcResultShBuilder;
26 import org.opendaylight.yang.gen.v1.http.org.openroadm.common.service.types.rev190531.ServiceNotificationTypes;
27 import org.opendaylight.yang.gen.v1.http.org.openroadm.common.state.types.rev191129.State;
28 import org.opendaylight.yang.gen.v1.http.org.openroadm.equipment.states.types.rev191129.AdminStates;
29 import org.opendaylight.yang.gen.v1.http.org.openroadm.service.rev190531.service.list.Services;
30 import org.opendaylight.yang.gen.v1.http.transportpce.topology.rev220123.OtnLinkType;
31 import org.opendaylight.yang.gen.v1.nbi.notifications.rev210813.PublishNotificationProcessService;
32 import org.opendaylight.yang.gen.v1.nbi.notifications.rev210813.PublishNotificationProcessServiceBuilder;
33 import org.opendaylight.yang.gen.v1.nbi.notifications.rev210813.notification.process.service.ServiceAEndBuilder;
34 import org.opendaylight.yang.gen.v1.nbi.notifications.rev210813.notification.process.service.ServiceZEndBuilder;
35 import org.slf4j.Logger;
36 import org.slf4j.LoggerFactory;
39 * Calls to listen to Renderer notifications.
41 * @author Martial Coulibaly ( martial.coulibaly@gfi.com ) on behalf of Orange
44 public class RendererListenerImpl implements TransportpceRendererListener {
46 private static final String PUBLISHER = "RendererListener";
47 private static final Logger LOG = LoggerFactory.getLogger(RendererListenerImpl.class);
48 private RendererRpcResultSp serviceRpcResultSp;
49 private ServiceDataStoreOperations serviceDataStoreOperations;
50 private ServiceInput input;
51 private PCEServiceWrapper pceServiceWrapper;
52 private Boolean tempService;
53 private NotificationPublishService notificationPublishService;
54 private final NetworkModelService networkModelService;
57 public RendererListenerImpl(PathComputationService pathComputationService,
58 NotificationPublishService notificationPublishService, NetworkModelService networkModelService) {
59 this.pceServiceWrapper = new PCEServiceWrapper(pathComputationService, notificationPublishService);
60 setServiceInput(null);
61 setTempService(false);
62 this.notificationPublishService = notificationPublishService;
63 this.networkModelService = networkModelService;
67 public void onRendererRpcResultSp(RendererRpcResultSp notification) {
68 if (compareServiceRpcResultSp(notification)) {
69 LOG.warn("ServiceRpcResultSp already wired !");
72 serviceRpcResultSp = notification;
73 int notifType = serviceRpcResultSp.getNotificationType().getIntValue();
74 LOG.info("Renderer '{}' Notification received : {}", serviceRpcResultSp.getNotificationType().getName(),
77 /* service-implementation-request. */
79 onServiceImplementationResult(notification);
83 onServiceDeleteResult(notification);
91 * Process service delete result for serviceName.
92 * @param notification RendererRpcResultSp
94 private void onServiceDeleteResult(RendererRpcResultSp notification) {
95 switch (serviceRpcResultSp.getStatus()) {
97 updateOtnTopology(notification, true);
100 LOG.error("Renderer service delete failed !");
101 Services service = serviceDataStoreOperations.getService(input.getServiceName()).get();
102 sendNbiNotification(new PublishNotificationProcessServiceBuilder()
103 .setServiceName(service.getServiceName())
104 .setServiceAEnd(new ServiceAEndBuilder(service.getServiceAEnd()).build())
105 .setServiceZEnd(new ServiceZEndBuilder(service.getServiceZEnd()).build())
106 .setCommonId(service.getCommonId())
107 .setConnectionType(service.getConnectionType())
108 .setResponseFailed("Renderer service delete failed !")
109 .setMessage("ServiceDelete request failed ...")
110 .setOperationalState(service.getOperationalState())
111 .setPublisherName(PUBLISHER)
115 LOG.warn("Renderer service delete returned a Pending RpcStatusEx code!");
118 LOG.error("Renderer service delete returned an unknown RpcStatusEx code!");
121 LOG.info("Service '{}' deleted !", notification.getServiceName());
122 if (this.input == null) {
123 LOG.error("ServiceInput parameter is null !");
126 LOG.info("sending PCE cancel resource reserve for '{}'", this.input.getServiceName());
127 this.pceServiceWrapper.cancelPCEResource(this.input.getServiceName(),
128 ServiceNotificationTypes.ServiceDeleteResult);
129 sendServiceHandlerNotification(notification, ServiceNotificationTypes.ServiceDeleteResult);
133 * Process service implementation result for serviceName.
134 * @param notification RendererRpcResultSp
136 private void onServiceImplementationResult(RendererRpcResultSp notification) {
137 switch (serviceRpcResultSp.getStatus()) {
139 onSuccededServiceImplementation(notification);
142 onFailedServiceImplementation(notification.getServiceName());
145 LOG.warn("Service Implementation still pending according to RpcStatusEx");
148 LOG.warn("Service Implementation has an unknown RpcStatusEx code");
154 * Process succeeded service implementation for service.
155 * @param notification RendererRpcResultSp
157 private void onSuccededServiceImplementation(RendererRpcResultSp notification) {
158 LOG.info("Service implemented !");
159 if (serviceDataStoreOperations == null) {
160 LOG.debug("serviceDataStoreOperations is null");
164 updateOtnTopology(notification, false);
166 PublishNotificationProcessServiceBuilder nbiNotificationBuilder = new PublishNotificationProcessServiceBuilder()
167 .setServiceName(input.getServiceName())
168 .setServiceAEnd(new ServiceAEndBuilder(input.getServiceAEnd()).build())
169 .setServiceZEnd(new ServiceZEndBuilder(input.getServiceZEnd()).build())
170 .setCommonId(input.getCommonId()).setConnectionType(input.getConnectionType())
171 .setPublisherName(PUBLISHER);
172 OperationResult operationResult;
173 String serviceTemp = "";
175 operationResult = this.serviceDataStoreOperations.modifyTempService(
176 serviceRpcResultSp.getServiceName(), State.InService, AdminStates.InService);
177 serviceTemp = "Temp ";
179 operationResult = this.serviceDataStoreOperations.modifyService(
180 serviceRpcResultSp.getServiceName(), State.InService, AdminStates.InService);
182 if (operationResult.isSuccess()) {
183 sendNbiNotification(nbiNotificationBuilder
184 .setResponseFailed("")
185 .setMessage("Service implemented !")
186 .setOperationalState(org.opendaylight.yang.gen.v1.http
187 .org.openroadm.common.state.types.rev181130.State.InService)
190 sendServiceHandlerNotification(notification, ServiceNotificationTypes.ServiceCreateResult);
193 LOG.warn("{}Service status not updated in datastore !", serviceTemp);
194 sendNbiNotification(nbiNotificationBuilder
195 .setResponseFailed(serviceTemp + "Service status not updated in datastore !")
196 .setMessage("ServiceCreate request failed ...")
197 .setOperationalState(org.opendaylight.yang.gen.v1.http
198 .org.openroadm.common.state.types.rev181130.State.OutOfService)
204 * Create and send service handler notification.
205 * @param notification RendererRpcResultSp
206 * @param type ServiceNotificationTypes
208 private void sendServiceHandlerNotification(RendererRpcResultSp notification, ServiceNotificationTypes type) {
210 ServiceRpcResultSh serviceHandlerNotification = new ServiceRpcResultShBuilder()
211 .setAToZDirection(notification.getAToZDirection())
212 .setZToADirection(notification.getZToADirection())
213 .setServiceName(notification.getServiceName())
214 .setStatus(notification.getStatus())
215 .setStatusMessage(notification.getStatusMessage())
216 .setNotificationType(type)
218 LOG.debug("Service update in datastore OK, sending notification {}", serviceHandlerNotification);
219 notificationPublishService.putNotification(
220 serviceHandlerNotification);
221 } catch (InterruptedException e) {
222 LOG.warn("Something went wrong while sending notification for service {}",
223 serviceRpcResultSp.getServiceName(), e);
224 Thread.currentThread().interrupt();
229 * Process failed service implementation for serviceName.
230 * @param serviceName String
232 private void onFailedServiceImplementation(String serviceName) {
233 LOG.error("Renderer implementation failed !");
234 Services service = serviceDataStoreOperations.getService(input.getServiceName()).get();
235 sendNbiNotification(new PublishNotificationProcessServiceBuilder()
236 .setServiceName(service.getServiceName())
237 .setServiceAEnd(new ServiceAEndBuilder(service.getServiceAEnd()).build())
238 .setServiceZEnd(new ServiceZEndBuilder(service.getServiceZEnd()).build())
239 .setCommonId(service.getCommonId())
240 .setConnectionType(service.getConnectionType())
241 .setResponseFailed("Renderer implementation failed !")
242 .setMessage("ServiceCreate request failed ...")
243 .setOperationalState(service.getOperationalState())
244 .setPublisherName(PUBLISHER)
246 OperationResult deleteServicePathOperationResult =
247 this.serviceDataStoreOperations.deleteServicePath(serviceName);
248 if (!deleteServicePathOperationResult.isSuccess()) {
249 LOG.warn("Service path was not removed from datastore!");
251 OperationResult deleteServiceOperationResult;
252 String serviceType = "";
254 deleteServiceOperationResult = this.serviceDataStoreOperations.deleteTempService(serviceName);
255 serviceType = "Temp ";
257 deleteServiceOperationResult = this.serviceDataStoreOperations.deleteService(serviceName);
259 if (deleteServiceOperationResult.isSuccess()) {
260 LOG.warn("{}Service was not removed from datastore!", serviceType);
265 value = "ES_COMPARING_STRINGS_WITH_EQ",
266 justification = "false positives, not strings but real object references comparisons")
267 private Boolean compareServiceRpcResultSp(RendererRpcResultSp notification) {
268 if (serviceRpcResultSp == null
269 || serviceRpcResultSp.getNotificationType() != notification.getNotificationType()
270 || serviceRpcResultSp.getServiceName() != notification.getServiceName()
271 || serviceRpcResultSp.getStatus() != notification.getStatus()
272 || serviceRpcResultSp.getStatusMessage() != notification.getStatusMessage()) {
278 public void setServiceInput(ServiceInput serviceInput) {
279 this.input = serviceInput;
282 public void setserviceDataStoreOperations(ServiceDataStoreOperations serviceData) {
283 this.serviceDataStoreOperations = serviceData;
286 public void setTempService(Boolean tempService) {
287 this.tempService = tempService;
291 * Send notification to NBI notification in order to publish message.
292 * @param service PublishNotificationService
294 private void sendNbiNotification(PublishNotificationProcessService service) {
296 notificationPublishService.putNotification(service);
297 } catch (InterruptedException e) {
298 LOG.warn("Cannot send notification to nbi", e);
299 Thread.currentThread().interrupt();
304 private void updateOtnTopology(RendererRpcResultSp notification, boolean isDeletion) {
305 Link link = notification.getLink();
306 List<String> supportedLinkIds = notification.getLinkId();
307 if (link == null && supportedLinkIds == null) {
311 String serviceType = notification.getServiceType();
312 switch (serviceType) {
313 case StringConstants.SERVICE_TYPE_OTU4:
314 case StringConstants.SERVICE_TYPE_OTUC2:
315 case StringConstants.SERVICE_TYPE_OTUC3:
316 case StringConstants.SERVICE_TYPE_OTUC4:
317 case StringConstants.SERVICE_TYPE_ODU4:
318 case StringConstants.SERVICE_TYPE_ODUC2:
319 case StringConstants.SERVICE_TYPE_ODUC3:
320 case StringConstants.SERVICE_TYPE_ODUC4:
321 Map<String, OtnLinkType> otnLinkTypeMap = Map.of(
322 StringConstants.SERVICE_TYPE_OTU4, OtnLinkType.OTU4,
323 // TODO: need to change it when OtnLinkType is updated with enum
324 StringConstants.SERVICE_TYPE_OTUC2, OtnLinkType.OTUC4,
325 StringConstants.SERVICE_TYPE_OTUC3, OtnLinkType.OTUC4,
326 StringConstants.SERVICE_TYPE_OTUC4, OtnLinkType.OTUC4,
327 StringConstants.SERVICE_TYPE_ODU4, OtnLinkType.ODTU4,
328 // TODO: need to change it when OtnLinkType is updated with enum
329 StringConstants.SERVICE_TYPE_ODUC2, OtnLinkType.ODUC4,
330 StringConstants.SERVICE_TYPE_ODUC3, OtnLinkType.ODUC4,
331 StringConstants.SERVICE_TYPE_ODUC4, OtnLinkType.ODUC4);
333 LOG.info("updating otn-topology removing links");
334 this.networkModelService.deleteOtnLinks(link, supportedLinkIds, otnLinkTypeMap.get(serviceType));
336 LOG.info("updating otn-topology adding links");
337 this.networkModelService.createOtnLinks(link, supportedLinkIds, otnLinkTypeMap.get(serviceType));
340 case StringConstants.SERVICE_TYPE_1GE:
341 case StringConstants.SERVICE_TYPE_10GE:
342 case StringConstants.SERVICE_TYPE_100GE_M:
343 Short tribPort = Short.valueOf(notification.getAToZDirection().getMinTribSlot().getValue()
345 Short minTribSlot = Short.valueOf(notification.getAToZDirection().getMinTribSlot().getValue()
347 Short maxTribSlot = Short.valueOf(notification.getAToZDirection().getMaxTribSlot().getValue()
349 LOG.info("updating otn-topology node tps -tps and tpn pools");
350 this.networkModelService.updateOtnLinks(link, supportedLinkIds,
351 notification.getAToZDirection().getRate(), tribPort, minTribSlot, maxTribSlot, isDeletion);
353 case StringConstants.SERVICE_TYPE_100GE_S:
354 this.networkModelService.updateOtnLinks(supportedLinkIds, isDeletion);
357 LOG.warn("service-type {} not managed yet", serviceType);