[SYNCOPE-141][SYNCOPE-142] Implementation completed

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

Branch: refs/heads/SYNCOPE-156
Commit: 1b81e33c74e883c38349630098316a7fb1ade866
Parents: 6d368c8
Author: Francesco Chicchiriccò <ilgro...@apache.org>
Authored: Thu Oct 29 17:31:58 2015 +0100
Committer: Francesco Chicchiriccò <ilgro...@apache.org>
Committed: Thu Oct 29 17:32:32 2015 +0100

----------------------------------------------------------------------
 .../cli/commands/task/TaskResultManager.java    |   2 +-
 .../cli/commands/user/UserResultManager.java    |   2 -
 .../syncope/client/console/pages/Realms.java    |   2 -
 .../syncope/client/console/panels/Realm.java    |   2 -
 .../client/console/panels/RealmModalPanel.java  |   2 -
 .../syncope/client/lib/SyncopeClient.java       |  13 +
 .../syncope/common/lib/patch/PasswordPatch.java |   2 +-
 .../org/apache/syncope/common/lib/to/AnyTO.java |   9 -
 .../common/lib/to/PropagationStatus.java        |  50 --
 .../common/lib/to/PropagationTaskTO.java        |  10 +-
 .../common/lib/to/ProvisioningResult.java       |  55 +++
 .../syncope/common/lib/to/ResourceTO.java       |  16 +-
 .../syncope/common/rest/api/RESTHeaders.java    |   5 +
 .../common/rest/api/service/AnyService.java     |   8 +-
 .../rest/api/service/UserSelfService.java       |  10 +-
 .../common/rest/api/service/UserService.java    |   4 +-
 .../syncope/core/logic/AbstractAnyLogic.java    |  40 +-
 .../core/logic/AbstractResourceAssociator.java  |  19 +-
 .../syncope/core/logic/AnyObjectLogic.java      |  69 +--
 .../apache/syncope/core/logic/GroupLogic.java   |  66 +--
 .../apache/syncope/core/logic/UserLogic.java    | 137 +++---
 .../api/entity/resource/ExternalResource.java   |   4 -
 .../api/entity/task/PropagationTask.java        |   2 +
 .../entity/resource/JPAExternalResource.java    |  21 -
 .../jpa/entity/task/JPAPropagationTask.java     |  17 +-
 .../persistence/jpa/inner/ResourceTest.java     |   3 -
 .../test/resources/domains/MasterContent.xml    |  64 +--
 .../api/AnyObjectProvisioningManager.java       |   2 +-
 .../api/GroupProvisioningManager.java           |   4 +-
 .../provisioning/api/ProvisioningManager.java   |  14 +-
 .../api/UserProvisioningManager.java            |  30 +-
 .../api/propagation/PropagationReporter.java    |  30 +-
 .../propagation/PropagationTaskCallable.java    |  32 ++
 .../propagation/PropagationTaskExecutor.java    |  21 +-
 .../api/sync/ProvisioningProfile.java           |   4 +-
 .../api/sync/ProvisioningReport.java            | 140 ++++++
 .../api/sync/ProvisioningResult.java            | 140 ------
 .../core/provisioning/api/sync/PushActions.java |   4 +-
 .../core/provisioning/api/sync/SyncActions.java |   4 +-
 .../DefaultAnyObjectProvisioningManager.java    |  72 ++-
 .../java/DefaultGroupProvisioningManager.java   |  84 ++--
 .../java/DefaultUserProvisioningManager.java    | 152 +++---
 .../java/data/AbstractAnyDataBinder.java        |   5 +-
 .../java/data/ResourceDataBinderImpl.java       |   4 -
 .../java/data/TaskDataBinderImpl.java           |   1 +
 .../java/job/SchedulerShutdown.java             |   4 -
 .../java/job/SpringBeanJobFactory.java          |   6 +-
 .../notification/NotificationManagerImpl.java   |  19 +-
 .../AbstractPropagationTaskExecutor.java        |  39 +-
 .../propagation/DefaultPropagationReporter.java |  80 ++--
 .../PriorityPropagationTaskExecutor.java        | 161 +++++--
 .../PropagationTaskCallableImpl.java            |  94 ++++
 .../sync/AbstractProvisioningJobDelegate.java   | 104 ++---
 .../java/sync/AbstractPushResultHandler.java    |  14 +-
 .../java/sync/AbstractSyncResultHandler.java    |  94 ++--
 .../sync/AnyObjectSyncResultHandlerImpl.java    |  11 +-
 .../java/sync/DBPasswordSyncActions.java        |   4 +-
 .../java/sync/DefaultPushActions.java           |   6 +-
 .../java/sync/DefaultSyncActions.java           |   6 +-
 .../java/sync/GroupSyncResultHandlerImpl.java   |  13 +-
 .../java/sync/LDAPMembershipSyncActions.java    |   4 +-
 .../java/sync/LDAPPasswordSyncActions.java      |   4 +-
 .../sync/PlainAttrsSyncCorrelationRule.java     |   6 +-
 .../java/sync/UserSyncResultHandlerImpl.java    |  17 +-
 .../src/main/resources/provisioning.properties  |   4 +
 .../src/main/resources/provisioningContext.xml  |  12 +-
 .../syncope/core/rest/cxf/AddETagFilter.java    |  18 +-
 .../rest/cxf/service/AbstractAnyService.java    |  59 ++-
 .../rest/cxf/service/AbstractServiceImpl.java   |  30 +-
 .../rest/cxf/service/ResourceServiceImpl.java   |   4 +-
 .../rest/cxf/service/UserSelfServiceImpl.java   |  11 +-
 .../core/rest/cxf/service/UserServiceImpl.java  |   7 +-
 .../CamelAnyObjectProvisioningManager.java      |  37 +-
 .../camel/CamelGroupProvisioningManager.java    |  45 +-
 .../camel/CamelUserProvisioningManager.java     | 106 +++--
 .../processor/AnyObjectCreateProcessor.java     |  13 +-
 .../processor/AnyObjectDeleteProcessor.java     |  13 +-
 .../AnyObjectDeprovisionProcessor.java          |  13 +-
 .../processor/AnyObjectProvisionProcessor.java  |  13 +-
 .../processor/AnyObjectUpdateProcessor.java     |  13 +-
 .../processor/GroupCreateInSyncProcessor.java   |  13 +-
 .../camel/processor/GroupCreateProcessor.java   |  13 +-
 .../camel/processor/GroupDeleteProcessor.java   |  13 +-
 .../processor/GroupDeprovisionProcessor.java    |  13 +-
 .../processor/GroupProvisionProcessor.java      |  13 +-
 .../camel/processor/GroupUpdateProcessor.java   |   9 +-
 .../processor/UserConfirmPwdResetProcessor.java |  12 +-
 .../camel/processor/UserCreateProcessor.java    |   9 +-
 .../camel/processor/UserDeleteProcessor.java    |  13 +-
 .../processor/UserDeprovisionProcessor.java     |  13 +-
 .../camel/processor/UserProvisionProcessor.java |  13 +-
 .../processor/UserSetStatusInSyncProcessor.java |   2 +-
 .../UserStatusPropagationProcessor.java         |  14 +-
 .../processor/UserUpdateInSyncProcessor.java    |   9 +-
 .../camel/processor/UserUpdateProcessor.java    |  13 +-
 .../src/main/resources/provisioning.properties  |   4 +
 .../src/main/resources/userRoutes.xml           |   2 +-
 .../main/resources/all/provisioning.properties  |   4 +
 .../resources/mariadb/provisioning.properties   |   4 +
 .../resources/mysql/provisioning.properties     |   4 +
 .../resources/oracle/provisioning.properties    |   4 +
 .../resources/postgres/provisioning.properties  |   4 +
 .../src/main/resources/provisioning.properties  |   4 +
 .../resources/sqlserver/provisioning.properties |   4 +
 .../fit/core/reference/AbstractITCase.java      |  96 ++--
 .../fit/core/reference/AnyObjectITCase.java     |  16 +-
 .../core/reference/AuthenticationITCase.java    |  29 +-
 .../fit/core/reference/CamelRouteITCase.java    |   2 +-
 .../syncope/fit/core/reference/GroupITCase.java | 102 ++--
 .../fit/core/reference/MultitenancyITCase.java  |   5 +-
 .../core/reference/NotificationTaskITCase.java  |   4 +-
 .../fit/core/reference/PlainSchemaITCase.java   |  11 +-
 .../fit/core/reference/PushTaskITCase.java      |   4 +-
 .../fit/core/reference/ReportITCase.java        |   2 +-
 .../fit/core/reference/ResourceITCase.java      |   6 +-
 .../fit/core/reference/SearchITCase.java        |   2 +-
 .../fit/core/reference/SyncTaskITCase.java      |  26 +-
 .../syncope/fit/core/reference/UserITCase.java  | 466 +++++++++++--------
 .../fit/core/reference/UserSelfITCase.java      |  26 +-
 .../fit/core/reference/UserWorkflowITCase.java  |  16 +-
 .../fit/core/reference/VirAttrITCase.java       |  86 ++--
 pom.xml                                         |   6 +-
 122 files changed, 1945 insertions(+), 1627 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/syncope/blob/1b81e33c/client/cli/src/main/java/org/apache/syncope/client/cli/commands/task/TaskResultManager.java
----------------------------------------------------------------------
diff --git 
a/client/cli/src/main/java/org/apache/syncope/client/cli/commands/task/TaskResultManager.java
 
b/client/cli/src/main/java/org/apache/syncope/client/cli/commands/task/TaskResultManager.java
index 6075be7..ad8b658 100644
--- 
a/client/cli/src/main/java/org/apache/syncope/client/cli/commands/task/TaskResultManager.java
+++ 
b/client/cli/src/main/java/org/apache/syncope/client/cli/commands/task/TaskResultManager.java
@@ -113,7 +113,7 @@ public class TaskResultManager extends CommonsResultManager 
{
         System.out.println("     latest execution status: "
                 + propagationTaskTO.getLatestExecStatus());
         System.out.println("     class name: " + 
propagationTaskTO.getObjectClassName());
-        System.out.println("     xml attribute: " + 
propagationTaskTO.getXmlAttributes());
+        System.out.println("     attributes: " + 
propagationTaskTO.getAttributes());
         System.out.println("     start date: " + 
propagationTaskTO.getStartDate());
         System.out.println("     end date: " + propagationTaskTO.getEndDate());
         System.out.println("     operation: " + 
propagationTaskTO.getOperation());

http://git-wip-us.apache.org/repos/asf/syncope/blob/1b81e33c/client/cli/src/main/java/org/apache/syncope/client/cli/commands/user/UserResultManager.java
----------------------------------------------------------------------
diff --git 
a/client/cli/src/main/java/org/apache/syncope/client/cli/commands/user/UserResultManager.java
 
b/client/cli/src/main/java/org/apache/syncope/client/cli/commands/user/UserResultManager.java
index 900d32c..b175842 100644
--- 
a/client/cli/src/main/java/org/apache/syncope/client/cli/commands/user/UserResultManager.java
+++ 
b/client/cli/src/main/java/org/apache/syncope/client/cli/commands/user/UserResultManager.java
@@ -58,8 +58,6 @@ public class UserResultManager extends CommonsResultManager {
         System.out.println("    last change: " + userTO.getLastChangeDate());
         System.out.println("    last login: " + userTO.getLastLoginDate());
         System.out.println("    failed logins: " + userTO.getFailedLogins());
-        System.out.println("PROPAGATIONS:");
-        printPropagationStatus(userTO.getPropagationStatusTOs());
         System.out.println("RELATIONSHIPS:");
         printRelationships(userTO.getRelationships());
         System.out.println("    security question id: " + 
userTO.getSecurityQuestion());

http://git-wip-us.apache.org/repos/asf/syncope/blob/1b81e33c/client/console/src/main/java/org/apache/syncope/client/console/pages/Realms.java
----------------------------------------------------------------------
diff --git 
a/client/console/src/main/java/org/apache/syncope/client/console/pages/Realms.java
 
b/client/console/src/main/java/org/apache/syncope/client/console/pages/Realms.java
index 3c5f0ea..4a2101d 100644
--- 
a/client/console/src/main/java/org/apache/syncope/client/console/pages/Realms.java
+++ 
b/client/console/src/main/java/org/apache/syncope/client/console/pages/Realms.java
@@ -18,8 +18,6 @@
  */
 package org.apache.syncope.client.console.pages;
 
-import static org.apache.wicket.Component.ENABLE;
-
 import org.apache.syncope.client.console.SyncopeConsoleSession;
 import org.apache.syncope.client.console.commons.Constants;
 import org.apache.syncope.client.console.panels.Realm;

http://git-wip-us.apache.org/repos/asf/syncope/blob/1b81e33c/client/console/src/main/java/org/apache/syncope/client/console/panels/Realm.java
----------------------------------------------------------------------
diff --git 
a/client/console/src/main/java/org/apache/syncope/client/console/panels/Realm.java
 
b/client/console/src/main/java/org/apache/syncope/client/console/panels/Realm.java
index 68a0b79..8a28b16 100644
--- 
a/client/console/src/main/java/org/apache/syncope/client/console/panels/Realm.java
+++ 
b/client/console/src/main/java/org/apache/syncope/client/console/panels/Realm.java
@@ -18,8 +18,6 @@
  */
 package org.apache.syncope.client.console.panels;
 
-import static org.apache.syncope.common.lib.types.AnyTypeKind.USER;
-
 import com.googlecode.wicket.jquery.core.panel.LabelPanel;
 import 
de.agilecoders.wicket.core.markup.html.bootstrap.tabs.AjaxBootstrapTabbedPanel;
 import java.util.ArrayList;

http://git-wip-us.apache.org/repos/asf/syncope/blob/1b81e33c/client/console/src/main/java/org/apache/syncope/client/console/panels/RealmModalPanel.java
----------------------------------------------------------------------
diff --git 
a/client/console/src/main/java/org/apache/syncope/client/console/panels/RealmModalPanel.java
 
b/client/console/src/main/java/org/apache/syncope/client/console/panels/RealmModalPanel.java
index 7e8f415..7e6aee6 100644
--- 
a/client/console/src/main/java/org/apache/syncope/client/console/panels/RealmModalPanel.java
+++ 
b/client/console/src/main/java/org/apache/syncope/client/console/panels/RealmModalPanel.java
@@ -18,8 +18,6 @@
  */
 package org.apache.syncope.client.console.panels;
 
-import static org.apache.wicket.Component.ENABLE;
-
 import org.apache.syncope.client.console.SyncopeConsoleSession;
 import org.apache.syncope.client.console.commons.Constants;
 import org.apache.syncope.client.console.pages.AbstractBasePage;

http://git-wip-us.apache.org/repos/asf/syncope/blob/1b81e33c/client/lib/src/main/java/org/apache/syncope/client/lib/SyncopeClient.java
----------------------------------------------------------------------
diff --git 
a/client/lib/src/main/java/org/apache/syncope/client/lib/SyncopeClient.java 
b/client/lib/src/main/java/org/apache/syncope/client/lib/SyncopeClient.java
index ca9f1c3..905fb4c 100644
--- a/client/lib/src/main/java/org/apache/syncope/client/lib/SyncopeClient.java
+++ b/client/lib/src/main/java/org/apache/syncope/client/lib/SyncopeClient.java
@@ -255,6 +255,19 @@ public class SyncopeClient {
     }
 
     /**
+     * Asks for asynchronous propagation towards external resources with null 
priority.
+     *
+     * @param <T> any service class
+     * @param serviceClass service class reference
+     * @param nullPriorityAsync whether asynchronous propagation towards 
external resources with null priority is
+     * requested
+     * @return service instance of the given reference class, with related 
header set
+     */
+    public <T> T nullPriorityAsync(final Class<T> serviceClass, final boolean 
nullPriorityAsync) {
+        return header(serviceClass, RESTHeaders.NULL_PRIORITY_ASYNC, 
nullPriorityAsync);
+    }
+
+    /**
      * Sets the {@code If-Match} or {@code If-None-Match} header on the given 
service instance.
      *
      * @param <T> any service class

http://git-wip-us.apache.org/repos/asf/syncope/blob/1b81e33c/common/lib/src/main/java/org/apache/syncope/common/lib/patch/PasswordPatch.java
----------------------------------------------------------------------
diff --git 
a/common/lib/src/main/java/org/apache/syncope/common/lib/patch/PasswordPatch.java
 
b/common/lib/src/main/java/org/apache/syncope/common/lib/patch/PasswordPatch.java
index 1149d2d..93e6b9e 100644
--- 
a/common/lib/src/main/java/org/apache/syncope/common/lib/patch/PasswordPatch.java
+++ 
b/common/lib/src/main/java/org/apache/syncope/common/lib/patch/PasswordPatch.java
@@ -55,7 +55,7 @@ public class PasswordPatch extends StringReplacePatchItem {
             return this;
         }
 
-        public Builder values(final String... resources) {
+        public Builder resources(final String... resources) {
             CollectionUtils.addAll(getInstance().getResources(), resources);
             return this;
         }

http://git-wip-us.apache.org/repos/asf/syncope/blob/1b81e33c/common/lib/src/main/java/org/apache/syncope/common/lib/to/AnyTO.java
----------------------------------------------------------------------
diff --git 
a/common/lib/src/main/java/org/apache/syncope/common/lib/to/AnyTO.java 
b/common/lib/src/main/java/org/apache/syncope/common/lib/to/AnyTO.java
index 7911d7d..ce4a58f 100644
--- a/common/lib/src/main/java/org/apache/syncope/common/lib/to/AnyTO.java
+++ b/common/lib/src/main/java/org/apache/syncope/common/lib/to/AnyTO.java
@@ -58,8 +58,6 @@ public abstract class AnyTO extends ConnObjectTO {
 
     private final Set<String> resources = new HashSet<>();
 
-    private final List<PropagationStatus> propagationStatusTOs = new 
ArrayList<>();
-
     public long getKey() {
         return key;
     }
@@ -140,11 +138,4 @@ public abstract class AnyTO extends ConnObjectTO {
         return resources;
     }
 
-    @XmlElementWrapper(name = "propagationStatuses")
-    @XmlElement(name = "propagationStatus")
-    @JsonProperty("propagationStatuses")
-    public List<PropagationStatus> getPropagationStatusTOs() {
-        return propagationStatusTOs;
-    }
-
 }

http://git-wip-us.apache.org/repos/asf/syncope/blob/1b81e33c/common/lib/src/main/java/org/apache/syncope/common/lib/to/PropagationStatus.java
----------------------------------------------------------------------
diff --git 
a/common/lib/src/main/java/org/apache/syncope/common/lib/to/PropagationStatus.java
 
b/common/lib/src/main/java/org/apache/syncope/common/lib/to/PropagationStatus.java
index 38a8da7..c2caa60 100644
--- 
a/common/lib/src/main/java/org/apache/syncope/common/lib/to/PropagationStatus.java
+++ 
b/common/lib/src/main/java/org/apache/syncope/common/lib/to/PropagationStatus.java
@@ -57,92 +57,42 @@ public class PropagationStatus extends AbstractBaseBean {
      */
     private String failureReason;
 
-    /**
-     * After object getter.
-     *
-     * @return after object.
-     */
     public ConnObjectTO getAfterObj() {
         return afterObj;
     }
 
-    /**
-     * After object setter.
-     *
-     * @param afterObj object.
-     */
     public void setAfterObj(final ConnObjectTO afterObj) {
         this.afterObj = afterObj;
     }
 
-    /**
-     * Before object getter.
-     *
-     * @return before object.
-     */
     public ConnObjectTO getBeforeObj() {
         return beforeObj;
     }
 
-    /**
-     * Before object setter.
-     *
-     * @param beforeObj object.
-     */
     public void setBeforeObj(final ConnObjectTO beforeObj) {
         this.beforeObj = beforeObj;
     }
 
-    /**
-     * resource name getter.
-     *
-     * @return resource name.
-     */
     public String getResource() {
         return resource;
     }
 
-    /**
-     * Resource name setter.
-     *
-     * @param resource resource name
-     */
     public void setResource(final String resource) {
         this.resource = resource;
     }
 
-    /**
-     * Propagation execution status getter.
-     *
-     * @return status
-     */
     public PropagationTaskExecStatus getStatus() {
         return status;
     }
 
-    /**
-     * Propagation execution status setter.
-     *
-     * @param status propagation execution status
-     */
     public void setStatus(final PropagationTaskExecStatus status) {
         this.status = status;
     }
 
-    /**
-     * Propagation execution message getter.
-     *
-     * @return failureReason.
-     */
     public String getFailureReason() {
         return failureReason;
     }
 
-    /**
-     * Propagation execution failure message setter.
-     *
-     * @param failureReason describes why this propagation failed
-     */
     public void setFailureReason(final String failureReason) {
         this.failureReason = failureReason;
     }

http://git-wip-us.apache.org/repos/asf/syncope/blob/1b81e33c/common/lib/src/main/java/org/apache/syncope/common/lib/to/PropagationTaskTO.java
----------------------------------------------------------------------
diff --git 
a/common/lib/src/main/java/org/apache/syncope/common/lib/to/PropagationTaskTO.java
 
b/common/lib/src/main/java/org/apache/syncope/common/lib/to/PropagationTaskTO.java
index 1b1d556..d176bb2 100644
--- 
a/common/lib/src/main/java/org/apache/syncope/common/lib/to/PropagationTaskTO.java
+++ 
b/common/lib/src/main/java/org/apache/syncope/common/lib/to/PropagationTaskTO.java
@@ -35,7 +35,7 @@ public class PropagationTaskTO extends AbstractTaskTO {
 
     private String oldConnObjectKey;
 
-    private String xmlAttributes;
+    private String attributes;
 
     private String resource;
 
@@ -77,12 +77,12 @@ public class PropagationTaskTO extends AbstractTaskTO {
         this.operation = operation;
     }
 
-    public String getXmlAttributes() {
-        return xmlAttributes;
+    public String getAttributes() {
+        return attributes;
     }
 
-    public void setXmlAttributes(final String xmlAttributes) {
-        this.xmlAttributes = xmlAttributes;
+    public void setAttributes(final String attributes) {
+        this.attributes = attributes;
     }
 
     public String getObjectClassName() {

http://git-wip-us.apache.org/repos/asf/syncope/blob/1b81e33c/common/lib/src/main/java/org/apache/syncope/common/lib/to/ProvisioningResult.java
----------------------------------------------------------------------
diff --git 
a/common/lib/src/main/java/org/apache/syncope/common/lib/to/ProvisioningResult.java
 
b/common/lib/src/main/java/org/apache/syncope/common/lib/to/ProvisioningResult.java
new file mode 100644
index 0000000..f2a5bc1
--- /dev/null
+++ 
b/common/lib/src/main/java/org/apache/syncope/common/lib/to/ProvisioningResult.java
@@ -0,0 +1,55 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.syncope.common.lib.to;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import java.util.ArrayList;
+import java.util.List;
+import javax.xml.bind.annotation.XmlElement;
+import javax.xml.bind.annotation.XmlElementWrapper;
+import javax.xml.bind.annotation.XmlRootElement;
+import javax.xml.bind.annotation.XmlType;
+import org.apache.syncope.common.lib.AbstractBaseBean;
+
+@XmlRootElement(name = "provisioningResult")
+@XmlType
+public class ProvisioningResult<A extends AnyTO> extends AbstractBaseBean {
+
+    private static final long serialVersionUID = 351317476398082746L;
+
+    private A any;
+
+    private final List<PropagationStatus> propagationStatuses = new 
ArrayList<>();
+
+    public A getAny() {
+        return any;
+    }
+
+    public void setAny(final A any) {
+        this.any = any;
+    }
+
+    @XmlElementWrapper(name = "propagationStatuses")
+    @XmlElement(name = "propagationStatus")
+    @JsonProperty("propagationStatuses")
+    public List<PropagationStatus> getPropagationStatuses() {
+        return propagationStatuses;
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/1b81e33c/common/lib/src/main/java/org/apache/syncope/common/lib/to/ResourceTO.java
----------------------------------------------------------------------
diff --git 
a/common/lib/src/main/java/org/apache/syncope/common/lib/to/ResourceTO.java 
b/common/lib/src/main/java/org/apache/syncope/common/lib/to/ResourceTO.java
index fc540a9..a74042f 100644
--- a/common/lib/src/main/java/org/apache/syncope/common/lib/to/ResourceTO.java
+++ b/common/lib/src/main/java/org/apache/syncope/common/lib/to/ResourceTO.java
@@ -56,9 +56,7 @@ public class ResourceTO extends AbstractAnnotatedBean {
 
     private final List<ProvisionTO> provisions = new ArrayList<>();
 
-    private boolean propagationPrimary;
-
-    private int propagationPriority = 0;
+    private Integer propagationPriority;
 
     private boolean randomPwdIfNotProvided;
 
@@ -119,19 +117,11 @@ public class ResourceTO extends AbstractAnnotatedBean {
         this.connectorDisplayName = connectorDisplayName;
     }
 
-    public boolean isPropagationPrimary() {
-        return propagationPrimary;
-    }
-
-    public void setPropagationPrimary(final boolean propagationPrimary) {
-        this.propagationPrimary = propagationPrimary;
-    }
-
-    public int getPropagationPriority() {
+    public Integer getPropagationPriority() {
         return propagationPriority;
     }
 
-    public void setPropagationPriority(final int propagationPriority) {
+    public void setPropagationPriority(final Integer propagationPriority) {
         this.propagationPriority = propagationPriority;
     }
 

http://git-wip-us.apache.org/repos/asf/syncope/blob/1b81e33c/common/rest-api/src/main/java/org/apache/syncope/common/rest/api/RESTHeaders.java
----------------------------------------------------------------------
diff --git 
a/common/rest-api/src/main/java/org/apache/syncope/common/rest/api/RESTHeaders.java
 
b/common/rest-api/src/main/java/org/apache/syncope/common/rest/api/RESTHeaders.java
index 13b30df..0b69531 100644
--- 
a/common/rest-api/src/main/java/org/apache/syncope/common/rest/api/RESTHeaders.java
+++ 
b/common/rest-api/src/main/java/org/apache/syncope/common/rest/api/RESTHeaders.java
@@ -34,6 +34,11 @@ public final class RESTHeaders {
     public static final String RESOURCE_KEY = "X-Syncope-Key";
 
     /**
+     * Asks for asynchronous propagation towards external resources with null 
priority.
+     */
+    public static final String NULL_PRIORITY_ASYNC = 
"X-Syncope-Null-Priority-Async";
+
+    /**
      * Declares the type of exception being raised.
      *
      * @see org.apache.syncope.common.lib.types.ClientExceptionType

http://git-wip-us.apache.org/repos/asf/syncope/blob/1b81e33c/common/rest-api/src/main/java/org/apache/syncope/common/rest/api/service/AnyService.java
----------------------------------------------------------------------
diff --git 
a/common/rest-api/src/main/java/org/apache/syncope/common/rest/api/service/AnyService.java
 
b/common/rest-api/src/main/java/org/apache/syncope/common/rest/api/service/AnyService.java
index 49899c2..ec8495c 100644
--- 
a/common/rest-api/src/main/java/org/apache/syncope/common/rest/api/service/AnyService.java
+++ 
b/common/rest-api/src/main/java/org/apache/syncope/common/rest/api/service/AnyService.java
@@ -111,7 +111,7 @@ public interface AnyService<TO extends AnyTO, P extends 
AnyPatch> extends JAXRSS
      *
      * @param anyTO any object to be created
      * @return Response object featuring Location header of created any object 
as well as the any
-     * object itself enriched with propagation status information - AnyTO as 
Entity
+     * object itself enriched with propagation status information - 
ProvisioningResult as Entity
      */
     @POST
     @Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
@@ -123,7 +123,7 @@ public interface AnyService<TO extends AnyTO, P extends 
AnyPatch> extends JAXRSS
      *
      * @param anyPatch modification to be applied to any object matching the 
provided key
      * @return Response object featuring the updated any object enriched with 
propagation status information
-     * - AnyTO as Entity
+     * - ProvisioningResult as Entity
      */
     @PATCH
     @Path("{key}")
@@ -153,7 +153,7 @@ public interface AnyService<TO extends AnyTO, P extends 
AnyPatch> extends JAXRSS
      *
      * @param anyTO complete update
      * @return Response object featuring the updated any object enriched with 
propagation status information
-     * - AnyTO as Entity
+     * - ProvisioningResult as Entity
      */
     @PUT
     @Path("{key}")
@@ -182,7 +182,7 @@ public interface AnyService<TO extends AnyTO, P extends 
AnyPatch> extends JAXRSS
      *
      * @param key key of any object to be deleted
      * @return Response object featuring the deleted any object enriched with 
propagation status information
-     * - AnyTO as Entity
+     * - ProvisioningResult as Entity
      */
     @DELETE
     @Path("{key}")

http://git-wip-us.apache.org/repos/asf/syncope/blob/1b81e33c/common/rest-api/src/main/java/org/apache/syncope/common/rest/api/service/UserSelfService.java
----------------------------------------------------------------------
diff --git 
a/common/rest-api/src/main/java/org/apache/syncope/common/rest/api/service/UserSelfService.java
 
b/common/rest-api/src/main/java/org/apache/syncope/common/rest/api/service/UserSelfService.java
index 745129f..21140ed 100644
--- 
a/common/rest-api/src/main/java/org/apache/syncope/common/rest/api/service/UserSelfService.java
+++ 
b/common/rest-api/src/main/java/org/apache/syncope/common/rest/api/service/UserSelfService.java
@@ -56,7 +56,7 @@ public interface UserSelfService extends JAXRSService {
      * @param userTO user to be created
      * @param storePassword whether password shall be stored internally
      * @return Response object featuring Location header of self-registered 
user as well as the user
-     * itself - UserTO as Entity
+     * itself - ProvisioningResult as Entity
      */
     @POST
     @Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
@@ -68,7 +68,7 @@ public interface UserSelfService extends JAXRSService {
      * Self-updates user.
      *
      * @param patch modification to be applied to self
-     * @return Response object featuring the updated user - UserTO as Entity
+     * @return Response object featuring the updated user - ProvisioningResult 
as Entity
      */
     @PATCH
     @Path("{key}")
@@ -80,7 +80,7 @@ public interface UserSelfService extends JAXRSService {
      * Self-updates user.
      *
      * @param user complete update
-     * @return Response object featuring the updated user - UserTO as Entity
+     * @return Response object featuring the updated user - ProvisioningResult 
as Entity
      */
     @PUT
     @Path("{key}")
@@ -91,7 +91,7 @@ public interface UserSelfService extends JAXRSService {
     /**
      * Self-deletes user.
      *
-     * @return Response object featuring the deleted user - UserTO as Entity
+     * @return Response object featuring the deleted user - ProvisioningResult 
as Entity
      */
     @DELETE
     @Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
@@ -102,7 +102,7 @@ public interface UserSelfService extends JAXRSService {
      *
      * @param password the password value to update
      *
-     * @return Response object featuring the updated user - UserTO as Entity
+     * @return Response object featuring the updated user - ProvisioningResult 
as Entity
      */
     @POST
     @Path("changePassword")

http://git-wip-us.apache.org/repos/asf/syncope/blob/1b81e33c/common/rest-api/src/main/java/org/apache/syncope/common/rest/api/service/UserService.java
----------------------------------------------------------------------
diff --git 
a/common/rest-api/src/main/java/org/apache/syncope/common/rest/api/service/UserService.java
 
b/common/rest-api/src/main/java/org/apache/syncope/common/rest/api/service/UserService.java
index 0368ef1..e23e6cd 100644
--- 
a/common/rest-api/src/main/java/org/apache/syncope/common/rest/api/service/UserService.java
+++ 
b/common/rest-api/src/main/java/org/apache/syncope/common/rest/api/service/UserService.java
@@ -65,7 +65,7 @@ public interface UserService extends AnyService<UserTO, 
UserPatch> {
      * @param userTO user to be created
      * @param storePassword whether password shall be stored internally
      * @return Response object featuring Location header of created user as 
well as the user itself
-     * enriched with propagation status information - UserTO as Entity
+     * enriched with propagation status information - ProvisioningResult as 
Entity
      */
     @POST
     @Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
@@ -79,7 +79,7 @@ public interface UserService extends AnyService<UserTO, 
UserPatch> {
      *
      * @param statusPatch status update details
      * @return Response object featuring the updated user enriched with 
propagation status information
-     * - UserTO as Entity
+     * - ProvisioningResult as Entity
      */
     @POST
     @Path("{key}/status")

http://git-wip-us.apache.org/repos/asf/syncope/blob/1b81e33c/core/logic/src/main/java/org/apache/syncope/core/logic/AbstractAnyLogic.java
----------------------------------------------------------------------
diff --git 
a/core/logic/src/main/java/org/apache/syncope/core/logic/AbstractAnyLogic.java 
b/core/logic/src/main/java/org/apache/syncope/core/logic/AbstractAnyLogic.java
index 111f0ba..987595d 100644
--- 
a/core/logic/src/main/java/org/apache/syncope/core/logic/AbstractAnyLogic.java
+++ 
b/core/logic/src/main/java/org/apache/syncope/core/logic/AbstractAnyLogic.java
@@ -31,6 +31,8 @@ import org.apache.syncope.common.lib.SyncopeClientException;
 import org.apache.syncope.common.lib.patch.AnyPatch;
 import org.apache.syncope.common.lib.to.AnyTO;
 import org.apache.syncope.common.lib.to.GroupTO;
+import org.apache.syncope.common.lib.to.PropagationStatus;
+import org.apache.syncope.common.lib.to.ProvisioningResult;
 import org.apache.syncope.common.lib.to.UserTO;
 import org.apache.syncope.common.lib.types.AnyTypeKind;
 import org.apache.syncope.common.lib.types.ClientExceptionType;
@@ -111,16 +113,6 @@ public abstract class AbstractAnyLogic<TO extends AnyTO, P 
extends AnyPatch>
         return ImmutablePair.of(any, actions);
     }
 
-    protected TO afterCreate(final TO input, final List<LogicActions> actions) 
{
-        TO any = input;
-
-        for (LogicActions action : actions) {
-            any = action.afterCreate(any);
-        }
-
-        return any;
-    }
-
     protected Pair<P, List<LogicActions>> beforeUpdate(final P input, final 
String realmPath) {
         Realm realm = realmDAO.find(realmPath);
         if (realm == null) {
@@ -141,16 +133,6 @@ public abstract class AbstractAnyLogic<TO extends AnyTO, P 
extends AnyPatch>
         return ImmutablePair.of(mod, actions);
     }
 
-    protected TO afterUpdate(final TO input, final List<LogicActions> actions) 
{
-        TO any = input;
-
-        for (LogicActions action : actions) {
-            any = action.afterUpdate(any);
-        }
-
-        return any;
-    }
-
     protected Pair<TO, List<LogicActions>> beforeDelete(final TO input) {
         Realm realm = realmDAO.find(input.getRealm());
         if (realm == null) {
@@ -171,14 +153,20 @@ public abstract class AbstractAnyLogic<TO extends AnyTO, 
P extends AnyPatch>
         return ImmutablePair.of(any, actions);
     }
 
-    protected TO afterDelete(final TO input, final List<LogicActions> actions) 
{
+    protected ProvisioningResult<TO> after(
+            final TO input, final List<PropagationStatus> statuses, final 
List<LogicActions> actions) {
+
         TO any = input;
 
         for (LogicActions action : actions) {
-            any = action.afterDelete(any);
+            any = action.afterCreate(any);
         }
 
-        return any;
+        ProvisioningResult<TO> result = new ProvisioningResult<>();
+        result.setAny(any);
+        result.getPropagationStatuses().addAll(statuses);
+
+        return result;
     }
 
     private static class StartsWithPredicate implements Predicate<String> {
@@ -238,11 +226,11 @@ public abstract class AbstractAnyLogic<TO extends AnyTO, 
P extends AnyPatch>
 
     public abstract int count(List<String> realms);
 
-    public abstract TO create(TO anyTO);
+    public abstract ProvisioningResult<TO> create(TO anyTO, boolean 
nullPriorityAsync);
 
-    public abstract TO update(P anyPatch);
+    public abstract ProvisioningResult<TO> update(P anyPatch, boolean 
nullPriorityAsync);
 
-    public abstract TO delete(Long key);
+    public abstract ProvisioningResult<TO> delete(Long key, boolean 
nullPriorityAsync);
 
     public abstract List<TO> list(
             int page, int size, List<OrderByClause> orderBy,

http://git-wip-us.apache.org/repos/asf/syncope/blob/1b81e33c/core/logic/src/main/java/org/apache/syncope/core/logic/AbstractResourceAssociator.java
----------------------------------------------------------------------
diff --git 
a/core/logic/src/main/java/org/apache/syncope/core/logic/AbstractResourceAssociator.java
 
b/core/logic/src/main/java/org/apache/syncope/core/logic/AbstractResourceAssociator.java
index 6741a89..3bd4492 100644
--- 
a/core/logic/src/main/java/org/apache/syncope/core/logic/AbstractResourceAssociator.java
+++ 
b/core/logic/src/main/java/org/apache/syncope/core/logic/AbstractResourceAssociator.java
@@ -20,18 +20,23 @@ package org.apache.syncope.core.logic;
 
 import java.util.Collection;
 import org.apache.syncope.common.lib.to.AnyTO;
+import org.apache.syncope.common.lib.to.ProvisioningResult;
 
-public abstract class AbstractResourceAssociator<T extends AnyTO> extends 
AbstractLogic<T> {
+public abstract class AbstractResourceAssociator<A extends AnyTO> extends 
AbstractLogic<A> {
 
-    public abstract T unlink(Long id, Collection<String> resources);
+    public abstract A unlink(Long key, Collection<String> resources);
 
-    public abstract T link(Long id, Collection<String> resources);
+    public abstract A link(Long key, Collection<String> resources);
 
-    public abstract T unassign(Long id, Collection<String> resources);
+    public abstract ProvisioningResult<A> unassign(
+            Long key, Collection<String> resources, boolean nullPriorityAsync);
 
-    public abstract T assign(Long id, Collection<String> resources, boolean 
changepwd, String password);
+    public abstract ProvisioningResult<A> assign(
+            Long key, Collection<String> resources, boolean changepwd, String 
password, boolean nullPriorityAsync);
 
-    public abstract T deprovision(Long userId, Collection<String> resources);
+    public abstract ProvisioningResult<A> deprovision(
+            Long key, Collection<String> resources, boolean nullPriorityAsync);
 
-    public abstract T provision(Long userId, Collection<String> resources, 
boolean changepwd, String password);
+    public abstract ProvisioningResult<A> provision(
+            Long key, Collection<String> resources, boolean changepwd, String 
password, boolean nullPriorityAsync);
 }

http://git-wip-us.apache.org/repos/asf/syncope/blob/1b81e33c/core/logic/src/main/java/org/apache/syncope/core/logic/AnyObjectLogic.java
----------------------------------------------------------------------
diff --git 
a/core/logic/src/main/java/org/apache/syncope/core/logic/AnyObjectLogic.java 
b/core/logic/src/main/java/org/apache/syncope/core/logic/AnyObjectLogic.java
index de0130e..b3f7a4a 100644
--- a/core/logic/src/main/java/org/apache/syncope/core/logic/AnyObjectLogic.java
+++ b/core/logic/src/main/java/org/apache/syncope/core/logic/AnyObjectLogic.java
@@ -24,7 +24,6 @@ import java.util.Collection;
 import java.util.Collections;
 import java.util.HashSet;
 import java.util.List;
-import java.util.Map;
 import java.util.Set;
 import org.apache.commons.collections4.CollectionUtils;
 import org.apache.commons.collections4.Transformer;
@@ -37,6 +36,7 @@ import org.apache.syncope.common.lib.patch.AnyObjectPatch;
 import org.apache.syncope.common.lib.patch.StringPatchItem;
 import org.apache.syncope.common.lib.to.PropagationStatus;
 import org.apache.syncope.common.lib.to.AnyObjectTO;
+import org.apache.syncope.common.lib.to.ProvisioningResult;
 import org.apache.syncope.common.lib.types.AnyTypeKind;
 import org.apache.syncope.common.lib.types.ClientExceptionType;
 import org.apache.syncope.common.lib.types.Entitlement;
@@ -147,7 +147,7 @@ public class AnyObjectLogic extends 
AbstractAnyLogic<AnyObjectTO, AnyObjectPatch
 
     @PreAuthorize("hasRole('" + Entitlement.ANY_OBJECT_CREATE + "')")
     @Override
-    public AnyObjectTO create(final AnyObjectTO anyObjectTO) {
+    public ProvisioningResult<AnyObjectTO> create(final AnyObjectTO 
anyObjectTO, final boolean nullPriorityAsync) {
         Pair<AnyObjectTO, List<LogicActions>> before = 
beforeCreate(anyObjectTO);
 
         if (before.getLeft().getRealm() == null) {
@@ -163,16 +163,17 @@ public class AnyObjectLogic extends 
AbstractAnyLogic<AnyObjectTO, AnyObjectPatch
             throw 
SyncopeClientException.build(ClientExceptionType.InvalidAnyType);
         }
 
-        Map.Entry<Long, List<PropagationStatus>> created = 
provisioningManager.create(before.getLeft());
-        AnyObjectTO savedTO = binder.getAnyObjectTO(created.getKey());
-        savedTO.getPropagationStatusTOs().addAll(created.getValue());
+        Pair<Long, List<PropagationStatus>> created =
+                provisioningManager.create(before.getLeft(), 
nullPriorityAsync);
 
-        return afterCreate(savedTO, before.getValue());
+        return after(binder.getAnyObjectTO(created.getKey()), 
created.getRight(), before.getRight());
     }
 
     @PreAuthorize("hasRole('" + Entitlement.ANY_OBJECT_UPDATE + "')")
     @Override
-    public AnyObjectTO update(final AnyObjectPatch anyObjectPatch) {
+    public ProvisioningResult<AnyObjectTO> update(
+            final AnyObjectPatch anyObjectPatch, final boolean 
nullPriorityAsync) {
+
         AnyObjectTO anyObjectTO = 
binder.getAnyObjectTO(anyObjectPatch.getKey());
         Pair<AnyObjectPatch, List<LogicActions>> before = 
beforeUpdate(anyObjectPatch, anyObjectTO.getRealm());
 
@@ -185,17 +186,15 @@ public class AnyObjectLogic extends 
AbstractAnyLogic<AnyObjectTO, AnyObjectPatch
             securityChecks(effectiveRealms, 
before.getLeft().getRealm().getValue(), before.getLeft().getKey());
         }
 
-        Map.Entry<Long, List<PropagationStatus>> updated = 
provisioningManager.update(anyObjectPatch);
-
-        AnyObjectTO updatedTO = binder.getAnyObjectTO(updated.getKey());
-        updatedTO.getPropagationStatusTOs().addAll(updated.getValue());
+        Pair<Long, List<PropagationStatus>> updated =
+                provisioningManager.update(anyObjectPatch, nullPriorityAsync);
 
-        return afterUpdate(updatedTO, before.getRight());
+        return after(binder.getAnyObjectTO(updated.getKey()), 
updated.getRight(), before.getRight());
     }
 
     @PreAuthorize("hasRole('" + Entitlement.ANY_OBJECT_DELETE + "')")
     @Override
-    public AnyObjectTO delete(final Long key) {
+    public ProvisioningResult<AnyObjectTO> delete(final Long key, final 
boolean nullPriorityAsync) {
         AnyObjectTO anyObject = binder.getAnyObjectTO(key);
         Pair<AnyObjectTO, List<LogicActions>> before = beforeDelete(anyObject);
 
@@ -204,13 +203,12 @@ public class AnyObjectLogic extends 
AbstractAnyLogic<AnyObjectTO, AnyObjectPatch
                 Collections.singleton(before.getLeft().getRealm()));
         securityChecks(effectiveRealms, before.getLeft().getRealm(), 
before.getLeft().getKey());
 
-        List<PropagationStatus> statuses = 
provisioningManager.delete(before.getLeft().getKey());
+        List<PropagationStatus> statuses = 
provisioningManager.delete(before.getLeft().getKey(), nullPriorityAsync);
 
         AnyObjectTO anyObjectTO = new AnyObjectTO();
         anyObjectTO.setKey(before.getLeft().getKey());
-        anyObjectTO.getPropagationStatusTOs().addAll(statuses);
 
-        return afterDelete(anyObjectTO, before.getRight());
+        return after(anyObjectTO, statuses, before.getRight());
     }
 
     @PreAuthorize("hasRole('" + Entitlement.ANY_OBJECT_UPDATE + "')")
@@ -261,7 +259,9 @@ public class AnyObjectLogic extends 
AbstractAnyLogic<AnyObjectTO, AnyObjectPatch
 
     @PreAuthorize("hasRole('" + Entitlement.ANY_OBJECT_UPDATE + "')")
     @Override
-    public AnyObjectTO unassign(final Long key, final Collection<String> 
resources) {
+    public ProvisioningResult<AnyObjectTO> unassign(
+            final Long key, final Collection<String> resources, final boolean 
nullPriorityAsync) {
+
         // security checks
         AnyObjectTO anyObject = binder.getAnyObjectTO(key);
         Set<String> effectiveRealms = getEffectiveRealms(
@@ -279,16 +279,17 @@ public class AnyObjectLogic extends 
AbstractAnyLogic<AnyObjectTO, AnyObjectPatch
             }
         }));
 
-        return update(patch);
+        return update(patch, nullPriorityAsync);
     }
 
     @PreAuthorize("hasRole('" + Entitlement.ANY_OBJECT_UPDATE + "')")
     @Override
-    public AnyObjectTO assign(
+    public ProvisioningResult<AnyObjectTO> assign(
             final Long key,
             final Collection<String> resources,
             final boolean changepwd,
-            final String password) {
+            final String password,
+            final boolean nullPriorityAsync) {
 
         // security checks
         AnyObjectTO anyObject = binder.getAnyObjectTO(key);
@@ -307,12 +308,14 @@ public class AnyObjectLogic extends 
AbstractAnyLogic<AnyObjectTO, AnyObjectPatch
             }
         }));
 
-        return update(patch);
+        return update(patch, nullPriorityAsync);
     }
 
     @PreAuthorize("hasRole('" + Entitlement.ANY_OBJECT_UPDATE + "')")
     @Override
-    public AnyObjectTO deprovision(final Long key, final Collection<String> 
resources) {
+    public ProvisioningResult<AnyObjectTO> deprovision(
+            final Long key, final Collection<String> resources, final boolean 
nullPriorityAsync) {
+
         // security checks
         AnyObjectTO anyObject = binder.getAnyObjectTO(key);
         Set<String> effectiveRealms = getEffectiveRealms(
@@ -320,20 +323,22 @@ public class AnyObjectLogic extends 
AbstractAnyLogic<AnyObjectTO, AnyObjectPatch
                 Collections.singleton(anyObject.getRealm()));
         securityChecks(effectiveRealms, anyObject.getRealm(), 
anyObject.getKey());
 
-        List<PropagationStatus> statuses = 
provisioningManager.deprovision(key, resources);
+        List<PropagationStatus> statuses = 
provisioningManager.deprovision(key, resources, nullPriorityAsync);
 
-        AnyObjectTO updatedTO = binder.getAnyObjectTO(key);
-        updatedTO.getPropagationStatusTOs().addAll(statuses);
-        return updatedTO;
+        ProvisioningResult<AnyObjectTO> result = new ProvisioningResult<>();
+        result.setAny(binder.getAnyObjectTO(key));
+        result.getPropagationStatuses().addAll(statuses);
+        return result;
     }
 
     @PreAuthorize("hasRole('" + Entitlement.ANY_OBJECT_UPDATE + "')")
     @Override
-    public AnyObjectTO provision(
+    public ProvisioningResult<AnyObjectTO> provision(
             final Long key,
             final Collection<String> resources,
             final boolean changePwd,
-            final String password) {
+            final String password,
+            final boolean nullPriorityAsync) {
 
         // security checks
         AnyObjectTO anyObject = binder.getAnyObjectTO(key);
@@ -342,8 +347,12 @@ public class AnyObjectLogic extends 
AbstractAnyLogic<AnyObjectTO, AnyObjectPatch
                 Collections.singleton(anyObject.getRealm()));
         securityChecks(effectiveRealms, anyObject.getRealm(), 
anyObject.getKey());
 
-        
anyObject.getPropagationStatusTOs().addAll(provisioningManager.provision(key, 
resources));
-        return anyObject;
+        List<PropagationStatus> statuses = provisioningManager.provision(key, 
resources, nullPriorityAsync);
+
+        ProvisioningResult<AnyObjectTO> result = new ProvisioningResult<>();
+        result.setAny(binder.getAnyObjectTO(key));
+        result.getPropagationStatuses().addAll(statuses);
+        return result;
     }
 
     @Override

http://git-wip-us.apache.org/repos/asf/syncope/blob/1b81e33c/core/logic/src/main/java/org/apache/syncope/core/logic/GroupLogic.java
----------------------------------------------------------------------
diff --git 
a/core/logic/src/main/java/org/apache/syncope/core/logic/GroupLogic.java 
b/core/logic/src/main/java/org/apache/syncope/core/logic/GroupLogic.java
index a563088..60249f2 100644
--- a/core/logic/src/main/java/org/apache/syncope/core/logic/GroupLogic.java
+++ b/core/logic/src/main/java/org/apache/syncope/core/logic/GroupLogic.java
@@ -24,7 +24,6 @@ import java.util.Collection;
 import java.util.Collections;
 import java.util.HashSet;
 import java.util.List;
-import java.util.Map;
 import java.util.Set;
 import org.apache.commons.collections4.CollectionUtils;
 import org.apache.commons.collections4.Predicate;
@@ -38,6 +37,7 @@ import org.apache.syncope.common.lib.patch.GroupPatch;
 import org.apache.syncope.common.lib.patch.StringPatchItem;
 import org.apache.syncope.common.lib.to.PropagationStatus;
 import org.apache.syncope.common.lib.to.GroupTO;
+import org.apache.syncope.common.lib.to.ProvisioningResult;
 import org.apache.syncope.common.lib.types.AnyTypeKind;
 import org.apache.syncope.common.lib.types.ClientExceptionType;
 import org.apache.syncope.common.lib.types.Entitlement;
@@ -171,7 +171,7 @@ public class GroupLogic extends AbstractAnyLogic<GroupTO, 
GroupPatch> {
 
     @PreAuthorize("hasRole('" + Entitlement.GROUP_CREATE + "')")
     @Override
-    public GroupTO create(final GroupTO groupTO) {
+    public ProvisioningResult<GroupTO> create(final GroupTO groupTO, final 
boolean nullPriorityAsync) {
         Pair<GroupTO, List<LogicActions>> before = beforeCreate(groupTO);
 
         if (before.getLeft().getRealm() == null) {
@@ -183,16 +183,15 @@ public class GroupLogic extends AbstractAnyLogic<GroupTO, 
GroupPatch> {
                 Collections.singleton(before.getLeft().getRealm()));
         securityChecks(effectiveRealms, before.getLeft().getRealm(), null);
 
-        Map.Entry<Long, List<PropagationStatus>> created = 
provisioningManager.create(before.getLeft());
-        GroupTO savedTO = binder.getGroupTO(created.getKey());
-        savedTO.getPropagationStatusTOs().addAll(created.getValue());
+        Pair<Long, List<PropagationStatus>> created =
+                provisioningManager.create(before.getLeft(), 
nullPriorityAsync);
 
-        return afterCreate(savedTO, before.getValue());
+        return after(binder.getGroupTO(created.getKey()), created.getRight(), 
before.getRight());
     }
 
     @PreAuthorize("hasRole('" + Entitlement.GROUP_UPDATE + "')")
     @Override
-    public GroupTO update(final GroupPatch groupPatch) {
+    public ProvisioningResult<GroupTO> update(final GroupPatch groupPatch, 
final boolean nullPriorityAsync) {
         GroupTO groupTO = binder.getGroupTO(groupPatch.getKey());
         Pair<GroupPatch, List<LogicActions>> before = beforeUpdate(groupPatch, 
groupTO.getRealm());
 
@@ -205,17 +204,14 @@ public class GroupLogic extends AbstractAnyLogic<GroupTO, 
GroupPatch> {
             securityChecks(effectiveRealms, 
before.getLeft().getRealm().getValue(), before.getLeft().getKey());
         }
 
-        Map.Entry<Long, List<PropagationStatus>> updated = 
provisioningManager.update(groupPatch);
+        Pair<Long, List<PropagationStatus>> updated = 
provisioningManager.update(groupPatch, nullPriorityAsync);
 
-        GroupTO updatedTO = binder.getGroupTO(updated.getKey());
-        updatedTO.getPropagationStatusTOs().addAll(updated.getValue());
-
-        return afterUpdate(updatedTO, before.getRight());
+        return after(binder.getGroupTO(updated.getKey()), updated.getRight(), 
before.getRight());
     }
 
     @PreAuthorize("hasRole('" + Entitlement.GROUP_DELETE + "')")
     @Override
-    public GroupTO delete(final Long key) {
+    public ProvisioningResult<GroupTO> delete(final Long key, final boolean 
nullPriorityAsync) {
         GroupTO group = binder.getGroupTO(key);
         Pair<GroupTO, List<LogicActions>> before = beforeDelete(group);
 
@@ -237,13 +233,12 @@ public class GroupLogic extends AbstractAnyLogic<GroupTO, 
GroupPatch> {
             throw sce;
         }
 
-        List<PropagationStatus> statuses = 
provisioningManager.delete(before.getLeft().getKey());
+        List<PropagationStatus> statuses = 
provisioningManager.delete(before.getLeft().getKey(), nullPriorityAsync);
 
         GroupTO groupTO = new GroupTO();
         groupTO.setKey(before.getLeft().getKey());
-        groupTO.getPropagationStatusTOs().addAll(statuses);
 
-        return afterDelete(groupTO, before.getRight());
+        return after(groupTO, statuses, before.getRight());
     }
 
     @PreAuthorize("hasRole('" + Entitlement.GROUP_UPDATE + "')")
@@ -294,7 +289,9 @@ public class GroupLogic extends AbstractAnyLogic<GroupTO, 
GroupPatch> {
 
     @PreAuthorize("hasRole('" + Entitlement.GROUP_UPDATE + "')")
     @Override
-    public GroupTO unassign(final Long key, final Collection<String> 
resources) {
+    public ProvisioningResult<GroupTO> unassign(
+            final Long key, final Collection<String> resources, final boolean 
nullPriorityAsync) {
+
         // security checks
         GroupTO group = binder.getGroupTO(key);
         Set<String> effectiveRealms = getEffectiveRealms(
@@ -312,16 +309,17 @@ public class GroupLogic extends AbstractAnyLogic<GroupTO, 
GroupPatch> {
             }
         }));
 
-        return update(patch);
+        return update(patch, nullPriorityAsync);
     }
 
     @PreAuthorize("hasRole('" + Entitlement.GROUP_UPDATE + "')")
     @Override
-    public GroupTO assign(
+    public ProvisioningResult<GroupTO> assign(
             final Long key,
             final Collection<String> resources,
             final boolean changepwd,
-            final String password) {
+            final String password,
+            final boolean nullPriorityAsync) {
 
         // security checks
         GroupTO group = binder.getGroupTO(key);
@@ -340,12 +338,14 @@ public class GroupLogic extends AbstractAnyLogic<GroupTO, 
GroupPatch> {
             }
         }));
 
-        return update(patch);
+        return update(patch, nullPriorityAsync);
     }
 
     @PreAuthorize("hasRole('" + Entitlement.GROUP_UPDATE + "')")
     @Override
-    public GroupTO deprovision(final Long key, final Collection<String> 
resources) {
+    public ProvisioningResult<GroupTO> deprovision(
+            final Long key, final Collection<String> resources, final boolean 
nullPriorityAsync) {
+
         // security checks
         GroupTO group = binder.getGroupTO(key);
         Set<String> effectiveRealms = getEffectiveRealms(
@@ -353,20 +353,22 @@ public class GroupLogic extends AbstractAnyLogic<GroupTO, 
GroupPatch> {
                 Collections.singleton(group.getRealm()));
         securityChecks(effectiveRealms, group.getRealm(), group.getKey());
 
-        List<PropagationStatus> statuses = 
provisioningManager.deprovision(key, resources);
+        List<PropagationStatus> statuses = 
provisioningManager.deprovision(key, resources, nullPriorityAsync);
 
-        GroupTO updatedTO = binder.getGroupTO(key);
-        updatedTO.getPropagationStatusTOs().addAll(statuses);
-        return updatedTO;
+        ProvisioningResult<GroupTO> result = new ProvisioningResult<>();
+        result.setAny(binder.getGroupTO(key));
+        result.getPropagationStatuses().addAll(statuses);
+        return result;
     }
 
     @PreAuthorize("hasRole('" + Entitlement.GROUP_UPDATE + "')")
     @Override
-    public GroupTO provision(
+    public ProvisioningResult<GroupTO> provision(
             final Long key,
             final Collection<String> resources,
             final boolean changePwd,
-            final String password) {
+            final String password,
+            final boolean nullPriorityAsync) {
 
         // security checks
         GroupTO group = binder.getGroupTO(key);
@@ -375,8 +377,12 @@ public class GroupLogic extends AbstractAnyLogic<GroupTO, 
GroupPatch> {
                 Collections.singleton(group.getRealm()));
         securityChecks(effectiveRealms, group.getRealm(), group.getKey());
 
-        
group.getPropagationStatusTOs().addAll(provisioningManager.provision(key, 
resources));
-        return group;
+        List<PropagationStatus> statuses = provisioningManager.provision(key, 
resources, nullPriorityAsync);
+
+        ProvisioningResult<GroupTO> result = new ProvisioningResult<>();
+        result.setAny(binder.getGroupTO(key));
+        result.getPropagationStatuses().addAll(statuses);
+        return result;
     }
 
     @Override

http://git-wip-us.apache.org/repos/asf/syncope/blob/1b81e33c/core/logic/src/main/java/org/apache/syncope/core/logic/UserLogic.java
----------------------------------------------------------------------
diff --git 
a/core/logic/src/main/java/org/apache/syncope/core/logic/UserLogic.java 
b/core/logic/src/main/java/org/apache/syncope/core/logic/UserLogic.java
index deab762..22b7ab5 100644
--- a/core/logic/src/main/java/org/apache/syncope/core/logic/UserLogic.java
+++ b/core/logic/src/main/java/org/apache/syncope/core/logic/UserLogic.java
@@ -24,7 +24,6 @@ import java.util.Collection;
 import java.util.Collections;
 import java.util.HashSet;
 import java.util.List;
-import java.util.Map;
 import java.util.Set;
 import org.apache.commons.collections4.CollectionUtils;
 import org.apache.commons.collections4.Transformer;
@@ -39,6 +38,7 @@ import org.apache.syncope.common.lib.patch.StatusPatch;
 import org.apache.syncope.common.lib.patch.StringPatchItem;
 import org.apache.syncope.common.lib.patch.UserPatch;
 import org.apache.syncope.common.lib.to.PropagationStatus;
+import org.apache.syncope.common.lib.to.ProvisioningResult;
 import org.apache.syncope.common.lib.to.UserTO;
 import org.apache.syncope.common.lib.types.AnyTypeKind;
 import org.apache.syncope.common.lib.types.ClientExceptionType;
@@ -169,22 +169,31 @@ public class UserLogic extends AbstractAnyLogic<UserTO, 
UserPatch> {
     }
 
     @PreAuthorize("isAnonymous() or hasRole('" + Entitlement.ANONYMOUS + "')")
-    public UserTO selfCreate(final UserTO userTO, final boolean storePassword) 
{
-        return doCreate(userTO, storePassword, true);
+    public ProvisioningResult<UserTO> selfCreate(
+            final UserTO userTO, final boolean storePassword, final boolean 
nullPriorityAsync) {
+
+        return doCreate(userTO, storePassword, true, nullPriorityAsync);
     }
 
     @PreAuthorize("hasRole('" + Entitlement.USER_CREATE + "')")
     @Override
-    public UserTO create(final UserTO userTO) {
-        return create(userTO, true);
+    public ProvisioningResult<UserTO> create(final UserTO userTO, final 
boolean nullPriorityAsync) {
+        return doCreate(userTO, true, false, nullPriorityAsync);
     }
 
     @PreAuthorize("hasRole('" + Entitlement.USER_CREATE + "')")
-    public UserTO create(final UserTO userTO, final boolean storePassword) {
-        return doCreate(userTO, storePassword, false);
+    public ProvisioningResult<UserTO> create(
+            final UserTO userTO, final boolean storePassword, final boolean 
nullPriorityAsync) {
+
+        return doCreate(userTO, storePassword, false, nullPriorityAsync);
     }
 
-    protected UserTO doCreate(final UserTO userTO, final boolean 
storePassword, final boolean self) {
+    protected ProvisioningResult<UserTO> doCreate(
+            final UserTO userTO,
+            final boolean storePassword,
+            final boolean self,
+            final boolean nullPriorityAsync) {
+
         Pair<UserTO, List<LogicActions>> before = beforeCreate(userTO);
 
         if (before.getLeft().getRealm() == null) {
@@ -198,28 +207,28 @@ public class UserLogic extends AbstractAnyLogic<UserTO, 
UserPatch> {
             securityChecks(effectiveRealms, before.getLeft().getRealm(), null);
         }
 
-        Map.Entry<Long, List<PropagationStatus>> created = 
provisioningManager.create(before.getLeft(), storePassword);
+        Pair<Long, List<PropagationStatus>> created =
+                provisioningManager.create(before.getLeft(), storePassword, 
nullPriorityAsync);
 
-        UserTO savedTO = binder.getUserTO(created.getKey());
-        savedTO.getPropagationStatusTOs().addAll(created.getValue());
-
-        return binder.returnUserTO(afterCreate(savedTO, before.getValue()));
+        return after(binder.returnUserTO(binder.getUserTO(created.getKey())), 
created.getRight(), before.getRight());
     }
 
     @PreAuthorize("isAuthenticated() and not(hasRole('" + 
Entitlement.ANONYMOUS + "'))")
-    public UserTO selfUpdate(final UserPatch userPatch) {
+    public ProvisioningResult<UserTO> selfUpdate(final UserPatch userPatch, 
final boolean nullPriorityAsync) {
         UserTO userTO = binder.getAuthenticatedUserTO();
         userPatch.setKey(userTO.getKey());
-        return doUpdate(userPatch, true);
+        return doUpdate(userPatch, true, nullPriorityAsync);
     }
 
     @PreAuthorize("hasRole('" + Entitlement.USER_UPDATE + "')")
     @Override
-    public UserTO update(final UserPatch userPatch) {
-        return doUpdate(userPatch, false);
+    public ProvisioningResult<UserTO> update(final UserPatch userPatch, final 
boolean nullPriorityAsync) {
+        return doUpdate(userPatch, false, nullPriorityAsync);
     }
 
-    protected UserTO doUpdate(final UserPatch userPatch, final boolean self) {
+    protected ProvisioningResult<UserTO> doUpdate(
+            final UserPatch userPatch, final boolean self, final boolean 
nullPriorityAsync) {
+
         UserTO userTO = binder.getUserTO(userPatch.getKey());
         Pair<UserPatch, List<LogicActions>> before = beforeUpdate(userPatch, 
userTO.getRealm());
 
@@ -235,29 +244,28 @@ public class UserLogic extends AbstractAnyLogic<UserTO, 
UserPatch> {
             securityChecks(effectiveRealms, 
before.getLeft().getRealm().getValue(), before.getLeft().getKey());
         }
 
-        Map.Entry<Long, List<PropagationStatus>> updated = 
provisioningManager.update(before.getLeft());
-
-        UserTO updatedTO = binder.getUserTO(updated.getKey());
-        updatedTO.getPropagationStatusTOs().addAll(updated.getValue());
+        Pair<Long, List<PropagationStatus>> updated = 
provisioningManager.update(before.getLeft(), nullPriorityAsync);
 
-        return binder.returnUserTO(afterUpdate(updatedTO, before.getRight()));
+        return after(binder.returnUserTO(binder.getUserTO(updated.getKey())), 
updated.getRight(), before.getRight());
     }
 
-    protected Map.Entry<Long, List<PropagationStatus>> 
setStatusOnWfAdapter(final StatusPatch statusPatch) {
-        Map.Entry<Long, List<PropagationStatus>> updated;
+    protected Pair<Long, List<PropagationStatus>> setStatusOnWfAdapter(
+            final StatusPatch statusPatch, final boolean nullPriorityAsync) {
+
+        Pair<Long, List<PropagationStatus>> updated;
 
         switch (statusPatch.getType()) {
             case SUSPEND:
-                updated = provisioningManager.suspend(statusPatch);
+                updated = provisioningManager.suspend(statusPatch, 
nullPriorityAsync);
                 break;
 
             case REACTIVATE:
-                updated = provisioningManager.reactivate(statusPatch);
+                updated = provisioningManager.reactivate(statusPatch, 
nullPriorityAsync);
                 break;
 
             case ACTIVATE:
             default:
-                updated = provisioningManager.activate(statusPatch);
+                updated = provisioningManager.activate(statusPatch, 
nullPriorityAsync);
                 break;
 
         }
@@ -266,7 +274,7 @@ public class UserLogic extends AbstractAnyLogic<UserTO, 
UserPatch> {
     }
 
     @PreAuthorize("hasRole('" + Entitlement.USER_UPDATE + "')")
-    public UserTO status(final StatusPatch statusPatch) {
+    public ProvisioningResult<UserTO> status(final StatusPatch statusPatch, 
final boolean nullPriorityAsync) {
         // security checks
         UserTO toUpdate = binder.getUserTO(statusPatch.getKey());
         Set<String> effectiveRealms = getEffectiveRealms(
@@ -274,18 +282,20 @@ public class UserLogic extends AbstractAnyLogic<UserTO, 
UserPatch> {
                 Collections.singleton(toUpdate.getRealm()));
         securityChecks(effectiveRealms, toUpdate.getRealm(), 
toUpdate.getKey());
 
-        Map.Entry<Long, List<PropagationStatus>> updated = 
setStatusOnWfAdapter(statusPatch);
-        UserTO savedTO = binder.getUserTO(updated.getKey());
-        savedTO.getPropagationStatusTOs().addAll(updated.getValue());
-        return binder.returnUserTO(savedTO);
+        Pair<Long, List<PropagationStatus>> updated = 
setStatusOnWfAdapter(statusPatch, nullPriorityAsync);
+
+        return after(
+                binder.returnUserTO(binder.getUserTO(updated.getKey())),
+                updated.getRight(),
+                Collections.<LogicActions>emptyList());
     }
 
     @PreAuthorize("hasRole('" + Entitlement.MUST_CHANGE_PASSWORD + "')")
-    public UserTO changePassword(final String password) {
+    public ProvisioningResult<UserTO> changePassword(final String password, 
final boolean nullPriorityAsync) {
         UserPatch userPatch = new UserPatch();
         userPatch.setPassword(new 
PasswordPatch.Builder().value(password).build());
         userPatch.setMustChangePassword(new 
BooleanReplacePatchItem.Builder().value(false).build());
-        return selfUpdate(userPatch);
+        return selfUpdate(userPatch, nullPriorityAsync);
     }
 
     @PreAuthorize("isAnonymous() or hasRole('" + Entitlement.ANONYMOUS + "')")
@@ -320,19 +330,21 @@ public class UserLogic extends AbstractAnyLogic<UserTO, 
UserPatch> {
     }
 
     @PreAuthorize("isAuthenticated() and not(hasRole('" + 
Entitlement.ANONYMOUS + "'))")
-    public UserTO selfDelete() {
+    public ProvisioningResult<UserTO> selfDelete(final boolean 
nullPriorityAsync) {
         UserTO userTO = binder.getAuthenticatedUserTO();
-        return doDelete(userTO, true);
+        return doDelete(userTO, true, nullPriorityAsync);
     }
 
     @PreAuthorize("hasRole('" + Entitlement.USER_DELETE + "')")
     @Override
-    public UserTO delete(final Long key) {
+    public ProvisioningResult<UserTO> delete(final Long key, final boolean 
nullPriorityAsync) {
         UserTO userTO = binder.getUserTO(key);
-        return doDelete(userTO, false);
+        return doDelete(userTO, false, nullPriorityAsync);
     }
 
-    protected UserTO doDelete(final UserTO userTO, final boolean self) {
+    protected ProvisioningResult<UserTO> doDelete(
+            final UserTO userTO, final boolean self, final boolean 
nullPriorityAsync) {
+
         Pair<UserTO, List<LogicActions>> before = beforeDelete(userTO);
 
         if (!self) {
@@ -355,7 +367,7 @@ public class UserLogic extends AbstractAnyLogic<UserTO, 
UserPatch> {
             throw sce;
         }
 
-        List<PropagationStatus> statuses = 
provisioningManager.delete(before.getLeft().getKey());
+        List<PropagationStatus> statuses = 
provisioningManager.delete(before.getLeft().getKey(), nullPriorityAsync);
 
         UserTO deletedTO;
         if (userDAO.find(before.getLeft().getKey()) == null) {
@@ -364,9 +376,8 @@ public class UserLogic extends AbstractAnyLogic<UserTO, 
UserPatch> {
         } else {
             deletedTO = binder.getUserTO(before.getLeft().getKey());
         }
-        deletedTO.getPropagationStatusTOs().addAll(statuses);
 
-        return binder.returnUserTO(afterDelete(deletedTO, before.getRight()));
+        return after(binder.returnUserTO(deletedTO), statuses, 
before.getRight());
     }
 
     @PreAuthorize("hasRole('" + Entitlement.USER_UPDATE + "')")
@@ -417,7 +428,9 @@ public class UserLogic extends AbstractAnyLogic<UserTO, 
UserPatch> {
 
     @PreAuthorize("hasRole('" + Entitlement.USER_UPDATE + "')")
     @Override
-    public UserTO unassign(final Long key, final Collection<String> resources) 
{
+    public ProvisioningResult<UserTO> unassign(
+            final Long key, final Collection<String> resources, final boolean 
nullPriorityAsync) {
+
         // security checks
         UserTO user = binder.getUserTO(key);
         Set<String> effectiveRealms = getEffectiveRealms(
@@ -435,16 +448,17 @@ public class UserLogic extends AbstractAnyLogic<UserTO, 
UserPatch> {
             }
         }));
 
-        return update(patch);
+        return update(patch, nullPriorityAsync);
     }
 
     @PreAuthorize("hasRole('" + Entitlement.USER_UPDATE + "')")
     @Override
-    public UserTO assign(
+    public ProvisioningResult<UserTO> assign(
             final Long key,
             final Collection<String> resources,
             final boolean changepwd,
-            final String password) {
+            final String password,
+            final boolean nullPriorityAsync) {
 
         // security checks
         UserTO user = binder.getUserTO(key);
@@ -468,12 +482,14 @@ public class UserLogic extends AbstractAnyLogic<UserTO, 
UserPatch> {
                     
value(password).onSyncope(false).resources(resources).build());
         }
 
-        return update(patch);
+        return update(patch, nullPriorityAsync);
     }
 
     @PreAuthorize("hasRole('" + Entitlement.USER_UPDATE + "')")
     @Override
-    public UserTO deprovision(final Long key, final Collection<String> 
resources) {
+    public ProvisioningResult<UserTO> deprovision(
+            final Long key, final Collection<String> resources, final boolean 
nullPriorityAsync) {
+
         // security checks
         UserTO user = binder.getUserTO(key);
         Set<String> effectiveRealms = getEffectiveRealms(
@@ -481,20 +497,22 @@ public class UserLogic extends AbstractAnyLogic<UserTO, 
UserPatch> {
                 Collections.singleton(user.getRealm()));
         securityChecks(effectiveRealms, user.getRealm(), user.getKey());
 
-        List<PropagationStatus> statuses = 
provisioningManager.deprovision(key, resources);
+        List<PropagationStatus> statuses = 
provisioningManager.deprovision(key, resources, nullPriorityAsync);
 
-        UserTO updatedTO = binder.getUserTO(key);
-        updatedTO.getPropagationStatusTOs().addAll(statuses);
-        return binder.returnUserTO(updatedTO);
+        ProvisioningResult<UserTO> result = new ProvisioningResult<>();
+        result.setAny(binder.returnUserTO(binder.getUserTO(key)));
+        result.getPropagationStatuses().addAll(statuses);
+        return result;
     }
 
     @PreAuthorize("hasRole('" + Entitlement.USER_UPDATE + "')")
     @Override
-    public UserTO provision(
+    public ProvisioningResult<UserTO> provision(
             final Long key,
             final Collection<String> resources,
             final boolean changePwd,
-            final String password) {
+            final String password,
+            final boolean nullPriorityAsync) {
 
         // security checks
         UserTO user = binder.getUserTO(key);
@@ -503,8 +521,13 @@ public class UserLogic extends AbstractAnyLogic<UserTO, 
UserPatch> {
                 Collections.singleton(user.getRealm()));
         securityChecks(effectiveRealms, user.getRealm(), user.getKey());
 
-        
user.getPropagationStatusTOs().addAll(provisioningManager.provision(key, 
changePwd, password, resources));
-        return binder.returnUserTO(user);
+        List<PropagationStatus> statuses =
+                provisioningManager.provision(key, changePwd, password, 
resources, nullPriorityAsync);
+
+        ProvisioningResult<UserTO> result = new ProvisioningResult<>();
+        result.setAny(binder.returnUserTO(binder.getUserTO(key)));
+        result.getPropagationStatuses().addAll(statuses);
+        return result;
     }
 
     @Override

http://git-wip-us.apache.org/repos/asf/syncope/blob/1b81e33c/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/resource/ExternalResource.java
----------------------------------------------------------------------
diff --git 
a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/resource/ExternalResource.java
 
b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/resource/ExternalResource.java
index 0cc3c04..968b779 100644
--- 
a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/resource/ExternalResource.java
+++ 
b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/resource/ExternalResource.java
@@ -87,10 +87,6 @@ public interface ExternalResource extends 
AnnotatedEntity<String> {
 
     void setEnforceMandatoryCondition(boolean enforce);
 
-    boolean isPropagationPrimary();
-
-    void setPropagationPrimary(boolean condition);
-
     boolean isRandomPwdIfNotProvided();
 
     void setRandomPwdIfNotProvided(boolean condition);

http://git-wip-us.apache.org/repos/asf/syncope/blob/1b81e33c/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/task/PropagationTask.java
----------------------------------------------------------------------
diff --git 
a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/task/PropagationTask.java
 
b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/task/PropagationTask.java
index 2d19436..842cf86 100644
--- 
a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/task/PropagationTask.java
+++ 
b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/task/PropagationTask.java
@@ -34,6 +34,8 @@ public interface PropagationTask extends Task {
 
     void setOldConnObjectKey(String oldConnObjectKey);
 
+    String getSerializedAttributes();
+
     Set<Attribute> getAttributes();
 
     void setAttributes(Set<Attribute> attributes);

http://git-wip-us.apache.org/repos/asf/syncope/blob/1b81e33c/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/resource/JPAExternalResource.java
----------------------------------------------------------------------
diff --git 
a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/resource/JPAExternalResource.java
 
b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/resource/JPAExternalResource.java
index 393338b..0653cf3 100644
--- 
a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/resource/JPAExternalResource.java
+++ 
b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/resource/JPAExternalResource.java
@@ -100,18 +100,8 @@ public class JPAExternalResource extends 
AbstractAnnotatedEntity<String> impleme
     private List<JPAProvision> provisions = new ArrayList<>();
 
     /**
-     * Is this resource primary, for propagations?
-     */
-    @NotNull
-    @Basic
-    @Min(0)
-    @Max(1)
-    private Integer propagationPrimary;
-
-    /**
      * Priority index for propagation ordering.
      */
-    @NotNull
     private Integer propagationPriority;
 
     /**
@@ -182,7 +172,6 @@ public class JPAExternalResource extends 
AbstractAnnotatedEntity<String> impleme
         super();
 
         enforceMandatoryCondition = getBooleanAsInteger(false);
-        propagationPrimary = 0;
         propagationPriority = 0;
         randomPwdIfNotProvided = 0;
         overrideCapabilities = 0;
@@ -254,16 +243,6 @@ public class JPAExternalResource extends 
AbstractAnnotatedEntity<String> impleme
     }
 
     @Override
-    public boolean isPropagationPrimary() {
-        return isBooleanAsInteger(propagationPrimary);
-    }
-
-    @Override
-    public void setPropagationPrimary(final boolean propagationPrimary) {
-        this.propagationPrimary = getBooleanAsInteger(propagationPrimary);
-    }
-
-    @Override
     public Integer getPropagationPriority() {
         return propagationPriority;
     }

http://git-wip-us.apache.org/repos/asf/syncope/blob/1b81e33c/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/task/JPAPropagationTask.java
----------------------------------------------------------------------
diff --git 
a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/task/JPAPropagationTask.java
 
b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/task/JPAPropagationTask.java
index 9882752..94c7d8d 100644
--- 
a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/task/JPAPropagationTask.java
+++ 
b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/task/JPAPropagationTask.java
@@ -68,7 +68,7 @@ public class JPAPropagationTask extends AbstractTask 
implements PropagationTask
      * Attributes to be propagated.
      */
     @Lob
-    private String xmlAttributes;
+    private String attributes;
 
     private String objectClassName;
 
@@ -111,18 +111,23 @@ public class JPAPropagationTask extends AbstractTask 
implements PropagationTask
     }
 
     @Override
+    public String getSerializedAttributes() {
+        return this.attributes;
+    }
+
+    @Override
     public Set<Attribute> getAttributes() {
-        Set<Attribute> attributes = new HashSet<>();
-        if (!StringUtils.isBlank(xmlAttributes)) {
-            CollectionUtils.addAll(attributes, 
POJOHelper.deserialize(xmlAttributes, Attribute[].class));
+        Set<Attribute> result = new HashSet<>();
+        if (StringUtils.isNotBlank(this.attributes)) {
+            CollectionUtils.addAll(result, 
POJOHelper.deserialize(this.attributes, Attribute[].class));
         }
 
-        return attributes;
+        return result;
     }
 
     @Override
     public void setAttributes(final Set<Attribute> attributes) {
-        xmlAttributes = POJOHelper.serialize(attributes);
+        this.attributes = POJOHelper.serialize(attributes);
     }
 
     @Override

http://git-wip-us.apache.org/repos/asf/syncope/blob/1b81e33c/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/inner/ResourceTest.java
----------------------------------------------------------------------
diff --git 
a/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/inner/ResourceTest.java
 
b/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/inner/ResourceTest.java
index 0fc2a3e..be37d88 100644
--- 
a/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/inner/ResourceTest.java
+++ 
b/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/inner/ResourceTest.java
@@ -105,7 +105,6 @@ public class ResourceTest extends AbstractTest {
         ExternalResource resource = 
entityFactory.newEntity(ExternalResource.class);
         resource.setKey("ws-target-resource-basic-save");
         resource.setPropagationPriority(2);
-        resource.setPropagationPrimary(true);
 
         Provision provision = entityFactory.newEntity(Provision.class);
         provision.setAnyType(anyTypeDAO.findUser());
@@ -135,7 +134,6 @@ public class ResourceTest extends AbstractTest {
         assertNotNull(actual.getProvision(anyTypeDAO.findUser()).getMapping());
         
assertFalse(actual.getProvision(anyTypeDAO.findUser()).getMapping().getItems().isEmpty());
         assertEquals(Integer.valueOf(2), actual.getPropagationPriority());
-        assertTrue(actual.isPropagationPrimary());
     }
 
     @Test(expected = InvalidEntityException.class)
@@ -264,7 +262,6 @@ public class ResourceTest extends AbstractTest {
         ExternalResource resource = 
entityFactory.newEntity(ExternalResource.class);
         resource.setKey("ws-target-resource-virtual-mapping");
         resource.setPropagationPriority(2);
-        resource.setPropagationPrimary(true);
 
         Provision provision = entityFactory.newEntity(Provision.class);
         provision.setAnyType(anyTypeDAO.findUser());

Reply via email to