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 2015/02/03 13:03:15 UTC

[2/3] syncope git commit: [SYNCOPE-620] IT for Camel: success

[SYNCOPE-620] IT for Camel: success


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

Branch: refs/heads/2_0_X
Commit: 42f78fee6e0419fb5be8cd334cee8e076749a12e
Parents: c7e8193
Author: Francesco Chicchiriccò <il...@apache.org>
Authored: Tue Feb 3 12:06:14 2015 +0100
Committer: Francesco Chicchiriccò <il...@apache.org>
Committed: Tue Feb 3 12:06:14 2015 +0100

----------------------------------------------------------------------
 .../common/rest/api/service/SyncopeService.java |   2 +-
 .../syncope/server/logic/CamelRouteLogic.java   |   7 +-
 .../server/logic/init/CamelRouteLoader.java     |  42 ++---
 .../persistence/jpa/dao/JPACamelRouteDAO.java   |   2 +-
 .../persistence/jpa/entity/JPACamelRoute.java   |   8 +-
 .../camel/AbstractCamelProvisioningManager.java |   2 +-
 .../camel/CamelRoleProvisioningManager.java     |  30 ++--
 .../camel/CamelUserProvisioningManager.java     |  76 ++++-----
 .../provisioning/camel/SyncopeCamelContext.java |  25 +--
 .../processor/RoleCreateInSyncProcessor.java    |  72 ++++++++
 .../camel/processor/RoleCreateProcessor.java    |  77 +++++++++
 .../camel/processor/RoleDeleteProcessor.java    | 105 ++++++++++++
 .../processor/RoleDeprovisionProcessor.java     |  78 +++++++++
 .../camel/processor/RoleUpdateProcessor.java    |  71 ++++++++
 .../processor/UserConfirmPwdResetProcessor.java |  61 +++++++
 .../camel/processor/UserCreateProcessor.java    |  76 +++++++++
 .../camel/processor/UserDeleteProcessor.java    |  72 ++++++++
 .../processor/UserDeprovisionProcessor.java     |  78 +++++++++
 .../processor/UserInnerSuspendProcessor.java    |  61 +++++++
 .../processor/UserSetStatusInSyncProcessor.java |  74 +++++++++
 .../UserStatusPropagationProcessor.java         |  76 +++++++++
 .../processor/UserUpdateInSyncProcessor.java    |  73 +++++++++
 .../camel/processor/UserUpdateProcessor.java    | 105 ++++++++++++
 .../main/resources/provisioningCamelContext.xml |   9 +-
 .../src/main/resources/roleRoutes.xml           |  50 ++----
 .../src/main/resources/userRoutes.xml           | 130 ++++-----------
 .../rest/api/service/CamelRouteService.java     |  12 +-
 .../rest/cxf/service/CamelRouteServiceImpl.java |   5 +
 syncope620/fit/reference/pom.xml                |  22 +++
 .../fit/reference/src/main/resources/log4j2.xml |   8 +-
 .../src/main/resources/provisioning.properties  |  19 +++
 .../fit/server/reference/AbstractITCase.java    |   4 +
 .../fit/server/reference/ActivitiDetector.java  |   4 -
 .../fit/server/reference/CamelDetector.java     |  32 ++++
 .../fit/server/reference/CamelRouteITCase.java  | 164 +++++++++++++++++++
 ...ltiJarAwarePersistenceUnitPostProcessor.java |  47 ++++++
 .../resources/persistenceContextEMFactory.xml   |   9 +-
 .../java/DefaultRoleProvisioningManager.java    |  35 ++--
 .../java/DefaultUserProvisioningManager.java    |  29 ++--
 .../java/sync/UserSyncResultHandlerImpl.java    |   1 -
 .../resources/META-INF/org.apache.cxf.Logger    |   1 +
 .../src/main/resources/workflowContext.xml      |   4 +-
 42 files changed, 1580 insertions(+), 278 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/syncope/blob/42f78fee/syncope620/common/rest-api/src/main/java/org/apache/syncope/common/rest/api/service/SyncopeService.java
----------------------------------------------------------------------
diff --git a/syncope620/common/rest-api/src/main/java/org/apache/syncope/common/rest/api/service/SyncopeService.java b/syncope620/common/rest-api/src/main/java/org/apache/syncope/common/rest/api/service/SyncopeService.java
index 55cc092..cdd6dbc 100644
--- a/syncope620/common/rest-api/src/main/java/org/apache/syncope/common/rest/api/service/SyncopeService.java
+++ b/syncope620/common/rest-api/src/main/java/org/apache/syncope/common/rest/api/service/SyncopeService.java
@@ -28,6 +28,6 @@ import org.apache.syncope.common.lib.to.SyncopeTO;
 public interface SyncopeService extends JAXRSService {
 
     @GET
-    @Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON, MediaType.APPLICATION_XHTML_XML })
+    @Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
     SyncopeTO info();
 }

http://git-wip-us.apache.org/repos/asf/syncope/blob/42f78fee/syncope620/ext/camel/logic/src/main/java/org/apache/syncope/server/logic/CamelRouteLogic.java
----------------------------------------------------------------------
diff --git a/syncope620/ext/camel/logic/src/main/java/org/apache/syncope/server/logic/CamelRouteLogic.java b/syncope620/ext/camel/logic/src/main/java/org/apache/syncope/server/logic/CamelRouteLogic.java
index 4602b51..1b13166 100644
--- a/syncope620/ext/camel/logic/src/main/java/org/apache/syncope/server/logic/CamelRouteLogic.java
+++ b/syncope620/ext/camel/logic/src/main/java/org/apache/syncope/server/logic/CamelRouteLogic.java
@@ -77,7 +77,12 @@ public class CamelRouteLogic extends AbstractTransactionalLogic<CamelRouteTO> {
         LOG.debug("Updating route {} with content {}", routeTO.getKey(), routeTO.getContent());
         binder.update(route, routeTO);
 
-        context.reloadContext(routeTO.getKey());
+        context.updateContext(routeTO.getKey());
+    }
+
+    @PreAuthorize("hasRole('ROUTE_UPDATE')")
+    public void restartContext() {
+        context.restartContext();
     }
 
     @Override

http://git-wip-us.apache.org/repos/asf/syncope/blob/42f78fee/syncope620/ext/camel/logic/src/main/java/org/apache/syncope/server/logic/init/CamelRouteLoader.java
----------------------------------------------------------------------
diff --git a/syncope620/ext/camel/logic/src/main/java/org/apache/syncope/server/logic/init/CamelRouteLoader.java b/syncope620/ext/camel/logic/src/main/java/org/apache/syncope/server/logic/init/CamelRouteLoader.java
index 34181ae..a7f24a7 100644
--- a/syncope620/ext/camel/logic/src/main/java/org/apache/syncope/server/logic/init/CamelRouteLoader.java
+++ b/syncope620/ext/camel/logic/src/main/java/org/apache/syncope/server/logic/init/CamelRouteLoader.java
@@ -22,8 +22,6 @@ import java.io.StringWriter;
 import java.util.List;
 import java.util.Map;
 import javax.sql.DataSource;
-import javax.xml.parsers.DocumentBuilderFactory;
-import javax.xml.transform.TransformerFactory;
 import org.apache.syncope.common.lib.types.SubjectType;
 import org.apache.syncope.server.misc.spring.ResourceWithFallbackLoader;
 import org.apache.syncope.server.persistence.api.SyncopeLoader;
@@ -52,10 +50,6 @@ public class CamelRouteLoader implements SyncopeLoader {
 
     private static final Logger LOG = LoggerFactory.getLogger(CamelRouteLoader.class);
 
-    private static final DocumentBuilderFactory DOC_FACTORY = DocumentBuilderFactory.newInstance();
-
-    private static final TransformerFactory T_FACTORY = TransformerFactory.newInstance();
-
     @javax.annotation.Resource(name = "userRoutes")
     private ResourceWithFallbackLoader userRoutesLoader;
 
@@ -68,8 +62,6 @@ public class CamelRouteLoader implements SyncopeLoader {
     @Autowired
     private CamelEntityFactory entityFactory;
 
-    private int size = 0;
-
     private boolean loaded = false;
 
     @Override
@@ -89,18 +81,19 @@ public class CamelRouteLoader implements SyncopeLoader {
         }
     }
 
-    private boolean routesAvailable(final SubjectType subject) {
-        final String sql = String.format("SELECT * FROM %s WHERE SUBJECT = ?", CamelRoute.class.getSimpleName());
+    private boolean loadRoutesFor(final SubjectType subject) {
+        final String sql = String.format("SELECT * FROM %s WHERE SUBJECTTYPE = ?", CamelRoute.class.getSimpleName());
         final JdbcTemplate jdbcTemplate = new JdbcTemplate(dataSource);
         final List<Map<String, Object>> rows = jdbcTemplate.queryForList(sql, new Object[] { subject.name() });
-        return !rows.isEmpty();
+        return rows.isEmpty();
     }
 
-    private String nodeToString(final Node content, final DOMImplementationLS impl) {
+    private String nodeToString(final Node content, final DOMImplementationLS domImpl) {
         StringWriter writer = new StringWriter();
         try {
-            LSSerializer serializer = impl.createLSSerializer();
-            LSOutput lso = impl.createLSOutput();
+            LSSerializer serializer = domImpl.createLSSerializer();
+            serializer.getDomConfig().setParameter("xml-declaration", false);
+            LSOutput lso = domImpl.createLSOutput();
             lso.setCharacterStream(writer);
             serializer.write(content, lso);
         } catch (Exception e) {
@@ -110,8 +103,8 @@ public class CamelRouteLoader implements SyncopeLoader {
     }
 
     private void loadRoutes(final Resource resource, final SubjectType subjectType) {
-        if (routesAvailable(subjectType)) {
-            String query = String.format("INSERT INTO %s(NAME, SUBJECT, ROUTECONTENT) VALUES (?, ?, ?, ?)",
+        if (loadRoutesFor(subjectType)) {
+            String query = String.format("INSERT INTO %s(NAME, SUBJECTTYPE, CONTENT) VALUES (?, ?, ?)",
                     CamelRoute.class.getSimpleName());
             JdbcTemplate jdbcTemplate = new JdbcTemplate(dataSource);
 
@@ -123,20 +116,19 @@ public class CamelRouteLoader implements SyncopeLoader {
 
                 LSParser parser = domImpl.createLSParser(DOMImplementationLS.MODE_SYNCHRONOUS, null);
 
-                NodeList routeNodes = parser.parse(lsinput).getElementsByTagName("route");
+                NodeList routeNodes = parser.parse(lsinput).getDocumentElement().getElementsByTagName("route");
                 for (int s = 0; s < routeNodes.getLength(); s++) {
                     Node routeElement = routeNodes.item(s);
                     String routeContent = nodeToString(routeNodes.item(s), domImpl);
+                    String routeId = ((Element) routeElement).getAttribute("id");
 
-                    //crate an instance of CamelRoute Entity
                     CamelRoute route = entityFactory.newCamelRoute();
                     route.setSubjectType(subjectType);
-                    route.setKey(((Element) routeElement).getAttribute("id"));
+                    route.setKey(routeId);
                     route.setContent(routeContent);
 
-                    jdbcTemplate.update(query, new Object[] {
-                        ((Element) routeElement).getAttribute("id"), subjectType.name(), routeContent });
-                    LOG.debug("Route {} successfully loaded", ((Element) routeElement).getAttribute("id"));
+                    jdbcTemplate.update(query, new Object[] { routeId, subjectType.name(), routeContent });
+                    LOG.debug("Route {} successfully loaded", routeId);
                 }
             } catch (DataAccessException e) {
                 LOG.error("While trying to store queries {}", e);
@@ -148,8 +140,8 @@ public class CamelRouteLoader implements SyncopeLoader {
 
     private void loadEntitlements() {
         final JdbcTemplate jdbcTemplate = new JdbcTemplate(dataSource);
-        jdbcTemplate.update("INSERT INTO Entitlement VALUES('ROUTE_READ')");
-        jdbcTemplate.update("INSERT INTO Entitlement VALUES('ROUTE_LIST')");
-        jdbcTemplate.update("INSERT INTO Entitlement VALUES('ROUTE_UPDATE')");
+        jdbcTemplate.update("INSERT INTO Entitlement(NAME) VALUES('ROUTE_READ')");
+        jdbcTemplate.update("INSERT INTO Entitlement(NAME) VALUES('ROUTE_LIST')");
+        jdbcTemplate.update("INSERT INTO Entitlement(NAME) VALUES('ROUTE_UPDATE')");
     }
 }

http://git-wip-us.apache.org/repos/asf/syncope/blob/42f78fee/syncope620/ext/camel/persistence-jpa/src/main/java/org/apache/syncope/server/persistence/jpa/dao/JPACamelRouteDAO.java
----------------------------------------------------------------------
diff --git a/syncope620/ext/camel/persistence-jpa/src/main/java/org/apache/syncope/server/persistence/jpa/dao/JPACamelRouteDAO.java b/syncope620/ext/camel/persistence-jpa/src/main/java/org/apache/syncope/server/persistence/jpa/dao/JPACamelRouteDAO.java
index 3302150..6b5fcb2 100644
--- a/syncope620/ext/camel/persistence-jpa/src/main/java/org/apache/syncope/server/persistence/jpa/dao/JPACamelRouteDAO.java
+++ b/syncope620/ext/camel/persistence-jpa/src/main/java/org/apache/syncope/server/persistence/jpa/dao/JPACamelRouteDAO.java
@@ -33,7 +33,7 @@ public class JPACamelRouteDAO extends AbstractDAO<CamelRoute, String> implements
 
     @Override
     public CamelRoute find(final String key) {
-        return entityManager.find(CamelRoute.class, key);
+        return entityManager.find(JPACamelRoute.class, key);
     }
 
     @Transactional(readOnly = true)

http://git-wip-us.apache.org/repos/asf/syncope/blob/42f78fee/syncope620/ext/camel/persistence-jpa/src/main/java/org/apache/syncope/server/persistence/jpa/entity/JPACamelRoute.java
----------------------------------------------------------------------
diff --git a/syncope620/ext/camel/persistence-jpa/src/main/java/org/apache/syncope/server/persistence/jpa/entity/JPACamelRoute.java b/syncope620/ext/camel/persistence-jpa/src/main/java/org/apache/syncope/server/persistence/jpa/entity/JPACamelRoute.java
index d9d5fad..2606305 100644
--- a/syncope620/ext/camel/persistence-jpa/src/main/java/org/apache/syncope/server/persistence/jpa/entity/JPACamelRoute.java
+++ b/syncope620/ext/camel/persistence-jpa/src/main/java/org/apache/syncope/server/persistence/jpa/entity/JPACamelRoute.java
@@ -41,7 +41,7 @@ public class JPACamelRoute extends AbstractEntity<String> implements CamelRoute
 
     @NotNull
     @Enumerated(EnumType.STRING)
-    private SubjectType subject;
+    private SubjectType subjectType;
 
     @Lob
     private String content;
@@ -58,12 +58,12 @@ public class JPACamelRoute extends AbstractEntity<String> implements CamelRoute
 
     @Override
     public SubjectType getSubjectType() {
-        return subject;
+        return subjectType;
     }
 
     @Override
-    public void setSubjectType(final SubjectType subject) {
-        this.subject = subject;
+    public void setSubjectType(final SubjectType subjectType) {
+        this.subjectType = subjectType;
     }
 
     @Override

http://git-wip-us.apache.org/repos/asf/syncope/blob/42f78fee/syncope620/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/server/provisioning/camel/AbstractCamelProvisioningManager.java
----------------------------------------------------------------------
diff --git a/syncope620/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/server/provisioning/camel/AbstractCamelProvisioningManager.java b/syncope620/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/server/provisioning/camel/AbstractCamelProvisioningManager.java
index b932d66..843e817 100644
--- a/syncope620/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/server/provisioning/camel/AbstractCamelProvisioningManager.java
+++ b/syncope620/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/server/provisioning/camel/AbstractCamelProvisioningManager.java
@@ -37,7 +37,7 @@ import org.springframework.beans.factory.annotation.Autowired;
 
 abstract class AbstractCamelProvisioningManager {
 
-    private static final Logger LOG = LoggerFactory.getLogger(CamelUserProvisioningManager.class);
+    private static final Logger LOG = LoggerFactory.getLogger(AbstractCamelProvisioningManager.class);
 
     @Autowired
     protected CamelRouteDAO routeDAO;

http://git-wip-us.apache.org/repos/asf/syncope/blob/42f78fee/syncope620/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/server/provisioning/camel/CamelRoleProvisioningManager.java
----------------------------------------------------------------------
diff --git a/syncope620/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/server/provisioning/camel/CamelRoleProvisioningManager.java b/syncope620/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/server/provisioning/camel/CamelRoleProvisioningManager.java
index 4dbe36a..73703f1 100644
--- a/syncope620/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/server/provisioning/camel/CamelRoleProvisioningManager.java
+++ b/syncope620/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/server/provisioning/camel/CamelRoleProvisioningManager.java
@@ -42,13 +42,13 @@ public class CamelRoleProvisioningManager extends AbstractCamelProvisioningManag
     @Override
     @SuppressWarnings("unchecked")
     public Map.Entry<Long, List<PropagationStatus>> create(final RoleTO roleTO, final Set<String> excludedResources) {
+        PollingConsumer pollingConsumer = getConsumer("direct:createRolePort");
+
         Map<String, Object> props = new HashMap<>();
         props.put("excludedResources", excludedResources);
 
         sendMessage("direct:createRole", roleTO, props);
 
-        String uri = "direct:createRolePort";
-        PollingConsumer pollingConsumer = getConsumer(uri);
         Exchange exchange = pollingConsumer.receive();
 
         if (exchange.getProperty(Exchange.EXCEPTION_CAUGHT) != null) {
@@ -63,14 +63,14 @@ public class CamelRoleProvisioningManager extends AbstractCamelProvisioningManag
     public Map.Entry<Long, List<PropagationStatus>> create(final RoleTO roleTO, final Map<Long, String> roleOwnerMap,
             final Set<String> excludedResources) throws PropagationException {
 
+        PollingConsumer pollingConsumer = getConsumer("direct:createRoleInSyncPort");
+
         Map<String, Object> props = new HashMap<>();
         props.put("roleOwnerMap", roleOwnerMap);
         props.put("excludedResources", excludedResources);
 
-        sendMessage("direct:createRoleSync", roleTO, props);
+        sendMessage("direct:createRoleInSync", roleTO, props);
 
-        String uri = "direct:createRoleSyncPort";
-        PollingConsumer pollingConsumer = getConsumer(uri);
         Exchange exchange = pollingConsumer.receive();
 
         if (exchange.getProperty(Exchange.EXCEPTION_CAUGHT) != null) {
@@ -90,13 +90,13 @@ public class CamelRoleProvisioningManager extends AbstractCamelProvisioningManag
     public Map.Entry<Long, List<PropagationStatus>> update(
             final RoleMod subjectMod, final Set<String> excludedResources) {
 
+        PollingConsumer pollingConsumer = getConsumer("direct:updateRolePort");
+
         Map<String, Object> props = new HashMap<>();
         props.put("excludedResources", excludedResources);
 
         sendMessage("direct:updateRole", subjectMod, props);
 
-        String uri = "direct:updateRolePort";
-        PollingConsumer pollingConsumer = getConsumer(uri);
         Exchange exchange = pollingConsumer.receive();
 
         if (exchange.getProperty(Exchange.EXCEPTION_CAUGHT) != null) {
@@ -109,10 +109,10 @@ public class CamelRoleProvisioningManager extends AbstractCamelProvisioningManag
     @Override
     @SuppressWarnings("unchecked")
     public List<PropagationStatus> delete(final Long roleKey) {
+        PollingConsumer pollingConsumer = getConsumer("direct:deleteRolePort");
+
         sendMessage("direct:deleteRole", roleKey);
 
-        String uri = "direct:deleteRolePort";
-        PollingConsumer pollingConsumer = getConsumer(uri);
         Exchange exchange = pollingConsumer.receive();
 
         if (exchange.getProperty(Exchange.EXCEPTION_CAUGHT) != null) {
@@ -124,10 +124,10 @@ public class CamelRoleProvisioningManager extends AbstractCamelProvisioningManag
 
     @Override
     public Long unlink(final RoleMod roleMod) {
+        PollingConsumer pollingConsumer = getConsumer("direct:unlinkRolePort");
+
         sendMessage("direct:unlinkRole", roleMod);
 
-        String uri = "direct:unlinkRolePort";
-        PollingConsumer pollingConsumer = getConsumer(uri);
         Exchange exchange = pollingConsumer.receive();
 
         if (exchange.getProperty(Exchange.EXCEPTION_CAUGHT) != null) {
@@ -139,10 +139,10 @@ public class CamelRoleProvisioningManager extends AbstractCamelProvisioningManag
 
     @Override
     public Long link(final RoleMod roleMod) {
+        PollingConsumer pollingConsumer = getConsumer("direct:linkRolePort");
+
         sendMessage("direct:linkRole", roleMod);
 
-        String uri = "direct:linkRolePort";
-        PollingConsumer pollingConsumer = getConsumer(uri);
         Exchange exchange = pollingConsumer.receive();
 
         if (exchange.getProperty(Exchange.EXCEPTION_CAUGHT) != null) {
@@ -155,13 +155,13 @@ public class CamelRoleProvisioningManager extends AbstractCamelProvisioningManag
     @Override
     @SuppressWarnings("unchecked")
     public List<PropagationStatus> deprovision(final Long roleKey, Collection<String> resources) {
+        PollingConsumer pollingConsumer = getConsumer("direct:deprovisionRolePort");
+
         Map<String, Object> props = new HashMap<>();
         props.put("resources", resources);
 
         sendMessage("direct:deprovisionRole", roleKey, props);
 
-        String uri = "direct:deprovisionRolePort";
-        PollingConsumer pollingConsumer = getConsumer(uri);
         Exchange exchange = pollingConsumer.receive();
 
         if (exchange.getProperty(Exchange.EXCEPTION_CAUGHT) != null) {

http://git-wip-us.apache.org/repos/asf/syncope/blob/42f78fee/syncope620/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/server/provisioning/camel/CamelUserProvisioningManager.java
----------------------------------------------------------------------
diff --git a/syncope620/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/server/provisioning/camel/CamelUserProvisioningManager.java b/syncope620/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/server/provisioning/camel/CamelUserProvisioningManager.java
index 1ed83fd..2c5afc5 100644
--- a/syncope620/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/server/provisioning/camel/CamelUserProvisioningManager.java
+++ b/syncope620/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/server/provisioning/camel/CamelUserProvisioningManager.java
@@ -59,6 +59,8 @@ public class CamelUserProvisioningManager extends AbstractCamelProvisioningManag
     public Map.Entry<Long, List<PropagationStatus>> create(final UserTO userTO, final boolean storePassword,
             boolean disablePwdPolicyCheck, Boolean enabled, Set<String> excludedResources) {
 
+        PollingConsumer pollingConsumer = getConsumer("direct:createPort");
+
         Map<String, Object> props = new HashMap<>();
         props.put("storePassword", storePassword);
         props.put("disablePwdPolicyCheck", disablePwdPolicyCheck);
@@ -67,8 +69,6 @@ public class CamelUserProvisioningManager extends AbstractCamelProvisioningManag
 
         sendMessage("direct:createUser", userTO, props);
 
-        String uri = "direct:createPort";
-        PollingConsumer pollingConsumer = getConsumer(uri);
         Exchange exchange = pollingConsumer.receive();
 
         if (exchange.getProperty(Exchange.EXCEPTION_CAUGHT) != null) {
@@ -86,13 +86,13 @@ public class CamelUserProvisioningManager extends AbstractCamelProvisioningManag
     @Override
     @SuppressWarnings("unchecked")
     public Map.Entry<Long, List<PropagationStatus>> update(UserMod userMod, boolean removeMemberships) {
+        PollingConsumer pollingConsumer = getConsumer("direct:updatePort");
+
         Map<String, Object> props = new HashMap<>();
         props.put("removeMemberships", removeMemberships);
 
         sendMessage("direct:updateUser", userMod, props);
 
-        String uri = "direct:updatePort";
-        PollingConsumer pollingConsumer = getConsumer(uri);
         Exchange exchange = pollingConsumer.receive();
 
         if (exchange.getProperty(Exchange.EXCEPTION_CAUGHT) != null) {
@@ -110,13 +110,13 @@ public class CamelUserProvisioningManager extends AbstractCamelProvisioningManag
     @Override
     @SuppressWarnings("unchecked")
     public List<PropagationStatus> delete(final Long userKey, final Set<String> excludedResources) {
+        PollingConsumer pollingConsumer = getConsumer("direct:deletePort");
+
         Map<String, Object> props = new HashMap<>();
         props.put("excludedResources", excludedResources);
 
         sendMessage("direct:deleteUser", userKey, props);
 
-        String uri = "direct:deletePort";
-        PollingConsumer pollingConsumer = getConsumer(uri);
         Exchange exchange = pollingConsumer.receive();
 
         if (exchange.getProperty(Exchange.EXCEPTION_CAUGHT) != null) {
@@ -128,10 +128,10 @@ public class CamelUserProvisioningManager extends AbstractCamelProvisioningManag
 
     @Override
     public Long unlink(final UserMod userMod) {
+        PollingConsumer pollingConsumer = getConsumer("direct:unlinkPort");
+
         sendMessage("direct:unlinkUser", userMod);
 
-        String uri = "direct:unlinkPort";
-        PollingConsumer pollingConsumer = getConsumer(uri);
         Exchange exchange = pollingConsumer.receive();
 
         if (exchange.getProperty(Exchange.EXCEPTION_CAUGHT) != null) {
@@ -145,6 +145,8 @@ public class CamelUserProvisioningManager extends AbstractCamelProvisioningManag
     @Override
     @SuppressWarnings("unchecked")
     public Map.Entry<Long, List<PropagationStatus>> activate(final User user, final StatusMod statusMod) {
+        PollingConsumer pollingConsumer = getConsumer("direct:statusPort");
+
         Map<String, Object> props = new HashMap<>();
         props.put("token", statusMod.getToken());
         props.put("user", user);
@@ -155,11 +157,9 @@ public class CamelUserProvisioningManager extends AbstractCamelProvisioningManag
         } else {
             WorkflowResult<Long> updated =
                     new WorkflowResult<>(user.getKey(), null, statusMod.getType().name().toLowerCase());
-            sendMessage("direct:statusUser", updated, props);
+            sendMessage("direct:userStatusPropagation", updated, props);
         }
 
-        String uri = "direct:statusPort";
-        PollingConsumer pollingConsumer = getConsumer(uri);
         Exchange exchange = pollingConsumer.receive();
 
         if (exchange.getProperty(Exchange.EXCEPTION_CAUGHT) != null) {
@@ -172,6 +172,8 @@ public class CamelUserProvisioningManager extends AbstractCamelProvisioningManag
     @Override
     @SuppressWarnings("unchecked")
     public Map.Entry<Long, List<PropagationStatus>> reactivate(final User user, final StatusMod statusMod) {
+        PollingConsumer pollingConsumer = getConsumer("direct:statusPort");
+
         Map<String, Object> props = new HashMap<>();
         props.put("user", user);
         props.put("statusMod", statusMod);
@@ -181,11 +183,9 @@ public class CamelUserProvisioningManager extends AbstractCamelProvisioningManag
         } else {
             WorkflowResult<Long> updated =
                     new WorkflowResult<>(user.getKey(), null, statusMod.getType().name().toLowerCase());
-            sendMessage("direct:statusUser", updated, props);
+            sendMessage("direct:userStatusPropagation", updated, props);
         }
 
-        String uri = "direct:statusPort";
-        PollingConsumer pollingConsumer = getConsumer(uri);
         Exchange exchange = pollingConsumer.receive();
 
         if (exchange.getProperty(Exchange.EXCEPTION_CAUGHT) != null) {
@@ -198,6 +198,8 @@ public class CamelUserProvisioningManager extends AbstractCamelProvisioningManag
     @Override
     @SuppressWarnings("unchecked")
     public Map.Entry<Long, List<PropagationStatus>> suspend(final User user, final StatusMod statusMod) {
+        PollingConsumer pollingConsumer = getConsumer("direct:statusPort");
+
         Map<String, Object> props = new HashMap<>();
         props.put("user", user);
         props.put("statusMod", statusMod);
@@ -207,11 +209,9 @@ public class CamelUserProvisioningManager extends AbstractCamelProvisioningManag
         } else {
             WorkflowResult<Long> updated =
                     new WorkflowResult<>(user.getKey(), null, statusMod.getType().name().toLowerCase());
-            sendMessage("direct:statusUser", updated, props);
+            sendMessage("direct:userStatusPropagation", updated, props);
         }
 
-        String uri = "direct:statusPort";
-        PollingConsumer pollingConsumer = getConsumer(uri);
         Exchange exchange = pollingConsumer.receive();
 
         if (exchange.getProperty(Exchange.EXCEPTION_CAUGHT) != null) {
@@ -223,10 +223,10 @@ public class CamelUserProvisioningManager extends AbstractCamelProvisioningManag
 
     @Override
     public Long link(final UserMod subjectMod) {
+        PollingConsumer pollingConsumer = getConsumer("direct:linkPort");
+
         sendMessage("direct:linkUser", subjectMod);
 
-        String uri = "direct:linkPort";
-        PollingConsumer pollingConsumer = getConsumer(uri);
         Exchange exchange = pollingConsumer.receive();
 
         if (exchange.getProperty(Exchange.EXCEPTION_CAUGHT) != null) {
@@ -240,13 +240,13 @@ public class CamelUserProvisioningManager extends AbstractCamelProvisioningManag
     @Override
     @SuppressWarnings("unchecked")
     public List<PropagationStatus> deprovision(final Long user, final Collection<String> resources) {
+        PollingConsumer pollingConsumer = getConsumer("direct:deprovisionPort");
+
         Map<String, Object> props = new HashMap<>();
         props.put("resources", resources);
 
         sendMessage("direct:deprovisionUser", user, props);
 
-        String uri = "direct:deprovisionPort";
-        PollingConsumer pollingConsumer = getConsumer(uri);
         Exchange exchange = pollingConsumer.receive();
 
         if (exchange.getProperty(Exchange.EXCEPTION_CAUGHT) != null) {
@@ -259,24 +259,24 @@ public class CamelUserProvisioningManager extends AbstractCamelProvisioningManag
     @Override
     @SuppressWarnings("unchecked")
     public Map.Entry<Long, List<PropagationStatus>> update(
-            final UserMod userMod, Long id, final ProvisioningResult result,
+            final UserMod userMod, final Long key, final ProvisioningResult result,
             final Boolean enabled, final Set<String> excludedResources) {
 
+        PollingConsumer pollingConsumer = getConsumer("direct:updateInSyncPort");
+
         Map<String, Object> props = new HashMap<>();
-        props.put("id", id);
+        props.put("key", key);
         props.put("result", result);
         props.put("enabled", enabled);
         props.put("excludedResources", excludedResources);
 
-        sendMessage("direct:updateSyncUser", userMod, props);
+        sendMessage("direct:updateUserInSync", userMod, props);
 
-        String uri = "direct:updateSyncPort";
-        PollingConsumer pollingConsumer = getConsumer(uri);
         Exchange exchange = pollingConsumer.receive();
 
         Exception e;
         if ((e = (Exception) exchange.getProperty(Exchange.EXCEPTION_CAUGHT)) != null) {
-            LOG.error("Update of user {} failed, trying to sync its status anyway (if configured)", id, e);
+            LOG.error("Update of user {} failed, trying to sync its status anyway (if configured)", key, e);
 
             result.setStatus(ProvisioningResult.Status.FAILURE);
             result.setMessage("Update failed, trying to sync status anyway (if configured)\n" + e.getMessage());
@@ -284,7 +284,7 @@ public class CamelUserProvisioningManager extends AbstractCamelProvisioningManag
             WorkflowResult<Map.Entry<UserMod, Boolean>> updated = new WorkflowResult<Map.Entry<UserMod, Boolean>>(
                     new AbstractMap.SimpleEntry<>(userMod, false), new PropagationByResource(),
                     new HashSet<String>());
-            sendMessage("direct:syncUserStatus", updated, props);
+            sendMessage("direct:userInSync", updated, props);
             exchange = pollingConsumer.receive();
         }
 
@@ -292,14 +292,14 @@ public class CamelUserProvisioningManager extends AbstractCamelProvisioningManag
     }
 
     @Override
-    public void innerSuspend(final User user, final boolean suspend) {
+    public void innerSuspend(final User user, final boolean propagate) {
+        PollingConsumer pollingConsumer = getConsumer("direct:innerSuspendUserPort");
+
         Map<String, Object> props = new HashMap<>();
-        props.put("suspend", suspend);
+        props.put("propagate", propagate);
 
-        sendMessage("direct:suspendUserWF", user, props);
+        sendMessage("direct:innerSuspendUser", user, props);
 
-        String uri = "direct:suspendWFPort";
-        PollingConsumer pollingConsumer = getConsumer(uri);
         Exchange exchange = pollingConsumer.receive();
 
         if (exchange.getProperty(Exchange.EXCEPTION_CAUGHT) != null) {
@@ -309,10 +309,10 @@ public class CamelUserProvisioningManager extends AbstractCamelProvisioningManag
 
     @Override
     public void requestPasswordReset(final Long userKey) {
+        PollingConsumer pollingConsumer = getConsumer("direct:requestPwdResetPort");
+
         sendMessage("direct:requestPwdReset", userKey);
 
-        String uri = "direct:requestPwdResetPort";
-        PollingConsumer pollingConsumer = getConsumer(uri);
         Exchange exchange = pollingConsumer.receive();
 
         if (exchange.getProperty(Exchange.EXCEPTION_CAUGHT) != null) {
@@ -322,16 +322,16 @@ public class CamelUserProvisioningManager extends AbstractCamelProvisioningManag
 
     @Override
     public void confirmPasswordReset(final User user, final String token, final String password) {
+        PollingConsumer pollingConsumer = getConsumer("direct:confirmPwdResetPort");
+
         Map<String, Object> props = new HashMap<>();
         props.put("user", user);
-        props.put("userId", user.getKey());
+        props.put("userKey", user.getKey());
         props.put("token", token);
         props.put("password", password);
 
         sendMessage("direct:confirmPwdReset", user, props);
 
-        String uri = "direct:confirmPwdResetPort";
-        PollingConsumer pollingConsumer = getConsumer(uri);
         Exchange exchange = pollingConsumer.receive();
 
         if (exchange.getProperty(Exchange.EXCEPTION_CAUGHT) != null) {

http://git-wip-us.apache.org/repos/asf/syncope/blob/42f78fee/syncope620/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/server/provisioning/camel/SyncopeCamelContext.java
----------------------------------------------------------------------
diff --git a/syncope620/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/server/provisioning/camel/SyncopeCamelContext.java b/syncope620/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/server/provisioning/camel/SyncopeCamelContext.java
index 2a7de7b..02c82cb 100644
--- a/syncope620/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/server/provisioning/camel/SyncopeCamelContext.java
+++ b/syncope620/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/server/provisioning/camel/SyncopeCamelContext.java
@@ -18,9 +18,7 @@
  */
 package org.apache.syncope.server.provisioning.camel;
 
-import java.io.ByteArrayInputStream;
 import java.io.InputStream;
-import java.net.URLDecoder;
 import java.util.ArrayList;
 import java.util.Collections;
 import java.util.List;
@@ -30,7 +28,6 @@ import org.apache.camel.model.Constants;
 import org.apache.camel.model.RouteDefinition;
 import org.apache.camel.spring.SpringCamelContext;
 import org.apache.commons.io.IOUtils;
-import org.apache.syncope.common.lib.SyncopeConstants;
 import org.apache.syncope.server.misc.spring.ApplicationContextProvider;
 import org.apache.syncope.server.persistence.api.dao.CamelRouteDAO;
 import org.apache.syncope.server.persistence.api.entity.CamelRoute;
@@ -64,7 +61,7 @@ public class SyncopeCamelContext {
         if (camelContext.getRouteDefinitions().isEmpty()) {
             List<CamelRoute> routes = routeDAO.findAll();
             LOG.debug("{} route(s) are going to be loaded ", routes.size());
-            loadContext(routeDAO, routes);
+            loadContext(routes);
             try {
                 camelContext.start();
             } catch (Exception e) {
@@ -75,7 +72,7 @@ public class SyncopeCamelContext {
         return camelContext;
     }
 
-    public void loadContext(final CamelRouteDAO routeDAO, final List<CamelRoute> routes) {
+    private void loadContext(final List<CamelRoute> routes) {
         try {
             DOMImplementationRegistry reg = DOMImplementationRegistry.newInstance();
             DOMImplementationLS domImpl = (DOMImplementationLS) reg.getDOMImplementation("LS");
@@ -87,12 +84,11 @@ public class SyncopeCamelContext {
             for (CamelRoute route : routes) {
                 InputStream input = null;
                 try {
-                    input = new ByteArrayInputStream(
-                            URLDecoder.decode(route.getContent(), SyncopeConstants.DEFAULT_ENCODING).getBytes());
+                    input = IOUtils.toInputStream(route.getContent());
                     LSInput lsinput = domImpl.createLSInput();
                     lsinput.setByteStream(input);
 
-                    Node routeElement = parser.parse(lsinput).getElementsByTagName("route").item(0);
+                    Node routeElement = parser.parse(lsinput).getDocumentElement();
                     routeDefs.add(unmarshaller.unmarshal(routeElement, RouteDefinition.class).getValue());
                 } finally {
                     IOUtils.closeQuietly(input);
@@ -104,15 +100,24 @@ public class SyncopeCamelContext {
         }
     }
 
-    public void reloadContext(final String routeKey) {
+    public void updateContext(final String routeKey) {
         if (camelContext == null) {
             getContext();
         } else {
             if (!camelContext.getRouteDefinitions().isEmpty()) {
                 camelContext.getRouteDefinitions().remove(camelContext.getRouteDefinition(routeKey));
-                loadContext(routeDAO, Collections.singletonList(routeDAO.find(routeKey)));
+                loadContext(Collections.singletonList(routeDAO.find(routeKey)));
             }
         }
     }
 
+    public void restartContext() {
+        try {
+            camelContext.stop();
+            camelContext.start();
+        } catch (Exception e) {
+            LOG.error("While restarting Camel context", e);
+        }
+    }
+
 }

http://git-wip-us.apache.org/repos/asf/syncope/blob/42f78fee/syncope620/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/server/provisioning/camel/processor/RoleCreateInSyncProcessor.java
----------------------------------------------------------------------
diff --git a/syncope620/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/server/provisioning/camel/processor/RoleCreateInSyncProcessor.java b/syncope620/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/server/provisioning/camel/processor/RoleCreateInSyncProcessor.java
new file mode 100644
index 0000000..aaced42
--- /dev/null
+++ b/syncope620/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/server/provisioning/camel/processor/RoleCreateInSyncProcessor.java
@@ -0,0 +1,72 @@
+package org.apache.syncope.server.provisioning.camel.processor;
+
+/*
+ * 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.
+ */
+import java.util.AbstractMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import org.apache.camel.Exchange;
+import org.apache.camel.Processor;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.apache.commons.lang3.StringUtils;
+import org.apache.syncope.common.lib.to.AttrTO;
+import org.apache.syncope.common.lib.to.RoleTO;
+import org.apache.syncope.server.misc.security.AuthContextUtil;
+import org.apache.syncope.server.persistence.api.RoleEntitlementUtil;
+import org.apache.syncope.server.persistence.api.entity.task.PropagationTask;
+import org.apache.syncope.server.provisioning.api.WorkflowResult;
+import org.apache.syncope.server.provisioning.api.propagation.PropagationManager;
+import org.apache.syncope.server.provisioning.api.propagation.PropagationTaskExecutor;
+import org.springframework.stereotype.Component;
+
+@Component
+public class RoleCreateInSyncProcessor implements Processor {
+
+    @Autowired
+    protected PropagationManager propagationManager;
+
+    @Autowired
+    protected PropagationTaskExecutor taskExecutor;
+
+    @Override
+    @SuppressWarnings("unchecked")
+    public void process(final Exchange exchange) {
+        WorkflowResult<Long> created = (WorkflowResult) exchange.getIn().getBody();
+
+        RoleTO actual = exchange.getProperty("subject", RoleTO.class);
+        Map<Long, String> roleOwnerMap = exchange.getProperty("roleOwnerMap", Map.class);
+        Set<String> excludedResource = exchange.getProperty("excludedResources", Set.class);
+
+        AttrTO roleOwner = actual.getPlainAttrMap().get(StringUtils.EMPTY);
+        if (roleOwner != null) {
+            roleOwnerMap.put(created.getResult(), roleOwner.getValues().iterator().next());
+        }
+
+        AuthContextUtil.extendAuthContext(
+                created.getResult(), RoleEntitlementUtil.getEntitlementNameFromRoleKey(created.getResult()));
+
+        List<PropagationTask> tasks = propagationManager.getRoleCreateTaskIds(
+                created, actual.getVirAttrs(), excludedResource);
+
+        taskExecutor.execute(tasks);
+
+        exchange.getOut().setBody(new AbstractMap.SimpleEntry<>(created.getResult(), null));
+    }
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/42f78fee/syncope620/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/server/provisioning/camel/processor/RoleCreateProcessor.java
----------------------------------------------------------------------
diff --git a/syncope620/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/server/provisioning/camel/processor/RoleCreateProcessor.java b/syncope620/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/server/provisioning/camel/processor/RoleCreateProcessor.java
new file mode 100644
index 0000000..d2219ba
--- /dev/null
+++ b/syncope620/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/server/provisioning/camel/processor/RoleCreateProcessor.java
@@ -0,0 +1,77 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.syncope.server.provisioning.camel.processor;
+
+import java.util.AbstractMap;
+import java.util.List;
+import java.util.Set;
+import org.apache.camel.Exchange;
+import org.apache.camel.Processor;
+import org.apache.syncope.common.lib.to.RoleTO;
+import org.apache.syncope.server.misc.security.AuthContextUtil;
+import org.apache.syncope.server.misc.spring.ApplicationContextProvider;
+import org.apache.syncope.server.persistence.api.RoleEntitlementUtil;
+import org.apache.syncope.server.persistence.api.entity.task.PropagationTask;
+import org.apache.syncope.server.provisioning.api.WorkflowResult;
+import org.apache.syncope.server.provisioning.api.propagation.PropagationException;
+import org.apache.syncope.server.provisioning.api.propagation.PropagationManager;
+import org.apache.syncope.server.provisioning.api.propagation.PropagationReporter;
+import org.apache.syncope.server.provisioning.api.propagation.PropagationTaskExecutor;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+
+@Component
+public class RoleCreateProcessor implements Processor {
+
+    private static final Logger LOG = LoggerFactory.getLogger(RoleCreateProcessor.class);
+
+    @Autowired
+    protected PropagationManager propagationManager;
+
+    @Autowired
+    protected PropagationTaskExecutor taskExecutor;
+
+    @SuppressWarnings("unchecked")
+    @Override
+    public void process(final Exchange exchange) {
+        WorkflowResult<Long> created = (WorkflowResult) exchange.getIn().getBody();
+        RoleTO subject = exchange.getProperty("subject", RoleTO.class);
+        Set<String> excludedResource = exchange.getProperty("excludedResources", Set.class);
+
+        AuthContextUtil.extendAuthContext(
+                created.getResult(), RoleEntitlementUtil.getEntitlementNameFromRoleKey(created.getResult()));
+
+        List<PropagationTask> tasks =
+                propagationManager.getRoleCreateTaskIds(created, subject.getVirAttrs(), excludedResource);
+        PropagationReporter propagationReporter =
+                ApplicationContextProvider.getApplicationContext().getBean(PropagationReporter.class);
+        try {
+            taskExecutor.execute(tasks, propagationReporter);
+        } catch (PropagationException e) {
+            LOG.error("Error propagation primary resource", e);
+            propagationReporter.onPrimaryResourceFailure(tasks);
+        }
+
+        exchange.getOut().setBody(new AbstractMap.SimpleEntry<>(
+                created.getResult(), propagationReporter.getStatuses()));
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/42f78fee/syncope620/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/server/provisioning/camel/processor/RoleDeleteProcessor.java
----------------------------------------------------------------------
diff --git a/syncope620/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/server/provisioning/camel/processor/RoleDeleteProcessor.java b/syncope620/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/server/provisioning/camel/processor/RoleDeleteProcessor.java
new file mode 100644
index 0000000..7c6e816
--- /dev/null
+++ b/syncope620/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/server/provisioning/camel/processor/RoleDeleteProcessor.java
@@ -0,0 +1,105 @@
+/*
+ * 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.server.provisioning.camel.processor;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+import java.util.Map;
+import org.apache.camel.Exchange;
+import org.apache.camel.Processor;
+import org.apache.syncope.common.lib.types.PropagationByResource;
+import org.apache.syncope.server.misc.spring.ApplicationContextProvider;
+import org.apache.syncope.server.persistence.api.dao.RoleDAO;
+import org.apache.syncope.server.persistence.api.entity.role.Role;
+import org.apache.syncope.server.persistence.api.entity.task.PropagationTask;
+import org.apache.syncope.server.provisioning.api.WorkflowResult;
+import org.apache.syncope.server.provisioning.api.propagation.PropagationException;
+import org.apache.syncope.server.provisioning.api.propagation.PropagationManager;
+import org.apache.syncope.server.provisioning.api.propagation.PropagationReporter;
+import org.apache.syncope.server.provisioning.api.propagation.PropagationTaskExecutor;
+import org.apache.syncope.server.workflow.api.RoleWorkflowAdapter;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+
+@Component
+public class RoleDeleteProcessor implements Processor {
+
+    private static final Logger LOG = LoggerFactory.getLogger(RoleDeleteProcessor.class);
+
+    @Autowired
+    protected RoleWorkflowAdapter rwfAdapter;
+
+    @Autowired
+    protected PropagationManager propagationManager;
+
+    @Autowired
+    protected PropagationTaskExecutor taskExecutor;
+
+    @Autowired
+    protected RoleDAO roleDAO;
+
+    @Override
+    public void process(final Exchange exchange) throws Exception {
+        final List<Role> toBeDeprovisioned = new ArrayList<>();
+
+        Long subjectKey = exchange.getIn().getBody(Long.class);
+        final Role syncopeRole = roleDAO.find(subjectKey);
+
+        if (syncopeRole != null) {
+            toBeDeprovisioned.add(syncopeRole);
+
+            final List<Role> descendants = roleDAO.findDescendants(toBeDeprovisioned.get(0));
+            if (descendants != null) {
+                toBeDeprovisioned.addAll(descendants);
+            }
+        }
+
+        final List<PropagationTask> tasks = new ArrayList<>();
+
+        for (Role role : toBeDeprovisioned) {
+            // Generate propagation tasks for deleting users from role resources, if they are on those resources only
+            // because of the reason being deleted (see SYNCOPE-357)
+            for (Map.Entry<Long, PropagationByResource> entry : roleDAO.findUsersWithIndirectResources(role.
+                    getKey()).entrySet()) {
+
+                WorkflowResult<Long> wfResult =
+                        new WorkflowResult<>(entry.getKey(), entry.getValue(), Collections.<String>emptySet());
+                tasks.addAll(propagationManager.getUserDeleteTaskIds(wfResult));
+            }
+
+            // Generate propagation tasks for deleting this role from resources
+            tasks.addAll(propagationManager.getRoleDeleteTaskIds(role.getKey()));
+        }
+
+        PropagationReporter propagationReporter =
+                ApplicationContextProvider.getApplicationContext().getBean(PropagationReporter.class);
+        try {
+            taskExecutor.execute(tasks, propagationReporter);
+        } catch (PropagationException e) {
+            LOG.error("Error propagation primary resource", e);
+            propagationReporter.onPrimaryResourceFailure(tasks);
+        }
+
+        exchange.setProperty("statuses", propagationReporter.getStatuses());
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/42f78fee/syncope620/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/server/provisioning/camel/processor/RoleDeprovisionProcessor.java
----------------------------------------------------------------------
diff --git a/syncope620/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/server/provisioning/camel/processor/RoleDeprovisionProcessor.java b/syncope620/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/server/provisioning/camel/processor/RoleDeprovisionProcessor.java
new file mode 100644
index 0000000..4753cd8
--- /dev/null
+++ b/syncope620/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/server/provisioning/camel/processor/RoleDeprovisionProcessor.java
@@ -0,0 +1,78 @@
+/*
+ * 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.server.provisioning.camel.processor;
+
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+import org.apache.camel.Exchange;
+import org.apache.camel.Processor;
+import org.apache.syncope.server.misc.spring.ApplicationContextProvider;
+import org.apache.syncope.server.persistence.api.dao.RoleDAO;
+import org.apache.syncope.server.persistence.api.entity.role.Role;
+import org.apache.syncope.server.persistence.api.entity.task.PropagationTask;
+import org.apache.syncope.server.provisioning.api.propagation.PropagationException;
+import org.apache.syncope.server.provisioning.api.propagation.PropagationManager;
+import org.apache.syncope.server.provisioning.api.propagation.PropagationReporter;
+import org.apache.syncope.server.provisioning.api.propagation.PropagationTaskExecutor;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+
+@Component
+public class RoleDeprovisionProcessor implements Processor {
+
+    private static final Logger LOG = LoggerFactory.getLogger(UserDeprovisionProcessor.class);
+
+    @Autowired
+    protected PropagationManager propagationManager;
+
+    @Autowired
+    protected PropagationTaskExecutor taskExecutor;
+
+    @Autowired
+    protected RoleDAO roleDAO;
+
+    @SuppressWarnings("unchecked")
+    @Override
+    public void process(final Exchange exchange) {
+        Long roleKey = exchange.getIn().getBody(Long.class);
+        List<String> resources = exchange.getProperty("resources", List.class);
+
+        Role role = roleDAO.authFetch(roleKey);
+
+        Set<String> noPropResourceName = role.getResourceNames();
+        noPropResourceName.removeAll(resources);
+
+        List<PropagationTask> tasks =
+                propagationManager.getRoleDeleteTaskIds(roleKey, new HashSet<>(resources), noPropResourceName);
+        PropagationReporter propagationReporter =
+                ApplicationContextProvider.getApplicationContext().getBean(PropagationReporter.class);
+        try {
+            taskExecutor.execute(tasks, propagationReporter);
+        } catch (PropagationException e) {
+            LOG.error("Error propagation primary resource", e);
+            propagationReporter.onPrimaryResourceFailure(tasks);
+        }
+
+        exchange.getOut().setBody(propagationReporter.getStatuses());
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/42f78fee/syncope620/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/server/provisioning/camel/processor/RoleUpdateProcessor.java
----------------------------------------------------------------------
diff --git a/syncope620/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/server/provisioning/camel/processor/RoleUpdateProcessor.java b/syncope620/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/server/provisioning/camel/processor/RoleUpdateProcessor.java
new file mode 100644
index 0000000..e91be21
--- /dev/null
+++ b/syncope620/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/server/provisioning/camel/processor/RoleUpdateProcessor.java
@@ -0,0 +1,71 @@
+/*
+ * 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.server.provisioning.camel.processor;
+
+import java.util.AbstractMap;
+import java.util.List;
+import java.util.Set;
+import org.apache.camel.Exchange;
+import org.apache.camel.Processor;
+import org.apache.syncope.common.lib.mod.RoleMod;
+import org.apache.syncope.server.misc.spring.ApplicationContextProvider;
+import org.apache.syncope.server.persistence.api.entity.task.PropagationTask;
+import org.apache.syncope.server.provisioning.api.WorkflowResult;
+import org.apache.syncope.server.provisioning.api.propagation.PropagationException;
+import org.apache.syncope.server.provisioning.api.propagation.PropagationManager;
+import org.apache.syncope.server.provisioning.api.propagation.PropagationReporter;
+import org.apache.syncope.server.provisioning.api.propagation.PropagationTaskExecutor;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+
+@Component
+public class RoleUpdateProcessor implements Processor {
+
+    private static final Logger LOG = LoggerFactory.getLogger(UserUpdateProcessor.class);
+
+    @Autowired
+    protected PropagationManager propagationManager;
+
+    @Autowired
+    protected PropagationTaskExecutor taskExecutor;
+
+    @SuppressWarnings("unchecked")
+    @Override
+    public void process(final Exchange exchange) {
+        WorkflowResult<Long> updated = (WorkflowResult) exchange.getIn().getBody();
+        RoleMod subjectMod = exchange.getProperty("subjectMod", RoleMod.class);
+        Set<String> excludedResource = exchange.getProperty("excludedResources", Set.class);
+
+        List<PropagationTask> tasks = propagationManager.getRoleUpdateTaskIds(updated,
+                subjectMod.getVirAttrsToRemove(), subjectMod.getVirAttrsToUpdate(), excludedResource);
+        PropagationReporter propagationReporter =
+                ApplicationContextProvider.getApplicationContext().getBean(PropagationReporter.class);
+        try {
+            taskExecutor.execute(tasks, propagationReporter);
+        } catch (PropagationException e) {
+            LOG.error("Error propagation primary resource", e);
+            propagationReporter.onPrimaryResourceFailure(tasks);
+        }
+
+        exchange.getOut().setBody(new AbstractMap.SimpleEntry<>(updated.getResult(), propagationReporter.getStatuses()));
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/42f78fee/syncope620/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/server/provisioning/camel/processor/UserConfirmPwdResetProcessor.java
----------------------------------------------------------------------
diff --git a/syncope620/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/server/provisioning/camel/processor/UserConfirmPwdResetProcessor.java b/syncope620/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/server/provisioning/camel/processor/UserConfirmPwdResetProcessor.java
new file mode 100644
index 0000000..3fb5ced
--- /dev/null
+++ b/syncope620/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/server/provisioning/camel/processor/UserConfirmPwdResetProcessor.java
@@ -0,0 +1,61 @@
+/*
+ * 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.server.provisioning.camel.processor;
+
+import java.util.List;
+import org.apache.camel.Exchange;
+import org.apache.camel.Processor;
+import org.apache.syncope.server.misc.spring.ApplicationContextProvider;
+import org.apache.syncope.server.persistence.api.entity.task.PropagationTask;
+import org.apache.syncope.server.persistence.api.entity.user.User;
+import org.apache.syncope.server.provisioning.api.propagation.PropagationException;
+import org.apache.syncope.server.provisioning.api.propagation.PropagationManager;
+import org.apache.syncope.server.provisioning.api.propagation.PropagationReporter;
+import org.apache.syncope.server.provisioning.api.propagation.PropagationTaskExecutor;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+
+@Component
+public class UserConfirmPwdResetProcessor implements Processor {
+
+    private static final Logger LOG = LoggerFactory.getLogger(UserConfirmPwdResetProcessor.class);
+
+    @Autowired
+    protected PropagationManager propagationManager;
+
+    @Autowired
+    protected PropagationTaskExecutor taskExecutor;
+
+    @Override
+    public void process(final Exchange exchange) {
+        User user = exchange.getProperty("user", User.class);
+
+        List<PropagationTask> tasks = propagationManager.getUserUpdateTaskIds(user, null, null);
+        PropagationReporter propReporter =
+                ApplicationContextProvider.getApplicationContext().getBean(PropagationReporter.class);
+        try {
+            taskExecutor.execute(tasks, propReporter);
+        } catch (PropagationException e) {
+            LOG.error("Error propagation primary resource", e);
+            propReporter.onPrimaryResourceFailure(tasks);
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/42f78fee/syncope620/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/server/provisioning/camel/processor/UserCreateProcessor.java
----------------------------------------------------------------------
diff --git a/syncope620/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/server/provisioning/camel/processor/UserCreateProcessor.java b/syncope620/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/server/provisioning/camel/processor/UserCreateProcessor.java
new file mode 100644
index 0000000..bcca679
--- /dev/null
+++ b/syncope620/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/server/provisioning/camel/processor/UserCreateProcessor.java
@@ -0,0 +1,76 @@
+/*
+ * 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.server.provisioning.camel.processor;
+
+import java.util.AbstractMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import org.apache.camel.Exchange;
+import org.apache.camel.Processor;
+import org.apache.syncope.common.lib.to.UserTO;
+import org.apache.syncope.server.misc.spring.ApplicationContextProvider;
+import org.apache.syncope.server.persistence.api.entity.task.PropagationTask;
+import org.apache.syncope.server.provisioning.api.WorkflowResult;
+import org.apache.syncope.server.provisioning.api.propagation.PropagationException;
+import org.apache.syncope.server.provisioning.api.propagation.PropagationManager;
+import org.apache.syncope.server.provisioning.api.propagation.PropagationReporter;
+import org.apache.syncope.server.provisioning.api.propagation.PropagationTaskExecutor;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+
+@Component
+public class UserCreateProcessor implements Processor {
+
+    private static final Logger LOG = LoggerFactory.getLogger(UserCreateProcessor.class);
+
+    @Autowired
+    protected PropagationManager propagationManager;
+
+    @Autowired
+    protected PropagationTaskExecutor taskExecutor;
+
+    @SuppressWarnings("unchecked")
+    @Override
+    public void process(final Exchange exchange) {
+        if ((exchange.getIn().getBody() instanceof WorkflowResult)) {
+
+            WorkflowResult<Map.Entry<Long, Boolean>> created = (WorkflowResult) exchange.getIn().getBody();
+            UserTO actual = exchange.getProperty("actual", UserTO.class);
+            Set<String> excludedResource = exchange.getProperty("excludedResources", Set.class);
+
+            List<PropagationTask> tasks = propagationManager.getUserCreateTaskIds(
+                    created, actual.getPassword(), actual.getVirAttrs(), excludedResource, actual.getMemberships());
+            PropagationReporter propagationReporter =
+                    ApplicationContextProvider.getApplicationContext().getBean(PropagationReporter.class);
+            try {
+                taskExecutor.execute(tasks, propagationReporter);
+            } catch (PropagationException e) {
+                LOG.error("Error propagation primary resource {}", e);
+                propagationReporter.onPrimaryResourceFailure(tasks);
+            }
+
+            exchange.getOut().setBody(
+                    new AbstractMap.SimpleEntry<>(created.getResult().getKey(), propagationReporter.getStatuses()));
+        }
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/42f78fee/syncope620/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/server/provisioning/camel/processor/UserDeleteProcessor.java
----------------------------------------------------------------------
diff --git a/syncope620/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/server/provisioning/camel/processor/UserDeleteProcessor.java b/syncope620/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/server/provisioning/camel/processor/UserDeleteProcessor.java
new file mode 100644
index 0000000..b9795ad
--- /dev/null
+++ b/syncope620/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/server/provisioning/camel/processor/UserDeleteProcessor.java
@@ -0,0 +1,72 @@
+/*
+ * 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.server.provisioning.camel.processor;
+
+import java.util.List;
+import java.util.Set;
+import org.apache.camel.Exchange;
+import org.apache.camel.Processor;
+import org.apache.syncope.server.misc.spring.ApplicationContextProvider;
+import org.apache.syncope.server.persistence.api.entity.task.PropagationTask;
+import org.apache.syncope.server.provisioning.api.propagation.PropagationException;
+import org.apache.syncope.server.provisioning.api.propagation.PropagationManager;
+import org.apache.syncope.server.provisioning.api.propagation.PropagationReporter;
+import org.apache.syncope.server.provisioning.api.propagation.PropagationTaskExecutor;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+
+@Component
+public class UserDeleteProcessor implements Processor {
+
+    private static final Logger LOG = LoggerFactory.getLogger(UserDeleteProcessor.class);
+
+    @Autowired
+    protected PropagationManager propagationManager;
+
+    @Autowired
+    protected PropagationTaskExecutor taskExecutor;
+
+    @SuppressWarnings("unchecked")
+    @Override
+    public void process(final Exchange exchange) throws Exception {
+        Long userKey = (Long) exchange.getIn().getBody();
+        Set<String> excludedResource = exchange.getProperty("excludedResources", Set.class);
+
+        // Note here that we can only notify about "delete", not any other
+        // task defined in workflow process definition: this because this
+        // information could only be available after uwfAdapter.delete(), which
+        // will also effectively remove user from db, thus making virtually
+        // impossible by NotificationManager to fetch required user information
+        List<PropagationTask> tasks = propagationManager.getUserDeleteTaskIds(userKey, excludedResource);
+
+        PropagationReporter propagationReporter =
+                ApplicationContextProvider.getApplicationContext().getBean(PropagationReporter.class);
+        try {
+            taskExecutor.execute(tasks, propagationReporter);
+        } catch (PropagationException e) {
+            LOG.error("Error propagation primary resource", e);
+            propagationReporter.onPrimaryResourceFailure(tasks);
+        }
+
+        exchange.setProperty("statuses", propagationReporter.getStatuses());
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/42f78fee/syncope620/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/server/provisioning/camel/processor/UserDeprovisionProcessor.java
----------------------------------------------------------------------
diff --git a/syncope620/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/server/provisioning/camel/processor/UserDeprovisionProcessor.java b/syncope620/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/server/provisioning/camel/processor/UserDeprovisionProcessor.java
new file mode 100644
index 0000000..042c287
--- /dev/null
+++ b/syncope620/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/server/provisioning/camel/processor/UserDeprovisionProcessor.java
@@ -0,0 +1,78 @@
+/*
+ * 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.server.provisioning.camel.processor;
+
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+import org.apache.camel.Exchange;
+import org.apache.camel.Processor;
+import org.apache.syncope.server.misc.spring.ApplicationContextProvider;
+import org.apache.syncope.server.persistence.api.dao.UserDAO;
+import org.apache.syncope.server.persistence.api.entity.task.PropagationTask;
+import org.apache.syncope.server.persistence.api.entity.user.User;
+import org.apache.syncope.server.provisioning.api.propagation.PropagationException;
+import org.apache.syncope.server.provisioning.api.propagation.PropagationManager;
+import org.apache.syncope.server.provisioning.api.propagation.PropagationReporter;
+import org.apache.syncope.server.provisioning.api.propagation.PropagationTaskExecutor;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+
+@Component
+public class UserDeprovisionProcessor implements Processor {
+
+    private static final Logger LOG = LoggerFactory.getLogger(UserDeprovisionProcessor.class);
+
+    @Autowired
+    protected PropagationManager propagationManager;
+
+    @Autowired
+    protected PropagationTaskExecutor taskExecutor;
+
+    @Autowired
+    protected UserDAO userDAO;
+
+    @Override
+    public void process(final Exchange exchange) {
+        Long userKey = exchange.getIn().getBody(Long.class);
+        @SuppressWarnings("unchecked")
+        List<String> resources = exchange.getProperty("resources", List.class);
+
+        final User user = userDAO.authFetch(userKey);
+
+        final Set<String> noPropResourceName = user.getResourceNames();
+        noPropResourceName.removeAll(resources);
+
+        final List<PropagationTask> tasks =
+                propagationManager.getUserDeleteTaskIds(userKey, new HashSet<>(resources), noPropResourceName);
+        final PropagationReporter propagationReporter =
+                ApplicationContextProvider.getApplicationContext().getBean(PropagationReporter.class);
+        try {
+            taskExecutor.execute(tasks, propagationReporter);
+        } catch (PropagationException e) {
+            LOG.error("Error propagation primary resource", e);
+            propagationReporter.onPrimaryResourceFailure(tasks);
+        }
+
+        exchange.getOut().setBody(propagationReporter.getStatuses());
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/42f78fee/syncope620/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/server/provisioning/camel/processor/UserInnerSuspendProcessor.java
----------------------------------------------------------------------
diff --git a/syncope620/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/server/provisioning/camel/processor/UserInnerSuspendProcessor.java b/syncope620/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/server/provisioning/camel/processor/UserInnerSuspendProcessor.java
new file mode 100644
index 0000000..69760f8
--- /dev/null
+++ b/syncope620/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/server/provisioning/camel/processor/UserInnerSuspendProcessor.java
@@ -0,0 +1,61 @@
+/*
+ * 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.server.provisioning.camel.processor;
+
+import java.util.AbstractMap.SimpleEntry;
+import java.util.List;
+import java.util.Map;
+import org.apache.camel.Exchange;
+import org.apache.camel.Processor;
+import org.apache.syncope.common.lib.mod.UserMod;
+import org.apache.syncope.server.persistence.api.entity.task.PropagationTask;
+import org.apache.syncope.server.provisioning.api.WorkflowResult;
+import org.apache.syncope.server.provisioning.api.propagation.PropagationManager;
+import org.apache.syncope.server.provisioning.api.propagation.PropagationTaskExecutor;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+
+@Component
+public class UserInnerSuspendProcessor implements Processor {
+
+    @Autowired
+    protected PropagationManager propagationManager;
+
+    @Autowired
+    protected PropagationTaskExecutor taskExecutor;
+
+    @SuppressWarnings("unchecked")
+    @Override
+    public void process(final Exchange exchange) {
+        WorkflowResult<Long> updated = (WorkflowResult) exchange.getIn().getBody();
+        Boolean propagate = exchange.getProperty("propagate", Boolean.class);
+
+        if (propagate) {
+            UserMod userMod = new UserMod();
+            userMod.setKey(updated.getResult());
+
+            final List<PropagationTask> tasks = propagationManager.getUserUpdateTaskIds(
+                    new WorkflowResult<Map.Entry<UserMod, Boolean>>(
+                            new SimpleEntry<>(userMod, Boolean.FALSE),
+                            updated.getPropByRes(), updated.getPerformedTasks()));
+            taskExecutor.execute(tasks);
+        }
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/42f78fee/syncope620/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/server/provisioning/camel/processor/UserSetStatusInSyncProcessor.java
----------------------------------------------------------------------
diff --git a/syncope620/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/server/provisioning/camel/processor/UserSetStatusInSyncProcessor.java b/syncope620/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/server/provisioning/camel/processor/UserSetStatusInSyncProcessor.java
new file mode 100644
index 0000000..11d0ff6
--- /dev/null
+++ b/syncope620/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/server/provisioning/camel/processor/UserSetStatusInSyncProcessor.java
@@ -0,0 +1,74 @@
+/*
+ * 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.server.provisioning.camel.processor;
+
+import java.util.Map;
+import org.apache.camel.Processor;
+import org.apache.camel.Exchange;
+import org.apache.syncope.common.lib.mod.UserMod;
+import org.apache.syncope.server.persistence.api.dao.UserDAO;
+import org.apache.syncope.server.persistence.api.entity.user.User;
+import org.apache.syncope.server.provisioning.api.WorkflowResult;
+import org.apache.syncope.server.workflow.api.UserWorkflowAdapter;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+
+@Component
+public class UserSetStatusInSyncProcessor implements Processor {
+
+    private static final Logger LOG = LoggerFactory.getLogger(UserSetStatusInSyncProcessor.class);
+
+    @Autowired
+    protected UserDAO userDAO;
+
+    @Autowired
+    protected UserWorkflowAdapter uwfAdapter;
+
+    @SuppressWarnings("unchecked")
+    @Override
+    public void process(final Exchange exchange) {
+        WorkflowResult<Map.Entry<UserMod, Boolean>> updated = (WorkflowResult) exchange.getIn().getBody();
+
+        Boolean enabled = exchange.getProperty("enabled", Boolean.class);
+        Long key = exchange.getProperty("key", Long.class);
+
+        if (enabled != null) {
+            User user = userDAO.find(key);
+
+            WorkflowResult<Long> enableUpdate = null;
+            if (user.isSuspended() == null) {
+                enableUpdate = uwfAdapter.activate(key, null);
+            } else if (enabled && user.isSuspended()) {
+                enableUpdate = uwfAdapter.reactivate(key);
+            } else if (!enabled && !user.isSuspended()) {
+                enableUpdate = uwfAdapter.suspend(key);
+            }
+
+            if (enableUpdate != null) {
+                if (enableUpdate.getPropByRes() != null) {
+                    updated.getPropByRes().merge(enableUpdate.getPropByRes());
+                    updated.getPropByRes().purge();
+                }
+                updated.getPerformedTasks().addAll(enableUpdate.getPerformedTasks());
+            }
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/42f78fee/syncope620/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/server/provisioning/camel/processor/UserStatusPropagationProcessor.java
----------------------------------------------------------------------
diff --git a/syncope620/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/server/provisioning/camel/processor/UserStatusPropagationProcessor.java b/syncope620/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/server/provisioning/camel/processor/UserStatusPropagationProcessor.java
new file mode 100644
index 0000000..eb1452f
--- /dev/null
+++ b/syncope620/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/server/provisioning/camel/processor/UserStatusPropagationProcessor.java
@@ -0,0 +1,76 @@
+/*
+ * 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.server.provisioning.camel.processor;
+
+import java.util.AbstractMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+import org.apache.camel.Exchange;
+import org.apache.camel.Processor;
+import org.apache.syncope.common.lib.mod.StatusMod;
+import org.apache.syncope.server.misc.spring.ApplicationContextProvider;
+import org.apache.syncope.server.persistence.api.entity.task.PropagationTask;
+import org.apache.syncope.server.persistence.api.entity.user.User;
+import org.apache.syncope.server.provisioning.api.WorkflowResult;
+import org.apache.syncope.server.provisioning.api.propagation.PropagationException;
+import org.apache.syncope.server.provisioning.api.propagation.PropagationManager;
+import org.apache.syncope.server.provisioning.api.propagation.PropagationReporter;
+import org.apache.syncope.server.provisioning.api.propagation.PropagationTaskExecutor;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+
+@Component
+public class UserStatusPropagationProcessor implements Processor {
+
+    private static final Logger LOG = LoggerFactory.getLogger(UserStatusPropagationProcessor.class);
+
+    @Autowired
+    protected PropagationManager propagationManager;
+
+    @Autowired
+    protected PropagationTaskExecutor taskExecutor;
+
+    @SuppressWarnings("unchecked")
+    @Override
+    public void process(final Exchange exchange) {
+        WorkflowResult<Long> updated = (WorkflowResult) exchange.getIn().getBody();
+
+        User user = exchange.getProperty("user", User.class);
+        StatusMod statusMod = exchange.getProperty("statusMod", StatusMod.class);
+
+        Set<String> resourcesToBeExcluded = new HashSet<>(user.getResourceNames());
+        resourcesToBeExcluded.removeAll(statusMod.getResourceNames());
+
+        List<PropagationTask> tasks = propagationManager.getUserUpdateTaskIds(
+                user, statusMod.getType() != StatusMod.ModType.SUSPEND, resourcesToBeExcluded);
+        PropagationReporter propReporter =
+                ApplicationContextProvider.getApplicationContext().getBean(PropagationReporter.class);
+        try {
+            taskExecutor.execute(tasks, propReporter);
+        } catch (PropagationException e) {
+            LOG.error("Error propagation primary resource", e);
+            propReporter.onPrimaryResourceFailure(tasks);
+        }
+
+        exchange.getOut().setBody(new AbstractMap.SimpleEntry<>(updated.getResult(), propReporter.getStatuses()));
+    }
+}