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.rev211210.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.rev211210.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(State.InService)
189 sendServiceHandlerNotification(notification, ServiceNotificationTypes.ServiceCreateResult);
192 LOG.warn("{}Service status not updated in datastore !", serviceTemp);
193 sendNbiNotification(nbiNotificationBuilder
194 .setResponseFailed(serviceTemp + "Service status not updated in datastore !")
195 .setMessage("ServiceCreate request failed ...")
196 .setOperationalState(State.OutOfService)
202 * Create and send service handler notification.
203 * @param notification RendererRpcResultSp
204 * @param type ServiceNotificationTypes
206 private void sendServiceHandlerNotification(RendererRpcResultSp notification, ServiceNotificationTypes type) {
208 ServiceRpcResultSh serviceHandlerNotification = new ServiceRpcResultShBuilder()
209 .setAToZDirection(notification.getAToZDirection())
210 .setZToADirection(notification.getZToADirection())
211 .setServiceName(notification.getServiceName())
212 .setStatus(notification.getStatus())
213 .setStatusMessage(notification.getStatusMessage())
214 .setNotificationType(type)
216 LOG.debug("Service update in datastore OK, sending notification {}", serviceHandlerNotification);
217 notificationPublishService.putNotification(
218 serviceHandlerNotification);
219 } catch (InterruptedException e) {
220 LOG.warn("Something went wrong while sending notification for service {}",
221 serviceRpcResultSp.getServiceName(), e);
222 Thread.currentThread().interrupt();
227 * Process failed service implementation for serviceName.
228 * @param serviceName String
230 private void onFailedServiceImplementation(String serviceName) {
231 LOG.error("Renderer implementation failed !");
232 Services service = serviceDataStoreOperations.getService(input.getServiceName()).get();
233 sendNbiNotification(new PublishNotificationProcessServiceBuilder()
234 .setServiceName(service.getServiceName())
235 .setServiceAEnd(new ServiceAEndBuilder(service.getServiceAEnd()).build())
236 .setServiceZEnd(new ServiceZEndBuilder(service.getServiceZEnd()).build())
237 .setCommonId(service.getCommonId())
238 .setConnectionType(service.getConnectionType())
239 .setResponseFailed("Renderer implementation failed !")
240 .setMessage("ServiceCreate request failed ...")
241 .setOperationalState(service.getOperationalState())
242 .setPublisherName(PUBLISHER)
244 OperationResult deleteServicePathOperationResult =
245 this.serviceDataStoreOperations.deleteServicePath(serviceName);
246 if (!deleteServicePathOperationResult.isSuccess()) {
247 LOG.warn("Service path was not removed from datastore!");
249 OperationResult deleteServiceOperationResult;
250 String serviceType = "";
252 deleteServiceOperationResult = this.serviceDataStoreOperations.deleteTempService(serviceName);
253 serviceType = "Temp ";
255 deleteServiceOperationResult = this.serviceDataStoreOperations.deleteService(serviceName);
257 if (deleteServiceOperationResult.isSuccess()) {
258 LOG.warn("{}Service was not removed from datastore!", serviceType);
263 value = "ES_COMPARING_STRINGS_WITH_EQ",
264 justification = "false positives, not strings but real object references comparisons")
265 private Boolean compareServiceRpcResultSp(RendererRpcResultSp notification) {
266 if (serviceRpcResultSp == null
267 || serviceRpcResultSp.getNotificationType() != notification.getNotificationType()
268 || serviceRpcResultSp.getServiceName() != notification.getServiceName()
269 || serviceRpcResultSp.getStatus() != notification.getStatus()
270 || serviceRpcResultSp.getStatusMessage() != notification.getStatusMessage()) {
276 public void setServiceInput(ServiceInput serviceInput) {
277 this.input = serviceInput;
280 public void setserviceDataStoreOperations(ServiceDataStoreOperations serviceData) {
281 this.serviceDataStoreOperations = serviceData;
284 public void setTempService(Boolean tempService) {
285 this.tempService = tempService;
289 * Send notification to NBI notification in order to publish message.
290 * @param service PublishNotificationService
292 private void sendNbiNotification(PublishNotificationProcessService service) {
294 notificationPublishService.putNotification(service);
295 } catch (InterruptedException e) {
296 LOG.warn("Cannot send notification to nbi", e);
297 Thread.currentThread().interrupt();
302 private void updateOtnTopology(RendererRpcResultSp notification, boolean isDeletion) {
303 Link link = notification.getLink();
304 List<String> supportedLinkIds = notification.getLinkId();
305 if (link == null && supportedLinkIds == null) {
309 String serviceType = notification.getServiceType();
310 switch (serviceType) {
311 case StringConstants.SERVICE_TYPE_OTU4:
312 case StringConstants.SERVICE_TYPE_OTUC2:
313 case StringConstants.SERVICE_TYPE_OTUC3:
314 case StringConstants.SERVICE_TYPE_OTUC4:
315 case StringConstants.SERVICE_TYPE_ODU4:
316 case StringConstants.SERVICE_TYPE_ODUC2:
317 case StringConstants.SERVICE_TYPE_ODUC3:
318 case StringConstants.SERVICE_TYPE_ODUC4:
319 Map<String, OtnLinkType> otnLinkTypeMap = Map.of(
320 StringConstants.SERVICE_TYPE_OTU4, OtnLinkType.OTU4,
321 // TODO: need to change it when OtnLinkType is updated with enum
322 StringConstants.SERVICE_TYPE_OTUC2, OtnLinkType.OTUC4,
323 StringConstants.SERVICE_TYPE_OTUC3, OtnLinkType.OTUC4,
324 StringConstants.SERVICE_TYPE_OTUC4, OtnLinkType.OTUC4,
325 StringConstants.SERVICE_TYPE_ODU4, OtnLinkType.ODTU4,
326 // TODO: need to change it when OtnLinkType is updated with enum
327 StringConstants.SERVICE_TYPE_ODUC2, OtnLinkType.ODUC4,
328 StringConstants.SERVICE_TYPE_ODUC3, OtnLinkType.ODUC4,
329 StringConstants.SERVICE_TYPE_ODUC4, OtnLinkType.ODUC4);
331 LOG.info("updating otn-topology removing links");
332 this.networkModelService.deleteOtnLinks(link, supportedLinkIds, otnLinkTypeMap.get(serviceType));
334 LOG.info("updating otn-topology adding links");
335 this.networkModelService.createOtnLinks(link, supportedLinkIds, otnLinkTypeMap.get(serviceType));
338 case StringConstants.SERVICE_TYPE_1GE:
339 case StringConstants.SERVICE_TYPE_10GE:
340 case StringConstants.SERVICE_TYPE_100GE_M:
341 Short tribPort = Short.valueOf(notification.getAToZDirection().getMinTribSlot().getValue()
343 Short minTribSlot = Short.valueOf(notification.getAToZDirection().getMinTribSlot().getValue()
345 Short maxTribSlot = Short.valueOf(notification.getAToZDirection().getMaxTribSlot().getValue()
347 LOG.info("updating otn-topology node tps -tps and tpn pools");
348 this.networkModelService.updateOtnLinks(link, supportedLinkIds,
349 notification.getAToZDirection().getRate(), tribPort, minTribSlot, maxTribSlot, isDeletion);
351 case StringConstants.SERVICE_TYPE_100GE_S:
352 this.networkModelService.updateOtnLinks(supportedLinkIds, isDeletion);
355 LOG.warn("service-type {} not managed yet", serviceType);