[SYNCOPE-732] Implementation completed
Project: http://git-wip-us.apache.org/repos/asf/syncope/repo Commit: http://git-wip-us.apache.org/repos/asf/syncope/commit/b4a51a8a Tree: http://git-wip-us.apache.org/repos/asf/syncope/tree/b4a51a8a Diff: http://git-wip-us.apache.org/repos/asf/syncope/diff/b4a51a8a Branch: refs/heads/master Commit: b4a51a8a86905ee9e3e7395df442ab2aea2bae34 Parents: 4eaee19 Author: Francesco Chicchiriccò <[email protected]> Authored: Mon Nov 16 15:21:52 2015 +0100 Committer: Francesco Chicchiriccò <[email protected]> Committed: Mon Nov 16 15:21:52 2015 +0100 ---------------------------------------------------------------------- .../EntitlementSyncopeOperations.java | 3 +- .../syncope/client/cli/commands/info/Info.java | 11 +- .../client/cli/commands/info/InfoCommand.java | 6 +- .../cli/commands/info/InfoResultManager.java | 38 +++--- .../client/cli/commands/task/TaskDetails.java | 7 +- .../cli/commands/task/TaskResultManager.java | 3 +- .../console/rest/ConfigurationRestClient.java | 3 +- .../client/console/rest/PolicyRestClient.java | 5 +- .../client/console/rest/ResourceRestClient.java | 3 +- .../client/console/rest/SchemaRestClient.java | 8 +- .../client/console/rest/TaskRestClient.java | 7 +- .../syncope/common/lib/to/SyncTaskTO.java | 29 +++-- .../apache/syncope/common/lib/to/SyncopeTO.java | 73 ++++++----- .../syncope/common/lib/types/SyncMode.java | 29 +++++ .../apache/syncope/core/logic/SyncopeLogic.java | 2 + .../init/ClassPathScanImplementationLookup.java | 6 + .../persistence/api/ImplementationLookup.java | 1 + .../persistence/api/entity/task/SyncTask.java | 13 +- .../jpa/entity/task/JPASyncTask.java | 48 +++++--- .../entity/ProvisioningTaskValidator.java | 27 ++++ .../core/persistence/jpa/outer/TaskTest.java | 3 + .../test/resources/domains/MasterContent.xml | 22 ++-- .../core/provisioning/api/Connector.java | 17 ++- .../api/sync/ReconciliationFilterBuilder.java | 30 +++++ .../provisioning/java/ConnectorFacadeProxy.java | 19 ++- .../java/data/TaskDataBinderImpl.java | 9 +- .../DefaultReconciliationFilterBuilder.java | 38 ++++++ .../java/sync/DefaultSyncActions.java | 2 +- .../provisioning/java/sync/SyncJobDelegate.java | 61 +++++---- .../TestReconciliationFilterBuilder.java | 35 ++++++ .../fit/core/reference/MultitenancyITCase.java | 5 +- .../fit/core/reference/PushTaskITCase.java | 3 +- .../fit/core/reference/ReportITCase.java | 3 +- .../fit/core/reference/ResourceITCase.java | 2 +- .../fit/core/reference/SchedTaskITCase.java | 3 +- .../fit/core/reference/SyncTaskITCase.java | 123 ++++++++++++++----- 36 files changed, 512 insertions(+), 185 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/syncope/blob/b4a51a8a/client/cli/src/main/java/org/apache/syncope/client/cli/commands/entitlement/EntitlementSyncopeOperations.java ---------------------------------------------------------------------- diff --git a/client/cli/src/main/java/org/apache/syncope/client/cli/commands/entitlement/EntitlementSyncopeOperations.java b/client/cli/src/main/java/org/apache/syncope/client/cli/commands/entitlement/EntitlementSyncopeOperations.java index ead55e7..797678f 100644 --- a/client/cli/src/main/java/org/apache/syncope/client/cli/commands/entitlement/EntitlementSyncopeOperations.java +++ b/client/cli/src/main/java/org/apache/syncope/client/cli/commands/entitlement/EntitlementSyncopeOperations.java @@ -19,7 +19,6 @@ package org.apache.syncope.client.cli.commands.entitlement; import java.util.HashSet; -import java.util.List; import java.util.Set; import java.util.TreeSet; import org.apache.syncope.client.cli.SyncopeServices; @@ -38,7 +37,7 @@ public class EntitlementSyncopeOperations { private final RoleSyncopeOperations roleSyncopeOperations = new RoleSyncopeOperations(); - public List<String> list() { + public Set<String> list() { return syncopeTO.getEntitlements(); } http://git-wip-us.apache.org/repos/asf/syncope/blob/b4a51a8a/client/cli/src/main/java/org/apache/syncope/client/cli/commands/info/Info.java ---------------------------------------------------------------------- diff --git a/client/cli/src/main/java/org/apache/syncope/client/cli/commands/info/Info.java b/client/cli/src/main/java/org/apache/syncope/client/cli/commands/info/Info.java index a1f6956..bdb430f 100644 --- a/client/cli/src/main/java/org/apache/syncope/client/cli/commands/info/Info.java +++ b/client/cli/src/main/java/org/apache/syncope/client/cli/commands/info/Info.java @@ -101,7 +101,7 @@ public class Info { } } - public void connidLocation() { + public void connidLocations() { try { infoResultManager.printConnidLocations(syncopeTO.getConnIdLocations()); } catch (final Exception ex) { @@ -110,6 +110,15 @@ public class Info { } } + public void reconciliationFilterBuilders() { + try { + infoResultManager.printReconciliationFilterBuilders(syncopeTO.getReconciliationFilterBuilders()); + } catch (final Exception ex) { + LOG.error("Information error", ex); + infoResultManager.genericError(ex.getMessage()); + } + } + public void logicActions() { try { infoResultManager.printLogicActions(syncopeTO.getLogicActions()); http://git-wip-us.apache.org/repos/asf/syncope/blob/b4a51a8a/client/cli/src/main/java/org/apache/syncope/client/cli/commands/info/InfoCommand.java ---------------------------------------------------------------------- diff --git a/client/cli/src/main/java/org/apache/syncope/client/cli/commands/info/InfoCommand.java b/client/cli/src/main/java/org/apache/syncope/client/cli/commands/info/InfoCommand.java index b2882d3..db2c283 100644 --- a/client/cli/src/main/java/org/apache/syncope/client/cli/commands/info/InfoCommand.java +++ b/client/cli/src/main/java/org/apache/syncope/client/cli/commands/info/InfoCommand.java @@ -59,7 +59,10 @@ public class InfoCommand extends AbstractCommand { info.accountRules(); break; case CONNID_LOCATION: - info.connidLocation(); + info.connidLocations(); + break; + case RECONCILIATION_FILTER_BUILDERS: + info.reconciliationFilterBuilders(); break; case LOGIC_ACTIONS: info.logicActions(); @@ -128,6 +131,7 @@ public class InfoCommand extends AbstractCommand { WORKFLOW_ADAPTER("--workflow-adapter-classes"), ACCOUNT_RULES("--account-rules-classes"), CONNID_LOCATION("--connid-locations"), + RECONCILIATION_FILTER_BUILDERS("--reconciliation-filter-builders"), LOGIC_ACTIONS("--logic-actions"), MAIL_TEMPLATES("--mail-templates"), MAPPING_ITEM_TRANSFORMERS("--mapping-item-transformers"), http://git-wip-us.apache.org/repos/asf/syncope/blob/b4a51a8a/client/cli/src/main/java/org/apache/syncope/client/cli/commands/info/InfoResultManager.java ---------------------------------------------------------------------- diff --git a/client/cli/src/main/java/org/apache/syncope/client/cli/commands/info/InfoResultManager.java b/client/cli/src/main/java/org/apache/syncope/client/cli/commands/info/InfoResultManager.java index c4eb206..f5f816f 100644 --- a/client/cli/src/main/java/org/apache/syncope/client/cli/commands/info/InfoResultManager.java +++ b/client/cli/src/main/java/org/apache/syncope/client/cli/commands/info/InfoResultManager.java @@ -18,7 +18,7 @@ */ package org.apache.syncope.client.cli.commands.info; -import java.util.List; +import java.util.Collection; import org.apache.syncope.client.cli.commands.CommonsResultManager; public class InfoResultManager extends CommonsResultManager { @@ -57,85 +57,91 @@ public class InfoResultManager extends CommonsResultManager { "Group workflow adapter class: " + groupWorkflowAdapter); } - public void printAccountRules(final List<String> rules) { + public void printAccountRules(final Collection<String> rules) { for (final String accountRule : rules) { genericMessage("Account rule: " + accountRule); } } - public void printConnidLocations(final List<String> locations) { + public void printConnidLocations(final Collection<String> locations) { for (final String location : locations) { genericMessage("ConnId location: " + location); } } - public void printLogicActions(final List<String> actions) { + public void printReconciliationFilterBuilders(final Collection<String> reconciliationFilterBuilders) { + for (final String reconciliationFilterBuilder : reconciliationFilterBuilders) { + genericMessage("Reconciliation filter builder: " + reconciliationFilterBuilder); + } + } + + public void printLogicActions(final Collection<String> actions) { for (final String action : actions) { genericMessage("Logic action: " + action); } } - public void printMailTemplates(final List<String> mailTemplates) { + public void printMailTemplates(final Collection<String> mailTemplates) { for (final String template : mailTemplates) { genericMessage("Mail template: " + template); } } - public void printMappingItemTransformers(final List<String> transformers) { + public void printMappingItemTransformers(final Collection<String> transformers) { for (final String tranformer : transformers) { genericMessage("Mapping item tranformer: " + tranformer); } } - public void printPasswordRules(final List<String> rules) { + public void printPasswordRules(final Collection<String> rules) { for (final String rule : rules) { genericMessage("Password rule: " + rule); } } - public void printCorrelationRules(final List<String> rules) { + public void printCorrelationRules(final Collection<String> rules) { for (final String rule : rules) { genericMessage("Correlation rule: " + rule); } } - public void printPropagationActions(final List<String> actions) { + public void printPropagationActions(final Collection<String> actions) { for (final String action : actions) { genericMessage("Propagation action: " + action); } } - public void printPushActions(final List<String> actions) { + public void printPushActions(final Collection<String> actions) { for (final String action : actions) { genericMessage("Push action: " + action); } } - public void printSyncActions(final List<String> actions) { + public void printSyncActions(final Collection<String> actions) { for (final String action : actions) { genericMessage("Sync action: " + action); } } - public void printCorrelationActions(final List<String> actions) { + public void printCorrelationActions(final Collection<String> actions) { for (final String action : actions) { genericMessage("Push correlation rule: " + action); } } - public void printReportlets(final List<String> reportlets) { + public void printReportlets(final Collection<String> reportlets) { for (final String reportlet : reportlets) { genericMessage("Reportlet: " + reportlet); } } - public void printJobs(final List<String> jobs) { + public void printJobs(final Collection<String> jobs) { for (final String job : jobs) { genericMessage("Task job: " + job); } } - public void printValidators(final List<String> validators) { + public void printValidators(final Collection<String> validators) { for (final String validator : validators) { genericMessage("Validator: " + validator); } @@ -144,7 +150,7 @@ public class InfoResultManager extends CommonsResultManager { public void printPasswordGenerator(final String passwordGenerator) { genericMessage("Password generator class: " + passwordGenerator); } - + public void printVirtualAttributeCacheClass(final String virAttrCache) { genericMessage("Virtual attribute cache class: " + virAttrCache); } http://git-wip-us.apache.org/repos/asf/syncope/blob/b4a51a8a/client/cli/src/main/java/org/apache/syncope/client/cli/commands/task/TaskDetails.java ---------------------------------------------------------------------- diff --git a/client/cli/src/main/java/org/apache/syncope/client/cli/commands/task/TaskDetails.java b/client/cli/src/main/java/org/apache/syncope/client/cli/commands/task/TaskDetails.java index 0e12590..4409c35 100644 --- a/client/cli/src/main/java/org/apache/syncope/client/cli/commands/task/TaskDetails.java +++ b/client/cli/src/main/java/org/apache/syncope/client/cli/commands/task/TaskDetails.java @@ -31,6 +31,7 @@ import org.apache.syncope.common.lib.to.PushTaskTO; import org.apache.syncope.common.lib.to.SchedTaskTO; import org.apache.syncope.common.lib.to.SyncTaskTO; import org.apache.syncope.common.lib.to.TaskExecTO; +import org.apache.syncope.common.lib.types.SyncMode; import org.apache.syncope.common.lib.types.TaskType; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -51,8 +52,8 @@ public class TaskDetails extends AbstractTaskCommand { if (input.parameterNumber() == 0) { try { final Map<String, String> details = new LinkedMap<>(); - final List<AbstractTaskTO> notificationTaskTOs - = taskSyncopeOperations.list(TaskType.NOTIFICATION.name()); + final List<AbstractTaskTO> notificationTaskTOs = + taskSyncopeOperations.list(TaskType.NOTIFICATION.name()); final List<AbstractTaskTO> propagationTaskTOs = taskSyncopeOperations.list(TaskType.PROPAGATION.name()); final List<AbstractTaskTO> pushTaskTOs = taskSyncopeOperations.list(TaskType.PUSH.name()); final List<AbstractTaskTO> scheduledTaskTOs = taskSyncopeOperations.list(TaskType.SCHEDULED.name()); @@ -105,7 +106,7 @@ public class TaskDetails extends AbstractTaskCommand { || ((SyncTaskTO) syncTaskTO).getExecutions().isEmpty()) { syncNotExecuted++; } - if (((SyncTaskTO) syncTaskTO).isFullReconciliation()) { + if (((SyncTaskTO) syncTaskTO).getSyncMode() == SyncMode.FULL_RECONCILIATION) { syncFull++; } } http://git-wip-us.apache.org/repos/asf/syncope/blob/b4a51a8a/client/cli/src/main/java/org/apache/syncope/client/cli/commands/task/TaskResultManager.java ---------------------------------------------------------------------- diff --git a/client/cli/src/main/java/org/apache/syncope/client/cli/commands/task/TaskResultManager.java b/client/cli/src/main/java/org/apache/syncope/client/cli/commands/task/TaskResultManager.java index 2441864..a1fdb0b 100644 --- a/client/cli/src/main/java/org/apache/syncope/client/cli/commands/task/TaskResultManager.java +++ b/client/cli/src/main/java/org/apache/syncope/client/cli/commands/task/TaskResultManager.java @@ -170,8 +170,7 @@ public class TaskResultManager extends CommonsResultManager { System.out.println(" realm destination: " + syncTaskTO.getDestinationRealm()); System.out.println(" cron expression: " + syncTaskTO.getCronExpression()); System.out.println(" description: " + syncTaskTO.getDescription()); - System.out.println(" is full reconciliation: " - + syncTaskTO.isFullReconciliation()); + System.out.println(" sync mode: " + syncTaskTO.getSyncMode()); System.out.println(" perform create: " + syncTaskTO.isPerformCreate()); System.out.println(" perform delete: " + syncTaskTO.isPerformDelete()); System.out.println(" perform update: " + syncTaskTO.isPerformUpdate()); http://git-wip-us.apache.org/repos/asf/syncope/blob/b4a51a8a/client/console/src/main/java/org/apache/syncope/client/console/rest/ConfigurationRestClient.java ---------------------------------------------------------------------- diff --git a/client/console/src/main/java/org/apache/syncope/client/console/rest/ConfigurationRestClient.java b/client/console/src/main/java/org/apache/syncope/client/console/rest/ConfigurationRestClient.java index d1ec74d..622a4ca 100644 --- a/client/console/src/main/java/org/apache/syncope/client/console/rest/ConfigurationRestClient.java +++ b/client/console/src/main/java/org/apache/syncope/client/console/rest/ConfigurationRestClient.java @@ -19,6 +19,7 @@ package org.apache.syncope.client.console.rest; import java.util.List; +import java.util.Set; import javax.ws.rs.core.Response; import org.apache.syncope.client.console.SyncopeConsoleSession; import org.apache.syncope.client.console.commons.AttrLayoutType; @@ -82,7 +83,7 @@ public class ConfigurationRestClient extends BaseRestClient { getService(ConfigurationService.class).delete(key); } - public List<String> getMailTemplates() { + public Set<String> getMailTemplates() { return SyncopeConsoleSession.get().getSyncopeTO().getMailTemplates(); } http://git-wip-us.apache.org/repos/asf/syncope/blob/b4a51a8a/client/console/src/main/java/org/apache/syncope/client/console/rest/PolicyRestClient.java ---------------------------------------------------------------------- diff --git a/client/console/src/main/java/org/apache/syncope/client/console/rest/PolicyRestClient.java b/client/console/src/main/java/org/apache/syncope/client/console/rest/PolicyRestClient.java index 7f5964b..a3f44a1 100644 --- a/client/console/src/main/java/org/apache/syncope/client/console/rest/PolicyRestClient.java +++ b/client/console/src/main/java/org/apache/syncope/client/console/rest/PolicyRestClient.java @@ -20,6 +20,7 @@ package org.apache.syncope.client.console.rest; import java.util.ArrayList; import java.util.List; +import java.util.Set; import org.apache.syncope.client.console.SyncopeConsoleSession; import org.apache.syncope.common.lib.policy.AbstractPolicyTO; import org.apache.syncope.common.lib.types.PolicyType; @@ -69,8 +70,8 @@ public class PolicyRestClient extends BaseRestClient { getService(PolicyService.class).delete(id); } - public List<String> getCorrelationRuleClasses() { - List<String> rules = null; + public Set<String> getCorrelationRuleClasses() { + Set<String> rules = null; try { rules = SyncopeConsoleSession.get().getSyncopeTO().getSyncCorrelationRules(); http://git-wip-us.apache.org/repos/asf/syncope/blob/b4a51a8a/client/console/src/main/java/org/apache/syncope/client/console/rest/ResourceRestClient.java ---------------------------------------------------------------------- diff --git a/client/console/src/main/java/org/apache/syncope/client/console/rest/ResourceRestClient.java b/client/console/src/main/java/org/apache/syncope/client/console/rest/ResourceRestClient.java index 3f7672d..e3bc2be 100644 --- a/client/console/src/main/java/org/apache/syncope/client/console/rest/ResourceRestClient.java +++ b/client/console/src/main/java/org/apache/syncope/client/console/rest/ResourceRestClient.java @@ -18,6 +18,7 @@ */ package org.apache.syncope.client.console.rest; +import java.util.ArrayList; import java.util.List; import javax.ws.rs.core.Response; import org.apache.syncope.client.console.SyncopeConsoleSession; @@ -39,7 +40,7 @@ public class ResourceRestClient extends BaseRestClient { private static final long serialVersionUID = -6898907679835668987L; public List<String> getPropagationActionsClasses() { - return SyncopeConsoleSession.get().getSyncopeTO().getPropagationActions(); + return new ArrayList<>(SyncopeConsoleSession.get().getSyncopeTO().getPropagationActions()); } public List<ResourceTO> getAll() { http://git-wip-us.apache.org/repos/asf/syncope/blob/b4a51a8a/client/console/src/main/java/org/apache/syncope/client/console/rest/SchemaRestClient.java ---------------------------------------------------------------------- diff --git a/client/console/src/main/java/org/apache/syncope/client/console/rest/SchemaRestClient.java b/client/console/src/main/java/org/apache/syncope/client/console/rest/SchemaRestClient.java index ee95e5c..4d5f9fb 100644 --- a/client/console/src/main/java/org/apache/syncope/client/console/rest/SchemaRestClient.java +++ b/client/console/src/main/java/org/apache/syncope/client/console/rest/SchemaRestClient.java @@ -51,10 +51,8 @@ public class SchemaRestClient extends BaseRestClient { if (!allowed.contains(schema.getKey())) { itor.remove(); } - } else { - if (allowed.contains(schema.getKey())) { - itor.remove(); - } + } else if (allowed.contains(schema.getKey())) { + itor.remove(); } } } @@ -197,7 +195,7 @@ public class SchemaRestClient extends BaseRestClient { List<String> response = null; try { - response = SyncopeConsoleSession.get().getSyncopeTO().getValidators(); + response = new ArrayList<>(SyncopeConsoleSession.get().getSyncopeTO().getValidators()); } catch (SyncopeClientException e) { LOG.error("While getting all validators", e); } http://git-wip-us.apache.org/repos/asf/syncope/blob/b4a51a8a/client/console/src/main/java/org/apache/syncope/client/console/rest/TaskRestClient.java ---------------------------------------------------------------------- diff --git a/client/console/src/main/java/org/apache/syncope/client/console/rest/TaskRestClient.java b/client/console/src/main/java/org/apache/syncope/client/console/rest/TaskRestClient.java index 974b78c..30087ce 100644 --- a/client/console/src/main/java/org/apache/syncope/client/console/rest/TaskRestClient.java +++ b/client/console/src/main/java/org/apache/syncope/client/console/rest/TaskRestClient.java @@ -19,6 +19,7 @@ package org.apache.syncope.client.console.rest; import java.util.List; +import java.util.Set; import org.apache.syncope.client.console.SyncopeConsoleSession; import org.apache.syncope.client.lib.SyncopeClient; import org.apache.syncope.common.lib.to.AbstractTaskTO; @@ -42,15 +43,15 @@ public class TaskRestClient extends BaseRestClient implements ExecutionRestClien private static final long serialVersionUID = 6284485820911028843L; - public List<String> getJobClasses() { + public Set<String> getJobClasses() { return SyncopeConsoleSession.get().getSyncopeTO().getTaskJobs(); } - public List<String> getSyncActionsClasses() { + public Set<String> getSyncActionsClasses() { return SyncopeConsoleSession.get().getSyncopeTO().getSyncActions(); } - public List<String> getPushActionsClasses() { + public Set<String> getPushActionsClasses() { return SyncopeConsoleSession.get().getSyncopeTO().getPushActions(); } http://git-wip-us.apache.org/repos/asf/syncope/blob/b4a51a8a/common/lib/src/main/java/org/apache/syncope/common/lib/to/SyncTaskTO.java ---------------------------------------------------------------------- diff --git a/common/lib/src/main/java/org/apache/syncope/common/lib/to/SyncTaskTO.java b/common/lib/src/main/java/org/apache/syncope/common/lib/to/SyncTaskTO.java index a6a7a8a..312f654 100644 --- a/common/lib/src/main/java/org/apache/syncope/common/lib/to/SyncTaskTO.java +++ b/common/lib/src/main/java/org/apache/syncope/common/lib/to/SyncTaskTO.java @@ -28,6 +28,7 @@ import javax.xml.bind.annotation.XmlRootElement; import javax.xml.bind.annotation.XmlType; import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter; import org.apache.syncope.common.lib.jaxb.XmlGenericMapAdapter; +import org.apache.syncope.common.lib.types.SyncMode; @XmlRootElement(name = "syncTask") @XmlType @@ -36,13 +37,31 @@ public class SyncTaskTO extends AbstractProvisioningTaskTO { private static final long serialVersionUID = -2143537546915809017L; + private SyncMode syncMode; + + private String reconciliationFilterBuilderClassName; + private String destinationRealm; @XmlJavaTypeAdapter(XmlGenericMapAdapter.class) @JsonIgnore private final Map<String, AnyTO> templates = new HashMap<>(); - private boolean fullReconciliation; + public SyncMode getSyncMode() { + return syncMode; + } + + public void setSyncMode(final SyncMode syncMode) { + this.syncMode = syncMode; + } + + public String getReconciliationFilterBuilderClassName() { + return reconciliationFilterBuilderClassName; + } + + public void setReconciliationFilterBuilderClassName(final String reconciliationFilterBuilderClassName) { + this.reconciliationFilterBuilderClassName = reconciliationFilterBuilderClassName; + } public String getDestinationRealm() { return destinationRealm; @@ -56,12 +75,4 @@ public class SyncTaskTO extends AbstractProvisioningTaskTO { public Map<String, AnyTO> getTemplates() { return templates; } - - public boolean isFullReconciliation() { - return fullReconciliation; - } - - public void setFullReconciliation(final boolean fullReconciliation) { - this.fullReconciliation = fullReconciliation; - } } http://git-wip-us.apache.org/repos/asf/syncope/blob/b4a51a8a/common/lib/src/main/java/org/apache/syncope/common/lib/to/SyncopeTO.java ---------------------------------------------------------------------- diff --git a/common/lib/src/main/java/org/apache/syncope/common/lib/to/SyncopeTO.java b/common/lib/src/main/java/org/apache/syncope/common/lib/to/SyncopeTO.java index c99532c..85b75cd 100644 --- a/common/lib/src/main/java/org/apache/syncope/common/lib/to/SyncopeTO.java +++ b/common/lib/src/main/java/org/apache/syncope/common/lib/to/SyncopeTO.java @@ -19,8 +19,8 @@ package org.apache.syncope.common.lib.to; import com.fasterxml.jackson.annotation.JsonProperty; -import java.util.ArrayList; -import java.util.List; +import java.util.HashSet; +import java.util.Set; import javax.xml.bind.annotation.XmlElement; import javax.xml.bind.annotation.XmlElementWrapper; import javax.xml.bind.annotation.XmlRootElement; @@ -41,7 +41,7 @@ public class SyncopeTO extends AbstractBaseBean { private boolean pwdResetRequiringSecurityQuestions; - private final List<String> connIdLocations = new ArrayList<>(); + private final Set<String> connIdLocations = new HashSet<>(); private String anyObjectWorkflowAdapter; @@ -59,33 +59,35 @@ public class SyncopeTO extends AbstractBaseBean { private String passwordGenerator; - private final List<String> entitlements = new ArrayList<>(); + private final Set<String> entitlements = new HashSet<>(); - private final List<String> reportlets = new ArrayList<>(); + private final Set<String> reportlets = new HashSet<>(); - private final List<String> accountRules = new ArrayList<>(); + private final Set<String> accountRules = new HashSet<>(); - private final List<String> passwordRules = new ArrayList<>(); + private final Set<String> passwordRules = new HashSet<>(); - private final List<String> mappingItemTransformers = new ArrayList<>(); + private final Set<String> mappingItemTransformers = new HashSet<>(); - private final List<String> taskJobs = new ArrayList<>(); + private final Set<String> taskJobs = new HashSet<>(); - private final List<String> logicActions = new ArrayList<>(); + private final Set<String> reconciliationFilterBuilders = new HashSet<>(); - private final List<String> propagationActions = new ArrayList<>(); + private final Set<String> logicActions = new HashSet<>(); - private final List<String> syncActions = new ArrayList<>(); + private final Set<String> propagationActions = new HashSet<>(); - private final List<String> pushActions = new ArrayList<>(); + private final Set<String> syncActions = new HashSet<>(); - private final List<String> syncCorrelationRules = new ArrayList<>(); + private final Set<String> pushActions = new HashSet<>(); - private final List<String> pushCorrelationRules = new ArrayList<>(); + private final Set<String> syncCorrelationRules = new HashSet<>(); - private final List<String> validators = new ArrayList<>(); + private final Set<String> pushCorrelationRules = new HashSet<>(); - private final List<String> mailTemplates = new ArrayList<>(); + private final Set<String> validators = new HashSet<>(); + + private final Set<String> mailTemplates = new HashSet<>(); public String getVersion() { return version; @@ -106,7 +108,7 @@ public class SyncopeTO extends AbstractBaseBean { @XmlElementWrapper(name = "connIdLocations") @XmlElement(name = "connIdLocation") @JsonProperty("connIdLocations") - public List<String> getConnIdLocations() { + public Set<String> getConnIdLocations() { return connIdLocations; } @@ -149,98 +151,105 @@ public class SyncopeTO extends AbstractBaseBean { @XmlElementWrapper(name = "entitlements") @XmlElement(name = "entitlement") @JsonProperty("entitlements") - public List<String> getEntitlements() { + public Set<String> getEntitlements() { return entitlements; } @XmlElementWrapper(name = "reportlets") @XmlElement(name = "reportlet") @JsonProperty("reportlets") - public List<String> getReportlets() { + public Set<String> getReportlets() { return reportlets; } @XmlElementWrapper(name = "accountRules") @XmlElement(name = "accountRule") @JsonProperty("accountRules") - public List<String> getAccountRules() { + public Set<String> getAccountRules() { return accountRules; } @XmlElementWrapper(name = "passwordRules") @XmlElement(name = "passwordRule") @JsonProperty("passwordRules") - public List<String> getPasswordRules() { + public Set<String> getPasswordRules() { return passwordRules; } @XmlElementWrapper(name = "mappingItemTransformers") @XmlElement(name = "mappingItemTransformer") @JsonProperty("mappingItemTransformers") - public List<String> getMappingItemTransformers() { + public Set<String> getMappingItemTransformers() { return mappingItemTransformers; } @XmlElementWrapper(name = "taskJobs") @XmlElement(name = "taskJob") @JsonProperty("taskJobs") - public List<String> getTaskJobs() { + public Set<String> getTaskJobs() { return taskJobs; } + @XmlElementWrapper(name = "reconciliationFilterBuilders") + @XmlElement(name = "reconciliationFilterBuilder") + @JsonProperty("reconciliationFilterBuilders") + public Set<String> getReconciliationFilterBuilders() { + return reconciliationFilterBuilders; + } + @XmlElementWrapper(name = "logicActions") @XmlElement(name = "logicAction") @JsonProperty("logicActions") - public List<String> getLogicActions() { + public Set<String> getLogicActions() { return logicActions; } @XmlElementWrapper(name = "propagationActions") @XmlElement(name = "propagationAction") @JsonProperty("propagationActions") - public List<String> getPropagationActions() { + public Set<String> getPropagationActions() { return propagationActions; } @XmlElementWrapper(name = "syncActions") @XmlElement(name = "syncAction") @JsonProperty("syncActions") - public List<String> getSyncActions() { + public Set<String> getSyncActions() { return syncActions; } @XmlElementWrapper(name = "pushActions") @XmlElement(name = "pushAction") @JsonProperty("pushActions") - public List<String> getPushActions() { + public Set<String> getPushActions() { return pushActions; } @XmlElementWrapper(name = "syncCorrelationRules") @XmlElement(name = "syncCorrelationRule") @JsonProperty("syncCorrelationRules") - public List<String> getSyncCorrelationRules() { + public Set<String> getSyncCorrelationRules() { return syncCorrelationRules; } @XmlElementWrapper(name = "pushCorrelationRules") @XmlElement(name = "pushCorrelationRule") @JsonProperty("pushCorrelationRules") - public List<String> getPushCorrelationRules() { + public Set<String> getPushCorrelationRules() { return pushCorrelationRules; } @XmlElementWrapper(name = "validators") @XmlElement(name = "validator") @JsonProperty("validators") - public List<String> getValidators() { + public Set<String> getValidators() { return validators; } @XmlElementWrapper(name = "mailTemplates") @XmlElement(name = "mailTemplate") @JsonProperty("mailTemplates") - public List<String> getMailTemplates() { + public Set<String> getMailTemplates() { return mailTemplates; } http://git-wip-us.apache.org/repos/asf/syncope/blob/b4a51a8a/common/lib/src/main/java/org/apache/syncope/common/lib/types/SyncMode.java ---------------------------------------------------------------------- diff --git a/common/lib/src/main/java/org/apache/syncope/common/lib/types/SyncMode.java b/common/lib/src/main/java/org/apache/syncope/common/lib/types/SyncMode.java new file mode 100644 index 0000000..afa9f19 --- /dev/null +++ b/common/lib/src/main/java/org/apache/syncope/common/lib/types/SyncMode.java @@ -0,0 +1,29 @@ +/* + * 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.common.lib.types; + +import javax.xml.bind.annotation.XmlEnum; + +@XmlEnum +public enum SyncMode { + FULL_RECONCILIATION, + FILTERED_RECONCILIATION, + INCREMENTAL; + +} http://git-wip-us.apache.org/repos/asf/syncope/blob/b4a51a8a/core/logic/src/main/java/org/apache/syncope/core/logic/SyncopeLogic.java ---------------------------------------------------------------------- diff --git a/core/logic/src/main/java/org/apache/syncope/core/logic/SyncopeLogic.java b/core/logic/src/main/java/org/apache/syncope/core/logic/SyncopeLogic.java index dcd24ad..f2a9c3b 100644 --- a/core/logic/src/main/java/org/apache/syncope/core/logic/SyncopeLogic.java +++ b/core/logic/src/main/java/org/apache/syncope/core/logic/SyncopeLogic.java @@ -136,6 +136,8 @@ public class SyncopeLogic extends AbstractLogic<SyncopeTO> { syncopeTO.getPasswordRules().addAll(implLookup.getClassNames(Type.PASSWORD_RULE)); syncopeTO.getMappingItemTransformers().addAll(implLookup.getClassNames(Type.MAPPING_ITEM_TRANSFORMER)); syncopeTO.getTaskJobs().addAll(implLookup.getClassNames(Type.TASKJOBDELEGATE)); + syncopeTO.getReconciliationFilterBuilders(). + addAll(implLookup.getClassNames(Type.RECONCILIATION_FILTER_BUILDER)); syncopeTO.getLogicActions().addAll(implLookup.getClassNames(Type.LOGIC_ACTIONS)); syncopeTO.getPropagationActions().addAll(implLookup.getClassNames(Type.PROPAGATION_ACTIONS)); syncopeTO.getSyncActions().addAll(implLookup.getClassNames(Type.SYNC_ACTIONS)); http://git-wip-us.apache.org/repos/asf/syncope/blob/b4a51a8a/core/logic/src/main/java/org/apache/syncope/core/logic/init/ClassPathScanImplementationLookup.java ---------------------------------------------------------------------- diff --git a/core/logic/src/main/java/org/apache/syncope/core/logic/init/ClassPathScanImplementationLookup.java b/core/logic/src/main/java/org/apache/syncope/core/logic/init/ClassPathScanImplementationLookup.java index 5147a39..3fc4fc4 100644 --- a/core/logic/src/main/java/org/apache/syncope/core/logic/init/ClassPathScanImplementationLookup.java +++ b/core/logic/src/main/java/org/apache/syncope/core/logic/init/ClassPathScanImplementationLookup.java @@ -53,6 +53,7 @@ import org.springframework.context.annotation.ClassPathScanningCandidateComponen import org.springframework.core.type.filter.AssignableTypeFilter; import org.springframework.stereotype.Component; import org.springframework.util.ClassUtils; +import org.apache.syncope.core.provisioning.api.sync.ReconciliationFilterBuilder; /** * Cache class names for all implementations of Syncope interfaces found in classpath, for later usage. @@ -93,6 +94,7 @@ public class ClassPathScanImplementationLookup implements ImplementationLookup { scanner.addIncludeFilter(new AssignableTypeFilter(PasswordRule.class)); scanner.addIncludeFilter(new AssignableTypeFilter(MappingItemTransformer.class)); scanner.addIncludeFilter(new AssignableTypeFilter(SchedTaskJobDelegate.class)); + scanner.addIncludeFilter(new AssignableTypeFilter(ReconciliationFilterBuilder.class)); scanner.addIncludeFilter(new AssignableTypeFilter(LogicActions.class)); scanner.addIncludeFilter(new AssignableTypeFilter(PropagationActions.class)); scanner.addIncludeFilter(new AssignableTypeFilter(SyncActions.class)); @@ -144,6 +146,10 @@ public class ClassPathScanImplementationLookup implements ImplementationLookup { classNames.get(Type.TASKJOBDELEGATE).add(bd.getBeanClassName()); } + if (ReconciliationFilterBuilder.class.isAssignableFrom(clazz) && !isAbsractClazz) { + classNames.get(Type.RECONCILIATION_FILTER_BUILDER).add(bd.getBeanClassName()); + } + if (LogicActions.class.isAssignableFrom(clazz) && !isAbsractClazz) { classNames.get(Type.LOGIC_ACTIONS).add(bd.getBeanClassName()); } http://git-wip-us.apache.org/repos/asf/syncope/blob/b4a51a8a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/ImplementationLookup.java ---------------------------------------------------------------------- diff --git a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/ImplementationLookup.java b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/ImplementationLookup.java index fa8847f..6b84c99 100644 --- a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/ImplementationLookup.java +++ b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/ImplementationLookup.java @@ -35,6 +35,7 @@ public interface ImplementationLookup extends SyncopeLoader { PASSWORD_RULE, MAPPING_ITEM_TRANSFORMER, TASKJOBDELEGATE, + RECONCILIATION_FILTER_BUILDER, LOGIC_ACTIONS, PROPAGATION_ACTIONS, SYNC_ACTIONS, http://git-wip-us.apache.org/repos/asf/syncope/blob/b4a51a8a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/task/SyncTask.java ---------------------------------------------------------------------- diff --git a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/task/SyncTask.java b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/task/SyncTask.java index bc0c2b2..ca07988 100644 --- a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/task/SyncTask.java +++ b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/task/SyncTask.java @@ -19,18 +19,23 @@ package org.apache.syncope.core.persistence.api.entity.task; import java.util.List; +import org.apache.syncope.common.lib.types.SyncMode; import org.apache.syncope.core.persistence.api.entity.AnyType; import org.apache.syncope.core.persistence.api.entity.Realm; public interface SyncTask extends ProvisioningTask { - Realm getDestinatioRealm(); + SyncMode getSyncMode(); - void setDestinationRealm(Realm destinationRealm); + void setSyncMode(SyncMode syncMode); + + String getReconciliationFilterBuilderClassName(); - boolean isFullReconciliation(); + void setReconciliationFilterBuilderClassName(String reconciliationFilterBuilderClassName); - void setFullReconciliation(boolean condition); + Realm getDestinatioRealm(); + + void setDestinationRealm(Realm destinationRealm); boolean add(AnyTemplateSyncTask template); http://git-wip-us.apache.org/repos/asf/syncope/blob/b4a51a8a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/task/JPASyncTask.java ---------------------------------------------------------------------- diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/task/JPASyncTask.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/task/JPASyncTask.java index 8cc8b05..935d76c 100644 --- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/task/JPASyncTask.java +++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/task/JPASyncTask.java @@ -22,21 +22,22 @@ import java.util.ArrayList; import java.util.HashSet; import java.util.List; import java.util.Set; -import javax.persistence.Basic; import javax.persistence.CascadeType; import javax.persistence.CollectionTable; import javax.persistence.Column; import javax.persistence.DiscriminatorValue; import javax.persistence.ElementCollection; import javax.persistence.Entity; +import javax.persistence.EnumType; +import javax.persistence.Enumerated; import javax.persistence.FetchType; import javax.persistence.JoinColumn; import javax.persistence.ManyToOne; import javax.persistence.OneToMany; -import javax.validation.constraints.Max; -import javax.validation.constraints.Min; +import javax.validation.constraints.NotNull; import org.apache.commons.collections4.CollectionUtils; import org.apache.commons.collections4.Predicate; +import org.apache.syncope.common.lib.types.SyncMode; import org.apache.syncope.common.lib.types.TaskType; import org.apache.syncope.core.persistence.api.entity.AnyType; import org.apache.syncope.core.persistence.api.entity.task.SyncTask; @@ -51,6 +52,12 @@ public class JPASyncTask extends AbstractProvisioningTask implements SyncTask { private static final long serialVersionUID = -4141057723006682563L; + @Enumerated(EnumType.STRING) + @NotNull + private SyncMode syncMode; + + private String reconciliationFilterBuilderClassName; + @ManyToOne(fetch = FetchType.EAGER, optional = false) private JPARealm destinationRealm; @@ -64,11 +71,6 @@ public class JPASyncTask extends AbstractProvisioningTask implements SyncTask { @OneToMany(cascade = CascadeType.ALL, orphanRemoval = true, fetch = FetchType.EAGER, mappedBy = "syncTask") private List<JPAAnyTemplateSyncTask> templates = new ArrayList<>(); - @Basic - @Min(0) - @Max(1) - private Integer fullReconciliation; - /** * Default constructor. */ @@ -77,6 +79,26 @@ public class JPASyncTask extends AbstractProvisioningTask implements SyncTask { } @Override + public SyncMode getSyncMode() { + return syncMode; + } + + @Override + public void setSyncMode(final SyncMode syncMode) { + this.syncMode = syncMode; + } + + @Override + public String getReconciliationFilterBuilderClassName() { + return reconciliationFilterBuilderClassName; + } + + @Override + public void setReconciliationFilterBuilderClassName(final String reconciliationFilterBuilderClassName) { + this.reconciliationFilterBuilderClassName = reconciliationFilterBuilderClassName; + } + + @Override public Realm getDestinatioRealm() { return destinationRealm; } @@ -93,16 +115,6 @@ public class JPASyncTask extends AbstractProvisioningTask implements SyncTask { } @Override - public boolean isFullReconciliation() { - return isBooleanAsInteger(fullReconciliation); - } - - @Override - public void setFullReconciliation(final boolean fullReconciliation) { - this.fullReconciliation = getBooleanAsInteger(fullReconciliation); - } - - @Override public boolean add(final AnyTemplateSyncTask template) { checkType(template, JPAAnyTemplateSyncTask.class); return this.templates.add((JPAAnyTemplateSyncTask) template); http://git-wip-us.apache.org/repos/asf/syncope/blob/b4a51a8a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/validation/entity/ProvisioningTaskValidator.java ---------------------------------------------------------------------- diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/validation/entity/ProvisioningTaskValidator.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/validation/entity/ProvisioningTaskValidator.java index e397bce..72b421e 100644 --- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/validation/entity/ProvisioningTaskValidator.java +++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/validation/entity/ProvisioningTaskValidator.java @@ -20,11 +20,14 @@ package org.apache.syncope.core.persistence.jpa.validation.entity; import javax.validation.ConstraintValidatorContext; import org.apache.syncope.common.lib.types.EntityViolationType; +import org.apache.syncope.common.lib.types.SyncMode; import org.apache.syncope.core.persistence.api.entity.task.ProvisioningTask; +import org.apache.syncope.core.persistence.api.entity.task.SyncTask; import org.apache.syncope.core.persistence.jpa.entity.task.JPAPushTask; import org.apache.syncope.core.persistence.jpa.entity.task.JPASyncTask; import org.apache.syncope.core.provisioning.api.sync.PushActions; import org.apache.syncope.core.provisioning.api.sync.SyncActions; +import org.apache.syncope.core.provisioning.api.sync.ReconciliationFilterBuilder; public class ProvisioningTaskValidator extends AbstractValidator<ProvisioningTaskCheck, ProvisioningTask> { @@ -78,6 +81,30 @@ public class ProvisioningTaskValidator extends AbstractValidator<ProvisioningTas } } } + + if (isValid && task instanceof SyncTask + && ((SyncTask) task).getSyncMode() == SyncMode.FILTERED_RECONCILIATION) { + + Class<?> filterBuilderClass = null; + boolean isAssignable = false; + try { + filterBuilderClass = Class.forName(((SyncTask) task).getReconciliationFilterBuilderClassName()); + isAssignable = ReconciliationFilterBuilder.class.isAssignableFrom(filterBuilderClass); + } catch (Exception e) { + LOG.error("Invalid {} specified", + ReconciliationFilterBuilder.class.getName(), SyncActions.class.getName(), e); + isValid = false; + } + + if (filterBuilderClass == null || !isAssignable) { + isValid = false; + + context.disableDefaultConstraintViolation(); + context.buildConstraintViolationWithTemplate( + getTemplate(EntityViolationType.InvalidProvisioningTask, "Invalid class name")). + addPropertyNode("reconciliationFilterBuilderClassName").addConstraintViolation(); + } + } } return isValid; http://git-wip-us.apache.org/repos/asf/syncope/blob/b4a51a8a/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/outer/TaskTest.java ---------------------------------------------------------------------- diff --git a/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/outer/TaskTest.java b/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/outer/TaskTest.java index 53f88d8..05a22ed 100644 --- a/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/outer/TaskTest.java +++ b/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/outer/TaskTest.java @@ -33,6 +33,7 @@ import org.apache.syncope.common.lib.types.AnyTypeKind; import org.apache.syncope.common.lib.types.MatchingRule; import org.apache.syncope.common.lib.types.PropagationTaskExecStatus; import org.apache.syncope.common.lib.types.ResourceOperation; +import org.apache.syncope.common.lib.types.SyncMode; import org.apache.syncope.common.lib.types.TaskType; import org.apache.syncope.common.lib.types.UnmatchingRule; import org.apache.syncope.core.persistence.api.attrvalue.validation.InvalidEntityException; @@ -217,6 +218,7 @@ public class TaskTest extends AbstractTest { SyncTask task = entityFactory.newEntity(SyncTask.class); task.setName("saveSyncTask"); task.setDescription("SyncTask description"); + task.setSyncMode(SyncMode.FULL_RECONCILIATION); task.add(template); task.setCronExpression("BLA BLA"); task.setMatchingRule(MatchingRule.UPDATE); @@ -274,6 +276,7 @@ public class TaskTest extends AbstractTest { task.setResource(resource); task.setName("issueSYNCOPE144"); task.setDescription("issueSYNCOPE144 Description"); + task.setSyncMode(SyncMode.FULL_RECONCILIATION); task.getActionsClassNames().add(SyncActions.class.getName()); task.setMatchingRule(MatchingRule.UPDATE); task.setUnmatchingRule(UnmatchingRule.PROVISION); http://git-wip-us.apache.org/repos/asf/syncope/blob/b4a51a8a/core/persistence-jpa/src/test/resources/domains/MasterContent.xml ---------------------------------------------------------------------- diff --git a/core/persistence-jpa/src/test/resources/domains/MasterContent.xml b/core/persistence-jpa/src/test/resources/domains/MasterContent.xml index 7e71cfd..73fee53 100644 --- a/core/persistence-jpa/src/test/resources/domains/MasterContent.xml +++ b/core/persistence-jpa/src/test/resources/domains/MasterContent.xml @@ -967,8 +967,8 @@ under the License. objectClassName="__ACCOUNT__" resource_name="ws-target-resource-2" anyTypeKind="USER" anyKey="1" 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"]}]'/> <Task DTYPE="SyncTask" type="SYNCHRONIZATION" id="4" name="CSV (update matching; assign unmatching)" resource_name="resource-csv" - destinationRealm_id="1" performCreate="1" performUpdate="1" performDelete="1" syncStatus="1" fullReconciliation="0" - unmatchingRule="ASSIGN" matchingRule="UPDATE"/> + destinationRealm_id="1" performCreate="1" performUpdate="1" performDelete="1" syncStatus="1" + syncMode="INCREMENTAL" unmatchingRule="ASSIGN" matchingRule="UPDATE"/> <AnyTemplateSyncTask id="41" syncTask_id="4" anyType_name="USER" template='{"@class":"org.apache.syncope.common.lib.to.UserTO","creator":null,"creationDate":null,"lastModifier":null,"lastChangeDate":null,"key":0,"type":"USER","realm":null,"status":null,"password":null,"token":null,"tokenExpireTime":null,"username":null,"lastLoginDate":null,"changePwdDate":null,"failedLogins":null,"securityQuestion":null,"securityAnswer":null,"auxClasses":["csv"],"derAttrs":[{"schema":"cn","readonly":false,"values":[""]}],"virAttrs":[],"resources":["resource-testdb"],"relationships":[],"memberships":[{"leftType":null,"leftKey":0,"rightType":"GROUP","rightKey":8,"groupName":null}],"dynGroups":[],"roles":[],"dynRoles":[],"plainAttrs":[{"schema":"type","readonly":false,"values":["email == '[email protected]'? 'TYPE_8': 'TYPE_OTHER'"]}]}'/> <AnyTemplateSyncTask id="42" syncTask_id="4" anyType_name="GROUP" @@ -980,7 +980,7 @@ under the License. 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="6" task_id="6" status="SUCCESS"/> <Task DTYPE="SyncTask" type="SYNCHRONIZATION" id="7" name="TestDB Task" resource_name="resource-testdb" - destinationRealm_id="1" performCreate="1" performUpdate="1" performDelete="0" syncStatus="1" fullReconciliation="1" + destinationRealm_id="1" performCreate="1" performUpdate="1" performDelete="0" syncStatus="1" syncMode="FULL_RECONCILIATION" unmatchingRule="PROVISION" matchingRule="UPDATE"/> <AnyTemplateSyncTask id="71" syncTask_id="7" anyType_name="USER" template='{"@class":"org.apache.syncope.common.lib.to.UserTO","creator":null,"creationDate":null,"lastModifier":null,"lastChangeDate":null,"key":0,"type":"USER","realm":null,"status":null,"password":null,"token":null,"tokenExpireTime":null,"username":null,"lastLoginDate":null,"changePwdDate":null,"failedLogins":null,"securityQuestion":null,"securityAnswer":null,"auxClasses":[],"derAttrs":[],"virAttrs":[],"resources":[],"relationships":[],"memberships":[],"dynGroups":[],"roles":[],"dynRoles":[],"plainAttrs":[{"schema":"type","readonly":false,"values":["'type a'"]},{"schema":"userId","readonly":false,"values":["'[email protected]'"]},{"schema":"fullname","readonly":false,"values":["'reconciled fullname'"]},{"schema":"surname","readonly":false,"values":["'surname'"]}]}'/> @@ -989,13 +989,13 @@ under the License. <Task DTYPE="NotificationTask" type="NOTIFICATION" id="8" sender="[email protected]" subject="Notification for SYNCOPE-81" textBody="NOTIFICATION-81" htmlBody="NOTIFICATION-81" traceLevel="ALL"/> <Task DTYPE="SyncTask" type="SYNCHRONIZATION" id="9" name="TestDB2 Task" resource_name="resource-testdb2" - destinationRealm_id="1" performCreate="1" performUpdate="1" performDelete="0" syncStatus="1" fullReconciliation="1" + destinationRealm_id="1" performCreate="1" performUpdate="1" performDelete="0" syncStatus="1" syncMode="FULL_RECONCILIATION" unmatchingRule="PROVISION" matchingRule="UPDATE"/> <Task DTYPE="SyncTask" type="SYNCHRONIZATION" id="10" name="TestDB Sync Task" resource_name="resource-db-sync" - destinationRealm_id="1" fullReconciliation="1" performCreate="1" performDelete="1" performUpdate="1" syncStatus="0" + destinationRealm_id="1" syncMode="FULL_RECONCILIATION" performCreate="1" performDelete="1" performUpdate="1" syncStatus="0" unmatchingRule="PROVISION" matchingRule="UPDATE"/> <Task DTYPE="SyncTask" type="SYNCHRONIZATION" id="11" name="LDAP Sync Task" resource_name="resource-ldap" - destinationRealm_id="1" fullReconciliation="1" performCreate="1" performDelete="1" performUpdate="1" syncStatus="0" + destinationRealm_id="1" syncMode="FULL_RECONCILIATION" performCreate="1" performDelete="1" performUpdate="1" syncStatus="0" unmatchingRule="PROVISION" matchingRule="UPDATE"/> <AnyTemplateSyncTask id="1" syncTask_id="11" anyType_name="USER" template='{"@class":"org.apache.syncope.common.lib.to.UserTO","creator":null,"creationDate":null,"lastModifier":null,"lastChangeDate":null,"key":0,"type":"USER","realm":null,"status":null,"password":null,"token":null,"tokenExpireTime":null,"username":null,"lastLoginDate":null,"changePwdDate":null,"failedLogins":null,"securityQuestion":null,"securityAnswer":null,"auxClasses":[],"derAttrs":[],"virAttrs":[{"schema":"virtualReadOnly","readonly":true,"values":[""]}],"resources":["resource-ldap"],"roles":[],"dynRoles":[],"relationships":[],"memberships":[],"dynGroups":[],"plainAttrs":[]}'/> @@ -1003,7 +1003,7 @@ under the License. template='{"@class":"org.apache.syncope.common.lib.to.GroupTO","creator":null,"creationDate":null,"lastModifier":null,"lastChangeDate":null,"key":0,"type":"GROUP","realm":null,"status":null,"name":null,"userOwner":null,"groupOwner":null,"adynMembershipCond":null,"udynMembershipCond":null,"auxClasses":[],"derAttrs":[],"virAttrs":[],"resources":[],"plainAttrs":[{"schema":"show","readonly":false,"values":["true"]}]}'/> <SyncTask_actionsClassNames SyncTask_id="11" actionClassName="org.apache.syncope.core.provisioning.java.sync.LDAPMembershipSyncActions"/> <Task DTYPE="SyncTask" type="SYNCHRONIZATION" id="12" name="VirAttrCache test" resource_name="resource-csv" - destinationRealm_id="1" performCreate="0" performUpdate="1" performDelete="0" syncStatus="0" fullReconciliation="1" + destinationRealm_id="1" performCreate="0" performUpdate="1" performDelete="0" syncStatus="0" syncMode="FULL_RECONCILIATION" unmatchingRule="PROVISION" matchingRule="UPDATE"/> <Task DTYPE="PushTask" type="PUSH" id="13" name="Export on resource-testdb2" resource_name="resource-testdb2" performCreate="1" performUpdate="1" performDelete="1" syncStatus="1" @@ -1062,23 +1062,23 @@ under the License. <AnyFilter id="231" anyType_name="USER" pushTask_id="23" filter="username==_NO_ONE_"/> <AnyFilter id="232" anyType_name="GROUP" pushTask_id="23" filter="name==citizen"/> <Task DTYPE="SyncTask" type="SYNCHRONIZATION" id="24" name="CSV Task (update matching; provision unmatching)" resource_name="resource-csv" - destinationRealm_id="1" performCreate="1" performUpdate="1" performDelete="1" syncStatus="1" fullReconciliation="0" + destinationRealm_id="1" performCreate="1" performUpdate="1" performDelete="1" syncStatus="1" syncMode="INCREMENTAL" unmatchingRule="PROVISION" matchingRule="UPDATE"/> <AnyTemplateSyncTask id="3" syncTask_id="24" anyType_name="USER" template='{"@class":"org.apache.syncope.common.lib.to.UserTO","creator":null,"creationDate":null,"lastModifier":null,"lastChangeDate":null,"key":0,"type":"USER","realm":null,"status":null,"password":null,"token":null,"tokenExpireTime":null,"username":null,"lastLoginDate":null,"changePwdDate":null,"failedLogins":null,"securityQuestion":null,"securityAnswer":null,"auxClasses":[],"derAttrs":[],"virAttrs":[],"resources":["resource-testdb"],"roles":[],"dynRoles":[],"relationships":[],"memberships":[],"dynGroups":[],"plainAttrs":[{"schema":"firstname","readonly":false,"values":[""]},{"schema":"userId","readonly":false,"values":["'test'"]},{"schema":"fullname","readonly":false,"values":["'test'"]},{"schema":"surname","readonly":false,"values":["'test'"]}]}'/> <AnyTemplateSyncTask id="4" syncTask_id="24" anyType_name="GROUP" template='{"@class":"org.apache.syncope.common.lib.to.GroupTO","creator":null,"creationDate":null,"lastModifier":null,"lastChangeDate":null,"key":0,"type":"GROUP","realm":null,"status":null,"name":null,"userOwner":null,"groupOwner":null,"adynMembershipCond":null,"udynMembershipCond":null,"auxClasses":[],"derAttrs":[],"virAttrs":[],"resources":[],"plainAttrs":[]}'/> <Task DTYPE="SyncTask" type="SYNCHRONIZATION" id="25" name="CSV (unlink matching; ignore unmatching)" resource_name="resource-csv" - destinationRealm_id="1" performCreate="1" performUpdate="1" performDelete="1" syncStatus="1" fullReconciliation="0" + destinationRealm_id="1" performCreate="1" performUpdate="1" performDelete="1" syncStatus="1" syncMode="INCREMENTAL" unmatchingRule="IGNORE" matchingRule="UNLINK"/> <Task DTYPE="SyncTask" type="SYNCHRONIZATION" id="26" name="CSV (ignore matching; assign unmatching)" resource_name="resource-csv" - destinationRealm_id="1" performCreate="1" performUpdate="1" performDelete="1" syncStatus="1" fullReconciliation="0" + destinationRealm_id="1" performCreate="1" performUpdate="1" performDelete="1" syncStatus="1" syncMode="INCREMENTAL" unmatchingRule="ASSIGN" matchingRule="IGNORE"/> <Task DTYPE="PropagationTask" type="PROPAGATION" id="27" operation="CREATE" objectClassName="__ACCOUNT__" resource_name="resource-testdb" anyTypeKind="USER" anyKey="1" 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"]}]'/> <Task DTYPE="SyncTask" type="SYNCHRONIZATION" id="28" name="Scripted SQL" resource_name="resource-db-scripted" - destinationRealm_id="1" performCreate="1" performUpdate="1" performDelete="1" syncStatus="0" fullReconciliation="0" + destinationRealm_id="1" performCreate="1" performUpdate="1" performDelete="1" syncStatus="0" syncMode="INCREMENTAL" unmatchingRule="PROVISION" matchingRule="UPDATE"/> <Notification id="1" active="1" recipientAttrName="email" recipientAttrType="UserPlainSchema" selfAsRecipient="1" http://git-wip-us.apache.org/repos/asf/syncope/blob/b4a51a8a/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/Connector.java ---------------------------------------------------------------------- diff --git a/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/Connector.java b/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/Connector.java index c93c2c4..7aed2ca 100644 --- a/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/Connector.java +++ b/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/Connector.java @@ -34,6 +34,7 @@ import org.identityconnectors.framework.common.objects.SyncResultsHandler; import org.identityconnectors.framework.common.objects.SyncToken; import org.identityconnectors.framework.common.objects.Uid; import org.identityconnectors.framework.common.objects.filter.Filter; +import org.apache.syncope.core.provisioning.api.sync.ReconciliationFilterBuilder; /** * Entry point for making requests on underlying connector bundles. @@ -103,7 +104,21 @@ public interface Connector { * @param handler to be used to handle deltas. * @param options ConnId's OperationOptions. */ - void getAllObjects(ObjectClass objectClass, SyncResultsHandler handler, OperationOptions options); + void fullReconciliation(ObjectClass objectClass, SyncResultsHandler handler, OperationOptions options); + + /** + * Fetches remote objects (for use during filtered reconciliation). + * + * @param objectClass ConnId's object class. + * @param filterBuilder reconciliation filter builder + * @param handler to be used to handle deltas. + * @param options ConnId's OperationOptions. + */ + void filteredReconciliation( + ObjectClass objectClass, + ReconciliationFilterBuilder filterBuilder, + SyncResultsHandler handler, + OperationOptions options); /** * Sync remote objects from a connector instance. http://git-wip-us.apache.org/repos/asf/syncope/blob/b4a51a8a/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/sync/ReconciliationFilterBuilder.java ---------------------------------------------------------------------- diff --git a/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/sync/ReconciliationFilterBuilder.java b/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/sync/ReconciliationFilterBuilder.java new file mode 100644 index 0000000..874215b --- /dev/null +++ b/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/sync/ReconciliationFilterBuilder.java @@ -0,0 +1,30 @@ +/* + * 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.api.sync; + +import org.identityconnectors.framework.common.objects.filter.Filter; + +/** + * Interface to be implemented for performing filtered reconciliation of a + * {@link org.apache.syncope.core.persistence.api.entity.task.SyncTask}. + */ +public interface ReconciliationFilterBuilder { + + Filter build(); +} http://git-wip-us.apache.org/repos/asf/syncope/blob/b4a51a8a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/ConnectorFacadeProxy.java ---------------------------------------------------------------------- diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/ConnectorFacadeProxy.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/ConnectorFacadeProxy.java index 86add58..3454985 100644 --- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/ConnectorFacadeProxy.java +++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/ConnectorFacadeProxy.java @@ -66,6 +66,7 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.util.ClassUtils; +import org.apache.syncope.core.provisioning.api.sync.ReconciliationFilterBuilder; public class ConnectorFacadeProxy implements Connector { @@ -332,10 +333,22 @@ public class ConnectorFacadeProxy implements Connector { } @Override - public void getAllObjects( - final ObjectClass objectClass, final SyncResultsHandler handler, final OperationOptions options) { + public void fullReconciliation( + final ObjectClass objectClass, + final SyncResultsHandler handler, + final OperationOptions options) { + + filteredReconciliation(objectClass, null, handler, options); + } + + @Override + public void filteredReconciliation( + final ObjectClass objectClass, + final ReconciliationFilterBuilder filterBuilder, + final SyncResultsHandler handler, + final OperationOptions options) { - search(objectClass, null, new ResultsHandler() { + search(objectClass, filterBuilder == null ? null : filterBuilder.build(), new ResultsHandler() { @Override public boolean handle(final ConnectorObject obj) { http://git-wip-us.apache.org/repos/asf/syncope/blob/b4a51a8a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/TaskDataBinderImpl.java ---------------------------------------------------------------------- diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/TaskDataBinderImpl.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/TaskDataBinderImpl.java index 3207bd2..5e69ad6 100644 --- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/TaskDataBinderImpl.java +++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/TaskDataBinderImpl.java @@ -140,6 +140,9 @@ public class TaskDataBinderImpl implements TaskDataBinder { final SyncTask syncTask = (SyncTask) task; final SyncTaskTO syncTaskTO = (SyncTaskTO) taskTO; + syncTask.setSyncMode(syncTaskTO.getSyncMode()); + syncTask.setReconciliationFilterBuilderClassName(syncTaskTO.getReconciliationFilterBuilderClassName()); + syncTask.setDestinationRealm(realmDAO.find(syncTaskTO.getDestinationRealm())); syncTask.setJobDelegateClassName(SyncJobDelegate.class.getName()); @@ -175,8 +178,6 @@ public class TaskDataBinderImpl implements TaskDataBinder { return syncTaskTO.getTemplates().containsKey(anyTemplate.getAnyType().getKey()); } }); - - syncTask.setFullReconciliation(syncTaskTO.isFullReconciliation()); } // 3. fill the remaining fields @@ -289,7 +290,9 @@ public class TaskDataBinderImpl implements TaskDataBinder { taskTO.setEndDate(latestExec == null ? null : latestExec.getEndDate()); for (TaskExec execution : task.getExecs()) { - taskTO.getExecutions().add(getTaskExecTO(execution)); + if (execution != null) { + taskTO.getExecutions().add(getTaskExecTO(execution)); + } } switch (taskUtils.getType()) { http://git-wip-us.apache.org/repos/asf/syncope/blob/b4a51a8a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/sync/DefaultReconciliationFilterBuilder.java ---------------------------------------------------------------------- diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/sync/DefaultReconciliationFilterBuilder.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/sync/DefaultReconciliationFilterBuilder.java new file mode 100644 index 0000000..2c75928 --- /dev/null +++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/sync/DefaultReconciliationFilterBuilder.java @@ -0,0 +1,38 @@ +/* + * 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.sync; + +import static org.identityconnectors.framework.impl.api.local.operations.FilteredResultsHandler.PassThroughFilter; + +import org.identityconnectors.framework.common.objects.filter.Filter; +import org.apache.syncope.core.provisioning.api.sync.ReconciliationFilterBuilder; + +/** + * Default (pass-through) implementation of {@link ReconciliationFilterBuilder}. + */ +public abstract class DefaultReconciliationFilterBuilder implements ReconciliationFilterBuilder { + + private static final PassThroughFilter PASS_THROUGH = new PassThroughFilter(); + + @Override + public Filter build() { + return PASS_THROUGH; + } + +} http://git-wip-us.apache.org/repos/asf/syncope/blob/b4a51a8a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/sync/DefaultSyncActions.java ---------------------------------------------------------------------- diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/sync/DefaultSyncActions.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/sync/DefaultSyncActions.java index 1612b6d..9045e2a 100644 --- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/sync/DefaultSyncActions.java +++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/sync/DefaultSyncActions.java @@ -27,7 +27,7 @@ import org.identityconnectors.framework.common.objects.SyncDelta; import org.quartz.JobExecutionException; /** - * Default (empty) implementation of SyncActions. + * Default (empty) implementation of {@link SyncActions}. */ public abstract class DefaultSyncActions implements SyncActions { http://git-wip-us.apache.org/repos/asf/syncope/blob/b4a51a8a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/sync/SyncJobDelegate.java ---------------------------------------------------------------------- diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/sync/SyncJobDelegate.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/sync/SyncJobDelegate.java index c5fad73..cf0f020 100644 --- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/sync/SyncJobDelegate.java +++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/sync/SyncJobDelegate.java @@ -50,6 +50,7 @@ import org.identityconnectors.framework.common.objects.SyncToken; import org.quartz.JobExecutionException; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.support.AbstractBeanDefinition; +import org.apache.syncope.core.provisioning.api.sync.ReconciliationFilterBuilder; public class SyncJobDelegate extends AbstractProvisioningJobDelegate<SyncTask> { @@ -166,11 +167,6 @@ public class SyncJobDelegate extends AbstractProvisioningJobDelegate<SyncTask> { } try { - SyncToken latestSyncToken = null; - if (!syncTask.isFullReconciliation()) { - latestSyncToken = connector.getLatestSyncToken(provision.getObjectClass()); - } - Set<MappingItem> linkinMappingItems = new HashSet<>(); for (VirSchema virSchema : virSchemaDAO.findByProvision(provision)) { linkinMappingItems.add(virSchema.asLinkingMappingItem()); @@ -179,29 +175,42 @@ public class SyncJobDelegate extends AbstractProvisioningJobDelegate<SyncTask> { provision.getMapping().getItems().iterator(), linkinMappingItems.iterator()); - if (syncTask.isFullReconciliation()) { - connector.getAllObjects( - provision.getObjectClass(), - handler, - MappingUtils.buildOperationOptions(mapItems)); - } else { - connector.sync( - provision.getObjectClass(), - provision.getSyncToken(), - handler, - MappingUtils.buildOperationOptions(mapItems)); - } - - if (!dryRun && !syncTask.isFullReconciliation()) { - try { - provision.setSyncToken(latestSyncToken); - resourceDAO.save(provision.getResource()); - } catch (Exception e) { - throw new JobExecutionException("While updating SyncToken", e); - } + switch (syncTask.getSyncMode()) { + case INCREMENTAL: + SyncToken latestSyncToken = connector.getLatestSyncToken(provision.getObjectClass()); + connector.sync( + provision.getObjectClass(), + provision.getSyncToken(), + handler, + MappingUtils.buildOperationOptions(mapItems)); + if (!dryRun) { + provision.setSyncToken(latestSyncToken); + resourceDAO.save(provision.getResource()); + } + break; + + case FILTERED_RECONCILIATION: + ReconciliationFilterBuilder filterBuilder = + (ReconciliationFilterBuilder) ApplicationContextProvider.getBeanFactory(). + createBean(Class.forName(syncTask.getReconciliationFilterBuilderClassName()), + AbstractBeanDefinition.AUTOWIRE_BY_NAME, false); + connector.filteredReconciliation( + provision.getObjectClass(), + filterBuilder, + handler, + MappingUtils.buildOperationOptions(mapItems)); + break; + + case FULL_RECONCILIATION: + default: + connector.fullReconciliation( + provision.getObjectClass(), + handler, + MappingUtils.buildOperationOptions(mapItems)); + break; } } catch (Throwable t) { - throw new JobExecutionException("While syncing on connector", t); + throw new JobExecutionException("While syncing from connector", t); } } } http://git-wip-us.apache.org/repos/asf/syncope/blob/b4a51a8a/fit/core-reference/src/main/java/org/apache/syncope/fit/core/reference/TestReconciliationFilterBuilder.java ---------------------------------------------------------------------- diff --git a/fit/core-reference/src/main/java/org/apache/syncope/fit/core/reference/TestReconciliationFilterBuilder.java b/fit/core-reference/src/main/java/org/apache/syncope/fit/core/reference/TestReconciliationFilterBuilder.java new file mode 100644 index 0000000..f6b5c2d --- /dev/null +++ b/fit/core-reference/src/main/java/org/apache/syncope/fit/core/reference/TestReconciliationFilterBuilder.java @@ -0,0 +1,35 @@ +/* + * 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.fit.core.reference; + +import org.apache.syncope.core.provisioning.java.sync.DefaultReconciliationFilterBuilder; +import org.identityconnectors.framework.common.objects.AttributeBuilder; +import org.identityconnectors.framework.common.objects.filter.Filter; +import org.identityconnectors.framework.common.objects.filter.FilterBuilder; + +public class TestReconciliationFilterBuilder extends DefaultReconciliationFilterBuilder { + + private static final Filter EQUALS = FilterBuilder.equalTo(AttributeBuilder.build("SURNAME", "Rossi")); + + @Override + public Filter build() { + return EQUALS; + } + +} http://git-wip-us.apache.org/repos/asf/syncope/blob/b4a51a8a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/MultitenancyITCase.java ---------------------------------------------------------------------- diff --git a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/MultitenancyITCase.java b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/MultitenancyITCase.java index 2a9dffe..5aac6c0 100644 --- a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/MultitenancyITCase.java +++ b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/MultitenancyITCase.java @@ -49,6 +49,7 @@ import org.apache.syncope.common.lib.types.LoggerType; import org.apache.syncope.common.lib.types.MappingPurpose; import org.apache.syncope.common.lib.types.PropagationTaskExecStatus; import org.apache.syncope.common.lib.types.SchemaType; +import org.apache.syncope.common.lib.types.SyncMode; import org.apache.syncope.common.rest.api.service.ConnectorService; import org.apache.syncope.common.rest.api.service.DomainService; import org.apache.syncope.common.rest.api.service.LoggerService; @@ -186,9 +187,9 @@ public class MultitenancyITCase extends AbstractITCase { // create sync task SyncTaskTO task = new SyncTaskTO(); task.setName("LDAP Sync Task"); - task.setDestinationRealm("/"); + task.setDestinationRealm(SyncopeConstants.ROOT_REALM); task.setResource(resource.getKey()); - task.setFullReconciliation(true); + task.setSyncMode(SyncMode.FULL_RECONCILIATION); task.setPerformCreate(true); response = adminClient.getService(TaskService.class).create(task); http://git-wip-us.apache.org/repos/asf/syncope/blob/b4a51a8a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/PushTaskITCase.java ---------------------------------------------------------------------- diff --git a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/PushTaskITCase.java b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/PushTaskITCase.java index 91b7840..bf294f6 100644 --- a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/PushTaskITCase.java +++ b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/PushTaskITCase.java @@ -26,7 +26,6 @@ import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; import java.util.HashSet; -import java.util.List; import java.util.Set; import javax.ws.rs.core.Response; import org.apache.syncope.client.lib.SyncopeClient; @@ -67,7 +66,7 @@ public class PushTaskITCase extends AbstractTaskITCase { @Test public void getPushActionsClasses() { - List<String> actions = syncopeService.info().getPushActions(); + Set<String> actions = syncopeService.info().getPushActions(); assertNotNull(actions); } http://git-wip-us.apache.org/repos/asf/syncope/blob/b4a51a8a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/ReportITCase.java ---------------------------------------------------------------------- diff --git a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/ReportITCase.java b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/ReportITCase.java index 86f3b1d..bed0aa4 100644 --- a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/ReportITCase.java +++ b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/ReportITCase.java @@ -27,6 +27,7 @@ import static org.junit.Assert.fail; import java.io.IOException; import java.io.InputStream; import java.util.List; +import java.util.Set; import javax.ws.rs.core.HttpHeaders; import javax.ws.rs.core.Response; import org.apache.commons.io.IOUtils; @@ -53,7 +54,7 @@ public class ReportITCase extends AbstractITCase { @Test public void getReportletClasses() { - List<String> reportlets = syncopeService.info().getReportlets(); + Set<String> reportlets = syncopeService.info().getReportlets(); assertNotNull(reportlets); assertFalse(reportlets.isEmpty()); } http://git-wip-us.apache.org/repos/asf/syncope/blob/b4a51a8a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/ResourceITCase.java ---------------------------------------------------------------------- diff --git a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/ResourceITCase.java b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/ResourceITCase.java index 90f5796..99be00a 100644 --- a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/ResourceITCase.java +++ b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/ResourceITCase.java @@ -103,7 +103,7 @@ public class ResourceITCase extends AbstractITCase { @Test public void getPropagationActionsClasses() { - List<String> actions = syncopeService.info().getPropagationActions(); + Set<String> actions = syncopeService.info().getPropagationActions(); assertNotNull(actions); assertFalse(actions.isEmpty()); } http://git-wip-us.apache.org/repos/asf/syncope/blob/b4a51a8a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/SchedTaskITCase.java ---------------------------------------------------------------------- diff --git a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/SchedTaskITCase.java b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/SchedTaskITCase.java index 42493af..614f5d3 100644 --- a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/SchedTaskITCase.java +++ b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/SchedTaskITCase.java @@ -26,6 +26,7 @@ import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; import java.util.List; +import java.util.Set; import javax.ws.rs.core.Response; import org.apache.syncope.client.lib.SyncopeClient; import org.apache.syncope.common.lib.to.AbstractTaskTO; @@ -47,7 +48,7 @@ public class SchedTaskITCase extends AbstractTaskITCase { @Test public void getJobClasses() { - List<String> jobClasses = syncopeService.info().getTaskJobs(); + Set<String> jobClasses = syncopeService.info().getTaskJobs(); assertNotNull(jobClasses); assertFalse(jobClasses.isEmpty()); }
