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 49e013436f [SYNCOPE-1705] Encapsulating each object processing into an inner transaction (#383) 49e013436f is described below commit 49e013436f13856093548672105d79e5d6edb9a7 Author: Francesco Chicchiriccò <ilgro...@users.noreply.github.com> AuthorDate: Thu Oct 27 12:51:49 2022 +0200 [SYNCOPE-1705] Encapsulating each object processing into an inner transaction (#383) --- .../persistence/api/dao/ExternalResourceDAO.java | 4 +- .../core/persistence/api/dao/RemediationDAO.java | 1 - .../api/pushpull/ProvisioningActions.java | 4 +- .../provisioning/java/job/SetUMembershipsJob.java | 129 --------------------- .../propagation/DefaultPropagationReporter.java | 4 +- .../java/pushpull/AbstractPullResultHandler.java | 64 ++-------- .../pushpull/DefaultUserPullResultHandler.java | 6 +- .../java/pushpull/LDAPMembershipPullActions.java | 81 ++++++++++--- .../java/pushpull/SchedulingPullActions.java | 2 + .../pushpull/LDAPMembershipPullActionsTest.java | 46 ++------ .../apache/syncope/fit/core/PullTaskITCase.java | 4 +- 11 files changed, 99 insertions(+), 246 deletions(-) diff --git a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/ExternalResourceDAO.java b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/ExternalResourceDAO.java index 8fc338e8c3..bc3ec6e880 100644 --- a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/ExternalResourceDAO.java +++ b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/ExternalResourceDAO.java @@ -37,9 +37,9 @@ public interface ExternalResourceDAO extends DAO<ExternalResource> { boolean anyItemHaving(Implementation transformer); - List<ExternalResource> findByProvisionSorter(Implementation propagationActions); + List<ExternalResource> findByProvisionSorter(Implementation provisionSorter); - List<ExternalResource> findByPropagationActions(Implementation provisionSorter); + List<ExternalResource> findByPropagationActions(Implementation propagationActions); List<ExternalResource> findByPolicy(Policy policy); diff --git a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/RemediationDAO.java b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/RemediationDAO.java index 73216b30cf..5fd3d49737 100644 --- a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/RemediationDAO.java +++ b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/RemediationDAO.java @@ -41,5 +41,4 @@ public interface RemediationDAO extends DAO<Remediation> { void delete(Remediation remediation); void delete(String key); - } diff --git a/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/pushpull/ProvisioningActions.java b/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/pushpull/ProvisioningActions.java index ff3a3e4df1..afbf49aac2 100644 --- a/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/pushpull/ProvisioningActions.java +++ b/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/pushpull/ProvisioningActions.java @@ -28,7 +28,7 @@ public interface ProvisioningActions { * @param profile provisioning profile * @throws JobExecutionException in case of generic failure */ - default void beforeAll(final ProvisioningProfile<?, ?> profile) throws JobExecutionException { + default void beforeAll(ProvisioningProfile<?, ?> profile) throws JobExecutionException { // do nothing } @@ -38,7 +38,7 @@ public interface ProvisioningActions { * @param profile provisioning profile * @throws JobExecutionException in case of generic failure */ - default void afterAll(final ProvisioningProfile<?, ?> profile) throws JobExecutionException { + default void afterAll(ProvisioningProfile<?, ?> profile) throws JobExecutionException { // do nothing } } diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/job/SetUMembershipsJob.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/job/SetUMembershipsJob.java deleted file mode 100644 index a9d9a52538..0000000000 --- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/job/SetUMembershipsJob.java +++ /dev/null @@ -1,129 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ -package org.apache.syncope.core.provisioning.java.job; - -import java.util.ArrayList; -import java.util.List; -import java.util.Map; -import java.util.Optional; -import java.util.Set; -import org.apache.syncope.common.lib.request.MembershipUR; -import org.apache.syncope.common.lib.request.UserUR; -import org.apache.syncope.common.lib.types.PatchOperation; -import org.apache.syncope.core.provisioning.api.UserProvisioningManager; -import org.apache.syncope.core.provisioning.api.job.JobManager; -import org.apache.syncope.core.spring.ApplicationContextProvider; -import org.apache.syncope.core.spring.security.AuthContextUtils; -import org.apache.syncope.core.spring.security.SecurityProperties; -import org.quartz.JobExecutionContext; -import org.quartz.JobExecutionException; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.beans.factory.annotation.Autowired; - -/** - * Quartz Job used for setting user memberships asynchronously, after the completion of - * {@link org.apache.syncope.core.provisioning.api.pushpull.PullActions}. - */ -public class SetUMembershipsJob extends AbstractInterruptableJob { - - private static final Logger LOG = LoggerFactory.getLogger(SetUMembershipsJob.class); - - public static final String MEMBERSHIPS_BEFORE_KEY = "membershipsBefore"; - - public static final String MEMBERSHIPS_AFTER_KEY = "membershipsAfter"; - - public static final String CONTEXT = "context"; - - @Autowired - private SecurityProperties securityProperties; - - @Autowired - private UserProvisioningManager userProvisioningManager; - - @Override - public void execute(final JobExecutionContext context) throws JobExecutionException { - String executor = Optional.ofNullable(context.getMergedJobDataMap().getString(JobManager.EXECUTOR_KEY)). - orElse(securityProperties.getAdminUser()); - - try { - AuthContextUtils.callAsAdmin(context.getMergedJobDataMap().getString(JobManager.DOMAIN_KEY), () -> { - - @SuppressWarnings("unchecked") - Map<String, Set<String>> membershipsBefore = - (Map<String, Set<String>>) context.getMergedJobDataMap().get(MEMBERSHIPS_BEFORE_KEY); - LOG.debug("Memberships before pull (User -> Groups) {}", membershipsBefore); - - @SuppressWarnings("unchecked") - Map<String, Set<String>> membershipsAfter = - (Map<String, Set<String>>) context.getMergedJobDataMap().get(MEMBERSHIPS_AFTER_KEY); - LOG.debug("Memberships after pull (User -> Groups) {}", membershipsAfter); - - List<UserUR> updateReqs = new ArrayList<>(); - - membershipsAfter.forEach((user, groups) -> { - UserUR userUR = new UserUR(); - userUR.setKey(user); - updateReqs.add(userUR); - - groups.forEach(group -> { - Set<String> before = membershipsBefore.get(user); - if (before == null || !before.contains(group)) { - userUR.getMemberships().add(new MembershipUR.Builder(group). - operation(PatchOperation.ADD_REPLACE). - build()); - } - }); - }); - - membershipsBefore.forEach((user, groups) -> { - UserUR userUR = updateReqs.stream(). - filter(req -> user.equals(req.getKey())).findFirst(). - orElseGet(() -> { - UserUR req = new UserUR.Builder(user).build(); - updateReqs.add(req); - return req; - }); - - groups.forEach(group -> { - Set<String> after = membershipsAfter.get(user); - if (after == null || !after.contains(group)) { - userUR.getMemberships().add(new MembershipUR.Builder(group). - operation(PatchOperation.DELETE). - build()); - } - }); - }); - - updateReqs.stream().filter(req -> !req.isEmpty()).forEach(req -> { - LOG.debug("About to update User {}", req); - userProvisioningManager.update( - req, true, executor, context.getMergedJobDataMap().getString(CONTEXT)); - }); - - return null; - }); - } catch (RuntimeException e) { - LOG.error("While setting memberships", e); - throw new JobExecutionException("While executing memberships", e); - } finally { - ApplicationContextProvider.getBeanFactory().destroySingleton(context.getJobDetail().getKey().getName()); - } - } -} diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/propagation/DefaultPropagationReporter.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/propagation/DefaultPropagationReporter.java index 13037ca4e6..12225b472f 100644 --- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/propagation/DefaultPropagationReporter.java +++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/propagation/DefaultPropagationReporter.java @@ -18,10 +18,10 @@ */ package org.apache.syncope.core.provisioning.java.propagation; -import java.util.ArrayList; import java.util.Collection; import java.util.Collections; import java.util.List; +import java.util.concurrent.CopyOnWriteArrayList; import org.apache.syncope.common.lib.to.PropagationStatus; import org.apache.syncope.common.lib.types.ExecStatus; import org.apache.syncope.core.persistence.api.entity.task.PropagationTask; @@ -36,7 +36,7 @@ public class DefaultPropagationReporter implements PropagationReporter { protected static final Logger LOG = LoggerFactory.getLogger(DefaultPropagationReporter.class); - protected final List<PropagationStatus> statuses = new ArrayList<>(); + protected final List<PropagationStatus> statuses = new CopyOnWriteArrayList<>(); protected boolean add(final PropagationStatus status) { return statuses.stream().anyMatch(item -> item.getResource().equals(status.getResource())) diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/AbstractPullResultHandler.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/AbstractPullResultHandler.java index 440d0cfb18..29c7dc094a 100644 --- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/AbstractPullResultHandler.java +++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/AbstractPullResultHandler.java @@ -70,9 +70,9 @@ import org.identityconnectors.framework.common.objects.Attribute; import org.identityconnectors.framework.common.objects.SyncDelta; import org.quartz.JobExecutionException; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.transaction.annotation.Propagation; import org.springframework.transaction.annotation.Transactional; -@Transactional(rollbackFor = Throwable.class) public abstract class AbstractPullResultHandler extends AbstractSyncopeResultHandler<PullTask, PullActions> implements SyncopePullResultHandler { @@ -128,6 +128,7 @@ public abstract class AbstractPullResultHandler extends AbstractSyncopeResultHan this.executor = executor; } + @Transactional(rollbackFor = Throwable.class, propagation = Propagation.REQUIRES_NEW) @Override public boolean handle(final SyncDelta delta) { Provision provision = null; @@ -265,15 +266,7 @@ public abstract class AbstractPullResultHandler extends AbstractSyncopeResultHan if (profile.getTask().isRemediation()) { // set to SUCCESS to let the incremental flow go on in case of errors resultStatus = Result.SUCCESS; - createRemediation( - provision.getAnyType(), - null, - anyCR, - null, - taskDAO.exists(TaskType.PULL, profile.getTask().getKey()) - ? profile.getTask() : null, - result, - delta); + createRemediation(provision.getAnyType(), null, anyCR, null, result, delta); } else { resultStatus = Result.FAILURE; } @@ -391,13 +384,7 @@ public abstract class AbstractPullResultHandler extends AbstractSyncopeResultHan if (profile.getTask().isRemediation()) { // set to SUCCESS to let the incremental flow go on in case of errors resultStatus = Result.SUCCESS; - createRemediation( - provision.getAnyType(), - anyUR, - taskDAO.exists(TaskType.PULL, profile.getTask().getKey()) - ? profile.getTask() : null, - result, - delta); + createRemediation(provision.getAnyType(), null, null, anyUR, result, delta); } else { resultStatus = Result.FAILURE; } @@ -695,14 +682,7 @@ public abstract class AbstractPullResultHandler extends AbstractSyncopeResultHan // set to SUCCESS to let the incremental flow go on in case of errors resultStatus = Result.SUCCESS; createRemediation( - provision.getAnyType(), - match.getAny().getKey(), - null, - null, - taskDAO.exists(TaskType.PULL, profile.getTask().getKey()) - ? profile.getTask() : null, - result, - delta); + provision.getAnyType(), match.getAny().getKey(), null, null, result, delta); } } @@ -989,43 +969,15 @@ public abstract class AbstractPullResultHandler extends AbstractSyncopeResultHan final ProvisioningReport result) { if (ProvisioningReport.Status.FAILURE == result.getStatus() && profile.getTask().isRemediation()) { - createRemediation( - result.getAnyType(), - null, - null, - anyUR, - taskDAO.exists(TaskType.PULL, profile.getTask().getKey()) ? profile.getTask() : null, - result, - delta); + createRemediation(result.getAnyType(), null, null, anyUR, result, delta); } } - protected void createRemediation( - final String anyType, - final AnyCR anyCR, - final PullTask pullTask, - final ProvisioningReport result, - final SyncDelta delta) { - - createRemediation(anyType, null, anyCR, null, pullTask, result, delta); - } - - protected void createRemediation( - final String anyType, - final AnyUR anyUR, - final PullTask pullTask, - final ProvisioningReport result, - final SyncDelta delta) { - - createRemediation(anyType, null, null, anyUR, pullTask, result, delta); - } - protected void createRemediation( final String anyType, final String anyKey, final AnyCR anyCR, final AnyUR anyUR, - final PullTask pullTask, final ProvisioningReport result, final SyncDelta delta) { @@ -1043,7 +995,9 @@ public abstract class AbstractPullResultHandler extends AbstractSyncopeResultHan remediation.setError(result.getMessage()); remediation.setInstant(OffsetDateTime.now()); remediation.setRemoteName(delta.getObject().getName().getNameValue()); - remediation.setPullTask(pullTask); + if (taskDAO.exists(TaskType.PULL, profile.getTask().getKey())) { + remediation.setPullTask((PullTask) taskDAO.find(TaskType.PULL, profile.getTask().getKey())); + } remediation = remediationDAO.save(remediation); diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/DefaultUserPullResultHandler.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/DefaultUserPullResultHandler.java index 9232e4b011..08164b5d91 100644 --- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/DefaultUserPullResultHandler.java +++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/DefaultUserPullResultHandler.java @@ -422,7 +422,7 @@ public class DefaultUserPullResultHandler extends AbstractPullResultHandler impl resultStatus = Result.FAILURE; if (profile.getTask().isRemediation()) { - createRemediation(provision.getAnyType(), req, profile.getTask(), report, delta); + createRemediation(provision.getAnyType(), null, null, req, report, delta); } } @@ -541,7 +541,7 @@ public class DefaultUserPullResultHandler extends AbstractPullResultHandler impl resultStatus = Result.FAILURE; if (profile.getTask().isRemediation()) { - createRemediation(provision.getAnyType(), userUR, profile.getTask(), report, delta); + createRemediation(provision.getAnyType(), null, null, userUR, report, delta); } } @@ -617,7 +617,7 @@ public class DefaultUserPullResultHandler extends AbstractPullResultHandler impl output = e; if (profile.getTask().isRemediation()) { - createRemediation(provision.getAnyType(), req, profile.getTask(), report, delta); + createRemediation(provision.getAnyType(), null, null, req, report, delta); } } diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/LDAPMembershipPullActions.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/LDAPMembershipPullActions.java index 3bb5a9cc86..0dad00af24 100644 --- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/LDAPMembershipPullActions.java +++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/LDAPMembershipPullActions.java @@ -18,6 +18,7 @@ */ package org.apache.syncope.core.provisioning.java.pushpull; +import java.util.ArrayList; import java.util.HashMap; import java.util.HashSet; import java.util.List; @@ -25,18 +26,23 @@ import java.util.Map; import java.util.Optional; import java.util.Set; import org.apache.syncope.common.lib.request.AnyUR; +import org.apache.syncope.common.lib.request.MembershipUR; +import org.apache.syncope.common.lib.request.UserUR; import org.apache.syncope.common.lib.to.EntityTO; import org.apache.syncope.common.lib.to.GroupTO; import org.apache.syncope.common.lib.to.Provision; import org.apache.syncope.common.lib.to.ProvisioningReport; import org.apache.syncope.common.lib.types.AnyTypeKind; +import org.apache.syncope.common.lib.types.PatchOperation; import org.apache.syncope.core.persistence.api.dao.AnyTypeDAO; import org.apache.syncope.core.persistence.api.dao.GroupDAO; import org.apache.syncope.core.persistence.api.dao.PullMatch; import org.apache.syncope.core.provisioning.api.Connector; -import org.apache.syncope.core.provisioning.api.job.JobManager; +import org.apache.syncope.core.provisioning.api.UserProvisioningManager; import org.apache.syncope.core.provisioning.api.pushpull.ProvisioningProfile; -import org.apache.syncope.core.provisioning.java.job.SetUMembershipsJob; +import org.apache.syncope.core.provisioning.api.pushpull.PullActions; +import org.apache.syncope.core.spring.implementation.InstanceScope; +import org.apache.syncope.core.spring.implementation.SyncopeImplementation; import org.identityconnectors.framework.common.objects.Attribute; import org.identityconnectors.framework.common.objects.ConnectorObject; import org.identityconnectors.framework.common.objects.ObjectClass; @@ -46,6 +52,7 @@ import org.quartz.JobExecutionException; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.transaction.annotation.Propagation; import org.springframework.transaction.annotation.Transactional; /** @@ -54,7 +61,8 @@ import org.springframework.transaction.annotation.Transactional; * * @see org.apache.syncope.core.provisioning.java.propagation.LDAPMembershipPropagationActions */ -public class LDAPMembershipPullActions extends SchedulingPullActions { +@SyncopeImplementation(scope = InstanceScope.PER_CONTEXT) +public class LDAPMembershipPullActions implements PullActions { protected static final Logger LOG = LoggerFactory.getLogger(LDAPMembershipPullActions.class); @@ -65,7 +73,10 @@ public class LDAPMembershipPullActions extends SchedulingPullActions { protected GroupDAO groupDAO; @Autowired - private InboundMatcher inboundMatcher; + protected InboundMatcher inboundMatcher; + + @Autowired + protected UserProvisioningManager userProvisioningManager; protected final Map<String, Set<String>> membershipsBefore = new HashMap<>(); @@ -137,7 +148,8 @@ public class LDAPMembershipPullActions extends SchedulingPullActions { final AnyUR anyUR) throws JobExecutionException { if (!(entity instanceof GroupTO)) { - super.beforeUpdate(profile, delta, entity, anyUR); + PullActions.super.beforeUpdate(profile, delta, entity, anyUR); + return; } groupDAO.findUMemberships(groupDAO.find(entity.getKey())).forEach(uMembership -> { @@ -162,13 +174,15 @@ public class LDAPMembershipPullActions extends SchedulingPullActions { final ProvisioningReport result) throws JobExecutionException { if (!(entity instanceof GroupTO)) { - super.after(profile, delta, entity, result); + PullActions.super.after(profile, delta, entity, result); + return; } Optional<Provision> provision = profile.getTask().getResource(). getProvisionByAnyType(AnyTypeKind.USER.name()).filter(p -> p.getMapping() != null); if (provision.isEmpty()) { - super.after(profile, delta, entity, result); + PullActions.super.after(profile, delta, entity, result); + return; } getMembAttrValues(delta, profile.getConnector()).forEach(membValue -> { @@ -190,15 +204,52 @@ public class LDAPMembershipPullActions extends SchedulingPullActions { }); } + @Transactional(propagation = Propagation.REQUIRES_NEW) @Override public void afterAll(final ProvisioningProfile<?, ?> profile) throws JobExecutionException { - Map<String, Object> jobMap = new HashMap<>(); - jobMap.put(SetUMembershipsJob.MEMBERSHIPS_BEFORE_KEY, membershipsBefore); - jobMap.put(SetUMembershipsJob.MEMBERSHIPS_AFTER_KEY, membershipsAfter); - jobMap.put(JobManager.EXECUTOR_KEY, profile.getExecutor()); - jobMap.put( - SetUMembershipsJob.CONTEXT, - "PullTask " + profile.getTask().getKey() + " '" + profile.getTask().getName() + "'"); - schedule(SetUMembershipsJob.class, jobMap); + List<UserUR> updateReqs = new ArrayList<>(); + + membershipsAfter.forEach((user, groups) -> { + UserUR userUR = new UserUR(); + userUR.setKey(user); + updateReqs.add(userUR); + + groups.stream().forEach(group -> { + Set<String> before = membershipsBefore.get(user); + if (before == null || !before.contains(group)) { + userUR.getMemberships().add(new MembershipUR.Builder(group). + operation(PatchOperation.ADD_REPLACE). + build()); + } + }); + }); + + membershipsBefore.forEach((user, groups) -> { + UserUR userUR = updateReqs.stream(). + filter(req -> user.equals(req.getKey())).findFirst(). + orElseGet(() -> { + UserUR req = new UserUR.Builder(user).build(); + updateReqs.add(req); + return req; + }); + + groups.forEach(group -> { + Set<String> after = membershipsAfter.get(user); + if (after == null || !after.contains(group)) { + userUR.getMemberships().add(new MembershipUR.Builder(group). + operation(PatchOperation.DELETE). + build()); + } + }); + }); + + membershipsAfter.clear(); + membershipsBefore.clear(); + + String context = "PullTask " + profile.getTask().getKey() + " '" + profile.getTask().getName() + "'"; + updateReqs.stream().filter(req -> !req.isEmpty()).forEach(req -> { + LOG.debug("About to update memberships for User {}", req.getKey()); + userProvisioningManager.update(req, true, profile.getExecutor(), context); + }); } } diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/SchedulingPullActions.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/SchedulingPullActions.java index cdf4483c45..c4fdbb0863 100644 --- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/SchedulingPullActions.java +++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/SchedulingPullActions.java @@ -41,6 +41,8 @@ import org.springframework.scheduling.quartz.SchedulerFactoryBean; * Superclass for pull actions that need to schedule actions to run after their completion. * * @see LDAPMembershipPullActions for a concrete example + * @deprecated From 3.0.0-M2 this class is not needed anymore and will be removed from 3.0.0 onwards. + * After SYNCOPE-1705 there is no need anymore to schedule a job to run after the current pull task execution */ public abstract class SchedulingPullActions implements PullActions { diff --git a/core/provisioning-java/src/test/java/org/apache/syncope/core/provisioning/java/pushpull/LDAPMembershipPullActionsTest.java b/core/provisioning-java/src/test/java/org/apache/syncope/core/provisioning/java/pushpull/LDAPMembershipPullActionsTest.java index a4d6ce0030..0d3a976d6a 100644 --- a/core/provisioning-java/src/test/java/org/apache/syncope/core/provisioning/java/pushpull/LDAPMembershipPullActionsTest.java +++ b/core/provisioning-java/src/test/java/org/apache/syncope/core/provisioning/java/pushpull/LDAPMembershipPullActionsTest.java @@ -39,6 +39,7 @@ import org.apache.syncope.common.lib.request.AnyUR; import org.apache.syncope.common.lib.request.UserUR; import org.apache.syncope.common.lib.to.EntityTO; import org.apache.syncope.common.lib.to.GroupTO; +import org.apache.syncope.common.lib.to.Mapping; import org.apache.syncope.common.lib.to.Provision; import org.apache.syncope.common.lib.to.ProvisioningReport; import org.apache.syncope.common.lib.to.UserTO; @@ -68,10 +69,7 @@ import org.junit.jupiter.api.Test; import org.mockito.InjectMocks; import org.mockito.Mock; import org.quartz.JobExecutionException; -import org.quartz.Scheduler; -import org.quartz.SchedulerException; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.scheduling.quartz.SchedulerFactoryBean; import org.springframework.test.util.ReflectionTestUtils; public class LDAPMembershipPullActionsTest extends AbstractTest { @@ -104,10 +102,13 @@ public class LDAPMembershipPullActionsTest extends AbstractTest { private Map<String, Set<String>> membershipsAfter; @Mock - private ProvisioningTask<?> provisioningTask; + private ProvisioningTask<?> pullTask; @Mock - private ExternalResource externalResource; + private ExternalResource resource; + + @Mock + private Provision provision; @Mock private Connector connector; @@ -150,8 +151,10 @@ public class LDAPMembershipPullActionsTest extends AbstractTest { connConfProperties = new HashSet<>(); connConfProperties.add(connConfProperty); - lenient().when(profile.getTask()).thenAnswer(ic -> provisioningTask); - lenient().when(provisioningTask.getResource()).thenReturn(externalResource); + lenient().when(profile.getTask()).thenAnswer(ic -> pullTask); + lenient().when(pullTask.getResource()).thenReturn(resource); + lenient().when(resource.getProvisionByAnyType(anyString())).thenReturn(Optional.of(provision)); + lenient().when(provision.getMapping()).thenReturn(new Mapping()); lenient().when(anyTypeDAO.findUser()).thenAnswer(ic -> { AnyType userAnyType = mock(AnyType.class); lenient().when(userAnyType.getKey()).thenReturn(AnyTypeKind.USER.name()); @@ -192,27 +195,14 @@ public class LDAPMembershipPullActionsTest extends AbstractTest { assertEquals(1, membershipsBefore.get(user.getKey()).size()); } - @Test - public void afterWithEmptyAttributes(final @Mock Attribute attribute) throws JobExecutionException { - entity = new GroupTO(); - - when(connectorObj.getAttributeByName(anyString())).thenReturn(attribute); - when(externalResource.getProvisionByAnyType(anyString())).thenAnswer(ic -> Optional.of(mock(Provision.class))); - - ldapMembershipPullActions.after(profile, syncDelta, entity, result); - - assertEquals(List.of(), attribute.getValue()); - } - @Test public void after() throws JobExecutionException { - entity = new UserTO(); + entity = new GroupTO(); String expectedUid = UUID.randomUUID().toString(); Attribute attribute = new Uid(expectedUid); List<String> expected = List.of(expectedUid); when(connectorObj.getAttributeByName(anyString())).thenReturn(attribute); - when(externalResource.getProvisionByAnyType(anyString())).thenAnswer(ic -> Optional.empty()); when(inboundMatcher.match(any(AnyType.class), anyString(), any(ExternalResource.class), any(Connector.class))). thenReturn(Optional.of(new PullMatch(MatchType.ANY, user))); @@ -222,18 +212,4 @@ public class LDAPMembershipPullActionsTest extends AbstractTest { verify(membershipsAfter).put(anyString(), any()); assertEquals(expected, attribute.getValue()); } - - @Test - public void afterAll( - final @Mock Map<String, Object> jobMap, - final @Mock SchedulerFactoryBean schedulerFactoryBean, - final @Mock Scheduler scheduler) throws JobExecutionException, SchedulerException { - - ReflectionTestUtils.setField(ldapMembershipPullActions, "scheduler", schedulerFactoryBean); - when(schedulerFactoryBean.getScheduler()).thenReturn(scheduler); - - ldapMembershipPullActions.afterAll(profile); - - verify(scheduler).scheduleJob(any(), any()); - } } diff --git a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/PullTaskITCase.java b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/PullTaskITCase.java index 1301d14e25..b6c1571008 100644 --- a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/PullTaskITCase.java +++ b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/PullTaskITCase.java @@ -436,7 +436,7 @@ public class PullTaskITCase extends AbstractTaskITCase { assertEquals("odd", userConnObject.getAttr("title").get().getValues().get(0)); Attr userDn = userConnObject.getAttr(Name.NAME).get(); updateLdapRemoteObject(RESOURCE_LDAP_ADMIN_DN, RESOURCE_LDAP_ADMIN_PWD, - userDn.getValues().get(0), Collections.singletonMap("title", (String) null)); + userDn.getValues().get(0), Collections.singletonMap("title", null)); // SYNCOPE-317 execProvisioningTask( @@ -1083,7 +1083,7 @@ public class PullTaskITCase extends AbstractTaskITCase { @Test public void issueSYNCOPE307() { assumeFalse(ElasticsearchDetector.isElasticSearchEnabled(ADMIN_CLIENT.platform())); - + UserCR userCR = UserITCase.getUniqueSample("s...@apache.org"); userCR.setUsername("test0"); userCR.getPlainAttrs().removeIf(attr -> "firstname".equals(attr.getSchema()));