X-Git-Url: https://git.opendaylight.org/gerrit/gitweb?a=blobdiff_plain;f=servicehandler%2Fsrc%2Fmain%2Fjava%2Forg%2Fopendaylight%2Ftransportpce%2Fservicehandler%2Flisteners%2FServiceListener.java;h=967cbe4ff08404997ef7ce4c8ff9c5866daea435;hb=b1b3bafd549bb501937cea5c976d5344608b6ed3;hp=64d46b4cf7f33bbf4431f5c0f1078d52d147dc32;hpb=966354326af4a6dd4fa05ceca0ac02ee82721242;p=transportpce.git diff --git a/servicehandler/src/main/java/org/opendaylight/transportpce/servicehandler/listeners/ServiceListener.java b/servicehandler/src/main/java/org/opendaylight/transportpce/servicehandler/listeners/ServiceListener.java index 64d46b4cf..967cbe4ff 100644 --- a/servicehandler/src/main/java/org/opendaylight/transportpce/servicehandler/listeners/ServiceListener.java +++ b/servicehandler/src/main/java/org/opendaylight/transportpce/servicehandler/listeners/ServiceListener.java @@ -9,8 +9,8 @@ package org.opendaylight.transportpce.servicehandler.listeners; import com.google.common.util.concurrent.ListenableFuture; import com.google.common.util.concurrent.MoreExecutors; -import java.util.Collection; import java.util.HashMap; +import java.util.List; import java.util.Map; import java.util.Optional; import java.util.concurrent.ExecutionException; @@ -21,59 +21,73 @@ import org.opendaylight.mdsal.binding.api.DataObjectModification; import org.opendaylight.mdsal.binding.api.DataTreeChangeListener; import org.opendaylight.mdsal.binding.api.DataTreeModification; import org.opendaylight.mdsal.binding.api.NotificationPublishService; +import org.opendaylight.mdsal.binding.api.RpcService; import org.opendaylight.transportpce.common.ResponseCodes; import org.opendaylight.transportpce.servicehandler.ServiceInput; -import org.opendaylight.transportpce.servicehandler.impl.ServicehandlerImpl; import org.opendaylight.transportpce.servicehandler.service.ServiceDataStoreOperations; -import org.opendaylight.yang.gen.v1.http.org.openroadm.common.service.types.rev211210.Restorable; -import org.opendaylight.yang.gen.v1.http.org.openroadm.common.service.types.rev211210.RpcActions; -import org.opendaylight.yang.gen.v1.http.org.openroadm.common.service.types.rev211210.sdnc.request.header.SdncRequestHeaderBuilder; +import org.opendaylight.yang.gen.v1.http.org.openroadm.common.service.types.rev230526.Restorable; +import org.opendaylight.yang.gen.v1.http.org.openroadm.common.service.types.rev230526.RpcActions; +import org.opendaylight.yang.gen.v1.http.org.openroadm.common.service.types.rev230526.routing.metric.RoutingMetric; +import org.opendaylight.yang.gen.v1.http.org.openroadm.common.service.types.rev230526.sdnc.request.header.SdncRequestHeaderBuilder; +import org.opendaylight.yang.gen.v1.http.org.openroadm.common.service.types.rev230526.service.resiliency.ServiceResiliency; import org.opendaylight.yang.gen.v1.http.org.openroadm.common.state.types.rev191129.State; import org.opendaylight.yang.gen.v1.http.org.openroadm.equipment.states.types.rev191129.AdminStates; -import org.opendaylight.yang.gen.v1.http.org.openroadm.service.rev211210.ServiceCreateInputBuilder; -import org.opendaylight.yang.gen.v1.http.org.openroadm.service.rev211210.ServiceCreateOutput; -import org.opendaylight.yang.gen.v1.http.org.openroadm.service.rev211210.ServiceDeleteInputBuilder; -import org.opendaylight.yang.gen.v1.http.org.openroadm.service.rev211210.ServiceDeleteOutput; -import org.opendaylight.yang.gen.v1.http.org.openroadm.service.rev211210.service.create.input.ServiceAEndBuilder; -import org.opendaylight.yang.gen.v1.http.org.openroadm.service.rev211210.service.create.input.ServiceZEndBuilder; -import org.opendaylight.yang.gen.v1.http.org.openroadm.service.rev211210.service.delete.input.ServiceDeleteReqInfo; -import org.opendaylight.yang.gen.v1.http.org.openroadm.service.rev211210.service.delete.input.ServiceDeleteReqInfoBuilder; -import org.opendaylight.yang.gen.v1.http.org.openroadm.service.rev211210.service.list.Services; -import org.opendaylight.yang.gen.v1.nbi.notifications.rev211013.PublishNotificationAlarmService; -import org.opendaylight.yang.gen.v1.nbi.notifications.rev211013.PublishNotificationAlarmServiceBuilder; +import org.opendaylight.yang.gen.v1.http.org.openroadm.service.rev230526.ServiceCreate; +import org.opendaylight.yang.gen.v1.http.org.openroadm.service.rev230526.ServiceCreateInputBuilder; +import org.opendaylight.yang.gen.v1.http.org.openroadm.service.rev230526.ServiceCreateOutput; +import org.opendaylight.yang.gen.v1.http.org.openroadm.service.rev230526.ServiceDelete; +import org.opendaylight.yang.gen.v1.http.org.openroadm.service.rev230526.ServiceDeleteInputBuilder; +import org.opendaylight.yang.gen.v1.http.org.openroadm.service.rev230526.ServiceDeleteOutput; +import org.opendaylight.yang.gen.v1.http.org.openroadm.service.rev230526.ServiceReroute; +import org.opendaylight.yang.gen.v1.http.org.openroadm.service.rev230526.ServiceRerouteInput; +import org.opendaylight.yang.gen.v1.http.org.openroadm.service.rev230526.ServiceRerouteInputBuilder; +import org.opendaylight.yang.gen.v1.http.org.openroadm.service.rev230526.ServiceRerouteOutput; +import org.opendaylight.yang.gen.v1.http.org.openroadm.service.rev230526.service.create.input.ServiceAEndBuilder; +import org.opendaylight.yang.gen.v1.http.org.openroadm.service.rev230526.service.create.input.ServiceZEndBuilder; +import org.opendaylight.yang.gen.v1.http.org.openroadm.service.rev230526.service.delete.input.ServiceDeleteReqInfo; +import org.opendaylight.yang.gen.v1.http.org.openroadm.service.rev230526.service.delete.input.ServiceDeleteReqInfoBuilder; +import org.opendaylight.yang.gen.v1.http.org.openroadm.service.rev230526.service.list.Services; +import org.opendaylight.yang.gen.v1.nbi.notifications.rev230728.PublishNotificationAlarmService; +import org.opendaylight.yang.gen.v1.nbi.notifications.rev230728.PublishNotificationAlarmServiceBuilder; import org.opendaylight.yangtools.yang.common.RpcResult; +import org.osgi.service.component.annotations.Activate; +import org.osgi.service.component.annotations.Component; +import org.osgi.service.component.annotations.Reference; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +@Component public class ServiceListener implements DataTreeChangeListener { private static final Logger LOG = LoggerFactory.getLogger(ServiceListener.class); private static final String PUBLISHER = "ServiceListener"; - private ServicehandlerImpl servicehandlerImpl; + private final RpcService rpcService; private ServiceDataStoreOperations serviceDataStoreOperations; private NotificationPublishService notificationPublishService; private Map mapServiceInputReroute; private final ScheduledExecutorService executor; - public ServiceListener(ServicehandlerImpl servicehandlerImpl, ServiceDataStoreOperations serviceDataStoreOperations, - NotificationPublishService notificationPublishService) { - this.servicehandlerImpl = servicehandlerImpl; - this.notificationPublishService = notificationPublishService; + @Activate + public ServiceListener(@Reference RpcService rpcService, + @Reference ServiceDataStoreOperations serviceDataStoreOperations, + @Reference NotificationPublishService notificationPublishService) { + this.rpcService = rpcService; this.serviceDataStoreOperations = serviceDataStoreOperations; + this.notificationPublishService = notificationPublishService; this.executor = MoreExecutors.getExitingScheduledExecutorService(new ScheduledThreadPoolExecutor(4)); mapServiceInputReroute = new HashMap<>(); } @Override - public void onDataTreeChanged(Collection> changes) { + public void onDataTreeChanged(List> changes) { LOG.info("onDataTreeChanged - {}", this.getClass().getSimpleName()); for (DataTreeModification change : changes) { DataObjectModification rootService = change.getRootNode(); - if (rootService.getDataBefore() == null) { + if (rootService.dataBefore() == null) { continue; } - String serviceInputName = rootService.getDataBefore().key().getServiceName(); - switch (rootService.getModificationType()) { + String serviceInputName = rootService.dataBefore().key().getServiceName(); + switch (rootService.modificationType()) { case DELETE: LOG.info("Service {} correctly deleted from controller", serviceInputName); if (mapServiceInputReroute.get(serviceInputName) != null) { @@ -81,8 +95,8 @@ public class ServiceListener implements DataTreeChangeListener { } break; case WRITE: - Services inputBefore = rootService.getDataBefore(); - Services inputAfter = rootService.getDataAfter(); + Services inputBefore = rootService.dataBefore(); + Services inputAfter = rootService.dataAfter(); if (inputBefore.getOperationalState() == State.InService && inputAfter.getOperationalState() == State.OutOfService) { LOG.info("Service {} is becoming outOfService", serviceInputName); @@ -96,9 +110,14 @@ public class ServiceListener implements DataTreeChangeListener { if (inputAfter.getAdministrativeState() == AdminStates.InService && inputAfter.getServiceResiliency() != null && inputAfter.getServiceResiliency().getResiliency() != null - && inputAfter.getServiceResiliency().getResiliency().equals(Restorable.class)) { + && inputAfter.getServiceResiliency().getResiliency().equals(Restorable.VALUE)) { LOG.info("Attempting to reroute the service '{}'...", serviceInputName); - // It is used for hold off time purposes + if (!serviceRerouteCheck(serviceInputName, inputAfter.getServiceResiliency(), + inputAfter.getRoutingMetric())) { + LOG.info("No other path available, cancelling reroute process of service '{}'...", + serviceInputName); + continue; + } mapServiceInputReroute.put(serviceInputName, null); if (inputAfter.getServiceResiliency().getHoldoffTime() != null) { LOG.info("Waiting hold off time before rerouting..."); @@ -108,7 +127,8 @@ public class ServiceListener implements DataTreeChangeListener { && mapServiceInputReroute.get(serviceInputName) == null) { serviceRerouteStep1(serviceInputName); } else { - LOG.info("Cancelling rerouting for service '{}'...", serviceInputName); + LOG.info("Cancelling reroute process of service '{}'...", + serviceInputName); } }, Long.parseLong(String.valueOf(inputAfter.getServiceResiliency() @@ -136,7 +156,7 @@ public class ServiceListener implements DataTreeChangeListener { } break; default: - LOG.debug("Unknown modification type {}", rootService.getModificationType().name()); + LOG.debug("Unknown modification type {}", rootService.modificationType().name()); break; } } @@ -154,8 +174,8 @@ public class ServiceListener implements DataTreeChangeListener { LOG.warn("Service '{}' does not exist in datastore", serviceNameToReroute); return; } - Services service = serviceOpt.get(); - ListenableFuture> res = this.servicehandlerImpl.serviceDelete( + Services service = serviceOpt.orElseThrow(); + ListenableFuture> res = rpcService.getRpc(ServiceDelete.class).invoke( new ServiceDeleteInputBuilder() .setSdncRequestHeader(new SdncRequestHeaderBuilder(service.getSdncRequestHeader()) .setRpcAction(RpcActions.ServiceDelete) @@ -200,7 +220,7 @@ public class ServiceListener implements DataTreeChangeListener { * @param serviceNameToReroute Name of the service */ private void serviceRerouteStep2(String serviceNameToReroute) { - ListenableFuture> res = this.servicehandlerImpl.serviceCreate( + ListenableFuture> res = rpcService.getRpc(ServiceCreate.class).invoke( mapServiceInputReroute.get(serviceNameToReroute).getServiceCreateInput()); try { String httpResponseCode = res.get().getResult().getConfigurationResponseCommon().getResponseCode(); @@ -215,6 +235,34 @@ public class ServiceListener implements DataTreeChangeListener { mapServiceInputReroute.remove(serviceNameToReroute); } + /** + * Prior to the reroute steps: check that an alternative route of the service is possible. + * + * @param serviceNameToReroute Name of the service + * @param serviceResiliency Resiliency of the service + * @param routingMetric Metric of the routing + */ + private boolean serviceRerouteCheck(String serviceNameToReroute, ServiceResiliency serviceResiliency, + RoutingMetric routingMetric) { + ServiceRerouteInput serviceRerouteInput = new ServiceRerouteInputBuilder() + .setServiceName(serviceNameToReroute) + .setServiceResiliency(serviceResiliency) + .setRoutingMetric(routingMetric) + .setSdncRequestHeader(new SdncRequestHeaderBuilder() + .setRpcAction(RpcActions.ServiceReroute) + .build()) + .build(); + ListenableFuture> res = rpcService.getRpc(ServiceReroute.class).invoke( + serviceRerouteInput); + try { + return res.get().getResult().getConfigurationResponseCommon().getResponseCode() + .equals(ResponseCodes.RESPONSE_OK); + } catch (ExecutionException | InterruptedException e) { + LOG.warn("ServiceRerouteCheck FAILED ! ", e); + return false; + } + } + /** * Send notification to NBI notification in order to publish message. * @@ -228,4 +276,5 @@ public class ServiceListener implements DataTreeChangeListener { Thread.currentThread().interrupt(); } } + }