You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@syncope.apache.org by fm...@apache.org on 2013/02/04 19:22:01 UTC
svn commit: r1442286 - in /syncope/trunk:
common/src/main/java/org/apache/syncope/common/annotation/
common/src/main/java/org/apache/syncope/common/types/
console/src/main/java/org/apache/syncope/console/pages/panels/
console/src/main/resources/org/apa...
Author: fmartelli
Date: Mon Feb 4 18:22:00 2013
New Revision: 1442286
URL: http://svn.apache.org/viewvc?rev=1442286&view=rev
Log:
SYNCOPE-258: provided feature on the core; the next step will be done on the console ...
Added:
syncope/trunk/common/src/main/java/org/apache/syncope/common/annotation/ClassList.java
- copied, changed from r1439893, syncope/trunk/common/src/main/java/org/apache/syncope/common/annotation/SchemaList.java
syncope/trunk/core/src/main/java/org/apache/syncope/core/sync/SyncRule.java
- copied, changed from r1441451, syncope/trunk/core/src/main/java/org/apache/syncope/core/sync/SyncActions.java
syncope/trunk/core/src/test/java/org/apache/syncope/core/sync/TestSyncRule.java (with props)
Modified:
syncope/trunk/common/src/main/java/org/apache/syncope/common/types/AuditElements.java
syncope/trunk/common/src/main/java/org/apache/syncope/common/types/SyncPolicySpec.java
syncope/trunk/console/src/main/java/org/apache/syncope/console/pages/panels/PolicyBeanPanel.java
syncope/trunk/console/src/main/resources/org/apache/syncope/console/pages/PolicyModalPage.properties
syncope/trunk/core/pom.xml
syncope/trunk/core/src/main/java/org/apache/syncope/core/init/ImplementationClassNamesLoader.java
syncope/trunk/core/src/main/java/org/apache/syncope/core/persistence/beans/Policy.java
syncope/trunk/core/src/main/java/org/apache/syncope/core/persistence/beans/SyncPolicy.java
syncope/trunk/core/src/main/java/org/apache/syncope/core/rest/controller/PolicyController.java
syncope/trunk/core/src/main/java/org/apache/syncope/core/sync/impl/SyncopeSyncResultHandler.java
syncope/trunk/core/src/main/java/org/apache/syncope/core/util/AttributableUtil.java
syncope/trunk/core/src/test/java/org/apache/syncope/core/persistence/dao/PolicyTest.java
syncope/trunk/core/src/test/java/org/apache/syncope/core/rest/PolicyTestITCase.java
syncope/trunk/core/src/test/java/org/apache/syncope/core/rest/TaskTestITCase.java
syncope/trunk/core/src/test/resources/content.xml
Copied: syncope/trunk/common/src/main/java/org/apache/syncope/common/annotation/ClassList.java (from r1439893, syncope/trunk/common/src/main/java/org/apache/syncope/common/annotation/SchemaList.java)
URL: http://svn.apache.org/viewvc/syncope/trunk/common/src/main/java/org/apache/syncope/common/annotation/ClassList.java?p2=syncope/trunk/common/src/main/java/org/apache/syncope/common/annotation/ClassList.java&p1=syncope/trunk/common/src/main/java/org/apache/syncope/common/annotation/SchemaList.java&r1=1439893&r2=1442286&rev=1442286&view=diff
==============================================================================
--- syncope/trunk/common/src/main/java/org/apache/syncope/common/annotation/SchemaList.java (original)
+++ syncope/trunk/common/src/main/java/org/apache/syncope/common/annotation/ClassList.java Mon Feb 4 18:22:00 2013
@@ -22,7 +22,5 @@ import java.lang.annotation.Retention;
import static java.lang.annotation.RetentionPolicy.RUNTIME;
@Retention(RUNTIME)
-public @interface SchemaList {
-
- boolean extended() default false;
+public @interface ClassList {
}
Modified: syncope/trunk/common/src/main/java/org/apache/syncope/common/types/AuditElements.java
URL: http://svn.apache.org/viewvc/syncope/trunk/common/src/main/java/org/apache/syncope/common/types/AuditElements.java?rev=1442286&r1=1442285&r2=1442286&view=diff
==============================================================================
--- syncope/trunk/common/src/main/java/org/apache/syncope/common/types/AuditElements.java (original)
+++ syncope/trunk/common/src/main/java/org/apache/syncope/common/types/AuditElements.java Mon Feb 4 18:22:00 2013
@@ -19,7 +19,6 @@
package org.apache.syncope.common.types;
import java.util.EnumSet;
-
import javax.xml.bind.annotation.XmlEnum;
public final class AuditElements {
@@ -135,7 +134,8 @@ public final class AuditElements {
create,
read,
update,
- delete
+ delete,
+ getCorrelationRuleClasses
}
Modified: syncope/trunk/common/src/main/java/org/apache/syncope/common/types/SyncPolicySpec.java
URL: http://svn.apache.org/viewvc/syncope/trunk/common/src/main/java/org/apache/syncope/common/types/SyncPolicySpec.java?rev=1442286&r1=1442285&r2=1442286&view=diff
==============================================================================
--- syncope/trunk/common/src/main/java/org/apache/syncope/common/types/SyncPolicySpec.java (original)
+++ syncope/trunk/common/src/main/java/org/apache/syncope/common/types/SyncPolicySpec.java Mon Feb 4 18:22:00 2013
@@ -20,11 +20,10 @@ package org.apache.syncope.common.types;
import java.util.ArrayList;
import java.util.List;
-
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlElementWrapper;
import javax.xml.bind.annotation.XmlType;
-
+import org.apache.syncope.common.annotation.ClassList;
import org.apache.syncope.common.annotation.SchemaList;
@XmlType
@@ -38,12 +37,18 @@ public class SyncPolicySpec extends Abst
@SchemaList(extended = true)
private List<String> uAltSearchSchemas;
+ @ClassList
+ private String userJavaRule;
+
/**
* SyncopeRole attributes and fields for matching during synchronization.
*/
@SchemaList(extended = true)
private List<String> rAltSearchSchemas;
+ @ClassList
+ private String roleJavaRule;
+
/**
* Conflict resolution action.
*/
@@ -85,4 +90,24 @@ public class SyncPolicySpec extends Abst
public void setrAltSearchSchemas(List<String> rAltSearchSchemas) {
this.rAltSearchSchemas = rAltSearchSchemas;
}
+
+ @XmlElementWrapper(name = "roleJavaRule")
+ @XmlElement(name = "roleJavaRule")
+ public String getRoleJavaRule() {
+ return roleJavaRule;
+ }
+
+ public void setRoleJavaRule(String roleJavaRule) {
+ this.roleJavaRule = roleJavaRule;
+ }
+
+ @XmlElementWrapper(name = "userJavaRule")
+ @XmlElement(name = "userJavaRule")
+ public String getUserJavaRule() {
+ return userJavaRule;
+ }
+
+ public void setUserJavaRule(String userJavaRule) {
+ this.userJavaRule = userJavaRule;
+ }
}
Modified: syncope/trunk/console/src/main/java/org/apache/syncope/console/pages/panels/PolicyBeanPanel.java
URL: http://svn.apache.org/viewvc/syncope/trunk/console/src/main/java/org/apache/syncope/console/pages/panels/PolicyBeanPanel.java?rev=1442286&r1=1442285&r2=1442286&view=diff
==============================================================================
--- syncope/trunk/console/src/main/java/org/apache/syncope/console/pages/panels/PolicyBeanPanel.java (original)
+++ syncope/trunk/console/src/main/java/org/apache/syncope/console/pages/panels/PolicyBeanPanel.java Mon Feb 4 18:22:00 2013
@@ -99,7 +99,6 @@ public class PolicyBeanPanel extends Pan
fieldWrapper.setType(field.getType());
final SchemaList schemaList = field.getAnnotation(SchemaList.class);
-
fieldWrapper.setSchemaList(schemaList);
items.add(fieldWrapper);
Modified: syncope/trunk/console/src/main/resources/org/apache/syncope/console/pages/PolicyModalPage.properties
URL: http://svn.apache.org/viewvc/syncope/trunk/console/src/main/resources/org/apache/syncope/console/pages/PolicyModalPage.properties?rev=1442286&r1=1442285&r2=1442286&view=diff
==============================================================================
--- syncope/trunk/console/src/main/resources/org/apache/syncope/console/pages/PolicyModalPage.properties (original)
+++ syncope/trunk/console/src/main/resources/org/apache/syncope/console/pages/PolicyModalPage.properties Mon Feb 4 18:22:00 2013
@@ -71,6 +71,9 @@ permittedLoginRetries=Maximum number of
# Sync policy specification properties
#-----------------------------
uAltSearchSchemas=Alternative attributes for local search (users)
+rAltSearchSchemas=Alternative attributes for local search (roles)
+userJavaRule=Custom user correlation rule
+roleJavaRule=Custom role correlation rule
conflictResolutionAction= Conflict resolution action
#-----------------------------
@@ -84,4 +87,3 @@ GLOBAL_PASSWORD=Global Password Policy
SYNC=Synchronization Policy
GLOBAL_SYNC=Global Synchronization Policy
#-----------------------------
-rAltSearchSchemas=Alternative attributes for local search (roles)
Modified: syncope/trunk/core/pom.xml
URL: http://svn.apache.org/viewvc/syncope/trunk/core/pom.xml?rev=1442286&r1=1442285&r2=1442286&view=diff
==============================================================================
--- syncope/trunk/core/pom.xml (original)
+++ syncope/trunk/core/pom.xml Mon Feb 4 18:22:00 2013
@@ -442,6 +442,8 @@ under the License.
</unzip>
<copy file="${project.build.directory}/test-classes/org/apache/syncope/core/sync/TestSyncActions.class"
todir="${cargo.run.dir}/WEB-INF/classes/org/apache/syncope/core/sync"/>
+ <copy file="${project.build.directory}/test-classes/org/apache/syncope/core/sync/TestSyncRule.class"
+ todir="${cargo.run.dir}/WEB-INF/classes/org/apache/syncope/core/sync"/>
<copy file="${project.build.directory}/test-classes/db.jsp" todir="${cargo.run.dir}"/>
<copy todir="${cargo.run.dir}/WEB-INF/classes" includeEmptyDirs="false">
<fileset dir="${project.build.directory}/test-classes">
Modified: syncope/trunk/core/src/main/java/org/apache/syncope/core/init/ImplementationClassNamesLoader.java
URL: http://svn.apache.org/viewvc/syncope/trunk/core/src/main/java/org/apache/syncope/core/init/ImplementationClassNamesLoader.java?rev=1442286&r1=1442285&r2=1442286&view=diff
==============================================================================
--- syncope/trunk/core/src/main/java/org/apache/syncope/core/init/ImplementationClassNamesLoader.java (original)
+++ syncope/trunk/core/src/main/java/org/apache/syncope/core/init/ImplementationClassNamesLoader.java Mon Feb 4 18:22:00 2013
@@ -31,6 +31,7 @@ import org.apache.syncope.core.propagati
import org.apache.syncope.core.report.ReportJob;
import org.apache.syncope.core.report.Reportlet;
import org.apache.syncope.core.sync.SyncActions;
+import org.apache.syncope.core.sync.SyncRule;
import org.apache.syncope.core.sync.impl.SyncJob;
import org.quartz.Job;
import org.slf4j.Logger;
@@ -54,6 +55,7 @@ public class ImplementationClassNamesLoa
REPORTLET,
JOB,
SYNC_ACTIONS,
+ SYNC_CORRELATION_RULES,
PROPAGATION_ACTIONS,
VALIDATOR
@@ -100,6 +102,10 @@ public class ImplementationClassNamesLoa
if (interfaces.contains(SyncActions.class) && !metadata.isAbstract()) {
classNames.get(Type.SYNC_ACTIONS).add(metadata.getClassName());
}
+
+ if (interfaces.contains(SyncRule.class) && !metadata.isAbstract()) {
+ classNames.get(Type.SYNC_CORRELATION_RULES).add(metadata.getClassName());
+ }
if (interfaces.contains(PropagationActions.class) && !metadata.isAbstract()) {
classNames.get(Type.PROPAGATION_ACTIONS).add(metadata.getClassName());
Modified: syncope/trunk/core/src/main/java/org/apache/syncope/core/persistence/beans/Policy.java
URL: http://svn.apache.org/viewvc/syncope/trunk/core/src/main/java/org/apache/syncope/core/persistence/beans/Policy.java?rev=1442286&r1=1442285&r2=1442286&view=diff
==============================================================================
--- syncope/trunk/core/src/main/java/org/apache/syncope/core/persistence/beans/Policy.java (original)
+++ syncope/trunk/core/src/main/java/org/apache/syncope/core/persistence/beans/Policy.java Mon Feb 4 18:22:00 2013
@@ -24,7 +24,6 @@ import javax.persistence.Enumerated;
import javax.persistence.Id;
import javax.persistence.Lob;
import javax.validation.constraints.NotNull;
-
import org.apache.syncope.common.types.AbstractPolicySpec;
import org.apache.syncope.common.types.PolicyType;
import org.apache.syncope.core.persistence.validation.entity.PolicyCheck;
Modified: syncope/trunk/core/src/main/java/org/apache/syncope/core/persistence/beans/SyncPolicy.java
URL: http://svn.apache.org/viewvc/syncope/trunk/core/src/main/java/org/apache/syncope/core/persistence/beans/SyncPolicy.java?rev=1442286&r1=1442285&r2=1442286&view=diff
==============================================================================
--- syncope/trunk/core/src/main/java/org/apache/syncope/core/persistence/beans/SyncPolicy.java (original)
+++ syncope/trunk/core/src/main/java/org/apache/syncope/core/persistence/beans/SyncPolicy.java Mon Feb 4 18:22:00 2013
@@ -19,7 +19,6 @@
package org.apache.syncope.core.persistence.beans;
import javax.persistence.Entity;
-
import org.apache.syncope.common.types.PolicyType;
@Entity
Modified: syncope/trunk/core/src/main/java/org/apache/syncope/core/rest/controller/PolicyController.java
URL: http://svn.apache.org/viewvc/syncope/trunk/core/src/main/java/org/apache/syncope/core/rest/controller/PolicyController.java?rev=1442286&r1=1442285&r2=1442286&view=diff
==============================================================================
--- syncope/trunk/core/src/main/java/org/apache/syncope/core/rest/controller/PolicyController.java (original)
+++ syncope/trunk/core/src/main/java/org/apache/syncope/core/rest/controller/PolicyController.java Mon Feb 4 18:22:00 2013
@@ -21,6 +21,7 @@ package org.apache.syncope.core.rest.con
import java.util.ArrayList;
import java.util.List;
import java.util.Locale;
+import java.util.Set;
import javax.servlet.http.HttpServletResponse;
@@ -28,12 +29,14 @@ import org.apache.syncope.common.to.Acco
import org.apache.syncope.common.to.PasswordPolicyTO;
import org.apache.syncope.common.to.PolicyTO;
import org.apache.syncope.common.to.SyncPolicyTO;
+import org.apache.syncope.common.types.AuditElements;
import org.apache.syncope.common.types.AuditElements.Category;
import org.apache.syncope.common.types.AuditElements.PolicySubCategory;
import org.apache.syncope.common.types.AuditElements.Result;
import org.apache.syncope.common.types.PolicyType;
import org.apache.syncope.common.validation.SyncopeClientCompositeErrorException;
import org.apache.syncope.core.audit.AuditManager;
+import org.apache.syncope.core.init.ImplementationClassNamesLoader;
import org.apache.syncope.core.persistence.beans.AccountPolicy;
import org.apache.syncope.core.persistence.beans.PasswordPolicy;
import org.apache.syncope.core.persistence.beans.Policy;
@@ -48,12 +51,16 @@ import org.springframework.web.bind.anno
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
+import org.springframework.web.servlet.ModelAndView;
@Controller
@RequestMapping("/policy")
public class PolicyController extends AbstractController {
@Autowired
+ private ImplementationClassNamesLoader classNamesLoader;
+
+ @Autowired
private AuditManager auditManager;
@Autowired
@@ -166,7 +173,8 @@ public class PolicyController extends Ab
@PreAuthorize("hasRole('POLICY_READ')")
@RequestMapping(method = RequestMethod.GET, value = "/password/global/read")
- public PasswordPolicyTO getGlobalPasswordPolicy() throws NotFoundException {
+ public PasswordPolicyTO getGlobalPasswordPolicy()
+ throws NotFoundException {
LOG.debug("Reading global password policy");
@@ -183,7 +191,8 @@ public class PolicyController extends Ab
@PreAuthorize("hasRole('POLICY_READ')")
@RequestMapping(method = RequestMethod.GET, value = "/account/global/read")
- public AccountPolicyTO getGlobalAccountPolicy() throws NotFoundException {
+ public AccountPolicyTO getGlobalAccountPolicy()
+ throws NotFoundException {
LOG.debug("Reading global account policy");
@@ -200,7 +209,8 @@ public class PolicyController extends Ab
@PreAuthorize("hasRole('POLICY_READ')")
@RequestMapping(method = RequestMethod.GET, value = "/sync/global/read")
- public SyncPolicyTO getGlobalSyncPolicy() throws NotFoundException {
+ public SyncPolicyTO getGlobalSyncPolicy()
+ throws NotFoundException {
LOG.debug("Reading global sync policy");
@@ -235,7 +245,8 @@ public class PolicyController extends Ab
@PreAuthorize("hasRole('POLICY_DELETE')")
@RequestMapping(method = RequestMethod.GET, value = "/delete/{id}")
- public PolicyTO delete(@PathVariable("id") final Long id) throws NotFoundException {
+ public PolicyTO delete(@PathVariable("id") final Long id)
+ throws NotFoundException {
Policy policy = policyDAO.find(id);
if (policy == null) {
throw new NotFoundException("Policy " + id + " not found");
@@ -249,4 +260,16 @@ public class PolicyController extends Ab
return policyToDelete;
}
+
+ @PreAuthorize("hasRole('POLICY_LIST')")
+ @RequestMapping(method = RequestMethod.GET, value = "/correlationRuleClasses")
+ public ModelAndView getCorrelationRuleClasses() {
+ final Set<String> actionsClasses =
+ classNamesLoader.getClassNames(ImplementationClassNamesLoader.Type.SYNC_CORRELATION_RULES);
+
+ auditManager.audit(Category.policy, AuditElements.PolicySubCategory.getCorrelationRuleClasses,
+ Result.success, "Successfully listed all correlation rule classes: " + actionsClasses.size());
+
+ return new ModelAndView().addObject(actionsClasses);
+ }
}
Copied: syncope/trunk/core/src/main/java/org/apache/syncope/core/sync/SyncRule.java (from r1441451, syncope/trunk/core/src/main/java/org/apache/syncope/core/sync/SyncActions.java)
URL: http://svn.apache.org/viewvc/syncope/trunk/core/src/main/java/org/apache/syncope/core/sync/SyncRule.java?p2=syncope/trunk/core/src/main/java/org/apache/syncope/core/sync/SyncRule.java&p1=syncope/trunk/core/src/main/java/org/apache/syncope/core/sync/SyncActions.java&r1=1441451&r2=1442286&rev=1442286&view=diff
==============================================================================
--- syncope/trunk/core/src/main/java/org/apache/syncope/core/sync/SyncActions.java (original)
+++ syncope/trunk/core/src/main/java/org/apache/syncope/core/sync/SyncRule.java Mon Feb 4 18:22:00 2013
@@ -18,83 +18,19 @@
*/
package org.apache.syncope.core.sync;
-import java.util.List;
-
-import org.apache.syncope.common.mod.AbstractAttributableMod;
-import org.apache.syncope.common.to.AbstractAttributableTO;
-import org.identityconnectors.framework.common.objects.SyncDelta;
-import org.identityconnectors.framework.common.objects.SyncResultsHandler;
-import org.quartz.JobExecutionException;
+import org.apache.syncope.common.search.NodeCond;
+import org.identityconnectors.framework.common.objects.ConnectorObject;
/**
- * Interface for actions to be performed during SyncJob execution.
+ * Interface for correlation rule to be evaluated during SyncJob execution.
*/
-public interface SyncActions {
-
- /**
- * Action to be executed before to start the synchronization task execution.
- *
- * @param handler synchronization handler being executed.
- * @throws JobExecutionException in case of generic failure.
- */
- void beforeAll(final SyncResultsHandler handler) throws JobExecutionException;
-
- /**
- * Action to be executed before to create a synchronized user locally.
- *
- * @param handler synchronization handler being executed.
- * @param delta retrieved synchronization information
- * @param subject user / role to be created
- * @return synchronization information used for user status evaluation and to be passed to the 'after' method.
- * @throws JobExecutionException in case of generic failure
- */
- <T extends AbstractAttributableTO> SyncDelta beforeCreate(final SyncResultsHandler handler,
- final SyncDelta delta, final T subject) throws JobExecutionException;
-
- /**
- * Action to be executed before to update a synchronized user locally.
- *
- * @param handler synchronization handler being executed.
- * @param delta retrieved synchronization information
- * @param subject local user / role information
- * @param subjectMod modification
- * @return synchronization information used for logging and to be passed to the 'after' method.
- * @throws JobExecutionException in case of generic failure.
- */
- <T extends AbstractAttributableTO, K extends AbstractAttributableMod> SyncDelta beforeUpdate(
- final SyncResultsHandler handler, final SyncDelta delta, final T subject, final K subjectMod)
- throws JobExecutionException;
-
- /**
- * Action to be executed before to delete a synchronized user locally.
- *
- * @param handler synchronization handler being executed.
- * @param delta retrieved synchronization information
- * @param subject lcao user / role to be deleted
- * @return synchronization information used for logging and to be passed to the 'after' method.
- * @throws JobExecutionException in case of generic failure
- */
- <T extends AbstractAttributableTO> SyncDelta beforeDelete(final SyncResultsHandler handler,
- final SyncDelta delta, final T subject) throws JobExecutionException;
-
- /**
- * Action to be executed after each local user synchronization.
- *
- * @param handler synchronization handler being executed.
- * @param delta retrieved synchronization information (may be modified by 'beforeCreate/beforeUpdate/beforeDelete')
- * @param subject synchronized local user / role
- * @param result global synchronization results at the current synchronization step
- * @throws JobExecutionException in case of generic failure
- */
- <T extends AbstractAttributableTO> void after(final SyncResultsHandler handler, final SyncDelta delta,
- final T subject, final SyncResult result) throws JobExecutionException;
+public interface SyncRule {
/**
- * Action to be executed after the synchronization task completion.
+ * Return a search condition.
*
- * @param handler synchronization handler being executed.
- * @param results synchronization result
- * @throws JobExecutionException in case of generic failure
+ * @param connObj connector object.
+ * @return search condition.
*/
- void afterAll(final SyncResultsHandler handler, final List<SyncResult> results) throws JobExecutionException;
+ NodeCond getSearchCond(final ConnectorObject connObj);
}
Modified: syncope/trunk/core/src/main/java/org/apache/syncope/core/sync/impl/SyncopeSyncResultHandler.java
URL: http://svn.apache.org/viewvc/syncope/trunk/core/src/main/java/org/apache/syncope/core/sync/impl/SyncopeSyncResultHandler.java?rev=1442286&r1=1442285&r2=1442286&view=diff
==============================================================================
--- syncope/trunk/core/src/main/java/org/apache/syncope/core/sync/impl/SyncopeSyncResultHandler.java (original)
+++ syncope/trunk/core/src/main/java/org/apache/syncope/core/sync/impl/SyncopeSyncResultHandler.java Mon Feb 4 18:22:00 2013
@@ -69,6 +69,7 @@ import org.apache.syncope.core.rest.data
import org.apache.syncope.core.rest.data.UserDataBinder;
import org.apache.syncope.core.sync.SyncActions;
import org.apache.syncope.core.sync.SyncResult;
+import org.apache.syncope.core.sync.SyncRule;
import org.apache.syncope.core.util.AttributableUtil;
import org.apache.syncope.core.util.EntitlementUtil;
import org.apache.syncope.core.workflow.WorkflowResult;
@@ -332,10 +333,13 @@ public class SyncopeSyncResultHandler im
return result;
}
- private List<Long> findByAttributableSearch(final ConnectorObject connObj, final SyncPolicySpec policySpec,
- final AttributableUtil attrUtil) {
+ private List<Long> findByCorrelationRule(
+ final ConnectorObject connObj, final SyncRule rule, final AttributableUtil attrUtil) {
+ return search(rule.getSearchCond(connObj), attrUtil);
+ }
- final List<Long> result = new ArrayList<Long>();
+ private List<Long> findByAttributableSearch(
+ final ConnectorObject connObj, final List<String> altSearchSchemas, final AttributableUtil attrUtil) {
// search for external attribute's name/value of each specified name
@@ -348,7 +352,7 @@ public class SyncopeSyncResultHandler im
// search for user/role by attribute(s) specified in the policy
NodeCond searchCond = null;
- for (String schema : attrUtil.getAltSearchSchemas(policySpec)) {
+ for (String schema : altSearchSchemas) {
Attribute value = extValues.get(schema);
AttributeCond.Type type;
@@ -390,6 +394,12 @@ public class SyncopeSyncResultHandler im
: NodeCond.getAndCond(searchCond, nodeCond);
}
+ return search(searchCond, attrUtil);
+ }
+
+ private List<Long> search(final NodeCond searchCond, final AttributableUtil attrUtil) {
+ final List<Long> result = new ArrayList<Long>();
+
final List<AbstractAttributable> subjects = searchDAO.search(
EntitlementUtil.getRoleIds(entitlementDAO.findAll()), searchCond, attrUtil);
for (AbstractAttributable subject : subjects) {
@@ -413,9 +423,18 @@ public class SyncopeSyncResultHandler im
policySpec = (SyncPolicySpec) syncTask.getResource().getSyncPolicy().getSpecification();
}
- return policySpec == null || attrUtil.getAltSearchSchemas(policySpec).isEmpty()
+ SyncRule syncRule = null;
+ List<String> altSearchSchemas = null;
+
+ if (policySpec != null) {
+ syncRule = attrUtil.getCorrelationRule(policySpec);
+ altSearchSchemas = attrUtil.getAltSearchSchemas(policySpec);
+ }
+
+ return syncRule == null ? altSearchSchemas == null
? findByAccountIdItem(uid, attrUtil)
- : findByAttributableSearch(connObj, policySpec, attrUtil);
+ : findByAttributableSearch(connObj, altSearchSchemas, attrUtil)
+ : findByCorrelationRule(connObj, syncRule, attrUtil);
}
public Long findMatchingAttributableId(final ObjectClass objectClass, final String name) {
@@ -645,7 +664,8 @@ public class SyncopeSyncResultHandler im
}
protected List<SyncResult> update(SyncDelta delta, final List<Long> subjects, final AttributableUtil attrUtil,
- final boolean dryRun) throws JobExecutionException {
+ final boolean dryRun)
+ throws JobExecutionException {
if (!syncTask.isPerformUpdate()) {
LOG.debug("SyncTask not configured for update");
Modified: syncope/trunk/core/src/main/java/org/apache/syncope/core/util/AttributableUtil.java
URL: http://svn.apache.org/viewvc/syncope/trunk/core/src/main/java/org/apache/syncope/core/util/AttributableUtil.java?rev=1442286&r1=1442285&r2=1442286&view=diff
==============================================================================
--- syncope/trunk/core/src/main/java/org/apache/syncope/core/util/AttributableUtil.java (original)
+++ syncope/trunk/core/src/main/java/org/apache/syncope/core/util/AttributableUtil.java Mon Feb 4 18:22:00 2013
@@ -20,6 +20,7 @@ package org.apache.syncope.core.util;
import java.util.Collections;
import java.util.List;
+import org.apache.commons.lang3.StringUtils;
import org.apache.syncope.common.to.AbstractAttributableTO;
import org.apache.syncope.common.to.MembershipTO;
import org.apache.syncope.common.to.RoleTO;
@@ -66,11 +67,18 @@ import org.apache.syncope.core.persisten
import org.apache.syncope.core.persistence.beans.user.USchema;
import org.apache.syncope.core.persistence.beans.user.UVirAttr;
import org.apache.syncope.core.persistence.beans.user.UVirSchema;
+import org.apache.syncope.core.sync.SyncRule;
import org.identityconnectors.framework.common.objects.ObjectClass;
+import org.slf4j.LoggerFactory;
@SuppressWarnings("unchecked")
public class AttributableUtil {
+ /**
+ * Logger.
+ */
+ protected static final org.slf4j.Logger LOG = LoggerFactory.getLogger(AttributableUtil.class);
+
private final AttributableType type;
public static AttributableUtil getInstance(final AttributableType type) {
@@ -579,22 +587,49 @@ public class AttributableUtil {
public List<String> getAltSearchSchemas(final SyncPolicySpec policySpec) {
List<String> result = Collections.EMPTY_LIST;
- if (policySpec != null) {
- switch (type) {
- case USER:
- result = policySpec.getuAltSearchSchemas();
- break;
- case ROLE:
- result = policySpec.getrAltSearchSchemas();
- break;
- case MEMBERSHIP:
- default:
- }
+ switch (type) {
+ case USER:
+ result = policySpec.getuAltSearchSchemas();
+ break;
+ case ROLE:
+ result = policySpec.getrAltSearchSchemas();
+ break;
+ case MEMBERSHIP:
+ default:
}
return result;
}
+ public SyncRule getCorrelationRule(final SyncPolicySpec policySpec) {
+
+ String clazz;
+
+ switch (type) {
+ case USER:
+ clazz = policySpec.getUserJavaRule();
+ break;
+ case ROLE:
+ clazz = policySpec.getRoleJavaRule();
+ break;
+ case MEMBERSHIP:
+ default:
+ clazz = null;
+ }
+
+ SyncRule res = null;
+
+ if (StringUtils.isNotBlank(clazz)) {
+ try {
+ res = (SyncRule) Class.forName(clazz).newInstance();
+ } catch (Exception e) {
+ LOG.error("Failure instantiating correlation rule class '{}'", clazz, e);
+ }
+ }
+
+ return res;
+ }
+
public String searchView() {
String result = "";
Modified: syncope/trunk/core/src/test/java/org/apache/syncope/core/persistence/dao/PolicyTest.java
URL: http://svn.apache.org/viewvc/syncope/trunk/core/src/test/java/org/apache/syncope/core/persistence/dao/PolicyTest.java?rev=1442286&r1=1442285&r2=1442286&view=diff
==============================================================================
--- syncope/trunk/core/src/test/java/org/apache/syncope/core/persistence/dao/PolicyTest.java (original)
+++ syncope/trunk/core/src/test/java/org/apache/syncope/core/persistence/dao/PolicyTest.java Mon Feb 4 18:22:00 2013
@@ -101,13 +101,23 @@ public class PolicyTest extends Abstract
@Test
public void create() {
SyncPolicy policy = new SyncPolicy();
- policy.setSpecification(new SyncPolicySpec());
+
+ final String syncURuleName = "net.tirasa.sync.correlation.TirasaURule";
+ final String syncRRuleName = "net.tirasa.sync.correlation.TirasaRRule";
+
+ SyncPolicySpec syncPolicySpec = new SyncPolicySpec();
+ syncPolicySpec.setUserJavaRule(syncURuleName);
+ syncPolicySpec.setRoleJavaRule(syncRRuleName);
+
+ policy.setSpecification(syncPolicySpec);
policy.setDescription("Sync policy");
policy = policyDAO.save(policy);
assertNotNull(policy);
assertEquals(PolicyType.SYNC, policy.getType());
+ assertEquals(syncURuleName, ((SyncPolicySpec) policy.getSpecification()).getUserJavaRule());
+ assertEquals(syncRRuleName, ((SyncPolicySpec) policy.getSpecification()).getRoleJavaRule());
}
@Test
Modified: syncope/trunk/core/src/test/java/org/apache/syncope/core/rest/PolicyTestITCase.java
URL: http://svn.apache.org/viewvc/syncope/trunk/core/src/test/java/org/apache/syncope/core/rest/PolicyTestITCase.java?rev=1442286&r1=1442285&r2=1442286&view=diff
==============================================================================
--- syncope/trunk/core/src/test/java/org/apache/syncope/core/rest/PolicyTestITCase.java (original)
+++ syncope/trunk/core/src/test/java/org/apache/syncope/core/rest/PolicyTestITCase.java Mon Feb 4 18:22:00 2013
@@ -35,6 +35,7 @@ import org.apache.syncope.common.types.P
import org.apache.syncope.common.types.SyncPolicySpec;
import org.apache.syncope.common.types.SyncopeClientExceptionType;
import org.apache.syncope.common.validation.SyncopeClientCompositeErrorException;
+import org.apache.syncope.core.sync.TestSyncRule;
import org.junit.FixMethodOrder;
import org.junit.Test;
import org.junit.runners.MethodSorters;
@@ -111,6 +112,7 @@ public class PolicyTestITCase extends Ab
assertNotNull(policyTO);
assertEquals(PolicyType.SYNC, policyTO.getType());
+ assertEquals(TestSyncRule.class.getName(), ((SyncPolicySpec) policyTO.getSpecification()).getUserJavaRule());
}
@Test
@@ -166,8 +168,13 @@ public class PolicyTestITCase extends Ab
private SyncPolicyTO buildSyncPolicyTO() {
SyncPolicyTO policy = new SyncPolicyTO();
- policy.setSpecification(new SyncPolicySpec());
+
+ SyncPolicySpec spec = new SyncPolicySpec();
+ spec.setUserJavaRule(TestSyncRule.class.getName());
+
+ policy.setSpecification(spec);
policy.setDescription("Sync policy");
+
return policy;
}
}
Modified: syncope/trunk/core/src/test/java/org/apache/syncope/core/rest/TaskTestITCase.java
URL: http://svn.apache.org/viewvc/syncope/trunk/core/src/test/java/org/apache/syncope/core/rest/TaskTestITCase.java?rev=1442286&r1=1442285&r2=1442286&view=diff
==============================================================================
--- syncope/trunk/core/src/test/java/org/apache/syncope/core/rest/TaskTestITCase.java (original)
+++ syncope/trunk/core/src/test/java/org/apache/syncope/core/rest/TaskTestITCase.java Mon Feb 4 18:22:00 2013
@@ -47,6 +47,7 @@ import org.apache.syncope.common.to.Sync
import org.apache.syncope.common.to.TaskExecTO;
import org.apache.syncope.common.to.TaskTO;
import org.apache.syncope.common.to.UserTO;
+import org.apache.syncope.common.mod.UserMod;
import org.apache.syncope.common.types.IntMappingType;
import org.apache.syncope.common.types.PropagationTaskExecStatus;
import org.apache.syncope.common.types.TaskType;
@@ -372,7 +373,8 @@ public class TaskTestITCase extends Abst
}
@Test
- public void reconcileFromLDAP() throws InvalidSearchConditionException {
+ public void reconcileFromLDAP()
+ throws InvalidSearchConditionException {
// Update sync task
SyncTaskTO task = taskService.read(TaskType.SYNCHRONIZATION, 11L);
assertNotNull(task);
@@ -777,6 +779,50 @@ public class TaskTestITCase extends Abst
}
}
+ @Test
+ public void issueSYNCOPE258() {
+ SyncTaskTO task = new SyncTaskTO();
+ task.setName("Test Sync Rule");
+ task.setResource("ws-target-resource-2");
+ task.setFullReconciliation(true);
+ task.setPerformCreate(true);
+ task.setPerformDelete(true);
+ task.setPerformUpdate(true);
+
+ Response response = taskService.create(task);
+ SyncTaskTO actual = getObject(response, SyncTaskTO.class, taskService);
+ assertNotNull(actual);
+
+ UserTO userTO = UserTestITCase.getUniqueSampleTO("s258_1@apache.org");
+ userTO.getResources().clear();
+ userTO.addResource("ws-target-resource-2");
+
+ userTO = createUser(userTO);
+
+ userTO = UserTestITCase.getUniqueSampleTO("s258_2@apache.org");
+ userTO.getResources().clear();
+ userTO.addResource("ws-target-resource-2");
+
+ userTO = createUser(userTO);
+
+ // change email in order to unmatch the second user
+ UserMod userMod = new UserMod();
+ userMod.setId(userTO.getId());
+ userMod.addAttributeToBeRemoved("email");
+ userMod.addAttributeToBeUpdated(attributeMod("email", "s258@apache.org"));
+
+ userTO = userService.update(userMod.getId(), userMod);
+
+ execSyncTask(actual.getId(), 50, false);
+
+ SyncTaskTO executed = taskService.read(TaskType.SYNCHRONIZATION, actual.getId());
+ assertEquals(1, executed.getExecutions().size());
+
+ // asser for just one match
+ assertTrue(executed.getExecutions().get(0).getMessage().substring(0, 55) + "...",
+ executed.getExecutions().get(0).getMessage().contains("[updated/failures]: 1/0"));
+ }
+
/**
* remove initial and synchronized users to make test re-runnable
*/
Added: syncope/trunk/core/src/test/java/org/apache/syncope/core/sync/TestSyncRule.java
URL: http://svn.apache.org/viewvc/syncope/trunk/core/src/test/java/org/apache/syncope/core/sync/TestSyncRule.java?rev=1442286&view=auto
==============================================================================
--- syncope/trunk/core/src/test/java/org/apache/syncope/core/sync/TestSyncRule.java (added)
+++ syncope/trunk/core/src/test/java/org/apache/syncope/core/sync/TestSyncRule.java Mon Feb 4 18:22:00 2013
@@ -0,0 +1,36 @@
+/*
+ * 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.sync;
+
+import org.apache.syncope.common.search.AttributeCond;
+import org.apache.syncope.common.search.NodeCond;
+import org.identityconnectors.framework.common.objects.ConnectorObject;
+
+public class TestSyncRule implements SyncRule {
+
+ @Override
+ public NodeCond getSearchCond(ConnectorObject connObj) {
+ AttributeCond cond = new AttributeCond();
+ cond.setSchema("email");
+ cond.setType(AttributeCond.Type.EQ);
+ cond.setExpression(connObj.getName().getNameValue());
+
+ return NodeCond.getLeafCond(cond);
+ }
+}
Propchange: syncope/trunk/core/src/test/java/org/apache/syncope/core/sync/TestSyncRule.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: syncope/trunk/core/src/test/java/org/apache/syncope/core/sync/TestSyncRule.java
------------------------------------------------------------------------------
svn:keywords = Date Author Id Revision HeadURL
Propchange: syncope/trunk/core/src/test/java/org/apache/syncope/core/sync/TestSyncRule.java
------------------------------------------------------------------------------
svn:mime-type = text/plain
Modified: syncope/trunk/core/src/test/resources/content.xml
URL: http://svn.apache.org/viewvc/syncope/trunk/core/src/test/resources/content.xml?rev=1442286&r1=1442285&r2=1442286&view=diff
==============================================================================
--- syncope/trunk/core/src/test/resources/content.xml (original)
+++ syncope/trunk/core/src/test/resources/content.xml Mon Feb 4 18:22:00 2013
@@ -40,6 +40,7 @@ under the License.
<Policy DTYPE="AccountPolicy" id="6" description="sample account policy" type="ACCOUNT" specification="%3Corg.apache.syncope.common.types.AccountPolicySpec%3E%0A++%3CmaxLength%3E0%3C%2FmaxLength%3E%0A++%3CminLength%3E4%3C%2FminLength%3E%0A++%3CprefixesNotPermitted%3E%0A++++%3Cstring%3Enotpermitted1%3C%2Fstring%3E%0A++++%3Cstring%3Enotpermitted2%3C%2Fstring%3E%0A++%3C%2FprefixesNotPermitted%3E%0A++%3CallUpperCase%3Efalse%3C%2FallUpperCase%3E%0A++%3CallLowerCase%3Efalse%3C%2FallLowerCase%3E%0A++%3CpropagateSuspension%3Efalse%3C%2FpropagateSuspension%3E%0A++%3CpermittedLoginRetries%3E3%3C%2FpermittedLoginRetries%3E%0A%3C%2Forg.apache.syncope.common.types.AccountPolicySpec%3E"/>
<Policy DTYPE="SyncPolicy" id="7" description="sync policy 1" type="SYNC" specification="%3Corg.apache.syncope.common.types.SyncPolicySpec%2F%3E"/>
<Policy DTYPE="PasswordPolicy" id="8" description="sample password policy" type="PASSWORD" specification="%3Corg.apache.syncope.common.types.PasswordPolicySpec%3E%0A++%3ChistoryLength%3E0%3C%2FhistoryLength%3E%0A++%3CmaxLength%3E0%3C%2FmaxLength%3E%0A++%3CminLength%3E10%3C%2FminLength%3E%0A++%3CnonAlphanumericRequired%3Etrue%3C%2FnonAlphanumericRequired%3E%0A++%3CalphanumericRequired%3Efalse%3C%2FalphanumericRequired%3E%0A++%3CdigitRequired%3Etrue%3C%2FdigitRequired%3E%0A++%3ClowercaseRequired%3Etrue%3C%2FlowercaseRequired%3E%0A++%3CuppercaseRequired%3Etrue%3C%2FuppercaseRequired%3E%0A++%3CmustStartWithDigit%3Etrue%3C%2FmustStartWithDigit%3E%0A++%3CmustntStartWithDigit%3Efalse%3C%2FmustntStartWithDigit%3E%0A++%3CmustEndWithDigit%3Etrue%3C%2FmustEndWithDigit%3E%0A++%3CmustntEndWithDigit%3Efalse%3C%2FmustntEndWithDigit%3E%0A++%3CmustStartWithNonAlpha%3Efalse%3C%2FmustStartWithNonAlpha%3E%0A++%3CmustStartWithAlpha%3Efalse%3C%2FmustStartWithAlpha%3E%0A++%3CmustntStartWithNonAl
pha%3Efalse%3C%2FmustntStartWithNonAlpha%3E%0A++%3CmustntStartWithAlpha%3Efalse%3C%2FmustntStartWithAlpha%3E%0A++%3CmustEndWithNonAlpha%3Efalse%3C%2FmustEndWithNonAlpha%3E%0A++%3CmustEndWithAlpha%3Efalse%3C%2FmustEndWithAlpha%3E%0A++%3CmustntEndWithNonAlpha%3Efalse%3C%2FmustntEndWithNonAlpha%3E%0A++%3CmustntEndWithAlpha%3Efalse%3C%2FmustntEndWithAlpha%3E%0A++%3CprefixesNotPermitted%3E%0A++++%3Cstring%3Enotpermitted1%3C%2Fstring%3E%0A++++%3Cstring%3Enotpermitted2%3C%2Fstring%3E%0A++%3C%2FprefixesNotPermitted%3E%0A%3C%2Forg.apache.syncope.common.types.PasswordPolicySpec%3E"/>
+ <Policy DTYPE="SyncPolicy" id="9" description="sync policy with a rule" type="SYNC" specification="%3Corg.apache.syncope.common.types.SyncPolicySpec%3E%0A++%3CuserJavaRule%3Eorg.apache.syncope.core.sync.TestSyncRule%3C/userJavaRule%3E%0A++%3CroleJavaRule%3E%3C/roleJavaRule%3E%0A++%3CconflictResolutionAction%3EIGNORE%3C/conflictResolutionAction%3E%0A%3C/org.apache.syncope.common.types.SyncPolicySpec%3E"/>
<SyncopeUser id="1" workflowId="0" status="active" password="5baa61e4c9b93f3f0682250b6cf8331b7ee68fd8" cipherAlgorithm="SHA1"
username="user1" creationDate="2010-10-20 11:00:00" suspended="0"/>
@@ -343,7 +344,8 @@ under the License.
propagationPriority="0" propagationPrimary="1" createTraceLevel="ALL" deleteTraceLevel="ALL" updateTraceLevel="ALL" syncTraceLevel="ALL"/>
<ExternalResource name="ws-target-resource-2" connector_id="100"
randomPwdIfNotProvided="0" enforceMandatoryCondition="1" propagationMode="TWO_PHASES"
- propagationPriority="0" propagationPrimary="1" createTraceLevel="FAILURES" deleteTraceLevel="NONE" updateTraceLevel="ALL" syncTraceLevel="ALL"/>
+ propagationPriority="0" propagationPrimary="1" createTraceLevel="FAILURES" deleteTraceLevel="NONE" updateTraceLevel="ALL" syncTraceLevel="ALL"
+ syncPolicy_id="9"/>
<ExternalResource name="ws-target-resource-3" connector_id="102"
randomPwdIfNotProvided="0" enforceMandatoryCondition="1" propagationMode="TWO_PHASES"
propagationPriority="0" propagationPrimary="1" createTraceLevel="FAILURES" deleteTraceLevel="NONE" updateTraceLevel="ALL" syncTraceLevel="ALL"