Implement service-reroute RPC 23/102023/7
authorThierry Jiao <thierry.jiao@orange.com>
Tue, 9 Aug 2022 14:57:43 +0000 (16:57 +0200)
committerGilles Thouenon <gilles.thouenon@orange.com>
Fri, 16 Sep 2022 08:59:13 +0000 (10:59 +0200)
The service-reroute RPC allows to check whether any route is possible
for an existing service.

JIRA: TRNSPRTPCE-683
Signed-off-by: Thierry Jiao <thierry.jiao@orange.com>
Change-Id: I3572b8c76c4600e463806da919f43e8bdbda1d4a

pce/src/main/java/org/opendaylight/transportpce/pce/PceSendingPceRPCs.java
pce/src/main/java/org/opendaylight/transportpce/pce/networkanalyzer/PceCalculation.java
servicehandler/src/main/java/org/opendaylight/transportpce/servicehandler/ModelMappingUtils.java
servicehandler/src/main/java/org/opendaylight/transportpce/servicehandler/ServiceInput.java
servicehandler/src/main/java/org/opendaylight/transportpce/servicehandler/impl/ServicehandlerImpl.java
servicehandler/src/main/java/org/opendaylight/transportpce/servicehandler/listeners/ServiceListener.java
servicehandler/src/main/java/org/opendaylight/transportpce/servicehandler/service/PCEServiceWrapper.java
servicehandler/src/main/resources/OSGI-INF/blueprint/servicehandler-blueprint.xml
servicehandler/src/test/java/org/opendaylight/transportpce/servicehandler/impl/ServicehandlerImplTest.java
servicehandler/src/test/java/org/opendaylight/transportpce/servicehandler/listeners/ServiceListenerTest.java

index 284603edcf7de50ac64b3218296a72aaaa0f6eb9..452b711708f1f471b03f62ecbed5932d989546d0 100644 (file)
@@ -63,7 +63,7 @@ public class PceSendingPceRPCs {
     private String responseCode;
     private final GnpyConsumer gnpyConsumer;
     private PortMapping portMapping;
-    // Define the termination points whose reserved status is not taken into account during the pruning process
+    // Define the termination points whose reservation status is not taken into account during the pruning process
     private Endpoints endpoints;
 
     public PceSendingPceRPCs(GnpyConsumer gnpyConsumer) {
index 7652ea3bb01bce4e0ed9ec610b6c3d2ff90dfec7..065eab4a5918743c23081ff2ee4ed3cc6a5248ae 100644 (file)
@@ -87,7 +87,7 @@ public class PceCalculation {
     private List<LinkId> linksToExclude = new ArrayList<>();
     private PceResult returnStructure;
     private PortMapping portMapping;
-    // Define the termination points whose reserved status is not taken into account during the pruning process
+    // Define the termination points whose reservation status is not taken into account during the pruning process
     private Endpoints endpoints;
 
     private enum ConstraintTypes {
index cd8ca876edd8c31dea19c8df008a3738a0824635..033dc72b123b696a7b49f810ef33ec9f6323f1eb 100644 (file)
@@ -417,14 +417,16 @@ public final class ModelMappingUtils {
     }
 
     public static ListenableFuture<RpcResult<ServiceRerouteOutput>> createRerouteServiceReply(
-            ServiceRerouteInput input, String finalAckYes, String message) {
+            ServiceRerouteInput input, String finalAckYes, String message, String responseCode) {
         return RpcResultBuilder
             .success(
                 new ServiceRerouteOutputBuilder()
                     .setConfigurationResponseCommon(
                         new ConfigurationResponseCommonBuilder()
-                            .setResponseMessage(message)
-                            .build())
+                             .setAckFinalIndicator(finalAckYes)
+                             .setResponseCode(responseCode)
+                             .setResponseMessage(message)
+                             .build())
                     .setHardConstraints(null)
                     .setSoftConstraints(null)
                     .build())
index a818df60cf14fe2b6f52ebb3204cf3b523c73490..d03293738f205a8f7bca85de93f4c5c87efb7531 100644 (file)
@@ -20,6 +20,7 @@ import org.opendaylight.yang.gen.v1.http.org.openroadm.service.rev211210.Service
 import org.opendaylight.yang.gen.v1.http.org.openroadm.service.rev211210.ServiceDeleteInput;
 import org.opendaylight.yang.gen.v1.http.org.openroadm.service.rev211210.ServiceFeasibilityCheckInput;
 import org.opendaylight.yang.gen.v1.http.org.openroadm.service.rev211210.ServiceReconfigureInput;
+import org.opendaylight.yang.gen.v1.http.org.openroadm.service.rev211210.ServiceRerouteInput;
 import org.opendaylight.yang.gen.v1.http.org.openroadm.service.rev211210.TempServiceCreateInput;
 import org.opendaylight.yang.gen.v1.http.org.openroadm.service.rev211210.TempServiceCreateInputBuilder;
 import org.opendaylight.yang.gen.v1.http.org.openroadm.service.rev211210.TempServiceDeleteInput;
@@ -30,7 +31,6 @@ import org.opendaylight.yang.gen.v1.http.org.openroadm.service.rev211210.service
  * Super class of {@link ServiceCreateInput} and {@link TempServiceCreateInput}.
  *
  * @author Martial Coulibaly ( martial.coulibaly@gfi.com ) on behalf of Orange
- *
  */
 public class ServiceInput {
     private String serviceName;
@@ -124,6 +124,13 @@ public class ServiceInput {
         setServiceReconfigure(false);
     }
 
+    public ServiceInput(ServiceRerouteInput serviceRerouteInput) {
+        setServiceName(serviceRerouteInput.getServiceName());
+        setSdncRequestHeader(serviceRerouteInput.getSdncRequestHeader());
+        setServiceResiliency(serviceRerouteInput.getServiceResiliency());
+        setServiceReconfigure(false);
+    }
+
     public ServiceCreateInput getServiceCreateInput() {
         ServiceCreateInputBuilder serviceCreateInputBuilder = new ServiceCreateInputBuilder()
                 .setCommonId(commonId)
index acd33d228948e91dcd638313be6f1274f77932b9..7d3d4f9edb7bcfde39b2cdc32d83bfd4100a121a 100644 (file)
@@ -11,6 +11,7 @@ import com.google.common.util.concurrent.ListenableFuture;
 import java.time.OffsetDateTime;
 import java.time.ZoneOffset;
 import java.time.format.DateTimeFormatter;
+import java.util.Map;
 import java.util.Optional;
 import org.opendaylight.mdsal.binding.api.DataBroker;
 import org.opendaylight.mdsal.binding.api.NotificationPublishService;
@@ -31,6 +32,8 @@ import org.opendaylight.transportpce.servicehandler.validation.ServiceCreateVali
 import org.opendaylight.transportpce.servicehandler.validation.checks.ComplianceCheckResult;
 import org.opendaylight.transportpce.servicehandler.validation.checks.ServicehandlerComplianceCheck;
 import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.pce.rev220808.PathComputationRequestOutput;
+import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.pce.rev220808.PathComputationRerouteRequestOutput;
+import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.pce.rev220808.path.computation.reroute.request.input.EndpointsBuilder;
 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.ServiceNotificationTypes;
 import org.opendaylight.yang.gen.v1.http.org.openroadm.common.service.types.rev211210.configuration.response.common.ConfigurationResponseCommon;
@@ -105,6 +108,10 @@ import org.opendaylight.yang.gen.v1.http.org.openroadm.service.rev211210.TempSer
 import org.opendaylight.yang.gen.v1.http.org.openroadm.service.rev211210.service.delete.input.ServiceDeleteReqInfo.TailRetention;
 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.http.org.transportpce.b.c._interface.pathdescription.rev210705.path.description.atoz.direction.AToZ;
+import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.pathdescription.rev210705.path.description.atoz.direction.AToZKey;
+import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.pathdescription.rev210705.pce.resource.resource.resource.TerminationPoint;
+import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.servicepath.rev171017.service.path.list.ServicePaths;
 import org.opendaylight.yang.gen.v1.nbi.notifications.rev211013.PublishNotificationProcessService;
 import org.opendaylight.yang.gen.v1.nbi.notifications.rev211013.PublishNotificationProcessServiceBuilder;
 import org.opendaylight.yang.gen.v1.nbi.notifications.rev211013.notification.process.service.ServiceAEndBuilder;
@@ -185,6 +192,10 @@ public class ServicehandlerImpl implements OrgOpenroadmServiceService {
             return "Service '" + serviceName + "' does not exist in datastore";
         }
 
+        public static String servicePathNotInDS(String serviceName) {
+            return "Service Path from '" + serviceName + "' does not exist in datastore";
+        }
+
         public static String serviceInService(String serviceName) {
             return "Service '" + serviceName + "' is in 'inService' state";
         }
@@ -490,50 +501,57 @@ public class ServicehandlerImpl implements OrgOpenroadmServiceService {
         if (servicesObject.isEmpty()) {
             LOG.warn("serviceReroute: {}", LogMessages.serviceNotInDS(serviceName));
             return ModelMappingUtils.createRerouteServiceReply(
-                    input, ResponseCodes.FINAL_ACK_NO,
-                    LogMessages.serviceNotInDS(serviceName));
+                    input, ResponseCodes.FINAL_ACK_YES,
+                    LogMessages.serviceNotInDS(serviceName),
+                    ResponseCodes.RESPONSE_FAILED);
         }
         Services service = servicesObject.get();
-        DateTimeFormatter dtf = DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ssxxx");
-        OffsetDateTime offsetDateTime = OffsetDateTime.now(ZoneOffset.UTC);
-        DateAndTime datetime = new DateAndTime(dtf.format(offsetDateTime));
-        SdncRequestHeaderBuilder sdncBuilder = new SdncRequestHeaderBuilder()
-                .setNotificationUrl(service.getSdncRequestHeader().getNotificationUrl())
-                .setRequestId(service.getSdncRequestHeader().getRequestId())
-                .setRequestSystemId(service.getSdncRequestHeader().getRequestSystemId())
-                .setRpcAction(RpcActions.ServiceDelete);
-        ServiceDeleteInputBuilder deleteInputBldr = new ServiceDeleteInputBuilder()
-                .setServiceDeleteReqInfo(new ServiceDeleteReqInfoBuilder()
-                    .setServiceName(serviceName).setDueDate(datetime)
-                    .setTailRetention(TailRetention.No).build())
-                .setSdncRequestHeader(sdncBuilder.build());
-        ServiceInput serviceInput = new ServiceInput(deleteInputBldr.build());
+        Optional<ServicePaths> servicePathsObject = this.serviceDataStoreOperations.getServicePath(serviceName);
+        if (servicePathsObject.isEmpty()) {
+            LOG.warn("serviceReroute: {}", LogMessages.servicePathNotInDS(serviceName));
+            return ModelMappingUtils.createRerouteServiceReply(
+                    input, ResponseCodes.FINAL_ACK_YES,
+                    LogMessages.servicePathNotInDS(serviceName),
+                    ResponseCodes.RESPONSE_FAILED);
+        }
+        ServicePaths servicePaths = servicePathsObject.get();
+        // serviceInput for later use maybe...
+        ServiceInput serviceInput = new ServiceInput(input);
         serviceInput.setServiceAEnd(service.getServiceAEnd());
         serviceInput.setServiceZEnd(service.getServiceZEnd());
         serviceInput.setConnectionType(service.getConnectionType());
-        this.pceListenerImpl.setInput(serviceInput);
-        this.pceListenerImpl.setServiceReconfigure(true);
-        this.pceListenerImpl.setserviceDataStoreOperations(this.serviceDataStoreOperations);
-        this.rendererListenerImpl.setServiceInput(serviceInput);
-        this.rendererListenerImpl.setserviceDataStoreOperations(this.serviceDataStoreOperations);
-        this.networkModelListenerImpl.setserviceDataStoreOperations(serviceDataStoreOperations);
-        org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.renderer.rev210915
-            .ServiceDeleteInput serviceDeleteInput = ModelMappingUtils.createServiceDeleteInput(
-                    new ServiceInput(deleteInputBldr.build()));
-        org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.renderer.rev210915
-            .ServiceDeleteOutput output = this.rendererServiceWrapper.performRenderer(serviceDeleteInput,
-                ServiceNotificationTypes.ServiceDeleteResult, null);
+        serviceInput.setCommonId(service.getCommonId());
+        serviceInput.setHardConstraints(service.getHardConstraints());
+        serviceInput.setSoftConstraints(service.getSoftConstraints());
+        serviceInput.setCustomer(service.getCustomer());
+        serviceInput.setCustomerContact(service.getCustomerContact());
+
+        // Get the network xpdr termination points
+        Map<AToZKey, AToZ> mapaToz = servicePaths.getPathDescription().getAToZDirection().getAToZ();
+        String aendtp = ((TerminationPoint) mapaToz.get(new AToZKey(String.valueOf(mapaToz.size() - 3)))
+                .getResource()
+                .getResource())
+                .getTpId();
+        String zendtp = ((TerminationPoint) mapaToz.get(new AToZKey("2"))
+                .getResource()
+                .getResource())
+                .getTpId();
+
+        PathComputationRerouteRequestOutput output = this.pceServiceWrapper.performPCEReroute(
+                service.getHardConstraints(), service.getSoftConstraints(), input.getSdncRequestHeader(),
+                service.getServiceAEnd(), service.getServiceZEnd(),
+                new EndpointsBuilder().setAEndTp(aendtp).setZEndTp(zendtp).build());
+
         if (output == null) {
-            LOG.error("serviceReroute: {}", LogMessages.RENDERER_DELETE_FAILED);
+            LOG.error("serviceReroute: {}", LogMessages.PCE_FAILED);
             return ModelMappingUtils.createRerouteServiceReply(
                     input, ResponseCodes.FINAL_ACK_YES,
-                    LogMessages.RENDERER_DELETE_FAILED);
+                    LogMessages.PCE_FAILED, ResponseCodes.RESPONSE_FAILED);
         }
-        LOG.info("RPC ServiceReroute in progress...");
+        LOG.info("RPC ServiceReroute is done");
         ConfigurationResponseCommon common = output.getConfigurationResponseCommon();
-        return ModelMappingUtils.createRerouteServiceReply(
-                input, common.getAckFinalIndicator(),
-                common.getResponseMessage());
+        return ModelMappingUtils.createRerouteServiceReply(input, common.getAckFinalIndicator(),
+                common.getResponseMessage(), common.getResponseCode());
     }
 
     @Override
index 434aa2cb31be964e6e9dcba2f5d47ad352bafbec..7caf6b2e1331eb485fe1b0a48d97e90e8df1a2e8 100644 (file)
@@ -7,9 +7,6 @@
  */
 package org.opendaylight.transportpce.servicehandler.listeners;
 
-import static org.opendaylight.transportpce.servicehandler.ModelMappingUtils.createServiceAEndReroute;
-import static org.opendaylight.transportpce.servicehandler.ModelMappingUtils.createServiceZEndReroute;
-
 import com.google.common.util.concurrent.ListenableFuture;
 import com.google.common.util.concurrent.MoreExecutors;
 import java.util.Collection;
@@ -29,29 +26,25 @@ import org.opendaylight.transportpce.pce.service.PathComputationService;
 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.opendaylight.transportpce.pce.rev220808.PathComputationRerouteRequestInput;
-import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.pce.rev220808.PathComputationRerouteRequestInputBuilder;
-import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.pce.rev220808.PathComputationRerouteRequestOutput;
-import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.pce.rev220808.path.computation.reroute.request.input.EndpointsBuilder;
 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.routing.metric.RoutingMetric;
 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.rev211210.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.ServiceRerouteInput;
+import org.opendaylight.yang.gen.v1.http.org.openroadm.service.rev211210.ServiceRerouteInputBuilder;
+import org.opendaylight.yang.gen.v1.http.org.openroadm.service.rev211210.ServiceRerouteOutput;
 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.http.org.transportpce.b.c._interface.pathdescription.rev210705.path.description.atoz.direction.AToZ;
-import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.pathdescription.rev210705.path.description.atoz.direction.AToZKey;
-import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.pathdescription.rev210705.pce.resource.resource.resource.TerminationPoint;
-import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.service.types.rev220118.PceMetric;
-import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.servicepath.rev171017.service.path.list.ServicePaths;
 import org.opendaylight.yang.gen.v1.nbi.notifications.rev211013.PublishNotificationAlarmService;
 import org.opendaylight.yang.gen.v1.nbi.notifications.rev211013.PublishNotificationAlarmServiceBuilder;
 import org.opendaylight.yangtools.yang.common.RpcResult;
@@ -70,12 +63,10 @@ public class ServiceListener implements DataTreeChangeListener<Services> {
     private final ScheduledExecutorService executor;
 
     public ServiceListener(ServicehandlerImpl servicehandlerImpl, ServiceDataStoreOperations serviceDataStoreOperations,
-                           NotificationPublishService notificationPublishService,
-                           PathComputationService pathComputationService) {
+                           NotificationPublishService notificationPublishService) {
         this.servicehandlerImpl = servicehandlerImpl;
         this.notificationPublishService = notificationPublishService;
         this.serviceDataStoreOperations = serviceDataStoreOperations;
-        this.pathComputationService = pathComputationService;
         this.executor = MoreExecutors.getExitingScheduledExecutorService(new ScheduledThreadPoolExecutor(4));
         mapServiceInputReroute = new HashMap<>();
     }
@@ -114,7 +105,8 @@ public class ServiceListener implements DataTreeChangeListener<Services> {
                                 && inputAfter.getServiceResiliency().getResiliency() != null
                                 && inputAfter.getServiceResiliency().getResiliency().equals(Restorable.VALUE)) {
                             LOG.info("Attempting to reroute the service '{}'...", serviceInputName);
-                            if (!serviceRerouteCheck(inputBefore)) {
+                            if (!serviceRerouteCheck(serviceInputName, inputAfter.getServiceResiliency(),
+                                    inputAfter.getRoutingMetric())) {
                                 LOG.info("No other path available, cancelling reroute process of service '{}'...",
                                         serviceInputName);
                                 continue;
@@ -237,37 +229,27 @@ public class ServiceListener implements DataTreeChangeListener<Services> {
     }
 
     /**
-     * Call the PCE RPC path-computation-reroute-request to check if any other path exists.
+     * Prior to the reroute steps: check that an alternative route of the service is possible.
      *
-     * @param input Service to be rerouted
+     * @param serviceNameToReroute Name of the service
+     * @param serviceResiliency Resiliency of the service
+     * @param routingMetric Metric of the routing
      */
-    protected boolean serviceRerouteCheck(Services input) {
-        Optional<ServicePaths> servicePaths = serviceDataStoreOperations.getServicePath(input.getServiceName());
-        if (servicePaths.isEmpty()) {
-            LOG.warn("Service path of '{}' does not exist in datastore", input.getServiceName());
-            return false;
-        }
-        // Get the network xpdr termination points
-        Map<AToZKey, AToZ> mapaToz = servicePaths.get().getPathDescription().getAToZDirection().getAToZ();
-        String aendtp = ((TerminationPoint) mapaToz.get(new AToZKey(String.valueOf(mapaToz.size() - 3)))
-                .getResource().getResource()).getTpId();
-        String zendtp = ((TerminationPoint) mapaToz.get(new AToZKey("2")).getResource()
-                .getResource()).getTpId();
-        PathComputationRerouteRequestInput inputPC = new PathComputationRerouteRequestInputBuilder()
-                .setHardConstraints(input.getHardConstraints())
-                .setSoftConstraints(input.getSoftConstraints())
-                .setServiceAEnd(createServiceAEndReroute(input.getServiceAEnd()))
-                .setServiceZEnd(createServiceZEndReroute(input.getServiceZEnd()))
-                .setPceRoutingMetric(PceMetric.TEMetric)
-                .setEndpoints(new EndpointsBuilder()
-                        .setAEndTp(aendtp)
-                        .setZEndTp(zendtp)
+    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<PathComputationRerouteRequestOutput> res =
-                pathComputationService.pathComputationRerouteRequest(inputPC);
+        ListenableFuture<RpcResult<ServiceRerouteOutput>> res = this.servicehandlerImpl.serviceReroute(
+                serviceRerouteInput);
         try {
-            return res.get().getConfigurationResponseCommon().getResponseCode().equals(ResponseCodes.RESPONSE_OK);
+            return res.get().getResult().getConfigurationResponseCommon().getResponseCode()
+                    .equals(ResponseCodes.RESPONSE_OK);
         } catch (ExecutionException | InterruptedException e) {
             LOG.warn("ServiceRerouteCheck FAILED ! ", e);
             return false;
index 20d81acdb99fa1dab878e3dd0c7fa2457dab6739..056b291e600bb544c731a4cb48a01a4dabb7e879 100644 (file)
@@ -12,6 +12,7 @@ import com.google.common.util.concurrent.Futures;
 import com.google.common.util.concurrent.ListenableFuture;
 import com.google.common.util.concurrent.ListeningExecutorService;
 import com.google.common.util.concurrent.MoreExecutors;
+import java.util.concurrent.ExecutionException;
 import java.util.concurrent.Executors;
 import org.opendaylight.mdsal.binding.api.NotificationPublishService;
 import org.opendaylight.transportpce.common.ResponseCodes;
@@ -25,6 +26,12 @@ import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.pce.rev22
 import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.pce.rev220808.PathComputationRequestInputBuilder;
 import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.pce.rev220808.PathComputationRequestOutput;
 import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.pce.rev220808.PathComputationRequestOutputBuilder;
+import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.pce.rev220808.PathComputationRerouteRequestInput;
+import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.pce.rev220808.PathComputationRerouteRequestInputBuilder;
+import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.pce.rev220808.PathComputationRerouteRequestOutput;
+import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.pce.rev220808.PathComputationRerouteRequestOutputBuilder;
+import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.pce.rev220808.path.computation.reroute.request.input.Endpoints;
+import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.pce.rev220808.path.computation.reroute.request.input.EndpointsBuilder;
 import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.servicehandler.rev201125.ServiceRpcResultSh;
 import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.servicehandler.rev201125.ServiceRpcResultShBuilder;
 import org.opendaylight.yang.gen.v1.http.org.openroadm.common.service.types.rev211210.ServiceEndpoint;
@@ -138,6 +145,31 @@ public class PCEServiceWrapper {
                 .build();
     }
 
+    public PathComputationRerouteRequestOutput performPCEReroute(HardConstraints hardConstraints,
+           SoftConstraints softConstraints, SdncRequestHeader serviceHandler, ServiceEndpoint serviceAEnd,
+           ServiceEndpoint serviceZEnd,
+           Endpoints endpoints) {
+        // TODO: Make it asynchronous
+        LOG.info("Calling path computation reroute");
+        PathComputationRerouteRequestInput inputPCE = createPceRerouteRequestInput(hardConstraints, softConstraints,
+                serviceHandler, serviceAEnd, serviceZEnd, endpoints);
+        ListenableFuture<PathComputationRerouteRequestOutput> res =
+                pathComputationService.pathComputationRerouteRequest(inputPCE);
+        try {
+            return res.get();
+        } catch (ExecutionException | InterruptedException e) {
+            LOG.warn("PerformPCEReroute FAILED ! ", e);
+            return new PathComputationRerouteRequestOutputBuilder()
+                    .setConfigurationResponseCommon(new ConfigurationResponseCommonBuilder()
+                            .setAckFinalIndicator(ResponseCodes.FINAL_ACK_YES)
+                            .setRequestId("None")
+                            .setResponseCode(ResponseCodes.RESPONSE_OK)
+                            .setResponseMessage("PCE calculation FAILED")
+                            .build())
+                    .build();
+        }
+    }
+
     private PathComputationRequestInput createPceRequestInput(String serviceName,
             SdncRequestHeader serviceHandler, HardConstraints hardConstraints,
             SoftConstraints softConstraints, Boolean reserveResource, ServiceEndpoint serviceAEnd,
@@ -160,6 +192,26 @@ public class PCEServiceWrapper {
             .build();
     }
 
+    private PathComputationRerouteRequestInput createPceRerouteRequestInput(HardConstraints hardConstraints,
+            SoftConstraints softConstraints, SdncRequestHeader serviceHandler, ServiceEndpoint serviceAEnd,
+            ServiceEndpoint serviceZEnd, Endpoints endpoints) {
+        LOG.info("Mapping Service-reroute to PCE requests");
+        return new PathComputationRerouteRequestInputBuilder()
+                .setServiceHandlerHeader(serviceHandler == null
+                        ? new ServiceHandlerHeaderBuilder().build()
+                        : new ServiceHandlerHeaderBuilder().setRequestId(serviceHandler.getRequestId()).build())
+                .setHardConstraints(hardConstraints)
+                .setSoftConstraints(softConstraints)
+                .setPceRoutingMetric(PceMetric.TEMetric)
+                .setEndpoints(new EndpointsBuilder()
+                        .setAEndTp(endpoints.getAEndTp())
+                        .setZEndTp(endpoints.getZEndTp())
+                        .build())
+                .setServiceAEnd(ModelMappingUtils.createServiceAEndReroute(serviceAEnd))
+                .setServiceZEnd(ModelMappingUtils.createServiceZEndReroute(serviceZEnd))
+                .build();
+    }
+
     private CancelResourceReserveInput mappingCancelResourceReserve(String serviceName,
                                                                     SdncRequestHeader sdncRequestHeader) {
         LOG.info("Mapping to PCE Cancel resource request input");
index a84205cbcf0614cd32b2c2b27bf978cc0ea209aa..affeddf0dd85cd0e7f949feb9c499fb93a02e69c 100644 (file)
@@ -47,7 +47,6 @@ Author: Martial Coulibaly <martial.coulibaly@gfi.com> on behalf of Orange
         <argument ref="serviceHandlerImpl" />
         <argument ref="serviceDatastoreOperation" />
         <argument ref="notificationPublishService" />
-        <argument ref="pathComputationService" />
     </bean>
 
     <bean id="rendererListener" class="org.opendaylight.transportpce.servicehandler.listeners.RendererListenerImpl">
index 9c3fcacc0f95d711398c8648df9b517a536617cf..8ff5eebc7fa843fde7355efee2de3d3c13bb1ec6 100644 (file)
@@ -357,8 +357,6 @@ public class ServicehandlerImplTest extends AbstractTest {
 
     @Test
     public void serviceRerouteShouldBeSuccessForExistingService() throws ExecutionException, InterruptedException {
-        // serviceReroute is calling service delete method in renderer
-        Mockito.when(rendererServiceOperations.serviceDelete(any(), any())).thenReturn(Futures.immediateFuture(any()));
         //create service to be rerouted later
         ServicehandlerImpl servicehandlerImpl = new ServicehandlerImpl(getNewDataBroker(), pathComputationService,
                 rendererServiceOperations, notificationPublishService, pceListenerImpl, rendererListenerImpl,
index d6163b21b696895e7e71310ee22ded2dd5cd8647..4471263cfd3c53cd343d922b296b2543b1c152fe 100755 (executable)
@@ -24,7 +24,6 @@ import java.util.Optional;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.mockito.Mock;
-import org.mockito.Mockito;
 import org.mockito.junit.MockitoJUnitRunner;
 import org.opendaylight.mdsal.binding.api.DataObjectModification;
 import org.opendaylight.mdsal.binding.api.DataTreeModification;
@@ -57,6 +56,7 @@ import org.opendaylight.yang.gen.v1.http.org.openroadm.equipment.states.types.re
 import org.opendaylight.yang.gen.v1.http.org.openroadm.service.format.rev191129.ServiceFormat;
 import org.opendaylight.yang.gen.v1.http.org.openroadm.service.rev211210.ServiceCreateOutputBuilder;
 import org.opendaylight.yang.gen.v1.http.org.openroadm.service.rev211210.ServiceDeleteOutputBuilder;
+import org.opendaylight.yang.gen.v1.http.org.openroadm.service.rev211210.ServiceRerouteOutputBuilder;
 import org.opendaylight.yang.gen.v1.http.org.openroadm.service.rev211210.service.list.Services;
 import org.opendaylight.yang.gen.v1.http.org.openroadm.service.rev211210.service.list.ServicesBuilder;
 import org.opendaylight.yang.gen.v1.nbi.notifications.rev211013.PublishNotificationAlarmService;
@@ -89,7 +89,7 @@ public class ServiceListenerTest {
         when(service.getModificationType()).thenReturn(DataObjectModification.ModificationType.DELETE);
         when(service.getDataBefore()).thenReturn(buildService(State.InService, AdminStates.InService));
         ServiceListener listener = new ServiceListener(servicehandler, serviceDataStoreOperations,
-                notificationPublishService, pathComputationService);
+                notificationPublishService);
         listener.onDataTreeChanged(changes);
         verify(ch, times(1)).getRootNode();
         verify(service, times(1)).getModificationType();
@@ -116,7 +116,7 @@ public class ServiceListenerTest {
         when(service.getDataBefore()).thenReturn(buildService(State.InService, AdminStates.InService));
         when(service.getDataAfter()).thenReturn(serviceDown);
         ServiceListener listener = new ServiceListener(servicehandler, serviceDataStoreOperations,
-                notificationPublishService, pathComputationService);
+                notificationPublishService);
         listener.onDataTreeChanged(changes);
         verify(ch, times(1)).getRootNode();
         verify(service, times(1)).getModificationType();
@@ -142,7 +142,7 @@ public class ServiceListenerTest {
         when(service.getModificationType()).thenReturn(DataObjectModification.ModificationType.SUBTREE_MODIFIED);
         when(service.getDataBefore()).thenReturn(buildService(State.InService, AdminStates.InService));
         ServiceListener listener = new ServiceListener(servicehandler, serviceDataStoreOperations,
-                notificationPublishService, pathComputationService);
+                notificationPublishService);
         listener.onDataTreeChanged(changes);
         verify(ch, times(1)).getRootNode();
         verify(service, times(2)).getModificationType();
@@ -184,6 +184,15 @@ public class ServiceListenerTest {
                                                 .build())
                                 .build())
                         .buildFuture());
+        when(servicehandler.serviceReroute(any())).thenReturn(
+                RpcResultBuilder.success(
+                        new ServiceRerouteOutputBuilder()
+                                .setConfigurationResponseCommon(
+                                        new ConfigurationResponseCommonBuilder()
+                                                .setResponseCode(ResponseCodes.RESPONSE_OK)
+                                                .build())
+                                .build())
+                        .buildFuture());
         when(servicehandler.serviceCreate(any())).thenReturn(
                 RpcResultBuilder.success(
                         new ServiceCreateOutputBuilder()
@@ -193,10 +202,8 @@ public class ServiceListenerTest {
                                                 .build())
                                 .build())
                         .buildFuture());
-        ServiceListener listener = Mockito.spy(new ServiceListener(servicehandler, serviceDataStoreOperations,
-                notificationPublishService, pathComputationService));
-        Mockito.doReturn(true).when(listener).serviceRerouteCheck(any());
-
+        ServiceListener listener = new ServiceListener(servicehandler, serviceDataStoreOperations,
+                notificationPublishService);
         listener.onDataTreeChanged(changes);
         verify(ch, times(1)).getRootNode();
         verify(service, times(1)).getModificationType();
@@ -223,7 +230,7 @@ public class ServiceListenerTest {
         when(service.getDataBefore()).thenReturn(buildService(State.InService, AdminStates.InService));
         when(service.getDataAfter()).thenReturn(serviceAfter);
         ServiceListener listener = new ServiceListener(servicehandler, serviceDataStoreOperations,
-                notificationPublishService, pathComputationService);
+                notificationPublishService);
         listener.onDataTreeChanged(changes);
         verify(ch, times(1)).getRootNode();
         verify(service, times(1)).getModificationType();