You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@syncope.apache.org by an...@apache.org on 2022/01/31 14:22:14 UTC

[syncope] branch 2_1_X updated: [SYNCOPE-1641] added resources to match to purge propagation tasks API (#304)

This is an automated email from the ASF dual-hosted git repository.

andreapatricelli pushed a commit to branch 2_1_X
in repository https://gitbox.apache.org/repos/asf/syncope.git


The following commit(s) were added to refs/heads/2_1_X by this push:
     new f4b6a50  [SYNCOPE-1641] added resources to match to purge propagation tasks API (#304)
f4b6a50 is described below

commit f4b6a50c911e48581cca8b9e09f75850a4f5feaf
Author: Andrea Patricelli <an...@apache.org>
AuthorDate: Mon Jan 31 15:22:09 2022 +0100

    [SYNCOPE-1641] added resources to match to purge propagation tasks API (#304)
    
    * [SYNCOPE-1641] added resources to match to purge propagation tasks API
---
 .../common/rest/api/service/TaskService.java       |  5 ++++-
 .../org/apache/syncope/core/logic/TaskLogic.java   | 10 ++++++++--
 .../syncope/core/persistence/api/dao/TaskDAO.java  |  5 ++++-
 .../core/persistence/jpa/dao/JPATaskDAO.java       | 13 ++++++++++++-
 .../core/persistence/jpa/inner/TaskTest.java       |  4 ++--
 .../src/test/resources/domains/MasterContent.xml   |  5 +++++
 .../core/rest/cxf/service/TaskServiceImpl.java     |  6 +++---
 .../syncope/fit/core/PropagationTaskITCase.java    | 22 ++++++++++++++++++++--
 8 files changed, 58 insertions(+), 12 deletions(-)

diff --git a/common/rest-api/src/main/java/org/apache/syncope/common/rest/api/service/TaskService.java b/common/rest-api/src/main/java/org/apache/syncope/common/rest/api/service/TaskService.java
index caa1695..dcaa2c7 100644
--- a/common/rest-api/src/main/java/org/apache/syncope/common/rest/api/service/TaskService.java
+++ b/common/rest-api/src/main/java/org/apache/syncope/common/rest/api/service/TaskService.java
@@ -148,6 +148,7 @@ public interface TaskService extends ExecutableService {
      *
      * @param since match all executions started afterwards
      * @param statuses execution status(es) to match
+     * @param resources external resource(s) to match
      * @return deleted propagation tasks
      */
     @ApiResponses({
@@ -157,5 +158,7 @@ public interface TaskService extends ExecutableService {
     @Path("PROPAGATION/purge")
     @Produces({ MediaType.APPLICATION_JSON, RESTHeaders.APPLICATION_YAML, MediaType.APPLICATION_XML })
     Response purgePropagations(
-            @QueryParam("since") Date since, @QueryParam("statuses") List<ExecStatus> statuses);
+            @QueryParam("since") Date since, 
+            @QueryParam("statuses") List<ExecStatus> statuses, 
+            @QueryParam("resources") List<String> resources);
 }
diff --git a/core/logic/src/main/java/org/apache/syncope/core/logic/TaskLogic.java b/core/logic/src/main/java/org/apache/syncope/core/logic/TaskLogic.java
index 5c51b68..8d25118 100644
--- a/core/logic/src/main/java/org/apache/syncope/core/logic/TaskLogic.java
+++ b/core/logic/src/main/java/org/apache/syncope/core/logic/TaskLogic.java
@@ -24,6 +24,7 @@ import java.util.Arrays;
 import java.util.Date;
 import java.util.List;
 import java.util.Map;
+import java.util.Objects;
 import java.util.stream.Collectors;
 import javax.ws.rs.core.Response;
 import org.apache.commons.lang3.ArrayUtils;
@@ -454,8 +455,13 @@ public class TaskLogic extends AbstractExecutableLogic<TaskTO> {
     }
 
     @PreAuthorize("hasRole('" + StandardEntitlement.TASK_DELETE + "')")
-    public List<PropagationTaskTO> purgePropagations(final Date since, final List<ExecStatus> statuses) {
-        return taskDAO.purgePropagations(since, statuses);
+    public List<PropagationTaskTO> purgePropagations(
+            final Date since,
+            final List<ExecStatus> statuses,
+            final List<String> resources) {
+        return taskDAO.purgePropagations(since, statuses, resources == null 
+                ? null
+                : resources.stream().map(resourceDAO::find).filter(Objects::nonNull).collect(Collectors.toList()));
     }
 
     @Override
diff --git a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/TaskDAO.java b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/TaskDAO.java
index 7161479..8cd5f73 100644
--- a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/TaskDAO.java
+++ b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/TaskDAO.java
@@ -76,5 +76,8 @@ public interface TaskDAO extends DAO<Task> {
 
     void deleteAll(ExternalResource resource, TaskType type);
 
-    List<PropagationTaskTO> purgePropagations(Date since, List<ExecStatus> statuses);
+    List<PropagationTaskTO> purgePropagations(
+            Date since, 
+            List<ExecStatus> statuses,
+            List<ExternalResource> externalResources);
 }
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPATaskDAO.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPATaskDAO.java
index 6987113..78d97bb 100644
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPATaskDAO.java
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPATaskDAO.java
@@ -485,7 +485,10 @@ public class JPATaskDAO extends AbstractDAO<Task> implements TaskDAO {
     }
 
     @Override
-    public List<PropagationTaskTO> purgePropagations(final Date since, final List<ExecStatus> statuses) {
+    public List<PropagationTaskTO> purgePropagations(
+            final Date since, 
+            final List<ExecStatus> statuses, 
+            final List<ExternalResource> externalResources) {
         StringBuilder queryString = new StringBuilder("SELECT t.task_id "
                 + "FROM TaskExec t INNER JOIN Task z ON t.task_id=z.id AND z.dtype='PropagationTask' "
                 + "WHERE t.enddate=(SELECT MAX(e.enddate) FROM TaskExec e WHERE e.task_id=t.task_id) ");
@@ -503,6 +506,14 @@ public class JPATaskDAO extends AbstractDAO<Task> implements TaskDAO {
                     }).collect(Collectors.joining(" OR "))).
                     append(")");
         }
+        if (!CollectionUtils.isEmpty(externalResources)) {
+            queryString.append("AND (").
+                    append(externalResources.stream().map(externalResource -> {
+                        queryParameters.add(externalResource.getKey());
+                        return "z.resource_id = ?" + queryParameters.size();
+                    }).collect(Collectors.joining(" OR "))).
+                    append(")");
+        }
 
         Query query = entityManager().createNativeQuery(queryString.toString());
         for (int i = 1; i <= queryParameters.size(); i++) {
diff --git a/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/inner/TaskTest.java b/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/inner/TaskTest.java
index 803984e..74a03c2 100644
--- a/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/inner/TaskTest.java
+++ b/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/inner/TaskTest.java
@@ -90,12 +90,12 @@ public class TaskTest extends AbstractTest {
         assertNotNull(tasks);
         assertTrue(tasks.isEmpty());
 
-        assertEquals(5, taskDAO.count(TaskType.PROPAGATION, null, null, null, null));
+        assertEquals(6, taskDAO.count(TaskType.PROPAGATION, null, null, null, null));
     }
 
     @Test
     public void findAll() {
-        assertEquals(5, taskDAO.findAll(TaskType.PROPAGATION).size());
+        assertEquals(6, taskDAO.findAll(TaskType.PROPAGATION).size());
         assertEquals(1, taskDAO.findAll(TaskType.NOTIFICATION).size());
         assertEquals(3, taskDAO.findAll(TaskType.SCHEDULED).size());
         assertEquals(10, taskDAO.findAll(TaskType.PULL).size());
diff --git a/core/persistence-jpa/src/test/resources/domains/MasterContent.xml b/core/persistence-jpa/src/test/resources/domains/MasterContent.xml
index 1b87118..c33a68f 100644
--- a/core/persistence-jpa/src/test/resources/domains/MasterContent.xml
+++ b/core/persistence-jpa/src/test/resources/domains/MasterContent.xml
@@ -1182,6 +1182,11 @@ under the License.
   <Task DTYPE="PropagationTask" id="316285cc-ae52-4ea2-a33b-7355e189ac3f" operation="DELETE"
         objectClassName="__ACCOUNT__" resource_id="ws-target-resource-2" anyTypeKind="USER" entityKey="1417acbe-cbf6-4277-9372-e75e04f97000"
         attributes='[{"name":"__PASSWORD__","value":[{"readOnly":false,"disposed":false,"encryptedBytes":"m9nh2US0Sa6m+cXccCq0Xw==","base64SHA1Hash":"GFJ69qfjxEOdrmt+9q+0Cw2uz60="}]},{"name":"__NAME__","value":["userId"],"nameValue":"userId"},{"name":"type","value":["type"]}]'/>
+  <!--SYNCOPE-1641 to be purged-->
+  <Task DTYPE="PropagationTask" id="025c956d-ea88-4bd7-9e44-2f35e0aa7055" operation="UPDATE"
+        objectClassName="__ACCOUNT__" resource_id="ws-target-resource-1" anyTypeKind="USER" entityKey="1417acbe-cbf6-4277-9372-e75e04f97000"
+        attributes='[{"name":"__PASSWORD__","value":[{"readOnly":false,"disposed":false,"encryptedBytes":"m9nh2US0Sa6m+cXccCq0Xw==","base64SHA1Hash":"GFJ69qfjxEOdrmt+9q+0Cw2uz60="}]},{"name":"__NAME__","value":["userId"],"nameValue":"userId"},{"name":"fullname","value":["fullname"]},{"name":"type","value":["type"]}]'/>
+  <TaskExec id="c3290f8b-caf9-4a85-84fb-fb619b65cd49" task_id="025c956d-ea88-4bd7-9e44-2f35e0aa7055" startDate="2015-12-17 09:40:00.506" endDate="2015-12-17 09:42:00.506" status="SUCCESS"/>
   <Task DTYPE="PullTask" remediation="0" id="c41b9b71-9bfa-4f90-89f2-84787def4c5c" name="CSV (update matching; assign unmatching)" resource_id="resource-csv"
         destinationRealm_id="e4c28e7a-9dbf-4ee7-9441-93812a0d4a28" performCreate="1" performUpdate="1" performDelete="1" syncStatus="1"
         pullMode="INCREMENTAL" unmatchingRule="ASSIGN" matchingRule="UPDATE" active="1"
diff --git a/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/TaskServiceImpl.java b/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/TaskServiceImpl.java
index 6efb30f..3a56ab9 100644
--- a/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/TaskServiceImpl.java
+++ b/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/TaskServiceImpl.java
@@ -96,11 +96,11 @@ public class TaskServiceImpl extends AbstractExecutableService implements TaskSe
     }
 
     @Override
-    public Response purgePropagations(final Date since, final List<ExecStatus> statuses) {
-        if (since == null && CollectionUtils.isEmpty(statuses)) {
+    public Response purgePropagations(final Date since, final List<ExecStatus> statuses, final List<String> resources) {
+        if (since == null && CollectionUtils.isEmpty(statuses) && CollectionUtils.isEmpty(resources)) {
             return Response.status(Response.Status.PRECONDITION_FAILED).build();
         }
 
-        return Response.ok(logic.purgePropagations(since, statuses)).build();
+        return Response.ok(logic.purgePropagations(since, statuses, resources)).build();
     }
 }
diff --git a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/PropagationTaskITCase.java b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/PropagationTaskITCase.java
index 13a469c..41f0f93 100644
--- a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/PropagationTaskITCase.java
+++ b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/PropagationTaskITCase.java
@@ -273,7 +273,7 @@ public class PropagationTaskITCase extends AbstractTaskITCase {
     @Test
     public void purgePropagations() {
         try {
-            taskService.purgePropagations(null, null);
+            taskService.purgePropagations(null, null, null);
             fail();
         } catch (WebServiceException e) {
             assertNotNull(e);
@@ -282,12 +282,30 @@ public class PropagationTaskITCase extends AbstractTaskITCase {
         Calendar oneWeekAgo = Calendar.getInstance();
         oneWeekAgo.add(Calendar.WEEK_OF_YEAR, -1);
         Response response = taskService.purgePropagations(
-                oneWeekAgo.getTime(), Collections.singletonList(ExecStatus.SUCCESS));
+                oneWeekAgo.getTime(), Collections.singletonList(ExecStatus.SUCCESS),
+                Collections.singletonList(RESOURCE_NAME_WS1));
         assertEquals(Response.Status.OK.getStatusCode(), response.getStatus());
 
         List<PropagationTaskTO> deleted = response.readEntity(new GenericType<List<PropagationTaskTO>>() {
         });
         assertNotNull(deleted);
+        // only ws-target-resource-1 PROPAGATION tasks should have been deleted
+        assertEquals(1, deleted.size());
+        assertTrue(deleted.stream().allMatch(d -> RESOURCE_NAME_WS1.equals(d.getResource())));
+        // check that other propagation tasks haven't been affected
+        assertFalse(taskService.search(new TaskQuery.Builder(TaskType.PROPAGATION)
+                .anyTypeKind(AnyTypeKind.USER)
+                .page(0).size(10)
+                .build()).getResult().isEmpty());
+        // delete all remaining SUCCESS tasks
+        response = taskService.purgePropagations(
+                oneWeekAgo.getTime(), Collections.singletonList(ExecStatus.SUCCESS),
+                Collections.emptyList());
+        assertEquals(Response.Status.OK.getStatusCode(), response.getStatus());
+
+        deleted = response.readEntity(new GenericType<List<PropagationTaskTO>>() {
+        });
+        assertNotNull(deleted);
     }
 
     @Test