http://git-wip-us.apache.org/repos/asf/syncope/blob/9cd92305/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/propagation/PropagationManagerImpl.java ---------------------------------------------------------------------- diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/propagation/PropagationManagerImpl.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/propagation/PropagationManagerImpl.java index 0d15ffd..77efd28 100644 --- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/propagation/PropagationManagerImpl.java +++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/propagation/PropagationManagerImpl.java @@ -29,7 +29,6 @@ import java.util.Set; import org.apache.commons.collections4.CollectionUtils; import org.apache.commons.collections4.Transformer; import org.apache.commons.lang3.tuple.Pair; -import org.apache.syncope.common.lib.patch.AttrPatch; import org.apache.syncope.common.lib.patch.StringPatchItem; import org.apache.syncope.common.lib.patch.UserPatch; import org.apache.syncope.common.lib.to.AttrTO; @@ -40,9 +39,7 @@ import org.apache.syncope.core.persistence.api.dao.ExternalResourceDAO; import org.apache.syncope.core.persistence.api.dao.GroupDAO; import org.apache.syncope.core.persistence.api.dao.UserDAO; import org.apache.syncope.core.persistence.api.entity.EntityFactory; -import org.apache.syncope.core.persistence.api.entity.VirAttr; import org.apache.syncope.core.persistence.api.entity.task.PropagationTask; -import org.apache.syncope.core.persistence.api.entity.user.User; import org.apache.syncope.core.provisioning.api.WorkflowResult; import org.apache.syncope.core.provisioning.api.propagation.PropagationManager; import org.apache.syncope.core.provisioning.api.propagation.PropagationTaskExecutor; @@ -51,11 +48,15 @@ import org.apache.syncope.core.misc.MappingUtils; import org.apache.syncope.core.misc.jexl.JexlUtils; import org.apache.syncope.core.persistence.api.dao.AnyDAO; import org.apache.syncope.core.persistence.api.dao.AnyObjectDAO; +import org.apache.syncope.core.persistence.api.dao.VirSchemaDAO; import org.apache.syncope.core.persistence.api.entity.Any; +import org.apache.syncope.core.persistence.api.entity.VirSchema; +import org.apache.syncope.core.persistence.api.entity.anyobject.AnyObject; +import org.apache.syncope.core.persistence.api.entity.group.Group; import org.apache.syncope.core.persistence.api.entity.resource.ExternalResource; import org.apache.syncope.core.persistence.api.entity.resource.MappingItem; import org.apache.syncope.core.persistence.api.entity.resource.Provision; -import org.apache.syncope.core.provisioning.api.VirAttrHandler; +import org.apache.syncope.core.persistence.api.entity.user.User; import org.identityconnectors.framework.common.objects.Attribute; import org.identityconnectors.framework.common.objects.AttributeBuilder; import org.identityconnectors.framework.common.objects.AttributeUtil; @@ -73,6 +74,9 @@ public class PropagationManagerImpl implements PropagationManager { protected static final Logger LOG = LoggerFactory.getLogger(PropagationManager.class); @Autowired + protected VirSchemaDAO virSchemaDAO; + + @Autowired protected AnyObjectDAO anyObjectDAO; /** @@ -103,13 +107,10 @@ public class PropagationManagerImpl implements PropagationManager { protected ConnObjectUtils connObjectUtils; @Autowired - protected VirAttrHandler virAttrHandler; - - @Autowired protected MappingUtils mappingUtils; - protected Any<?, ?, ?> find(final AnyTypeKind kind, final Long key) { - AnyDAO<? extends Any<?, ?, ?>> dao; + protected Any<?, ?> find(final AnyTypeKind kind, final Long key) { + AnyDAO<? extends Any<?, ?>> dao; switch (kind) { case ANY_OBJECT: dao = anyObjectDAO; @@ -135,12 +136,7 @@ public class PropagationManagerImpl implements PropagationManager { final Collection<AttrTO> vAttrs, final Collection<String> noPropResourceNames) { - Any<?, ?, ?> any = find(kind, key); - if (vAttrs != null && !vAttrs.isEmpty()) { - virAttrHandler.createVirtual(any, vAttrs); - } - - return getCreateTasks(any, null, null, propByRes, noPropResourceNames); + return getCreateTasks(find(kind, key), null, null, propByRes, vAttrs, noPropResourceNames); } @Override @@ -152,19 +148,15 @@ public class PropagationManagerImpl implements PropagationManager { final Collection<AttrTO> vAttrs, final Collection<String> noPropResourceNames) { - User user = userDAO.authFind(key); - if (vAttrs != null && !vAttrs.isEmpty()) { - virAttrHandler.createVirtual(user, vAttrs); - } - - return getCreateTasks(user, password, enable, propByRes, noPropResourceNames); + return getCreateTasks(userDAO.authFind(key), password, enable, propByRes, vAttrs, noPropResourceNames); } protected List<PropagationTask> getCreateTasks( - final Any<?, ?, ?> any, + final Any<?, ?> any, final String password, final Boolean enable, final PropagationByResource propByRes, + final Collection<AttrTO> vAttrs, final Collection<String> noPropResourceNames) { if (propByRes == null || propByRes.isEmpty()) { @@ -175,7 +167,7 @@ public class PropagationManagerImpl implements PropagationManager { propByRes.get(ResourceOperation.CREATE).removeAll(noPropResourceNames); } - return createTasks(any, password, true, null, enable, false, propByRes); + return createTasks(any, password, true, enable, false, propByRes, vAttrs); } @Override @@ -185,7 +177,7 @@ public class PropagationManagerImpl implements PropagationManager { final boolean changePwd, final Boolean enable, final PropagationByResource propByRes, - final Collection<AttrPatch> vAttrs, + final Collection<AttrTO> vAttrs, final Collection<String> noPropResourceNames) { return getUpdateTasks(find(kind, key), null, changePwd, enable, propByRes, vAttrs, noPropResourceNames); @@ -257,31 +249,19 @@ public class PropagationManagerImpl implements PropagationManager { } protected List<PropagationTask> getUpdateTasks( - final Any<?, ?, ?> any, + final Any<?, ?> any, final String password, final boolean changePwd, final Boolean enable, final PropagationByResource propByRes, - final Collection<AttrPatch> vAttrs, + final Collection<AttrTO> vAttrs, final Collection<String> noPropResourceNames) { - PropagationByResource localPropByRes = virAttrHandler.updateVirtual( - any, - vAttrs == null ? Collections.<AttrPatch>emptySet() : vAttrs); - localPropByRes.merge(propByRes); if (noPropResourceNames != null) { - localPropByRes.removeAll(noPropResourceNames); - } - - Map<String, AttrPatch> vAttrsMap = null; - if (vAttrs != null) { - vAttrsMap = new HashMap<>(); - for (AttrPatch attrPatch : vAttrs) { - vAttrsMap.put(attrPatch.getAttrTO().getSchema(), attrPatch); - } + propByRes.removeAll(noPropResourceNames); } - return createTasks(any, password, changePwd, vAttrsMap, enable, false, localPropByRes); + return createTasks(any, password, changePwd, enable, false, propByRes, vAttrs); } @Override @@ -291,7 +271,7 @@ public class PropagationManagerImpl implements PropagationManager { final PropagationByResource propByRes, final Collection<String> noPropResourceNames) { - Any<?, ?, ?> any = find(kind, key); + Any<?, ?> any = find(kind, key); PropagationByResource localPropByRes = new PropagationByResource(); @@ -309,109 +289,143 @@ public class PropagationManagerImpl implements PropagationManager { } protected List<PropagationTask> getDeleteTasks( - final Any<?, ?, ?> any, + final Any<?, ?> any, final PropagationByResource propByRes, final Collection<String> noPropResourceNames) { - return createTasks(any, null, false, null, false, true, propByRes); + return createTasks(any, null, false, false, true, propByRes, null); } /** * Create propagation tasks. * - * @param any user / group to be provisioned - * @param password cleartext password to be provisioned + * @param any to be provisioned + * @param password clear text password to be provisioned * @param changePwd whether password should be included for propagation attributes or not - * @param vAttrs virtual attributes to be maaged * @param enable whether user must be enabled or not - * @param deleteOnResource whether user / group must be deleted anyway from external resource or not + * @param deleteOnResource whether any must be deleted anyway from external resource or not * @param propByRes operation to be performed per resource + * @param vAttrs virtual attributes to be set * @return list of propagation tasks created */ - protected List<PropagationTask> createTasks(final Any<?, ?, ?> any, + protected List<PropagationTask> createTasks(final Any<?, ?> any, final String password, final boolean changePwd, - final Map<String, AttrPatch> vAttrs, - final Boolean enable, final boolean deleteOnResource, final PropagationByResource propByRes) { + final Boolean enable, final boolean deleteOnResource, final PropagationByResource propByRes, + final Collection<AttrTO> vAttrs) { - LOG.debug("Provisioning any {}:\n{}", any, propByRes); + LOG.debug("Provisioning {}:\n{}", any, propByRes); - if (!propByRes.get(ResourceOperation.CREATE).isEmpty() && vAttrs != null) { - virAttrHandler.retrieveVirAttrValues(any); + // Avoid duplicates - see javadoc + propByRes.purge(); + LOG.debug("After purge {}:\n{}", any, propByRes); + + // Virtual attributes + Set<String> virtualResources = new HashSet<>(); + virtualResources.addAll(propByRes.get(ResourceOperation.CREATE)); + virtualResources.addAll(propByRes.get(ResourceOperation.UPDATE)); + if (any instanceof User) { + virtualResources.addAll(userDAO.findAllResourceNames((User) any)); + } else if (any instanceof AnyObject) { + virtualResources.addAll(anyObjectDAO.findAllResourceNames((AnyObject) any)); + } else { + virtualResources.addAll(((Group) any).getResourceNames()); + } - // update vAttrsToBeUpdated as well - for (VirAttr<?> virAttr : any.getVirAttrs()) { - String schema = virAttr.getSchema().getKey(); + Map<String, Set<Attribute>> vAttrMap = new HashMap<>(); + for (AttrTO vAttr : CollectionUtils.emptyIfNull(vAttrs)) { + VirSchema schema = virSchemaDAO.find(vAttr.getSchema()); + if (schema == null) { + LOG.warn("Ignoring invalid {} {}", VirSchema.class.getSimpleName(), vAttr.getSchema()); + } else if (schema.isReadonly()) { + LOG.warn("Ignoring read-only {} {}", VirSchema.class.getSimpleName(), vAttr.getSchema()); + } else { + if (any.getAllowedVirSchemas().contains(schema) + && virtualResources.contains(schema.getProvision().getResource().getKey())) { + + Set<Attribute> values = vAttrMap.get(schema.getProvision().getResource().getKey()); + if (values == null) { + values = new HashSet<>(); + vAttrMap.put(schema.getProvision().getResource().getKey(), values); + } + values.add(AttributeBuilder.build(schema.getExtAttrName(), vAttr.getValues())); - vAttrs.put(schema, new AttrPatch.Builder(). - attrTO(new AttrTO.Builder().schema(schema).values(virAttr.getValues()).build()). - build()); + propByRes.add(ResourceOperation.UPDATE, schema.getProvision().getResource().getKey()); + } else { + LOG.warn("{} not owned by or {} not allowed for {}", + schema.getProvision().getResource(), schema, any); + } } } - - // Avoid duplicates - see javadoc - propByRes.purge(); - LOG.debug("After purge: {}", propByRes); + LOG.debug("With virtual attributes {}:\n{}\n{}", any, propByRes, vAttrMap); List<PropagationTask> tasks = new ArrayList<>(); - for (ResourceOperation operation : ResourceOperation.values()) { - for (String resourceName : propByRes.get(operation)) { - ExternalResource resource = resourceDAO.find(resourceName); - Provision provision = resource == null ? null : resource.getProvision(any.getType()); - if (resource == null) { - LOG.error("Invalid resource name specified: {}, ignoring...", resourceName); - } else if (provision == null) { - LOG.error("No provision specified on resource {} for type {}, ignoring...", - resource, any.getType()); - } else if (MappingUtils.getPropagationMappingItems(provision).isEmpty()) { - LOG.warn("Requesting propagation for {} but no propagation mapping provided for {}", - any.getType(), resource); - } else { - PropagationTask task = entityFactory.newEntity(PropagationTask.class); - task.setResource(resource); - task.setObjectClassName( - resource.getProvision(any.getType()).getObjectClass().getObjectClassValue()); - task.setAnyTypeKind(any.getType().getKind()); - if (!deleteOnResource) { - task.setAnyKey(any.getKey()); - } - task.setOperation(operation); - task.setOldConnObjectKey(propByRes.getOldConnObjectKey(resource.getKey())); - - Pair<String, Set<Attribute>> preparedAttrs = mappingUtils.prepareAttrs( - any, password, changePwd, vAttrs, enable, provision); - task.setConnObjectKey(preparedAttrs.getKey()); - - // Check if any of mandatory attributes (in the mapping) is missing or not received any value: - // if so, add special attributes that will be evaluated by PropagationTaskExecutor - List<String> mandatoryMissing = new ArrayList<>(); - List<String> mandatoryNullOrEmpty = new ArrayList<>(); - for (MappingItem item : MappingUtils.getPropagationMappingItems(provision)) { - if (!item.isConnObjectKey() - && JexlUtils.evaluateMandatoryCondition(item.getMandatoryCondition(), any)) { - - Attribute attr = AttributeUtil.find(item.getExtAttrName(), preparedAttrs.getValue()); - if (attr == null) { - mandatoryMissing.add(item.getExtAttrName()); - } else if (attr.getValue() == null || attr.getValue().isEmpty()) { - mandatoryNullOrEmpty.add(item.getExtAttrName()); - } + for (Map.Entry<String, ResourceOperation> entry : propByRes.asMap().entrySet()) { + ExternalResource resource = resourceDAO.find(entry.getKey()); + Provision provision = resource == null ? null : resource.getProvision(any.getType()); + List<MappingItem> mappingItems = provision == null + ? Collections.<MappingItem>emptyList() + : MappingUtils.getPropagationMappingItems(provision); + + if (resource == null) { + LOG.error("Invalid resource name specified: {}, ignoring...", entry.getKey()); + } else if (provision == null) { + LOG.error("No provision specified on resource {} for type {}, ignoring...", + resource, any.getType()); + } else if (mappingItems.isEmpty()) { + LOG.warn("Requesting propagation for {} but no propagation mapping provided for {}", + any.getType(), resource); + } else { + PropagationTask task = entityFactory.newEntity(PropagationTask.class); + task.setResource(resource); + task.setObjectClassName( + resource.getProvision(any.getType()).getObjectClass().getObjectClassValue()); + task.setAnyTypeKind(any.getType().getKind()); + task.setAnyType(any.getType().getKey()); + if (!deleteOnResource) { + task.setAnyKey(any.getKey()); + } + task.setOperation(entry.getValue()); + task.setOldConnObjectKey(propByRes.getOldConnObjectKey(resource.getKey())); + + Pair<String, Set<Attribute>> preparedAttrs = + mappingUtils.prepareAttrs(any, password, changePwd, enable, provision); + task.setConnObjectKey(preparedAttrs.getKey()); + + // Check if any of mandatory attributes (in the mapping) is missing or not received any value: + // if so, add special attributes that will be evaluated by PropagationTaskExecutor + List<String> mandatoryMissing = new ArrayList<>(); + List<String> mandatoryNullOrEmpty = new ArrayList<>(); + for (MappingItem item : mappingItems) { + if (!item.isConnObjectKey() + && JexlUtils.evaluateMandatoryCondition(item.getMandatoryCondition(), any)) { + + Attribute attr = AttributeUtil.find(item.getExtAttrName(), preparedAttrs.getValue()); + if (attr == null) { + mandatoryMissing.add(item.getExtAttrName()); + } else if (attr.getValue() == null || attr.getValue().isEmpty()) { + mandatoryNullOrEmpty.add(item.getExtAttrName()); } } - if (!mandatoryMissing.isEmpty()) { - preparedAttrs.getValue().add(AttributeBuilder.build( - PropagationTaskExecutor.MANDATORY_MISSING_ATTR_NAME, mandatoryMissing)); - } - if (!mandatoryNullOrEmpty.isEmpty()) { - preparedAttrs.getValue().add(AttributeBuilder.build( - PropagationTaskExecutor.MANDATORY_NULL_OR_EMPTY_ATTR_NAME, mandatoryNullOrEmpty)); - } - - task.setAttributes(preparedAttrs.getValue()); - tasks.add(task); + } + if (!mandatoryMissing.isEmpty()) { + preparedAttrs.getValue().add(AttributeBuilder.build( + PropagationTaskExecutor.MANDATORY_MISSING_ATTR_NAME, mandatoryMissing)); + } + if (!mandatoryNullOrEmpty.isEmpty()) { + preparedAttrs.getValue().add(AttributeBuilder.build( + PropagationTaskExecutor.MANDATORY_NULL_OR_EMPTY_ATTR_NAME, mandatoryNullOrEmpty)); + } - LOG.debug("PropagationTask created: {}", task); + if (vAttrMap.containsKey(resource.getKey())) { + preparedAttrs.getValue().addAll(vAttrMap.get(resource.getKey())); } + + task.setAttributes(preparedAttrs.getValue()); + + tasks.add(task); + + LOG.debug("PropagationTask created: {}", task); } }
http://git-wip-us.apache.org/repos/asf/syncope/blob/9cd92305/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/sync/AbstractPushResultHandler.java ---------------------------------------------------------------------- diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/sync/AbstractPushResultHandler.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/sync/AbstractPushResultHandler.java index 94936eb..dcce5e5 100644 --- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/sync/AbstractPushResultHandler.java +++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/sync/AbstractPushResultHandler.java @@ -20,25 +20,19 @@ package org.apache.syncope.core.provisioning.java.sync; import java.util.ArrayList; import java.util.Collection; -import java.util.Collections; -import java.util.HashSet; import java.util.List; -import java.util.Set; +import org.apache.commons.collections4.IteratorUtils; import org.apache.commons.lang3.exception.ExceptionUtils; import org.apache.syncope.common.lib.patch.AnyPatch; -import org.apache.syncope.common.lib.patch.AttrPatch; import org.apache.syncope.common.lib.patch.StringPatchItem; import org.apache.syncope.common.lib.to.AnyTO; -import org.apache.syncope.common.lib.to.AttrTO; import org.apache.syncope.common.lib.types.AuditElements; import org.apache.syncope.common.lib.types.AuditElements.Result; -import org.apache.syncope.common.lib.types.IntMappingType; import org.apache.syncope.common.lib.types.MatchingRule; import org.apache.syncope.common.lib.types.PatchOperation; import org.apache.syncope.common.lib.types.PropagationByResource; import org.apache.syncope.common.lib.types.ResourceOperation; import org.apache.syncope.common.lib.types.UnmatchingRule; -import org.apache.syncope.core.persistence.api.entity.VirAttr; import org.apache.syncope.core.persistence.api.entity.task.PushTask; import org.apache.syncope.core.persistence.api.entity.user.User; import org.apache.syncope.core.provisioning.api.sync.ProvisioningResult; @@ -48,7 +42,6 @@ import org.apache.syncope.core.persistence.api.entity.Any; import org.apache.syncope.core.persistence.api.entity.AnyUtils; import org.apache.syncope.core.persistence.api.entity.anyobject.AnyObject; import org.apache.syncope.core.persistence.api.entity.group.Group; -import org.apache.syncope.core.persistence.api.entity.resource.Mapping; import org.apache.syncope.core.persistence.api.entity.resource.MappingItem; import org.apache.syncope.core.persistence.api.entity.resource.Provision; import org.apache.syncope.core.provisioning.api.TimeoutException; @@ -68,9 +61,9 @@ public abstract class AbstractPushResultHandler extends AbstractSyncopeResultHan @Autowired protected MappingUtils mappingUtils; - protected abstract String getName(Any<?, ?, ?> any); + protected abstract String getName(Any<?, ?> any); - protected void deprovision(final Any<?, ?, ?> any) { + protected void deprovision(final Any<?, ?> any) { AnyTO before = getAnyTO(any.getKey()); List<String> noPropResources = new ArrayList<>(before.getResources()); @@ -83,7 +76,7 @@ public abstract class AbstractPushResultHandler extends AbstractSyncopeResultHan noPropResources)); } - protected void provision(final Any<?, ?, ?> any, final Boolean enabled) { + protected void provision(final Any<?, ?> any, final Boolean enabled) { AnyTO before = getAnyTO(any.getKey()); List<String> noPropResources = new ArrayList<>(before.getResources()); @@ -101,7 +94,7 @@ public abstract class AbstractPushResultHandler extends AbstractSyncopeResultHan } @SuppressWarnings("unchecked") - protected void link(final Any<?, ?, ?> any, final Boolean unlink) { + protected void link(final Any<?, ?> any, final Boolean unlink) { AnyPatch patch = newPatch(any.getKey()); patch.getResources().add(new StringPatchItem.Builder(). operation(unlink ? PatchOperation.DELETE : PatchOperation.ADD_REPLACE). @@ -111,7 +104,7 @@ public abstract class AbstractPushResultHandler extends AbstractSyncopeResultHan } @SuppressWarnings("unchecked") - protected void unassign(final Any<?, ?, ?> any) { + protected void unassign(final Any<?, ?> any) { AnyPatch patch = newPatch(any.getKey()); patch.getResources().add(new StringPatchItem.Builder(). operation(PatchOperation.DELETE). @@ -122,7 +115,7 @@ public abstract class AbstractPushResultHandler extends AbstractSyncopeResultHan deprovision(any); } - protected void assign(final Any<?, ?, ?> any, final Boolean enabled) { + protected void assign(final Any<?, ?> any, final Boolean enabled) { AnyPatch patch = newPatch(any.getKey()); patch.getResources().add(new StringPatchItem.Builder(). operation(PatchOperation.ADD_REPLACE). @@ -141,7 +134,7 @@ public abstract class AbstractPushResultHandler extends AbstractSyncopeResultHan obj = profile.getConnector().getObject( objectClass, uid, - profile.getConnector().getOperationOptions(Collections.<MappingItem>emptySet())); + profile.getConnector().getOperationOptions(IteratorUtils.<MappingItem>emptyIterator())); } catch (TimeoutException toe) { LOG.debug("Request timeout", toe); throw toe; @@ -155,7 +148,7 @@ public abstract class AbstractPushResultHandler extends AbstractSyncopeResultHan @Transactional(propagation = Propagation.REQUIRES_NEW) @Override public boolean handle(final long anyKey) { - Any<?, ?, ?> any = null; + Any<?, ?> any = null; try { any = getAny(anyKey); doHandle(any); @@ -176,7 +169,7 @@ public abstract class AbstractPushResultHandler extends AbstractSyncopeResultHan } } - protected final void doHandle(final Any<?, ?, ?> any) throws JobExecutionException { + protected final void doHandle(final Any<?, ?> any) throws JobExecutionException { AnyUtils anyUtils = anyUtilsFactory.getInstance(any); ProvisioningResult result = new ProvisioningResult(); @@ -406,33 +399,7 @@ public abstract class AbstractPushResultHandler extends AbstractSyncopeResultHan } } - protected Any<?, ?, ?> update(final Any<?, ?, ?> any, final Boolean enabled) { - Set<AttrPatch> vattrs = new HashSet<>(); - - // Search for all mapped vattrs - Mapping mapping = profile.getTask().getResource().getProvision(any.getType()).getMapping(); - for (MappingItem mappingItem : mapping.getItems()) { - if (mappingItem.getIntMappingType() == IntMappingType.UserVirtualSchema) { - vattrs.add(new AttrPatch.Builder(). - operation(PatchOperation.DELETE). - attrTO(new AttrTO.Builder().schema(mappingItem.getIntAttrName()).build()). - build()); - } - } - - // Search for all user's vattrs and: - // 1. add mapped vattrs not owned by the user to the set of vattrs to be removed - // 2. add all vattrs owned by the user to the set of vattrs to be update - for (VirAttr<?> vattr : any.getVirAttrs()) { - vattrs.add(new AttrPatch.Builder(). - operation(PatchOperation.ADD_REPLACE). - attrTO(new AttrTO.Builder(). - schema(vattr.getSchema().getKey()). - values(vattr.getValues()). - build()). - build()); - } - + protected Any<?, ?> update(final Any<?, ?> any, final Boolean enabled) { boolean changepwd; Collection<String> resourceNames; if (any instanceof User) { @@ -458,7 +425,7 @@ public abstract class AbstractPushResultHandler extends AbstractSyncopeResultHan changepwd, null, propByRes, - vattrs, + null, noPropResources)); return getAny(any.getKey()); http://git-wip-us.apache.org/repos/asf/syncope/blob/9cd92305/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/sync/AbstractSyncResultHandler.java ---------------------------------------------------------------------- diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/sync/AbstractSyncResultHandler.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/sync/AbstractSyncResultHandler.java index 2ca7eaa..3967f2b 100644 --- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/sync/AbstractSyncResultHandler.java +++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/sync/AbstractSyncResultHandler.java @@ -38,12 +38,17 @@ import org.apache.syncope.core.persistence.api.entity.task.SyncTask; import org.apache.syncope.core.provisioning.api.propagation.PropagationException; import org.apache.syncope.core.provisioning.api.sync.SyncActions; import org.apache.syncope.core.misc.security.DelegatedAdministrationException; +import org.apache.syncope.core.persistence.api.dao.VirSchemaDAO; import org.apache.syncope.core.persistence.api.entity.AnyUtils; +import org.apache.syncope.core.persistence.api.entity.VirSchema; import org.apache.syncope.core.persistence.api.entity.resource.Provision; import org.apache.syncope.core.provisioning.api.ProvisioningManager; +import org.apache.syncope.core.provisioning.api.cache.VirAttrCache; +import org.apache.syncope.core.provisioning.api.cache.VirAttrCacheValue; import org.apache.syncope.core.provisioning.api.sync.IgnoreProvisionException; import org.apache.syncope.core.provisioning.api.sync.ProvisioningResult; import org.apache.syncope.core.provisioning.api.sync.SyncopeSyncResultHandler; +import org.identityconnectors.framework.common.objects.Attribute; import org.identityconnectors.framework.common.objects.SyncDelta; import org.identityconnectors.framework.common.objects.SyncDeltaType; import org.quartz.JobExecutionException; @@ -57,6 +62,12 @@ public abstract class AbstractSyncResultHandler extends AbstractSyncopeResultHan @Autowired protected SyncUtils syncUtilities; + @Autowired + protected VirSchemaDAO virSchemaDAO; + + @Autowired + protected VirAttrCache virAttrCache; + protected abstract String getName(AnyTO anyTO); protected abstract ProvisioningManager<?, ?> getProvisioningManager(); @@ -656,6 +667,8 @@ public abstract class AbstractSyncResultHandler extends AbstractSyncopeResultHan try { List<Long> anyKeys = syncUtilities.findExisting(uid, delta.getObject(), provision, anyUtils); + LOG.debug("Match(es) found for {} as {}: {}", + delta.getUid().getUidValue(), delta.getObject().getObjectClass(), anyKeys); if (anyKeys.size() > 1) { switch (profile.getResAct()) { @@ -671,7 +684,7 @@ public abstract class AbstractSyncResultHandler extends AbstractSyncopeResultHan break; default: - // keep anyIds as is + // keep anyKeys unmodified } } @@ -694,25 +707,52 @@ public abstract class AbstractSyncResultHandler extends AbstractSyncopeResultHan // do nothing } } else { + // update VirAttrCache + for (VirSchema virSchema : virSchemaDAO.findByProvision(provision)) { + Attribute attr = delta.getObject().getAttributeByName(virSchema.getExtAttrName()); + for (Long anyKey : anyKeys) { + if (attr == null) { + virAttrCache.expire( + provision.getAnyType().getKey(), + anyKey, + virSchema.getKey()); + } else { + VirAttrCacheValue cacheValue = new VirAttrCacheValue(); + cacheValue.setValues(attr.getValue()); + virAttrCache.put( + provision.getAnyType().getKey(), + anyKey, + virSchema.getKey(), + cacheValue); + } + } + } + switch (profile.getTask().getMatchingRule()) { case UPDATE: profile.getResults().addAll(update(delta, anyKeys, provision)); break; + case DEPROVISION: profile.getResults().addAll(deprovision(delta, anyKeys, provision, false)); break; + case UNASSIGN: profile.getResults().addAll(deprovision(delta, anyKeys, provision, true)); break; + case LINK: profile.getResults().addAll(link(delta, anyKeys, provision, false)); break; + case UNLINK: profile.getResults().addAll(link(delta, anyKeys, provision, true)); break; + case IGNORE: profile.getResults().addAll(ignore(delta, provision, true)); break; + default: // do nothing } http://git-wip-us.apache.org/repos/asf/syncope/blob/9cd92305/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/sync/AbstractSyncopeResultHandler.java ---------------------------------------------------------------------- diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/sync/AbstractSyncopeResultHandler.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/sync/AbstractSyncopeResultHandler.java index 2527d5f..570cb76 100644 --- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/sync/AbstractSyncopeResultHandler.java +++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/sync/AbstractSyncopeResultHandler.java @@ -137,7 +137,7 @@ public abstract class AbstractSyncopeResultHandler<T extends ProvisioningTask, A protected abstract AnyTO getAnyTO(long key); - protected abstract Any<?, ?, ?> getAny(long key); + protected abstract Any<?, ?> getAny(long key); protected abstract AnyPatch newPatch(final long key); http://git-wip-us.apache.org/repos/asf/syncope/blob/9cd92305/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/sync/AnyObjectPushResultHandlerImpl.java ---------------------------------------------------------------------- diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/sync/AnyObjectPushResultHandlerImpl.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/sync/AnyObjectPushResultHandlerImpl.java index 755e818..7d9ab24 100644 --- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/sync/AnyObjectPushResultHandlerImpl.java +++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/sync/AnyObjectPushResultHandlerImpl.java @@ -36,12 +36,12 @@ public class AnyObjectPushResultHandlerImpl extends AbstractPushResultHandler im } @Override - protected String getName(final Any<?, ?, ?> any) { + protected String getName(final Any<?, ?> any) { return StringUtils.EMPTY; } @Override - protected Any<?, ?, ?> getAny(final long key) { + protected Any<?, ?> getAny(final long key) { try { return anyObjectDAO.authFind(key); } catch (Exception e) { http://git-wip-us.apache.org/repos/asf/syncope/blob/9cd92305/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/sync/AnyObjectSyncResultHandlerImpl.java ---------------------------------------------------------------------- diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/sync/AnyObjectSyncResultHandlerImpl.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/sync/AnyObjectSyncResultHandlerImpl.java index 02f0b67..079529d 100644 --- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/sync/AnyObjectSyncResultHandlerImpl.java +++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/sync/AnyObjectSyncResultHandlerImpl.java @@ -54,7 +54,7 @@ public class AnyObjectSyncResultHandlerImpl extends AbstractSyncResultHandler im } @Override - protected Any<?, ?, ?> getAny(final long key) { + protected Any<?, ?> getAny(final long key) { try { return anyObjectDAO.authFind(key); } catch (Exception e) { http://git-wip-us.apache.org/repos/asf/syncope/blob/9cd92305/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/sync/DefaultPushActions.java ---------------------------------------------------------------------- diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/sync/DefaultPushActions.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/sync/DefaultPushActions.java index a99b3e5..15f06e0 100644 --- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/sync/DefaultPushActions.java +++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/sync/DefaultPushActions.java @@ -34,49 +34,49 @@ public abstract class DefaultPushActions implements PushActions { } @Override - public <A extends Any<?, ?, ?>> A beforeAssign(final ProvisioningProfile<?, ?> profile, final A any) + public <A extends Any<?, ?>> A beforeAssign(final ProvisioningProfile<?, ?> profile, final A any) throws JobExecutionException { return any; } @Override - public <A extends Any<?, ?, ?>> A beforeProvision(final ProvisioningProfile<?, ?> profile, final A any) + public <A extends Any<?, ?>> A beforeProvision(final ProvisioningProfile<?, ?> profile, final A any) throws JobExecutionException { return any; } @Override - public <A extends Any<?, ?, ?>> A beforeLink(final ProvisioningProfile<?, ?> profile, final A any) + public <A extends Any<?, ?>> A beforeLink(final ProvisioningProfile<?, ?> profile, final A any) throws JobExecutionException { return any; } @Override - public <A extends Any<?, ?, ?>> A beforeUnassign(final ProvisioningProfile<?, ?> profile, final A any) + public <A extends Any<?, ?>> A beforeUnassign(final ProvisioningProfile<?, ?> profile, final A any) throws JobExecutionException { return any; } @Override - public <A extends Any<?, ?, ?>> A beforeDeprovision(final ProvisioningProfile<?, ?> profile, final A any) + public <A extends Any<?, ?>> A beforeDeprovision(final ProvisioningProfile<?, ?> profile, final A any) throws JobExecutionException { return any; } @Override - public <A extends Any<?, ?, ?>> A beforeUnlink(final ProvisioningProfile<?, ?> profile, final A any) + public <A extends Any<?, ?>> A beforeUnlink(final ProvisioningProfile<?, ?> profile, final A any) throws JobExecutionException { return any; } @Override - public <A extends Any<?, ?, ?>> void onError( + public <A extends Any<?, ?>> void onError( final ProvisioningProfile<?, ?> profile, final A any, final ProvisioningResult result, final Exception error) throws JobExecutionException { @@ -84,7 +84,7 @@ public abstract class DefaultPushActions implements PushActions { } @Override - public <A extends Any<?, ?, ?>> void after( + public <A extends Any<?, ?>> void after( final ProvisioningProfile<?, ?> profile, final A any, final ProvisioningResult result) throws JobExecutionException { http://git-wip-us.apache.org/repos/asf/syncope/blob/9cd92305/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/sync/GroupPushResultHandlerImpl.java ---------------------------------------------------------------------- diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/sync/GroupPushResultHandlerImpl.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/sync/GroupPushResultHandlerImpl.java index 2fd1df7..212eb84 100644 --- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/sync/GroupPushResultHandlerImpl.java +++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/sync/GroupPushResultHandlerImpl.java @@ -36,12 +36,12 @@ public class GroupPushResultHandlerImpl extends AbstractPushResultHandler implem } @Override - protected String getName(final Any<?, ?, ?> any) { + protected String getName(final Any<?, ?> any) { return Group.class.cast(any).getName(); } @Override - protected Any<?, ?, ?> getAny(final long key) { + protected Any<?, ?> getAny(final long key) { try { return groupDAO.authFind(key); } catch (Exception e) { http://git-wip-us.apache.org/repos/asf/syncope/blob/9cd92305/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/sync/GroupSyncResultHandlerImpl.java ---------------------------------------------------------------------- diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/sync/GroupSyncResultHandlerImpl.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/sync/GroupSyncResultHandlerImpl.java index 2d803b2..c3b9eda 100644 --- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/sync/GroupSyncResultHandlerImpl.java +++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/sync/GroupSyncResultHandlerImpl.java @@ -63,7 +63,7 @@ public class GroupSyncResultHandlerImpl extends AbstractSyncResultHandler implem } @Override - protected Any<?, ?, ?> getAny(final long key) { + protected Any<?, ?> getAny(final long key) { try { return groupDAO.authFind(key); } catch (Exception e) { http://git-wip-us.apache.org/repos/asf/syncope/blob/9cd92305/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/sync/PushJobDelegate.java ---------------------------------------------------------------------- diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/sync/PushJobDelegate.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/sync/PushJobDelegate.java index ff6ff21..e13407d 100644 --- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/sync/PushJobDelegate.java +++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/sync/PushJobDelegate.java @@ -145,13 +145,13 @@ public class PushJobDelegate extends AbstractProvisioningJobDelegate<PushTask> { int count = anyDAO.count(SyncopeConstants.FULL_ADMIN_REALMS); for (int page = 1; page <= (count / PAGE_SIZE) + 1; page++) { - List<? extends Any<?, ?, ?>> localAnys = StringUtils.isBlank(filter) + List<? extends Any<?, ?>> localAnys = StringUtils.isBlank(filter) ? anyDAO.findAll(SyncopeConstants.FULL_ADMIN_REALMS, page, PAGE_SIZE) : searchDAO.search(SyncopeConstants.FULL_ADMIN_REALMS, SearchCondConverter.convert(filter), Collections.<OrderByClause>emptyList(), provision.getAnyType().getKind()); - for (Any<?, ?, ?> any : localAnys) { + for (Any<?, ?> any : localAnys) { SyncopePushResultHandler handler; switch (provision.getAnyType().getKind()) { case USER: http://git-wip-us.apache.org/repos/asf/syncope/blob/9cd92305/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 3f19afc..890cece 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 @@ -19,15 +19,22 @@ package org.apache.syncope.core.provisioning.java.sync; import java.util.ArrayList; +import java.util.HashSet; +import java.util.Iterator; import java.util.List; import java.util.Map; +import java.util.Set; +import org.apache.commons.collections4.IteratorUtils; import org.apache.commons.lang3.StringUtils; import org.apache.syncope.common.lib.policy.SyncPolicySpec; import org.apache.syncope.core.misc.spring.ApplicationContextProvider; import org.apache.syncope.core.persistence.api.dao.GroupDAO; import org.apache.syncope.core.persistence.api.dao.NotFoundException; import org.apache.syncope.core.persistence.api.dao.UserDAO; +import org.apache.syncope.core.persistence.api.dao.VirSchemaDAO; +import org.apache.syncope.core.persistence.api.entity.VirSchema; import org.apache.syncope.core.persistence.api.entity.group.Group; +import org.apache.syncope.core.persistence.api.entity.resource.MappingItem; import org.apache.syncope.core.persistence.api.entity.resource.Provision; import org.apache.syncope.core.persistence.api.entity.task.ProvisioningTask; import org.apache.syncope.core.persistence.api.entity.task.SyncTask; @@ -52,6 +59,9 @@ public class SyncJobDelegate extends AbstractProvisioningJobDelegate<SyncTask> { private GroupDAO groupDAO; @Autowired + private VirSchemaDAO virSchemaDAO; + + @Autowired protected SyncUtils syncUtils; protected void setGroupOwners(final GroupSyncResultHandler ghandler) { @@ -163,12 +173,25 @@ public class SyncJobDelegate extends AbstractProvisioningJobDelegate<SyncTask> { latestSyncToken = connector.getLatestSyncToken(provision.getObjectClass()); } + Set<MappingItem> linkinMappingItems = new HashSet<>(); + for (VirSchema virSchema : virSchemaDAO.findByProvision(provision)) { + linkinMappingItems.add(virSchema.asLinkingMappingItem()); + } + Iterator<MappingItem> mapItems = IteratorUtils.chainedIterator( + provision.getMapping().getItems().iterator(), + linkinMappingItems.iterator()); + if (syncTask.isFullReconciliation()) { - connector.getAllObjects(provision.getObjectClass(), handler, - connector.getOperationOptions(provision.getMapping().getItems())); + connector.getAllObjects( + provision.getObjectClass(), + handler, + connector.getOperationOptions(mapItems)); } else { - connector.sync(provision.getObjectClass(), provision.getSyncToken(), handler, - connector.getOperationOptions(provision.getMapping().getItems())); + connector.sync( + provision.getObjectClass(), + provision.getSyncToken(), + handler, + connector.getOperationOptions(mapItems)); } if (!dryRun && !syncTask.isFullReconciliation()) { http://git-wip-us.apache.org/repos/asf/syncope/blob/9cd92305/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/sync/SyncUtils.java ---------------------------------------------------------------------- diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/sync/SyncUtils.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/sync/SyncUtils.java index 0c01254..eefccad 100644 --- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/sync/SyncUtils.java +++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/sync/SyncUtils.java @@ -128,7 +128,7 @@ public class SyncUtils { return found.add(obj); } }, - connector.getOperationOptions(MappingUtils.getSyncMappingItems(provision))); + connector.getOperationOptions(MappingUtils.getSyncMappingItems(provision).iterator())); if (found.isEmpty()) { LOG.debug("No {} found on {} with __NAME__ {}", provision.getObjectClass(), resource, name); @@ -199,9 +199,9 @@ public class SyncUtils { } } - List<? extends Any<?, ?, ?>> anys = + List<? extends Any<?, ?>> anys = getAnyDAO(connObjectKeyItem).findByAttrValue(connObjectKeyItem.getIntAttrName(), value); - for (Any<?, ?, ?> any : anys) { + for (Any<?, ?> any : anys) { result.add(any.getKey()); } break; @@ -210,7 +210,7 @@ public class SyncUtils { case GroupDerivedSchema: case AnyObjectDerivedSchema: anys = getAnyDAO(connObjectKeyItem).findByDerAttrValue(connObjectKeyItem.getIntAttrName(), transfUid); - for (Any<?, ?, ?> any : anys) { + for (Any<?, ?> any : anys) { result.add(any.getKey()); } break; @@ -218,7 +218,7 @@ public class SyncUtils { case UserKey: case GroupKey: case AnyObjectKey: - Any<?, ?, ?> any = getAnyDAO(connObjectKeyItem).find(Long.parseLong(transfUid)); + Any<?, ?> any = getAnyDAO(connObjectKeyItem).find(Long.parseLong(transfUid)); if (any != null) { result.add(any.getKey()); } @@ -249,7 +249,7 @@ public class SyncUtils { final ConnectorObject connObj, final SyncCorrelationRule rule, final AnyTypeKind type) { List<Long> result = new ArrayList<>(); - for (Any<?, ?, ?> any : searchDAO.search( + for (Any<?, ?> any : searchDAO.search( SyncopeConstants.FULL_ADMIN_REALMS, rule.getSearchCond(connObj), Collections.<OrderByClause>emptyList(), http://git-wip-us.apache.org/repos/asf/syncope/blob/9cd92305/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/sync/UserPushResultHandlerImpl.java ---------------------------------------------------------------------- diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/sync/UserPushResultHandlerImpl.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/sync/UserPushResultHandlerImpl.java index 5829216..8f70560 100644 --- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/sync/UserPushResultHandlerImpl.java +++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/sync/UserPushResultHandlerImpl.java @@ -41,7 +41,7 @@ public class UserPushResultHandlerImpl extends AbstractPushResultHandler impleme } @Override - protected void provision(final Any<?, ?, ?> any, final Boolean enabled) { + protected void provision(final Any<?, ?> any, final Boolean enabled) { AnyTO before = getAnyTO(any.getKey()); List<String> noPropResources = new ArrayList<>(before.getResources()); @@ -60,12 +60,12 @@ public class UserPushResultHandlerImpl extends AbstractPushResultHandler impleme } @Override - protected String getName(final Any<?, ?, ?> any) { + protected String getName(final Any<?, ?> any) { return User.class.cast(any).getUsername(); } @Override - protected Any<?, ?, ?> getAny(final long key) { + protected Any<?, ?> getAny(final long key) { try { return userDAO.authFind(key); } catch (Exception e) { http://git-wip-us.apache.org/repos/asf/syncope/blob/9cd92305/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/sync/UserSyncResultHandlerImpl.java ---------------------------------------------------------------------- diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/sync/UserSyncResultHandlerImpl.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/sync/UserSyncResultHandlerImpl.java index c5e918a..23e209c 100644 --- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/sync/UserSyncResultHandlerImpl.java +++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/sync/UserSyncResultHandlerImpl.java @@ -54,7 +54,7 @@ public class UserSyncResultHandlerImpl extends AbstractSyncResultHandler impleme } @Override - protected Any<?, ?, ?> getAny(final long key) { + protected Any<?, ?> getAny(final long key) { try { return userDAO.authFind(key); } catch (Exception e) { http://git-wip-us.apache.org/repos/asf/syncope/blob/9cd92305/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/ThreadLocalCleanupListener.java ---------------------------------------------------------------------- diff --git a/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/ThreadLocalCleanupListener.java b/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/ThreadLocalCleanupListener.java index 39f5573..fe19915 100644 --- a/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/ThreadLocalCleanupListener.java +++ b/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/ThreadLocalCleanupListener.java @@ -20,7 +20,7 @@ package org.apache.syncope.core.rest.cxf; import javax.servlet.ServletRequestEvent; import javax.servlet.ServletRequestListener; -import org.apache.syncope.core.misc.DataFormat; +import org.apache.syncope.core.misc.FormatUtils; import org.identityconnectors.common.l10n.CurrentLocale; import org.identityconnectors.framework.impl.api.local.ThreadClassLoaderManager; @@ -36,7 +36,7 @@ public class ThreadLocalCleanupListener implements ServletRequestListener { @Override public void requestDestroyed(final ServletRequestEvent sre) { - DataFormat.clear(); + FormatUtils.clear(); ThreadClassLoaderManager.clearInstance(); CurrentLocale.clear(); http://git-wip-us.apache.org/repos/asf/syncope/blob/9cd92305/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/AbstractAnyService.java ---------------------------------------------------------------------- diff --git a/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/AbstractAnyService.java b/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/AbstractAnyService.java index d33cde2..4258e64 100644 --- a/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/AbstractAnyService.java +++ b/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/AbstractAnyService.java @@ -179,23 +179,20 @@ public abstract class AbstractAnyService<TO extends AnyTO, P extends AnyPatch> P patch = newPatch(key); - Set<AttrPatch> patches; switch (schemaType) { case DERIVED: - patches = patch.getDerAttrs(); + patch.getDerAttrs().add(new AttrPatch.Builder().operation(operation).attrTO(attrTO).build()); break; case VIRTUAL: - patches = patch.getVirAttrs(); + patch.getVirAttrs().add(attrTO); break; case PLAIN: default: - patches = patch.getPlainAttrs(); + patch.getPlainAttrs().add(new AttrPatch.Builder().operation(operation).attrTO(attrTO).build()); } - patches.add(new AttrPatch.Builder().operation(operation).attrTO(attrTO).build()); - update(patch); } http://git-wip-us.apache.org/repos/asf/syncope/blob/9cd92305/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/processor/AnyObjectUpdateProcessor.java ---------------------------------------------------------------------- diff --git a/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/processor/AnyObjectUpdateProcessor.java b/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/processor/AnyObjectUpdateProcessor.java index 158cc09..3f2b690 100644 --- a/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/processor/AnyObjectUpdateProcessor.java +++ b/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/processor/AnyObjectUpdateProcessor.java @@ -25,7 +25,6 @@ import org.apache.camel.Processor; import org.apache.commons.lang3.tuple.ImmutablePair; import org.apache.syncope.common.lib.patch.AnyObjectPatch; import org.apache.syncope.common.lib.types.AnyTypeKind; -import org.apache.syncope.common.lib.types.PropagationByResource; import org.apache.syncope.core.misc.spring.ApplicationContextProvider; import org.apache.syncope.core.persistence.api.entity.task.PropagationTask; import org.apache.syncope.core.provisioning.api.VirAttrHandler; @@ -60,17 +59,6 @@ public class AnyObjectUpdateProcessor implements Processor { AnyObjectPatch anyObjectPatch = exchange.getProperty("anyPatch", AnyObjectPatch.class); Set<String> excludedResources = exchange.getProperty("excludedResources", Set.class); - // SYNCOPE-459: take care of user virtual attributes ... - PropagationByResource propByResVirAttr = virtAttrHandler.updateVirtual( - updated.getResult(), - AnyTypeKind.ANY_OBJECT, - anyObjectPatch.getVirAttrs()); - if (updated.getPropByRes() == null) { - updated.setPropByRes(propByResVirAttr); - } else { - updated.getPropByRes().merge(propByResVirAttr); - } - List<PropagationTask> tasks = propagationManager.getUpdateTasks( AnyTypeKind.ANY_OBJECT, updated.getResult(), @@ -79,7 +67,6 @@ public class AnyObjectUpdateProcessor implements Processor { updated.getPropByRes(), anyObjectPatch.getVirAttrs(), excludedResources); - PropagationReporter propagationReporter = ApplicationContextProvider.getBeanFactory().getBean(PropagationReporter.class); try { http://git-wip-us.apache.org/repos/asf/syncope/blob/9cd92305/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/processor/GroupUpdateProcessor.java ---------------------------------------------------------------------- diff --git a/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/processor/GroupUpdateProcessor.java b/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/processor/GroupUpdateProcessor.java index 22868bf..599f54b 100644 --- a/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/processor/GroupUpdateProcessor.java +++ b/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/processor/GroupUpdateProcessor.java @@ -25,7 +25,6 @@ import org.apache.camel.Processor; import org.apache.commons.lang3.tuple.ImmutablePair; import org.apache.syncope.common.lib.patch.GroupPatch; import org.apache.syncope.common.lib.types.AnyTypeKind; -import org.apache.syncope.common.lib.types.PropagationByResource; import org.apache.syncope.core.misc.spring.ApplicationContextProvider; import org.apache.syncope.core.persistence.api.entity.task.PropagationTask; import org.apache.syncope.core.provisioning.api.VirAttrHandler; @@ -60,17 +59,6 @@ public class GroupUpdateProcessor implements Processor { GroupPatch groupPatch = exchange.getProperty("anyPatch", GroupPatch.class); Set<String> excludedResources = exchange.getProperty("excludedResources", Set.class); - // SYNCOPE-459: take care of user virtual attributes ... - PropagationByResource propByResVirAttr = virtAttrHandler.updateVirtual( - updated.getResult(), - AnyTypeKind.GROUP, - groupPatch.getVirAttrs()); - if (updated.getPropByRes() == null) { - updated.setPropByRes(propByResVirAttr); - } else { - updated.getPropByRes().merge(propByResVirAttr); - } - List<PropagationTask> tasks = propagationManager.getUpdateTasks( AnyTypeKind.GROUP, updated.getResult(), @@ -79,7 +67,6 @@ public class GroupUpdateProcessor implements Processor { updated.getPropByRes(), groupPatch.getVirAttrs(), excludedResources); - PropagationReporter propagationReporter = ApplicationContextProvider.getBeanFactory().getBean(PropagationReporter.class); try { http://git-wip-us.apache.org/repos/asf/syncope/blob/9cd92305/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/processor/UserUpdateInSyncProcessor.java ---------------------------------------------------------------------- diff --git a/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/processor/UserUpdateInSyncProcessor.java b/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/processor/UserUpdateInSyncProcessor.java index ffdd5d2..8b49a5d 100644 --- a/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/processor/UserUpdateInSyncProcessor.java +++ b/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/processor/UserUpdateInSyncProcessor.java @@ -54,12 +54,10 @@ public class UserUpdateInSyncProcessor implements Processor { WorkflowResult<Pair<UserPatch, Boolean>> updated = (WorkflowResult) exchange.getIn().getBody(); Set<String> excludedResources = exchange.getProperty("excludedResources", Set.class); - PropagationReporter propagationReporter = - ApplicationContextProvider.getBeanFactory().getBean(PropagationReporter.class); - List<PropagationTask> tasks = propagationManager.getUserUpdateTasks( updated, updated.getResult().getKey().getPassword() != null, excludedResources); - + PropagationReporter propagationReporter = + ApplicationContextProvider.getBeanFactory().getBean(PropagationReporter.class); try { taskExecutor.execute(tasks, propagationReporter); } catch (PropagationException e) { http://git-wip-us.apache.org/repos/asf/syncope/blob/9cd92305/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/processor/UserUpdateProcessor.java ---------------------------------------------------------------------- diff --git a/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/processor/UserUpdateProcessor.java b/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/processor/UserUpdateProcessor.java index bd0df76..8f175dd 100644 --- a/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/processor/UserUpdateProcessor.java +++ b/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/processor/UserUpdateProcessor.java @@ -24,8 +24,6 @@ import org.apache.camel.Processor; import org.apache.commons.lang3.tuple.ImmutablePair; import org.apache.commons.lang3.tuple.Pair; import org.apache.syncope.common.lib.patch.UserPatch; -import org.apache.syncope.common.lib.types.AnyTypeKind; -import org.apache.syncope.common.lib.types.PropagationByResource; import org.apache.syncope.core.misc.spring.ApplicationContextProvider; import org.apache.syncope.core.persistence.api.entity.task.PropagationTask; import org.apache.syncope.core.provisioning.api.VirAttrHandler; @@ -57,30 +55,15 @@ public class UserUpdateProcessor implements Processor { @SuppressWarnings("unchecked") public void process(final Exchange exchange) { WorkflowResult<Pair<UserPatch, Boolean>> updated = (WorkflowResult) exchange.getIn().getBody(); - UserPatch userPatch = exchange.getProperty("actual", UserPatch.class); - - // SYNCOPE-459: take care of user virtual attributes ... - PropagationByResource propByResVirAttr = virtAttrHandler.updateVirtual( - updated.getResult().getKey().getKey(), - AnyTypeKind.USER, - userPatch.getVirAttrs()); - if (updated.getPropByRes() == null) { - updated.setPropByRes(propByResVirAttr); - } else { - updated.getPropByRes().merge(propByResVirAttr); - } List<PropagationTask> tasks = propagationManager.getUserUpdateTasks(updated); - PropagationReporter propagationReporter = ApplicationContextProvider.getBeanFactory().getBean(PropagationReporter.class); - if (!tasks.isEmpty()) { - try { - taskExecutor.execute(tasks, propagationReporter); - } catch (PropagationException e) { - LOG.error("Error propagation primary resource", e); - propagationReporter.onPrimaryResourceFailure(tasks); - } + try { + taskExecutor.execute(tasks, propagationReporter); + } catch (PropagationException e) { + LOG.error("Error propagation primary resource", e); + propagationReporter.onPrimaryResourceFailure(tasks); } exchange.getOut().setBody(new ImmutablePair<>( http://git-wip-us.apache.org/repos/asf/syncope/blob/9cd92305/fit/console-reference/pom.xml ---------------------------------------------------------------------- diff --git a/fit/console-reference/pom.xml b/fit/console-reference/pom.xml index b518886..3c89990 100644 --- a/fit/console-reference/pom.xml +++ b/fit/console-reference/pom.xml @@ -457,19 +457,19 @@ ORYX.Editor.createByUrl = function(modelUrl){"/> <resource> <directory>${basedir}/../../core/logic/target/classes</directory> <excludes> - <exclude>*Context.xml</exclude> + <exclude>logicContext.xml</exclude> </excludes> </resource> <resource> <directory>${basedir}/../../core/rest-cxf/target/classes</directory> <excludes> - <exclude>*Context.xml</exclude> + <exclude>restCXFContext.xml</exclude> </excludes> </resource> <resource> <directory>${basedir}/../../core/misc/target/classes</directory> <excludes> - <exclude>*Context.xml</exclude> + <exclude>securityContext.xml</exclude> </excludes> </resource> <resource> @@ -478,7 +478,7 @@ ORYX.Editor.createByUrl = function(modelUrl){"/> <resource> <directory>${basedir}/../../core/persistence-jpa/target/classes</directory> <excludes> - <exclude>*Context.xml</exclude> + <exclude>persistenceContext.xml</exclude> </excludes> </resource> <resource> @@ -487,7 +487,7 @@ ORYX.Editor.createByUrl = function(modelUrl){"/> <resource> <directory>${basedir}/../../core/provisioning-java/target/classes</directory> <excludes> - <exclude>*Context.xml</exclude> + <exclude>provisioningContext.xml</exclude> </excludes> </resource> <resource> @@ -496,85 +496,22 @@ ORYX.Editor.createByUrl = function(modelUrl){"/> <resource> <directory>${basedir}/../../core/workflow-java/target/classes</directory> <excludes> - <exclude>*Context.xml</exclude> + <exclude>workflowContext.xml</exclude> </excludes> </resource> <resource> <directory>${basedir}/../../core/workflow-activiti/target/classes</directory> <excludes> - <exclude>*Context.xml</exclude> + <exclude>workflowActivitiContext.xml</exclude> </excludes> </resource> <resource> <directory>${basedir}/../../ext/camel/provisioning-camel/target/classes</directory> <excludes> - <exclude>*Context.xml</exclude> - </excludes> - </resource> - - <resource> - <directory>${basedir}/../../common/lib/target/classes</directory> - </resource> - <resource> - <directory>${basedir}/../../common/rest-api/target/classes</directory> - </resource> - <resource> - <directory>${basedir}/../../core/logic/target/classes</directory> - <excludes> - <exclude>*Context.xml</exclude> - </excludes> - </resource> - <resource> - <directory>${basedir}/../../core/rest-cxf/target/classes</directory> - <excludes> - <exclude>*Context.xml</exclude> - </excludes> - </resource> - <resource> - <directory>${basedir}/../../core/misc/target/classes</directory> - <excludes> - <exclude>*Context.xml</exclude> - </excludes> - </resource> - <resource> - <directory>${basedir}/../../core/persistence-api/target/classes</directory> - </resource> - <resource> - <directory>${basedir}/../../core/persistence-jpa/target/classes</directory> - <excludes> - <exclude>*Context.xml</exclude> - </excludes> - </resource> - <resource> - <directory>${basedir}/../../core/provisioning-api/target/classes</directory> - </resource> - <resource> - <directory>${basedir}/../../core/provisioning-java/target/classes</directory> - <excludes> - <exclude>*Context.xml</exclude> - </excludes> - </resource> - <resource> - <directory>${basedir}/../../core/workflow-api/target/classes</directory> - </resource> - <resource> - <directory>${basedir}/../../core/workflow-java/target/classes</directory> - <excludes> - <exclude>*Context.xml</exclude> - </excludes> - </resource> - <resource> - <directory>${basedir}/../../core/workflow-activiti/target/classes</directory> - <excludes> - <exclude>*Context.xml</exclude> - </excludes> - </resource> - <resource> - <directory>${basedir}/../../ext/camel/provisioning-camel/target/classes</directory> - <excludes> - <exclude>*Context.xml</exclude> + <exclude>provisioningCamelContext.xml</exclude> </excludes> </resource> + <resource> <directory>${basedir}/../../client/console/target/classes</directory> </resource> http://git-wip-us.apache.org/repos/asf/syncope/blob/9cd92305/fit/core-reference/pom.xml ---------------------------------------------------------------------- diff --git a/fit/core-reference/pom.xml b/fit/core-reference/pom.xml index 7e0fd9f..724f592 100644 --- a/fit/core-reference/pom.xml +++ b/fit/core-reference/pom.xml @@ -758,19 +758,19 @@ under the License. <resource> <directory>${basedir}/../../core/logic/target/classes</directory> <excludes> - <exclude>*Context.xml</exclude> + <exclude>logicContext.xml</exclude> </excludes> </resource> <resource> <directory>${basedir}/../../core/rest-cxf/target/classes</directory> <excludes> - <exclude>*Context.xml</exclude> + <exclude>restCXFContext.xml</exclude> </excludes> </resource> <resource> <directory>${basedir}/../../core/misc/target/classes</directory> <excludes> - <exclude>*Context.xml</exclude> + <exclude>securityContext.xml</exclude> </excludes> </resource> <resource> @@ -779,7 +779,7 @@ under the License. <resource> <directory>${basedir}/../../core/persistence-jpa/target/classes</directory> <excludes> - <exclude>*Context.xml</exclude> + <exclude>persistenceContext.xml</exclude> </excludes> </resource> <resource> @@ -788,7 +788,7 @@ under the License. <resource> <directory>${basedir}/../../core/provisioning-java/target/classes</directory> <excludes> - <exclude>*Context.xml</exclude> + <exclude>provisioningContext.xml</exclude> </excludes> </resource> <resource> @@ -797,19 +797,19 @@ under the License. <resource> <directory>${basedir}/../../core/workflow-java/target/classes</directory> <excludes> - <exclude>*Context.xml</exclude> + <exclude>workflowContext.xml</exclude> </excludes> </resource> <resource> <directory>${basedir}/../../core/workflow-activiti/target/classes</directory> <excludes> - <exclude>*Context.xml</exclude> + <exclude>workflowActivitiContext.xml</exclude> </excludes> </resource> <resource> <directory>${basedir}/../../ext/camel/provisioning-camel/target/classes</directory> <excludes> - <exclude>*Context.xml</exclude> + <exclude>provisioningCamelContext.xml</exclude> </excludes> </resource> </resources> http://git-wip-us.apache.org/repos/asf/syncope/blob/9cd92305/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/GroupITCase.java ---------------------------------------------------------------------- diff --git a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/GroupITCase.java b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/GroupITCase.java index 1abb943..148f0eb 100644 --- a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/GroupITCase.java +++ b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/GroupITCase.java @@ -59,6 +59,7 @@ import org.apache.syncope.common.lib.to.PlainSchemaTO; import org.apache.syncope.common.lib.to.ResourceTO; import org.apache.syncope.common.lib.to.GroupTO; import org.apache.syncope.common.lib.to.MappingTO; +import org.apache.syncope.common.lib.to.ProvisionTO; import org.apache.syncope.common.lib.to.UserTO; import org.apache.syncope.common.lib.types.AnyTypeKind; import org.apache.syncope.common.lib.types.ClientExceptionType; @@ -218,27 +219,6 @@ public class GroupITCase extends AbstractITCase { } @Test - public void updateRemovingVirAttribute() { - GroupTO groupTO = getBasicSampleTO("withvirtual" + getUUIDString()); - groupTO.getVirAttrs().add(attrTO("rvirtualdata", null)); - - groupTO = createGroup(groupTO); - - assertNotNull(groupTO); - assertEquals(1, groupTO.getVirAttrs().size()); - - GroupPatch groupPatch = new GroupPatch(); - groupPatch.setKey(groupTO.getKey()); - groupPatch.getVirAttrs().add(new AttrPatch.Builder().operation(PatchOperation.DELETE). - attrTO(new AttrTO.Builder().schema("rvirtualdata").build()). - build()); - - groupTO = updateGroup(groupPatch); - assertNotNull(groupTO); - assertTrue(groupTO.getVirAttrs().isEmpty()); - } - - @Test public void updateRemovingDerAttribute() { GroupTO groupTO = getBasicSampleTO("withderived" + getUUIDString()); groupTO.getDerAttrs().add(attrTO("rderivedschema", null)); @@ -638,6 +618,10 @@ public class GroupITCase extends AbstractITCase { newLDAP.setKey("new-ldap"); newLDAP.setPropagationPrimary(true); + for (ProvisionTO provision : newLDAP.getProvisions()) { + provision.getVirSchemas().clear(); + } + MappingTO mapping = newLDAP.getProvision(AnyTypeKind.GROUP.name()).getMapping(); MappingItemTO connObjectKey = mapping.getConnObjectKeyItem(); http://git-wip-us.apache.org/repos/asf/syncope/blob/9cd92305/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/PropagationTaskITCase.java ---------------------------------------------------------------------- diff --git a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/PropagationTaskITCase.java b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/PropagationTaskITCase.java index 4115bfa..7f2964f 100644 --- a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/PropagationTaskITCase.java +++ b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/PropagationTaskITCase.java @@ -85,14 +85,6 @@ public class PropagationTaskITCase extends AbstractTaskITCase { } @Test - public void issue196() { - TaskExecTO exec = taskService.execute(6L, false); - assertNotNull(exec); - assertEquals(0, exec.getKey()); - assertNotNull(exec.getTask()); - } - - @Test public void bulkAction() { PagedResult<PropagationTaskTO> before = taskService.list( TaskType.PROPAGATION, SyncopeClient.getTaskQueryBuilder().build()); http://git-wip-us.apache.org/repos/asf/syncope/blob/9cd92305/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/SyncTaskITCase.java ---------------------------------------------------------------------- diff --git a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/SyncTaskITCase.java b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/SyncTaskITCase.java index 75049da..d645c77 100644 --- a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/SyncTaskITCase.java +++ b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/SyncTaskITCase.java @@ -607,6 +607,9 @@ public class SyncTaskITCase extends AbstractTaskITCase { @Test public void issueSYNCOPE307() { UserTO userTO = UserITCase.getUniqueSampleTO("s...@apache.org"); + userTO.setUsername("test0"); + userTO.getPlainAttrMap().get("firstname").getValues().clear(); + userTO.getPlainAttrMap().get("firstname").getValues().add("nome0"); userTO.getAuxClasses().add("csv"); AttrTO csvuserid = new AttrTO(); @@ -615,37 +618,34 @@ public class SyncTaskITCase extends AbstractTaskITCase { userTO.getResources().clear(); userTO.getResources().add(RESOURCE_NAME_WS2); - userTO.getResources().add(RESOURCE_NAME_CSV); userTO = createUser(userTO); assertNotNull(userTO); userTO = userService.read(userTO.getKey()); - assertEquals("virtualvalue", userTO.getVirAttrMap().get("virtualdata").getValues().get(0)); + assertTrue(userTO.getVirAttrMap().isEmpty()); // Update sync task SyncTaskTO task = taskService.read(12L); assertNotNull(task); - // add user template UserTO template = new UserTO(); + template.setPassword("'password123'"); template.getResources().add(RESOURCE_NAME_DBVIRATTR); - - AttrTO userId = attrTO("userId", "'s...@apache.org'"); - template.getPlainAttrs().add(userId); - - AttrTO email = attrTO("email", "'s...@apache.org'"); - template.getPlainAttrs().add(email); + template.getVirAttrs().add(attrTO("virtualdata", "'virtualvalue'")); task.getTemplates().put(AnyTypeKind.USER.name(), template); taskService.update(task); + + // exec task: one user from CSV will match the user created above and template will be applied execProvisioningTask(taskService, task.getKey(), 50, false); - // check for sync policy + // check that template was successfully applied... userTO = userService.read(userTO.getKey()); assertEquals("virtualvalue", userTO.getVirAttrMap().get("virtualdata").getValues().get(0)); + // ...and that propagation to db succeeded try { JdbcTemplate jdbcTemplate = new JdbcTemplate(testDataSource);