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();
-    }
 }