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 2014/01/07 15:33:45 UTC
svn commit: r1556227 [3/3] - in /syncope/trunk:
common/src/main/java/org/apache/syncope/common/services/
common/src/main/java/org/apache/syncope/common/to/
common/src/main/java/org/apache/syncope/common/types/
common/src/main/java/org/apache/syncope/co...
Copied: syncope/trunk/core/src/main/java/org/apache/syncope/core/sync/impl/SyncopePushResultHandler.java (from r1554763, 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/SyncopePushResultHandler.java?p2=syncope/trunk/core/src/main/java/org/apache/syncope/core/sync/impl/SyncopePushResultHandler.java&p1=syncope/trunk/core/src/main/java/org/apache/syncope/core/sync/impl/SyncopeSyncResultHandler.java&r1=1554763&r2=1556227&rev=1556227&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/SyncopePushResultHandler.java Tue Jan 7 14:33:44 2014
@@ -18,127 +18,54 @@
*/
package org.apache.syncope.core.sync.impl;
-import java.util.AbstractMap;
+import static org.apache.syncope.core.sync.impl.AbstractSyncopeResultHandler.LOG;
import java.util.ArrayList;
-import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
-import java.util.List;
import java.util.Map;
-import org.apache.commons.lang3.StringUtils;
-import org.apache.syncope.common.mod.AttributeMod;
-import org.apache.syncope.common.mod.RoleMod;
-import org.apache.syncope.common.mod.UserMod;
-import org.apache.syncope.core.persistence.dao.search.AttributableCond;
-import org.apache.syncope.core.persistence.dao.search.AttributeCond;
-import org.apache.syncope.core.persistence.dao.search.SearchCond;
-import org.apache.syncope.common.to.AbstractAttributableTO;
-import org.apache.syncope.common.to.AttributeTO;
-import org.apache.syncope.common.to.RoleTO;
-import org.apache.syncope.common.to.UserTO;
+import java.util.Set;
import org.apache.syncope.common.types.AttributableType;
import org.apache.syncope.common.types.AuditElements;
import org.apache.syncope.common.types.AuditElements.Result;
-import org.apache.syncope.common.types.ConflictResolutionAction;
-import org.apache.syncope.common.types.MappingPurpose;
import org.apache.syncope.common.types.ResourceOperation;
-import org.apache.syncope.common.types.SyncPolicySpec;
import org.apache.syncope.core.audit.AuditManager;
import org.apache.syncope.core.connid.ConnObjectUtil;
import org.apache.syncope.core.notification.NotificationManager;
-import org.apache.syncope.core.persistence.beans.AbstractAttrValue;
import org.apache.syncope.core.persistence.beans.AbstractAttributable;
import org.apache.syncope.core.persistence.beans.AbstractMappingItem;
-import org.apache.syncope.core.persistence.beans.AbstractNormalSchema;
-import org.apache.syncope.core.persistence.beans.PropagationTask;
-import org.apache.syncope.core.persistence.beans.SyncPolicy;
-import org.apache.syncope.core.persistence.beans.SyncTask;
+import org.apache.syncope.core.persistence.beans.PushTask;
import org.apache.syncope.core.persistence.beans.role.SyncopeRole;
import org.apache.syncope.core.persistence.beans.user.SyncopeUser;
-import org.apache.syncope.core.persistence.dao.AttributableSearchDAO;
-import org.apache.syncope.core.persistence.dao.EntitlementDAO;
-import org.apache.syncope.core.persistence.dao.NotFoundException;
-import org.apache.syncope.core.persistence.dao.PolicyDAO;
-import org.apache.syncope.core.persistence.dao.RoleDAO;
-import org.apache.syncope.core.persistence.dao.SchemaDAO;
-import org.apache.syncope.core.persistence.dao.UserDAO;
-import org.apache.syncope.core.persistence.dao.search.OrderByClause;
-import org.apache.syncope.core.persistence.validation.attrvalue.ParsingValidationException;
-import org.apache.syncope.core.propagation.PropagationByResource;
-import org.apache.syncope.core.propagation.PropagationException;
-import org.apache.syncope.core.propagation.PropagationTaskExecutor;
-import org.apache.syncope.core.propagation.Connector;
-import org.apache.syncope.core.propagation.impl.PropagationManager;
-import org.apache.syncope.core.rest.controller.UnauthorizedRoleException;
-import org.apache.syncope.core.rest.data.AttributableTransformer;
+import org.apache.syncope.core.propagation.TimeoutException;
+import org.apache.syncope.core.propagation.impl.AbstractPropagationTaskExecutor;
import org.apache.syncope.core.rest.data.RoleDataBinder;
import org.apache.syncope.core.rest.data.UserDataBinder;
-import org.apache.syncope.core.sync.SyncActions;
+import org.apache.syncope.core.sync.PushActions;
import org.apache.syncope.core.sync.SyncResult;
-import org.apache.syncope.core.sync.SyncCorrelationRule;
import org.apache.syncope.core.util.AttributableUtil;
-import org.apache.syncope.core.util.EntitlementUtil;
-import org.apache.syncope.core.workflow.WorkflowResult;
-import org.apache.syncope.core.workflow.role.RoleWorkflowAdapter;
-import org.apache.syncope.core.workflow.user.UserWorkflowAdapter;
+import org.apache.syncope.core.util.MappingUtil;
import org.identityconnectors.framework.common.objects.Attribute;
-import org.identityconnectors.framework.common.objects.AttributeUtil;
import org.identityconnectors.framework.common.objects.ConnectorObject;
-import org.identityconnectors.framework.common.objects.Name;
import org.identityconnectors.framework.common.objects.ObjectClass;
-import org.identityconnectors.framework.common.objects.OperationalAttributes;
-import org.identityconnectors.framework.common.objects.SyncDelta;
-import org.identityconnectors.framework.common.objects.SyncDeltaType;
-import org.identityconnectors.framework.common.objects.SyncResultsHandler;
-import org.identityconnectors.framework.common.objects.filter.EqualsFilter;
+import org.identityconnectors.framework.common.objects.Uid;
import org.quartz.JobExecutionException;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.transaction.annotation.Transactional;
-public class SyncopeSyncResultHandler implements SyncResultsHandler {
+public class SyncopePushResultHandler extends AbstractSyncopeResultHandler {
/**
- * Logger.
- */
- protected static final Logger LOG = LoggerFactory.getLogger(SyncopeSyncResultHandler.class);
-
- /**
- * Policy DAO.
- */
- @Autowired
- protected PolicyDAO policyDAO;
-
- /**
- * Entitlement DAO.
- */
- @Autowired
- protected EntitlementDAO entitlementDAO;
-
- /**
- * Schema DAO.
- */
- @Autowired
- protected SchemaDAO schemaDAO;
-
- /**
- * User DAO.
- */
- @Autowired
- protected UserDAO userDAO;
-
- /**
- * Role DAO.
+ * User data binder.
*/
@Autowired
- protected RoleDAO roleDAO;
+ protected UserDataBinder userDataBinder;
/**
- * Search DAO.
+ * Role data binder.
*/
@Autowired
- protected AttributableSearchDAO searchDAO;
+ protected RoleDataBinder roleDataBinder;
/**
* ConnectorObject util.
@@ -147,42 +74,6 @@ public class SyncopeSyncResultHandler im
protected ConnObjectUtil connObjectUtil;
/**
- * User workflow adapter.
- */
- @Autowired
- protected UserWorkflowAdapter uwfAdapter;
-
- /**
- * Role workflow adapter.
- */
- @Autowired
- protected RoleWorkflowAdapter rwfAdapter;
-
- /**
- * Propagation Manager.
- */
- @Autowired
- protected PropagationManager propagationManager;
-
- /**
- * PropagationTask executor.
- */
- @Autowired
- protected PropagationTaskExecutor taskExecutor;
-
- /**
- * User data binder.
- */
- @Autowired
- protected UserDataBinder userDataBinder;
-
- /**
- * Role data binder.
- */
- @Autowired
- protected RoleDataBinder roleDataBinder;
-
- /**
* Notification Manager.
*/
@Autowired
@@ -194,85 +85,39 @@ public class SyncopeSyncResultHandler im
@Autowired
protected AuditManager auditManager;
- @Autowired
- protected AttributableTransformer attrTransformer;
-
- /**
- * Syncing connector.
- */
- protected Connector connector;
+ protected Map<Long, String> roleOwnerMap = new HashMap<Long, String>();
/**
* SyncJob actions.
*/
- protected SyncActions actions;
-
- protected Collection<SyncResult> results;
-
- protected SyncTask syncTask;
-
- protected ConflictResolutionAction resAct;
+ protected PushActions actions;
- protected boolean dryRun;
+ protected PushTask syncTask;
- protected Map<Long, String> roleOwnerMap = new HashMap<Long, String>();
-
- public Connector getConnector() {
- return connector;
- }
-
- public void setConnector(final Connector connector) {
- this.connector = connector;
- }
-
- public SyncActions getActions() {
+ public PushActions getActions() {
return actions;
}
- public void setActions(final SyncActions actions) {
+ public void setActions(final PushActions actions) {
this.actions = actions;
}
- public Collection<SyncResult> getResults() {
- return results;
- }
-
- public void setResults(final Collection<SyncResult> results) {
- this.results = results;
- }
-
- public SyncTask getSyncTask() {
+ public PushTask getSyncTask() {
return syncTask;
}
- public void setSyncTask(final SyncTask syncTask) {
+ public void setSyncTask(final PushTask syncTask) {
this.syncTask = syncTask;
}
- public ConflictResolutionAction getResAct() {
- return resAct;
- }
-
- public void setResAct(final ConflictResolutionAction resAct) {
- this.resAct = resAct;
- }
-
- public boolean isDryRun() {
- return dryRun;
- }
-
- public void setDryRun(final boolean dryRun) {
- this.dryRun = dryRun;
- }
-
public Map<Long, String> getRoleOwnerMap() {
return roleOwnerMap;
}
- @Override
- public boolean handle(final SyncDelta delta) {
+ @Transactional
+ public boolean handle(final AbstractAttributable attributable) {
try {
- doHandle(delta);
+ doHandle(attributable);
return true;
} catch (JobExecutionException e) {
LOG.error("Synchronization failed", e);
@@ -280,720 +125,139 @@ public class SyncopeSyncResultHandler im
}
}
- protected List<Long> findByAccountIdItem(final String uid, final AttributableUtil attrUtil) {
- final List<Long> result = new ArrayList<Long>();
-
- final AbstractMappingItem accountIdItem = attrUtil.getAccountIdItem(syncTask.getResource());
- switch (accountIdItem.getIntMappingType()) {
- case UserSchema:
- case RoleSchema:
- final AbstractAttrValue value = attrUtil.newAttrValue();
-
- AbstractNormalSchema schema = schemaDAO.find(accountIdItem.getIntAttrName(), attrUtil.schemaClass());
- if (schema == null) {
- value.setStringValue(uid);
- } else {
- try {
- value.parseValue(schema, uid);
- } catch (ParsingValidationException e) {
- LOG.error("While parsing provided __UID__ {}", uid, e);
- value.setStringValue(uid);
- }
- }
-
- List<AbstractAttributable> subjects =
- userDAO.findByAttrValue(accountIdItem.getIntAttrName(), value, attrUtil);
- for (AbstractAttributable subject : subjects) {
- result.add(subject.getId());
- }
- break;
-
- case UserDerivedSchema:
- case RoleDerivedSchema:
- subjects = userDAO.findByDerAttrValue(accountIdItem.getIntAttrName(), uid, attrUtil);
- for (AbstractAttributable subject : subjects) {
- result.add(subject.getId());
- }
- break;
-
- case Username:
- SyncopeUser user = userDAO.find(uid);
- if (user != null) {
- result.add(user.getId());
- }
- break;
-
- case UserId:
- user = userDAO.find(Long.parseLong(uid));
- if (user != null) {
- result.add(user.getId());
- }
- break;
-
- case RoleName:
- List<SyncopeRole> roles = roleDAO.find(uid);
- for (SyncopeRole role : roles) {
- result.add(role.getId());
- }
- break;
-
- case RoleId:
- SyncopeRole role = roleDAO.find(Long.parseLong(uid));
- if (role != null) {
- result.add(role.getId());
- }
- break;
-
- default:
- LOG.error("Invalid accountId type '{}'", accountIdItem.getIntMappingType());
- }
-
- return result;
- }
-
- protected List<Long> search(final SearchCond searchCond, final AttributableUtil attrUtil) {
- final List<Long> result = new ArrayList<Long>();
-
- final List<AbstractAttributable> subjects = searchDAO.search(
- EntitlementUtil.getRoleIds(entitlementDAO.findAll()),
- searchCond, Collections.<OrderByClause>emptyList(), attrUtil);
- for (AbstractAttributable subject : subjects) {
- result.add(subject.getId());
- }
-
- return result;
- }
-
- protected List<Long> findByCorrelationRule(
- final ConnectorObject connObj, final SyncCorrelationRule rule, final AttributableUtil attrUtil) {
-
- return search(rule.getSearchCond(connObj), attrUtil);
- }
-
- protected List<Long> findByAttributableSearch(
- final ConnectorObject connObj, final List<String> altSearchSchemas, final AttributableUtil attrUtil) {
-
- // search for external attribute's name/value of each specified name
- final Map<String, Attribute> extValues = new HashMap<String, Attribute>();
-
- for (AbstractMappingItem item
- : attrUtil.getMappingItems(syncTask.getResource(), MappingPurpose.SYNCHRONIZATION)) {
-
- extValues.put(item.getIntAttrName(), connObj.getAttributeByName(item.getExtAttrName()));
- }
-
- // search for user/role by attribute(s) specified in the policy
- SearchCond searchCond = null;
-
- for (String schema : altSearchSchemas) {
- Attribute value = extValues.get(schema);
-
- AttributeCond.Type type;
- String expression = null;
-
- if (value == null || value.getValue() == null || value.getValue().isEmpty()
- || (value.getValue().size() == 1 && value.getValue().get(0) == null)) {
- type = AttributeCond.Type.ISNULL;
- } else {
- type = AttributeCond.Type.EQ;
- expression = value.getValue().size() > 1
- ? value.getValue().toString()
- : value.getValue().get(0).toString();
- }
-
- SearchCond nodeCond;
- // users: just id or username can be selected to be used
- // roles: just id or name can be selected to be used
- if ("id".equalsIgnoreCase(schema) || "username".equalsIgnoreCase(schema)
- || "name".equalsIgnoreCase(schema)) {
-
- AttributableCond cond = new AttributableCond();
- cond.setSchema(schema);
- cond.setType(type);
- cond.setExpression(expression);
-
- nodeCond = SearchCond.getLeafCond(cond);
- } else {
- AttributeCond cond = new AttributeCond();
- cond.setSchema(schema);
- cond.setType(type);
- cond.setExpression(expression);
-
- nodeCond = SearchCond.getLeafCond(cond);
- }
-
- searchCond = searchCond == null
- ? nodeCond
- : SearchCond.getAndCond(searchCond, nodeCond);
- }
-
- return search(searchCond, attrUtil);
- }
-
/**
- * Find users / roles based on mapped uid value (or previous uid value, if updated).
+ * Look into SyncDelta and take necessary actions (create / update / delete) on user(s).
*
- * @param uid for finding by account id
- * @param connObj for finding by attribute value
- * @param attrUtil attributable util
- * @return list of matching users / roles
+ * @param delta returned by the underlying connector
+ * @throws JobExecutionException in case of synchronization failure.
*/
- protected List<Long> findExisting(final String uid, final ConnectorObject connObj,
- final AttributableUtil attrUtil) {
-
- SyncPolicySpec syncPolicySpec = null;
- if (syncTask.getResource().getSyncPolicy() == null) {
- SyncPolicy globalSP = policyDAO.getGlobalSyncPolicy();
- if (globalSP != null) {
- syncPolicySpec = globalSP.<SyncPolicySpec>getSpecification();
- }
- } else {
- syncPolicySpec = syncTask.getResource().getSyncPolicy().<SyncPolicySpec>getSpecification();
- }
-
- SyncCorrelationRule syncRule = null;
- List<String> altSearchSchemas = null;
+ protected final void doHandle(final AbstractAttributable attributable)
+ throws JobExecutionException {
- if (syncPolicySpec != null) {
- syncRule = attrUtil.getCorrelationRule(syncPolicySpec);
- altSearchSchemas = attrUtil.getAltSearchSchemas(syncPolicySpec);
+ if (results == null) {
+ results = new ArrayList<SyncResult>();
}
- return syncRule == null ? altSearchSchemas == null || altSearchSchemas.isEmpty()
- ? findByAccountIdItem(uid, attrUtil)
- : findByAttributableSearch(connObj, altSearchSchemas, attrUtil)
- : findByCorrelationRule(connObj, syncRule, attrUtil);
- }
+ final AttributableUtil attrUtil = AttributableUtil.getInstance(attributable);
- public Long findMatchingAttributableId(final ObjectClass objectClass, final String name) {
- Long result = null;
+ final SyncResult result = new SyncResult();
+ results.add(result);
- final AttributableUtil attrUtil = AttributableUtil.getInstance(objectClass);
+ result.setId(attributable.getId());
+ result.setSubjectType(attrUtil.getType());
- final List<ConnectorObject> found = connector.search(objectClass,
- new EqualsFilter(new Name(name)), connector.getOperationOptions(
- attrUtil.getMappingItems(syncTask.getResource(), MappingPurpose.SYNCHRONIZATION)));
+ final AbstractAttributable toBeHandled;
+ final Boolean enabled;
- if (found.isEmpty()) {
- LOG.debug("No {} found on {} with __NAME__ {}", objectClass, syncTask.getResource(), name);
+ if (attrUtil.getType() == AttributableType.USER) {
+ toBeHandled = userDataBinder.getUserFromId(attributable.getId());
+ result.setName(((SyncopeUser) toBeHandled).getUsername());
+ enabled = getSyncTask().isSyncStatus()
+ ? ((SyncopeUser) toBeHandled).isSuspended() ? Boolean.FALSE : Boolean.TRUE
+ : null;
} else {
- if (found.size() > 1) {
- LOG.warn("More than one {} found on {} with __NAME__ {} - taking first only",
- objectClass, syncTask.getResource(), name);
- }
-
- ConnectorObject connObj = found.iterator().next();
- final List<Long> subjectIds = findExisting(connObj.getUid().getUidValue(), connObj, attrUtil);
- if (subjectIds.isEmpty()) {
- LOG.debug("No matching {} found for {}, aborting", attrUtil.getType(), connObj);
- } else {
- if (subjectIds.size() > 1) {
- LOG.warn("More than one {} found {} - taking first only", attrUtil.getType(), subjectIds);
- }
-
- result = subjectIds.iterator().next();
- }
+ toBeHandled = roleDataBinder.getRoleFromId(attributable.getId());
+ result.setName(((SyncopeRole) toBeHandled).getName());
+ enabled = null;
}
- return result;
- }
+ LOG.debug("Propagating {} with ID {} towards {}",
+ attrUtil.getType(), toBeHandled.getId(), getSyncTask().getResource());
+
+ Object output = null;
+ Result resultStatus = null;
+ ConnectorObject beforeObj = null;
+ Map.Entry<String, Set<Attribute>> values = null;
- protected Boolean readEnabled(final ConnectorObject connectorObject) {
- Boolean enabled = null;
- if (syncTask.isSyncStatus()) {
- Attribute status = AttributeUtil.find(OperationalAttributes.ENABLE_NAME, connectorObject.getAttributes());
- if (status != null && status.getValue() != null && !status.getValue().isEmpty()) {
- enabled = (Boolean) status.getValue().get(0);
+ try {
+ values = MappingUtil.prepareAttributes(
+ attrUtil, // attributable util
+ toBeHandled, // attributable (user or role)
+ null, // current password if decode is possible; generate otherwise
+ true, // propagate password (if required)
+ null, // no vir attrs to be removed
+ null, // propagate current vir attr values
+ enabled, // propagate status (suspended or not) if required
+ getSyncTask().getResource()); // target external resource
+
+ final ObjectClass oclass =
+ attrUtil.getType() == AttributableType.USER ? ObjectClass.ACCOUNT : ObjectClass.GROUP;
+
+ // Try to read remote object (user / group) BEFORE any actual operation
+ beforeObj = getRemoteObject(oclass, values.getKey(), getSyncTask().getResource().getName());
+
+ if (beforeObj == null) {
+ result.setOperation(ResourceOperation.CREATE);
+ actions.beforeCreate(this, toBeHandled, values);
+ } else {
+ result.setOperation(ResourceOperation.UPDATE);
+ actions.beforeUpdate(this, toBeHandled, values);
}
- }
-
- return enabled;
- }
-
- protected List<SyncResult> create(SyncDelta delta, final AttributableUtil attrUtil, final boolean dryRun)
- throws JobExecutionException {
- if (!syncTask.isPerformCreate()) {
- LOG.debug("SyncTask not configured for create");
- return Collections.<SyncResult>emptyList();
- }
+ AbstractPropagationTaskExecutor.createOrUpdate(
+ oclass,
+ values.getKey(),
+ values.getValue(),
+ getSyncTask().getResource().getName(),
+ getSyncTask().getResource().getPropagationMode(),
+ beforeObj,
+ connector,
+ new HashSet<String>(),
+ connObjectUtil);
- final SyncResult result = new SyncResult();
- result.setOperation(ResourceOperation.CREATE);
- result.setSubjectType(attrUtil.getType());
- result.setStatus(SyncResult.Status.SUCCESS);
-
- AbstractAttributableTO subjectTO = connObjectUtil.getAttributableTO(delta.getObject(), syncTask, attrUtil);
-
- delta = actions.beforeCreate(this, delta, subjectTO);
-
- // Attributable transformation (if configured)
- AbstractAttributableTO actual = attrTransformer.transform(subjectTO);
- LOG.debug("Transformed: {}", actual);
-
- if (dryRun) {
- result.setId(0L);
- if (actual instanceof UserTO) {
- result.setName(((UserTO) actual).getUsername());
- }
- if (actual instanceof RoleTO) {
- result.setName(((RoleTO) actual).getName());
- }
- } else {
- Object output = null;
- Result resultStatus;
+ result.setStatus(SyncResult.Status.SUCCESS);
+ resultStatus = AuditElements.Result.SUCCESS;
+ } catch (Exception e) {
+ result.setStatus(SyncResult.Status.FAILURE);
+ result.setMessage(e.getMessage());
+ resultStatus = AuditElements.Result.FAILURE;
+ output = e;
+
+ LOG.warn("Error pushing {} towards {}", toBeHandled, getSyncTask().getResource(), e);
+ throw new JobExecutionException(e);
+ } finally {
- try {
- if (AttributableType.USER == attrUtil.getType()) {
- Boolean enabled = readEnabled(delta.getObject());
- WorkflowResult<Map.Entry<Long, Boolean>> created =
- uwfAdapter.create((UserTO) actual, true, enabled);
-
- List<PropagationTask> tasks = propagationManager.getUserCreateTaskIds(created,
- ((UserTO) actual).getPassword(), actual.getVirAttrs(),
- Collections.singleton(syncTask.getResource().getName()));
-
- taskExecutor.execute(tasks);
-
- actual = userDataBinder.getUserTO(created.getResult().getKey());
-
- result.setId(created.getResult().getKey());
- result.setName(((UserTO) actual).getUsername());
- } else if (AttributableType.ROLE == attrUtil.getType()) {
- WorkflowResult<Long> created = rwfAdapter.create((RoleTO) actual);
- AttributeTO roleOwner = actual.getAttrMap().get(StringUtils.EMPTY);
- if (roleOwner != null) {
- roleOwnerMap.put(created.getResult(), roleOwner.getValues().iterator().next());
- }
-
- EntitlementUtil.extendAuthContext(created.getResult());
-
- List<PropagationTask> tasks = propagationManager.getRoleCreateTaskIds(created,
- actual.getVirAttrs(), Collections.singleton(syncTask.getResource().getName()));
-
- taskExecutor.execute(tasks);
-
- actual = roleDataBinder.getRoleTO(created.getResult());
-
- result.setId(created.getResult());
- result.setName(((RoleTO) actual).getName());
- }
- output = actual;
- resultStatus = Result.SUCCESS;
-
- } catch (PropagationException e) {
- // A propagation failure doesn't imply a synchronization failure.
- // The propagation exception status will be reported into the propagation task execution.
- LOG.error("Could not propagate {} {}", attrUtil.getType(), delta.getUid().getUidValue(), e);
- output = e;
- resultStatus = Result.FAILURE;
- } catch (Exception e) {
- result.setStatus(SyncResult.Status.FAILURE);
- result.setMessage(e.getMessage());
- LOG.error("Could not create {} {} ", attrUtil.getType(), delta.getUid().getUidValue(), e);
- output = e;
- resultStatus = Result.FAILURE;
- }
+ actions.after(this, toBeHandled, values, result);
notificationManager.createTasks(
- AuditElements.EventCategoryType.SYNCHRONIZATION,
+ AuditElements.EventCategoryType.PUSH,
AttributableType.USER.name().toLowerCase(),
syncTask.getResource().getName(),
- "create",
+ result.getOperation() == null ? null : result.getOperation().name().toLowerCase(),
resultStatus,
- null, // searching for before object is too much expensive ...
+ beforeObj,
output,
- delta);
+ toBeHandled);
auditManager.audit(
- AuditElements.EventCategoryType.SYNCHRONIZATION,
+ AuditElements.EventCategoryType.PUSH,
AttributableType.USER.name().toLowerCase(),
syncTask.getResource().getName(),
- "create",
+ result.getOperation() == null ? null : result.getOperation().name().toLowerCase(),
resultStatus,
- null, // searching for before object is too much expensive ...
+ beforeObj,
output,
- delta);
+ toBeHandled);
}
-
- actions.after(this, delta, actual, result);
- return Collections.singletonList(result);
}
- protected Map.Entry<UserTO, UserTO> updateUser(final Long id, SyncDelta delta, final boolean dryRun,
- final SyncResult result)
- throws Exception {
-
- final UserTO before = userDataBinder.getUserTO(id);
- UserMod userMod = connObjectUtil.getAttributableMod(
- id, delta.getObject(), before, syncTask, AttributableUtil.getInstance(AttributableType.USER));
-
- delta = actions.beforeUpdate(this, delta, before, userMod);
-
- if (dryRun) {
- return new AbstractMap.SimpleEntry<UserTO, UserTO>(before, before);
- }
+ private ConnectorObject getRemoteObject(
+ final ObjectClass oclass, final String accountId, final String resource) {
+ ConnectorObject obj = null;
- // Attribute value transformation (if configured)
- UserMod actual = attrTransformer.transform(userMod);
- LOG.debug("Transformed: {}", actual);
-
- WorkflowResult<Map.Entry<UserMod, Boolean>> updated;
try {
- updated = uwfAdapter.update(actual);
- } catch (Exception e) {
- LOG.error("Update of user {} failed, trying to sync its status anyway (if configured)", id, e);
- result.setStatus(SyncResult.Status.FAILURE);
- result.setMessage("Update failed, trying to sync status anyway (if configured)\n" + e.getMessage());
+ final Uid uid = new Uid(accountId);
- updated = new WorkflowResult<Map.Entry<UserMod, Boolean>>(
- new AbstractMap.SimpleEntry<UserMod, Boolean>(userMod, false), new PropagationByResource(),
- new HashSet<String>());
- }
+ connector.getObject(
+ oclass, uid, connector.getOperationOptions(Collections.<AbstractMappingItem>emptySet()));
- Boolean enabled = readEnabled(delta.getObject());
- if (enabled != null) {
- SyncopeUser user = userDAO.find(id);
-
- WorkflowResult<Long> enableUpdate = null;
- if (user.isSuspended() == null) {
- enableUpdate = uwfAdapter.activate(id, null);
- } else if (enabled && user.isSuspended()) {
- enableUpdate = uwfAdapter.reactivate(id);
- } else if (!enabled && !user.isSuspended()) {
- enableUpdate = uwfAdapter.suspend(id);
- }
-
- if (enableUpdate != null) {
- if (enableUpdate.getPropByRes() != null) {
- updated.getPropByRes().merge(enableUpdate.getPropByRes());
- updated.getPropByRes().purge();
- }
- updated.getPerformedTasks().addAll(enableUpdate.getPerformedTasks());
- }
- }
-
- List<PropagationTask> tasks = propagationManager.getUserUpdateTaskIds(
- updated, updated.getResult().getKey().getPassword() != null,
- Collections.singleton(syncTask.getResource().getName()));
-
- taskExecutor.execute(tasks);
-
- final UserTO after = userDataBinder.getUserTO(updated.getResult().getKey().getId());
- actions.after(this, delta, after, result);
-
- return new AbstractMap.SimpleEntry<UserTO, UserTO>(before, after);
- }
-
- protected Map.Entry<RoleTO, RoleTO> updateRole(
- final Long id, SyncDelta delta, final boolean dryRun, final SyncResult result)
- throws Exception {
-
- final RoleTO before = roleDataBinder.getRoleTO(id);
- RoleMod roleMod = connObjectUtil.getAttributableMod(
- id, delta.getObject(), before, syncTask, AttributableUtil.getInstance(AttributableType.ROLE));
-
- delta = actions.beforeUpdate(this, delta, before, roleMod);
-
- if (dryRun) {
- return new AbstractMap.SimpleEntry<RoleTO, RoleTO>(before, before);
- }
-
- // Attribute value transformation (if configured)
- RoleMod actual = attrTransformer.transform(roleMod);
- LOG.debug("Transformed: {}", actual);
-
- WorkflowResult<Long> updated = rwfAdapter.update(actual);
- String roleOwner = null;
- for (AttributeMod attrMod : actual.getAttrsToUpdate()) {
- if (attrMod.getSchema().isEmpty()) {
- roleOwner = attrMod.getValuesToBeAdded().iterator().next();
- }
- }
- if (roleOwner != null) {
- roleOwnerMap.put(updated.getResult(), roleOwner);
- }
-
- List<PropagationTask> tasks = propagationManager.getRoleUpdateTaskIds(updated,
- actual.getVirAttrsToRemove(),
- actual.getVirAttrsToUpdate(),
- Collections.singleton(syncTask.getResource().getName()));
-
- taskExecutor.execute(tasks);
-
- final RoleTO after = roleDataBinder.getRoleTO(updated.getResult());
-
- actions.after(this, delta, after, result);
-
- return new AbstractMap.SimpleEntry<RoleTO, RoleTO>(before, after);
- }
-
- protected List<SyncResult> update(SyncDelta delta, final List<Long> subjects, final AttributableUtil attrUtil,
- final boolean dryRun)
- throws JobExecutionException {
-
- if (!syncTask.isPerformUpdate()) {
- LOG.debug("SyncTask not configured for update");
- return Collections.<SyncResult>emptyList();
- }
-
- LOG.debug("About to update {}", subjects);
-
- List<SyncResult> updResults = new ArrayList<SyncResult>();
-
- for (Long id : subjects) {
- LOG.debug("About to update {}", id);
-
- Object output = null;
- AbstractAttributableTO before = null;
- Result resultStatus;
-
- final SyncResult result = new SyncResult();
- result.setOperation(ResourceOperation.UPDATE);
- result.setSubjectType(attrUtil.getType());
- result.setStatus(SyncResult.Status.SUCCESS);
- result.setId(id);
-
- try {
- final AbstractAttributableTO updated;
- if (AttributableType.USER == attrUtil.getType()) {
- final Map.Entry<UserTO, UserTO> res = updateUser(id, delta, dryRun, result);
- before = res.getKey();
- updated = res.getValue();
- result.setName(((UserTO) updated).getUsername());
- } else if (AttributableType.ROLE == attrUtil.getType()) {
- final Map.Entry<RoleTO, RoleTO> res = updateRole(id, delta, dryRun, result);
- before = res.getKey();
- updated = res.getValue();
- result.setName(((RoleTO) updated).getName());
- } else {
- updated = null;
- }
- output = updated;
- resultStatus = Result.SUCCESS;
- } catch (PropagationException e) {
- // A propagation failure doesn't imply a synchronization failure.
- // The propagation exception status will be reported into the propagation task execution.
- LOG.error("Could not propagate {} {}", attrUtil.getType(), delta.getUid().getUidValue(), e);
- output = e;
- resultStatus = Result.FAILURE;
- } catch (Exception e) {
- result.setStatus(SyncResult.Status.FAILURE);
- result.setMessage(e.getMessage());
- LOG.error("Could not update {} {}", attrUtil.getType(), delta.getUid().getUidValue(), e);
- output = e;
- resultStatus = Result.FAILURE;
- }
- updResults.add(result);
-
- if (!dryRun) {
- notificationManager.createTasks(
- AuditElements.EventCategoryType.SYNCHRONIZATION,
- attrUtil.getType().name().toLowerCase(),
- syncTask.getResource().getName(),
- "update",
- resultStatus,
- before,
- output,
- delta);
-
- auditManager.audit(
- AuditElements.EventCategoryType.SYNCHRONIZATION,
- attrUtil.getType().name().toLowerCase(),
- syncTask.getResource().getName(),
- "update",
- resultStatus,
- before,
- output,
- delta);
- }
-
- LOG.debug("{} {} successfully updated", attrUtil.getType(), id);
- }
-
- return updResults;
- }
-
- protected List<SyncResult> delete(SyncDelta delta, final List<Long> subjects, final AttributableUtil attrUtil,
- final boolean dryRun)
- throws JobExecutionException {
-
- if (!syncTask.isPerformDelete()) {
- LOG.debug("SyncTask not configured for delete");
- return Collections.<SyncResult>emptyList();
- }
-
- LOG.debug("About to delete {}", subjects);
-
- List<SyncResult> delResults = new ArrayList<SyncResult>();
-
- for (Long id : subjects) {
- Object output = null;
- Result resultStatus = Result.FAILURE;
-
- try {
- AbstractAttributableTO subjectTO = AttributableType.USER == attrUtil.getType()
- ? userDataBinder.getUserTO(id)
- : roleDataBinder.getRoleTO(id);
- delta = actions.beforeDelete(this, delta, subjectTO);
-
- final SyncResult result = new SyncResult();
- result.setId(id);
- if (subjectTO instanceof UserTO) {
- result.setName(((UserTO) subjectTO).getUsername());
- }
- if (subjectTO instanceof RoleTO) {
- result.setName(((RoleTO) subjectTO).getName());
- }
- result.setOperation(ResourceOperation.DELETE);
- result.setSubjectType(attrUtil.getType());
- result.setStatus(SyncResult.Status.SUCCESS);
-
- if (!dryRun) {
- try {
- List<PropagationTask> tasks = Collections.<PropagationTask>emptyList();
- if (AttributableType.USER == attrUtil.getType()) {
- tasks = propagationManager.getUserDeleteTaskIds(id, syncTask.getResource().getName());
- } else if (AttributableType.ROLE == attrUtil.getType()) {
- tasks = propagationManager.getRoleDeleteTaskIds(id, syncTask.getResource().getName());
- }
- taskExecutor.execute(tasks);
- } catch (Exception e) {
- // A propagation failure doesn't imply a synchronization failure.
- // The propagation exception status will be reported into the propagation task execution.
- LOG.error("Could not propagate user " + id, e);
- }
-
- try {
- if (AttributableType.USER == attrUtil.getType()) {
- uwfAdapter.delete(id);
- } else if (AttributableType.ROLE == attrUtil.getType()) {
- rwfAdapter.delete(id);
- }
- output = null;
- resultStatus = Result.SUCCESS;
- } catch (Exception e) {
- result.setStatus(SyncResult.Status.FAILURE);
- result.setMessage(e.getMessage());
- LOG.error("Could not delete {} {}", attrUtil.getType(), id, e);
- output = e;
- }
- }
-
- actions.after(this, delta, subjectTO, result);
- delResults.add(result);
-
- } catch (NotFoundException e) {
- LOG.error("Could not find {} {}", attrUtil.getType(), id, e);
- } catch (UnauthorizedRoleException e) {
- LOG.error("Not allowed to read {} {}", attrUtil.getType(), id, e);
- }
-
- if (!dryRun) {
- notificationManager.createTasks(
- AuditElements.EventCategoryType.SYNCHRONIZATION,
- attrUtil.getType().name().toLowerCase(),
- syncTask.getResource().getName(),
- "delete",
- resultStatus,
- null, // searching for before object is too much expensive ...
- output,
- delta);
-
- auditManager.audit(
- AuditElements.EventCategoryType.SYNCHRONIZATION,
- attrUtil.getType().name().toLowerCase(),
- syncTask.getResource().getName(),
- "delete",
- resultStatus,
- null, // searching for before object is too much expensive ...
- output,
- delta);
- }
- }
-
- return delResults;
- }
-
- /**
- * Look into SyncDelta and take necessary actions (create / update / delete) on user(s).
- *
- * @param delta returned by the underlying connector
- * @throws JobExecutionException in case of synchronization failure.
- */
- protected final void doHandle(final SyncDelta delta)
- throws JobExecutionException {
-
- if (results == null) {
- results = new ArrayList<SyncResult>();
- }
-
- LOG.debug("Process {} for {} as {}",
- delta.getDeltaType(), delta.getUid().getUidValue(), delta.getObject().getObjectClass());
-
- AttributableUtil attrUtil = AttributableUtil.getInstance(delta.getObject().getObjectClass());
-
- final String uid = delta.getPreviousUid() == null
- ? delta.getUid().getUidValue()
- : delta.getPreviousUid().getUidValue();
- final List<Long> subjectIds = findExisting(uid, delta.getObject(), attrUtil);
-
- if (SyncDeltaType.CREATE_OR_UPDATE == delta.getDeltaType()) {
- if (subjectIds.isEmpty()) {
- results.addAll(create(delta, attrUtil, dryRun));
- } else if (subjectIds.size() == 1) {
- results.addAll(update(delta, subjectIds.subList(0, 1), attrUtil, dryRun));
- } else {
- switch (resAct) {
- case IGNORE:
- LOG.error("More than one match {}", subjectIds);
- break;
-
- case FIRSTMATCH:
- results.addAll(update(delta, subjectIds.subList(0, 1), attrUtil, dryRun));
- break;
-
- case LASTMATCH:
- results.addAll(update(delta, subjectIds.subList(subjectIds.size() - 1, subjectIds.size()),
- attrUtil, dryRun));
- break;
-
- case ALL:
- results.addAll(update(delta, subjectIds, attrUtil, dryRun));
- break;
-
- default:
- }
- }
- } else if (SyncDeltaType.DELETE == delta.getDeltaType()) {
- if (subjectIds.isEmpty()) {
- LOG.debug("No match found for deletion");
- } else if (subjectIds.size() == 1) {
- results.addAll(delete(delta, subjectIds, attrUtil, dryRun));
- } else {
- switch (resAct) {
- case IGNORE:
- LOG.error("More than one match {}", subjectIds);
- break;
-
- case FIRSTMATCH:
- results.addAll(delete(delta, subjectIds.subList(0, 1), attrUtil, dryRun));
- break;
-
- case LASTMATCH:
- results.addAll(delete(delta, subjectIds.subList(subjectIds.size() - 1, subjectIds.size()),
- attrUtil,
- dryRun));
- break;
-
- case ALL:
- results.addAll(delete(delta, subjectIds, attrUtil, dryRun));
- break;
-
- default:
- }
- }
+ } catch (TimeoutException toe) {
+ LOG.debug("Request timeout", toe);
+ throw toe;
+ } catch (RuntimeException ignore) {
+ LOG.debug("While resolving {}", accountId, ignore);
}
+ return obj;
}
}
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=1556227&r1=1556226&r2=1556227&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 Tue Jan 7 14:33:44 2014
@@ -20,7 +20,6 @@ package org.apache.syncope.core.sync.imp
import java.util.AbstractMap;
import java.util.ArrayList;
-import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
@@ -40,7 +39,6 @@ import org.apache.syncope.common.to.User
import org.apache.syncope.common.types.AttributableType;
import org.apache.syncope.common.types.AuditElements;
import org.apache.syncope.common.types.AuditElements.Result;
-import org.apache.syncope.common.types.ConflictResolutionAction;
import org.apache.syncope.common.types.MappingPurpose;
import org.apache.syncope.common.types.ResourceOperation;
import org.apache.syncope.common.types.SyncPolicySpec;
@@ -53,7 +51,6 @@ import org.apache.syncope.core.persisten
import org.apache.syncope.core.persistence.beans.AbstractNormalSchema;
import org.apache.syncope.core.persistence.beans.PropagationTask;
import org.apache.syncope.core.persistence.beans.SyncPolicy;
-import org.apache.syncope.core.persistence.beans.SyncTask;
import org.apache.syncope.core.persistence.beans.role.SyncopeRole;
import org.apache.syncope.core.persistence.beans.user.SyncopeUser;
import org.apache.syncope.core.persistence.dao.AttributableSearchDAO;
@@ -68,13 +65,11 @@ import org.apache.syncope.core.persisten
import org.apache.syncope.core.propagation.PropagationByResource;
import org.apache.syncope.core.propagation.PropagationException;
import org.apache.syncope.core.propagation.PropagationTaskExecutor;
-import org.apache.syncope.core.propagation.Connector;
import org.apache.syncope.core.propagation.impl.PropagationManager;
import org.apache.syncope.core.rest.controller.UnauthorizedRoleException;
import org.apache.syncope.core.rest.data.AttributableTransformer;
import org.apache.syncope.core.rest.data.RoleDataBinder;
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.SyncCorrelationRule;
import org.apache.syncope.core.util.AttributableUtil;
@@ -90,19 +85,11 @@ import org.identityconnectors.framework.
import org.identityconnectors.framework.common.objects.OperationalAttributes;
import org.identityconnectors.framework.common.objects.SyncDelta;
import org.identityconnectors.framework.common.objects.SyncDeltaType;
-import org.identityconnectors.framework.common.objects.SyncResultsHandler;
import org.identityconnectors.framework.common.objects.filter.EqualsFilter;
import org.quartz.JobExecutionException;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
-public class SyncopeSyncResultHandler implements SyncResultsHandler {
-
- /**
- * Logger.
- */
- protected static final Logger LOG = LoggerFactory.getLogger(SyncopeSyncResultHandler.class);
+public class SyncopeSyncResultHandler extends AbstractSyncopeSyncResultHandler {
/**
* Policy DAO.
@@ -197,74 +184,8 @@ public class SyncopeSyncResultHandler im
@Autowired
protected AttributableTransformer attrTransformer;
- /**
- * Syncing connector.
- */
- protected Connector connector;
-
- /**
- * SyncJob actions.
- */
- protected SyncActions actions;
-
- protected Collection<SyncResult> results;
-
- protected SyncTask syncTask;
-
- protected ConflictResolutionAction resAct;
-
- protected boolean dryRun;
-
protected Map<Long, String> roleOwnerMap = new HashMap<Long, String>();
- public Connector getConnector() {
- return connector;
- }
-
- public void setConnector(final Connector connector) {
- this.connector = connector;
- }
-
- public SyncActions getActions() {
- return actions;
- }
-
- public void setActions(final SyncActions actions) {
- this.actions = actions;
- }
-
- public Collection<SyncResult> getResults() {
- return results;
- }
-
- public void setResults(final Collection<SyncResult> results) {
- this.results = results;
- }
-
- public SyncTask getSyncTask() {
- return syncTask;
- }
-
- public void setSyncTask(final SyncTask syncTask) {
- this.syncTask = syncTask;
- }
-
- public ConflictResolutionAction getResAct() {
- return resAct;
- }
-
- public void setResAct(final ConflictResolutionAction resAct) {
- this.resAct = resAct;
- }
-
- public boolean isDryRun() {
- return dryRun;
- }
-
- public void setDryRun(final boolean dryRun) {
- this.dryRun = dryRun;
- }
-
public Map<Long, String> getRoleOwnerMap() {
return roleOwnerMap;
}
@@ -472,7 +393,7 @@ public class SyncopeSyncResultHandler im
final List<ConnectorObject> found = connector.search(objectClass,
new EqualsFilter(new Name(name)), connector.getOperationOptions(
- attrUtil.getMappingItems(syncTask.getResource(), MappingPurpose.SYNCHRONIZATION)));
+ attrUtil.getMappingItems(syncTask.getResource(), MappingPurpose.SYNCHRONIZATION)));
if (found.isEmpty()) {
LOG.debug("No {} found on {} with __NAME__ {}", objectClass, syncTask.getResource(), name);
Modified: syncope/trunk/core/src/main/java/org/apache/syncope/core/util/MappingUtil.java
URL: http://svn.apache.org/viewvc/syncope/trunk/core/src/main/java/org/apache/syncope/core/util/MappingUtil.java?rev=1556227&r1=1556226&r2=1556227&view=diff
==============================================================================
--- syncope/trunk/core/src/main/java/org/apache/syncope/core/util/MappingUtil.java (original)
+++ syncope/trunk/core/src/main/java/org/apache/syncope/core/util/MappingUtil.java Tue Jan 7 14:33:44 2014
@@ -30,8 +30,10 @@ import org.apache.commons.jexl2.JexlCont
import org.apache.commons.jexl2.MapContext;
import org.apache.commons.lang3.StringUtils;
import org.apache.syncope.common.mod.AttributeMod;
+import org.apache.syncope.common.types.AttributableType;
import org.apache.syncope.common.types.IntMappingType;
import org.apache.syncope.common.types.AttributeSchemaType;
+import org.apache.syncope.common.types.MappingPurpose;
import org.apache.syncope.core.connid.ConnObjectUtil;
import org.apache.syncope.core.connid.PasswordGenerator;
import org.apache.syncope.core.persistence.beans.AbstractAttr;
@@ -61,7 +63,9 @@ import org.apache.syncope.core.persisten
import org.identityconnectors.framework.common.FrameworkUtil;
import org.identityconnectors.framework.common.objects.Attribute;
import org.identityconnectors.framework.common.objects.AttributeBuilder;
+import org.identityconnectors.framework.common.objects.AttributeUtil;
import org.identityconnectors.framework.common.objects.Name;
+import org.identityconnectors.framework.common.objects.OperationalAttributes;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.ConfigurableApplicationContext;
@@ -116,6 +120,89 @@ public final class MappingUtil {
}
/**
+ * Prepare attributes for sending to a connector instance.
+ *
+ * @param <T> user / role
+ * @param attrUtil user / role
+ * @param subject given user / role
+ * @param password clear-text password
+ * @param changePwd whether password should be included for propagation attributes or not
+ * @param vAttrsToBeRemoved virtual attributes to be removed
+ * @param vAttrsToBeUpdated virtual attributes to be added
+ * @param enable whether user must be enabled or not
+ * @param resource target resource
+ * @return account link + prepared attributes
+ */
+ public static <T extends AbstractAttributable> Map.Entry<String, Set<Attribute>> prepareAttributes(
+ final AttributableUtil attrUtil, final T subject, final String password, final boolean changePwd,
+ final Set<String> vAttrsToBeRemoved, final Map<String, AttributeMod> vAttrsToBeUpdated,
+ final Boolean enable, final ExternalResource resource) {
+
+ LOG.debug("Preparing resource attributes for {} on resource {} with attributes {}",
+ subject, resource, subject.getAttrs());
+
+ final ConfigurableApplicationContext context = ApplicationContextProvider.getApplicationContext();
+ final VirAttrCache virAttrCache = context.getBean(VirAttrCache.class);
+ final PasswordGenerator passwordGenerator = context.getBean(PasswordGenerator.class);
+
+ Set<Attribute> attributes = new HashSet<Attribute>();
+ String accountId = null;
+
+ for (AbstractMappingItem mapping : attrUtil.getMappingItems(resource, MappingPurpose.PROPAGATION)) {
+ LOG.debug("Processing schema {}", mapping.getIntAttrName());
+
+ try {
+ if ((attrUtil.getType() == AttributableType.USER
+ && mapping.getIntMappingType() == IntMappingType.UserVirtualSchema)
+ || (attrUtil.getType() == AttributableType.ROLE
+ && mapping.getIntMappingType() == IntMappingType.RoleVirtualSchema)) {
+
+ LOG.debug("Expire entry cache {}-{}", subject.getId(), mapping.getIntAttrName());
+ virAttrCache.expire(attrUtil.getType(), subject.getId(), mapping.getIntAttrName());
+ }
+
+ Map.Entry<String, Attribute> preparedAttribute = prepareAttribute(
+ resource, mapping, subject, password, passwordGenerator, vAttrsToBeRemoved, vAttrsToBeUpdated);
+
+ if (preparedAttribute != null && preparedAttribute.getKey() != null) {
+ accountId = preparedAttribute.getKey();
+ }
+
+ if (preparedAttribute != null && preparedAttribute.getValue() != null) {
+ Attribute alreadyAdded = AttributeUtil.find(preparedAttribute.getValue().getName(), attributes);
+
+ if (alreadyAdded == null) {
+ attributes.add(preparedAttribute.getValue());
+ } else {
+ attributes.remove(alreadyAdded);
+
+ Set<Object> values = new HashSet<Object>(alreadyAdded.getValue());
+ values.addAll(preparedAttribute.getValue().getValue());
+
+ attributes.add(AttributeBuilder.build(preparedAttribute.getValue().getName(), values));
+ }
+ }
+ } catch (Exception e) {
+ LOG.debug("Attribute '{}' processing failed", mapping.getIntAttrName(), e);
+ }
+ }
+
+ attributes.add(MappingUtil.evaluateNAME(subject, resource, accountId));
+
+ if (enable != null) {
+ attributes.add(AttributeBuilder.buildEnabled(enable));
+ }
+ if (!changePwd) {
+ Attribute pwdAttr = AttributeUtil.find(OperationalAttributes.PASSWORD_NAME, attributes);
+ if (pwdAttr != null) {
+ attributes.remove(pwdAttr);
+ }
+ }
+
+ return new AbstractMap.SimpleEntry<String, Set<Attribute>>(accountId, attributes);
+ }
+
+ /**
* Prepare an attribute to be sent to a connector instance.
*
* @param resource target resource
@@ -129,7 +216,7 @@ public final class MappingUtil {
* @return account link + prepared attribute
*/
@SuppressWarnings("unchecked")
- public static <T extends AbstractAttributable> Map.Entry<String, Attribute> prepareAttribute(
+ private static <T extends AbstractAttributable> Map.Entry<String, Attribute> prepareAttribute(
final ExternalResource resource, final AbstractMappingItem mapItem,
final T subject, final String password, final PasswordGenerator passwordGenerator,
final Set<String> vAttrsToBeRemoved, final Map<String, AttributeMod> vAttrsToBeUpdated) {
@@ -250,16 +337,19 @@ public final class MappingUtil {
if (passwordAttrValue == null) {
result = null;
} else {
- result = new AbstractMap.SimpleEntry<String, Attribute>(null,
+ result = new AbstractMap.SimpleEntry<String, Attribute>(
+ null,
AttributeBuilder.buildPassword(passwordAttrValue.toCharArray()));
}
} else {
if ((schema != null && schema.isMultivalue()) || AttributableUtil.getInstance(subject).getType()
!= mapItem.getIntMappingType().getAttributableType()) {
- result = new AbstractMap.SimpleEntry<String, Attribute>(null, AttributeBuilder.build(extAttrName,
- objValues));
+ result = new AbstractMap.SimpleEntry<String, Attribute>(
+ null,
+ AttributeBuilder.build(extAttrName, objValues));
} else {
- result = new AbstractMap.SimpleEntry<String, Attribute>(null, objValues.isEmpty()
+ result = new AbstractMap.SimpleEntry<String, Attribute>(
+ null, objValues.isEmpty()
? AttributeBuilder.build(extAttrName)
: AttributeBuilder.build(extAttrName, objValues.iterator().next()));
}
@@ -378,13 +468,6 @@ public final class MappingUtil {
for (AbstractAttributable attributable : attributables) {
AbstractVirAttr virAttr = attributable.getVirAttr(mappingItem.getIntAttrName());
if (virAttr != null) {
- if (virAttr.getValues() != null) {
- for (String value : virAttr.getValues()) {
- attrValue = new UAttrValue();
- attrValue.setStringValue(value);
- values.add(attrValue);
- }
- }
if (vAttrsToBeRemoved != null && vAttrsToBeUpdated != null) {
if (vAttrsToBeUpdated.containsKey(mappingItem.getIntAttrName())) {
virAttr.setValues(
@@ -396,6 +479,13 @@ public final class MappingUtil {
+ mappingItem.getIntAttrName() + "'");
}
}
+ if (virAttr.getValues() != null) {
+ for (String value : virAttr.getValues()) {
+ attrValue = new UAttrValue();
+ attrValue.setStringValue(value);
+ values.add(attrValue);
+ }
+ }
}
LOG.debug("Retrieved virtual attribute {}"
Modified: syncope/trunk/core/src/main/java/org/apache/syncope/core/util/TaskUtil.java
URL: http://svn.apache.org/viewvc/syncope/trunk/core/src/main/java/org/apache/syncope/core/util/TaskUtil.java?rev=1556227&r1=1556226&r2=1556227&view=diff
==============================================================================
--- syncope/trunk/core/src/main/java/org/apache/syncope/core/util/TaskUtil.java (original)
+++ syncope/trunk/core/src/main/java/org/apache/syncope/core/util/TaskUtil.java Tue Jan 7 14:33:44 2014
@@ -23,9 +23,11 @@ import org.apache.syncope.common.to.Prop
import org.apache.syncope.common.to.SchedTaskTO;
import org.apache.syncope.common.to.SyncTaskTO;
import org.apache.syncope.common.to.AbstractTaskTO;
+import org.apache.syncope.common.to.PushTaskTO;
import org.apache.syncope.common.types.TaskType;
import org.apache.syncope.core.persistence.beans.NotificationTask;
import org.apache.syncope.core.persistence.beans.PropagationTask;
+import org.apache.syncope.core.persistence.beans.PushTask;
import org.apache.syncope.core.persistence.beans.SchedTask;
import org.apache.syncope.core.persistence.beans.SyncTask;
import org.apache.syncope.core.persistence.beans.Task;
@@ -43,6 +45,8 @@ public final class TaskUtil {
TaskType type;
if (task instanceof SyncTask) {
type = TaskType.SYNCHRONIZATION;
+ } else if (task instanceof PushTask) {
+ type = TaskType.PUSH;
} else if (task instanceof SchedTask) {
type = TaskType.SCHEDULED;
} else if (task instanceof PropagationTask) {
@@ -66,6 +70,8 @@ public final class TaskUtil {
type = TaskType.SCHEDULED;
} else if (taskClass == SyncTaskTO.class) {
type = TaskType.SYNCHRONIZATION;
+ } else if (taskClass == PushTaskTO.class) {
+ type = TaskType.PUSH;
} else {
throw new IllegalArgumentException("Invalid TaskTO class: " + taskClass.getName());
}
@@ -101,6 +107,10 @@ public final class TaskUtil {
result = (Class<T>) SyncTask.class;
break;
+ case PUSH:
+ result = (Class<T>) PushTask.class;
+ break;
+
case NOTIFICATION:
result = (Class<T>) NotificationTask.class;
break;
@@ -112,29 +122,12 @@ public final class TaskUtil {
}
public <T extends Task> T newTask() {
- T result = null;
-
- switch (type) {
- case PROPAGATION:
- result = (T) new PropagationTask();
- break;
-
- case SCHEDULED:
- result = (T) new SchedTask();
- break;
-
- case SYNCHRONIZATION:
- result = (T) new SyncTask();
- break;
-
- case NOTIFICATION:
- result = (T) new NotificationTask();
- break;
-
- default:
+ final Class<T> taskClass = taskClass();
+ try {
+ return taskClass == null ? null : taskClass.newInstance();
+ } catch (Exception e) {
+ return null;
}
-
- return result;
}
public <T extends AbstractTaskTO> Class<T> taskTOClass() {
@@ -153,6 +146,10 @@ public final class TaskUtil {
result = (Class<T>) SyncTaskTO.class;
break;
+ case PUSH:
+ result = (Class<T>) PushTaskTO.class;
+ break;
+
case NOTIFICATION:
result = (Class<T>) NotificationTaskTO.class;
break;
@@ -163,29 +160,13 @@ public final class TaskUtil {
return result;
}
+ @SuppressWarnings("unchecked")
public <T extends AbstractTaskTO> T newTaskTO() {
- T result = null;
-
- switch (type) {
- case PROPAGATION:
- result = (T) new PropagationTaskTO();
- break;
-
- case SCHEDULED:
- result = (T) new SchedTaskTO();
- break;
-
- case SYNCHRONIZATION:
- result = (T) new SyncTaskTO();
- break;
-
- case NOTIFICATION:
- result = (T) new NotificationTaskTO();
- break;
-
- default:
+ final Class<T> taskClass = taskTOClass();
+ try {
+ return taskClass == null ? null : taskClass.newInstance();
+ } catch (Exception e) {
+ return null;
}
-
- return result;
}
}
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=1556227&r1=1556226&r2=1556227&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 Tue Jan 7 14:33:44 2014
@@ -18,6 +18,7 @@
*/
package org.apache.syncope.core.rest;
+import static org.apache.syncope.core.rest.AbstractTest.taskService;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
@@ -54,6 +55,7 @@ import org.apache.syncope.common.types.P
import org.apache.syncope.common.types.TaskType;
import org.apache.syncope.common.types.TraceLevel;
import org.apache.syncope.common.SyncopeClientException;
+import org.apache.syncope.common.to.PushTaskTO;
import org.apache.syncope.core.sync.TestSyncActions;
import org.apache.syncope.core.sync.TestSyncRule;
import org.apache.syncope.core.sync.impl.SyncJob;
@@ -692,8 +694,7 @@ public class TaskTestITCase extends Abst
assertEquals("updatedSYNCOPE230@syncope.apache.org", email);
}
- private TaskExecTO execSyncTask(final Long taskId, final int maxWaitSeconds,
- final boolean dryRun) {
+ private TaskExecTO execSyncTask(final Long taskId, final int maxWaitSeconds, final boolean dryRun) {
AbstractTaskTO taskTO = taskService.read(taskId);
assertNotNull(taskTO);
@@ -910,4 +911,20 @@ public class TaskTestITCase extends Abst
assertFalse(taskService.list(TaskType.PROPAGATION).getResult().containsAll(after));
}
+
+ @Test
+ public void pushUsers() {
+ // Read sync task
+ PushTaskTO task = taskService.<PushTaskTO>read(13L);
+ assertNotNull(task);
+
+ execSyncTask(task.getId(), 50, false);
+
+ final JdbcTemplate jdbcTemplate = new JdbcTemplate(testDataSource);
+
+ assertEquals("vivaldi", jdbcTemplate.queryForObject("SELECT ID FROM test2 WHERE ID=?", String.class, "vivaldi"));
+ assertEquals("bellini", jdbcTemplate.queryForObject("SELECT ID FROM test2 WHERE ID=?", String.class, "bellini"));
+ assertEquals("rossini", jdbcTemplate.queryForObject("SELECT ID FROM test2 WHERE ID=?", String.class, "rossini"));
+ assertEquals("puccini", jdbcTemplate.queryForObject("SELECT ID FROM test2 WHERE ID=?", String.class, "puccini"));
+ }
}
Modified: syncope/trunk/core/src/test/java/org/apache/syncope/core/sync/TestSyncActions.java
URL: http://svn.apache.org/viewvc/syncope/trunk/core/src/test/java/org/apache/syncope/core/sync/TestSyncActions.java?rev=1556227&r1=1556226&r2=1556227&view=diff
==============================================================================
--- syncope/trunk/core/src/test/java/org/apache/syncope/core/sync/TestSyncActions.java (original)
+++ syncope/trunk/core/src/test/java/org/apache/syncope/core/sync/TestSyncActions.java Tue Jan 7 14:33:44 2014
@@ -22,8 +22,8 @@ import org.apache.syncope.common.mod.Abs
import org.apache.syncope.common.mod.AttributeMod;
import org.apache.syncope.common.to.AbstractAttributableTO;
import org.apache.syncope.common.to.AttributeTO;
+import org.apache.syncope.core.sync.impl.AbstractSyncopeSyncResultHandler;
import org.identityconnectors.framework.common.objects.SyncDelta;
-import org.identityconnectors.framework.common.objects.SyncResultsHandler;
import org.quartz.JobExecutionException;
public class TestSyncActions extends DefaultSyncActions {
@@ -31,7 +31,7 @@ public class TestSyncActions extends Def
private int counter = 0;
@Override
- public <T extends AbstractAttributableTO> SyncDelta beforeCreate(final SyncResultsHandler handler,
+ public <T extends AbstractAttributableTO> SyncDelta beforeCreate(final AbstractSyncopeSyncResultHandler handler,
final SyncDelta delta, final T subject) throws JobExecutionException {
AttributeTO attrTO = null;
@@ -53,7 +53,7 @@ public class TestSyncActions extends Def
@Override
public <T extends AbstractAttributableTO, K extends AbstractAttributableMod> SyncDelta beforeUpdate(
- final SyncResultsHandler handler, final SyncDelta delta, final T subject, final K subjectMod)
+ final AbstractSyncopeSyncResultHandler handler, final SyncDelta delta, final T subject, final K subjectMod)
throws JobExecutionException {
subjectMod.getAttrsToRemove().add("fullname");
Modified: syncope/trunk/core/src/test/resources/content.xml
URL: http://svn.apache.org/viewvc/syncope/trunk/core/src/test/resources/content.xml?rev=1556227&r1=1556226&r2=1556227&view=diff
==============================================================================
--- syncope/trunk/core/src/test/resources/content.xml (original)
+++ syncope/trunk/core/src/test/resources/content.xml Tue Jan 7 14:33:44 2014
@@ -512,7 +512,7 @@ under the License.
creator="admin" lastModifier="admin"
creationDate="2010-10-20 11:00:00" lastChangeDate="2010-10-20 11:00:00"/>
<ExternalResource name="resource-testdb2" connector_id="106"
- randomPwdIfNotProvided="0" enforceMandatoryCondition="1" propagationMode="ONE_PHASE"
+ randomPwdIfNotProvided="1" enforceMandatoryCondition="1" propagationMode="ONE_PHASE"
propagationPriority="0" propagationPrimary="0" createTraceLevel="ALL" deleteTraceLevel="ALL" updateTraceLevel="ALL" syncTraceLevel="ALL"
creator="admin" lastModifier="admin"
creationDate="2010-10-20 11:00:00" lastChangeDate="2010-10-20 11:00:00"/>
@@ -839,7 +839,10 @@ under the License.
jobClassName="org.apache.syncope.core.sync.impl.SyncJob"/>
<Task DTYPE="SyncTask" id="12" name="VirAttrCache test" resource_name="resource-csv"
performCreate="0" performUpdate="1" performDelete="0" syncStatus="0" fullReconciliation="1"
- jobClassName="org.apache.syncope.core.sync.impl.SyncJob"/>
+ jobClassName="org.apache.syncope.core.sync.impl.SyncJob"/>
+ <Task DTYPE="PushTask" id="13" name="Export on resource-testdb" resource_name="resource-testdb2"
+ performCreate="1" performUpdate="1" performDelete="1" syncStatus="1"
+ jobClassName="org.apache.syncope.core.sync.impl.PushJob"/>
<Notification id="1" sender="test@syncope.apache.org" subject="Test subject" template="test" selfAsRecipient="0" traceLevel="ALL"
about="fullname==*o*;fullname==*i*"