You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@syncope.apache.org by il...@apache.org on 2017/07/12 13:42:56 UTC

[1/2] syncope git commit: [SYNCOPE-1158][SYNCOPE-1153] Better PushTask reports

Repository: syncope
Updated Branches:
  refs/heads/2_0_X 26cd1d419 -> f191fd002
  refs/heads/master f9c61fbc6 -> 3e90e38fd


[SYNCOPE-1158][SYNCOPE-1153] Better PushTask reports


Project: http://git-wip-us.apache.org/repos/asf/syncope/repo
Commit: http://git-wip-us.apache.org/repos/asf/syncope/commit/f191fd00
Tree: http://git-wip-us.apache.org/repos/asf/syncope/tree/f191fd00
Diff: http://git-wip-us.apache.org/repos/asf/syncope/diff/f191fd00

Branch: refs/heads/2_0_X
Commit: f191fd00284c345cae1002c5989d780c3d6daa5f
Parents: 26cd1d4
Author: Francesco Chicchiriccò <il...@apache.org>
Authored: Wed Jul 12 15:42:33 2017 +0200
Committer: Francesco Chicchiriccò <il...@apache.org>
Committed: Wed Jul 12 15:42:33 2017 +0200

----------------------------------------------------------------------
 .../syncope/core/logic/UserWorkflowLogic.java   |   4 +-
 .../persistence/jpa/dao/JPAAccessTokenDAO.java  |   4 +-
 .../persistence/jpa/dao/JPAAnyObjectDAO.java    |   2 +-
 .../core/persistence/jpa/dao/JPAGroupDAO.java   |   2 +-
 .../core/persistence/jpa/dao/JPATaskDAO.java    |   4 +-
 .../core/persistence/jpa/dao/JPAUserDAO.java    |   2 +-
 .../propagation/PropagationTaskExecutor.java    |   8 -
 .../java/DefaultUserProvisioningManager.java    |   2 +-
 .../AbstractPropagationTaskExecutor.java        |   5 -
 .../pushpull/AbstractPullResultHandler.java     |   6 +-
 .../pushpull/AbstractPushResultHandler.java     | 165 +++++++++++--------
 .../pushpull/RealmPullResultHandlerImpl.java    |   2 +-
 .../pushpull/RealmPushResultHandlerImpl.java    | 162 +++++++++++-------
 .../pushpull/UserPushResultHandlerImpl.java     |  10 +-
 .../camel/producer/SuspendProducer.java         |   2 +-
 15 files changed, 216 insertions(+), 164 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/syncope/blob/f191fd00/core/logic/src/main/java/org/apache/syncope/core/logic/UserWorkflowLogic.java
----------------------------------------------------------------------
diff --git a/core/logic/src/main/java/org/apache/syncope/core/logic/UserWorkflowLogic.java b/core/logic/src/main/java/org/apache/syncope/core/logic/UserWorkflowLogic.java
index 41b89ca..433e943 100644
--- a/core/logic/src/main/java/org/apache/syncope/core/logic/UserWorkflowLogic.java
+++ b/core/logic/src/main/java/org/apache/syncope/core/logic/UserWorkflowLogic.java
@@ -76,7 +76,7 @@ public class UserWorkflowLogic extends AbstractTransactionalLogic<WorkflowFormTO
                         new ImmutablePair<UserPatch, Boolean>(userPatch, null),
                         updated.getPropByRes(), updated.getPerformedTasks()));
 
-        taskExecutor.execute(tasks);
+        taskExecutor.execute(tasks, false);
 
         return binder.getUserTO(updated.getResult());
     }
@@ -111,7 +111,7 @@ public class UserWorkflowLogic extends AbstractTransactionalLogic<WorkflowFormTO
                             updated.getPropByRes(),
                             updated.getPerformedTasks()));
 
-            taskExecutor.execute(tasks);
+            taskExecutor.execute(tasks, false);
         }
 
         return binder.getUserTO(updated.getResult().getKey());

http://git-wip-us.apache.org/repos/asf/syncope/blob/f191fd00/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAAccessTokenDAO.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAAccessTokenDAO.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAAccessTokenDAO.java
index 01c53fd..2ecc44e 100644
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAAccessTokenDAO.java
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAAccessTokenDAO.java
@@ -100,9 +100,7 @@ public class JPAAccessTokenDAO extends AbstractDAO<AccessToken> implements Acces
 
         TypedQuery<AccessToken> query = entityManager().createQuery(queryString.toString(), AccessToken.class);
 
-        query.setFirstResult(itemsPerPage * (page <= 0
-                ? 0
-                : page - 1));
+        query.setFirstResult(itemsPerPage * (page <= 0 ? 0 : page - 1));
 
         if (itemsPerPage > 0) {
             query.setMaxResults(itemsPerPage);

http://git-wip-us.apache.org/repos/asf/syncope/blob/f191fd00/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAAnyObjectDAO.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAAnyObjectDAO.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAAnyObjectDAO.java
index b052f30..457944b 100644
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAAnyObjectDAO.java
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAAnyObjectDAO.java
@@ -204,7 +204,7 @@ public class JPAAnyObjectDAO extends AbstractAnyDAO<AnyObject> implements AnyObj
     @Override
     public List<AnyObject> findAll(final int page, final int itemsPerPage) {
         TypedQuery<AnyObject> query = entityManager().createQuery(
-                "SELECT e FROM  " + JPAAnyObject.class.getSimpleName() + " e", AnyObject.class);
+                "SELECT e FROM  " + JPAAnyObject.class.getSimpleName() + " e ORDER BY e.id", AnyObject.class);
         query.setFirstResult(itemsPerPage * (page <= 0 ? 0 : page - 1));
         query.setMaxResults(itemsPerPage);
 

http://git-wip-us.apache.org/repos/asf/syncope/blob/f191fd00/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAGroupDAO.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAGroupDAO.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAGroupDAO.java
index e4e34a3..9d833ea 100644
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAGroupDAO.java
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAGroupDAO.java
@@ -277,7 +277,7 @@ public class JPAGroupDAO extends AbstractAnyDAO<Group> implements GroupDAO {
     @Override
     public List<Group> findAll(final int page, final int itemsPerPage) {
         TypedQuery<Group> query = entityManager().createQuery(
-                "SELECT e FROM  " + JPAGroup.class.getSimpleName() + " e", Group.class);
+                "SELECT e FROM  " + JPAGroup.class.getSimpleName() + " e ORDER BY e.id", Group.class);
         query.setFirstResult(itemsPerPage * (page <= 0 ? 0 : page - 1));
         query.setMaxResults(itemsPerPage);
 

http://git-wip-us.apache.org/repos/asf/syncope/blob/f191fd00/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPATaskDAO.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPATaskDAO.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPATaskDAO.java
index 1f5db3b..dfb7536 100644
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPATaskDAO.java
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPATaskDAO.java
@@ -206,9 +206,7 @@ public class JPATaskDAO extends AbstractDAO<Task> implements TaskDAO {
             query.setParameter("entityKey", entityKey);
         }
 
-        query.setFirstResult(itemsPerPage * (page <= 0
-                ? 0
-                : page - 1));
+        query.setFirstResult(itemsPerPage * (page <= 0 ? 0 : page - 1));
 
         if (itemsPerPage > 0) {
             query.setMaxResults(itemsPerPage);

http://git-wip-us.apache.org/repos/asf/syncope/blob/f191fd00/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAUserDAO.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAUserDAO.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAUserDAO.java
index 5b7ec8e..560ad44 100644
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAUserDAO.java
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAUserDAO.java
@@ -281,7 +281,7 @@ public class JPAUserDAO extends AbstractAnyDAO<User> implements UserDAO {
     @Override
     public List<User> findAll(final int page, final int itemsPerPage) {
         TypedQuery<User> query = entityManager().createQuery(
-                "SELECT e FROM  " + JPAUser.class.getSimpleName() + " e", User.class);
+                "SELECT e FROM  " + JPAUser.class.getSimpleName() + " e ORDER BY e.id", User.class);
         query.setFirstResult(itemsPerPage * (page <= 0 ? 0 : page - 1));
         query.setMaxResults(itemsPerPage);
 

http://git-wip-us.apache.org/repos/asf/syncope/blob/f191fd00/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/propagation/PropagationTaskExecutor.java
----------------------------------------------------------------------
diff --git a/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/propagation/PropagationTaskExecutor.java b/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/propagation/PropagationTaskExecutor.java
index cd34ca0..af66189 100644
--- a/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/propagation/PropagationTaskExecutor.java
+++ b/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/propagation/PropagationTaskExecutor.java
@@ -51,14 +51,6 @@ public interface PropagationTaskExecutor {
 
     /**
      * Execute a collection of PropagationTask objects.
-     * The process is interrupted as soon as the result of the communication with a primary resource is in error.
-     *
-     * @param tasks to be executed
-     */
-    void execute(Collection<PropagationTask> tasks);
-
-    /**
-     * Execute a collection of PropagationTask objects.
      * The process is interrupted as soon as the result of the communication with a resource with non-null priority is
      * in error.
      *

http://git-wip-us.apache.org/repos/asf/syncope/blob/f191fd00/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/DefaultUserProvisioningManager.java
----------------------------------------------------------------------
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/DefaultUserProvisioningManager.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/DefaultUserProvisioningManager.java
index df9881da..d59af7b 100644
--- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/DefaultUserProvisioningManager.java
+++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/DefaultUserProvisioningManager.java
@@ -290,7 +290,7 @@ public class DefaultUserProvisioningManager implements UserProvisioningManager {
                     new WorkflowResult<Pair<UserPatch, Boolean>>(
                             new ImmutablePair<>(userPatch, Boolean.FALSE),
                             updated.getLeft().getPropByRes(), updated.getLeft().getPerformedTasks()));
-            taskExecutor.execute(tasks);
+            taskExecutor.execute(tasks, false);
         }
     }
 

http://git-wip-us.apache.org/repos/asf/syncope/blob/f191fd00/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/propagation/AbstractPropagationTaskExecutor.java
----------------------------------------------------------------------
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/propagation/AbstractPropagationTaskExecutor.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/propagation/AbstractPropagationTaskExecutor.java
index 2635413..ff91c41 100644
--- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/propagation/AbstractPropagationTaskExecutor.java
+++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/propagation/AbstractPropagationTaskExecutor.java
@@ -536,11 +536,6 @@ public abstract class AbstractPropagationTaskExecutor implements PropagationTask
         return execution;
     }
 
-    @Override
-    public void execute(final Collection<PropagationTask> tasks) {
-        execute(tasks, false);
-    }
-
     protected abstract void doExecute(
             Collection<PropagationTask> tasks, PropagationReporter reporter, boolean nullPriorityAsync);
 

http://git-wip-us.apache.org/repos/asf/syncope/blob/f191fd00/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/AbstractPullResultHandler.java
----------------------------------------------------------------------
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/AbstractPullResultHandler.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/AbstractPullResultHandler.java
index 3491736..af8466c 100644
--- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/AbstractPullResultHandler.java
+++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/AbstractPullResultHandler.java
@@ -102,7 +102,8 @@ public abstract class AbstractPullResultHandler extends AbstractSyncopeResultHan
                     kind,
                     key,
                     propByRes,
-                    null));
+                    null),
+                    false);
         } catch (Exception e) {
             // A propagation failure doesn't imply a pull failure.
             // The propagation exception status will be reported into the propagation task execution.
@@ -441,7 +442,8 @@ public abstract class AbstractPullResultHandler extends AbstractSyncopeResultHan
                                 provision.getAnyType().getKind(),
                                 key,
                                 propByRes,
-                                null));
+                                null),
+                                false);
 
                         AnyPatch anyPatch = null;
                         if (unlink) {

http://git-wip-us.apache.org/repos/asf/syncope/blob/f191fd00/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/AbstractPushResultHandler.java
----------------------------------------------------------------------
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/AbstractPushResultHandler.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/AbstractPushResultHandler.java
index d84fa25..66595ac 100644
--- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/AbstractPushResultHandler.java
+++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/AbstractPushResultHandler.java
@@ -25,7 +25,6 @@ import java.util.List;
 import java.util.Map;
 import org.apache.commons.collections4.CollectionUtils;
 import org.apache.commons.collections4.IteratorUtils;
-import org.apache.commons.lang3.exception.ExceptionUtils;
 import org.apache.syncope.common.lib.patch.AnyPatch;
 import org.apache.syncope.common.lib.patch.StringPatchItem;
 import org.apache.syncope.common.lib.to.AnyTO;
@@ -33,6 +32,7 @@ import org.apache.syncope.common.lib.types.AuditElements;
 import org.apache.syncope.common.lib.types.AuditElements.Result;
 import org.apache.syncope.common.lib.types.MatchingRule;
 import org.apache.syncope.common.lib.types.PatchOperation;
+import org.apache.syncope.common.lib.types.PropagationTaskExecStatus;
 import org.apache.syncope.core.provisioning.api.PropagationByResource;
 import org.apache.syncope.common.lib.types.ResourceOperation;
 import org.apache.syncope.common.lib.types.UnmatchingRule;
@@ -51,6 +51,7 @@ import org.apache.syncope.core.provisioning.api.MappingManager;
 import org.apache.syncope.core.provisioning.api.TimeoutException;
 import org.apache.syncope.core.provisioning.api.event.AfterHandlingEvent;
 import org.apache.syncope.core.provisioning.api.notification.NotificationManager;
+import org.apache.syncope.core.provisioning.api.propagation.PropagationReporter;
 import org.apache.syncope.core.provisioning.api.pushpull.IgnoreProvisionException;
 import org.apache.syncope.core.provisioning.api.pushpull.SyncopePushResultHandler;
 import org.apache.syncope.core.provisioning.api.utils.EntityUtils;
@@ -88,20 +89,63 @@ public abstract class AbstractPushResultHandler extends AbstractSyncopeResultHan
 
     protected abstract String getName(Any<?> any);
 
-    protected void deprovision(final Any<?> any) {
+    protected void reportPropagation(final ProvisioningReport result, final PropagationReporter reporter) {
+        if (!reporter.getStatuses().isEmpty()) {
+            result.setStatus(toProvisioningReportStatus(reporter.getStatuses().get(0).getStatus()));
+            result.setMessage(reporter.getStatuses().get(0).getFailureReason());
+        }
+    }
+
+    private void update(final Any<?> any, final ProvisioningReport result) {
+        boolean changepwd;
+        Collection<String> resourceKeys;
+        if (any instanceof User) {
+            changepwd = true;
+            resourceKeys = CollectionUtils.collect(
+                    userDAO.findAllResources((User) any), EntityUtils.keyTransformer());
+        } else if (any instanceof AnyObject) {
+            changepwd = false;
+            resourceKeys = CollectionUtils.collect(
+                    anyObjectDAO.findAllResources((AnyObject) any), EntityUtils.keyTransformer());
+        } else {
+            changepwd = false;
+            resourceKeys = ((Group) any).getResourceKeys();
+        }
+
+        List<String> noPropResources = new ArrayList<>(resourceKeys);
+        noPropResources.remove(profile.getTask().getResource().getKey());
+
+        PropagationByResource propByRes = new PropagationByResource();
+        propByRes.add(ResourceOperation.CREATE, profile.getTask().getResource().getKey());
+
+        PropagationReporter reporter = taskExecutor.execute(propagationManager.getUpdateTasks(
+                any.getType().getKind(),
+                any.getKey(),
+                changepwd,
+                null,
+                propByRes,
+                null,
+                noPropResources),
+                false);
+        reportPropagation(result, reporter);
+    }
+
+    protected void deprovision(final Any<?> any, final ProvisioningReport result) {
         AnyTO before = getAnyTO(any.getKey());
 
         List<String> noPropResources = new ArrayList<>(before.getResources());
         noPropResources.remove(profile.getTask().getResource().getKey());
 
-        taskExecutor.execute(propagationManager.getDeleteTasks(
+        PropagationReporter reporter = taskExecutor.execute(propagationManager.getDeleteTasks(
                 any.getType().getKind(),
                 any.getKey(),
                 null,
-                noPropResources));
+                noPropResources),
+                false);
+        reportPropagation(result, reporter);
     }
 
-    protected void provision(final Any<?> any, final Boolean enabled) {
+    protected void provision(final Any<?> any, final Boolean enabled, final ProvisioningReport result) {
         AnyTO before = getAnyTO(any.getKey());
 
         List<String> noPropResources = new ArrayList<>(before.getResources());
@@ -110,24 +154,28 @@ public abstract class AbstractPushResultHandler extends AbstractSyncopeResultHan
         PropagationByResource propByRes = new PropagationByResource();
         propByRes.add(ResourceOperation.CREATE, profile.getTask().getResource().getKey());
 
-        taskExecutor.execute(propagationManager.getCreateTasks(
+        PropagationReporter reporter = taskExecutor.execute(propagationManager.getCreateTasks(
                 any.getType().getKind(),
                 any.getKey(),
                 propByRes,
                 before.getVirAttrs(),
-                noPropResources));
+                noPropResources),
+                false);
+        reportPropagation(result, reporter);
     }
 
-    protected void link(final Any<?> any, final Boolean unlink) {
+    protected void link(final Any<?> any, final boolean unlink, final ProvisioningReport result) {
         AnyPatch patch = newPatch(any.getKey());
         patch.getResources().add(new StringPatchItem.Builder().
                 operation(unlink ? PatchOperation.DELETE : PatchOperation.ADD_REPLACE).
                 value(profile.getTask().getResource().getKey()).build());
 
         update(patch);
+
+        result.setStatus(ProvisioningReport.Status.SUCCESS);
     }
 
-    protected void unassign(final Any<?> any) {
+    protected void unassign(final Any<?> any, final ProvisioningReport result) {
         AnyPatch patch = newPatch(any.getKey());
         patch.getResources().add(new StringPatchItem.Builder().
                 operation(PatchOperation.DELETE).
@@ -135,10 +183,10 @@ public abstract class AbstractPushResultHandler extends AbstractSyncopeResultHan
 
         update(patch);
 
-        deprovision(any);
+        deprovision(any, result);
     }
 
-    protected void assign(final Any<?> any, final Boolean enabled) {
+    protected void assign(final Any<?> any, final Boolean enabled, final ProvisioningReport result) {
         AnyPatch patch = newPatch(any.getKey());
         patch.getResources().add(new StringPatchItem.Builder().
                 operation(PatchOperation.ADD_REPLACE).
@@ -146,7 +194,7 @@ public abstract class AbstractPushResultHandler extends AbstractSyncopeResultHan
 
         update(patch);
 
-        provision(any, enabled);
+        provision(any, enabled, result);
     }
 
     protected ConnectorObject getRemoteObject(final String connObjectKey, final ObjectClass objectClass) {
@@ -221,9 +269,9 @@ public abstract class AbstractPushResultHandler extends AbstractSyncopeResultHan
 
         if (profile.isDryRun()) {
             if (beforeObj == null) {
-                result.setOperation(getResourceOperation(profile.getTask().getUnmatchingRule()));
+                result.setOperation(toResourceOperation(profile.getTask().getUnmatchingRule()));
             } else {
-                result.setOperation(getResourceOperation(profile.getTask().getMatchingRule()));
+                result.setOperation(toResourceOperation(profile.getTask().getMatchingRule()));
             }
             result.setStatus(ProvisioningReport.Status.SUCCESS);
         } else {
@@ -243,7 +291,7 @@ public abstract class AbstractPushResultHandler extends AbstractSyncopeResultHan
                     operation);
             try {
                 if (beforeObj == null) {
-                    result.setOperation(getResourceOperation(profile.getTask().getUnmatchingRule()));
+                    result.setOperation(toResourceOperation(profile.getTask().getUnmatchingRule()));
 
                     switch (profile.getTask().getUnmatchingRule()) {
                         case ASSIGN:
@@ -253,10 +301,10 @@ public abstract class AbstractPushResultHandler extends AbstractSyncopeResultHan
 
                             if (!profile.getTask().isPerformCreate()) {
                                 LOG.debug("PushTask not configured for create");
+                                result.setStatus(ProvisioningReport.Status.IGNORE);
                             } else {
-                                assign(any, status);
+                                assign(any, status, result);
                             }
-
                             break;
 
                         case PROVISION:
@@ -266,10 +314,10 @@ public abstract class AbstractPushResultHandler extends AbstractSyncopeResultHan
 
                             if (!profile.getTask().isPerformCreate()) {
                                 LOG.debug("PushTask not configured for create");
+                                result.setStatus(ProvisioningReport.Status.IGNORE);
                             } else {
-                                provision(any, status);
+                                provision(any, status, result);
                             }
-
                             break;
 
                         case UNLINK:
@@ -279,20 +327,22 @@ public abstract class AbstractPushResultHandler extends AbstractSyncopeResultHan
 
                             if (!profile.getTask().isPerformUpdate()) {
                                 LOG.debug("PushTask not configured for update");
+                                result.setStatus(ProvisioningReport.Status.IGNORE);
                             } else {
-                                link(any, true);
+                                link(any, true, result);
                             }
-
                             break;
 
                         case IGNORE:
                             LOG.debug("Ignored any: {}", any);
+                            result.setStatus(ProvisioningReport.Status.IGNORE);
                             break;
+
                         default:
                         // do nothing
                     }
                 } else {
-                    result.setOperation(getResourceOperation(profile.getTask().getMatchingRule()));
+                    result.setOperation(toResourceOperation(profile.getTask().getMatchingRule()));
 
                     switch (profile.getTask().getMatchingRule()) {
                         case UPDATE:
@@ -301,10 +351,10 @@ public abstract class AbstractPushResultHandler extends AbstractSyncopeResultHan
                             }
                             if (!profile.getTask().isPerformUpdate()) {
                                 LOG.debug("PushTask not configured for update");
+                                result.setStatus(ProvisioningReport.Status.IGNORE);
                             } else {
-                                update(any);
+                                update(any, result);
                             }
-
                             break;
 
                         case DEPROVISION:
@@ -314,10 +364,10 @@ public abstract class AbstractPushResultHandler extends AbstractSyncopeResultHan
 
                             if (!profile.getTask().isPerformDelete()) {
                                 LOG.debug("PushTask not configured for delete");
+                                result.setStatus(ProvisioningReport.Status.IGNORE);
                             } else {
-                                deprovision(any);
+                                deprovision(any, result);
                             }
-
                             break;
 
                         case UNASSIGN:
@@ -327,10 +377,10 @@ public abstract class AbstractPushResultHandler extends AbstractSyncopeResultHan
 
                             if (!profile.getTask().isPerformDelete()) {
                                 LOG.debug("PushTask not configured for delete");
+                                result.setStatus(ProvisioningReport.Status.IGNORE);
                             } else {
-                                unassign(any);
+                                unassign(any, result);
                             }
-
                             break;
 
                         case LINK:
@@ -340,10 +390,10 @@ public abstract class AbstractPushResultHandler extends AbstractSyncopeResultHan
 
                             if (!profile.getTask().isPerformUpdate()) {
                                 LOG.debug("PushTask not configured for update");
+                                result.setStatus(ProvisioningReport.Status.IGNORE);
                             } else {
-                                link(any, false);
+                                link(any, false, result);
                             }
-
                             break;
 
                         case UNLINK:
@@ -353,15 +403,18 @@ public abstract class AbstractPushResultHandler extends AbstractSyncopeResultHan
 
                             if (!profile.getTask().isPerformUpdate()) {
                                 LOG.debug("PushTask not configured for update");
+                                result.setStatus(ProvisioningReport.Status.IGNORE);
                             } else {
-                                link(any, true);
+                                link(any, true, result);
                             }
 
                             break;
 
                         case IGNORE:
                             LOG.debug("Ignored any: {}", any);
+                            result.setStatus(ProvisioningReport.Status.IGNORE);
                             break;
+
                         default:
                         // do nothing
                     }
@@ -371,15 +424,10 @@ public abstract class AbstractPushResultHandler extends AbstractSyncopeResultHan
                     action.after(profile, any, result);
                 }
 
-                result.setStatus(ProvisioningReport.Status.SUCCESS);
-                resultStatus = AuditElements.Result.SUCCESS;
                 output = getRemoteObject(connObjecKey, provision.getObjectClass());
             } catch (IgnoreProvisionException e) {
                 throw e;
             } catch (Exception e) {
-                result.setStatus(ProvisioningReport.Status.FAILURE);
-                result.setMessage(ExceptionUtils.getRootCauseMessage(e));
-                resultStatus = AuditElements.Result.FAILURE;
                 output = e;
 
                 LOG.warn("Error pushing {} towards {}", any, profile.getTask().getResource(), e);
@@ -407,7 +455,7 @@ public abstract class AbstractPushResultHandler extends AbstractSyncopeResultHan
         }
     }
 
-    private ResourceOperation getResourceOperation(final UnmatchingRule rule) {
+    private ResourceOperation toResourceOperation(final UnmatchingRule rule) {
         switch (rule) {
             case ASSIGN:
             case PROVISION:
@@ -417,7 +465,7 @@ public abstract class AbstractPushResultHandler extends AbstractSyncopeResultHan
         }
     }
 
-    private ResourceOperation getResourceOperation(final MatchingRule rule) {
+    private ResourceOperation toResourceOperation(final MatchingRule rule) {
         switch (rule) {
             case UPDATE:
                 return ResourceOperation.UPDATE;
@@ -429,37 +477,18 @@ public abstract class AbstractPushResultHandler extends AbstractSyncopeResultHan
         }
     }
 
-    private Any<?> update(final Any<?> any) {
-        boolean changepwd;
-        Collection<String> resourceKeys;
-        if (any instanceof User) {
-            changepwd = true;
-            resourceKeys = CollectionUtils.collect(
-                    userDAO.findAllResources((User) any), EntityUtils.keyTransformer());
-        } else if (any instanceof AnyObject) {
-            changepwd = false;
-            resourceKeys = CollectionUtils.collect(
-                    anyObjectDAO.findAllResources((AnyObject) any), EntityUtils.keyTransformer());
-        } else {
-            changepwd = false;
-            resourceKeys = ((Group) any).getResourceKeys();
-        }
+    private ProvisioningReport.Status toProvisioningReportStatus(final PropagationTaskExecStatus status) {
+        switch (status) {
+            case FAILURE:
+                return ProvisioningReport.Status.FAILURE;
 
-        List<String> noPropResources = new ArrayList<>(resourceKeys);
-        noPropResources.remove(profile.getTask().getResource().getKey());
+            case SUCCESS:
+                return ProvisioningReport.Status.SUCCESS;
 
-        PropagationByResource propByRes = new PropagationByResource();
-        propByRes.add(ResourceOperation.CREATE, profile.getTask().getResource().getKey());
-
-        taskExecutor.execute(propagationManager.getUpdateTasks(
-                any.getType().getKind(),
-                any.getKey(),
-                changepwd,
-                null,
-                propByRes,
-                null,
-                noPropResources));
-
-        return getAny(any.getKey());
+            case CREATED:
+            case NOT_ATTEMPTED:
+            default:
+                return ProvisioningReport.Status.IGNORE;
+        }
     }
 }

http://git-wip-us.apache.org/repos/asf/syncope/blob/f191fd00/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/RealmPullResultHandlerImpl.java
----------------------------------------------------------------------
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/RealmPullResultHandlerImpl.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/RealmPullResultHandlerImpl.java
index 7053ef6..fc711ca 100644
--- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/RealmPullResultHandlerImpl.java
+++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/RealmPullResultHandlerImpl.java
@@ -347,7 +347,7 @@ public class RealmPullResultHandlerImpl
 
                 PropagationByResource propByRes = new PropagationByResource();
                 propByRes.add(ResourceOperation.DELETE, profile.getTask().getResource().getKey());
-                taskExecutor.execute(propagationManager.createTasks(realm, propByRes, null));
+                taskExecutor.execute(propagationManager.createTasks(realm, propByRes, null), false);
 
                 if (unlink) {
                     realm.getResources().remove(profile.getTask().getResource());

http://git-wip-us.apache.org/repos/asf/syncope/blob/f191fd00/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/RealmPushResultHandlerImpl.java
----------------------------------------------------------------------
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/RealmPushResultHandlerImpl.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/RealmPushResultHandlerImpl.java
index 50e68f0..9cd574a 100644
--- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/RealmPushResultHandlerImpl.java
+++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/RealmPushResultHandlerImpl.java
@@ -22,21 +22,21 @@ import java.util.ArrayList;
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
-import org.apache.commons.lang3.exception.ExceptionUtils;
 import org.apache.syncope.common.lib.to.RealmTO;
 import org.apache.syncope.common.lib.types.AuditElements;
 import org.apache.syncope.common.lib.types.AuditElements.Result;
 import org.apache.syncope.common.lib.types.MatchingRule;
+import org.apache.syncope.common.lib.types.PropagationTaskExecStatus;
 import org.apache.syncope.core.provisioning.api.PropagationByResource;
 import org.apache.syncope.common.lib.types.ResourceOperation;
 import org.apache.syncope.common.lib.types.UnmatchingRule;
 import org.apache.syncope.core.persistence.api.entity.Realm;
 import org.apache.syncope.core.persistence.api.entity.resource.OrgUnit;
-import org.apache.syncope.core.persistence.api.entity.task.PropagationTask;
 import org.apache.syncope.core.persistence.api.entity.task.PushTask;
 import org.apache.syncope.core.provisioning.api.Connector;
 import org.apache.syncope.core.provisioning.api.TimeoutException;
 import org.apache.syncope.core.provisioning.api.event.AfterHandlingEvent;
+import org.apache.syncope.core.provisioning.api.propagation.PropagationReporter;
 import org.apache.syncope.core.provisioning.api.pushpull.IgnoreProvisionException;
 import org.apache.syncope.core.provisioning.api.pushpull.ProvisioningReport;
 import org.apache.syncope.core.provisioning.api.pushpull.PushActions;
@@ -84,38 +84,50 @@ public class RealmPushResultHandlerImpl
         }
     }
 
-    private Realm update(final RealmTO realmTO) {
+    private void reportPropagation(final ProvisioningReport result, final PropagationReporter reporter) {
+        if (!reporter.getStatuses().isEmpty()) {
+            result.setStatus(toProvisioningReportStatus(reporter.getStatuses().get(0).getStatus()));
+            result.setMessage(reporter.getStatuses().get(0).getFailureReason());
+        }
+    }
+
+    private Realm update(final RealmTO realmTO, final ProvisioningReport result) {
         Realm realm = realmDAO.findByFullPath(realmTO.getFullPath());
         PropagationByResource propByRes = binder.update(realm, realmTO);
         realm = realmDAO.save(realm);
 
-        List<PropagationTask> tasks = propagationManager.createTasks(realm, propByRes, null);
-        taskExecutor.execute(tasks, false);
+        PropagationReporter reporter = taskExecutor.execute(
+                propagationManager.createTasks(realm, propByRes, null), false);
+        reportPropagation(result, reporter);
 
         return realm;
     }
 
-    private void deprovision(final Realm realm) {
+    private void deprovision(final Realm realm, final ProvisioningReport result) {
         List<String> noPropResources = new ArrayList<>(realm.getResourceKeys());
         noPropResources.remove(profile.getTask().getResource().getKey());
 
         PropagationByResource propByRes = new PropagationByResource();
         propByRes.addAll(ResourceOperation.DELETE, realm.getResourceKeys());
 
-        taskExecutor.execute(propagationManager.createTasks(realm, propByRes, noPropResources));
+        PropagationReporter reporter = taskExecutor.execute(
+                propagationManager.createTasks(realm, propByRes, noPropResources), false);
+        reportPropagation(result, reporter);
     }
 
-    private void provision(final Realm realm) {
+    private void provision(final Realm realm, final ProvisioningReport result) {
         List<String> noPropResources = new ArrayList<>(realm.getResourceKeys());
         noPropResources.remove(profile.getTask().getResource().getKey());
 
         PropagationByResource propByRes = new PropagationByResource();
         propByRes.add(ResourceOperation.CREATE, profile.getTask().getResource().getKey());
 
-        taskExecutor.execute(propagationManager.createTasks(realm, propByRes, noPropResources));
+        PropagationReporter reporter = taskExecutor.execute(
+                propagationManager.createTasks(realm, propByRes, noPropResources), false);
+        reportPropagation(result, reporter);
     }
 
-    private void link(final Realm realm, final Boolean unlink) {
+    private void link(final Realm realm, final boolean unlink, final ProvisioningReport result) {
         RealmTO realmTO = binder.getRealmTO(realm, true);
         if (unlink) {
             realmTO.getResources().remove(profile.getTask().getResource().getKey());
@@ -123,21 +135,56 @@ public class RealmPushResultHandlerImpl
             realmTO.getResources().add(profile.getTask().getResource().getKey());
         }
 
-        update(realmTO);
+        update(realmTO, result);
     }
 
-    private void unassign(final Realm realm) {
+    private void unassign(final Realm realm, final ProvisioningReport result) {
         RealmTO realmTO = binder.getRealmTO(realm, true);
         realmTO.getResources().remove(profile.getTask().getResource().getKey());
 
-        deprovision(update(realmTO));
+        deprovision(update(realmTO, result), result);
     }
 
-    private void assign(final Realm realm) {
+    private void assign(final Realm realm, final ProvisioningReport result) {
         RealmTO realmTO = binder.getRealmTO(realm, true);
         realmTO.getResources().add(profile.getTask().getResource().getKey());
 
-        provision(update(realmTO));
+        provision(update(realmTO, result), result);
+    }
+
+    /**
+     * Get remote object for given realm .
+     *
+     * @param connector connector facade proxy.
+     * @param task current propagation task.
+     * @param orgUnit orgUnit
+     * @return remote connector object.
+     */
+    private ConnectorObject getRemoteObject(
+            final String realmName,
+            final Connector connector,
+            final OrgUnit orgUnit) {
+
+        final ConnectorObject[] obj = new ConnectorObject[1];
+        try {
+            connector.search(orgUnit.getObjectClass(),
+                    new EqualsFilter(AttributeBuilder.build(orgUnit.getExtAttrName(), realmName)),
+                    new ResultsHandler() {
+
+                @Override
+                public boolean handle(final ConnectorObject connectorObject) {
+                    obj[0] = connectorObject;
+                    return false;
+                }
+            }, MappingUtils.buildOperationOptions(orgUnit));
+        } catch (TimeoutException toe) {
+            LOG.debug("Request timeout", toe);
+            throw toe;
+        } catch (RuntimeException ignore) {
+            LOG.debug("While resolving {}", realmName, ignore);
+        }
+
+        return obj[0];
     }
 
     private void doHandle(final Realm realm) throws JobExecutionException {
@@ -161,9 +208,9 @@ public class RealmPushResultHandlerImpl
 
         if (profile.isDryRun()) {
             if (beforeObj == null) {
-                result.setOperation(getResourceOperation(profile.getTask().getUnmatchingRule()));
+                result.setOperation(toResourceOperation(profile.getTask().getUnmatchingRule()));
             } else {
-                result.setOperation(getResourceOperation(profile.getTask().getMatchingRule()));
+                result.setOperation(toResourceOperation(profile.getTask().getMatchingRule()));
             }
             result.setStatus(ProvisioningReport.Status.SUCCESS);
         } else {
@@ -183,7 +230,7 @@ public class RealmPushResultHandlerImpl
                     operation);
             try {
                 if (beforeObj == null) {
-                    result.setOperation(getResourceOperation(profile.getTask().getUnmatchingRule()));
+                    result.setOperation(toResourceOperation(profile.getTask().getUnmatchingRule()));
 
                     switch (profile.getTask().getUnmatchingRule()) {
                         case ASSIGN:
@@ -193,8 +240,9 @@ public class RealmPushResultHandlerImpl
 
                             if (!profile.getTask().isPerformCreate()) {
                                 LOG.debug("PushTask not configured for create");
+                                result.setStatus(ProvisioningReport.Status.IGNORE);
                             } else {
-                                assign(realm);
+                                assign(realm, result);
                             }
 
                             break;
@@ -206,8 +254,9 @@ public class RealmPushResultHandlerImpl
 
                             if (!profile.getTask().isPerformCreate()) {
                                 LOG.debug("PushTask not configured for create");
+                                result.setStatus(ProvisioningReport.Status.IGNORE);
                             } else {
-                                provision(realm);
+                                provision(realm, result);
                             }
 
                             break;
@@ -219,20 +268,23 @@ public class RealmPushResultHandlerImpl
 
                             if (!profile.getTask().isPerformUpdate()) {
                                 LOG.debug("PushTask not configured for update");
+                                result.setStatus(ProvisioningReport.Status.IGNORE);
                             } else {
-                                link(realm, true);
+                                link(realm, true, result);
                             }
 
                             break;
 
                         case IGNORE:
                             LOG.debug("Ignored any: {}", realm);
+                            result.setStatus(ProvisioningReport.Status.IGNORE);
                             break;
+
                         default:
                         // do nothing
                     }
                 } else {
-                    result.setOperation(getResourceOperation(profile.getTask().getMatchingRule()));
+                    result.setOperation(toResourceOperation(profile.getTask().getMatchingRule()));
 
                     switch (profile.getTask().getMatchingRule()) {
                         case UPDATE:
@@ -241,8 +293,9 @@ public class RealmPushResultHandlerImpl
                             }
                             if (!profile.getTask().isPerformUpdate()) {
                                 LOG.debug("PushTask not configured for update");
+                                result.setStatus(ProvisioningReport.Status.IGNORE);
                             } else {
-                                update(binder.getRealmTO(realm, true));
+                                update(binder.getRealmTO(realm, true), result);
                             }
 
                             break;
@@ -254,8 +307,9 @@ public class RealmPushResultHandlerImpl
 
                             if (!profile.getTask().isPerformDelete()) {
                                 LOG.debug("PushTask not configured for delete");
+                                result.setStatus(ProvisioningReport.Status.IGNORE);
                             } else {
-                                deprovision(realm);
+                                deprovision(realm, result);
                             }
 
                             break;
@@ -267,8 +321,9 @@ public class RealmPushResultHandlerImpl
 
                             if (!profile.getTask().isPerformDelete()) {
                                 LOG.debug("PushTask not configured for delete");
+                                result.setStatus(ProvisioningReport.Status.IGNORE);
                             } else {
-                                unassign(realm);
+                                unassign(realm, result);
                             }
 
                             break;
@@ -280,8 +335,9 @@ public class RealmPushResultHandlerImpl
 
                             if (!profile.getTask().isPerformUpdate()) {
                                 LOG.debug("PushTask not configured for update");
+                                result.setStatus(ProvisioningReport.Status.IGNORE);
                             } else {
-                                link(realm, false);
+                                link(realm, false, result);
                             }
 
                             break;
@@ -293,15 +349,18 @@ public class RealmPushResultHandlerImpl
 
                             if (!profile.getTask().isPerformUpdate()) {
                                 LOG.debug("PushTask not configured for update");
+                                result.setStatus(ProvisioningReport.Status.IGNORE);
                             } else {
-                                link(realm, true);
+                                link(realm, true, result);
                             }
 
                             break;
 
                         case IGNORE:
                             LOG.debug("Ignored any: {}", realm);
+                            result.setStatus(ProvisioningReport.Status.IGNORE);
                             break;
+
                         default:
                         // do nothing
                     }
@@ -311,8 +370,6 @@ public class RealmPushResultHandlerImpl
                     action.after(profile, realm, result);
                 }
 
-                result.setStatus(ProvisioningReport.Status.SUCCESS);
-                resultStatus = AuditElements.Result.SUCCESS;
                 output = getRemoteObject(
                         realm.getName(),
                         profile.getConnector(),
@@ -320,9 +377,6 @@ public class RealmPushResultHandlerImpl
             } catch (IgnoreProvisionException e) {
                 throw e;
             } catch (Exception e) {
-                result.setStatus(ProvisioningReport.Status.FAILURE);
-                result.setMessage(ExceptionUtils.getRootCauseMessage(e));
-                resultStatus = AuditElements.Result.FAILURE;
                 output = e;
 
                 LOG.warn("Error pushing {} towards {}", realm, profile.getTask().getResource(), e);
@@ -350,7 +404,7 @@ public class RealmPushResultHandlerImpl
         }
     }
 
-    private ResourceOperation getResourceOperation(final UnmatchingRule rule) {
+    private ResourceOperation toResourceOperation(final UnmatchingRule rule) {
         switch (rule) {
             case ASSIGN:
             case PROVISION:
@@ -360,7 +414,7 @@ public class RealmPushResultHandlerImpl
         }
     }
 
-    private ResourceOperation getResourceOperation(final MatchingRule rule) {
+    private ResourceOperation toResourceOperation(final MatchingRule rule) {
         switch (rule) {
             case UPDATE:
                 return ResourceOperation.UPDATE;
@@ -372,38 +426,18 @@ public class RealmPushResultHandlerImpl
         }
     }
 
-    /**
-     * Get remote object for given realm .
-     *
-     * @param connector connector facade proxy.
-     * @param task current propagation task.
-     * @param orgUnit orgUnit
-     * @return remote connector object.
-     */
-    private ConnectorObject getRemoteObject(
-            final String realmName,
-            final Connector connector,
-            final OrgUnit orgUnit) {
+    private ProvisioningReport.Status toProvisioningReportStatus(final PropagationTaskExecStatus status) {
+        switch (status) {
+            case FAILURE:
+                return ProvisioningReport.Status.FAILURE;
 
-        final ConnectorObject[] obj = new ConnectorObject[1];
-        try {
-            connector.search(orgUnit.getObjectClass(),
-                    new EqualsFilter(AttributeBuilder.build(orgUnit.getExtAttrName(), realmName)),
-                    new ResultsHandler() {
+            case SUCCESS:
+                return ProvisioningReport.Status.SUCCESS;
 
-                @Override
-                public boolean handle(final ConnectorObject connectorObject) {
-                    obj[0] = connectorObject;
-                    return false;
-                }
-            }, MappingUtils.buildOperationOptions(orgUnit));
-        } catch (TimeoutException toe) {
-            LOG.debug("Request timeout", toe);
-            throw toe;
-        } catch (RuntimeException ignore) {
-            LOG.debug("While resolving {}", realmName, ignore);
+            case CREATED:
+            case NOT_ATTEMPTED:
+            default:
+                return ProvisioningReport.Status.IGNORE;
         }
-
-        return obj[0];
     }
 }

http://git-wip-us.apache.org/repos/asf/syncope/blob/f191fd00/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/UserPushResultHandlerImpl.java
----------------------------------------------------------------------
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/UserPushResultHandlerImpl.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/UserPushResultHandlerImpl.java
index 255f317..60dd98b 100644
--- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/UserPushResultHandlerImpl.java
+++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/UserPushResultHandlerImpl.java
@@ -31,6 +31,8 @@ import org.apache.syncope.core.persistence.api.entity.Any;
 import org.apache.syncope.core.persistence.api.entity.AnyUtils;
 import org.apache.syncope.core.persistence.api.entity.user.User;
 import org.apache.syncope.core.provisioning.api.WorkflowResult;
+import org.apache.syncope.core.provisioning.api.propagation.PropagationReporter;
+import org.apache.syncope.core.provisioning.api.pushpull.ProvisioningReport;
 import org.apache.syncope.core.provisioning.api.pushpull.UserPushResultHandler;
 
 public class UserPushResultHandlerImpl extends AbstractPushResultHandler implements UserPushResultHandler {
@@ -41,7 +43,7 @@ public class UserPushResultHandlerImpl extends AbstractPushResultHandler impleme
     }
 
     @Override
-    protected void provision(final Any<?> any, final Boolean enabled) {
+    protected void provision(final Any<?> any, final Boolean enabled, final ProvisioningReport result) {
         AnyTO before = getAnyTO(any.getKey());
 
         List<String> noPropResources = new ArrayList<>(before.getResources());
@@ -50,13 +52,15 @@ public class UserPushResultHandlerImpl extends AbstractPushResultHandler impleme
         PropagationByResource propByRes = new PropagationByResource();
         propByRes.add(ResourceOperation.CREATE, profile.getTask().getResource().getKey());
 
-        taskExecutor.execute(propagationManager.getUserCreateTasks(
+        PropagationReporter reporter = taskExecutor.execute(propagationManager.getUserCreateTasks(
                 before.getKey(),
                 null,
                 enabled,
                 propByRes,
                 before.getVirAttrs(),
-                noPropResources));
+                noPropResources),
+                false);
+        reportPropagation(result, reporter);
     }
 
     @Override

http://git-wip-us.apache.org/repos/asf/syncope/blob/f191fd00/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/producer/SuspendProducer.java
----------------------------------------------------------------------
diff --git a/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/producer/SuspendProducer.java b/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/producer/SuspendProducer.java
index 57c1404..235faea 100644
--- a/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/producer/SuspendProducer.java
+++ b/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/producer/SuspendProducer.java
@@ -51,7 +51,7 @@ public class SuspendProducer extends AbstractProducer {
                         new WorkflowResult<Pair<UserPatch, Boolean>>(
                                 new ImmutablePair<>(userPatch, Boolean.FALSE),
                                 updated.getKey().getPropByRes(), updated.getKey().getPerformedTasks()));
-                getPropagationTaskExecutor().execute(tasks);
+                getPropagationTaskExecutor().execute(tasks, false);
             }
         }
     }


[2/2] syncope git commit: [SYNCOPE-1158][SYNCOPE-1153] Better PushTask reports

Posted by il...@apache.org.
[SYNCOPE-1158][SYNCOPE-1153] Better PushTask reports


Project: http://git-wip-us.apache.org/repos/asf/syncope/repo
Commit: http://git-wip-us.apache.org/repos/asf/syncope/commit/3e90e38f
Tree: http://git-wip-us.apache.org/repos/asf/syncope/tree/3e90e38f
Diff: http://git-wip-us.apache.org/repos/asf/syncope/diff/3e90e38f

Branch: refs/heads/master
Commit: 3e90e38fd6519ac3b94a6ca3c4db9eab9434f1bd
Parents: f9c61fb
Author: Francesco Chicchiriccò <il...@apache.org>
Authored: Wed Jul 12 15:42:33 2017 +0200
Committer: Francesco Chicchiriccò <il...@apache.org>
Committed: Wed Jul 12 15:42:46 2017 +0200

----------------------------------------------------------------------
 .../syncope/core/logic/UserWorkflowLogic.java   |   4 +-
 .../persistence/jpa/dao/JPAAccessTokenDAO.java  |   4 +-
 .../persistence/jpa/dao/JPAAnyObjectDAO.java    |   2 +-
 .../core/persistence/jpa/dao/JPAGroupDAO.java   |   2 +-
 .../core/persistence/jpa/dao/JPATaskDAO.java    |   4 +-
 .../core/persistence/jpa/dao/JPAUserDAO.java    |   2 +-
 .../propagation/PropagationTaskExecutor.java    |   8 -
 .../java/DefaultUserProvisioningManager.java    |   2 +-
 .../AbstractPropagationTaskExecutor.java        |   5 -
 .../pushpull/AbstractPullResultHandler.java     |   6 +-
 .../pushpull/AbstractPushResultHandler.java     | 165 +++++++++++--------
 .../pushpull/RealmPullResultHandlerImpl.java    |   2 +-
 .../pushpull/RealmPushResultHandlerImpl.java    | 162 +++++++++++-------
 .../pushpull/UserPushResultHandlerImpl.java     |  10 +-
 .../camel/producer/SuspendProducer.java         |   2 +-
 15 files changed, 216 insertions(+), 164 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/syncope/blob/3e90e38f/core/logic/src/main/java/org/apache/syncope/core/logic/UserWorkflowLogic.java
----------------------------------------------------------------------
diff --git a/core/logic/src/main/java/org/apache/syncope/core/logic/UserWorkflowLogic.java b/core/logic/src/main/java/org/apache/syncope/core/logic/UserWorkflowLogic.java
index 41b89ca..433e943 100644
--- a/core/logic/src/main/java/org/apache/syncope/core/logic/UserWorkflowLogic.java
+++ b/core/logic/src/main/java/org/apache/syncope/core/logic/UserWorkflowLogic.java
@@ -76,7 +76,7 @@ public class UserWorkflowLogic extends AbstractTransactionalLogic<WorkflowFormTO
                         new ImmutablePair<UserPatch, Boolean>(userPatch, null),
                         updated.getPropByRes(), updated.getPerformedTasks()));
 
-        taskExecutor.execute(tasks);
+        taskExecutor.execute(tasks, false);
 
         return binder.getUserTO(updated.getResult());
     }
@@ -111,7 +111,7 @@ public class UserWorkflowLogic extends AbstractTransactionalLogic<WorkflowFormTO
                             updated.getPropByRes(),
                             updated.getPerformedTasks()));
 
-            taskExecutor.execute(tasks);
+            taskExecutor.execute(tasks, false);
         }
 
         return binder.getUserTO(updated.getResult().getKey());

http://git-wip-us.apache.org/repos/asf/syncope/blob/3e90e38f/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAAccessTokenDAO.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAAccessTokenDAO.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAAccessTokenDAO.java
index 01c53fd..2ecc44e 100644
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAAccessTokenDAO.java
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAAccessTokenDAO.java
@@ -100,9 +100,7 @@ public class JPAAccessTokenDAO extends AbstractDAO<AccessToken> implements Acces
 
         TypedQuery<AccessToken> query = entityManager().createQuery(queryString.toString(), AccessToken.class);
 
-        query.setFirstResult(itemsPerPage * (page <= 0
-                ? 0
-                : page - 1));
+        query.setFirstResult(itemsPerPage * (page <= 0 ? 0 : page - 1));
 
         if (itemsPerPage > 0) {
             query.setMaxResults(itemsPerPage);

http://git-wip-us.apache.org/repos/asf/syncope/blob/3e90e38f/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAAnyObjectDAO.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAAnyObjectDAO.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAAnyObjectDAO.java
index b052f30..457944b 100644
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAAnyObjectDAO.java
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAAnyObjectDAO.java
@@ -204,7 +204,7 @@ public class JPAAnyObjectDAO extends AbstractAnyDAO<AnyObject> implements AnyObj
     @Override
     public List<AnyObject> findAll(final int page, final int itemsPerPage) {
         TypedQuery<AnyObject> query = entityManager().createQuery(
-                "SELECT e FROM  " + JPAAnyObject.class.getSimpleName() + " e", AnyObject.class);
+                "SELECT e FROM  " + JPAAnyObject.class.getSimpleName() + " e ORDER BY e.id", AnyObject.class);
         query.setFirstResult(itemsPerPage * (page <= 0 ? 0 : page - 1));
         query.setMaxResults(itemsPerPage);
 

http://git-wip-us.apache.org/repos/asf/syncope/blob/3e90e38f/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAGroupDAO.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAGroupDAO.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAGroupDAO.java
index e4e34a3..9d833ea 100644
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAGroupDAO.java
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAGroupDAO.java
@@ -277,7 +277,7 @@ public class JPAGroupDAO extends AbstractAnyDAO<Group> implements GroupDAO {
     @Override
     public List<Group> findAll(final int page, final int itemsPerPage) {
         TypedQuery<Group> query = entityManager().createQuery(
-                "SELECT e FROM  " + JPAGroup.class.getSimpleName() + " e", Group.class);
+                "SELECT e FROM  " + JPAGroup.class.getSimpleName() + " e ORDER BY e.id", Group.class);
         query.setFirstResult(itemsPerPage * (page <= 0 ? 0 : page - 1));
         query.setMaxResults(itemsPerPage);
 

http://git-wip-us.apache.org/repos/asf/syncope/blob/3e90e38f/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPATaskDAO.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPATaskDAO.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPATaskDAO.java
index 1f5db3b..dfb7536 100644
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPATaskDAO.java
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPATaskDAO.java
@@ -206,9 +206,7 @@ public class JPATaskDAO extends AbstractDAO<Task> implements TaskDAO {
             query.setParameter("entityKey", entityKey);
         }
 
-        query.setFirstResult(itemsPerPage * (page <= 0
-                ? 0
-                : page - 1));
+        query.setFirstResult(itemsPerPage * (page <= 0 ? 0 : page - 1));
 
         if (itemsPerPage > 0) {
             query.setMaxResults(itemsPerPage);

http://git-wip-us.apache.org/repos/asf/syncope/blob/3e90e38f/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAUserDAO.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAUserDAO.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAUserDAO.java
index 5b7ec8e..560ad44 100644
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAUserDAO.java
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAUserDAO.java
@@ -281,7 +281,7 @@ public class JPAUserDAO extends AbstractAnyDAO<User> implements UserDAO {
     @Override
     public List<User> findAll(final int page, final int itemsPerPage) {
         TypedQuery<User> query = entityManager().createQuery(
-                "SELECT e FROM  " + JPAUser.class.getSimpleName() + " e", User.class);
+                "SELECT e FROM  " + JPAUser.class.getSimpleName() + " e ORDER BY e.id", User.class);
         query.setFirstResult(itemsPerPage * (page <= 0 ? 0 : page - 1));
         query.setMaxResults(itemsPerPage);
 

http://git-wip-us.apache.org/repos/asf/syncope/blob/3e90e38f/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/propagation/PropagationTaskExecutor.java
----------------------------------------------------------------------
diff --git a/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/propagation/PropagationTaskExecutor.java b/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/propagation/PropagationTaskExecutor.java
index cd34ca0..af66189 100644
--- a/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/propagation/PropagationTaskExecutor.java
+++ b/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/propagation/PropagationTaskExecutor.java
@@ -51,14 +51,6 @@ public interface PropagationTaskExecutor {
 
     /**
      * Execute a collection of PropagationTask objects.
-     * The process is interrupted as soon as the result of the communication with a primary resource is in error.
-     *
-     * @param tasks to be executed
-     */
-    void execute(Collection<PropagationTask> tasks);
-
-    /**
-     * Execute a collection of PropagationTask objects.
      * The process is interrupted as soon as the result of the communication with a resource with non-null priority is
      * in error.
      *

http://git-wip-us.apache.org/repos/asf/syncope/blob/3e90e38f/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/DefaultUserProvisioningManager.java
----------------------------------------------------------------------
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/DefaultUserProvisioningManager.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/DefaultUserProvisioningManager.java
index df9881da..d59af7b 100644
--- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/DefaultUserProvisioningManager.java
+++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/DefaultUserProvisioningManager.java
@@ -290,7 +290,7 @@ public class DefaultUserProvisioningManager implements UserProvisioningManager {
                     new WorkflowResult<Pair<UserPatch, Boolean>>(
                             new ImmutablePair<>(userPatch, Boolean.FALSE),
                             updated.getLeft().getPropByRes(), updated.getLeft().getPerformedTasks()));
-            taskExecutor.execute(tasks);
+            taskExecutor.execute(tasks, false);
         }
     }
 

http://git-wip-us.apache.org/repos/asf/syncope/blob/3e90e38f/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/propagation/AbstractPropagationTaskExecutor.java
----------------------------------------------------------------------
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/propagation/AbstractPropagationTaskExecutor.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/propagation/AbstractPropagationTaskExecutor.java
index 2635413..ff91c41 100644
--- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/propagation/AbstractPropagationTaskExecutor.java
+++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/propagation/AbstractPropagationTaskExecutor.java
@@ -536,11 +536,6 @@ public abstract class AbstractPropagationTaskExecutor implements PropagationTask
         return execution;
     }
 
-    @Override
-    public void execute(final Collection<PropagationTask> tasks) {
-        execute(tasks, false);
-    }
-
     protected abstract void doExecute(
             Collection<PropagationTask> tasks, PropagationReporter reporter, boolean nullPriorityAsync);
 

http://git-wip-us.apache.org/repos/asf/syncope/blob/3e90e38f/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/AbstractPullResultHandler.java
----------------------------------------------------------------------
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/AbstractPullResultHandler.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/AbstractPullResultHandler.java
index 3491736..af8466c 100644
--- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/AbstractPullResultHandler.java
+++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/AbstractPullResultHandler.java
@@ -102,7 +102,8 @@ public abstract class AbstractPullResultHandler extends AbstractSyncopeResultHan
                     kind,
                     key,
                     propByRes,
-                    null));
+                    null),
+                    false);
         } catch (Exception e) {
             // A propagation failure doesn't imply a pull failure.
             // The propagation exception status will be reported into the propagation task execution.
@@ -441,7 +442,8 @@ public abstract class AbstractPullResultHandler extends AbstractSyncopeResultHan
                                 provision.getAnyType().getKind(),
                                 key,
                                 propByRes,
-                                null));
+                                null),
+                                false);
 
                         AnyPatch anyPatch = null;
                         if (unlink) {

http://git-wip-us.apache.org/repos/asf/syncope/blob/3e90e38f/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/AbstractPushResultHandler.java
----------------------------------------------------------------------
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/AbstractPushResultHandler.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/AbstractPushResultHandler.java
index d84fa25..66595ac 100644
--- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/AbstractPushResultHandler.java
+++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/AbstractPushResultHandler.java
@@ -25,7 +25,6 @@ import java.util.List;
 import java.util.Map;
 import org.apache.commons.collections4.CollectionUtils;
 import org.apache.commons.collections4.IteratorUtils;
-import org.apache.commons.lang3.exception.ExceptionUtils;
 import org.apache.syncope.common.lib.patch.AnyPatch;
 import org.apache.syncope.common.lib.patch.StringPatchItem;
 import org.apache.syncope.common.lib.to.AnyTO;
@@ -33,6 +32,7 @@ import org.apache.syncope.common.lib.types.AuditElements;
 import org.apache.syncope.common.lib.types.AuditElements.Result;
 import org.apache.syncope.common.lib.types.MatchingRule;
 import org.apache.syncope.common.lib.types.PatchOperation;
+import org.apache.syncope.common.lib.types.PropagationTaskExecStatus;
 import org.apache.syncope.core.provisioning.api.PropagationByResource;
 import org.apache.syncope.common.lib.types.ResourceOperation;
 import org.apache.syncope.common.lib.types.UnmatchingRule;
@@ -51,6 +51,7 @@ import org.apache.syncope.core.provisioning.api.MappingManager;
 import org.apache.syncope.core.provisioning.api.TimeoutException;
 import org.apache.syncope.core.provisioning.api.event.AfterHandlingEvent;
 import org.apache.syncope.core.provisioning.api.notification.NotificationManager;
+import org.apache.syncope.core.provisioning.api.propagation.PropagationReporter;
 import org.apache.syncope.core.provisioning.api.pushpull.IgnoreProvisionException;
 import org.apache.syncope.core.provisioning.api.pushpull.SyncopePushResultHandler;
 import org.apache.syncope.core.provisioning.api.utils.EntityUtils;
@@ -88,20 +89,63 @@ public abstract class AbstractPushResultHandler extends AbstractSyncopeResultHan
 
     protected abstract String getName(Any<?> any);
 
-    protected void deprovision(final Any<?> any) {
+    protected void reportPropagation(final ProvisioningReport result, final PropagationReporter reporter) {
+        if (!reporter.getStatuses().isEmpty()) {
+            result.setStatus(toProvisioningReportStatus(reporter.getStatuses().get(0).getStatus()));
+            result.setMessage(reporter.getStatuses().get(0).getFailureReason());
+        }
+    }
+
+    private void update(final Any<?> any, final ProvisioningReport result) {
+        boolean changepwd;
+        Collection<String> resourceKeys;
+        if (any instanceof User) {
+            changepwd = true;
+            resourceKeys = CollectionUtils.collect(
+                    userDAO.findAllResources((User) any), EntityUtils.keyTransformer());
+        } else if (any instanceof AnyObject) {
+            changepwd = false;
+            resourceKeys = CollectionUtils.collect(
+                    anyObjectDAO.findAllResources((AnyObject) any), EntityUtils.keyTransformer());
+        } else {
+            changepwd = false;
+            resourceKeys = ((Group) any).getResourceKeys();
+        }
+
+        List<String> noPropResources = new ArrayList<>(resourceKeys);
+        noPropResources.remove(profile.getTask().getResource().getKey());
+
+        PropagationByResource propByRes = new PropagationByResource();
+        propByRes.add(ResourceOperation.CREATE, profile.getTask().getResource().getKey());
+
+        PropagationReporter reporter = taskExecutor.execute(propagationManager.getUpdateTasks(
+                any.getType().getKind(),
+                any.getKey(),
+                changepwd,
+                null,
+                propByRes,
+                null,
+                noPropResources),
+                false);
+        reportPropagation(result, reporter);
+    }
+
+    protected void deprovision(final Any<?> any, final ProvisioningReport result) {
         AnyTO before = getAnyTO(any.getKey());
 
         List<String> noPropResources = new ArrayList<>(before.getResources());
         noPropResources.remove(profile.getTask().getResource().getKey());
 
-        taskExecutor.execute(propagationManager.getDeleteTasks(
+        PropagationReporter reporter = taskExecutor.execute(propagationManager.getDeleteTasks(
                 any.getType().getKind(),
                 any.getKey(),
                 null,
-                noPropResources));
+                noPropResources),
+                false);
+        reportPropagation(result, reporter);
     }
 
-    protected void provision(final Any<?> any, final Boolean enabled) {
+    protected void provision(final Any<?> any, final Boolean enabled, final ProvisioningReport result) {
         AnyTO before = getAnyTO(any.getKey());
 
         List<String> noPropResources = new ArrayList<>(before.getResources());
@@ -110,24 +154,28 @@ public abstract class AbstractPushResultHandler extends AbstractSyncopeResultHan
         PropagationByResource propByRes = new PropagationByResource();
         propByRes.add(ResourceOperation.CREATE, profile.getTask().getResource().getKey());
 
-        taskExecutor.execute(propagationManager.getCreateTasks(
+        PropagationReporter reporter = taskExecutor.execute(propagationManager.getCreateTasks(
                 any.getType().getKind(),
                 any.getKey(),
                 propByRes,
                 before.getVirAttrs(),
-                noPropResources));
+                noPropResources),
+                false);
+        reportPropagation(result, reporter);
     }
 
-    protected void link(final Any<?> any, final Boolean unlink) {
+    protected void link(final Any<?> any, final boolean unlink, final ProvisioningReport result) {
         AnyPatch patch = newPatch(any.getKey());
         patch.getResources().add(new StringPatchItem.Builder().
                 operation(unlink ? PatchOperation.DELETE : PatchOperation.ADD_REPLACE).
                 value(profile.getTask().getResource().getKey()).build());
 
         update(patch);
+
+        result.setStatus(ProvisioningReport.Status.SUCCESS);
     }
 
-    protected void unassign(final Any<?> any) {
+    protected void unassign(final Any<?> any, final ProvisioningReport result) {
         AnyPatch patch = newPatch(any.getKey());
         patch.getResources().add(new StringPatchItem.Builder().
                 operation(PatchOperation.DELETE).
@@ -135,10 +183,10 @@ public abstract class AbstractPushResultHandler extends AbstractSyncopeResultHan
 
         update(patch);
 
-        deprovision(any);
+        deprovision(any, result);
     }
 
-    protected void assign(final Any<?> any, final Boolean enabled) {
+    protected void assign(final Any<?> any, final Boolean enabled, final ProvisioningReport result) {
         AnyPatch patch = newPatch(any.getKey());
         patch.getResources().add(new StringPatchItem.Builder().
                 operation(PatchOperation.ADD_REPLACE).
@@ -146,7 +194,7 @@ public abstract class AbstractPushResultHandler extends AbstractSyncopeResultHan
 
         update(patch);
 
-        provision(any, enabled);
+        provision(any, enabled, result);
     }
 
     protected ConnectorObject getRemoteObject(final String connObjectKey, final ObjectClass objectClass) {
@@ -221,9 +269,9 @@ public abstract class AbstractPushResultHandler extends AbstractSyncopeResultHan
 
         if (profile.isDryRun()) {
             if (beforeObj == null) {
-                result.setOperation(getResourceOperation(profile.getTask().getUnmatchingRule()));
+                result.setOperation(toResourceOperation(profile.getTask().getUnmatchingRule()));
             } else {
-                result.setOperation(getResourceOperation(profile.getTask().getMatchingRule()));
+                result.setOperation(toResourceOperation(profile.getTask().getMatchingRule()));
             }
             result.setStatus(ProvisioningReport.Status.SUCCESS);
         } else {
@@ -243,7 +291,7 @@ public abstract class AbstractPushResultHandler extends AbstractSyncopeResultHan
                     operation);
             try {
                 if (beforeObj == null) {
-                    result.setOperation(getResourceOperation(profile.getTask().getUnmatchingRule()));
+                    result.setOperation(toResourceOperation(profile.getTask().getUnmatchingRule()));
 
                     switch (profile.getTask().getUnmatchingRule()) {
                         case ASSIGN:
@@ -253,10 +301,10 @@ public abstract class AbstractPushResultHandler extends AbstractSyncopeResultHan
 
                             if (!profile.getTask().isPerformCreate()) {
                                 LOG.debug("PushTask not configured for create");
+                                result.setStatus(ProvisioningReport.Status.IGNORE);
                             } else {
-                                assign(any, status);
+                                assign(any, status, result);
                             }
-
                             break;
 
                         case PROVISION:
@@ -266,10 +314,10 @@ public abstract class AbstractPushResultHandler extends AbstractSyncopeResultHan
 
                             if (!profile.getTask().isPerformCreate()) {
                                 LOG.debug("PushTask not configured for create");
+                                result.setStatus(ProvisioningReport.Status.IGNORE);
                             } else {
-                                provision(any, status);
+                                provision(any, status, result);
                             }
-
                             break;
 
                         case UNLINK:
@@ -279,20 +327,22 @@ public abstract class AbstractPushResultHandler extends AbstractSyncopeResultHan
 
                             if (!profile.getTask().isPerformUpdate()) {
                                 LOG.debug("PushTask not configured for update");
+                                result.setStatus(ProvisioningReport.Status.IGNORE);
                             } else {
-                                link(any, true);
+                                link(any, true, result);
                             }
-
                             break;
 
                         case IGNORE:
                             LOG.debug("Ignored any: {}", any);
+                            result.setStatus(ProvisioningReport.Status.IGNORE);
                             break;
+
                         default:
                         // do nothing
                     }
                 } else {
-                    result.setOperation(getResourceOperation(profile.getTask().getMatchingRule()));
+                    result.setOperation(toResourceOperation(profile.getTask().getMatchingRule()));
 
                     switch (profile.getTask().getMatchingRule()) {
                         case UPDATE:
@@ -301,10 +351,10 @@ public abstract class AbstractPushResultHandler extends AbstractSyncopeResultHan
                             }
                             if (!profile.getTask().isPerformUpdate()) {
                                 LOG.debug("PushTask not configured for update");
+                                result.setStatus(ProvisioningReport.Status.IGNORE);
                             } else {
-                                update(any);
+                                update(any, result);
                             }
-
                             break;
 
                         case DEPROVISION:
@@ -314,10 +364,10 @@ public abstract class AbstractPushResultHandler extends AbstractSyncopeResultHan
 
                             if (!profile.getTask().isPerformDelete()) {
                                 LOG.debug("PushTask not configured for delete");
+                                result.setStatus(ProvisioningReport.Status.IGNORE);
                             } else {
-                                deprovision(any);
+                                deprovision(any, result);
                             }
-
                             break;
 
                         case UNASSIGN:
@@ -327,10 +377,10 @@ public abstract class AbstractPushResultHandler extends AbstractSyncopeResultHan
 
                             if (!profile.getTask().isPerformDelete()) {
                                 LOG.debug("PushTask not configured for delete");
+                                result.setStatus(ProvisioningReport.Status.IGNORE);
                             } else {
-                                unassign(any);
+                                unassign(any, result);
                             }
-
                             break;
 
                         case LINK:
@@ -340,10 +390,10 @@ public abstract class AbstractPushResultHandler extends AbstractSyncopeResultHan
 
                             if (!profile.getTask().isPerformUpdate()) {
                                 LOG.debug("PushTask not configured for update");
+                                result.setStatus(ProvisioningReport.Status.IGNORE);
                             } else {
-                                link(any, false);
+                                link(any, false, result);
                             }
-
                             break;
 
                         case UNLINK:
@@ -353,15 +403,18 @@ public abstract class AbstractPushResultHandler extends AbstractSyncopeResultHan
 
                             if (!profile.getTask().isPerformUpdate()) {
                                 LOG.debug("PushTask not configured for update");
+                                result.setStatus(ProvisioningReport.Status.IGNORE);
                             } else {
-                                link(any, true);
+                                link(any, true, result);
                             }
 
                             break;
 
                         case IGNORE:
                             LOG.debug("Ignored any: {}", any);
+                            result.setStatus(ProvisioningReport.Status.IGNORE);
                             break;
+
                         default:
                         // do nothing
                     }
@@ -371,15 +424,10 @@ public abstract class AbstractPushResultHandler extends AbstractSyncopeResultHan
                     action.after(profile, any, result);
                 }
 
-                result.setStatus(ProvisioningReport.Status.SUCCESS);
-                resultStatus = AuditElements.Result.SUCCESS;
                 output = getRemoteObject(connObjecKey, provision.getObjectClass());
             } catch (IgnoreProvisionException e) {
                 throw e;
             } catch (Exception e) {
-                result.setStatus(ProvisioningReport.Status.FAILURE);
-                result.setMessage(ExceptionUtils.getRootCauseMessage(e));
-                resultStatus = AuditElements.Result.FAILURE;
                 output = e;
 
                 LOG.warn("Error pushing {} towards {}", any, profile.getTask().getResource(), e);
@@ -407,7 +455,7 @@ public abstract class AbstractPushResultHandler extends AbstractSyncopeResultHan
         }
     }
 
-    private ResourceOperation getResourceOperation(final UnmatchingRule rule) {
+    private ResourceOperation toResourceOperation(final UnmatchingRule rule) {
         switch (rule) {
             case ASSIGN:
             case PROVISION:
@@ -417,7 +465,7 @@ public abstract class AbstractPushResultHandler extends AbstractSyncopeResultHan
         }
     }
 
-    private ResourceOperation getResourceOperation(final MatchingRule rule) {
+    private ResourceOperation toResourceOperation(final MatchingRule rule) {
         switch (rule) {
             case UPDATE:
                 return ResourceOperation.UPDATE;
@@ -429,37 +477,18 @@ public abstract class AbstractPushResultHandler extends AbstractSyncopeResultHan
         }
     }
 
-    private Any<?> update(final Any<?> any) {
-        boolean changepwd;
-        Collection<String> resourceKeys;
-        if (any instanceof User) {
-            changepwd = true;
-            resourceKeys = CollectionUtils.collect(
-                    userDAO.findAllResources((User) any), EntityUtils.keyTransformer());
-        } else if (any instanceof AnyObject) {
-            changepwd = false;
-            resourceKeys = CollectionUtils.collect(
-                    anyObjectDAO.findAllResources((AnyObject) any), EntityUtils.keyTransformer());
-        } else {
-            changepwd = false;
-            resourceKeys = ((Group) any).getResourceKeys();
-        }
+    private ProvisioningReport.Status toProvisioningReportStatus(final PropagationTaskExecStatus status) {
+        switch (status) {
+            case FAILURE:
+                return ProvisioningReport.Status.FAILURE;
 
-        List<String> noPropResources = new ArrayList<>(resourceKeys);
-        noPropResources.remove(profile.getTask().getResource().getKey());
+            case SUCCESS:
+                return ProvisioningReport.Status.SUCCESS;
 
-        PropagationByResource propByRes = new PropagationByResource();
-        propByRes.add(ResourceOperation.CREATE, profile.getTask().getResource().getKey());
-
-        taskExecutor.execute(propagationManager.getUpdateTasks(
-                any.getType().getKind(),
-                any.getKey(),
-                changepwd,
-                null,
-                propByRes,
-                null,
-                noPropResources));
-
-        return getAny(any.getKey());
+            case CREATED:
+            case NOT_ATTEMPTED:
+            default:
+                return ProvisioningReport.Status.IGNORE;
+        }
     }
 }

http://git-wip-us.apache.org/repos/asf/syncope/blob/3e90e38f/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/RealmPullResultHandlerImpl.java
----------------------------------------------------------------------
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/RealmPullResultHandlerImpl.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/RealmPullResultHandlerImpl.java
index 7053ef6..fc711ca 100644
--- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/RealmPullResultHandlerImpl.java
+++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/RealmPullResultHandlerImpl.java
@@ -347,7 +347,7 @@ public class RealmPullResultHandlerImpl
 
                 PropagationByResource propByRes = new PropagationByResource();
                 propByRes.add(ResourceOperation.DELETE, profile.getTask().getResource().getKey());
-                taskExecutor.execute(propagationManager.createTasks(realm, propByRes, null));
+                taskExecutor.execute(propagationManager.createTasks(realm, propByRes, null), false);
 
                 if (unlink) {
                     realm.getResources().remove(profile.getTask().getResource());

http://git-wip-us.apache.org/repos/asf/syncope/blob/3e90e38f/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/RealmPushResultHandlerImpl.java
----------------------------------------------------------------------
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/RealmPushResultHandlerImpl.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/RealmPushResultHandlerImpl.java
index 50e68f0..9cd574a 100644
--- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/RealmPushResultHandlerImpl.java
+++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/RealmPushResultHandlerImpl.java
@@ -22,21 +22,21 @@ import java.util.ArrayList;
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
-import org.apache.commons.lang3.exception.ExceptionUtils;
 import org.apache.syncope.common.lib.to.RealmTO;
 import org.apache.syncope.common.lib.types.AuditElements;
 import org.apache.syncope.common.lib.types.AuditElements.Result;
 import org.apache.syncope.common.lib.types.MatchingRule;
+import org.apache.syncope.common.lib.types.PropagationTaskExecStatus;
 import org.apache.syncope.core.provisioning.api.PropagationByResource;
 import org.apache.syncope.common.lib.types.ResourceOperation;
 import org.apache.syncope.common.lib.types.UnmatchingRule;
 import org.apache.syncope.core.persistence.api.entity.Realm;
 import org.apache.syncope.core.persistence.api.entity.resource.OrgUnit;
-import org.apache.syncope.core.persistence.api.entity.task.PropagationTask;
 import org.apache.syncope.core.persistence.api.entity.task.PushTask;
 import org.apache.syncope.core.provisioning.api.Connector;
 import org.apache.syncope.core.provisioning.api.TimeoutException;
 import org.apache.syncope.core.provisioning.api.event.AfterHandlingEvent;
+import org.apache.syncope.core.provisioning.api.propagation.PropagationReporter;
 import org.apache.syncope.core.provisioning.api.pushpull.IgnoreProvisionException;
 import org.apache.syncope.core.provisioning.api.pushpull.ProvisioningReport;
 import org.apache.syncope.core.provisioning.api.pushpull.PushActions;
@@ -84,38 +84,50 @@ public class RealmPushResultHandlerImpl
         }
     }
 
-    private Realm update(final RealmTO realmTO) {
+    private void reportPropagation(final ProvisioningReport result, final PropagationReporter reporter) {
+        if (!reporter.getStatuses().isEmpty()) {
+            result.setStatus(toProvisioningReportStatus(reporter.getStatuses().get(0).getStatus()));
+            result.setMessage(reporter.getStatuses().get(0).getFailureReason());
+        }
+    }
+
+    private Realm update(final RealmTO realmTO, final ProvisioningReport result) {
         Realm realm = realmDAO.findByFullPath(realmTO.getFullPath());
         PropagationByResource propByRes = binder.update(realm, realmTO);
         realm = realmDAO.save(realm);
 
-        List<PropagationTask> tasks = propagationManager.createTasks(realm, propByRes, null);
-        taskExecutor.execute(tasks, false);
+        PropagationReporter reporter = taskExecutor.execute(
+                propagationManager.createTasks(realm, propByRes, null), false);
+        reportPropagation(result, reporter);
 
         return realm;
     }
 
-    private void deprovision(final Realm realm) {
+    private void deprovision(final Realm realm, final ProvisioningReport result) {
         List<String> noPropResources = new ArrayList<>(realm.getResourceKeys());
         noPropResources.remove(profile.getTask().getResource().getKey());
 
         PropagationByResource propByRes = new PropagationByResource();
         propByRes.addAll(ResourceOperation.DELETE, realm.getResourceKeys());
 
-        taskExecutor.execute(propagationManager.createTasks(realm, propByRes, noPropResources));
+        PropagationReporter reporter = taskExecutor.execute(
+                propagationManager.createTasks(realm, propByRes, noPropResources), false);
+        reportPropagation(result, reporter);
     }
 
-    private void provision(final Realm realm) {
+    private void provision(final Realm realm, final ProvisioningReport result) {
         List<String> noPropResources = new ArrayList<>(realm.getResourceKeys());
         noPropResources.remove(profile.getTask().getResource().getKey());
 
         PropagationByResource propByRes = new PropagationByResource();
         propByRes.add(ResourceOperation.CREATE, profile.getTask().getResource().getKey());
 
-        taskExecutor.execute(propagationManager.createTasks(realm, propByRes, noPropResources));
+        PropagationReporter reporter = taskExecutor.execute(
+                propagationManager.createTasks(realm, propByRes, noPropResources), false);
+        reportPropagation(result, reporter);
     }
 
-    private void link(final Realm realm, final Boolean unlink) {
+    private void link(final Realm realm, final boolean unlink, final ProvisioningReport result) {
         RealmTO realmTO = binder.getRealmTO(realm, true);
         if (unlink) {
             realmTO.getResources().remove(profile.getTask().getResource().getKey());
@@ -123,21 +135,56 @@ public class RealmPushResultHandlerImpl
             realmTO.getResources().add(profile.getTask().getResource().getKey());
         }
 
-        update(realmTO);
+        update(realmTO, result);
     }
 
-    private void unassign(final Realm realm) {
+    private void unassign(final Realm realm, final ProvisioningReport result) {
         RealmTO realmTO = binder.getRealmTO(realm, true);
         realmTO.getResources().remove(profile.getTask().getResource().getKey());
 
-        deprovision(update(realmTO));
+        deprovision(update(realmTO, result), result);
     }
 
-    private void assign(final Realm realm) {
+    private void assign(final Realm realm, final ProvisioningReport result) {
         RealmTO realmTO = binder.getRealmTO(realm, true);
         realmTO.getResources().add(profile.getTask().getResource().getKey());
 
-        provision(update(realmTO));
+        provision(update(realmTO, result), result);
+    }
+
+    /**
+     * Get remote object for given realm .
+     *
+     * @param connector connector facade proxy.
+     * @param task current propagation task.
+     * @param orgUnit orgUnit
+     * @return remote connector object.
+     */
+    private ConnectorObject getRemoteObject(
+            final String realmName,
+            final Connector connector,
+            final OrgUnit orgUnit) {
+
+        final ConnectorObject[] obj = new ConnectorObject[1];
+        try {
+            connector.search(orgUnit.getObjectClass(),
+                    new EqualsFilter(AttributeBuilder.build(orgUnit.getExtAttrName(), realmName)),
+                    new ResultsHandler() {
+
+                @Override
+                public boolean handle(final ConnectorObject connectorObject) {
+                    obj[0] = connectorObject;
+                    return false;
+                }
+            }, MappingUtils.buildOperationOptions(orgUnit));
+        } catch (TimeoutException toe) {
+            LOG.debug("Request timeout", toe);
+            throw toe;
+        } catch (RuntimeException ignore) {
+            LOG.debug("While resolving {}", realmName, ignore);
+        }
+
+        return obj[0];
     }
 
     private void doHandle(final Realm realm) throws JobExecutionException {
@@ -161,9 +208,9 @@ public class RealmPushResultHandlerImpl
 
         if (profile.isDryRun()) {
             if (beforeObj == null) {
-                result.setOperation(getResourceOperation(profile.getTask().getUnmatchingRule()));
+                result.setOperation(toResourceOperation(profile.getTask().getUnmatchingRule()));
             } else {
-                result.setOperation(getResourceOperation(profile.getTask().getMatchingRule()));
+                result.setOperation(toResourceOperation(profile.getTask().getMatchingRule()));
             }
             result.setStatus(ProvisioningReport.Status.SUCCESS);
         } else {
@@ -183,7 +230,7 @@ public class RealmPushResultHandlerImpl
                     operation);
             try {
                 if (beforeObj == null) {
-                    result.setOperation(getResourceOperation(profile.getTask().getUnmatchingRule()));
+                    result.setOperation(toResourceOperation(profile.getTask().getUnmatchingRule()));
 
                     switch (profile.getTask().getUnmatchingRule()) {
                         case ASSIGN:
@@ -193,8 +240,9 @@ public class RealmPushResultHandlerImpl
 
                             if (!profile.getTask().isPerformCreate()) {
                                 LOG.debug("PushTask not configured for create");
+                                result.setStatus(ProvisioningReport.Status.IGNORE);
                             } else {
-                                assign(realm);
+                                assign(realm, result);
                             }
 
                             break;
@@ -206,8 +254,9 @@ public class RealmPushResultHandlerImpl
 
                             if (!profile.getTask().isPerformCreate()) {
                                 LOG.debug("PushTask not configured for create");
+                                result.setStatus(ProvisioningReport.Status.IGNORE);
                             } else {
-                                provision(realm);
+                                provision(realm, result);
                             }
 
                             break;
@@ -219,20 +268,23 @@ public class RealmPushResultHandlerImpl
 
                             if (!profile.getTask().isPerformUpdate()) {
                                 LOG.debug("PushTask not configured for update");
+                                result.setStatus(ProvisioningReport.Status.IGNORE);
                             } else {
-                                link(realm, true);
+                                link(realm, true, result);
                             }
 
                             break;
 
                         case IGNORE:
                             LOG.debug("Ignored any: {}", realm);
+                            result.setStatus(ProvisioningReport.Status.IGNORE);
                             break;
+
                         default:
                         // do nothing
                     }
                 } else {
-                    result.setOperation(getResourceOperation(profile.getTask().getMatchingRule()));
+                    result.setOperation(toResourceOperation(profile.getTask().getMatchingRule()));
 
                     switch (profile.getTask().getMatchingRule()) {
                         case UPDATE:
@@ -241,8 +293,9 @@ public class RealmPushResultHandlerImpl
                             }
                             if (!profile.getTask().isPerformUpdate()) {
                                 LOG.debug("PushTask not configured for update");
+                                result.setStatus(ProvisioningReport.Status.IGNORE);
                             } else {
-                                update(binder.getRealmTO(realm, true));
+                                update(binder.getRealmTO(realm, true), result);
                             }
 
                             break;
@@ -254,8 +307,9 @@ public class RealmPushResultHandlerImpl
 
                             if (!profile.getTask().isPerformDelete()) {
                                 LOG.debug("PushTask not configured for delete");
+                                result.setStatus(ProvisioningReport.Status.IGNORE);
                             } else {
-                                deprovision(realm);
+                                deprovision(realm, result);
                             }
 
                             break;
@@ -267,8 +321,9 @@ public class RealmPushResultHandlerImpl
 
                             if (!profile.getTask().isPerformDelete()) {
                                 LOG.debug("PushTask not configured for delete");
+                                result.setStatus(ProvisioningReport.Status.IGNORE);
                             } else {
-                                unassign(realm);
+                                unassign(realm, result);
                             }
 
                             break;
@@ -280,8 +335,9 @@ public class RealmPushResultHandlerImpl
 
                             if (!profile.getTask().isPerformUpdate()) {
                                 LOG.debug("PushTask not configured for update");
+                                result.setStatus(ProvisioningReport.Status.IGNORE);
                             } else {
-                                link(realm, false);
+                                link(realm, false, result);
                             }
 
                             break;
@@ -293,15 +349,18 @@ public class RealmPushResultHandlerImpl
 
                             if (!profile.getTask().isPerformUpdate()) {
                                 LOG.debug("PushTask not configured for update");
+                                result.setStatus(ProvisioningReport.Status.IGNORE);
                             } else {
-                                link(realm, true);
+                                link(realm, true, result);
                             }
 
                             break;
 
                         case IGNORE:
                             LOG.debug("Ignored any: {}", realm);
+                            result.setStatus(ProvisioningReport.Status.IGNORE);
                             break;
+
                         default:
                         // do nothing
                     }
@@ -311,8 +370,6 @@ public class RealmPushResultHandlerImpl
                     action.after(profile, realm, result);
                 }
 
-                result.setStatus(ProvisioningReport.Status.SUCCESS);
-                resultStatus = AuditElements.Result.SUCCESS;
                 output = getRemoteObject(
                         realm.getName(),
                         profile.getConnector(),
@@ -320,9 +377,6 @@ public class RealmPushResultHandlerImpl
             } catch (IgnoreProvisionException e) {
                 throw e;
             } catch (Exception e) {
-                result.setStatus(ProvisioningReport.Status.FAILURE);
-                result.setMessage(ExceptionUtils.getRootCauseMessage(e));
-                resultStatus = AuditElements.Result.FAILURE;
                 output = e;
 
                 LOG.warn("Error pushing {} towards {}", realm, profile.getTask().getResource(), e);
@@ -350,7 +404,7 @@ public class RealmPushResultHandlerImpl
         }
     }
 
-    private ResourceOperation getResourceOperation(final UnmatchingRule rule) {
+    private ResourceOperation toResourceOperation(final UnmatchingRule rule) {
         switch (rule) {
             case ASSIGN:
             case PROVISION:
@@ -360,7 +414,7 @@ public class RealmPushResultHandlerImpl
         }
     }
 
-    private ResourceOperation getResourceOperation(final MatchingRule rule) {
+    private ResourceOperation toResourceOperation(final MatchingRule rule) {
         switch (rule) {
             case UPDATE:
                 return ResourceOperation.UPDATE;
@@ -372,38 +426,18 @@ public class RealmPushResultHandlerImpl
         }
     }
 
-    /**
-     * Get remote object for given realm .
-     *
-     * @param connector connector facade proxy.
-     * @param task current propagation task.
-     * @param orgUnit orgUnit
-     * @return remote connector object.
-     */
-    private ConnectorObject getRemoteObject(
-            final String realmName,
-            final Connector connector,
-            final OrgUnit orgUnit) {
+    private ProvisioningReport.Status toProvisioningReportStatus(final PropagationTaskExecStatus status) {
+        switch (status) {
+            case FAILURE:
+                return ProvisioningReport.Status.FAILURE;
 
-        final ConnectorObject[] obj = new ConnectorObject[1];
-        try {
-            connector.search(orgUnit.getObjectClass(),
-                    new EqualsFilter(AttributeBuilder.build(orgUnit.getExtAttrName(), realmName)),
-                    new ResultsHandler() {
+            case SUCCESS:
+                return ProvisioningReport.Status.SUCCESS;
 
-                @Override
-                public boolean handle(final ConnectorObject connectorObject) {
-                    obj[0] = connectorObject;
-                    return false;
-                }
-            }, MappingUtils.buildOperationOptions(orgUnit));
-        } catch (TimeoutException toe) {
-            LOG.debug("Request timeout", toe);
-            throw toe;
-        } catch (RuntimeException ignore) {
-            LOG.debug("While resolving {}", realmName, ignore);
+            case CREATED:
+            case NOT_ATTEMPTED:
+            default:
+                return ProvisioningReport.Status.IGNORE;
         }
-
-        return obj[0];
     }
 }

http://git-wip-us.apache.org/repos/asf/syncope/blob/3e90e38f/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/UserPushResultHandlerImpl.java
----------------------------------------------------------------------
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/UserPushResultHandlerImpl.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/UserPushResultHandlerImpl.java
index 255f317..60dd98b 100644
--- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/UserPushResultHandlerImpl.java
+++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/UserPushResultHandlerImpl.java
@@ -31,6 +31,8 @@ import org.apache.syncope.core.persistence.api.entity.Any;
 import org.apache.syncope.core.persistence.api.entity.AnyUtils;
 import org.apache.syncope.core.persistence.api.entity.user.User;
 import org.apache.syncope.core.provisioning.api.WorkflowResult;
+import org.apache.syncope.core.provisioning.api.propagation.PropagationReporter;
+import org.apache.syncope.core.provisioning.api.pushpull.ProvisioningReport;
 import org.apache.syncope.core.provisioning.api.pushpull.UserPushResultHandler;
 
 public class UserPushResultHandlerImpl extends AbstractPushResultHandler implements UserPushResultHandler {
@@ -41,7 +43,7 @@ public class UserPushResultHandlerImpl extends AbstractPushResultHandler impleme
     }
 
     @Override
-    protected void provision(final Any<?> any, final Boolean enabled) {
+    protected void provision(final Any<?> any, final Boolean enabled, final ProvisioningReport result) {
         AnyTO before = getAnyTO(any.getKey());
 
         List<String> noPropResources = new ArrayList<>(before.getResources());
@@ -50,13 +52,15 @@ public class UserPushResultHandlerImpl extends AbstractPushResultHandler impleme
         PropagationByResource propByRes = new PropagationByResource();
         propByRes.add(ResourceOperation.CREATE, profile.getTask().getResource().getKey());
 
-        taskExecutor.execute(propagationManager.getUserCreateTasks(
+        PropagationReporter reporter = taskExecutor.execute(propagationManager.getUserCreateTasks(
                 before.getKey(),
                 null,
                 enabled,
                 propByRes,
                 before.getVirAttrs(),
-                noPropResources));
+                noPropResources),
+                false);
+        reportPropagation(result, reporter);
     }
 
     @Override

http://git-wip-us.apache.org/repos/asf/syncope/blob/3e90e38f/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/producer/SuspendProducer.java
----------------------------------------------------------------------
diff --git a/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/producer/SuspendProducer.java b/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/producer/SuspendProducer.java
index 57c1404..235faea 100644
--- a/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/producer/SuspendProducer.java
+++ b/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/producer/SuspendProducer.java
@@ -51,7 +51,7 @@ public class SuspendProducer extends AbstractProducer {
                         new WorkflowResult<Pair<UserPatch, Boolean>>(
                                 new ImmutablePair<>(userPatch, Boolean.FALSE),
                                 updated.getKey().getPropByRes(), updated.getKey().getPerformedTasks()));
-                getPropagationTaskExecutor().execute(tasks);
+                getPropagationTaskExecutor().execute(tasks, false);
             }
         }
     }