You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@syncope.apache.org by md...@apache.org on 2015/03/18 09:49:13 UTC
[2/5] syncope git commit: [SYNCOPE-648]Merge from 1_2_X
http://git-wip-us.apache.org/repos/asf/syncope/blob/53721b82/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/sync/RolePushResultHandlerImpl.java
----------------------------------------------------------------------
diff --cc core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/sync/RolePushResultHandlerImpl.java
index d51b26f,0000000..c160556
mode 100644,000000..100644
--- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/sync/RolePushResultHandlerImpl.java
+++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/sync/RolePushResultHandlerImpl.java
@@@ -1,155 -1,0 +1,162 @@@
+/*
+ * 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.java.sync;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+import org.apache.syncope.common.lib.mod.RoleMod;
+import org.apache.syncope.common.lib.to.AbstractSubjectTO;
+import org.apache.syncope.common.lib.to.RoleTO;
++import org.apache.syncope.common.lib.types.AttributableType;
+import org.apache.syncope.common.lib.types.PropagationByResource;
+import org.apache.syncope.common.lib.types.ResourceOperation;
++import org.apache.syncope.core.persistence.api.entity.AttributableUtil;
+import org.apache.syncope.core.persistence.api.entity.Mapping;
+import org.apache.syncope.core.persistence.api.entity.MappingItem;
+import org.apache.syncope.core.persistence.api.entity.Subject;
+import org.apache.syncope.core.persistence.api.entity.role.Role;
+import org.apache.syncope.core.provisioning.api.TimeoutException;
+import org.apache.syncope.core.provisioning.api.sync.RolePushResultHandler;
+import org.identityconnectors.framework.common.objects.ConnectorObject;
+import org.identityconnectors.framework.common.objects.ObjectClass;
+import org.identityconnectors.framework.common.objects.Uid;
+
+public class RolePushResultHandlerImpl extends AbstractPushResultHandler implements RolePushResultHandler {
+
+ @Override
++ protected AttributableUtil getAttributableUtil() {
++ return attrUtilFactory.getInstance(AttributableType.ROLE);
++ }
++
++ @Override
+ protected Subject<?, ?, ?> deprovision(final Subject<?, ?, ?> sbj) {
+ final RoleTO before = roleTransfer.getRoleTO(Role.class.cast(sbj));
+
+ final List<String> noPropResources = new ArrayList<>(before.getResources());
+ noPropResources.remove(profile.getTask().getResource().getKey());
+
+ taskExecutor.execute(propagationManager.getRoleDeleteTaskIds(before.getKey(), noPropResources));
+
+ return roleDAO.authFetch(before.getKey());
+ }
+
+ @Override
+ protected Subject<?, ?, ?> provision(final Subject<?, ?, ?> sbj, final Boolean enabled) {
+ final RoleTO before = roleTransfer.getRoleTO(Role.class.cast(sbj));
+
+ final List<String> noPropResources = new ArrayList<>(before.getResources());
+ noPropResources.remove(profile.getTask().getResource().getKey());
+
+ final PropagationByResource propByRes = new PropagationByResource();
+ propByRes.add(ResourceOperation.CREATE, profile.getTask().getResource().getKey());
+
+ taskExecutor.execute(propagationManager.getRoleCreateTaskIds(
+ before.getKey(),
+ Collections.unmodifiableCollection(before.getVirAttrs()),
+ propByRes,
+ noPropResources));
+
+ return roleDAO.authFetch(before.getKey());
+ }
+
+ @Override
+ protected Subject<?, ?, ?> link(final Subject<?, ?, ?> sbj, final Boolean unlink) {
+ final RoleMod roleMod = new RoleMod();
+ roleMod.setKey(sbj.getKey());
+
+ if (unlink) {
+ roleMod.getResourcesToRemove().add(profile.getTask().getResource().getKey());
+ } else {
+ roleMod.getResourcesToAdd().add(profile.getTask().getResource().getKey());
+ }
+
+ rwfAdapter.update(roleMod);
+
+ return roleDAO.authFetch(sbj.getKey());
+ }
+
+ @Override
+ protected Subject<?, ?, ?> unassign(final Subject<?, ?, ?> sbj) {
+ final RoleMod roleMod = new RoleMod();
+ roleMod.setKey(sbj.getKey());
+ roleMod.getResourcesToRemove().add(profile.getTask().getResource().getKey());
+ rwfAdapter.update(roleMod);
+ return deprovision(sbj);
+ }
+
+ @Override
+ protected Subject<?, ?, ?> assign(final Subject<?, ?, ?> sbj, final Boolean enabled) {
+ final RoleMod roleMod = new RoleMod();
+ roleMod.setKey(sbj.getKey());
+ roleMod.getResourcesToAdd().add(profile.getTask().getResource().getKey());
+ rwfAdapter.update(roleMod);
+ return provision(sbj, enabled);
+ }
+
+ @Override
+ protected String getName(final Subject<?, ?, ?> subject) {
+ return Role.class.cast(subject).getName();
+ }
+
+ @Override
+ protected AbstractSubjectTO getSubjectTO(final long key) {
+ try {
+ return roleTransfer.getRoleTO(key);
+ } catch (Exception e) {
+ LOG.warn("Error retrieving user {}", key, e);
+ return null;
+ }
+ }
+
+ @Override
+ protected Subject<?, ?, ?> getSubject(final long key) {
+ try {
+ return roleDAO.authFetch(key);
+ } catch (Exception e) {
+ LOG.warn("Error retrieving role {}", key, e);
+ return null;
+ }
+ }
+
+ @Override
+ protected ConnectorObject getRemoteObject(final String accountId) {
+ ConnectorObject obj = null;
+
+ try {
+ final Uid uid = new Uid(accountId);
+
+ obj = profile.getConnector().getObject(
+ ObjectClass.GROUP,
+ uid,
+ profile.getConnector().getOperationOptions(Collections.<MappingItem>emptySet()));
+ } catch (TimeoutException toe) {
+ LOG.debug("Request timeout", toe);
+ throw toe;
+ } catch (RuntimeException ignore) {
+ LOG.debug("While resolving {}", accountId, ignore);
+ }
+ return obj;
+ }
+
+ @Override
+ protected Mapping<?> getMapping() {
+ return profile.getTask().getResource().getRmapping();
+ }
+}
http://git-wip-us.apache.org/repos/asf/syncope/blob/53721b82/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/sync/UserPushResultHandlerImpl.java
----------------------------------------------------------------------
diff --cc core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/sync/UserPushResultHandlerImpl.java
index 0c1ad8b,0000000..61637a4
mode 100644,000000..100644
--- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/sync/UserPushResultHandlerImpl.java
+++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/sync/UserPushResultHandlerImpl.java
@@@ -1,160 -1,0 +1,167 @@@
+/*
+ * 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.java.sync;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+import org.apache.syncope.common.lib.mod.UserMod;
+import org.apache.syncope.common.lib.to.AbstractSubjectTO;
+import org.apache.syncope.common.lib.to.UserTO;
++import org.apache.syncope.common.lib.types.AttributableType;
+import org.apache.syncope.common.lib.types.PropagationByResource;
+import org.apache.syncope.common.lib.types.ResourceOperation;
++import org.apache.syncope.core.persistence.api.entity.AttributableUtil;
+import org.apache.syncope.core.persistence.api.entity.Mapping;
+import org.apache.syncope.core.persistence.api.entity.MappingItem;
+import org.apache.syncope.core.persistence.api.entity.Subject;
+import org.apache.syncope.core.persistence.api.entity.user.User;
+import org.apache.syncope.core.provisioning.api.TimeoutException;
+import org.apache.syncope.core.provisioning.api.sync.UserPushResultHandler;
+import org.identityconnectors.framework.common.objects.ConnectorObject;
+import org.identityconnectors.framework.common.objects.ObjectClass;
+import org.identityconnectors.framework.common.objects.Uid;
+
+public class UserPushResultHandlerImpl extends AbstractPushResultHandler implements UserPushResultHandler {
+
+ @Override
++ protected AttributableUtil getAttributableUtil() {
++ return attrUtilFactory.getInstance(AttributableType.USER);
++ }
++
++ @Override
+ protected Subject<?, ?, ?> deprovision(final Subject<?, ?, ?> sbj) {
+ final UserTO before = userTransfer.getUserTO(sbj.getKey());
+
+ final List<String> noPropResources = new ArrayList<>(before.getResources());
+ noPropResources.remove(profile.getTask().getResource().getKey());
+
+ taskExecutor.execute(propagationManager.getUserDeleteTaskIds(before.getKey(),
+ Collections.singleton(profile.getTask().getResource().getKey()), noPropResources));
+
+ return userDAO.authFetch(before.getKey());
+ }
+
+ @Override
+ protected Subject<?, ?, ?> provision(final Subject<?, ?, ?> sbj, final Boolean enabled) {
+ final UserTO before = userTransfer.getUserTO(sbj.getKey());
+
+ final List<String> noPropResources = new ArrayList<>(before.getResources());
+ noPropResources.remove(profile.getTask().getResource().getKey());
+
+ final PropagationByResource propByRes = new PropagationByResource();
+ propByRes.add(ResourceOperation.CREATE, profile.getTask().getResource().getKey());
+
+ taskExecutor.execute(propagationManager.getUserCreateTaskIds(
+ before.getKey(),
+ enabled,
+ propByRes,
+ null,
+ Collections.unmodifiableCollection(before.getVirAttrs()),
+ Collections.unmodifiableCollection(before.getMemberships()),
+ noPropResources));
+
+ return userDAO.authFetch(before.getKey());
+ }
+
+ @Override
+ protected Subject<?, ?, ?> link(final Subject<?, ?, ?> sbj, final Boolean unlink) {
+ final UserMod userMod = new UserMod();
+ userMod.setKey(sbj.getKey());
+
+ if (unlink) {
+ userMod.getResourcesToRemove().add(profile.getTask().getResource().getKey());
+ } else {
+ userMod.getResourcesToAdd().add(profile.getTask().getResource().getKey());
+ }
+
+ uwfAdapter.update(userMod);
+
+ return userDAO.authFetch(userMod.getKey());
+ }
+
+ @Override
+ protected Subject<?, ?, ?> unassign(final Subject<?, ?, ?> sbj) {
+ final UserMod userMod = new UserMod();
+ userMod.setKey(sbj.getKey());
+ userMod.getResourcesToRemove().add(profile.getTask().getResource().getKey());
+ uwfAdapter.update(userMod);
+ return deprovision(sbj);
+ }
+
+ @Override
+ protected Subject<?, ?, ?> assign(final Subject<?, ?, ?> sbj, final Boolean enabled) {
+ final UserMod userMod = new UserMod();
+ userMod.setKey(sbj.getKey());
+ userMod.getResourcesToAdd().add(profile.getTask().getResource().getKey());
+ uwfAdapter.update(userMod);
+ return provision(sbj, enabled);
+ }
+
+ @Override
+ protected String getName(final Subject<?, ?, ?> subject) {
+ return User.class.cast(subject).getUsername();
+ }
+
+ @Override
+ protected AbstractSubjectTO getSubjectTO(final long key) {
+ try {
+ return userTransfer.getUserTO(key);
+ } catch (Exception e) {
+ LOG.warn("Error retrieving user {}", key, e);
+ return null;
+ }
+ }
+
+ @Override
+ protected Subject<?, ?, ?> getSubject(final long key) {
+ try {
+ return userDAO.authFetch(key);
+ } catch (Exception e) {
+ LOG.warn("Error retrieving user {}", key, e);
+ return null;
+ }
+ }
+
+ @Override
+ protected ConnectorObject getRemoteObject(final String accountId) {
+ ConnectorObject obj = null;
+
+ try {
+ final Uid uid = new Uid(accountId);
+
+ obj = profile.getConnector().getObject(
+ ObjectClass.ACCOUNT,
+ uid,
+ profile.getConnector().getOperationOptions(Collections.<MappingItem>emptySet()));
+
+ } catch (TimeoutException toe) {
+ LOG.debug("Request timeout", toe);
+ throw toe;
+ } catch (RuntimeException ignore) {
+ LOG.debug("While resolving {}", accountId, ignore);
+ }
+ return obj;
+ }
+
+ @Override
+ protected Mapping<?> getMapping() {
+ return profile.getTask().getResource().getUmapping();
+ }
+}
http://git-wip-us.apache.org/repos/asf/syncope/blob/53721b82/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/AbstractTaskITCase.java
----------------------------------------------------------------------
diff --cc fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/AbstractTaskITCase.java
index 6ba1dd8,0000000..669d088
mode 100644,000000..100644
--- a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/AbstractTaskITCase.java
+++ b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/AbstractTaskITCase.java
@@@ -1,137 -1,0 +1,155 @@@
+/*
+ * 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.fit.core.reference;
+
++import static org.apache.syncope.fit.core.reference.AbstractITCase.taskService;
+import static org.junit.Assert.assertEquals;
++import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.fail;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.concurrent.Callable;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+import java.util.concurrent.Future;
+import java.util.concurrent.TimeUnit;
+import org.apache.syncope.common.lib.to.AbstractTaskTO;
++import org.apache.syncope.common.lib.to.NotificationTaskTO;
++import org.apache.syncope.common.lib.to.PagedResult;
+import org.apache.syncope.common.lib.to.TaskExecTO;
+import org.apache.syncope.common.lib.to.UserTO;
++import org.apache.syncope.common.lib.types.TaskType;
+
+public abstract class AbstractTaskITCase extends AbstractITCase {
+
+ protected static final Long SYNC_TASK_ID = 4L;
+
+ protected static final Long SCHED_TASK_ID = 5L;
+
+ protected static class ThreadExec implements Callable<TaskExecTO> {
+
+ private final AbstractTaskITCase test;
+
+ private final Long taskKey;
+
+ private final int maxWaitSeconds;
+
+ private final boolean dryRun;
+
+ public ThreadExec(AbstractTaskITCase test, Long taskKey, int maxWaitSeconds, boolean dryRun) {
+ this.test = test;
+ this.taskKey = taskKey;
+ this.maxWaitSeconds = maxWaitSeconds;
+ this.dryRun = dryRun;
+ }
+
+ @Override
+ public TaskExecTO call() throws Exception {
+ return test.execSyncTask(taskKey, maxWaitSeconds, dryRun);
+ }
+ }
+
+ /**
+ * Remove initial and synchronized users to make test re-runnable.
+ */
+ protected void removeTestUsers() {
+ for (int i = 0; i < 10; i++) {
+ String cUserName = "test" + i;
+ try {
+ UserTO cUserTO = readUser(cUserName);
+ userService.delete(cUserTO.getKey());
+ } catch (Exception e) {
+ // Ignore
+ }
+ }
+ }
+
+ protected TaskExecTO execSyncTask(final Long taskKey, final int maxWaitSeconds, final boolean dryRun) {
+ AbstractTaskTO taskTO = taskService.read(taskKey);
+ assertNotNull(taskTO);
+ assertNotNull(taskTO.getExecutions());
+
+ int preSyncSize = taskTO.getExecutions().size();
+ TaskExecTO execution = taskService.execute(taskTO.getKey(), dryRun);
+ assertEquals("JOB_FIRED", execution.getStatus());
+
+ int i = 0;
+ int maxit = maxWaitSeconds;
+
+ // wait for sync completion (executions incremented)
+ do {
+ try {
+ Thread.sleep(1000);
+ } catch (InterruptedException e) {
+ }
+
+ taskTO = taskService.read(taskTO.getKey());
+
+ assertNotNull(taskTO);
+ assertNotNull(taskTO.getExecutions());
+
+ i++;
+ } while (preSyncSize == taskTO.getExecutions().size() && i < maxit);
+ if (i == maxit) {
+ fail("Timeout when executing task " + taskKey);
+ }
+ return taskTO.getExecutions().get(taskTO.getExecutions().size() - 1);
+ }
+
+ protected Map<Long, TaskExecTO> execSyncTasks(
+ final Set<Long> taskKeys, final int maxWaitSeconds, final boolean dryRun) throws Exception {
+
+ final ExecutorService service = Executors.newFixedThreadPool(taskKeys.size());
+ final List<Future<TaskExecTO>> futures = new ArrayList<>();
+
+ for (Long key : taskKeys) {
+ futures.add(service.submit(new ThreadExec(this, key, maxWaitSeconds, dryRun)));
+ }
+
+ final Map<Long, TaskExecTO> res = new HashMap<>();
+
+ for (Future<TaskExecTO> future : futures) {
+ TaskExecTO taskExecTO = future.get(100, TimeUnit.SECONDS);
+ res.put(taskExecTO.getTask(), taskExecTO);
+ }
+
+ service.shutdownNow();
+
+ return res;
+ }
+
++ protected NotificationTaskTO findNotificationTaskBySender(final String sender) {
++ PagedResult<NotificationTaskTO> tasks = taskService.list(TaskType.NOTIFICATION);
++ assertNotNull(tasks);
++ assertFalse(tasks.getResult().isEmpty());
++ NotificationTaskTO taskTO = null;
++ for (NotificationTaskTO task : tasks.getResult()) {
++ if (sender.equals(task.getSender())) {
++ taskTO = task;
++ }
++ }
++ return taskTO;
++ }
++
+}
http://git-wip-us.apache.org/repos/asf/syncope/blob/53721b82/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/NotificationTaskITCase.java
----------------------------------------------------------------------
diff --cc fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/NotificationTaskITCase.java
index 87a49fb,0000000..ee75de9
mode 100644,000000..100644
--- a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/NotificationTaskITCase.java
+++ b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/NotificationTaskITCase.java
@@@ -1,155 -1,0 +1,140 @@@
+/*
+ * 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.fit.core.reference;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+
+import javax.ws.rs.core.Response;
+import org.apache.syncope.client.lib.SyncopeClient;
+import org.apache.syncope.common.lib.to.MembershipTO;
+import org.apache.syncope.common.lib.to.NotificationTO;
+import org.apache.syncope.common.lib.to.NotificationTaskTO;
- import org.apache.syncope.common.lib.to.PagedResult;
+import org.apache.syncope.common.lib.to.TaskExecTO;
+import org.apache.syncope.common.lib.to.UserTO;
+import org.apache.syncope.common.lib.types.IntMappingType;
- import org.apache.syncope.common.lib.types.TaskType;
+import org.apache.syncope.common.lib.types.TraceLevel;
+import org.apache.syncope.common.rest.api.service.NotificationService;
+import org.junit.FixMethodOrder;
+import org.junit.Test;
+import org.junit.runners.MethodSorters;
+
+@FixMethodOrder(MethodSorters.JVM)
+public class NotificationTaskITCase extends AbstractTaskITCase {
+
+ @Test
+ public void issueSYNCOPE81() {
+ String sender = "syncope81@syncope.apache.org";
+ createNotificationTask(sender);
+ NotificationTaskTO taskTO = findNotificationTaskBySender(sender);
+ assertNotNull(taskTO);
+
+ assertTrue(taskTO.getExecutions().isEmpty());
+
+ // generate an execution in order to verify the deletion of a notification task with one or more executions
+ TaskExecTO execution = taskService.execute(taskTO.getKey(), false);
+ assertEquals("NOT_SENT", execution.getStatus());
+
+ int i = 0;
+ int maxit = 50;
+ int executions = 0;
+
+ // wait for task exec completion (executions incremented)
+ do {
+ try {
+ Thread.sleep(1000);
+ } catch (InterruptedException e) {
+ }
+
+ taskTO = taskService.read(taskTO.getKey());
+
+ assertNotNull(taskTO);
+ assertNotNull(taskTO.getExecutions());
+
+ i++;
+ } while (executions == taskTO.getExecutions().size() && i < maxit);
+
+ assertFalse(taskTO.getExecutions().isEmpty());
+
+ taskService.delete(taskTO.getKey());
+ }
+
+ @Test
+ public void issueSYNCOPE86() {
+ // 1. create notification task
+ String sender = "syncope86@syncope.apache.org";
+ createNotificationTask(sender);
+
+ // 2. get NotificationTaskTO for user just created
+ NotificationTaskTO taskTO = findNotificationTaskBySender(sender);
+ assertNotNull(taskTO);
+ assertTrue(taskTO.getExecutions().isEmpty());
+
+ try {
+ // 3. execute the generated NotificationTask
+ TaskExecTO execution = taskService.execute(taskTO.getKey(), false);
+ assertNotNull(execution);
+
+ // 4. verify
+ taskTO = taskService.read(taskTO.getKey());
+ assertNotNull(taskTO);
+ assertEquals(1, taskTO.getExecutions().size());
+ } finally {
+ // Remove execution to make test re-runnable
+ taskService.deleteExecution(taskTO.getExecutions().get(0).getKey());
+ }
+ }
+
- private NotificationTaskTO findNotificationTaskBySender(final String sender) {
- PagedResult<NotificationTaskTO> tasks = taskService.list(TaskType.NOTIFICATION);
- assertNotNull(tasks);
- assertFalse(tasks.getResult().isEmpty());
- NotificationTaskTO taskTO = null;
- for (NotificationTaskTO task : tasks.getResult()) {
- if (sender.equals(task.getSender())) {
- taskTO = task;
- }
- }
- return taskTO;
- }
-
+ private void createNotificationTask(final String sender) {
+ // 1. Create notification
+ NotificationTO notification = new NotificationTO();
+ notification.setTraceLevel(TraceLevel.FAILURES);
+ notification.getEvents().add("[REST]:[UserLogic]:[]:[create]:[SUCCESS]");
+
+ notification.setUserAbout(SyncopeClient.getUserSearchConditionBuilder().hasRoles(7L).query());
+
+ notification.setRecipients(SyncopeClient.getUserSearchConditionBuilder().hasRoles(8L).query());
+ notification.setSelfAsRecipient(true);
+
+ notification.setRecipientAttrName("email");
+ notification.setRecipientAttrType(IntMappingType.UserPlainSchema);
+
+ notification.setSender(sender);
+ String subject = "Test notification";
+ notification.setSubject(subject);
+ notification.setTemplate("optin");
+ notification.setActive(true);
+
+ Response response = notificationService.create(notification);
+ notification = getObject(response.getLocation(), NotificationService.class, NotificationTO.class);
+ assertNotNull(notification);
+
+ // 2. create user
+ UserTO userTO = UserITCase.getUniqueSampleTO("syncope@syncope.apache.org");
+ MembershipTO membershipTO = new MembershipTO();
+ membershipTO.setRoleId(7);
+ userTO.getMemberships().add(membershipTO);
+
+ userTO = createUser(userTO);
+ assertNotNull(userTO);
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/syncope/blob/53721b82/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/PushTaskITCase.java
----------------------------------------------------------------------
diff --cc fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/PushTaskITCase.java
index d7d354f,0000000..3427a1d
mode 100644,000000..100644
--- a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/PushTaskITCase.java
+++ b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/PushTaskITCase.java
@@@ -1,353 -1,0 +1,401 @@@
+/*
+ * 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.fit.core.reference;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+import javax.ws.rs.core.Response;
+import org.apache.syncope.client.lib.SyncopeClient;
+import org.apache.syncope.common.lib.to.AbstractTaskTO;
+import org.apache.syncope.common.lib.to.MappingItemTO;
+import org.apache.syncope.common.lib.to.MappingTO;
++import org.apache.syncope.common.lib.to.NotificationTO;
++import org.apache.syncope.common.lib.to.NotificationTaskTO;
+import org.apache.syncope.common.lib.to.PagedResult;
+import org.apache.syncope.common.lib.to.PlainSchemaTO;
+import org.apache.syncope.common.lib.to.PushTaskTO;
+import org.apache.syncope.common.lib.to.ResourceTO;
+import org.apache.syncope.common.lib.to.RoleTO;
+import org.apache.syncope.common.lib.to.TaskExecTO;
+import org.apache.syncope.common.lib.types.AttrSchemaType;
+import org.apache.syncope.common.lib.types.AttributableType;
+import org.apache.syncope.common.lib.types.IntMappingType;
+import org.apache.syncope.common.lib.types.MappingPurpose;
+import org.apache.syncope.common.lib.types.MatchingRule;
+import org.apache.syncope.common.lib.types.PropagationTaskExecStatus;
+import org.apache.syncope.common.lib.types.SchemaType;
+import org.apache.syncope.common.lib.types.SubjectType;
+import org.apache.syncope.common.lib.types.TaskType;
++import org.apache.syncope.common.lib.types.TraceLevel;
+import org.apache.syncope.common.lib.types.UnmatchingRule;
++import org.apache.syncope.common.rest.api.service.NotificationService;
+import org.apache.syncope.common.rest.api.service.ResourceService;
+import org.apache.syncope.common.rest.api.service.TaskService;
+import org.junit.FixMethodOrder;
+import org.junit.Test;
+import org.junit.runners.MethodSorters;
+import org.springframework.jdbc.core.JdbcTemplate;
+
+@FixMethodOrder(MethodSorters.JVM)
+public class PushTaskITCase extends AbstractTaskITCase {
+
+ @Test
+ public void getPushActionsClasses() {
+ List<String> actions = syncopeService.info().getPushActions();
+ assertNotNull(actions);
+ }
+
+ @Test
+ public void read() {
+ PushTaskTO pushTaskTO = taskService.<PushTaskTO>read(17L);
+ assertEquals(UnmatchingRule.ASSIGN, pushTaskTO.getUnmatchingRule());
+ assertEquals(MatchingRule.UPDATE, pushTaskTO.getMatchingRule());
+ }
+
+ @Test
+ public void list() {
+ final PagedResult<PushTaskTO> tasks = taskService.list(TaskType.PUSH);
+ assertFalse(tasks.getResult().isEmpty());
+ for (AbstractTaskTO task : tasks.getResult()) {
+ if (!(task instanceof PushTaskTO)) {
+ fail();
+ }
+ }
+ }
+
+ @Test
+ public void createPushTask() {
+ PushTaskTO task = new PushTaskTO();
+ task.setName("Test create Push");
+ task.setResource(RESOURCE_NAME_WS2);
+ task.setUserFilter(
+ SyncopeClient.getUserSearchConditionBuilder().hasNotResources(RESOURCE_NAME_TESTDB2).query());
+ task.setRoleFilter(
+ SyncopeClient.getRoleSearchConditionBuilder().isNotNull("cool").query());
+ task.setMatchingRule(MatchingRule.LINK);
+
+ final Response response = taskService.create(task);
+ final PushTaskTO actual = getObject(response.getLocation(), TaskService.class, PushTaskTO.class);
+ assertNotNull(actual);
+
+ task = taskService.read(actual.getKey());
+ assertNotNull(task);
+ assertEquals(task.getKey(), actual.getKey());
+ assertEquals(task.getJobClassName(), actual.getJobClassName());
+ assertEquals(task.getUserFilter(), actual.getUserFilter());
+ assertEquals(task.getRoleFilter(), actual.getRoleFilter());
+ assertEquals(UnmatchingRule.ASSIGN, actual.getUnmatchingRule());
+ assertEquals(MatchingRule.LINK, actual.getMatchingRule());
+ }
+
+ @Test
+ public void pushMatchingUnmatchingRoles() {
+ assertFalse(roleService.read(3L).getResources().contains(RESOURCE_NAME_LDAP));
+
+ execSyncTask(23L, 50, false);
+
+ assertNotNull(resourceService.getConnectorObject(RESOURCE_NAME_LDAP, SubjectType.ROLE, 3L));
+ assertTrue(roleService.read(3L).getResources().contains(RESOURCE_NAME_LDAP));
+
+ execSyncTask(23L, 50, false);
+
+ assertNotNull(resourceService.getConnectorObject(RESOURCE_NAME_LDAP, SubjectType.ROLE, 3L));
+ assertFalse(roleService.read(3L).getResources().contains(RESOURCE_NAME_LDAP));
+ }
+
+ @Test
+ public void pushUnmatchingUsers() throws Exception {
+ assertFalse(userService.read(2L).getResources().contains(RESOURCE_NAME_TESTDB2));
+ assertFalse(userService.read(3L).getResources().contains(RESOURCE_NAME_TESTDB2));
+ assertFalse(userService.read(4L).getResources().contains(RESOURCE_NAME_TESTDB2));
+ assertTrue(userService.read(5L).getResources().contains(RESOURCE_NAME_TESTDB2));
+
+ final JdbcTemplate jdbcTemplate = new JdbcTemplate(testDataSource);
+ assertEquals(0, jdbcTemplate.queryForList("SELECT ID FROM test2 WHERE ID='puccini'").size());
+
+ // ------------------------------------------
+ // Unmatching --> Assign --> dryRuyn
+ // ------------------------------------------
+ execSyncTask(13L, 50, true);
+ assertEquals(0, jdbcTemplate.queryForList("SELECT ID FROM test2 WHERE ID='vivaldi'").size());
+ assertFalse(userService.read(3L).getResources().contains(RESOURCE_NAME_TESTDB2));
+ // ------------------------------------------
+
+ final Set<Long> pushTaskIds = new HashSet<>();
+ pushTaskIds.add(13L);
+ pushTaskIds.add(14L);
+ pushTaskIds.add(15L);
+ pushTaskIds.add(16L);
+ execSyncTasks(pushTaskIds, 50, false);
+
+ // ------------------------------------------
+ // Unatching --> Ignore
+ // ------------------------------------------
+ assertEquals(1, jdbcTemplate.queryForList("SELECT ID FROM test2 WHERE ID='verdi'").size());
+ assertFalse(userService.read(2L).getResources().contains(RESOURCE_NAME_TESTDB2));
+ // ------------------------------------------
+
+ // ------------------------------------------
+ // Unmatching --> Assign
+ // ------------------------------------------
+ assertEquals(1, jdbcTemplate.queryForList("SELECT ID FROM test2 WHERE ID='vivaldi'").size());
+ assertTrue(userService.read(3L).getResources().contains(RESOURCE_NAME_TESTDB2));
+ jdbcTemplate.execute("DELETE FROM test2 WHERE ID='vivaldi'");
+ // ------------------------------------------
+
+ // ------------------------------------------
+ // Unmatching --> Provision
+ // ------------------------------------------
+ assertEquals(1, jdbcTemplate.queryForList("SELECT ID FROM test2 WHERE ID='bellini'").size());
+ assertFalse(userService.read(4L).getResources().contains(RESOURCE_NAME_TESTDB2));
+ jdbcTemplate.execute("DELETE FROM test2 WHERE ID='bellini'");
+ // ------------------------------------------
+
+ // ------------------------------------------
+ // Unmatching --> Unlink
+ // ------------------------------------------
+ assertEquals(0, jdbcTemplate.queryForList("SELECT ID FROM test2 WHERE ID='puccini'").size());
+ assertFalse(userService.read(5L).getResources().contains(RESOURCE_NAME_TESTDB2));
+ // ------------------------------------------
+ }
+
+ @Test
+ public void pushMatchingUser() throws Exception {
+ assertTrue(userService.read(1L).getResources().contains(RESOURCE_NAME_TESTDB2));
+ assertFalse(userService.read(2L).getResources().contains(RESOURCE_NAME_TESTDB2));
+
+ final JdbcTemplate jdbcTemplate = new JdbcTemplate(testDataSource);
+ assertEquals(1, jdbcTemplate.queryForList("SELECT ID FROM test2 WHERE ID='verdi'").size());
+ assertEquals(1, jdbcTemplate.queryForList("SELECT ID FROM test2 WHERE ID='rossini'").size());
+
+ // ------------------------------------------
+ // Matching --> Deprovision --> dryRuyn
+ // ------------------------------------------
+ execSyncTask(19L, 50, true);
+ assertTrue(userService.read(1L).getResources().contains(RESOURCE_NAME_TESTDB2));
+ assertEquals(1, jdbcTemplate.queryForList("SELECT ID FROM test2 WHERE ID='rossini'").size());
+ // ------------------------------------------
+
+ final Set<Long> pushTaskIds = new HashSet<>();
+ pushTaskIds.add(18L);
+ pushTaskIds.add(19L);
+ pushTaskIds.add(16L);
+
+ execSyncTasks(pushTaskIds, 50, false);
+
+ // ------------------------------------------
+ // Matching --> Deprovision && Ignore
+ // ------------------------------------------
+ assertFalse(userService.read(2L).getResources().contains(RESOURCE_NAME_TESTDB2));
+ // DELETE Capability not available ....
+ assertEquals(1, jdbcTemplate.queryForList("SELECT ID FROM test2 WHERE ID='verdi'").size());
+ // ------------------------------------------
+
+ // ------------------------------------------
+ // Matching --> Unassign
+ // ------------------------------------------
+ assertFalse(userService.read(1L).getResources().contains(RESOURCE_NAME_TESTDB2));
+ // DELETE Capability not available ....
+ assertEquals(1, jdbcTemplate.queryForList("SELECT ID FROM test2 WHERE ID='rossini'").size());
+ // ------------------------------------------
+
+ // ------------------------------------------
+ // Matching --> Link
+ // ------------------------------------------
+ execSyncTask(20L, 50, false);
+ assertTrue(userService.read(2L).getResources().contains(RESOURCE_NAME_TESTDB2));
+ assertEquals(1, jdbcTemplate.queryForList("SELECT ID FROM test2 WHERE ID='verdi'").size());
+ // ------------------------------------------
+
+ pushTaskIds.clear();
+ pushTaskIds.add(21L);
+ pushTaskIds.add(22L);
+
+ execSyncTasks(pushTaskIds, 50, false);
+
+ // ------------------------------------------
+ // Matching --> Unlink && Update
+ // ------------------------------------------
+ assertFalse(userService.read(2L).getResources().contains(RESOURCE_NAME_TESTDB2));
+ assertEquals(1, jdbcTemplate.queryForList("SELECT ID FROM test2 WHERE ID='verdi'").size());
+ // ------------------------------------------
+ }
+
+ @Test
+ public void issueSYNCOPE598() {
+ // create a new role schema
+ final PlainSchemaTO schemaTO = new PlainSchemaTO();
+ schemaTO.setKey("LDAPGroupName" + getUUIDString());
+ schemaTO.setType(AttrSchemaType.String);
+ schemaTO.setMandatoryCondition("true");
+
+ final PlainSchemaTO newPlainSchemaTO = createSchema(AttributableType.ROLE, SchemaType.PLAIN, schemaTO);
+ assertEquals(schemaTO, newPlainSchemaTO);
+
+ // create a new sample role
+ RoleTO roleTO = new RoleTO();
+ roleTO.setName("all" + getUUIDString());
+ roleTO.setParent(8L);
+
+ roleTO.getRPlainAttrTemplates().add(newPlainSchemaTO.getKey());
+ roleTO.getPlainAttrs().add(attrTO(newPlainSchemaTO.getKey(), "all"));
+
+ roleTO = createRole(roleTO);
+ assertNotNull(roleTO);
+
+ String resourceName = "resource-ldap-roleonly";
+ ResourceTO newResourceTO = null;
+
+ try {
+ // Create resource ad-hoc
+ ResourceTO resourceTO = new ResourceTO();
+ resourceTO.setKey(resourceName);
+ resourceTO.setConnectorId(105L);
+
+ final MappingTO umapping = new MappingTO();
+ MappingItemTO item = new MappingItemTO();
+ item.setIntMappingType(IntMappingType.Username);
+ item.setExtAttrName("cn");
+ item.setAccountid(true);
+ item.setPurpose(MappingPurpose.PROPAGATION);
+ item.setMandatoryCondition("true");
+ umapping.setAccountIdItem(item);
+
+ item = new MappingItemTO();
+ item.setIntMappingType(IntMappingType.UserPlainSchema);
+ item.setExtAttrName("surname");
+ item.setIntAttrName("sn");
+ item.setPurpose(MappingPurpose.BOTH);
+ umapping.addItem(item);
+
+ item = new MappingItemTO();
+ item.setIntMappingType(IntMappingType.UserPlainSchema);
+ item.setExtAttrName("email");
+ item.setIntAttrName("mail");
+ item.setPurpose(MappingPurpose.BOTH);
+ umapping.addItem(item);
+
+ item = new MappingItemTO();
+ item.setIntMappingType(IntMappingType.Password);
+ item.setPassword(true);
+ item.setPurpose(MappingPurpose.BOTH);
+ item.setMandatoryCondition("true");
+ umapping.addItem(item);
+
+ umapping.setAccountLink("'cn=' + username + ',ou=people,o=isp'");
+
+ final MappingTO rmapping = new MappingTO();
+
+ item = new MappingItemTO();
+ item.setIntMappingType(IntMappingType.RolePlainSchema);
+ item.setExtAttrName("cn");
+ item.setIntAttrName(newPlainSchemaTO.getKey());
+ item.setAccountid(true);
+ item.setPurpose(MappingPurpose.BOTH);
+ rmapping.setAccountIdItem(item);
+
+ rmapping.setAccountLink("'cn=' + " + newPlainSchemaTO.getKey() + " + ',ou=groups,o=isp'");
+
+ resourceTO.setRmapping(rmapping);
+
+ Response response = resourceService.create(resourceTO);
+ newResourceTO = getObject(response.getLocation(), ResourceService.class, ResourceTO.class);
+
+ assertNotNull(newResourceTO);
+ assertNull(newResourceTO.getUmapping());
+ assertNotNull(newResourceTO.getRmapping());
+
+ // create push task ad-hoc
+ final PushTaskTO task = new PushTaskTO();
+ task.setName("issueSYNCOPE598");
+ task.setResource(resourceName);
+ task.setPerformCreate(true);
+ task.setPerformDelete(true);
+ task.setPerformUpdate(true);
+ task.setUnmatchingRule(UnmatchingRule.ASSIGN);
+ task.setMatchingRule(MatchingRule.UPDATE);
+
+ response = taskService.create(task);
+ final PushTaskTO push = getObject(response.getLocation(), TaskService.class, PushTaskTO.class);
+
+ assertNotNull(push);
+
+ // execute the new task
+ final TaskExecTO pushExec = execSyncTask(push.getKey(), 50, false);
+ assertTrue(PropagationTaskExecStatus.valueOf(pushExec.getStatus()).isSuccessful());
+ } finally {
+ roleService.delete(roleTO.getKey());
+ if (newResourceTO != null) {
+ resourceService.delete(resourceName);
+ }
+ }
+ }
++
++ @Test
++ public void issueSYNCOPE648() {
++ //1. Create Push Task
++ final PushTaskTO task = new PushTaskTO();
++ task.setName("Test create Push");
++ task.setResource(RESOURCE_NAME_LDAP);
++ task.setUserFilter(
++ SyncopeClient.getUserSearchConditionBuilder().is("username").equalTo("_NO_ONE_").query());
++ task.setRoleFilter(
++ SyncopeClient.getRoleSearchConditionBuilder().is("name").equalTo("citizen").query());
++ task.setMatchingRule(MatchingRule.IGNORE);
++ task.setUnmatchingRule(UnmatchingRule.IGNORE);
++
++ final Response response = taskService.create(task);
++ final PushTaskTO actual = getObject(response.getLocation(), TaskService.class, PushTaskTO.class);
++ assertNotNull(actual);
++
++ // 2. Create notification
++ NotificationTO notification = new NotificationTO();
++ notification.setTraceLevel(TraceLevel.FAILURES);
++ notification.getEvents().add("[PushTask]:[role]:[resource-ldap]:[matchingrule_ignore]:[SUCCESS]");
++ notification.getEvents().add("[PushTask]:[role]:[resource-ldap]:[unmatchingrule_ignore]:[SUCCESS]");
++
++ notification.getStaticRecipients().add("issueyncope648@syncope.apache.org");
++ notification.setSelfAsRecipient(false);
++ notification.setRecipientAttrName("email");
++ notification.setRecipientAttrType(IntMappingType.UserPlainSchema);
++
++ notification.setSender("syncope648@syncope.apache.org");
++ String subject = "Test notification";
++ notification.setSubject(subject);
++ notification.setTemplate("optin");
++ notification.setActive(true);
++
++ Response responseNotification = notificationService.create(notification);
++ notification = getObject(responseNotification.getLocation(), NotificationService.class, NotificationTO.class);
++ assertNotNull(notification);
++
++ execSyncTask(actual.getKey(), 50, false);
++
++ NotificationTaskTO taskTO = findNotificationTaskBySender("syncope648@syncope.apache.org");
++ assertNotNull(taskTO);
++ }
+}