Bump upstream dependencies to Ca
[transportpce.git] / servicehandler / src / main / java / org / opendaylight / transportpce / servicehandler / listeners / ServiceListener.java
index 64d46b4cf7f33bbf4431f5c0f1078d52d147dc32..967cbe4ff08404997ef7ce4c8ff9c5866daea435 100644 (file)
@@ -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<Services> {
 
     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<String, ServiceInput> 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<DataTreeModification<Services>> changes) {
+    public void onDataTreeChanged(List<DataTreeModification<Services>> changes) {
         LOG.info("onDataTreeChanged - {}", this.getClass().getSimpleName());
         for (DataTreeModification<Services> change : changes) {
             DataObjectModification<Services> 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<Services> {
                     }
                     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<Services> {
                         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<Services> {
                                                     && 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<Services> {
                     }
                     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<Services> {
             LOG.warn("Service '{}' does not exist in datastore", serviceNameToReroute);
             return;
         }
-        Services service = serviceOpt.get();
-        ListenableFuture<RpcResult<ServiceDeleteOutput>> res = this.servicehandlerImpl.serviceDelete(
+        Services service = serviceOpt.orElseThrow();
+        ListenableFuture<RpcResult<ServiceDeleteOutput>> 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<Services> {
      * @param serviceNameToReroute Name of the service
      */
     private void serviceRerouteStep2(String serviceNameToReroute) {
-        ListenableFuture<RpcResult<ServiceCreateOutput>> res = this.servicehandlerImpl.serviceCreate(
+        ListenableFuture<RpcResult<ServiceCreateOutput>> 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<Services> {
         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<RpcResult<ServiceRerouteOutput>> 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<Services> {
             Thread.currentThread().interrupt();
         }
     }
+
 }