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/01/05 14:34:07 UTC

[02/53] [abbrv] syncope git commit: Initial running version, in order to fix #1

http://git-wip-us.apache.org/repos/asf/syncope/blob/5b3b124a/core/src/main/java/org/apache/syncope/core/provisioning/camel/processors/DefaultUserStatusPropagation.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/syncope/core/provisioning/camel/processors/DefaultUserStatusPropagation.java b/core/src/main/java/org/apache/syncope/core/provisioning/camel/processors/DefaultUserStatusPropagation.java
new file mode 100644
index 0000000..2cf1e6f
--- /dev/null
+++ b/core/src/main/java/org/apache/syncope/core/provisioning/camel/processors/DefaultUserStatusPropagation.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.core.provisioning.camel.processors;
+
+import java.util.AbstractMap;
+import java.util.HashSet;
+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.mod.StatusMod;
+import org.apache.syncope.common.to.PropagationStatus;
+import org.apache.syncope.core.persistence.beans.PropagationTask;
+import org.apache.syncope.core.persistence.beans.user.SyncopeUser;
+import org.apache.syncope.core.propagation.PropagationException;
+import org.apache.syncope.core.propagation.PropagationReporter;
+import org.apache.syncope.core.propagation.PropagationTaskExecutor;
+import org.apache.syncope.core.propagation.impl.PropagationManager;
+import org.apache.syncope.core.util.ApplicationContextProvider;
+import org.apache.syncope.core.workflow.WorkflowResult;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+
+public class DefaultUserStatusPropagation implements Processor{
+    
+    private static final Logger LOG = LoggerFactory.getLogger(DefaultUserStatusPropagation.class);
+    @Autowired
+    protected PropagationManager propagationManager;
+    @Autowired
+    protected PropagationTaskExecutor taskExecutor;
+    
+    @Override
+    public void process(Exchange exchange){
+        
+        WorkflowResult<Long> updated = (WorkflowResult) exchange.getIn().getBody();
+        
+        SyncopeUser user = exchange.getProperty("user", SyncopeUser.class);
+        StatusMod statusMod = exchange.getProperty("statusMod", StatusMod.class);
+        
+        Set<String> resourcesToBeExcluded = new HashSet<String>(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);
+        }
+        
+        Map.Entry<Long, List<PropagationStatus>> result = new AbstractMap.SimpleEntry<Long, List<PropagationStatus>>(updated.getResult(), propReporter.getStatuses());
+        exchange.getOut().setBody(result); 
+    }    
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/5b3b124a/core/src/main/java/org/apache/syncope/core/provisioning/camel/processors/DefaultUserUpdateInSyncPropagation.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/syncope/core/provisioning/camel/processors/DefaultUserUpdateInSyncPropagation.java b/core/src/main/java/org/apache/syncope/core/provisioning/camel/processors/DefaultUserUpdateInSyncPropagation.java
new file mode 100644
index 0000000..6fdec75
--- /dev/null
+++ b/core/src/main/java/org/apache/syncope/core/provisioning/camel/processors/DefaultUserUpdateInSyncPropagation.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.core.provisioning.camel.processors;
+
+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.mod.UserMod;
+import org.apache.syncope.common.to.PropagationStatus;
+import org.apache.syncope.core.persistence.beans.PropagationTask;
+import org.apache.syncope.core.persistence.dao.UserDAO;
+import org.apache.syncope.core.propagation.PropagationException;
+import org.apache.syncope.core.propagation.PropagationReporter;
+import org.apache.syncope.core.propagation.PropagationTaskExecutor;
+import org.apache.syncope.core.propagation.impl.PropagationManager;
+import org.apache.syncope.core.rest.data.UserDataBinder;
+import org.apache.syncope.core.util.ApplicationContextProvider;
+import org.apache.syncope.core.workflow.WorkflowResult;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+
+public class DefaultUserUpdateInSyncPropagation implements Processor{
+
+    private static final Logger LOG = LoggerFactory.getLogger(DefaultUserUpdateInSyncPropagation.class);
+    
+    @Autowired
+    protected PropagationManager propagationManager;
+    @Autowired
+    protected PropagationTaskExecutor taskExecutor;
+    @Autowired
+    protected UserDataBinder binder;
+    @Autowired
+    protected UserDAO userDAO;
+    
+    @Override
+    public void process(Exchange exchange){
+                 
+            WorkflowResult<Map.Entry<UserMod, Boolean>> updated = (WorkflowResult) exchange.getIn().getBody();            
+
+            Set<String> excludedResource = exchange.getProperty("excludedResources", Set.class);            
+                              
+            PropagationReporter propagationReporter = ApplicationContextProvider.getApplicationContext().
+                    getBean(PropagationReporter.class);
+
+            List<PropagationTask> tasks = propagationManager.getUserUpdateTaskIds(updated,updated.getResult().getKey().getPassword() != null,excludedResource);
+                
+            try {
+                    taskExecutor.execute(tasks, propagationReporter);
+            } catch (PropagationException e) {
+                    LOG.error("Error propagation primary resource", e);
+                    propagationReporter.onPrimaryResourceFailure(tasks);
+            }
+            
+            Map.Entry<Long, List<PropagationStatus>> result = new AbstractMap.SimpleEntry<Long, List<PropagationStatus>>(updated.getResult().getKey().getId(), propagationReporter.getStatuses());
+            exchange.getOut().setBody(result);            
+    }
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/5b3b124a/core/src/main/java/org/apache/syncope/core/provisioning/camel/processors/DefaultUserUpdatePropagation.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/syncope/core/provisioning/camel/processors/DefaultUserUpdatePropagation.java b/core/src/main/java/org/apache/syncope/core/provisioning/camel/processors/DefaultUserUpdatePropagation.java
new file mode 100644
index 0000000..880912e
--- /dev/null
+++ b/core/src/main/java/org/apache/syncope/core/provisioning/camel/processors/DefaultUserUpdatePropagation.java
@@ -0,0 +1,120 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.syncope.core.provisioning.camel.processors;
+
+import java.util.AbstractMap;
+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.mod.AttributeMod;
+import org.apache.syncope.common.mod.MembershipMod;
+import org.apache.syncope.common.mod.UserMod;
+import org.apache.syncope.common.to.PropagationStatus;
+import org.apache.syncope.common.to.UserTO;
+import org.apache.syncope.core.persistence.beans.PropagationTask;
+import org.apache.syncope.core.propagation.PropagationByResource;
+import org.apache.syncope.core.propagation.PropagationException;
+import org.apache.syncope.core.propagation.PropagationReporter;
+import org.apache.syncope.core.propagation.PropagationTaskExecutor;
+import org.apache.syncope.core.propagation.impl.PropagationManager;
+import org.apache.syncope.core.rest.data.UserDataBinder;
+import org.apache.syncope.core.util.ApplicationContextProvider;
+import org.apache.syncope.core.workflow.WorkflowResult;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+
+public class DefaultUserUpdatePropagation implements Processor{
+
+    private static final Logger LOG = LoggerFactory.getLogger(DefaultUserUpdatePropagation.class);
+    
+    @Autowired
+    protected PropagationManager propagationManager;
+    @Autowired
+    protected PropagationTaskExecutor taskExecutor;
+    @Autowired
+    protected UserDataBinder binder;
+    
+    @Override
+    public void process(Exchange exchange){
+                 
+            WorkflowResult<Map.Entry<UserMod, Boolean>> updated = (WorkflowResult) exchange.getIn().getBody();            
+            UserMod actual = exchange.getProperty("actual", UserMod.class);
+            boolean removeMemberships = exchange.getProperty("removeMemberships", boolean.class);
+            
+            // SYNCOPE-501: check if there are memberships to be removed with virtual attributes assigned
+            /*for (Long membershipId : actual.getMembershipsToRemove()) {
+                if (!binder.fillMembershipVirtual(
+                        null,
+                        null,
+                        membershipId,
+                        Collections.<String>emptySet(),
+                        Collections.<AttributeMod>emptySet(),
+                        true).isEmpty()) {
+
+                    removeMemberships = true;
+                }
+            }*/
+            
+            List<PropagationTask> tasks = propagationManager.getUserUpdateTaskIds(updated);
+            if (tasks.isEmpty()) {
+                // SYNCOPE-459: take care of user virtual attributes ...
+                final PropagationByResource propByResVirAttr = binder.fillVirtual(
+                        updated.getResult().getKey().getId(),
+                        actual.getVirAttrsToRemove(),
+                        actual.getVirAttrsToUpdate());
+                // SYNCOPE-501: update only virtual attributes (if any of them changed), password propagation is
+                // not required, take care also of membership virtual attributes
+                boolean addOrUpdateMemberships = false;
+                for (MembershipMod membershipMod : actual.getMembershipsToAdd()) {
+                    if (!binder.fillMembershipVirtual(
+                            updated.getResult().getKey().getId(),
+                            membershipMod.getRole(),
+                            null,
+                            membershipMod.getVirAttrsToRemove(),
+                            membershipMod.getVirAttrsToUpdate(),
+                            false).isEmpty()) {
+
+                        addOrUpdateMemberships = true;
+                    }
+                }
+                tasks.addAll(!propByResVirAttr.isEmpty() || addOrUpdateMemberships || removeMemberships
+                        ? propagationManager.getUserUpdateTaskIds(updated, false, null)
+                        : Collections.<PropagationTask>emptyList());
+            }
+
+            PropagationReporter propagationReporter = ApplicationContextProvider.getApplicationContext().
+                    getBean(PropagationReporter.class);
+
+            if (!tasks.isEmpty()) {
+                try {
+                    taskExecutor.execute(tasks, propagationReporter);
+                } catch (PropagationException e) {
+                    LOG.error("Error propagation primary resource", e);
+                    propagationReporter.onPrimaryResourceFailure(tasks);
+                }
+            }
+            
+            Map.Entry<Long, List<PropagationStatus>> result = new AbstractMap.SimpleEntry<Long, List<PropagationStatus>>(updated.getResult().getKey().getId(), propagationReporter.getStatuses());
+            exchange.getOut().setBody(result);            
+    }
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/5b3b124a/core/src/main/java/org/apache/syncope/core/provisioning/camel/processors/DefaultUserWFSuspendPropagation.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/syncope/core/provisioning/camel/processors/DefaultUserWFSuspendPropagation.java b/core/src/main/java/org/apache/syncope/core/provisioning/camel/processors/DefaultUserWFSuspendPropagation.java
new file mode 100644
index 0000000..2d08b93
--- /dev/null
+++ b/core/src/main/java/org/apache/syncope/core/provisioning/camel/processors/DefaultUserWFSuspendPropagation.java
@@ -0,0 +1,64 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.syncope.core.provisioning.camel.processors;
+
+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.mod.UserMod;
+import org.apache.syncope.core.persistence.beans.PropagationTask;
+import org.apache.syncope.core.propagation.PropagationTaskExecutor;
+import org.apache.syncope.core.propagation.impl.PropagationManager;
+import org.apache.syncope.core.workflow.WorkflowResult;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+
+public class DefaultUserWFSuspendPropagation implements Processor{
+
+    private static final Logger LOG = LoggerFactory.getLogger(DefaultUserWFSuspendPropagation.class);
+    
+    @Autowired
+    protected PropagationManager propagationManager;
+    @Autowired
+    protected PropagationTaskExecutor taskExecutor;
+    
+    @Override
+    public void process(Exchange exchange){
+                 
+        WorkflowResult<Long> updated = (WorkflowResult) exchange.getIn().getBody();            
+        Boolean suspend = exchange.getProperty("suspend", Boolean.class);
+
+        if (suspend) {
+            UserMod userMod = new UserMod();
+            userMod.setId(updated.getResult());
+
+            final List<PropagationTask> tasks = propagationManager.getUserUpdateTaskIds(
+                    new WorkflowResult<Map.Entry<UserMod, Boolean>>(
+                            new SimpleEntry<UserMod, Boolean>(userMod, Boolean.FALSE),
+                            updated.getPropByRes(), updated.getPerformedTasks()));
+
+            taskExecutor.execute(tasks);
+        }
+    }
+    
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/5b3b124a/core/src/main/java/org/apache/syncope/core/provisioning/camel/processors/UserStatusOnSync.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/syncope/core/provisioning/camel/processors/UserStatusOnSync.java b/core/src/main/java/org/apache/syncope/core/provisioning/camel/processors/UserStatusOnSync.java
new file mode 100644
index 0000000..7e4c18e
--- /dev/null
+++ b/core/src/main/java/org/apache/syncope/core/provisioning/camel/processors/UserStatusOnSync.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.core.provisioning.camel.processors;
+
+import java.util.Map;
+import org.apache.camel.Processor;
+import org.apache.camel.Exchange;
+import org.apache.syncope.common.mod.UserMod;
+import org.apache.syncope.core.persistence.beans.user.SyncopeUser;
+import org.apache.syncope.core.persistence.dao.UserDAO;
+import org.apache.syncope.core.workflow.WorkflowResult;
+import org.apache.syncope.core.workflow.user.UserWorkflowAdapter;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+
+public class UserStatusOnSync implements Processor{
+    
+    private static final Logger LOG = LoggerFactory.getLogger(UserStatusOnSync.class);
+    
+    @Autowired
+    protected UserDAO userDAO;
+    @Autowired
+    protected UserWorkflowAdapter uwfAdapter;
+    
+    @Override
+    public void process(Exchange exchange){
+        
+        WorkflowResult<Map.Entry<UserMod, Boolean>> updated = (WorkflowResult) exchange.getIn().getBody();                    
+          
+        Boolean enabled = exchange.getProperty("enabled", Boolean.class);
+        Long id = exchange.getProperty("id", Long.class);
+                
+        if (enabled != null) {
+             SyncopeUser user = userDAO.find(id);
+
+             WorkflowResult<Long> enableUpdate = null;
+             if (user.isSuspended() == null) {
+                 enableUpdate = uwfAdapter.activate(id, null);
+             } else if (enabled && user.isSuspended()) {
+                 enableUpdate = uwfAdapter.reactivate(id);
+             } else if (!enabled && !user.isSuspended()) {
+                 enableUpdate = uwfAdapter.suspend(id);
+             }
+
+             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/5b3b124a/core/src/main/java/org/apache/syncope/core/provisioning/provisioning/ProvisioningManager.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/syncope/core/provisioning/provisioning/ProvisioningManager.java b/core/src/main/java/org/apache/syncope/core/provisioning/provisioning/ProvisioningManager.java
new file mode 100644
index 0000000..adc1cb0
--- /dev/null
+++ b/core/src/main/java/org/apache/syncope/core/provisioning/provisioning/ProvisioningManager.java
@@ -0,0 +1,42 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.syncope.core.provisioning;
+
+import java.util.Collection;
+import java.util.List;
+import java.util.Map;
+import org.apache.syncope.common.mod.AbstractAttributableMod;
+import org.apache.syncope.common.to.AbstractAttributableTO;
+import org.apache.syncope.common.to.PropagationStatus;
+
+public interface ProvisioningManager<T extends AbstractAttributableTO, M extends AbstractAttributableMod>{
+
+    public Map.Entry<Long, List<PropagationStatus>> create(T subject);
+
+    public Map.Entry<Long, List<PropagationStatus>> update(M subjectMod);
+
+    public List<PropagationStatus> delete(Long subjectId);
+
+    public Long unlink(M subjectMod);
+
+    public Long link(M subjectMod);
+
+    public List<PropagationStatus> deprovision(Long user, Collection<String> resources);
+
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/5b3b124a/core/src/main/java/org/apache/syncope/core/rest/controller/RoleController.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/syncope/core/rest/controller/RoleController.java b/core/src/main/java/org/apache/syncope/core/rest/controller/RoleController.java
index 22001e5..f7a2981 100644
--- a/core/src/main/java/org/apache/syncope/core/rest/controller/RoleController.java
+++ b/core/src/main/java/org/apache/syncope/core/rest/controller/RoleController.java
@@ -26,6 +26,7 @@ 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 javax.annotation.Resource;
 import org.apache.commons.lang3.ArrayUtils;
@@ -34,6 +35,9 @@ import org.apache.syncope.core.persistence.dao.search.SearchCond;
 import org.apache.syncope.common.to.RoleTO;
 import org.apache.syncope.common.types.ClientExceptionType;
 import org.apache.syncope.common.SyncopeClientException;
+import org.apache.syncope.common.to.PropagationStatus;
+import org.apache.syncope.core.provisioning.ProvisioningManager;
+import org.apache.syncope.core.provisioning.RoleProvisioningManager;
 import org.apache.syncope.common.reqres.BulkAction;
 import org.apache.syncope.common.reqres.BulkActionResult;
 import org.apache.syncope.common.types.SubjectType;
@@ -53,8 +57,6 @@ import org.apache.syncope.core.rest.data.AttributableTransformer;
 import org.apache.syncope.core.rest.data.RoleDataBinder;
 import org.apache.syncope.core.util.ApplicationContextProvider;
 import org.apache.syncope.core.util.EntitlementUtil;
-import org.apache.syncope.core.workflow.WorkflowResult;
-import org.apache.syncope.core.workflow.role.RoleWorkflowAdapter;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.security.access.prepost.PreAuthorize;
 import org.springframework.stereotype.Component;
@@ -83,9 +85,6 @@ public class RoleController extends AbstractSubjectController<RoleTO, RoleMod> {
     protected RoleDataBinder binder;
 
     @Autowired
-    protected RoleWorkflowAdapter rwfAdapter;
-
-    @Autowired
     protected PropagationManager propagationManager;
 
     @Autowired
@@ -96,6 +95,9 @@ public class RoleController extends AbstractSubjectController<RoleTO, RoleMod> {
 
     @Resource(name = "anonymousUser")
     private String anonymousUser;
+    
+    @Resource(name = "defaultRoleProvisioningManager")
+    protected RoleProvisioningManager provisioningManager;
 
     @PreAuthorize("hasAnyRole('ROLE_READ', T(org.apache.syncope.common.SyncopeConstants).ANONYMOUS_ENTITLEMENT)")
     @Transactional(readOnly = true)
@@ -240,22 +242,9 @@ public class RoleController extends AbstractSubjectController<RoleTO, RoleMod> {
         /*
          * Actual operations: workflow, propagation
          */
-        WorkflowResult<Long> created = rwfAdapter.create(actual);
-
-        EntitlementUtil.extendAuthContext(created.getResult());
-
-        List<PropagationTask> tasks = propagationManager.getRoleCreateTaskIds(created, actual.getVirAttrs());
-        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);
-        }
-
-        final RoleTO savedTO = binder.getRoleTO(created.getResult());
-        savedTO.getPropagationStatusTOs().addAll(propagationReporter.getStatuses());
+        Map.Entry<Long, List<PropagationStatus>> created = provisioningManager.create(roleTO);
+        final RoleTO savedTO = binder.getRoleTO(created.getKey());
+        savedTO.getPropagationStatusTOs().addAll(created.getValue());
         return savedTO;
     }
 
@@ -269,23 +258,10 @@ public class RoleController extends AbstractSubjectController<RoleTO, RoleMod> {
         RoleMod actual = attrTransformer.transform(roleMod);
         LOG.debug("Transformed: {}", actual);
 
-        /*
-         * Actual operations: workflow, propagation
-         */
-        WorkflowResult<Long> updated = rwfAdapter.update(actual);
-
-        List<PropagationTask> tasks = propagationManager.getRoleUpdateTaskIds(updated,
-                actual.getVirAttrsToRemove(), actual.getVirAttrsToUpdate());
-        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);
-        }
-        final RoleTO updatedTO = binder.getRoleTO(updated.getResult());
-        updatedTO.getPropagationStatusTOs().addAll(propagationReporter.getStatuses());
+        Map.Entry<Long, List<PropagationStatus>> updated = provisioningManager.update(roleMod);
+        
+        final RoleTO updatedTO = binder.getRoleTO(updated.getKey());
+        updatedTO.getPropagationStatusTOs().addAll(updated.getValue());
         return updatedTO;
     }
 
@@ -304,45 +280,12 @@ public class RoleController extends AbstractSubjectController<RoleTO, RoleMod> {
             throw sce;
         }
 
-        final List<SyncopeRole> toBeDeprovisioned = new ArrayList<SyncopeRole>();
-
-        final SyncopeRole syncopeRole = roleDAO.find(roleId);
-
-        if (syncopeRole != null) {
-            final List<SyncopeRole> descendants = roleDAO.findDescendants(syncopeRole);
-            if (descendants != null) {
-                // among descendants there is also parent role syncopeRole (to delete)
-                toBeDeprovisioned.addAll(descendants);
-            }
-        }
-
-        final List<PropagationTask> tasks = new ArrayList<PropagationTask>();
-
-        for (SyncopeRole 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 (WorkflowResult<Long> wfResult : binder.getUsersOnResourcesOnlyBecauseOfRole(role.getId())) {
-                tasks.addAll(propagationManager.getUserDeleteTaskIds(wfResult));
-            }
-
-            // Generate propagation tasks for deleting this role from resources
-            tasks.addAll(propagationManager.getRoleDeleteTaskIds(role.getId()));
-        }
-
+        List<PropagationStatus> statuses = provisioningManager.delete(roleId);
+        
         RoleTO roleTO = new RoleTO();
         roleTO.setId(roleId);
 
-        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);
-        }
-        roleTO.getPropagationStatusTOs().addAll(propagationReporter.getStatuses());
-
-        rwfAdapter.delete(roleId);
+        roleTO.getPropagationStatusTOs().addAll(statuses);
 
         return roleTO;
     }
@@ -374,7 +317,9 @@ public class RoleController extends AbstractSubjectController<RoleTO, RoleMod> {
         final RoleMod roleMod = new RoleMod();
         roleMod.setId(roleId);
         roleMod.getResourcesToRemove().addAll(resources);
-        return binder.getRoleTO(rwfAdapter.update(roleMod).getResult());
+        final Long updatedResult = provisioningManager.unlink(roleMod);
+ 
+        return binder.getRoleTO(updatedResult);
     }
 
     @PreAuthorize("hasRole('ROLE_UPDATE')")
@@ -384,7 +329,7 @@ public class RoleController extends AbstractSubjectController<RoleTO, RoleMod> {
         final RoleMod roleMod = new RoleMod();
         roleMod.setId(roleId);
         roleMod.getResourcesToAdd().addAll(resources);
-        return binder.getRoleTO(rwfAdapter.update(roleMod).getResult());
+        return binder.getRoleTO(provisioningManager.link(roleMod));
     }
 
     @PreAuthorize("hasRole('ROLE_UPDATE')")
@@ -414,22 +359,10 @@ public class RoleController extends AbstractSubjectController<RoleTO, RoleMod> {
     public RoleTO deprovision(final Long roleId, final Collection<String> resources) {
         final SyncopeRole role = binder.getRoleFromId(roleId);
 
-        final Set<String> noPropResourceName = role.getResourceNames();
-        noPropResourceName.removeAll(resources);
-
-        final List<PropagationTask> tasks =
-                propagationManager.getRoleDeleteTaskIds(roleId, new HashSet<String>(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);
-        }
+        List<PropagationStatus> statuses = provisioningManager.deprovision(roleId, resources);
 
         final RoleTO updatedTO = binder.getRoleTO(role);
-        updatedTO.getPropagationStatusTOs().addAll(propagationReporter.getStatuses());
+        updatedTO.getPropagationStatusTOs().addAll(statuses);
         return updatedTO;
     }
 

http://git-wip-us.apache.org/repos/asf/syncope/blob/5b3b124a/core/src/main/java/org/apache/syncope/core/rest/controller/RouteController.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/syncope/core/rest/controller/RouteController.java b/core/src/main/java/org/apache/syncope/core/rest/controller/RouteController.java
new file mode 100644
index 0000000..117d10f
--- /dev/null
+++ b/core/src/main/java/org/apache/syncope/core/rest/controller/RouteController.java
@@ -0,0 +1,92 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.syncope.core.rest.controller;
+
+import java.lang.reflect.Method;
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+import org.apache.syncope.common.to.RouteTO;
+import org.apache.syncope.core.persistence.beans.CamelRoute;
+import org.apache.syncope.core.persistence.dao.NotFoundException;
+import org.apache.syncope.core.persistence.dao.RouteDAO;
+import org.apache.syncope.core.provisioning.camel.SyncopeCamelContext;
+import org.apache.syncope.core.rest.data.RouteDataBinder;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.security.access.prepost.PreAuthorize;
+import org.springframework.stereotype.Component;
+import org.springframework.transaction.annotation.Transactional;
+
+@Component
+public class RouteController extends AbstractTransactionalController<RouteTO>{
+    
+    private static final org.slf4j.Logger LOG = LoggerFactory.getLogger(RouteDataBinder.class);
+    
+    @Autowired
+    private RouteDAO routeDao;
+    
+    @Autowired
+    private RouteDataBinder binder;
+    
+    @Autowired
+    private SyncopeCamelContext context;
+    
+    
+    @PreAuthorize("hasRole('ROUTE_LIST')")
+    @Transactional(readOnly = true)
+    public List<RouteTO> listRoutes(){
+        List<RouteTO> routes = new ArrayList<RouteTO>();
+        Iterator it = routeDao.findAll().iterator();
+        while(it.hasNext()){
+            routes.add(binder.getRouteTO((CamelRoute) it.next()));
+        }
+        return routes;
+    }
+    
+    @PreAuthorize("hasRole('ROUTE_READ')")
+    @Transactional(readOnly = true)
+    public RouteTO readRoute(Long id){
+        CamelRoute route = routeDao.find(id);
+        if (route==null) 
+            throw new NotFoundException("Route with id="+id);
+        
+        return binder.getRouteTO(route);
+    }
+    
+    @PreAuthorize("hasRole('ROUTE_UPDATE')")
+    public void updateRoute(RouteTO routeTO){
+
+        CamelRoute route = routeDao.find(routeTO.getId());
+        if (route==null) 
+            throw new NotFoundException("Route with id="+route.getId());
+        route.setRouteContent(routeTO.getRouteContent());
+        routeDao.save(route);       
+        LOG.info("UPDATING ROUTE WITH ID {} ", routeTO.getId());
+        LOG.info("NEW ROUTE CONTENT {} ", routeTO.getRouteContent());
+        context.reloadContext(routeDao, routeTO.getId());
+    }   
+    
+    @Override
+    protected RouteTO resolveReference(Method method, Object... args) throws UnresolvedReferenceException {
+        throw new UnresolvedReferenceException();
+    }
+    
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/5b3b124a/core/src/main/java/org/apache/syncope/core/rest/controller/UserController.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/syncope/core/rest/controller/UserController.java b/core/src/main/java/org/apache/syncope/core/rest/controller/UserController.java
index be426b7..d8fa5f8 100644
--- a/core/src/main/java/org/apache/syncope/core/rest/controller/UserController.java
+++ b/core/src/main/java/org/apache/syncope/core/rest/controller/UserController.java
@@ -18,15 +18,19 @@
  */
 package org.apache.syncope.core.rest.controller;
 
+import java.io.FileNotFoundException;
+import java.io.PrintStream;
 import java.lang.reflect.Method;
 import java.security.AccessControlException;
 import java.util.ArrayList;
 import java.util.Collection;
 import java.util.Collections;
 import java.util.HashSet;
+import java.util.Iterator;
 import java.util.List;
 import java.util.Map;
 import java.util.Set;
+import javax.annotation.Resource;
 import org.apache.syncope.common.mod.StatusMod;
 import org.apache.commons.lang3.ArrayUtils;
 import org.apache.syncope.common.mod.UserMod;
@@ -41,7 +45,10 @@ import org.apache.syncope.common.SyncopeClientException;
 import org.apache.syncope.common.mod.AttributeMod;
 import org.apache.syncope.common.mod.MembershipMod;
 import org.apache.syncope.common.types.SubjectType;
+import org.apache.syncope.common.to.PropagationStatus;
+import org.apache.syncope.core.persistence.beans.CamelRoute;
 import org.apache.syncope.core.persistence.beans.PropagationTask;
+import org.apache.syncope.core.provisioning.UserProvisioningManager;
 import org.apache.syncope.core.persistence.beans.role.SyncopeRole;
 import org.apache.syncope.core.persistence.beans.user.SyncopeUser;
 import org.apache.syncope.core.persistence.dao.SubjectSearchDAO;
@@ -55,6 +62,7 @@ import org.apache.syncope.core.propagation.PropagationException;
 import org.apache.syncope.core.propagation.PropagationReporter;
 import org.apache.syncope.core.propagation.PropagationTaskExecutor;
 import org.apache.syncope.core.propagation.impl.PropagationManager;
+import org.apache.syncope.core.provisioning.camel.CamelUserProvisioningManager;
 import org.apache.syncope.core.rest.data.AttributableTransformer;
 import org.apache.syncope.core.rest.data.UserDataBinder;
 import org.apache.syncope.core.util.ApplicationContextProvider;
@@ -92,9 +100,6 @@ public class UserController extends AbstractSubjectController<UserTO, UserMod> {
     protected UserDataBinder binder;
 
     @Autowired
-    protected UserWorkflowAdapter uwfAdapter;
-
-    @Autowired
     protected PropagationManager propagationManager;
 
     @Autowired
@@ -102,6 +107,12 @@ public class UserController extends AbstractSubjectController<UserTO, UserMod> {
 
     @Autowired
     protected AttributableTransformer attrTransformer;
+    
+    @Autowired
+    protected UserWorkflowAdapter uwfAdapter;
+    
+    @Resource(name = "defaultUserProvisioningManager")
+    protected UserProvisioningManager provisioningManager;
 
     @Transactional(readOnly = true)
     public boolean isSelfRegAllowed() {
@@ -215,24 +226,11 @@ public class UserController extends AbstractSubjectController<UserTO, UserMod> {
         UserTO actual = attrTransformer.transform(userTO);
         LOG.debug("Transformed: {}", actual);
 
-        /*
-         * Actual operations: workflow, propagation, notification
-         */
-        WorkflowResult<Map.Entry<Long, Boolean>> created = uwfAdapter.create(actual, storePassword);
-
-        List<PropagationTask> tasks = propagationManager.getUserCreateTaskIds(
-                created, actual.getPassword(), actual.getVirAttrs(), 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);
-        }
+        Map.Entry<Long, List<PropagationStatus>>
+                created = provisioningManager.create(actual,storePassword);
 
-        final UserTO savedTO = binder.getUserTO(created.getResult().getKey());
-        savedTO.getPropagationStatusTOs().addAll(propagationReporter.getStatuses());
+        final UserTO savedTO = binder.getUserTO(created.getKey());
+        savedTO.getPropagationStatusTOs().addAll(created.getValue());
         return savedTO;
     }
 
@@ -254,7 +252,8 @@ public class UserController extends AbstractSubjectController<UserTO, UserMod> {
         // AttributableMod transformation (if configured)
         UserMod actual = attrTransformer.transform(userMod);
         LOG.debug("Transformed: {}", actual);
-
+        
+        //CAMEL
         // SYNCOPE-501: check if there are memberships to be removed with virtual attributes assigned
         boolean removeMemberships = false;
         for (Long membershipId : actual.getMembershipsToRemove()) {
@@ -269,8 +268,9 @@ public class UserController extends AbstractSubjectController<UserTO, UserMod> {
                 removeMemberships = true;
             }
         }
+        
         //Actual operations: workflow, propagation, notification
-        WorkflowResult<Map.Entry<UserMod, Boolean>> updated = uwfAdapter.update(actual);
+        /*WorkflowResult<Map.Entry<UserMod, Boolean>> updated = uwfAdapter.update(actual);
 
         List<PropagationTask> tasks = propagationManager.getUserUpdateTaskIds(updated);
         if (tasks.isEmpty()) {
@@ -312,25 +312,29 @@ public class UserController extends AbstractSubjectController<UserTO, UserMod> {
         }
 
         final UserTO updatedTO = binder.getUserTO(updated.getResult().getKey().getId());
-        updatedTO.getPropagationStatusTOs().addAll(propagationReporter.getStatuses());
+        updatedTO.getPropagationStatusTOs().addAll(propagationReporter.getStatuses());*/
+        Map.Entry<Long, List<PropagationStatus>> updated = provisioningManager.update(actual,removeMemberships);
+
+        final UserTO updatedTO = binder.getUserTO(updated.getKey());
+        updatedTO.getPropagationStatusTOs().addAll(updated.getValue());
         return updatedTO;
     }
 
-    protected WorkflowResult<Long> setStatusOnWfAdapter(final SyncopeUser user, final StatusMod statusMod) {
-        WorkflowResult<Long> updated;
+     protected Map.Entry<Long, List<PropagationStatus>> setStatusOnWfAdapter(final SyncopeUser user, final StatusMod statusMod) {
+        Map.Entry<Long, List<PropagationStatus>> updated;
 
         switch (statusMod.getType()) {
             case SUSPEND:
-                updated = uwfAdapter.suspend(user.getId());
+                updated = provisioningManager.suspend(user, statusMod);
                 break;
 
             case REACTIVATE:
-                updated = uwfAdapter.reactivate(user.getId());
+                updated = provisioningManager.reactivate(user, statusMod);
                 break;
 
             case ACTIVATE:
             default:
-                updated = uwfAdapter.activate(user.getId(), statusMod.getToken());
+                updated = provisioningManager.activate(user, statusMod);
                 break;
 
         }
@@ -343,30 +347,10 @@ public class UserController extends AbstractSubjectController<UserTO, UserMod> {
     public UserTO status(final StatusMod statusMod) {
         SyncopeUser user = binder.getUserFromId(statusMod.getId());
 
-        WorkflowResult<Long> updated;
-        if (statusMod.isOnSyncope()) {
+        Map.Entry<Long, List<PropagationStatus>>
             updated = setStatusOnWfAdapter(user, statusMod);
-        } else {
-            updated = new WorkflowResult<Long>(user.getId(), null, statusMod.getType().name().toLowerCase());
-        }
-
-        // Resources to exclude from propagation
-        Set<String> resourcesToBeExcluded = new HashSet<String>(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);
-        }
-
-        final UserTO savedTO = binder.getUserTO(updated.getResult());
-        savedTO.getPropagationStatusTOs().addAll(propReporter.getStatuses());
+        final UserTO savedTO = binder.getUserTO(updated.getKey());
+        savedTO.getPropagationStatusTOs().addAll(updated.getValue());
         return savedTO;
     }
 
@@ -435,23 +419,7 @@ public class UserController extends AbstractSubjectController<UserTO, UserMod> {
             throw sce;
         }
 
-        // 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(userId);
-
-        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);
-        }
-
-        uwfAdapter.delete(userId);
+        List<PropagationStatus> statuses = provisioningManager.delete(userId);
 
         final UserTO deletedTO;
         SyncopeUser deleted = userDAO.find(userId);
@@ -461,7 +429,7 @@ public class UserController extends AbstractSubjectController<UserTO, UserMod> {
         } else {
             deletedTO = binder.getUserTO(userId);
         }
-        deletedTO.getPropagationStatusTOs().addAll(propagationReporter.getStatuses());
+        deletedTO.getPropagationStatusTOs().addAll(statuses);
 
         return deletedTO;
     }
@@ -526,7 +494,9 @@ public class UserController extends AbstractSubjectController<UserTO, UserMod> {
         final UserMod userMod = new UserMod();
         userMod.setId(userId);
         userMod.getResourcesToRemove().addAll(resources);
-        return binder.getUserTO(uwfAdapter.update(userMod).getResult().getKey().getId());
+        Long updatedId = provisioningManager.unlink(userMod);
+
+        return binder.getUserTO(updatedId);
     }
 
     @PreAuthorize("hasRole('USER_UPDATE')")
@@ -536,7 +506,7 @@ public class UserController extends AbstractSubjectController<UserTO, UserMod> {
         final UserMod userMod = new UserMod();
         userMod.setId(userId);
         userMod.getResourcesToAdd().addAll(resources);
-        return binder.getUserTO(uwfAdapter.update(userMod).getResult().getKey().getId());
+        return binder.getUserTO(provisioningManager.link(userMod));
     }
 
     @PreAuthorize("hasRole('USER_UPDATE')")
@@ -576,24 +546,12 @@ public class UserController extends AbstractSubjectController<UserTO, UserMod> {
     @Transactional(rollbackFor = { Throwable.class })
     @Override
     public UserTO deprovision(final Long userId, final Collection<String> resources) {
-        final SyncopeUser user = binder.getUserFromId(userId);
-
-        final Set<String> noPropResourceName = user.getResourceNames();
-        noPropResourceName.removeAll(resources);
-
-        final List<PropagationTask> tasks =
-                propagationManager.getUserDeleteTaskIds(userId, new HashSet<String>(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);
-        }
+        final SyncopeUser user = binder.getUserFromId(userId);        
+        
+        List<PropagationStatus> statuses = provisioningManager.deprovision(userId, resources);
 
         final UserTO updatedUserTO = binder.getUserTO(user);
-        updatedUserTO.getPropagationStatusTOs().addAll(propagationReporter.getStatuses());
+        updatedUserTO.getPropagationStatusTOs().addAll(statuses);
         return updatedUserTO;
     }
 
@@ -646,4 +604,18 @@ public class UserController extends AbstractSubjectController<UserTO, UserMod> {
 
         throw new UnresolvedReferenceException();
     }
+    
+    public PrintStream getDefinition() throws FileNotFoundException{
+        /*String result = "";
+        if(provisioningManager instanceof CamelUserProvisioningManager){
+            List l = ((CamelUserProvisioningManager)provisioningManager).getRoutes();
+            Iterator<CamelRoute> it = l.iterator();
+            
+            while(it.hasNext()){
+                result += it.next().getRouteContent();
+            }                        
+        }
+        return new PrintStream(result);*/
+        return null;
+    }
 }

http://git-wip-us.apache.org/repos/asf/syncope/blob/5b3b124a/core/src/main/java/org/apache/syncope/core/rest/data/RouteDataBinder.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/syncope/core/rest/data/RouteDataBinder.java b/core/src/main/java/org/apache/syncope/core/rest/data/RouteDataBinder.java
new file mode 100644
index 0000000..c1016e6
--- /dev/null
+++ b/core/src/main/java/org/apache/syncope/core/rest/data/RouteDataBinder.java
@@ -0,0 +1,40 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.syncope.core.rest.data;
+
+
+import org.apache.syncope.common.to.RouteTO;
+import org.apache.syncope.common.util.BeanUtils;
+import org.apache.syncope.core.persistence.beans.CamelRoute;
+import org.slf4j.LoggerFactory;
+import org.springframework.stereotype.Component;
+
+@Component
+public class RouteDataBinder {
+  
+    private static final org.slf4j.Logger LOG = LoggerFactory.getLogger(RouteDataBinder.class);
+    
+    public RouteTO getRouteTO(CamelRoute route){        
+              
+        RouteTO routeTO = new RouteTO();
+        BeanUtils.copyProperties(route, routeTO);
+        return routeTO;
+    }
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/5b3b124a/core/src/main/java/org/apache/syncope/core/services/RouteServiceImpl.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/syncope/core/services/RouteServiceImpl.java b/core/src/main/java/org/apache/syncope/core/services/RouteServiceImpl.java
new file mode 100644
index 0000000..1c44765
--- /dev/null
+++ b/core/src/main/java/org/apache/syncope/core/services/RouteServiceImpl.java
@@ -0,0 +1,52 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.syncope.core.services;
+
+import java.util.List;
+import org.apache.syncope.common.services.RouteService;
+import org.apache.syncope.common.to.RouteTO;
+import org.apache.syncope.core.rest.controller.RouteController;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+@Service
+public class RouteServiceImpl extends AbstractServiceImpl implements RouteService{
+
+    @Autowired
+    private RouteController controller;
+    
+    @Override
+    public List<RouteTO> getRoutes() {
+        
+        return  controller.listRoutes();
+    }
+    
+    @Override
+    public RouteTO getRoute(Long id){
+        
+        return controller.readRoute(id);
+    }
+
+    @Override
+    public void importRoute(Long id, RouteTO route) {
+        controller.updateRoute(route);
+    }
+    
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/syncope/blob/5b3b124a/core/src/main/java/org/apache/syncope/core/services/WorkflowServiceImpl.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/syncope/core/services/WorkflowServiceImpl.java b/core/src/main/java/org/apache/syncope/core/services/WorkflowServiceImpl.java
index 8fd0416..fa88e7c 100644
--- a/core/src/main/java/org/apache/syncope/core/services/WorkflowServiceImpl.java
+++ b/core/src/main/java/org/apache/syncope/core/services/WorkflowServiceImpl.java
@@ -113,4 +113,14 @@ public class WorkflowServiceImpl extends AbstractServiceImpl implements Workflow
             controller.importRoleDefinition(contentType, definition);
         }
     }
+
+    @Override
+    public Response getRoute(Long id) {
+        throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
+    }
+
+    @Override
+    public Response getRoutes() {
+        throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
+    }
 }

http://git-wip-us.apache.org/repos/asf/syncope/blob/5b3b124a/core/src/main/java/org/apache/syncope/core/sync/impl/AbstractSyncopeResultHandler.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/syncope/core/sync/impl/AbstractSyncopeResultHandler.java b/core/src/main/java/org/apache/syncope/core/sync/impl/AbstractSyncopeResultHandler.java
index adf7c8d..b356e64 100644
--- a/core/src/main/java/org/apache/syncope/core/sync/impl/AbstractSyncopeResultHandler.java
+++ b/core/src/main/java/org/apache/syncope/core/sync/impl/AbstractSyncopeResultHandler.java
@@ -18,6 +18,7 @@
  */
 package org.apache.syncope.core.sync.impl;
 
+import javax.annotation.Resource;
 import org.apache.syncope.core.sync.SyncProfile;
 import org.apache.syncope.core.audit.AuditManager;
 import org.apache.syncope.core.connid.ConnObjectUtil;
@@ -25,6 +26,8 @@ import org.apache.syncope.core.notification.NotificationManager;
 import org.apache.syncope.core.persistence.beans.AbstractSyncTask;
 import org.apache.syncope.core.propagation.PropagationTaskExecutor;
 import org.apache.syncope.core.propagation.impl.PropagationManager;
+import org.apache.syncope.core.provisioning.RoleProvisioningManager;
+import org.apache.syncope.core.provisioning.UserProvisioningManager;
 import org.apache.syncope.core.rest.data.RoleDataBinder;
 import org.apache.syncope.core.rest.data.UserDataBinder;
 import org.apache.syncope.core.sync.AbstractSyncActions;
@@ -99,6 +102,12 @@ public abstract class AbstractSyncopeResultHandler<T extends AbstractSyncTask, A
      * Sync profile.
      */
     protected SyncProfile<T, A> profile;
+    
+    @Resource(name = "defaultUserProvisioningManager")
+    protected UserProvisioningManager userProvisioningManager;
+    
+    @Resource(name = "defaultRoleProvisioningManager")
+    protected RoleProvisioningManager roleProvisioningManager;
 
     public void setProfile(final SyncProfile<T, A> profile) {
         this.profile = profile;

http://git-wip-us.apache.org/repos/asf/syncope/blob/5b3b124a/core/src/main/java/org/apache/syncope/core/sync/impl/RoleSyncResultHandler.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/syncope/core/sync/impl/RoleSyncResultHandler.java b/core/src/main/java/org/apache/syncope/core/sync/impl/RoleSyncResultHandler.java
index 8eb3960..e544687 100644
--- a/core/src/main/java/org/apache/syncope/core/sync/impl/RoleSyncResultHandler.java
+++ b/core/src/main/java/org/apache/syncope/core/sync/impl/RoleSyncResultHandler.java
@@ -30,6 +30,7 @@ import org.apache.syncope.common.mod.RoleMod;
 import org.apache.syncope.common.mod.UserMod;
 import org.apache.syncope.common.to.AbstractSubjectTO;
 import org.apache.syncope.common.to.AttributeTO;
+import org.apache.syncope.common.to.PropagationStatus;
 import org.apache.syncope.common.to.RoleTO;
 import org.apache.syncope.common.types.AttributableType;
 import org.apache.syncope.core.persistence.beans.PropagationTask;
@@ -85,22 +86,12 @@ public class RoleSyncResultHandler extends AbstractSubjectSyncResultHandler {
 
         RoleTO roleTO = RoleTO.class.cast(subjectTO);
 
-        WorkflowResult<Long> created = rwfAdapter.create(roleTO);
-        AttributeTO roleOwner = roleTO.getAttrMap().get(StringUtils.EMPTY);
-        if (roleOwner != null) {
-            roleOwnerMap.put(created.getResult(), roleOwner.getValues().iterator().next());
-        }
-
-        EntitlementUtil.extendAuthContext(created.getResult());
-
-        List<PropagationTask> tasks = propagationManager.getRoleCreateTaskIds(created,
-                roleTO.getVirAttrs(), Collections.singleton(profile.getSyncTask().getResource().getName()));
+        Map.Entry<Long, List<PropagationStatus>> created = roleProvisioningManager.createInSync
+                           (roleTO, roleOwnerMap, Collections.singleton(profile.getSyncTask().getResource().getName()));
 
-        taskExecutor.execute(tasks);
+        roleTO = roleDataBinder.getRoleTO(created.getKey());
 
-        roleTO = roleDataBinder.getRoleTO(created.getResult());
-
-        result.setId(created.getResult());
+        result.setId(created.getKey());
         result.setName(getName(subjectTO));
 
         return roleTO;
@@ -135,7 +126,9 @@ public class RoleSyncResultHandler extends AbstractSubjectSyncResultHandler {
 
         RoleMod roleMod = RoleMod.class.cast(subjectMod);
 
-        final WorkflowResult<Long> updated = rwfAdapter.update(roleMod);
+        Map.Entry<Long, List<PropagationStatus>> updated = roleProvisioningManager.update(roleMod);
+                
+        //moved after role provisioning manager
         String roleOwner = null;
         for (AttributeMod attrMod : roleMod.getAttrsToUpdate()) {
             if (attrMod.getSchema().isEmpty()) {
@@ -143,17 +136,11 @@ public class RoleSyncResultHandler extends AbstractSubjectSyncResultHandler {
             }
         }
         if (roleOwner != null) {
-            roleOwnerMap.put(updated.getResult(), roleOwner);
+            roleOwnerMap.put(updated.getKey(), roleOwner);
         }
 
-        List<PropagationTask> tasks = propagationManager.getRoleUpdateTaskIds(updated,
-                roleMod.getVirAttrsToRemove(),
-                roleMod.getVirAttrsToUpdate(),
-                Collections.singleton(profile.getSyncTask().getResource().getName()));
-
-        taskExecutor.execute(tasks);
-
-        final RoleTO after = roleDataBinder.getRoleTO(updated.getResult());
+        final RoleTO after = roleDataBinder.getRoleTO(updated.getKey());
+        
         result.setName(getName(after));
 
         return after;
@@ -183,6 +170,6 @@ public class RoleSyncResultHandler extends AbstractSubjectSyncResultHandler {
             LOG.error("Could not propagate user " + id, e);
         }
 
-        rwfAdapter.delete(id);
+        roleProvisioningManager.delete(id); 
     }
 }

http://git-wip-us.apache.org/repos/asf/syncope/blob/5b3b124a/core/src/main/java/org/apache/syncope/core/sync/impl/UserSyncResultHandler.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/syncope/core/sync/impl/UserSyncResultHandler.java b/core/src/main/java/org/apache/syncope/core/sync/impl/UserSyncResultHandler.java
index a8cc00b..e5bdc06 100644
--- a/core/src/main/java/org/apache/syncope/core/sync/impl/UserSyncResultHandler.java
+++ b/core/src/main/java/org/apache/syncope/core/sync/impl/UserSyncResultHandler.java
@@ -29,6 +29,7 @@ import org.apache.commons.lang3.exception.ExceptionUtils;
 import org.apache.syncope.common.mod.AbstractSubjectMod;
 import org.apache.syncope.common.mod.UserMod;
 import org.apache.syncope.common.to.AbstractSubjectTO;
+import org.apache.syncope.common.to.PropagationStatus;
 import org.apache.syncope.common.to.UserTO;
 import org.apache.syncope.common.types.AttributableType;
 import org.apache.syncope.core.persistence.beans.PropagationTask;
@@ -80,19 +81,13 @@ public class UserSyncResultHandler extends AbstractSubjectSyncResultHandler {
         UserTO userTO = UserTO.class.cast(subjectTO);
 
         Boolean enabled = syncUtilities.readEnabled(delta.getObject(), profile.getSyncTask());
-        WorkflowResult<Map.Entry<Long, Boolean>> created =
-                uwfAdapter.create(userTO, true, enabled, true);
+        //Delegate User Workflow Creation and its Propagation to provisioning manager
+        Map.Entry<Long, List<PropagationStatus>>
+            created = userProvisioningManager.create(userTO, true, true, enabled,Collections.singleton(profile.getSyncTask().getResource().getName()));                             
 
-        List<PropagationTask> tasks = propagationManager.getUserCreateTaskIds(created,
-                userTO.getPassword(), userTO.getVirAttrs(),
-                Collections.singleton(profile.getSyncTask().getResource().getName()),
-                userTO.getMemberships());
+        userTO = userDataBinder.getUserTO(created.getKey());
 
-        taskExecutor.execute(tasks);
-
-        userTO = userDataBinder.getUserTO(created.getResult().getKey());
-
-        result.setId(created.getResult().getKey());
+        result.setId(created.getKey());
 
         return userTO;
     }
@@ -126,7 +121,7 @@ public class UserSyncResultHandler extends AbstractSubjectSyncResultHandler {
 
         final UserMod userMod = UserMod.class.cast(subjectMod);
 
-        WorkflowResult<Map.Entry<UserMod, Boolean>> updated;
+        /*WorkflowResult<Map.Entry<UserMod, Boolean>> updated;
         try {
             updated = uwfAdapter.update(userMod);
         } catch (Exception e) {
@@ -140,10 +135,10 @@ public class UserSyncResultHandler extends AbstractSubjectSyncResultHandler {
                     new AbstractMap.SimpleEntry<UserMod, Boolean>(userMod, false),
                     new PropagationByResource(),
                     new HashSet<String>());
-        }
+        }*/
 
         final Boolean enabled = syncUtilities.readEnabled(delta.getObject(), profile.getSyncTask());
-        if (enabled != null) {
+        /*if (enabled != null) {
             SyncopeUser user = userDAO.find(before.getId());
 
             WorkflowResult<Long> enableUpdate = null;
@@ -168,9 +163,11 @@ public class UserSyncResultHandler extends AbstractSubjectSyncResultHandler {
                 updated, updated.getResult().getKey().getPassword() != null,
                 Collections.singleton(profile.getSyncTask().getResource().getName()));
 
-        taskExecutor.execute(tasks);
+        taskExecutor.execute(tasks);*/
+                 
+        Map.Entry<Long, List<PropagationStatus>> updated = userProvisioningManager.updateInSync(userMod, before.getId(), result,enabled, Collections.singleton(profile.getSyncTask().getResource().getName()));        
 
-        return userDataBinder.getUserTO(updated.getResult().getKey().getId());
+        return userDataBinder.getUserTO(updated.getKey());
     }
 
     @Override
@@ -191,8 +188,8 @@ public class UserSyncResultHandler extends AbstractSubjectSyncResultHandler {
     @Override
     protected void delete(final Long id) {
         try {
-            taskExecutor.execute(
-                    propagationManager.getUserDeleteTaskIds(id, profile.getSyncTask().getResource().getName()));
+            userProvisioningManager.
+                    delete(id,Collections.<String>singleton(profile.getSyncTask().getResource().getName()));
         } catch (Exception e) {
             // A propagation failure doesn't imply a synchronization failure.
             // The propagation exception status will be reported into the propagation task execution.

http://git-wip-us.apache.org/repos/asf/syncope/blob/5b3b124a/core/src/main/java/org/apache/syncope/core/util/RouteManager.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/syncope/core/util/RouteManager.java b/core/src/main/java/org/apache/syncope/core/util/RouteManager.java
new file mode 100644
index 0000000..67ebd82
--- /dev/null
+++ b/core/src/main/java/org/apache/syncope/core/util/RouteManager.java
@@ -0,0 +1,39 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.syncope.core.util;
+
+import java.util.ArrayList;
+import java.util.List;
+import org.apache.syncope.core.persistence.beans.CamelRoute;
+
+
+public class RouteManager {
+    private static List<CamelRoute> routelist;
+    
+    public static void addElement(CamelRoute route){
+        if(routelist == null) routelist= new ArrayList<CamelRoute>();
+        routelist.add(route);
+    }
+    
+    public static List<CamelRoute> getRoutes(){
+        if(routelist == null) routelist= new ArrayList<CamelRoute>();
+        return routelist;
+    }
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/5b3b124a/core/src/main/java/org/apache/syncope/core/workflow/WorkflowUserSuspender.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/syncope/core/workflow/WorkflowUserSuspender.java b/core/src/main/java/org/apache/syncope/core/workflow/WorkflowUserSuspender.java
index 7b1ee15..ef4a46d 100644
--- a/core/src/main/java/org/apache/syncope/core/workflow/WorkflowUserSuspender.java
+++ b/core/src/main/java/org/apache/syncope/core/workflow/WorkflowUserSuspender.java
@@ -21,12 +21,14 @@ package org.apache.syncope.core.workflow;
 import java.util.AbstractMap.SimpleEntry;
 import java.util.List;
 import java.util.Map;
+import javax.annotation.Resource;
 import org.apache.syncope.common.mod.UserMod;
 import org.apache.syncope.core.persistence.beans.PropagationTask;
 import org.apache.syncope.core.persistence.beans.user.SyncopeUser;
 import org.apache.syncope.core.policy.UserSuspender;
 import org.apache.syncope.core.propagation.PropagationTaskExecutor;
 import org.apache.syncope.core.propagation.impl.PropagationManager;
+import org.apache.syncope.core.provisioning.UserProvisioningManager;
 import org.apache.syncope.core.workflow.user.UserWorkflowAdapter;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -38,14 +40,8 @@ public class WorkflowUserSuspender implements UserSuspender {
 
     private static final Logger LOG = LoggerFactory.getLogger(WorkflowUserSuspender.class);
 
-    @Autowired
-    private UserWorkflowAdapter uwfAdapter;
-
-    @Autowired
-    private PropagationManager propagationManager;
-
-    @Autowired
-    private PropagationTaskExecutor taskExecutor;
+    @Resource(name = "defaultUserProvisioningManager")
+    protected UserProvisioningManager provisioningManager;
 
     @Override
     public void suspend(final SyncopeUser user, final boolean suspend) {
@@ -55,21 +51,8 @@ public class WorkflowUserSuspender implements UserSuspender {
             // reduce failed logins number to avoid multiple request
             user.setFailedLogins(user.getFailedLogins() - 1);
 
-            // disable user
-            final WorkflowResult<Long> updated = uwfAdapter.suspend(user);
-
-            // propagate suspension if and only if it is required by policy
-            if (suspend) {
-                UserMod userMod = new UserMod();
-                userMod.setId(updated.getResult());
-
-                final List<PropagationTask> tasks = propagationManager.getUserUpdateTaskIds(
-                        new WorkflowResult<Map.Entry<UserMod, Boolean>>(
-                                new SimpleEntry<UserMod, Boolean>(userMod, Boolean.FALSE),
-                                updated.getPropByRes(), updated.getPerformedTasks()));
-
-                taskExecutor.execute(tasks);
-            }
+            // disable user and propagate suspension if and only if it is required by policy          
+            provisioningManager.innerSuspend(user, suspend);
         } catch (Exception e) {
             LOG.error("Error during user suspension", e);
         }

http://git-wip-us.apache.org/repos/asf/syncope/blob/5b3b124a/core/src/main/java/org/apache/syncope/core/workflow/user/AbstractUserWorkflowAdapter.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/syncope/core/workflow/user/AbstractUserWorkflowAdapter.java b/core/src/main/java/org/apache/syncope/core/workflow/user/AbstractUserWorkflowAdapter.java
index 9425f17..f059a9a 100644
--- a/core/src/main/java/org/apache/syncope/core/workflow/user/AbstractUserWorkflowAdapter.java
+++ b/core/src/main/java/org/apache/syncope/core/workflow/user/AbstractUserWorkflowAdapter.java
@@ -19,9 +19,7 @@
 package org.apache.syncope.core.workflow.user;
 
 import java.util.Map;
-import java.util.Map.Entry;
 import org.apache.syncope.common.mod.UserMod;
-import org.apache.syncope.common.to.UserTO;
 import org.apache.syncope.core.persistence.beans.user.SyncopeUser;
 import org.apache.syncope.core.persistence.dao.UserDAO;
 import org.apache.syncope.core.rest.controller.UnauthorizedRoleException;
@@ -61,13 +59,6 @@ public abstract class AbstractUserWorkflowAdapter implements UserWorkflowAdapter
         return null;
     }
 
-    @Override
-    public WorkflowResult<Entry<Long, Boolean>> create(final UserTO userTO, final boolean storePassword)
-            throws UnauthorizedRoleException, WorkflowException {
-
-        return create(userTO, false, storePassword);
-    }
-
     protected abstract WorkflowResult<Long> doActivate(SyncopeUser user, String token) throws WorkflowException;
 
     @Override

http://git-wip-us.apache.org/repos/asf/syncope/blob/5b3b124a/core/src/main/java/org/apache/syncope/core/workflow/user/NoOpUserWorkflowAdapter.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/syncope/core/workflow/user/NoOpUserWorkflowAdapter.java b/core/src/main/java/org/apache/syncope/core/workflow/user/NoOpUserWorkflowAdapter.java
index 1ffc4c7..8713261 100644
--- a/core/src/main/java/org/apache/syncope/core/workflow/user/NoOpUserWorkflowAdapter.java
+++ b/core/src/main/java/org/apache/syncope/core/workflow/user/NoOpUserWorkflowAdapter.java
@@ -228,4 +228,9 @@ public class NoOpUserWorkflowAdapter extends AbstractUserWorkflowAdapter {
 
         throw new WorkflowException(new UnsupportedOperationException("Not supported."));
     }
+
+    @Override
+    public WorkflowResult<Map.Entry<Long, Boolean>> create(UserTO userTO, boolean storePassword) throws UnauthorizedRoleException, WorkflowException {
+        return create(userTO, false, true);
+    }
 }

http://git-wip-us.apache.org/repos/asf/syncope/blob/5b3b124a/core/src/main/java/org/apache/syncope/core/workflow/user/activiti/ActivitiUserWorkflowAdapter.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/syncope/core/workflow/user/activiti/ActivitiUserWorkflowAdapter.java b/core/src/main/java/org/apache/syncope/core/workflow/user/activiti/ActivitiUserWorkflowAdapter.java
index f6cc322..460b73b 100644
--- a/core/src/main/java/org/apache/syncope/core/workflow/user/activiti/ActivitiUserWorkflowAdapter.java
+++ b/core/src/main/java/org/apache/syncope/core/workflow/user/activiti/ActivitiUserWorkflowAdapter.java
@@ -883,4 +883,9 @@ public class ActivitiUserWorkflowAdapter extends AbstractUserWorkflowAdapter {
 
         return new WorkflowResult<UserMod>(userMod, propByRes, postTasks);
     }
+
+    @Override
+    public WorkflowResult<Map.Entry<Long, Boolean>> create(UserTO userTO, boolean storePassword) throws UnauthorizedRoleException, WorkflowException {
+        return create(userTO, false, storePassword);
+    }
 }