You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@syncope.apache.org by il...@apache.org on 2022/01/31 17:20:01 UTC
[syncope] branch master updated: [SYNCOPE-1641] added resources to match to purge propagation tasks API (#305)
This is an automated email from the ASF dual-hosted git repository.
ilgrosso pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/syncope.git
The following commit(s) were added to refs/heads/master by this push:
new c1087c5 [SYNCOPE-1641] added resources to match to purge propagation tasks API (#305)
c1087c5 is described below
commit c1087c525b65258fdea224a85acb8fda5eb32384
Author: Andrea Patricelli <an...@apache.org>
AuthorDate: Mon Jan 31 18:19:54 2022 +0100
[SYNCOPE-1641] added resources to match to purge propagation tasks API (#305)
---
.../common/rest/api/service/TaskService.java | 5 ++++-
.../org/apache/syncope/core/logic/TaskLogic.java | 11 +++++++++--
.../core/rest/cxf/service/TaskServiceImpl.java | 7 ++++---
.../syncope/core/persistence/api/dao/TaskDAO.java | 5 ++++-
.../src/test/resources/domains/MasterContent.xml | 5 +++++
.../core/persistence/jpa/dao/JPATaskDAO.java | 13 ++++++++++++-
.../core/persistence/jpa/inner/TaskTest.java | 4 ++--
.../src/test/resources/domains/MasterContent.xml | 5 +++++
.../syncope/fit/core/PropagationTaskITCase.java | 21 +++++++++++++++++++--
9 files changed, 64 insertions(+), 12 deletions(-)
diff --git a/common/idrepo/rest-api/src/main/java/org/apache/syncope/common/rest/api/service/TaskService.java b/common/idrepo/rest-api/src/main/java/org/apache/syncope/common/rest/api/service/TaskService.java
index caa1695..dcaa2c7 100644
--- a/common/idrepo/rest-api/src/main/java/org/apache/syncope/common/rest/api/service/TaskService.java
+++ b/common/idrepo/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/idrepo/logic/src/main/java/org/apache/syncope/core/logic/TaskLogic.java b/core/idrepo/logic/src/main/java/org/apache/syncope/core/logic/TaskLogic.java
index afcb042..904491f 100644
--- a/core/idrepo/logic/src/main/java/org/apache/syncope/core/logic/TaskLogic.java
+++ b/core/idrepo/logic/src/main/java/org/apache/syncope/core/logic/TaskLogic.java
@@ -23,6 +23,8 @@ import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;
+import java.util.Objects;
+import java.util.Optional;
import java.util.stream.Collectors;
import javax.ws.rs.core.Response;
import org.apache.commons.lang3.ArrayUtils;
@@ -472,8 +474,13 @@ public class TaskLogic extends AbstractExecutableLogic<TaskTO> {
}
@PreAuthorize("hasRole('" + IdRepoEntitlement.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, Optional.ofNullable(resources).
+ map(r -> r.stream().map(resourceDAO::find).filter(Objects::nonNull).collect(Collectors.toList()))
+ .orElse(null));
}
@Override
diff --git a/core/idrepo/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/TaskServiceImpl.java b/core/idrepo/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/TaskServiceImpl.java
index 9b32cb4..3177cdd 100644
--- a/core/idrepo/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/TaskServiceImpl.java
+++ b/core/idrepo/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/TaskServiceImpl.java
@@ -98,11 +98,12 @@ 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/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-json/src/test/resources/domains/MasterContent.xml b/core/persistence-jpa-json/src/test/resources/domains/MasterContent.xml
index 698faf4..dbc0d9c 100644
--- a/core/persistence-jpa-json/src/test/resources/domains/MasterContent.xml
+++ b/core/persistence-jpa-json/src/test/resources/domains/MasterContent.xml
@@ -1038,6 +1038,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/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 c28b6ff..d7d573c 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
@@ -487,7 +487,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) ");
@@ -505,6 +508,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 d9257fc..04d2470 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
@@ -88,12 +88,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 7bfcd49..b657243 100644
--- a/core/persistence-jpa/src/test/resources/domains/MasterContent.xml
+++ b/core/persistence-jpa/src/test/resources/domains/MasterContent.xml
@@ -1125,6 +1125,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/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 a61a70e..1f26de8 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
@@ -275,7 +275,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);
@@ -284,12 +284,29 @@ 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(), List.of(ExecStatus.SUCCESS),
+ List.of(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(), List.of(ExecStatus.SUCCESS), List.of());
+ assertEquals(Response.Status.OK.getStatusCode(), response.getStatus());
+
+ deleted = response.readEntity(new GenericType<List<PropagationTaskTO>>() {
+ });
+ assertNotNull(deleted);
}
@Test