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 [2/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/PushActions.java (from r1554763, syncope/trunk/core/src/main/java/org/apache/syncope/core/sync/SyncActions.java)
URL: http://svn.apache.org/viewvc/syncope/trunk/core/src/main/java/org/apache/syncope/core/sync/PushActions.java?p2=syncope/trunk/core/src/main/java/org/apache/syncope/core/sync/PushActions.java&p1=syncope/trunk/core/src/main/java/org/apache/syncope/core/sync/SyncActions.java&r1=1554763&r2=1556227&rev=1556227&view=diff
==============================================================================
--- syncope/trunk/core/src/main/java/org/apache/syncope/core/sync/SyncActions.java (original)
+++ syncope/trunk/core/src/main/java/org/apache/syncope/core/sync/PushActions.java Tue Jan 7 14:33:44 2014
@@ -18,83 +18,58 @@
*/
package org.apache.syncope.core.sync;
-import java.util.List;
-
-import org.apache.syncope.common.mod.AbstractAttributableMod;
-import org.apache.syncope.common.to.AbstractAttributableTO;
-import org.identityconnectors.framework.common.objects.SyncDelta;
-import org.identityconnectors.framework.common.objects.SyncResultsHandler;
+import java.util.Map;
+import java.util.Set;
+import org.apache.syncope.core.persistence.beans.AbstractAttributable;
+import org.apache.syncope.core.sync.impl.AbstractSyncopeResultHandler;
+import org.identityconnectors.framework.common.objects.Attribute;
import org.quartz.JobExecutionException;
/**
- * Interface for actions to be performed during SyncJob execution.
+ * Interface for actions to be performed during PushJob execution.
*/
-public interface SyncActions {
-
- /**
- * Action to be executed before to start the synchronization task execution.
- *
- * @param handler synchronization handler being executed.
- * @throws JobExecutionException in case of generic failure.
- */
- void beforeAll(final SyncResultsHandler handler) throws JobExecutionException;
+public interface PushActions extends AbstractSyncActions<AbstractSyncopeResultHandler> {
/**
* Action to be executed before to create a synchronized user locally.
*
* @param handler synchronization handler being executed.
- * @param delta retrieved synchronization information
* @param subject user / role to be created
- * @return synchronization information used for user status evaluation and to be passed to the 'after' method.
+ * @param delta info to be pushed out (accountId, attributes)
+ * @return info to be pushed out (accountId, attributes).
* @throws JobExecutionException in case of generic failure
*/
- <T extends AbstractAttributableTO> SyncDelta beforeCreate(final SyncResultsHandler handler,
- final SyncDelta delta, final T subject) throws JobExecutionException;
+ <T extends AbstractAttributable> Map.Entry<String, Set<Attribute>> beforeCreate(
+ final AbstractSyncopeResultHandler handler,
+ final T subject,
+ final Map.Entry<String, Set<Attribute>> delta) throws JobExecutionException;
/**
* Action to be executed before to update a synchronized user locally.
*
* @param handler synchronization handler being executed.
- * @param delta retrieved synchronization information
- * @param subject local user / role information
- * @param subjectMod modification
- * @return synchronization information used for logging and to be passed to the 'after' method.
- * @throws JobExecutionException in case of generic failure.
- */
- <T extends AbstractAttributableTO, K extends AbstractAttributableMod> SyncDelta beforeUpdate(
- final SyncResultsHandler handler, final SyncDelta delta, final T subject, final K subjectMod)
- throws JobExecutionException;
-
- /**
- * Action to be executed before to delete a synchronized user locally.
- *
- * @param handler synchronization handler being executed.
- * @param delta retrieved synchronization information
- * @param subject lcao user / role to be deleted
- * @return synchronization information used for logging and to be passed to the 'after' method.
+ * @param subject user / role to be created
+ * @param delta info to be pushed out (accountId, attributes)
+ * @return info to be pushed out (accountId, attributes).
* @throws JobExecutionException in case of generic failure
*/
- <T extends AbstractAttributableTO> SyncDelta beforeDelete(final SyncResultsHandler handler,
- final SyncDelta delta, final T subject) throws JobExecutionException;
+ <T extends AbstractAttributable> Map.Entry<String, Set<Attribute>> beforeUpdate(
+ final AbstractSyncopeResultHandler handler,
+ final T subject,
+ final Map.Entry<String, Set<Attribute>> delta) throws JobExecutionException;
/**
* Action to be executed after each local user synchronization.
*
* @param handler synchronization handler being executed.
- * @param delta retrieved synchronization information (may be modified by 'beforeCreate/beforeUpdate/beforeDelete')
- * @param subject synchronized local user / role
- * @param result global synchronization results at the current synchronization step
- * @throws JobExecutionException in case of generic failure
- */
- <T extends AbstractAttributableTO> void after(final SyncResultsHandler handler, final SyncDelta delta,
- final T subject, final SyncResult result) throws JobExecutionException;
-
- /**
- * Action to be executed after the synchronization task completion.
- *
- * @param handler synchronization handler being executed.
- * @param results synchronization result
+ * @param subject user / role to be created
+ * @param delta info pushed out (accountId, attributes)
+ * @param result operation result.
* @throws JobExecutionException in case of generic failure
*/
- void afterAll(final SyncResultsHandler handler, final List<SyncResult> results) throws JobExecutionException;
+ <T extends AbstractAttributable> void after(
+ final AbstractSyncopeResultHandler handler,
+ final T subject,
+ final Map.Entry<String, Set<Attribute>> delta,
+ final SyncResult result) throws JobExecutionException;
}
Modified: syncope/trunk/core/src/main/java/org/apache/syncope/core/sync/SyncActions.java
URL: http://svn.apache.org/viewvc/syncope/trunk/core/src/main/java/org/apache/syncope/core/sync/SyncActions.java?rev=1556227&r1=1556226&r2=1556227&view=diff
==============================================================================
--- syncope/trunk/core/src/main/java/org/apache/syncope/core/sync/SyncActions.java (original)
+++ syncope/trunk/core/src/main/java/org/apache/syncope/core/sync/SyncActions.java Tue Jan 7 14:33:44 2014
@@ -18,26 +18,16 @@
*/
package org.apache.syncope.core.sync;
-import java.util.List;
-
import org.apache.syncope.common.mod.AbstractAttributableMod;
import org.apache.syncope.common.to.AbstractAttributableTO;
+import org.apache.syncope.core.sync.impl.AbstractSyncopeSyncResultHandler;
import org.identityconnectors.framework.common.objects.SyncDelta;
-import org.identityconnectors.framework.common.objects.SyncResultsHandler;
import org.quartz.JobExecutionException;
/**
* Interface for actions to be performed during SyncJob execution.
*/
-public interface SyncActions {
-
- /**
- * Action to be executed before to start the synchronization task execution.
- *
- * @param handler synchronization handler being executed.
- * @throws JobExecutionException in case of generic failure.
- */
- void beforeAll(final SyncResultsHandler handler) throws JobExecutionException;
+public interface SyncActions extends AbstractSyncActions<AbstractSyncopeSyncResultHandler> {
/**
* Action to be executed before to create a synchronized user locally.
@@ -48,8 +38,10 @@ public interface SyncActions {
* @return synchronization information used for user status evaluation and to be passed to the 'after' method.
* @throws JobExecutionException in case of generic failure
*/
- <T extends AbstractAttributableTO> SyncDelta beforeCreate(final SyncResultsHandler handler,
- final SyncDelta delta, final T subject) throws JobExecutionException;
+ <T extends AbstractAttributableTO> SyncDelta beforeCreate(
+ final AbstractSyncopeSyncResultHandler handler,
+ final SyncDelta delta,
+ final T subject) throws JobExecutionException;
/**
* Action to be executed before to update a synchronized user locally.
@@ -62,7 +54,10 @@ public interface SyncActions {
* @throws JobExecutionException in case of generic failure.
*/
<T extends AbstractAttributableTO, K extends AbstractAttributableMod> SyncDelta beforeUpdate(
- final SyncResultsHandler handler, final SyncDelta delta, final T subject, final K subjectMod)
+ final AbstractSyncopeSyncResultHandler handler,
+ final SyncDelta delta,
+ final T subject,
+ final K subjectMod)
throws JobExecutionException;
/**
@@ -74,8 +69,10 @@ public interface SyncActions {
* @return synchronization information used for logging and to be passed to the 'after' method.
* @throws JobExecutionException in case of generic failure
*/
- <T extends AbstractAttributableTO> SyncDelta beforeDelete(final SyncResultsHandler handler,
- final SyncDelta delta, final T subject) throws JobExecutionException;
+ <T extends AbstractAttributableTO> SyncDelta beforeDelete(
+ final AbstractSyncopeSyncResultHandler handler,
+ final SyncDelta delta,
+ final T subject) throws JobExecutionException;
/**
* Action to be executed after each local user synchronization.
@@ -86,15 +83,8 @@ public interface SyncActions {
* @param result global synchronization results at the current synchronization step
* @throws JobExecutionException in case of generic failure
*/
- <T extends AbstractAttributableTO> void after(final SyncResultsHandler handler, final SyncDelta delta,
+ <T extends AbstractAttributableTO> void after(
+ final AbstractSyncopeSyncResultHandler handler,
+ final SyncDelta delta,
final T subject, final SyncResult result) throws JobExecutionException;
-
- /**
- * Action to be executed after the synchronization task completion.
- *
- * @param handler synchronization handler being executed.
- * @param results synchronization result
- * @throws JobExecutionException in case of generic failure
- */
- void afterAll(final SyncResultsHandler handler, final List<SyncResult> results) throws JobExecutionException;
}
Copied: syncope/trunk/core/src/main/java/org/apache/syncope/core/sync/impl/AbstractSyncJob.java (from r1554763, syncope/trunk/core/src/main/java/org/apache/syncope/core/sync/impl/SyncJob.java)
URL: http://svn.apache.org/viewvc/syncope/trunk/core/src/main/java/org/apache/syncope/core/sync/impl/AbstractSyncJob.java?p2=syncope/trunk/core/src/main/java/org/apache/syncope/core/sync/impl/AbstractSyncJob.java&p1=syncope/trunk/core/src/main/java/org/apache/syncope/core/sync/impl/SyncJob.java&r1=1554763&r2=1556227&rev=1556227&view=diff
==============================================================================
--- syncope/trunk/core/src/main/java/org/apache/syncope/core/sync/impl/SyncJob.java (original)
+++ syncope/trunk/core/src/main/java/org/apache/syncope/core/sync/impl/AbstractSyncJob.java Tue Jan 7 14:33:44 2014
@@ -20,37 +20,20 @@ package org.apache.syncope.core.sync.imp
import java.util.ArrayList;
import java.util.List;
-import java.util.Map;
-import org.apache.commons.lang3.StringUtils;
-import org.apache.syncope.common.mod.ReferenceMod;
-import org.apache.syncope.common.mod.RoleMod;
-import org.apache.syncope.common.types.ConflictResolutionAction;
-import org.apache.syncope.common.types.SyncPolicySpec;
import org.apache.syncope.common.types.TraceLevel;
+import org.apache.syncope.core.persistence.beans.AbstractSyncTask;
import org.apache.syncope.core.persistence.beans.Entitlement;
-import org.apache.syncope.core.persistence.beans.ExternalResource;
-import org.apache.syncope.core.persistence.beans.SyncPolicy;
+import org.apache.syncope.core.persistence.beans.PushTask;
import org.apache.syncope.core.persistence.beans.SyncTask;
import org.apache.syncope.core.persistence.beans.TaskExec;
-import org.apache.syncope.core.persistence.beans.role.RMapping;
-import org.apache.syncope.core.persistence.beans.user.UMapping;
import org.apache.syncope.core.persistence.dao.EntitlementDAO;
-import org.apache.syncope.core.persistence.dao.NotFoundException;
import org.apache.syncope.core.persistence.dao.ResourceDAO;
import org.apache.syncope.core.propagation.ConnectorFactory;
-import org.apache.syncope.core.propagation.Connector;
import org.apache.syncope.core.quartz.AbstractTaskJob;
-import org.apache.syncope.core.rest.controller.UnauthorizedRoleException;
-import org.apache.syncope.core.sync.SyncActions;
+import org.apache.syncope.core.sync.AbstractSyncActions;
import org.apache.syncope.core.sync.SyncResult;
-import org.apache.syncope.core.util.ApplicationContextProvider;
-import org.apache.syncope.core.workflow.role.RoleWorkflowAdapter;
-import org.identityconnectors.framework.common.objects.ObjectClass;
-import org.identityconnectors.framework.common.objects.SyncToken;
import org.quartz.JobExecutionException;
import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.beans.factory.support.AbstractBeanDefinition;
-import org.springframework.beans.factory.support.DefaultListableBeanFactory;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
@@ -63,39 +46,35 @@ import org.springframework.security.core
*
* @see AbstractTaskJob
* @see SyncTask
+ * @see PushTask
*/
-public class SyncJob extends AbstractTaskJob {
+public abstract class AbstractSyncJob<H extends AbstractSyncopeResultHandler, A extends AbstractSyncActions<?>>
+ extends AbstractTaskJob {
/**
* ConnInstance loader.
*/
@Autowired
- private ConnectorFactory connFactory;
+ protected ConnectorFactory connFactory;
/**
* Resource DAO.
*/
@Autowired
- private ResourceDAO resourceDAO;
+ protected ResourceDAO resourceDAO;
/**
* Entitlement DAO.
*/
@Autowired
- private EntitlementDAO entitlementDAO;
-
- /**
- * Role workflow adapter.
- */
- @Autowired
- private RoleWorkflowAdapter rwfAdapter;
+ protected EntitlementDAO entitlementDAO;
/**
* SyncJob actions.
*/
- private SyncActions actions;
+ protected A actions;
- public void setActions(final SyncActions actions) {
+ public void setActions(final A actions) {
this.actions = actions;
}
@@ -298,32 +277,6 @@ public class SyncJob extends AbstractTas
return report.toString();
}
- protected void setRoleOwners(final SyncopeSyncResultHandler handler)
- throws UnauthorizedRoleException, NotFoundException {
-
- for (Map.Entry<Long, String> entry : handler.getRoleOwnerMap().entrySet()) {
- RoleMod roleMod = new RoleMod();
- roleMod.setId(entry.getKey());
-
- if (StringUtils.isBlank(entry.getValue())) {
- roleMod.setRoleOwner(null);
- roleMod.setUserOwner(null);
- } else {
- Long userId = handler.findMatchingAttributableId(ObjectClass.ACCOUNT, entry.getValue());
- if (userId == null) {
- Long roleId = handler.findMatchingAttributableId(ObjectClass.GROUP, entry.getValue());
- if (roleId != null) {
- roleMod.setRoleOwner(new ReferenceMod(roleId));
- }
- } else {
- roleMod.setUserOwner(new ReferenceMod(userId));
- }
- }
-
- rwfAdapter.update(roleMod);
- }
- }
-
@Override
protected String doExecute(final boolean dryRun) throws JobExecutionException {
// PRE: grant all authorities (i.e. setup the SecurityContextHolder)
@@ -346,122 +299,11 @@ public class SyncJob extends AbstractTas
}
}
- protected String executeWithSecurityContext(final boolean dryRun) throws JobExecutionException {
- if (!(task instanceof SyncTask)) {
- throw new JobExecutionException("Task " + taskId + " isn't a SyncTask");
- }
- final SyncTask syncTask = (SyncTask) this.task;
-
- Connector connector;
- try {
- connector = connFactory.getConnector(syncTask.getResource());
- } catch (Exception e) {
- final String msg = String.format("Connector instance bean for resource %s and connInstance %s not found",
- syncTask.getResource(), syncTask.getResource().getConnector());
-
- throw new JobExecutionException(msg, e);
- }
-
- UMapping uMapping = syncTask.getResource().getUmapping();
- if (uMapping != null && uMapping.getAccountIdItem() == null) {
- throw new JobExecutionException("Invalid user account id mapping for resource " + syncTask.getResource());
- }
- RMapping rMapping = syncTask.getResource().getRmapping();
- if (rMapping != null && rMapping.getAccountIdItem() == null) {
- throw new JobExecutionException("Invalid role account id mapping for resource " + syncTask.getResource());
- }
- if (uMapping == null && rMapping == null) {
- return "No mapping configured for both users and roles: aborting...";
- }
-
- LOG.debug("Execute synchronization with token {}", syncTask.getResource().getUsyncToken());
-
- final List<SyncResult> results = new ArrayList<SyncResult>();
-
- final SyncPolicy syncPolicy = syncTask.getResource().getSyncPolicy();
- final ConflictResolutionAction resAct = syncPolicy == null || syncPolicy.getSpecification() == null
- ? ConflictResolutionAction.IGNORE
- : ((SyncPolicySpec) syncPolicy.getSpecification()).getConflictResolutionAction();
-
- // Prepare handler for SyncDelta objects
- final SyncopeSyncResultHandler handler =
- (SyncopeSyncResultHandler) ((DefaultListableBeanFactory) ApplicationContextProvider.
- getApplicationContext().getBeanFactory()).createBean(
- SyncopeSyncResultHandler.class, AbstractBeanDefinition.AUTOWIRE_BY_NAME, false);
- handler.setConnector(connector);
- handler.setActions(actions);
- handler.setDryRun(dryRun);
- handler.setResAct(resAct);
- handler.setResults(results);
- handler.setSyncTask(syncTask);
-
- actions.beforeAll(handler);
- try {
- SyncToken latestUSyncToken = null;
- if (uMapping != null && !syncTask.isFullReconciliation()) {
- latestUSyncToken = connector.getLatestSyncToken(ObjectClass.ACCOUNT);
- }
- SyncToken latestRSyncToken = null;
- if (rMapping != null && !syncTask.isFullReconciliation()) {
- latestRSyncToken = connector.getLatestSyncToken(ObjectClass.GROUP);
- }
-
- if (syncTask.isFullReconciliation()) {
- if (uMapping != null) {
- connector.getAllObjects(ObjectClass.ACCOUNT, handler,
- connector.getOperationOptions(uMapping.getItems()));
- }
- if (rMapping != null) {
- connector.getAllObjects(ObjectClass.GROUP, handler,
- connector.getOperationOptions(rMapping.getItems()));
- }
- } else {
- if (uMapping != null) {
- connector.sync(ObjectClass.ACCOUNT, syncTask.getResource().getUsyncToken(), handler,
- connector.getOperationOptions(uMapping.getItems()));
- }
- if (rMapping != null) {
- connector.sync(ObjectClass.GROUP, syncTask.getResource().getRsyncToken(), handler,
- connector.getOperationOptions(rMapping.getItems()));
- }
- }
-
- if (!dryRun && !syncTask.isFullReconciliation()) {
- try {
- ExternalResource resource = resourceDAO.find(syncTask.getResource().getName());
- if (uMapping != null) {
- resource.setUsyncToken(latestUSyncToken);
- }
- if (rMapping != null) {
- resource.setRsyncToken(latestRSyncToken);
- }
- resourceDAO.save(resource);
- } catch (Exception e) {
- throw new JobExecutionException("While updating SyncToken", e);
- }
- }
- } catch (Exception e) {
- throw new JobExecutionException("While syncing on connector", e);
- }
-
- try {
- setRoleOwners(handler);
- } catch (Exception e) {
- LOG.error("While setting role owners", e);
- }
-
- actions.afterAll(handler, results);
-
- final String result = createReport(results, syncTask.getResource().getSyncTraceLevel(), dryRun);
-
- LOG.debug("Sync result: {}", result);
-
- return result;
- }
+ protected abstract String executeWithSecurityContext(final boolean dryRun) throws JobExecutionException;
@Override
protected boolean hasToBeRegistered(final TaskExec execution) {
- SyncTask syncTask = (SyncTask) task;
+ final AbstractSyncTask syncTask = (AbstractSyncTask) task;
// True if either failed and failures have to be registered, or if ALL has to be registered.
return (Status.valueOf(execution.getStatus()) == Status.FAILURE
Added: syncope/trunk/core/src/main/java/org/apache/syncope/core/sync/impl/AbstractSyncopeResultHandler.java
URL: http://svn.apache.org/viewvc/syncope/trunk/core/src/main/java/org/apache/syncope/core/sync/impl/AbstractSyncopeResultHandler.java?rev=1556227&view=auto
==============================================================================
--- syncope/trunk/core/src/main/java/org/apache/syncope/core/sync/impl/AbstractSyncopeResultHandler.java (added)
+++ syncope/trunk/core/src/main/java/org/apache/syncope/core/sync/impl/AbstractSyncopeResultHandler.java Tue Jan 7 14:33:44 2014
@@ -0,0 +1,77 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.syncope.core.sync.impl;
+
+import java.util.Collection;
+import org.apache.syncope.common.types.ConflictResolutionAction;
+import org.apache.syncope.core.propagation.Connector;
+import org.apache.syncope.core.sync.SyncResult;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public abstract class AbstractSyncopeResultHandler {
+
+ /**
+ * Logger.
+ */
+ protected static final Logger LOG = LoggerFactory.getLogger(AbstractSyncopeResultHandler.class);
+
+ /**
+ * Syncing connector.
+ */
+ protected Connector connector;
+
+ protected Collection<SyncResult> results;
+
+ protected boolean dryRun;
+
+ protected ConflictResolutionAction resAct;
+
+ public Connector getConnector() {
+ return connector;
+ }
+
+ public void setConnector(final Connector connector) {
+ this.connector = connector;
+ }
+
+ public Collection<SyncResult> getResults() {
+ return results;
+ }
+
+ public void setResults(final Collection<SyncResult> results) {
+ this.results = results;
+ }
+
+ public boolean isDryRun() {
+ return dryRun;
+ }
+
+ public void setDryRun(final boolean dryRun) {
+ this.dryRun = dryRun;
+ }
+
+ public ConflictResolutionAction getResAct() {
+ return resAct;
+ }
+
+ public void setResAct(final ConflictResolutionAction resAct) {
+ this.resAct = resAct;
+ }
+}
Added: syncope/trunk/core/src/main/java/org/apache/syncope/core/sync/impl/AbstractSyncopeSyncResultHandler.java
URL: http://svn.apache.org/viewvc/syncope/trunk/core/src/main/java/org/apache/syncope/core/sync/impl/AbstractSyncopeSyncResultHandler.java?rev=1556227&view=auto
==============================================================================
--- syncope/trunk/core/src/main/java/org/apache/syncope/core/sync/impl/AbstractSyncopeSyncResultHandler.java (added)
+++ syncope/trunk/core/src/main/java/org/apache/syncope/core/sync/impl/AbstractSyncopeSyncResultHandler.java Tue Jan 7 14:33:44 2014
@@ -0,0 +1,53 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.syncope.core.sync.impl;
+
+import org.apache.syncope.core.persistence.beans.SyncTask;
+import org.apache.syncope.core.sync.SyncActions;
+import org.identityconnectors.framework.common.objects.SyncResultsHandler;
+
+/**
+ * Abstract class introduced to facilitate sync handler extension/override.
+ */
+public abstract class AbstractSyncopeSyncResultHandler extends AbstractSyncopeResultHandler
+ implements SyncResultsHandler {
+
+ /**
+ * SyncJob actions.
+ */
+ protected SyncActions actions;
+
+ protected SyncTask syncTask;
+
+ public SyncActions getActions() {
+ return actions;
+ }
+
+ public void setActions(final SyncActions actions) {
+ this.actions = actions;
+ }
+
+ public SyncTask getSyncTask() {
+ return syncTask;
+ }
+
+ public void setSyncTask(final SyncTask syncTask) {
+ this.syncTask = syncTask;
+ }
+}
Modified: syncope/trunk/core/src/main/java/org/apache/syncope/core/sync/impl/LDAPMembershipSyncActions.java
URL: http://svn.apache.org/viewvc/syncope/trunk/core/src/main/java/org/apache/syncope/core/sync/impl/LDAPMembershipSyncActions.java?rev=1556227&r1=1556226&r2=1556227&view=diff
==============================================================================
--- syncope/trunk/core/src/main/java/org/apache/syncope/core/sync/impl/LDAPMembershipSyncActions.java (original)
+++ syncope/trunk/core/src/main/java/org/apache/syncope/core/sync/impl/LDAPMembershipSyncActions.java Tue Jan 7 14:33:44 2014
@@ -53,7 +53,6 @@ import org.identityconnectors.framework.
import org.identityconnectors.framework.common.objects.ObjectClass;
import org.identityconnectors.framework.common.objects.OperationOptionsBuilder;
import org.identityconnectors.framework.common.objects.SyncDelta;
-import org.identityconnectors.framework.common.objects.SyncResultsHandler;
import org.quartz.JobExecutionException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -122,7 +121,7 @@ public class LDAPMembershipSyncActions e
@Transactional(readOnly = true)
@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 {
if (subject instanceof RoleTO) {
@@ -283,8 +282,11 @@ public class LDAPMembershipSyncActions e
* {@inheritDoc}
*/
@Override
- public <T extends AbstractAttributableTO> void after(final SyncResultsHandler handler, final SyncDelta delta,
- final T subject, final SyncResult result) throws JobExecutionException {
+ public <T extends AbstractAttributableTO> void after(
+ final AbstractSyncopeSyncResultHandler handler,
+ final SyncDelta delta,
+ final T subject,
+ final SyncResult result) throws JobExecutionException {
if (!(handler instanceof SyncopeSyncResultHandler)) {
return;
Copied: syncope/trunk/core/src/main/java/org/apache/syncope/core/sync/impl/PushJob.java (from r1554763, syncope/trunk/core/src/main/java/org/apache/syncope/core/sync/impl/SyncJob.java)
URL: http://svn.apache.org/viewvc/syncope/trunk/core/src/main/java/org/apache/syncope/core/sync/impl/PushJob.java?p2=syncope/trunk/core/src/main/java/org/apache/syncope/core/sync/impl/PushJob.java&p1=syncope/trunk/core/src/main/java/org/apache/syncope/core/sync/impl/SyncJob.java&r1=1554763&r2=1556227&rev=1556227&view=diff
==============================================================================
--- syncope/trunk/core/src/main/java/org/apache/syncope/core/sync/impl/SyncJob.java (original)
+++ syncope/trunk/core/src/main/java/org/apache/syncope/core/sync/impl/PushJob.java Tue Jan 7 14:33:44 2014
@@ -20,452 +20,140 @@ package org.apache.syncope.core.sync.imp
import java.util.ArrayList;
import java.util.List;
-import java.util.Map;
-import org.apache.commons.lang3.StringUtils;
-import org.apache.syncope.common.mod.ReferenceMod;
-import org.apache.syncope.common.mod.RoleMod;
-import org.apache.syncope.common.types.ConflictResolutionAction;
-import org.apache.syncope.common.types.SyncPolicySpec;
-import org.apache.syncope.common.types.TraceLevel;
-import org.apache.syncope.core.persistence.beans.Entitlement;
-import org.apache.syncope.core.persistence.beans.ExternalResource;
-import org.apache.syncope.core.persistence.beans.SyncPolicy;
-import org.apache.syncope.core.persistence.beans.SyncTask;
-import org.apache.syncope.core.persistence.beans.TaskExec;
+import java.util.Set;
+import org.apache.syncope.core.persistence.beans.PushTask;
import org.apache.syncope.core.persistence.beans.role.RMapping;
+import org.apache.syncope.core.persistence.beans.role.SyncopeRole;
+import org.apache.syncope.core.persistence.beans.user.SyncopeUser;
import org.apache.syncope.core.persistence.beans.user.UMapping;
-import org.apache.syncope.core.persistence.dao.EntitlementDAO;
-import org.apache.syncope.core.persistence.dao.NotFoundException;
-import org.apache.syncope.core.persistence.dao.ResourceDAO;
-import org.apache.syncope.core.propagation.ConnectorFactory;
+import org.apache.syncope.core.persistence.dao.RoleDAO;
+import org.apache.syncope.core.persistence.dao.UserDAO;
import org.apache.syncope.core.propagation.Connector;
-import org.apache.syncope.core.quartz.AbstractTaskJob;
-import org.apache.syncope.core.rest.controller.UnauthorizedRoleException;
-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.util.ApplicationContextProvider;
-import org.apache.syncope.core.workflow.role.RoleWorkflowAdapter;
-import org.identityconnectors.framework.common.objects.ObjectClass;
-import org.identityconnectors.framework.common.objects.SyncToken;
+import org.apache.syncope.core.util.EntitlementUtil;
import org.quartz.JobExecutionException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.support.AbstractBeanDefinition;
import org.springframework.beans.factory.support.DefaultListableBeanFactory;
-import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
-import org.springframework.security.core.GrantedAuthority;
-import org.springframework.security.core.authority.SimpleGrantedAuthority;
-import org.springframework.security.core.context.SecurityContextHolder;
-import org.springframework.security.core.userdetails.User;
-import org.springframework.security.core.userdetails.UserDetails;
/**
- * Job for executing synchronization tasks.
+ * Job for executing synchronization (towards external resource) tasks.
*
- * @see AbstractTaskJob
- * @see SyncTask
+ * @see AbstractSyncJob
+ * @see PushTask
*/
-public class SyncJob extends AbstractTaskJob {
+public class PushJob extends AbstractSyncJob<AbstractSyncopeResultHandler, PushActions> {
/**
- * ConnInstance loader.
+ * User DAO.
*/
@Autowired
- private ConnectorFactory connFactory;
+ private UserDAO userDAO;
/**
- * Resource DAO.
+ * Role DAO.
*/
@Autowired
- private ResourceDAO resourceDAO;
+ private RoleDAO roleDAO;
- /**
- * Entitlement DAO.
- */
- @Autowired
- private EntitlementDAO entitlementDAO;
-
- /**
- * Role workflow adapter.
- */
- @Autowired
- private RoleWorkflowAdapter rwfAdapter;
-
- /**
- * SyncJob actions.
- */
- private SyncActions actions;
-
- public void setActions(final SyncActions actions) {
- this.actions = actions;
- }
-
- /**
- * Create a textual report of the synchronization, based on the trace level.
- *
- * @param syncResults Sync results
- * @param syncTraceLevel Sync trace level
- * @param dryRun dry run?
- * @return report as string
- */
- protected String createReport(final List<SyncResult> syncResults, final TraceLevel syncTraceLevel,
- final boolean dryRun) {
-
- if (syncTraceLevel == TraceLevel.NONE) {
- return null;
- }
-
- StringBuilder report = new StringBuilder();
-
- if (dryRun) {
- report.append("==>Dry run only, no modifications were made<==\n\n");
- }
-
- List<SyncResult> uSuccCreate = new ArrayList<SyncResult>();
- List<SyncResult> uFailCreate = new ArrayList<SyncResult>();
- List<SyncResult> uSuccUpdate = new ArrayList<SyncResult>();
- List<SyncResult> uFailUpdate = new ArrayList<SyncResult>();
- List<SyncResult> uSuccDelete = new ArrayList<SyncResult>();
- List<SyncResult> uFailDelete = new ArrayList<SyncResult>();
- List<SyncResult> rSuccCreate = new ArrayList<SyncResult>();
- List<SyncResult> rFailCreate = new ArrayList<SyncResult>();
- List<SyncResult> rSuccUpdate = new ArrayList<SyncResult>();
- List<SyncResult> rFailUpdate = new ArrayList<SyncResult>();
- List<SyncResult> rSuccDelete = new ArrayList<SyncResult>();
- List<SyncResult> rFailDelete = new ArrayList<SyncResult>();
-
- for (SyncResult syncResult : syncResults) {
- switch (syncResult.getStatus()) {
- case SUCCESS:
- switch (syncResult.getOperation()) {
- case CREATE:
- switch (syncResult.getSubjectType()) {
- case USER:
- uSuccCreate.add(syncResult);
- break;
-
- case ROLE:
- rSuccCreate.add(syncResult);
- break;
-
- default:
- }
- break;
-
- case UPDATE:
- switch (syncResult.getSubjectType()) {
- case USER:
- uSuccUpdate.add(syncResult);
- break;
-
- case ROLE:
- rSuccUpdate.add(syncResult);
- break;
-
- default:
- }
- break;
-
- case DELETE:
- switch (syncResult.getSubjectType()) {
- case USER:
- uSuccDelete.add(syncResult);
- break;
-
- case ROLE:
- rSuccDelete.add(syncResult);
- break;
-
- default:
- }
- break;
-
- default:
- }
- break;
-
- case FAILURE:
- switch (syncResult.getOperation()) {
- case CREATE:
- switch (syncResult.getSubjectType()) {
- case USER:
- uFailCreate.add(syncResult);
- break;
-
- case ROLE:
- rFailCreate.add(syncResult);
- break;
-
- default:
- }
- break;
-
- case UPDATE:
- switch (syncResult.getSubjectType()) {
- case USER:
- uFailUpdate.add(syncResult);
- break;
-
- case ROLE:
- rFailUpdate.add(syncResult);
- break;
-
- default:
- }
- break;
-
- case DELETE:
- switch (syncResult.getSubjectType()) {
- case USER:
- uFailDelete.add(syncResult);
- break;
-
- case ROLE:
- rFailDelete.add(syncResult);
- break;
-
- default:
- }
- break;
-
- default:
- }
- break;
-
- default:
- }
- }
-
- // Summary, also to be included for FAILURE and ALL, so create it anyway.
- report.append("Users ").
- append("[created/failures]: ").append(uSuccCreate.size()).append('/').append(uFailCreate.size()).
- append(' ').
- append("[updated/failures]: ").append(uSuccUpdate.size()).append('/').append(uFailUpdate.size()).
- append(' ').
- append("[deleted/failures]: ").append(uSuccDelete.size()).append('/').append(uFailDelete.size()).
- append('\n');
- report.append("Roles ").
- append("[created/failures]: ").append(rSuccCreate.size()).append('/').append(rFailCreate.size()).
- append(' ').
- append("[updated/failures]: ").append(rSuccUpdate.size()).append('/').append(rFailUpdate.size()).
- append(' ').
- append("[deleted/failures]: ").append(rSuccDelete.size()).append('/').append(rFailDelete.size());
-
- // Failures
- if (syncTraceLevel == TraceLevel.FAILURES || syncTraceLevel == TraceLevel.ALL) {
- if (!uFailCreate.isEmpty()) {
- report.append("\n\nUsers failed to create: ");
- report.append(SyncResult.produceReport(uFailCreate, syncTraceLevel));
- }
- if (!uFailUpdate.isEmpty()) {
- report.append("\nUsers failed to update: ");
- report.append(SyncResult.produceReport(uFailUpdate, syncTraceLevel));
- }
- if (!uFailDelete.isEmpty()) {
- report.append("\nUsers failed to delete: ");
- report.append(SyncResult.produceReport(uFailDelete, syncTraceLevel));
- }
-
- if (!rFailCreate.isEmpty()) {
- report.append("\n\nRoles failed to create: ");
- report.append(SyncResult.produceReport(rFailCreate, syncTraceLevel));
- }
- if (!rFailUpdate.isEmpty()) {
- report.append("\nRoles failed to update: ");
- report.append(SyncResult.produceReport(rFailUpdate, syncTraceLevel));
- }
- if (!rFailDelete.isEmpty()) {
- report.append("\nRoles failed to delete: ");
- report.append(SyncResult.produceReport(rFailDelete, syncTraceLevel));
- }
- }
-
- // Succeeded, only if on 'ALL' level
- if (syncTraceLevel == TraceLevel.ALL) {
- report.append("\n\nUsers created:\n")
- .append(SyncResult.produceReport(uSuccCreate, syncTraceLevel))
- .append("\nUsers updated:\n")
- .append(SyncResult.produceReport(uSuccUpdate, syncTraceLevel))
- .append("\nUsers deleted:\n")
- .append(SyncResult.produceReport(uSuccDelete, syncTraceLevel));
- report.append("\n\nRoles created:\n")
- .append(SyncResult.produceReport(rSuccCreate, syncTraceLevel))
- .append("\nRoles updated:\n")
- .append(SyncResult.produceReport(rSuccUpdate, syncTraceLevel))
- .append("\nRoles deleted:\n")
- .append(SyncResult.produceReport(rSuccDelete, syncTraceLevel));
- }
-
- return report.toString();
- }
-
- protected void setRoleOwners(final SyncopeSyncResultHandler handler)
- throws UnauthorizedRoleException, NotFoundException {
-
- for (Map.Entry<Long, String> entry : handler.getRoleOwnerMap().entrySet()) {
- RoleMod roleMod = new RoleMod();
- roleMod.setId(entry.getKey());
-
- if (StringUtils.isBlank(entry.getValue())) {
- roleMod.setRoleOwner(null);
- roleMod.setUserOwner(null);
- } else {
- Long userId = handler.findMatchingAttributableId(ObjectClass.ACCOUNT, entry.getValue());
- if (userId == null) {
- Long roleId = handler.findMatchingAttributableId(ObjectClass.GROUP, entry.getValue());
- if (roleId != null) {
- roleMod.setRoleOwner(new ReferenceMod(roleId));
- }
- } else {
- roleMod.setUserOwner(new ReferenceMod(userId));
- }
- }
-
- rwfAdapter.update(roleMod);
- }
- }
+ private final int PAGE_SIZE = 1000;
@Override
- protected String doExecute(final boolean dryRun) throws JobExecutionException {
- // PRE: grant all authorities (i.e. setup the SecurityContextHolder)
- final List<GrantedAuthority> authorities = new ArrayList<GrantedAuthority>();
-
- for (Entitlement entitlement : entitlementDAO.findAll()) {
- authorities.add(new SimpleGrantedAuthority(entitlement.getName()));
- }
-
- final UserDetails userDetails = new User("admin", "FAKE_PASSWORD", true, true, true, true, authorities);
-
- SecurityContextHolder.getContext().setAuthentication(
- new UsernamePasswordAuthenticationToken(userDetails, "FAKE_PASSWORD", authorities));
-
- try {
- return executeWithSecurityContext(dryRun);
- } finally {
- // POST: clean up the SecurityContextHolder
- SecurityContextHolder.clearContext();
- }
- }
-
protected String executeWithSecurityContext(final boolean dryRun) throws JobExecutionException {
- if (!(task instanceof SyncTask)) {
- throw new JobExecutionException("Task " + taskId + " isn't a SyncTask");
+ if (!(task instanceof PushTask)) {
+ throw new JobExecutionException("Task " + taskId + " isn't a PushTask");
}
- final SyncTask syncTask = (SyncTask) this.task;
+
+ final PushTask pushTask = (PushTask) this.task;
Connector connector;
try {
- connector = connFactory.getConnector(syncTask.getResource());
+ connector = connFactory.getConnector(pushTask.getResource());
} catch (Exception e) {
final String msg = String.format("Connector instance bean for resource %s and connInstance %s not found",
- syncTask.getResource(), syncTask.getResource().getConnector());
+ pushTask.getResource(), pushTask.getResource().getConnector());
throw new JobExecutionException(msg, e);
}
- UMapping uMapping = syncTask.getResource().getUmapping();
+ UMapping uMapping = pushTask.getResource().getUmapping();
if (uMapping != null && uMapping.getAccountIdItem() == null) {
- throw new JobExecutionException("Invalid user account id mapping for resource " + syncTask.getResource());
+ throw new JobExecutionException("Invalid user account id mapping for resource " + pushTask.getResource());
}
- RMapping rMapping = syncTask.getResource().getRmapping();
+ RMapping rMapping = pushTask.getResource().getRmapping();
if (rMapping != null && rMapping.getAccountIdItem() == null) {
- throw new JobExecutionException("Invalid role account id mapping for resource " + syncTask.getResource());
+ throw new JobExecutionException("Invalid role account id mapping for resource " + pushTask.getResource());
}
if (uMapping == null && rMapping == null) {
return "No mapping configured for both users and roles: aborting...";
}
- LOG.debug("Execute synchronization with token {}", syncTask.getResource().getUsyncToken());
+ LOG.debug("Execute synchronization (push) with resource {}", pushTask.getResource());
final List<SyncResult> results = new ArrayList<SyncResult>();
- final SyncPolicy syncPolicy = syncTask.getResource().getSyncPolicy();
- final ConflictResolutionAction resAct = syncPolicy == null || syncPolicy.getSpecification() == null
- ? ConflictResolutionAction.IGNORE
- : ((SyncPolicySpec) syncPolicy.getSpecification()).getConflictResolutionAction();
+ final Set<Long> authorizations = EntitlementUtil.getRoleIds(entitlementDAO.findAll());
// Prepare handler for SyncDelta objects
- final SyncopeSyncResultHandler handler =
- (SyncopeSyncResultHandler) ((DefaultListableBeanFactory) ApplicationContextProvider.
+ final SyncopePushResultHandler handler =
+ (SyncopePushResultHandler) ((DefaultListableBeanFactory) ApplicationContextProvider.
getApplicationContext().getBeanFactory()).createBean(
- SyncopeSyncResultHandler.class, AbstractBeanDefinition.AUTOWIRE_BY_NAME, false);
+ SyncopePushResultHandler.class, AbstractBeanDefinition.AUTOWIRE_BY_NAME, false);
handler.setConnector(connector);
- handler.setActions(actions);
handler.setDryRun(dryRun);
- handler.setResAct(resAct);
handler.setResults(results);
- handler.setSyncTask(syncTask);
+ handler.setSyncTask(pushTask);
+ handler.setActions(actions);
actions.beforeAll(handler);
- try {
- SyncToken latestUSyncToken = null;
- if (uMapping != null && !syncTask.isFullReconciliation()) {
- latestUSyncToken = connector.getLatestSyncToken(ObjectClass.ACCOUNT);
- }
- SyncToken latestRSyncToken = null;
- if (rMapping != null && !syncTask.isFullReconciliation()) {
- latestRSyncToken = connector.getLatestSyncToken(ObjectClass.GROUP);
- }
- if (syncTask.isFullReconciliation()) {
- if (uMapping != null) {
- connector.getAllObjects(ObjectClass.ACCOUNT, handler,
- connector.getOperationOptions(uMapping.getItems()));
- }
- if (rMapping != null) {
- connector.getAllObjects(ObjectClass.GROUP, handler,
- connector.getOperationOptions(rMapping.getItems()));
- }
- } else {
- if (uMapping != null) {
- connector.sync(ObjectClass.ACCOUNT, syncTask.getResource().getUsyncToken(), handler,
- connector.getOperationOptions(uMapping.getItems()));
- }
- if (rMapping != null) {
- connector.sync(ObjectClass.GROUP, syncTask.getResource().getRsyncToken(), handler,
- connector.getOperationOptions(rMapping.getItems()));
+ if (uMapping != null) {
+ final int count = userDAO.count(authorizations);
+ for (int page = 1; page <= (count / PAGE_SIZE) + 1; page++) {
+ final List<SyncopeUser> localUsers = userDAO.findAll(authorizations, page, PAGE_SIZE);
+
+ for (SyncopeUser localUser : localUsers) {
+ try {
+ // user propagation
+ handler.handle(localUser);
+ } catch (Exception e) {
+ LOG.warn("Failure pushing user '{}' on '{}'", localUser, pushTask.getResource());
+ if (!continueOnError()) {
+ throw new JobExecutionException("While pushing users on connector", e);
+ }
+ }
}
}
+ }
+
+ if (rMapping != null) {
+ final List<SyncopeRole> localRoles = roleDAO.findAll();
- if (!dryRun && !syncTask.isFullReconciliation()) {
+ for (SyncopeRole localRole : localRoles) {
try {
- ExternalResource resource = resourceDAO.find(syncTask.getResource().getName());
- if (uMapping != null) {
- resource.setUsyncToken(latestUSyncToken);
- }
- if (rMapping != null) {
- resource.setRsyncToken(latestRSyncToken);
- }
- resourceDAO.save(resource);
+ // role propagation
+ handler.handle(localRole);
} catch (Exception e) {
- throw new JobExecutionException("While updating SyncToken", e);
+ LOG.warn("Failure pushing role '{}' on '{}'", localRole, pushTask.getResource());
+ if (!continueOnError()) {
+ throw new JobExecutionException("While pushing roles on connector", e);
+ }
}
}
- } catch (Exception e) {
- throw new JobExecutionException("While syncing on connector", e);
- }
-
- try {
- setRoleOwners(handler);
- } catch (Exception e) {
- LOG.error("While setting role owners", e);
}
actions.afterAll(handler, results);
- final String result = createReport(results, syncTask.getResource().getSyncTraceLevel(), dryRun);
+ final String result = createReport(results, pushTask.getResource().getSyncTraceLevel(), dryRun);
LOG.debug("Sync result: {}", result);
return result;
}
- @Override
- protected boolean hasToBeRegistered(final TaskExec execution) {
- SyncTask syncTask = (SyncTask) task;
-
- // True if either failed and failures have to be registered, or if ALL has to be registered.
- return (Status.valueOf(execution.getStatus()) == Status.FAILURE
- && syncTask.getResource().getSyncTraceLevel().ordinal() >= TraceLevel.FAILURES.ordinal())
- || syncTask.getResource().getSyncTraceLevel().ordinal() >= TraceLevel.SUMMARY.ordinal();
+ protected boolean continueOnError() {
+ return true;
}
}
Modified: syncope/trunk/core/src/main/java/org/apache/syncope/core/sync/impl/SyncJob.java
URL: http://svn.apache.org/viewvc/syncope/trunk/core/src/main/java/org/apache/syncope/core/sync/impl/SyncJob.java?rev=1556227&r1=1556226&r2=1556227&view=diff
==============================================================================
--- syncope/trunk/core/src/main/java/org/apache/syncope/core/sync/impl/SyncJob.java (original)
+++ syncope/trunk/core/src/main/java/org/apache/syncope/core/sync/impl/SyncJob.java Tue Jan 7 14:33:44 2014
@@ -26,20 +26,13 @@ import org.apache.syncope.common.mod.Ref
import org.apache.syncope.common.mod.RoleMod;
import org.apache.syncope.common.types.ConflictResolutionAction;
import org.apache.syncope.common.types.SyncPolicySpec;
-import org.apache.syncope.common.types.TraceLevel;
-import org.apache.syncope.core.persistence.beans.Entitlement;
import org.apache.syncope.core.persistence.beans.ExternalResource;
import org.apache.syncope.core.persistence.beans.SyncPolicy;
import org.apache.syncope.core.persistence.beans.SyncTask;
-import org.apache.syncope.core.persistence.beans.TaskExec;
import org.apache.syncope.core.persistence.beans.role.RMapping;
import org.apache.syncope.core.persistence.beans.user.UMapping;
-import org.apache.syncope.core.persistence.dao.EntitlementDAO;
import org.apache.syncope.core.persistence.dao.NotFoundException;
-import org.apache.syncope.core.persistence.dao.ResourceDAO;
-import org.apache.syncope.core.propagation.ConnectorFactory;
import org.apache.syncope.core.propagation.Connector;
-import org.apache.syncope.core.quartz.AbstractTaskJob;
import org.apache.syncope.core.rest.controller.UnauthorizedRoleException;
import org.apache.syncope.core.sync.SyncActions;
import org.apache.syncope.core.sync.SyncResult;
@@ -51,38 +44,14 @@ import org.quartz.JobExecutionException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.support.AbstractBeanDefinition;
import org.springframework.beans.factory.support.DefaultListableBeanFactory;
-import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
-import org.springframework.security.core.GrantedAuthority;
-import org.springframework.security.core.authority.SimpleGrantedAuthority;
-import org.springframework.security.core.context.SecurityContextHolder;
-import org.springframework.security.core.userdetails.User;
-import org.springframework.security.core.userdetails.UserDetails;
/**
- * Job for executing synchronization tasks.
+ * Job for executing synchronization (from external resource) tasks.
*
- * @see AbstractTaskJob
+ * @see AbstractSyncJob
* @see SyncTask
*/
-public class SyncJob extends AbstractTaskJob {
-
- /**
- * ConnInstance loader.
- */
- @Autowired
- private ConnectorFactory connFactory;
-
- /**
- * Resource DAO.
- */
- @Autowired
- private ResourceDAO resourceDAO;
-
- /**
- * Entitlement DAO.
- */
- @Autowired
- private EntitlementDAO entitlementDAO;
+public class SyncJob extends AbstractSyncJob<AbstractSyncopeSyncResultHandler, SyncActions> {
/**
* Role workflow adapter.
@@ -90,214 +59,6 @@ public class SyncJob extends AbstractTas
@Autowired
private RoleWorkflowAdapter rwfAdapter;
- /**
- * SyncJob actions.
- */
- private SyncActions actions;
-
- public void setActions(final SyncActions actions) {
- this.actions = actions;
- }
-
- /**
- * Create a textual report of the synchronization, based on the trace level.
- *
- * @param syncResults Sync results
- * @param syncTraceLevel Sync trace level
- * @param dryRun dry run?
- * @return report as string
- */
- protected String createReport(final List<SyncResult> syncResults, final TraceLevel syncTraceLevel,
- final boolean dryRun) {
-
- if (syncTraceLevel == TraceLevel.NONE) {
- return null;
- }
-
- StringBuilder report = new StringBuilder();
-
- if (dryRun) {
- report.append("==>Dry run only, no modifications were made<==\n\n");
- }
-
- List<SyncResult> uSuccCreate = new ArrayList<SyncResult>();
- List<SyncResult> uFailCreate = new ArrayList<SyncResult>();
- List<SyncResult> uSuccUpdate = new ArrayList<SyncResult>();
- List<SyncResult> uFailUpdate = new ArrayList<SyncResult>();
- List<SyncResult> uSuccDelete = new ArrayList<SyncResult>();
- List<SyncResult> uFailDelete = new ArrayList<SyncResult>();
- List<SyncResult> rSuccCreate = new ArrayList<SyncResult>();
- List<SyncResult> rFailCreate = new ArrayList<SyncResult>();
- List<SyncResult> rSuccUpdate = new ArrayList<SyncResult>();
- List<SyncResult> rFailUpdate = new ArrayList<SyncResult>();
- List<SyncResult> rSuccDelete = new ArrayList<SyncResult>();
- List<SyncResult> rFailDelete = new ArrayList<SyncResult>();
-
- for (SyncResult syncResult : syncResults) {
- switch (syncResult.getStatus()) {
- case SUCCESS:
- switch (syncResult.getOperation()) {
- case CREATE:
- switch (syncResult.getSubjectType()) {
- case USER:
- uSuccCreate.add(syncResult);
- break;
-
- case ROLE:
- rSuccCreate.add(syncResult);
- break;
-
- default:
- }
- break;
-
- case UPDATE:
- switch (syncResult.getSubjectType()) {
- case USER:
- uSuccUpdate.add(syncResult);
- break;
-
- case ROLE:
- rSuccUpdate.add(syncResult);
- break;
-
- default:
- }
- break;
-
- case DELETE:
- switch (syncResult.getSubjectType()) {
- case USER:
- uSuccDelete.add(syncResult);
- break;
-
- case ROLE:
- rSuccDelete.add(syncResult);
- break;
-
- default:
- }
- break;
-
- default:
- }
- break;
-
- case FAILURE:
- switch (syncResult.getOperation()) {
- case CREATE:
- switch (syncResult.getSubjectType()) {
- case USER:
- uFailCreate.add(syncResult);
- break;
-
- case ROLE:
- rFailCreate.add(syncResult);
- break;
-
- default:
- }
- break;
-
- case UPDATE:
- switch (syncResult.getSubjectType()) {
- case USER:
- uFailUpdate.add(syncResult);
- break;
-
- case ROLE:
- rFailUpdate.add(syncResult);
- break;
-
- default:
- }
- break;
-
- case DELETE:
- switch (syncResult.getSubjectType()) {
- case USER:
- uFailDelete.add(syncResult);
- break;
-
- case ROLE:
- rFailDelete.add(syncResult);
- break;
-
- default:
- }
- break;
-
- default:
- }
- break;
-
- default:
- }
- }
-
- // Summary, also to be included for FAILURE and ALL, so create it anyway.
- report.append("Users ").
- append("[created/failures]: ").append(uSuccCreate.size()).append('/').append(uFailCreate.size()).
- append(' ').
- append("[updated/failures]: ").append(uSuccUpdate.size()).append('/').append(uFailUpdate.size()).
- append(' ').
- append("[deleted/failures]: ").append(uSuccDelete.size()).append('/').append(uFailDelete.size()).
- append('\n');
- report.append("Roles ").
- append("[created/failures]: ").append(rSuccCreate.size()).append('/').append(rFailCreate.size()).
- append(' ').
- append("[updated/failures]: ").append(rSuccUpdate.size()).append('/').append(rFailUpdate.size()).
- append(' ').
- append("[deleted/failures]: ").append(rSuccDelete.size()).append('/').append(rFailDelete.size());
-
- // Failures
- if (syncTraceLevel == TraceLevel.FAILURES || syncTraceLevel == TraceLevel.ALL) {
- if (!uFailCreate.isEmpty()) {
- report.append("\n\nUsers failed to create: ");
- report.append(SyncResult.produceReport(uFailCreate, syncTraceLevel));
- }
- if (!uFailUpdate.isEmpty()) {
- report.append("\nUsers failed to update: ");
- report.append(SyncResult.produceReport(uFailUpdate, syncTraceLevel));
- }
- if (!uFailDelete.isEmpty()) {
- report.append("\nUsers failed to delete: ");
- report.append(SyncResult.produceReport(uFailDelete, syncTraceLevel));
- }
-
- if (!rFailCreate.isEmpty()) {
- report.append("\n\nRoles failed to create: ");
- report.append(SyncResult.produceReport(rFailCreate, syncTraceLevel));
- }
- if (!rFailUpdate.isEmpty()) {
- report.append("\nRoles failed to update: ");
- report.append(SyncResult.produceReport(rFailUpdate, syncTraceLevel));
- }
- if (!rFailDelete.isEmpty()) {
- report.append("\nRoles failed to delete: ");
- report.append(SyncResult.produceReport(rFailDelete, syncTraceLevel));
- }
- }
-
- // Succeeded, only if on 'ALL' level
- if (syncTraceLevel == TraceLevel.ALL) {
- report.append("\n\nUsers created:\n")
- .append(SyncResult.produceReport(uSuccCreate, syncTraceLevel))
- .append("\nUsers updated:\n")
- .append(SyncResult.produceReport(uSuccUpdate, syncTraceLevel))
- .append("\nUsers deleted:\n")
- .append(SyncResult.produceReport(uSuccDelete, syncTraceLevel));
- report.append("\n\nRoles created:\n")
- .append(SyncResult.produceReport(rSuccCreate, syncTraceLevel))
- .append("\nRoles updated:\n")
- .append(SyncResult.produceReport(rSuccUpdate, syncTraceLevel))
- .append("\nRoles deleted:\n")
- .append(SyncResult.produceReport(rSuccDelete, syncTraceLevel));
- }
-
- return report.toString();
- }
-
protected void setRoleOwners(final SyncopeSyncResultHandler handler)
throws UnauthorizedRoleException, NotFoundException {
@@ -325,27 +86,6 @@ public class SyncJob extends AbstractTas
}
@Override
- protected String doExecute(final boolean dryRun) throws JobExecutionException {
- // PRE: grant all authorities (i.e. setup the SecurityContextHolder)
- final List<GrantedAuthority> authorities = new ArrayList<GrantedAuthority>();
-
- for (Entitlement entitlement : entitlementDAO.findAll()) {
- authorities.add(new SimpleGrantedAuthority(entitlement.getName()));
- }
-
- final UserDetails userDetails = new User("admin", "FAKE_PASSWORD", true, true, true, true, authorities);
-
- SecurityContextHolder.getContext().setAuthentication(
- new UsernamePasswordAuthenticationToken(userDetails, "FAKE_PASSWORD", authorities));
-
- try {
- return executeWithSecurityContext(dryRun);
- } finally {
- // POST: clean up the SecurityContextHolder
- SecurityContextHolder.clearContext();
- }
- }
-
protected String executeWithSecurityContext(final boolean dryRun) throws JobExecutionException {
if (!(task instanceof SyncTask)) {
throw new JobExecutionException("Task " + taskId + " isn't a SyncTask");
@@ -387,7 +127,7 @@ public class SyncJob extends AbstractTas
final SyncopeSyncResultHandler handler =
(SyncopeSyncResultHandler) ((DefaultListableBeanFactory) ApplicationContextProvider.
getApplicationContext().getBeanFactory()).createBean(
- SyncopeSyncResultHandler.class, AbstractBeanDefinition.AUTOWIRE_BY_NAME, false);
+ SyncopeSyncResultHandler.class, AbstractBeanDefinition.AUTOWIRE_BY_NAME, false);
handler.setConnector(connector);
handler.setActions(actions);
handler.setDryRun(dryRun);
@@ -458,14 +198,4 @@ public class SyncJob extends AbstractTas
return result;
}
-
- @Override
- protected boolean hasToBeRegistered(final TaskExec execution) {
- SyncTask syncTask = (SyncTask) task;
-
- // True if either failed and failures have to be registered, or if ALL has to be registered.
- return (Status.valueOf(execution.getStatus()) == Status.FAILURE
- && syncTask.getResource().getSyncTraceLevel().ordinal() >= TraceLevel.FAILURES.ordinal())
- || syncTask.getResource().getSyncTraceLevel().ordinal() >= TraceLevel.SUMMARY.ordinal();
- }
}