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:08 UTC
[03/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/DefaultUserProvisioningManager.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/syncope/core/provisioning/DefaultUserProvisioningManager.java b/core/src/main/java/org/apache/syncope/core/provisioning/DefaultUserProvisioningManager.java
new file mode 100644
index 0000000..86f6ebe
--- /dev/null
+++ b/core/src/main/java/org/apache/syncope/core/provisioning/DefaultUserProvisioningManager.java
@@ -0,0 +1,347 @@
+/*
+ * 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.AbstractMap;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import org.apache.syncope.common.mod.StatusMod;
+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.persistence.beans.user.SyncopeUser;
+import org.apache.syncope.core.persistence.dao.UserDAO;
+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.sync.SyncResult;
+import org.apache.syncope.core.util.ApplicationContextProvider;
+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 DefaultUserProvisioningManager implements UserProvisioningManager{
+
+ private static final Logger LOG = LoggerFactory.getLogger(DefaultUserProvisioningManager.class);
+
+ @Autowired
+ protected UserWorkflowAdapter uwfAdapter;
+
+ @Autowired
+ protected PropagationManager propagationManager;
+
+ @Autowired
+ protected PropagationTaskExecutor taskExecutor;
+
+ @Autowired
+ protected UserDataBinder binder;
+
+ @Autowired
+ protected UserDAO userDAO;
+
+ @Override
+ public Map.Entry<Long, List<PropagationStatus>> create(final UserTO userTO){
+ return create(userTO, true);
+ }
+
+ public Map.Entry<Long, List<PropagationStatus>> create(final UserTO userTO, boolean storePassword) {
+ WorkflowResult<Map.Entry<Long, Boolean>> created;
+ try {
+ created = uwfAdapter.create(userTO,storePassword);
+ } catch (RuntimeException e) {
+ throw e;
+ }
+
+ List<PropagationTask> tasks = propagationManager.getUserCreateTaskIds(
+ created, userTO.getPassword(), userTO.getVirAttrs(), userTO.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>> result = new AbstractMap.SimpleEntry<Long, List<PropagationStatus>>(
+ created.getResult().getKey(), propagationReporter.getStatuses());
+ return result;
+ }
+
+ @Override
+ public Map.Entry<Long, List<PropagationStatus>> create(UserTO userTO, boolean storePassword, boolean disablePwdPolicyCheck, Boolean enabled, Set<String> excludedResources) {
+ WorkflowResult<Map.Entry<Long, Boolean>> created;
+ try {
+ created = uwfAdapter.create(userTO,storePassword);
+ } catch (RuntimeException e) {
+ throw e;
+ }
+
+ List<PropagationTask> tasks = propagationManager.getUserCreateTaskIds(
+ created, userTO.getPassword(), userTO.getVirAttrs(), excludedResources, null);
+ 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>> result = new AbstractMap.SimpleEntry<Long, List<PropagationStatus>>(
+ created.getResult().getKey(), propagationReporter.getStatuses());
+ return result;
+ }
+
+ @Override
+ public Map.Entry<Long, List<PropagationStatus>> update(final UserMod userMod) {
+ return update(userMod, false);
+ }
+
+ @Override
+ public Map.Entry<Long, List<PropagationStatus>> update(UserMod userMod, boolean removeMemberships) {
+ WorkflowResult<Map.Entry<UserMod, Boolean>> updated;
+ try {
+ updated = uwfAdapter.update(userMod);
+ } catch (RuntimeException e) {
+ throw e;
+ }
+
+ List<PropagationTask> tasks = propagationManager.getUserUpdateTaskIds(updated);
+
+ 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>> result = new AbstractMap.SimpleEntry<Long, List<PropagationStatus>>(
+ updated.getResult().getKey().getId(), propagationReporter.getStatuses());
+ return result;
+ }
+
+ @Override
+ public List<PropagationStatus> delete(final Long userId) {
+
+ return delete(userId, Collections.<String>emptySet());
+ }
+
+ @Override
+ public List<PropagationStatus> delete(Long subjectId, Set<String> excludedResources) {
+ List<PropagationTask> tasks = propagationManager.getUserDeleteTaskIds(subjectId,excludedResources);
+
+ 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);
+ }
+
+ try {
+ uwfAdapter.delete(subjectId);
+ } catch (RuntimeException e) {
+ throw e;
+ }
+
+ return propagationReporter.getStatuses();
+ }
+
+
+ @Override
+ public Long unlink(UserMod userMod) {
+ WorkflowResult<Map.Entry<UserMod, Boolean>> updated = uwfAdapter.update(userMod);
+ return updated.getResult().getKey().getId();
+ }
+
+ @Override
+ public Long link(UserMod subjectMod) {
+ return uwfAdapter.update(subjectMod).getResult().getKey().getId();
+ }
+
+ @Override
+ public Map.Entry<Long, List<PropagationStatus>> activate(SyncopeUser user, StatusMod statusMod) {
+ WorkflowResult<Long> updated;
+ if (statusMod.isOnSyncope()) {
+ updated = uwfAdapter.activate(user.getId(), statusMod.getToken());
+ } else {
+ updated = new WorkflowResult<Long>(user.getId(), null, statusMod.getType().name().toLowerCase());
+ }
+
+ List<PropagationStatus> statuses = propagateStatus(user, statusMod);
+ return new AbstractMap.SimpleEntry<Long, List<PropagationStatus>>(updated.getResult(), statuses);
+ }
+
+ @Override
+ public Map.Entry<Long, List<PropagationStatus>> reactivate(SyncopeUser user, StatusMod statusMod) {
+ WorkflowResult<Long> updated;
+ if (statusMod.isOnSyncope()) {
+ updated = uwfAdapter.reactivate(user.getId());
+ } else {
+ updated = new WorkflowResult<Long>(user.getId(), null, statusMod.getType().name().toLowerCase());
+ }
+
+ List<PropagationStatus> statuses = propagateStatus(user, statusMod);
+ return new AbstractMap.SimpleEntry<Long, List<PropagationStatus>>(updated.getResult(), statuses);
+ }
+
+ @Override
+ public Map.Entry<Long, List<PropagationStatus>> suspend(SyncopeUser user, StatusMod statusMod) {
+ WorkflowResult<Long> updated;
+ if (statusMod.isOnSyncope()) {
+ updated = uwfAdapter.suspend(user.getId());
+ } else {
+ updated = new WorkflowResult<Long>(user.getId(), null, statusMod.getType().name().toLowerCase());
+ }
+
+ List<PropagationStatus> statuses = propagateStatus(user, statusMod);
+ return new AbstractMap.SimpleEntry<Long, List<PropagationStatus>>(updated.getResult(), statuses);
+ }
+
+ public List<PropagationStatus> propagateStatus(SyncopeUser user, StatusMod statusMod){
+
+ 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);
+ }
+
+ return propReporter.getStatuses();
+
+ }
+
+ @Override
+ public List<PropagationStatus> deprovision(Long userId, 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);
+ }
+
+ return propagationReporter.getStatuses();
+ }
+
+ @Override
+ public Map.Entry<Long, List<PropagationStatus>> updateInSync(final UserMod userMod,final Long id, final SyncResult result, Boolean enabled, Set<String> excludedResources){
+
+ WorkflowResult<Map.Entry<UserMod, Boolean>> updated;
+ try {
+ updated = uwfAdapter.update(userMod);
+ } catch (Exception e) {
+ LOG.error("Update of user {} failed, trying to sync its status anyway (if configured)", id, e);
+
+ result.setStatus(SyncResult.Status.FAILURE);
+ result.setMessage("Update failed, trying to sync status anyway (if configured)\n" + e.getMessage());
+
+ updated = new WorkflowResult<Map.Entry<UserMod, Boolean>>(
+ new AbstractMap.SimpleEntry<UserMod, Boolean>(userMod, false), new PropagationByResource(),
+ new HashSet<String>());
+ }
+
+ 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());
+ }
+ }
+
+ PropagationReporter propagationReporter = ApplicationContextProvider.getApplicationContext().
+ getBean(PropagationReporter.class);
+
+ List<PropagationTask> tasks = propagationManager.getUserUpdateTaskIds(updated,updated.getResult().getKey().getPassword() != null,excludedResources);
+
+ try {
+ taskExecutor.execute(tasks, propagationReporter);
+ } catch (PropagationException e) {
+ LOG.error("Error propagation primary resource", e);
+ propagationReporter.onPrimaryResourceFailure(tasks);
+ }
+
+ return new AbstractMap.SimpleEntry<Long, List<PropagationStatus>>(updated.getResult().getKey().getId(), propagationReporter.getStatuses());
+
+ }
+
+ @Override
+ public void innerSuspend(SyncopeUser user, boolean suspend) {
+
+ 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 AbstractMap.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/RoleProvisioningManager.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/syncope/core/provisioning/RoleProvisioningManager.java b/core/src/main/java/org/apache/syncope/core/provisioning/RoleProvisioningManager.java
new file mode 100644
index 0000000..594bf5e
--- /dev/null
+++ b/core/src/main/java/org/apache/syncope/core/provisioning/RoleProvisioningManager.java
@@ -0,0 +1,35 @@
+/*
+ * Copyright 2013 The Apache Software Foundation.
+ *
+ * Licensed 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.List;
+import java.util.Map;
+import java.util.Set;
+import org.apache.syncope.common.to.RoleTO;
+import org.apache.syncope.common.mod.RoleMod;
+import org.apache.syncope.common.to.PropagationStatus;
+import org.apache.syncope.core.propagation.PropagationException;
+
+public interface RoleProvisioningManager extends ProvisioningManager<RoleTO, RoleMod>{
+
+ public Map.Entry<Long, List<PropagationStatus>> create(final RoleTO roleTO, Set<String> excludedResources);
+
+ public Map.Entry<Long, List<PropagationStatus>> createInSync(final RoleTO roleTO, Map<Long, String> roleOwnerMap,Set<String> excludedResources) throws PropagationException;
+
+ public Map.Entry<Long, List<PropagationStatus>> update(RoleMod subjectMod, Set<String> excludedResources);
+
+}
http://git-wip-us.apache.org/repos/asf/syncope/blob/5b3b124a/core/src/main/java/org/apache/syncope/core/provisioning/UserProvisioningManager.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/syncope/core/provisioning/UserProvisioningManager.java b/core/src/main/java/org/apache/syncope/core/provisioning/UserProvisioningManager.java
new file mode 100644
index 0000000..da29a42
--- /dev/null
+++ b/core/src/main/java/org/apache/syncope/core/provisioning/UserProvisioningManager.java
@@ -0,0 +1,50 @@
+/*
+ * Copyright 2013 The Apache Software Foundation.
+ *
+ * Licensed 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.List;
+import java.util.Map;
+import java.util.Set;
+import org.apache.syncope.common.mod.StatusMod;
+import org.apache.syncope.core.workflow.WorkflowResult;
+import org.apache.syncope.common.to.UserTO;
+import org.apache.syncope.common.mod.UserMod;
+import org.apache.syncope.common.to.PropagationStatus;
+import org.apache.syncope.core.persistence.beans.user.SyncopeUser;
+import org.apache.syncope.core.sync.SyncResult;
+
+public interface UserProvisioningManager extends ProvisioningManager<UserTO, UserMod>{
+
+ public Map.Entry<Long, List<PropagationStatus>> activate(SyncopeUser user, StatusMod statusMod);
+
+ public Map.Entry<Long, List<PropagationStatus>> reactivate(SyncopeUser user, StatusMod statusMod);
+
+ public Map.Entry<Long, List<PropagationStatus>> suspend(SyncopeUser user, StatusMod statusMod);
+
+ public Map.Entry<Long, List<PropagationStatus>> create(final UserTO userTO, final boolean storePassword);
+
+ public Map.Entry<Long, List<PropagationStatus>> create(final UserTO userTO, final boolean storePassword, boolean disablePwdPolicyCheck, Boolean enabled,Set<String> excludedResources);
+
+ public Map.Entry<Long, List<PropagationStatus>> update(final UserMod userMod, final boolean removeMemberships);
+
+ public Map.Entry<Long, List<PropagationStatus>> updateInSync(final UserMod userMod,final Long id, final SyncResult result, Boolean enabled, Set<String> excludedResources);
+
+ public List<PropagationStatus> delete(Long subjectId, Set<String> excludedResources);
+
+ public void innerSuspend(SyncopeUser user, boolean suspend);
+
+}
http://git-wip-us.apache.org/repos/asf/syncope/blob/5b3b124a/core/src/main/java/org/apache/syncope/core/provisioning/camel/CamelRoleProvisioningManager.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/syncope/core/provisioning/camel/CamelRoleProvisioningManager.java b/core/src/main/java/org/apache/syncope/core/provisioning/camel/CamelRoleProvisioningManager.java
new file mode 100644
index 0000000..4857d2f
--- /dev/null
+++ b/core/src/main/java/org/apache/syncope/core/provisioning/camel/CamelRoleProvisioningManager.java
@@ -0,0 +1,307 @@
+/*
+ * 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;
+
+import java.io.ByteArrayInputStream;
+import java.io.File;
+import java.io.InputStream;
+import java.net.URLDecoder;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import javax.xml.bind.JAXBContext;
+import javax.xml.bind.JAXBElement;
+import javax.xml.bind.Unmarshaller;
+import javax.xml.parsers.DocumentBuilder;
+import javax.xml.parsers.DocumentBuilderFactory;
+import org.apache.camel.CamelContext;
+import org.apache.camel.Endpoint;
+import org.apache.camel.Exchange;
+import org.apache.camel.PollingConsumer;
+import org.apache.camel.ProducerTemplate;
+import org.apache.camel.impl.DefaultCamelContext;
+import org.apache.camel.impl.DefaultExchange;
+import org.apache.camel.impl.DefaultMessage;
+import org.apache.camel.model.Constants;
+import org.apache.camel.model.RouteDefinition;
+import org.apache.camel.model.RoutesDefinition;
+import org.apache.camel.spring.SpringCamelContext;
+import org.apache.syncope.common.mod.RoleMod;
+import org.apache.syncope.common.to.PropagationStatus;
+import org.apache.syncope.common.to.RoleTO;
+import org.apache.syncope.core.persistence.beans.CamelRoute;
+import org.apache.syncope.core.persistence.dao.RouteDAO;
+import org.apache.syncope.core.propagation.PropagationException;
+import org.apache.syncope.core.provisioning.RoleProvisioningManager;
+import org.apache.syncope.core.util.ApplicationContextProvider;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.context.ApplicationContext;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.w3c.dom.Node;
+import org.w3c.dom.NodeList;
+
+public class CamelRoleProvisioningManager implements RoleProvisioningManager{
+
+ private static final Logger LOG = LoggerFactory.getLogger(CamelRoleProvisioningManager.class);
+
+ private DefaultCamelContext camelContext;
+
+ private RoutesDefinition routes;
+
+ protected Map<String, PollingConsumer> consumerMap;
+
+ protected List<String> knownUri;
+
+ @Autowired
+ protected RouteDAO routeDAO;
+
+ @Autowired
+ protected SyncopeCamelContext contextFactory;
+
+ public CamelRoleProvisioningManager() throws Exception {
+ knownUri = new ArrayList<String>();
+ consumerMap = new HashMap();
+ }
+
+ public void startContext() throws Exception {
+ camelContext.start();
+ }
+
+ public void stopContext() throws Exception {
+ camelContext.stop();
+ }
+
+ public CamelContext getContext() {
+ //ApplicationContext context = ApplicationContextProvider.getApplicationContext();
+ //return context.getBean("camel-context", DefaultCamelContext.class);
+ return contextFactory.getContext(routeDAO);
+ }
+
+ public void changeRoute(String routePath) {
+ try {
+ camelContext.removeRouteDefinitions(routes.getRoutes());
+ InputStream is = getClass().getResourceAsStream(routePath);
+ routes = getContext().loadRoutesDefinition(is);
+ camelContext.addRouteDefinitions(routes.getRoutes());
+ } catch (Exception e) {
+ // TODO Auto-generated catch block
+ LOG.error("Unexpected error", e);
+ }
+ }
+
+ protected void sendMessage(String uri, Object obj) {
+ Exchange exc = new DefaultExchange(getContext());
+ DefaultMessage m = new DefaultMessage();
+ m.setBody(obj);
+ exc.setIn(m);
+ ProducerTemplate template = getContext().createProducerTemplate();
+ template.send(uri, exc);
+ }
+
+ protected void sendMessage(String uri, Object obj, Map<String, Object> properties) {
+ Exchange exc = new DefaultExchange(getContext());
+
+ Iterator<Map.Entry<String, Object>> it = properties.entrySet().iterator();
+ while (it.hasNext()) {
+ Map.Entry<String, Object> property = it.next();
+ exc.setProperty(property.getKey(), property.getValue());
+ LOG.info("Added property {}", property.getKey());
+ }
+
+ DefaultMessage m = new DefaultMessage();
+ m.setBody(obj);
+ exc.setIn(m);
+ ProducerTemplate template = getContext().createProducerTemplate();
+ template.send(uri, exc);
+ }
+
+ protected PollingConsumer getConsumer(final String uri) {
+
+ if (!knownUri.contains(uri)) {
+ knownUri.add(uri);
+ Endpoint endpoint = getContext().getEndpoint(uri);
+ PollingConsumer pollingConsumer = null;
+ try {
+ pollingConsumer = endpoint.createPollingConsumer();
+ consumerMap.put(uri, pollingConsumer);
+ pollingConsumer.start();
+ } catch (Exception ex) {
+ LOG.error("Unexpected error in Consumer creation ", ex);
+ }
+ return pollingConsumer;
+ } else {
+ return consumerMap.get(uri);
+ }
+ }
+
+ @Override
+ public Map.Entry<Long, List<PropagationStatus>> create(RoleTO subject) {
+
+ return create(subject, Collections.<String>emptySet());
+ }
+
+ @Override
+ public Map.Entry<Long, List<PropagationStatus>> create(RoleTO roleTO, Set<String> excludedResources) {
+
+ String uri = "direct:createRolePort";
+ PollingConsumer pollingConsumer = getConsumer(uri);
+
+ Map<String, Object> props = new HashMap<String, Object>();
+ props.put("excludedResources", excludedResources);
+
+ sendMessage("direct:createRole", roleTO, props);
+
+ Exchange o = pollingConsumer.receive();
+
+ if (o.getProperty(Exchange.EXCEPTION_CAUGHT) != null) {
+ throw (RuntimeException) o.getProperty(Exchange.EXCEPTION_CAUGHT);
+ }
+
+ return o.getIn().getBody(Map.Entry.class);
+ }
+
+ @Override
+ public Map.Entry<Long, List<PropagationStatus>> createInSync(RoleTO roleTO, Map<Long, String> roleOwnerMap, Set<String> excludedResources) throws PropagationException {
+
+ String uri = "direct:createRoleSyncPort";
+ PollingConsumer pollingConsumer = getConsumer(uri);
+
+ Map<String, Object> props = new HashMap<String, Object>();
+ props.put("roleOwnerMap", roleOwnerMap);
+ props.put("excludedResources", excludedResources);
+
+ sendMessage("direct:createRoleSync", roleTO, props);
+
+ Exchange o = pollingConsumer.receive();
+
+ if (o.getProperty(Exchange.EXCEPTION_CAUGHT) != null) {
+ throw (RuntimeException) o.getProperty(Exchange.EXCEPTION_CAUGHT);
+ }
+
+ return o.getIn().getBody(Map.Entry.class);
+ }
+
+ @Override
+ public Map.Entry<Long, List<PropagationStatus>> update(RoleMod subjectMod) {
+
+ return update(subjectMod, Collections.<String>emptySet());
+ }
+
+ @Override
+ public Map.Entry<Long, List<PropagationStatus>> update(RoleMod subjectMod, Set<String> excludedResources) {
+
+ String uri = "direct:updateRolePort";
+ PollingConsumer pollingConsumer = getConsumer(uri);
+
+ Map<String, Object> props = new HashMap<String, Object>();
+ props.put("excludedResources", excludedResources);
+
+ sendMessage("direct:updateRole",subjectMod, props);
+
+ Exchange o = pollingConsumer.receive();
+
+ if (o.getProperty(Exchange.EXCEPTION_CAUGHT) != null) {
+ throw (RuntimeException) o.getProperty(Exchange.EXCEPTION_CAUGHT);
+ }
+
+ return o.getIn().getBody(Map.Entry.class);
+ }
+
+ @Override
+ public List<PropagationStatus> delete(Long subjectId) {
+
+ String uri = "direct:deleteRolePort";
+ PollingConsumer pollingConsumer = getConsumer(uri);
+
+ sendMessage("direct:deleteRole", subjectId);
+
+ Exchange o = pollingConsumer.receive();
+
+ if (o.getProperty(Exchange.EXCEPTION_CAUGHT) != null) {
+ throw (RuntimeException) o.getProperty(Exchange.EXCEPTION_CAUGHT);
+ }
+
+ return o.getIn().getBody(List.class);
+ }
+
+ @Override
+ public Long unlink(RoleMod subjectMod) {
+ String uri = "direct:unlinkRolePort";
+ PollingConsumer pollingConsumer = getConsumer(uri);
+
+ sendMessage("direct:unlinkRole", subjectMod);
+
+ Exchange o = pollingConsumer.receive();
+
+ if (o.getProperty(Exchange.EXCEPTION_CAUGHT) != null) {
+ throw (RuntimeException) o.getProperty(Exchange.EXCEPTION_CAUGHT);
+ }
+
+ return o.getIn().getBody(Long.class);
+ }
+
+ @Override
+ public Long link(RoleMod subjectMod) {
+
+ String uri = "direct:linkRolePort";
+
+ PollingConsumer pollingConsumer = getConsumer(uri);
+
+ sendMessage("direct:linkRole", subjectMod);
+
+ Exchange o = pollingConsumer.receive();
+
+ if (o.getProperty(Exchange.EXCEPTION_CAUGHT) != null) {
+ throw (RuntimeException) o.getProperty(Exchange.EXCEPTION_CAUGHT);
+ }
+
+ return o.getIn().getBody(Long.class);
+ }
+
+ @Override
+ public List<PropagationStatus> deprovision(final Long roleId, Collection<String> resources) {
+
+ String uri = "direct:deprovisionRolePort";
+
+ PollingConsumer pollingConsumer = getConsumer(uri);
+
+ Map props = new HashMap<String, Object>();
+ props.put("resources", resources);
+
+ sendMessage("direct:deprovisionRole", roleId, props);
+
+ Exchange o = pollingConsumer.receive();
+
+ if (o.getProperty(Exchange.EXCEPTION_CAUGHT) != null) {
+ throw (RuntimeException) o.getProperty(Exchange.EXCEPTION_CAUGHT);
+ }
+
+ return o.getIn().getBody(List.class);
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/syncope/blob/5b3b124a/core/src/main/java/org/apache/syncope/core/provisioning/camel/CamelUserProvisioningManager.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/syncope/core/provisioning/camel/CamelUserProvisioningManager.java b/core/src/main/java/org/apache/syncope/core/provisioning/camel/CamelUserProvisioningManager.java
new file mode 100644
index 0000000..dc0c552
--- /dev/null
+++ b/core/src/main/java/org/apache/syncope/core/provisioning/camel/CamelUserProvisioningManager.java
@@ -0,0 +1,456 @@
+/*
+ * 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;
+
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.Reader;
+import java.net.URLDecoder;
+import java.util.AbstractMap;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import javax.xml.bind.JAXBContext;
+import javax.xml.bind.JAXBElement;
+import javax.xml.bind.Unmarshaller;
+import javax.xml.parsers.DocumentBuilder;
+import javax.xml.parsers.DocumentBuilderFactory;
+import org.apache.camel.CamelContext;
+import org.apache.camel.Endpoint;
+import org.apache.camel.Exchange;
+import org.apache.camel.PollingConsumer;
+import org.apache.camel.ProducerTemplate;
+import org.apache.camel.impl.DefaultCamelContext;
+import org.apache.camel.impl.DefaultExchange;
+import org.apache.camel.impl.DefaultMessage;
+import org.apache.camel.model.Constants;
+import org.apache.camel.model.RouteDefinition;
+import org.apache.camel.model.RoutesDefinition;
+import org.apache.camel.spring.SpringCamelContext;
+import org.apache.syncope.common.mod.StatusMod;
+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.CamelRoute;
+import org.apache.syncope.core.persistence.beans.user.SyncopeUser;
+import org.apache.syncope.core.persistence.dao.RouteDAO;
+import org.apache.syncope.core.propagation.PropagationByResource;
+import org.apache.syncope.core.provisioning.UserProvisioningManager;
+import org.apache.syncope.core.sync.SyncResult;
+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;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.w3c.dom.Node;
+import org.w3c.dom.NodeList;
+
+public class CamelUserProvisioningManager implements UserProvisioningManager {
+
+ private static final Logger LOG = LoggerFactory.getLogger(CamelUserProvisioningManager.class);
+
+ private DefaultCamelContext camelContext;
+
+ private RoutesDefinition routes;
+
+ protected Map<String, PollingConsumer> consumerMap;
+
+ protected List<String> knownUri;
+
+ @Autowired
+ protected RouteDAO routeDAO;
+
+ @Autowired
+ protected SyncopeCamelContext contextFactory;
+
+ public CamelUserProvisioningManager() throws Exception {
+ knownUri = new ArrayList<String>();
+ consumerMap = new HashMap();
+ }
+
+ public String readerToString(Reader reader, int size) throws IOException {
+ StringBuffer content = new StringBuffer();
+ char[] buffer = new char[size];
+ int n;
+
+ while ((n = reader.read(buffer)) != -1) {
+ content.append(buffer, 0, n);
+ }
+
+ return content.toString();
+ }
+
+ public void startContext() throws Exception {
+ getContext().start();
+ }
+
+ public void stopContext() throws Exception {
+ camelContext.stop();
+ }
+
+ public CamelContext getContext() {
+ //ApplicationContext context = ApplicationContextProvider.getApplicationContext();
+ //return context.getBean("camel-context", DefaultCamelContext.class);
+ return contextFactory.getContext(routeDAO);
+ }
+
+ protected List<CamelRoute> getRoutes() {
+ return routeDAO.findAll();
+ }
+
+ public void changeRoute(String routePath) {
+ try {
+ camelContext.removeRouteDefinitions(routes.getRoutes());
+ InputStream is = getClass().getResourceAsStream(routePath);
+ routes = getContext().loadRoutesDefinition(is);
+ camelContext.addRouteDefinitions(routes.getRoutes());
+ } catch (Exception e) {
+ // TODO Auto-generated catch block
+ LOG.error("Unexpected error", e);
+ }
+ }
+
+ protected void sendMessage(String uri, Object obj) {
+ Exchange exc = new DefaultExchange(getContext());
+ DefaultMessage m = new DefaultMessage();
+ m.setBody(obj);
+ exc.setIn(m);
+ ProducerTemplate template = getContext().createProducerTemplate();
+ template.send(uri, exc);
+ }
+
+ protected void sendMessage(String uri, Object obj, Map<String, Object> properties) {
+ Exchange exc = new DefaultExchange(getContext());
+
+ Iterator<Map.Entry<String, Object>> it = properties.entrySet().iterator();
+ while (it.hasNext()) {
+ Map.Entry<String, Object> property = it.next();
+ exc.setProperty(property.getKey(), property.getValue());
+ LOG.info("Added property {}", property.getKey());
+ }
+
+ DefaultMessage m = new DefaultMessage();
+ m.setBody(obj);
+ exc.setIn(m);
+ ProducerTemplate template = getContext().createProducerTemplate();
+ template.send(uri, exc);
+ }
+
+ protected PollingConsumer getConsumer(String uri) {
+ if (!knownUri.contains(uri)) {
+ knownUri.add(uri);
+ Endpoint endpoint = getContext().getEndpoint(uri);
+ PollingConsumer pollingConsumer = null;
+ try {
+ pollingConsumer = endpoint.createPollingConsumer();
+ consumerMap.put(uri, pollingConsumer);
+ pollingConsumer.start();
+ } catch (Exception ex) {
+ LOG.error("Unexpected error in Consumer creation ", ex);
+ }
+ return pollingConsumer;
+ } else {
+ return consumerMap.get(uri);
+ }
+ }
+
+ @Override
+ public Map.Entry<Long, List<PropagationStatus>> create(final UserTO userTO) {
+
+ return create(userTO, true, false, null, Collections.<String>emptySet());
+ }
+
+
+ public Map.Entry<Long, List<PropagationStatus>> create(final UserTO userTO, boolean storePassword) {
+
+ return create(userTO, storePassword, false, null, Collections.<String>emptySet());
+ }
+
+ @Override
+ public Map.Entry<Long, List<PropagationStatus>> create(final UserTO userTO, final boolean storePassword, boolean disablePwdPolicyCheck, Boolean enabled, Set<String> excludedResources) {
+ String uri = "direct:createPort";
+ PollingConsumer pollingConsumer = getConsumer(uri);
+
+ Map<String, Object> props = new HashMap<String, Object>();
+ props.put("storePassword", storePassword);
+ props.put("disablePwdPolicyCheck", disablePwdPolicyCheck);
+ props.put("enabled", enabled);
+ props.put("excludedResources", excludedResources);
+
+ sendMessage("direct:createUser", userTO, props);
+
+ Exchange o = pollingConsumer.receive();
+
+ if (o.getProperty(Exchange.EXCEPTION_CAUGHT) != null) {
+ throw (RuntimeException) o.getProperty(Exchange.EXCEPTION_CAUGHT);
+ }
+
+ return o.getIn().getBody(Map.Entry.class);
+ }
+
+ /**
+ *
+ * @param userMod
+ * @return
+ * @throws RuntimeException if problems arise on workflow update
+ */
+ @Override
+ public Map.Entry<Long, List<PropagationStatus>> update(final UserMod userMod) {
+ return update(userMod, false);
+ }
+
+
+ @Override
+ public Map.Entry<Long, List<PropagationStatus>> update(UserMod userMod, boolean removeMemberships) {
+ String uri = "direct:updatePort";
+ PollingConsumer pollingConsumer = getConsumer(uri);
+
+ Map<String, Object> props = new HashMap<String, Object>();
+ props.put("removeMemberships", removeMemberships);
+
+ sendMessage("direct:updateUser", userMod, props);
+
+ Exchange o = pollingConsumer.receive();
+
+ if (o.getProperty(Exchange.EXCEPTION_CAUGHT) != null) {
+ throw (RuntimeException) o.getProperty(Exchange.EXCEPTION_CAUGHT);
+ }
+
+ return o.getIn().getBody(Map.Entry.class);
+ }
+
+
+ @Override
+ public List<PropagationStatus> delete(final Long userId) {
+
+ return delete(userId, Collections.<String>emptySet());
+ }
+
+ @Override
+ public List<PropagationStatus> delete(final Long userId, Set<String> excludedResources) {
+ String uri = "direct:deletePort";
+ PollingConsumer pollingConsumer = getConsumer(uri);
+
+ Map<String, Object> props = new HashMap<String, Object>();
+ props.put("excludedResources", excludedResources);
+
+ sendMessage("direct:deleteUser", userId, props);
+
+ Exchange o = pollingConsumer.receive();
+
+ if (o.getProperty(Exchange.EXCEPTION_CAUGHT) != null) {
+ throw (RuntimeException) o.getProperty(Exchange.EXCEPTION_CAUGHT);
+ }
+
+ return o.getIn().getBody(List.class);
+ }
+
+ @Override
+ public Long unlink(final UserMod userMod) {
+ String uri = "direct:unlinkPort";
+ PollingConsumer pollingConsumer = getConsumer(uri);
+
+ sendMessage("direct:unlinkUser", userMod);
+
+ Exchange o = pollingConsumer.receive();
+
+ if (o.getProperty(Exchange.EXCEPTION_CAUGHT) != null) {
+ throw (RuntimeException) o.getProperty(Exchange.EXCEPTION_CAUGHT);
+ }
+
+ o.getIn().setBody((o.getIn().getBody(UserMod.class).getId()));
+ return o.getIn().getBody(Long.class);
+ }
+
+ @Override
+ public Map.Entry<Long, List<PropagationStatus>> activate(SyncopeUser user, StatusMod statusMod) {
+ String uri = "direct:statusPort";
+ PollingConsumer pollingConsumer = getConsumer(uri);
+
+ Map props = new HashMap<String, Object>();
+ props.put("token", statusMod.getToken());
+ props.put("user", user);
+ props.put("statusMod", statusMod);
+
+ if (statusMod.isOnSyncope()) {
+ sendMessage("direct:activateUser", user.getId(), props);
+ } else {
+ WorkflowResult<Long> updated = new WorkflowResult<Long>(user.getId(), null, statusMod.getType().name().toLowerCase());
+ sendMessage("direct:statusUser", updated, props);
+ }
+
+ Exchange o = pollingConsumer.receive();
+
+ if (o.getProperty(Exchange.EXCEPTION_CAUGHT) != null) {
+ throw (RuntimeException) o.getProperty(Exchange.EXCEPTION_CAUGHT);
+ }
+
+ return o.getIn().getBody(Map.Entry.class);
+ }
+
+ @Override
+ public Map.Entry<Long, List<PropagationStatus>> reactivate(SyncopeUser user, StatusMod statusMod) {
+ String uri = "direct:statusPort";
+ PollingConsumer pollingConsumer = getConsumer(uri);
+
+ Map props = new HashMap<String, Object>();
+ props.put("user", user);
+ props.put("statusMod", statusMod);
+
+ if (statusMod.isOnSyncope()) {
+ sendMessage("direct:reactivateUser", user.getId(), props);
+ } else {
+ WorkflowResult<Long> updated = new WorkflowResult<Long>(user.getId(), null, statusMod.getType().name().toLowerCase());
+ sendMessage("direct:statusUser", updated, props);
+ }
+
+ Exchange o = pollingConsumer.receive();
+
+ if (o.getProperty(Exchange.EXCEPTION_CAUGHT) != null) {
+ throw (RuntimeException) o.getProperty(Exchange.EXCEPTION_CAUGHT);
+ }
+
+ return o.getIn().getBody(Map.Entry.class);
+ }
+
+ @Override
+ public Map.Entry<Long, List<PropagationStatus>> suspend(SyncopeUser user, StatusMod statusMod) {
+
+ String uri = "direct:statusPort";
+ PollingConsumer pollingConsumer = getConsumer(uri);
+
+ Map props = new HashMap<String, Object>();
+ props.put("user", user);
+ props.put("statusMod", statusMod);
+
+ if (statusMod.isOnSyncope()) {
+ sendMessage("direct:suspendUser", user.getId(), props);
+ } else {
+ WorkflowResult<Long> updated = new WorkflowResult<Long>(user.getId(), null, statusMod.getType().name().toLowerCase());
+ sendMessage("direct:statusUser", updated, props);
+ }
+
+ Exchange o = pollingConsumer.receive();
+
+ if (o.getProperty(Exchange.EXCEPTION_CAUGHT) != null) {
+ throw (RuntimeException) o.getProperty(Exchange.EXCEPTION_CAUGHT);
+ }
+
+ return o.getIn().getBody(Map.Entry.class);
+ }
+
+ @Override
+ public Long link(UserMod subjectMod) {
+ String uri = "direct:linkPort";
+
+ PollingConsumer pollingConsumer = getConsumer(uri);
+
+ sendMessage("direct:linkUser", subjectMod);
+
+ Exchange o = pollingConsumer.receive();
+
+ if (o.getProperty(Exchange.EXCEPTION_CAUGHT) != null) {
+ throw (RuntimeException) o.getProperty(Exchange.EXCEPTION_CAUGHT);
+ }
+
+ o.getIn().setBody((o.getIn().getBody(UserMod.class).getId()));
+ return o.getIn().getBody(Long.class);
+ }
+
+ @Override
+ public List<PropagationStatus> deprovision(Long user, Collection<String> resources) {
+ String uri = "direct:deprovisionPort";
+
+ PollingConsumer pollingConsumer = getConsumer(uri);
+
+ Map props = new HashMap<String, Object>();
+ props.put("resources", resources);
+
+ sendMessage("direct:deprovisionUser", user, props);
+
+ Exchange o = pollingConsumer.receive();
+
+ if (o.getProperty(Exchange.EXCEPTION_CAUGHT) != null) {
+ throw (RuntimeException) o.getProperty(Exchange.EXCEPTION_CAUGHT);
+ }
+
+ return o.getIn().getBody(List.class);
+ }
+
+ @Override
+ public Map.Entry<Long, List<PropagationStatus>> updateInSync(UserMod userMod, Long id, SyncResult result, Boolean enabled, Set<String> excludedResources) {
+
+ String uri = "direct:updateSyncPort";
+ PollingConsumer pollingConsumer = getConsumer(uri);
+
+ Map<String, Object> props = new HashMap<String, Object>();
+ props.put("id", id);
+ props.put("result", result);
+ props.put("enabled", enabled);
+ props.put("excludedResources", excludedResources);
+
+ sendMessage("direct:updateSyncUser", userMod, props);
+
+ Exchange o = pollingConsumer.receive();
+ Exception e;
+ if ((e = (Exception) o.getProperty(Exchange.EXCEPTION_CAUGHT)) != null) {
+
+ LOG.error("Update of user {} failed, trying to sync its status anyway (if configured)", id, e);
+
+ result.setStatus(SyncResult.Status.FAILURE);
+ result.setMessage("Update failed, trying to sync status anyway (if configured)\n" + e.getMessage());
+
+ WorkflowResult<Map.Entry<UserMod, Boolean>> updated = new WorkflowResult<Map.Entry<UserMod, Boolean>>(
+ new AbstractMap.SimpleEntry<UserMod, Boolean>(userMod, false), new PropagationByResource(),
+ new HashSet<String>());
+ sendMessage("direct:syncUserStatus", updated, props);
+ o = pollingConsumer.receive();
+ }
+
+ return o.getIn().getBody(Map.Entry.class);
+ }
+
+ @Override
+ public void innerSuspend(SyncopeUser user, boolean suspend) {
+
+ String uri = "direct:suspendWFPort";
+ PollingConsumer pollingConsumer = getConsumer(uri);
+
+ Map<String, Object> props = new HashMap<String, Object>();
+ props.put("suspend", suspend);
+
+ sendMessage("direct:suspendUserWF", user, props);
+ Exchange o = pollingConsumer.receive();
+
+ if (o.getProperty(Exchange.EXCEPTION_CAUGHT) != null) {
+ throw (RuntimeException) o.getProperty(Exchange.EXCEPTION_CAUGHT);
+ }
+
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/syncope/blob/5b3b124a/core/src/main/java/org/apache/syncope/core/provisioning/camel/SyncopeCamelContext.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/syncope/core/provisioning/camel/SyncopeCamelContext.java b/core/src/main/java/org/apache/syncope/core/provisioning/camel/SyncopeCamelContext.java
new file mode 100644
index 0000000..6381649
--- /dev/null
+++ b/core/src/main/java/org/apache/syncope/core/provisioning/camel/SyncopeCamelContext.java
@@ -0,0 +1,137 @@
+/*
+ * 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;
+
+import java.io.ByteArrayInputStream;
+import java.io.InputStream;
+import java.net.URLDecoder;
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+import java.util.logging.Level;
+import javax.xml.bind.JAXBContext;
+import javax.xml.bind.JAXBElement;
+import javax.xml.bind.Unmarshaller;
+import javax.xml.parsers.DocumentBuilder;
+import javax.xml.parsers.DocumentBuilderFactory;
+import org.apache.camel.CamelContext;
+import org.apache.camel.model.Constants;
+import org.apache.camel.model.RouteDefinition;
+import org.apache.camel.spring.SpringCamelContext;
+import org.apache.syncope.core.persistence.beans.CamelRoute;
+import org.apache.syncope.core.persistence.dao.RouteDAO;
+import org.apache.syncope.core.util.ApplicationContextProvider;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.stereotype.Component;
+import org.w3c.dom.Document;
+import org.w3c.dom.Node;
+
+
+@Component
+public class SyncopeCamelContext{
+
+ private static final Logger LOG = LoggerFactory.getLogger(SyncopeCamelContext.class);
+
+ private CamelContext camelContext = null;
+
+ public SyncopeCamelContext() {
+ }
+
+ public CamelContext getContext(RouteDAO routeDAO){
+
+ if(camelContext == null) camelContext = new SpringCamelContext(ApplicationContextProvider.getApplicationContext());
+ if(camelContext.getRouteDefinitions().isEmpty()){
+
+ List<CamelRoute> crl = routeDAO.findAll();
+ LOG.info("{} route(s) are going to be loaded ", crl.size());
+ loadContext(routeDAO, crl);
+
+ try {
+ camelContext.start();
+ } catch (Exception ex) {
+ LOG.error("Error during staring camel context {}", ex);
+ }
+ }
+
+ return camelContext;
+ }
+
+ public void loadContext(RouteDAO routeDAO, List<CamelRoute> crl){
+
+ try {
+ DocumentBuilder dBuilder = DocumentBuilderFactory.newInstance().newDocumentBuilder();
+ JAXBContext jaxbContext = JAXBContext.newInstance(Constants.JAXB_CONTEXT_PACKAGES);
+ Unmarshaller unmarshaller = jaxbContext.createUnmarshaller();
+ List rds = new ArrayList();
+
+ for (int s = 0; s < crl.size(); s++) {
+
+ InputStream is = new ByteArrayInputStream( URLDecoder.decode(crl.get(s).getRouteContent(), "UTF-8").getBytes());
+ Document doc = dBuilder.parse(is);
+ doc.getDocumentElement().normalize();
+ Node routeEl = doc.getElementsByTagName("route").item(0);
+ JAXBElement obj = unmarshaller.unmarshal(routeEl, RouteDefinition.class);
+ //adding route definition to list
+ rds.add(obj.getValue());
+ }
+ camelContext.addRouteDefinitions(rds);
+ } catch (Exception ex) {
+ LOG.error("Error during loading camel context {}", ex);
+ }
+
+ }
+
+ public void reloadContext(RouteDAO routeDAO){
+
+ List<CamelRoute> crl = routeDAO.findAll();
+ if(camelContext == null) getContext(routeDAO);
+ else {
+ if( ! camelContext.getRouteDefinitions().isEmpty()){
+ for (Iterator<RouteDefinition> it = camelContext.getRouteDefinitions().iterator(); it.hasNext(); ) {
+ RouteDefinition ard = it.next();
+ it.remove();
+ }
+ }
+
+ loadContext(routeDAO, crl);
+ }
+ }
+
+ public void reloadContext(RouteDAO routeDAO, Long routeId){
+
+ if(camelContext == null) getContext(routeDAO);
+ else {
+ if( ! camelContext.getRouteDefinitions().isEmpty()){
+
+ camelContext.getRouteDefinitions().remove(routeId.intValue());
+ List<CamelRoute> crl = new ArrayList<CamelRoute>();
+ crl.add(routeDAO.find(routeId));
+ loadContext(routeDAO, crl);
+ }
+
+ }
+
+ }
+
+ public List<RouteDefinition> getDefinitions(){
+ return camelContext.getRouteDefinitions();
+ }
+}
http://git-wip-us.apache.org/repos/asf/syncope/blob/5b3b124a/core/src/main/java/org/apache/syncope/core/provisioning/camel/processors/DefaultRoleCreatePropagation.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/syncope/core/provisioning/camel/processors/DefaultRoleCreatePropagation.java b/core/src/main/java/org/apache/syncope/core/provisioning/camel/processors/DefaultRoleCreatePropagation.java
new file mode 100644
index 0000000..a6b40fb
--- /dev/null
+++ b/core/src/main/java/org/apache/syncope/core/provisioning/camel/processors/DefaultRoleCreatePropagation.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.List;
+import java.util.Map;
+import java.util.Set;
+import org.apache.camel.Exchange;
+import org.apache.camel.Processor;
+import org.apache.syncope.common.to.PropagationStatus;
+import org.apache.syncope.common.to.RoleTO;
+import org.apache.syncope.core.persistence.beans.PropagationTask;
+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.util.EntitlementUtil;
+import org.apache.syncope.core.workflow.WorkflowResult;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+
+public class DefaultRoleCreatePropagation implements Processor{
+
+ private static final Logger LOG = LoggerFactory.getLogger(DefaultRoleCreatePropagation.class);
+
+ @Autowired
+ protected PropagationManager propagationManager;
+ @Autowired
+ protected PropagationTaskExecutor taskExecutor;
+
+ @Override
+ public void process(Exchange exchange){
+
+ WorkflowResult<Long> created = (WorkflowResult) exchange.getIn().getBody();
+ RoleTO subject = exchange.getProperty("subject", RoleTO.class);
+ Set<String> excludedResource = exchange.getProperty("excludedResources", Set.class);
+
+ EntitlementUtil.extendAuthContext(created.getResult());
+
+ List<PropagationTask> tasks = propagationManager.getRoleCreateTaskIds(created, subject.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);
+ }
+
+ Map.Entry<Long, List<PropagationStatus>> result = new AbstractMap.SimpleEntry<Long, List<PropagationStatus>>(
+ created.getResult(), 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/DefaultRoleCreateSyncPropagation.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/syncope/core/provisioning/camel/processors/DefaultRoleCreateSyncPropagation.java b/core/src/main/java/org/apache/syncope/core/provisioning/camel/processors/DefaultRoleCreateSyncPropagation.java
new file mode 100644
index 0000000..ea8df72
--- /dev/null
+++ b/core/src/main/java/org/apache/syncope/core/provisioning/camel/processors/DefaultRoleCreateSyncPropagation.java
@@ -0,0 +1,79 @@
+package org.apache.syncope.core.provisioning.camel.processors;
+
+/*
+ * 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.Collections;
+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.to.RoleTO;
+import org.apache.syncope.core.propagation.PropagationTaskExecutor;
+import org.apache.syncope.core.propagation.impl.PropagationManager;
+import org.apache.syncope.core.workflow.WorkflowResult;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.apache.commons.lang3.StringUtils;
+import org.apache.syncope.common.to.AttributeTO;
+import org.apache.syncope.common.to.PropagationStatus;
+import org.apache.syncope.core.persistence.beans.PropagationTask;
+import org.apache.syncope.core.util.EntitlementUtil;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class DefaultRoleCreateSyncPropagation implements Processor{
+
+
+ @Autowired
+ protected PropagationManager propagationManager;
+ @Autowired
+ protected PropagationTaskExecutor taskExecutor;
+
+ private static final Logger LOG = LoggerFactory.getLogger(DefaultRoleCreateSyncPropagation.class);
+
+ @Override
+ public void process(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);
+
+ AttributeTO roleOwner = actual.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,
+ actual.getVirAttrs(), excludedResource);
+
+ taskExecutor.execute(tasks);
+
+ Map.Entry<Long, List<PropagationStatus>> result = new AbstractMap.SimpleEntry<Long, List<PropagationStatus>>(
+ created.getResult(), Collections.<PropagationStatus>emptyList());
+
+ 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/DefaultRoleDeletePropagation.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/syncope/core/provisioning/camel/processors/DefaultRoleDeletePropagation.java b/core/src/main/java/org/apache/syncope/core/provisioning/camel/processors/DefaultRoleDeletePropagation.java
new file mode 100644
index 0000000..1d2c20e
--- /dev/null
+++ b/core/src/main/java/org/apache/syncope/core/provisioning/camel/processors/DefaultRoleDeletePropagation.java
@@ -0,0 +1,100 @@
+/*
+ * 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.ArrayList;
+import java.util.List;
+import org.apache.camel.Exchange;
+import org.apache.camel.Processor;
+import org.apache.syncope.core.persistence.beans.PropagationTask;
+import org.apache.syncope.core.persistence.beans.role.SyncopeRole;
+import org.apache.syncope.core.persistence.dao.RoleDAO;
+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.RoleDataBinder;
+import org.apache.syncope.core.util.ApplicationContextProvider;
+import org.apache.syncope.core.workflow.WorkflowResult;
+import org.apache.syncope.core.workflow.role.RoleWorkflowAdapter;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+
+public class DefaultRoleDeletePropagation implements Processor{
+
+ private static final Logger LOG = LoggerFactory.getLogger(DefaultRoleDeletePropagation.class);
+ @Autowired
+ protected RoleWorkflowAdapter rwfAdapter;
+ @Autowired
+ protected PropagationManager propagationManager;
+ @Autowired
+ protected PropagationTaskExecutor taskExecutor;
+ @Autowired
+ protected RoleDAO roleDAO;
+ @Autowired
+ protected RoleDataBinder binder;
+
+ @Override
+ public void process(Exchange exchange) throws Exception {
+
+ Long subjectId = exchange.getIn().getBody(Long.class);
+
+ final List<SyncopeRole> toBeDeprovisioned = new ArrayList<SyncopeRole>();
+
+ final SyncopeRole syncopeRole = roleDAO.find(subjectId);
+
+ if (syncopeRole != null) {
+ toBeDeprovisioned.add(syncopeRole);
+
+ final List<SyncopeRole> descendants = roleDAO.findDescendants(toBeDeprovisioned.get(0));
+ if (descendants != null) {
+ 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()));
+ }
+
+ 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/5b3b124a/core/src/main/java/org/apache/syncope/core/provisioning/camel/processors/DefaultRoleDeprovisionPropagation.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/syncope/core/provisioning/camel/processors/DefaultRoleDeprovisionPropagation.java b/core/src/main/java/org/apache/syncope/core/provisioning/camel/processors/DefaultRoleDeprovisionPropagation.java
new file mode 100644
index 0000000..0f02258
--- /dev/null
+++ b/core/src/main/java/org/apache/syncope/core/provisioning/camel/processors/DefaultRoleDeprovisionPropagation.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.core.provisioning.camel.processors;
+
+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.core.persistence.beans.PropagationTask;
+import org.apache.syncope.core.persistence.beans.role.SyncopeRole;
+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.RoleDataBinder;
+import org.apache.syncope.core.util.ApplicationContextProvider;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+
+public class DefaultRoleDeprovisionPropagation implements Processor{
+
+ private static final Logger LOG = LoggerFactory.getLogger(DefaultUserDeprovisionPropagation.class);
+
+ @Autowired
+ protected PropagationManager propagationManager;
+ @Autowired
+ protected PropagationTaskExecutor taskExecutor;
+ @Autowired
+ protected RoleDataBinder binder;
+
+ @Override
+ public void process(Exchange exchange){
+
+ Long roleId = exchange.getIn().getBody(Long.class);
+ List<String> resources = exchange.getProperty("resources", List.class);
+
+ 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);
+ }
+
+ exchange.getOut().setBody(propagationReporter.getStatuses());
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/syncope/blob/5b3b124a/core/src/main/java/org/apache/syncope/core/provisioning/camel/processors/DefaultRoleUpdatePropagation.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/syncope/core/provisioning/camel/processors/DefaultRoleUpdatePropagation.java b/core/src/main/java/org/apache/syncope/core/provisioning/camel/processors/DefaultRoleUpdatePropagation.java
new file mode 100644
index 0000000..cc2fcc0
--- /dev/null
+++ b/core/src/main/java/org/apache/syncope/core/provisioning/camel/processors/DefaultRoleUpdatePropagation.java
@@ -0,0 +1,75 @@
+/*
+ * 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.RoleMod;
+import org.apache.syncope.common.to.PropagationStatus;
+import org.apache.syncope.core.persistence.beans.PropagationTask;
+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 DefaultRoleUpdatePropagation 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<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);
+ }
+
+ Map.Entry<Long, List<PropagationStatus>> result = new AbstractMap.SimpleEntry<Long, List<PropagationStatus>>(
+ updated.getResult(), 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/DefaultUserCreatePropagation.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/syncope/core/provisioning/camel/processors/DefaultUserCreatePropagation.java b/core/src/main/java/org/apache/syncope/core/provisioning/camel/processors/DefaultUserCreatePropagation.java
new file mode 100644
index 0000000..c71e3dc
--- /dev/null
+++ b/core/src/main/java/org/apache/syncope/core/provisioning/camel/processors/DefaultUserCreatePropagation.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.List;
+import java.util.Map;
+import java.util.Set;
+import org.apache.camel.Exchange;
+import org.apache.camel.Processor;
+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.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 DefaultUserCreatePropagation implements Processor{
+
+ private static final Logger LOG = LoggerFactory.getLogger(DefaultUserCreatePropagation.class);
+
+ @Autowired
+ protected PropagationManager propagationManager;
+ @Autowired
+ protected PropagationTaskExecutor taskExecutor;
+
+ @Override
+ public void process(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);
+ }
+
+ Map.Entry<Long, List<PropagationStatus>> result = new AbstractMap.SimpleEntry<Long, List<PropagationStatus>>(created.getResult().getKey(), 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/DefaultUserDeletePropagation.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/syncope/core/provisioning/camel/processors/DefaultUserDeletePropagation.java b/core/src/main/java/org/apache/syncope/core/provisioning/camel/processors/DefaultUserDeletePropagation.java
new file mode 100644
index 0000000..1afef83
--- /dev/null
+++ b/core/src/main/java/org/apache/syncope/core/provisioning/camel/processors/DefaultUserDeletePropagation.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.List;
+import java.util.Set;
+import org.apache.camel.Exchange;
+import org.apache.camel.Processor;
+import org.apache.syncope.core.persistence.beans.PropagationTask;
+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.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+
+
+public class DefaultUserDeletePropagation implements Processor{
+
+ private static final Logger LOG = LoggerFactory.getLogger(DefaultUserDeletePropagation.class);
+ @Autowired
+ protected PropagationManager propagationManager;
+ @Autowired
+ protected PropagationTaskExecutor taskExecutor;
+
+ @Override
+ public void process(Exchange exchange) throws Exception {
+
+ Long userId = (Long) exchange.getIn().getBody();
+ LOG.info("UserId {} ", userId);
+
+ 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(userId,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/5b3b124a/core/src/main/java/org/apache/syncope/core/provisioning/camel/processors/DefaultUserDeprovisionPropagation.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/syncope/core/provisioning/camel/processors/DefaultUserDeprovisionPropagation.java b/core/src/main/java/org/apache/syncope/core/provisioning/camel/processors/DefaultUserDeprovisionPropagation.java
new file mode 100644
index 0000000..f62e4b6
--- /dev/null
+++ b/core/src/main/java/org/apache/syncope/core/provisioning/camel/processors/DefaultUserDeprovisionPropagation.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.core.provisioning.camel.processors;
+
+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.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.rest.data.UserDataBinder;
+import org.apache.syncope.core.util.ApplicationContextProvider;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+
+public class DefaultUserDeprovisionPropagation implements Processor{
+
+ private static final Logger LOG = LoggerFactory.getLogger(DefaultUserDeprovisionPropagation.class);
+
+ @Autowired
+ protected PropagationManager propagationManager;
+ @Autowired
+ protected PropagationTaskExecutor taskExecutor;
+ @Autowired
+ protected UserDataBinder binder;
+
+ @Override
+ public void process(Exchange exchange){
+
+ Long userId = exchange.getIn().getBody(Long.class);
+ List<String> resources = exchange.getProperty("resources", List.class);
+
+ 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);
+ }
+
+ exchange.getOut().setBody(propagationReporter.getStatuses());
+ }
+
+}