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/26 17:27:37 UTC
[1/2] syncope git commit: [SYNCOPE-620] Simplifying Activiti init +
splitting task IT cases
Repository: syncope
Updated Branches:
refs/heads/2_0_X 16984bdaf -> 6f24e8170
http://git-wip-us.apache.org/repos/asf/syncope/blob/6f24e817/syncope620/fit/reference/src/test/java/org/apache/syncope/fit/server/reference/TaskITCase.java
----------------------------------------------------------------------
diff --git a/syncope620/fit/reference/src/test/java/org/apache/syncope/fit/server/reference/TaskITCase.java b/syncope620/fit/reference/src/test/java/org/apache/syncope/fit/server/reference/TaskITCase.java
deleted file mode 100644
index 0c191f4..0000000
--- a/syncope620/fit/reference/src/test/java/org/apache/syncope/fit/server/reference/TaskITCase.java
+++ /dev/null
@@ -1,1383 +0,0 @@
-/*
- * 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.server.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.ArrayList;
-import java.util.HashMap;
-import java.util.HashSet;
-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 javax.ws.rs.core.Response;
-import org.apache.syncope.client.lib.SyncopeClient;
-import org.apache.syncope.common.lib.SyncopeClientException;
-import org.apache.syncope.common.lib.mod.StatusMod;
-import org.apache.syncope.common.lib.mod.UserMod;
-import org.apache.syncope.common.lib.to.AbstractTaskTO;
-import org.apache.syncope.common.lib.to.AttrTO;
-import org.apache.syncope.common.lib.to.BulkAction;
-import org.apache.syncope.common.lib.to.ConnInstanceTO;
-import org.apache.syncope.common.lib.to.ConnObjectTO;
-import org.apache.syncope.common.lib.to.MappingItemTO;
-import org.apache.syncope.common.lib.to.MappingTO;
-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.PlainSchemaTO;
-import org.apache.syncope.common.lib.to.PropagationTaskTO;
-import org.apache.syncope.common.lib.to.PushTaskTO;
-import org.apache.syncope.common.lib.to.ReportExecTO;
-import org.apache.syncope.common.lib.to.ResourceTO;
-import org.apache.syncope.common.lib.to.RoleTO;
-import org.apache.syncope.common.lib.to.SchedTaskTO;
-import org.apache.syncope.common.lib.to.SyncPolicyTO;
-import org.apache.syncope.common.lib.to.SyncTaskTO;
-import org.apache.syncope.common.lib.to.TaskExecTO;
-import org.apache.syncope.common.lib.to.UserTO;
-import org.apache.syncope.common.lib.types.AttrSchemaType;
-import org.apache.syncope.common.lib.types.AttributableType;
-import org.apache.syncope.common.lib.types.CipherAlgorithm;
-import org.apache.syncope.common.lib.types.ConnConfProperty;
-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.ResourceDeassociationActionType;
-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.lib.wrap.ResourceName;
-import org.apache.syncope.common.rest.api.CollectionWrapper;
-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.apache.syncope.server.misc.security.Encryptor;
-import org.apache.syncope.server.provisioning.api.job.SyncJob;
-import org.apache.syncope.server.provisioning.java.sync.DBPasswordSyncActions;
-import org.apache.syncope.server.provisioning.java.sync.LDAPPasswordSyncActions;
-import org.identityconnectors.framework.common.objects.Name;
-import org.junit.BeforeClass;
-import org.junit.FixMethodOrder;
-import org.junit.Test;
-import org.junit.runners.MethodSorters;
-import org.springframework.dao.EmptyResultDataAccessException;
-import org.springframework.jdbc.core.JdbcTemplate;
-
-@FixMethodOrder(MethodSorters.JVM)
-public class TaskITCase extends AbstractITCase {
-
- private static final Long SCHED_TASK_ID = 5L;
-
- private static final Long SYNC_TASK_ID = 4L;
-
- private static class ThreadExec implements Callable<TaskExecTO> {
-
- private final TaskITCase test;
-
- private final Long taskKey;
-
- private final int maxWaitSeconds;
-
- private final boolean dryRun;
-
- public ThreadExec(TaskITCase 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);
- }
- }
-
- @BeforeClass
- public static void testSyncActionsSetup() {
- SyncTaskTO syncTask = taskService.read(SYNC_TASK_ID);
- syncTask.getActionsClassNames().add(TestSyncActions.class.getName());
- taskService.update(SYNC_TASK_ID, syncTask);
- }
-
- /**
- * Remove initial and synchronized users to make test re-runnable.
- */
- private 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
- }
- }
- }
-
- @Test
- public void getJobClasses() {
- List<String> jobClasses = syncopeService.info().getTaskJobs();
- assertNotNull(jobClasses);
- assertFalse(jobClasses.isEmpty());
- }
-
- @Test
- public void getSyncActionsClasses() {
- List<String> actions = syncopeService.info().getSyncActions();
- assertNotNull(actions);
- assertFalse(actions.isEmpty());
- }
-
- @Test
- public void getPushActionsClasses() {
- List<String> actions = syncopeService.info().getPushActions();
- assertNotNull(actions);
- }
-
- @Test
- public void createSyncTask() {
- SyncTaskTO task = new SyncTaskTO();
- task.setName("Test create Sync");
- task.setResource(RESOURCE_NAME_WS2);
-
- UserTO userTemplate = new UserTO();
- userTemplate.getResources().add(RESOURCE_NAME_WS2);
-
- MembershipTO membershipTO = new MembershipTO();
- membershipTO.setRoleId(8L);
- userTemplate.getMemberships().add(membershipTO);
- task.setUserTemplate(userTemplate);
-
- RoleTO roleTemplate = new RoleTO();
- roleTemplate.getResources().add(RESOURCE_NAME_LDAP);
- task.setRoleTemplate(roleTemplate);
-
- Response response = taskService.create(task);
- SyncTaskTO actual = getObject(response.getLocation(), TaskService.class, SyncTaskTO.class);
- assertNotNull(actual);
-
- task = taskService.read(actual.getKey());
- assertNotNull(task);
- assertEquals(actual.getKey(), task.getKey());
- assertEquals(actual.getJobClassName(), task.getJobClassName());
- assertEquals(userTemplate, task.getUserTemplate());
- assertEquals(roleTemplate, task.getRoleTemplate());
- }
-
- @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 update() {
- SchedTaskTO task = taskService.read(SCHED_TASK_ID);
- assertNotNull(task);
-
- final SchedTaskTO taskMod = new SchedTaskTO();
- taskMod.setKey(5);
- taskMod.setCronExpression(null);
-
- taskService.update(taskMod.getKey(), taskMod);
- SchedTaskTO actual = taskService.read(taskMod.getKey());
- assertNotNull(actual);
- assertEquals(task.getKey(), actual.getKey());
- assertNull(actual.getCronExpression());
- }
-
- @Test
- public void listSchedTask() {
- final PagedResult<SchedTaskTO> tasks = taskService.list(TaskType.SCHEDULED);
- assertFalse(tasks.getResult().isEmpty());
- for (AbstractTaskTO task : tasks.getResult()) {
- if (!(task instanceof SchedTaskTO) || task instanceof SyncTaskTO || task instanceof PushTaskTO) {
- fail();
- }
- }
- }
-
- @Test
- public void listSyncTask() {
- final PagedResult<SyncTaskTO> tasks = taskService.list(TaskType.SYNCHRONIZATION);
- assertFalse(tasks.getResult().isEmpty());
- for (AbstractTaskTO task : tasks.getResult()) {
- if (!(task instanceof SyncTaskTO)) {
- fail();
- }
- }
- }
-
- @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 paginatedList() {
- PagedResult<PropagationTaskTO> tasks = taskService.list(TaskType.PROPAGATION, 1, 2);
-
- assertNotNull(tasks);
- assertFalse(tasks.getResult().isEmpty());
- assertEquals(2, tasks.getResult().size());
-
- for (AbstractTaskTO task : tasks.getResult()) {
- assertNotNull(task);
- }
-
- tasks = taskService.list(TaskType.PROPAGATION, 2, 2);
-
- assertNotNull(tasks);
- assertFalse(tasks.getResult().isEmpty());
-
- for (AbstractTaskTO task : tasks.getResult()) {
- assertNotNull(task);
- }
-
- tasks = taskService.list(TaskType.PROPAGATION, 1000, 2);
-
- assertNotNull(tasks);
- assertTrue(tasks.getResult().isEmpty());
- }
-
- @Test
- public void read() {
- final PropagationTaskTO taskTO = taskService.read(3L);
-
- assertNotNull(taskTO);
- assertNotNull(taskTO.getExecutions());
- assertTrue(taskTO.getExecutions().isEmpty());
-
- final PushTaskTO pushTaskTO = taskService.<PushTaskTO>read(17L);
- assertEquals(UnmatchingRule.ASSIGN, pushTaskTO.getUnmatchingRule());
- assertEquals(MatchingRule.UPDATE, pushTaskTO.getMatchingRule());
- }
-
- @Test
- public void readExecution() {
- TaskExecTO taskTO = taskService.readExecution(6L);
- assertNotNull(taskTO);
- }
-
- @Test
- // Currently test is not re-runnable.
- // To successfully run test second time it is necessary to restart cargo.
- public void deal() {
- try {
- taskService.delete(0L);
- } catch (SyncopeClientException e) {
- assertEquals(Response.Status.NOT_FOUND, e.getType().getResponseStatus());
- }
- TaskExecTO exec = taskService.execute(1L, false);
- assertEquals(PropagationTaskExecStatus.SUBMITTED.name(), exec.getStatus());
-
- ReportExecTO report = new ReportExecTO();
- report.setStatus(PropagationTaskExecStatus.SUCCESS.name());
- report.setMessage("OK");
- taskService.report(exec.getKey(), report);
- exec = taskService.readExecution(exec.getKey());
- assertEquals(PropagationTaskExecStatus.SUCCESS.name(), exec.getStatus());
- assertEquals("OK", exec.getMessage());
-
- taskService.delete(1L);
- try {
- taskService.readExecution(exec.getKey());
- } catch (SyncopeClientException e) {
- assertEquals(Response.Status.NOT_FOUND, e.getType().getResponseStatus());
- }
- }
-
- @Test
- public void sync() throws Exception {
- removeTestUsers();
-
- // -----------------------------
- // Create a new user ... it should be updated applying sync policy
- // -----------------------------
- UserTO inUserTO = new UserTO();
- inUserTO.setPassword("password123");
- String userName = "test9";
- inUserTO.setUsername(userName);
- inUserTO.getPlainAttrs().add(attrTO("firstname", "nome9"));
- inUserTO.getPlainAttrs().add(attrTO("surname", "cognome"));
- inUserTO.getPlainAttrs().add(attrTO("type", "a type"));
- inUserTO.getPlainAttrs().add(attrTO("fullname", "nome cognome"));
- inUserTO.getPlainAttrs().add(attrTO("userId", "puccini@syncope.apache.org"));
- inUserTO.getPlainAttrs().add(attrTO("email", "puccini@syncope.apache.org"));
- inUserTO.getDerAttrs().add(attrTO("csvuserid", null));
-
- inUserTO = createUser(inUserTO);
- assertNotNull(inUserTO);
- assertFalse(inUserTO.getResources().contains(RESOURCE_NAME_CSV));
-
- // -----------------------------
- try {
- int usersPre = userService.list(1, 1).getTotalCount();
- assertNotNull(usersPre);
-
- execSyncTask(SYNC_TASK_ID, 50, false);
-
- // after execution of the sync task the user data should be synced from
- // csv datasource and processed by user template
- UserTO userTO = userService.read(inUserTO.getKey());
- assertNotNull(userTO);
- assertEquals(userName, userTO.getUsername());
- assertEquals(ActivitiDetector.isActivitiEnabledForUsers(syncopeService)
- ? "active" : "created", userTO.getStatus());
- assertEquals("test9@syncope.apache.org", userTO.getPlainAttrMap().get("email").getValues().get(0));
- assertEquals("test9@syncope.apache.org", userTO.getPlainAttrMap().get("userId").getValues().get(0));
- assertTrue(Integer.valueOf(userTO.getPlainAttrMap().get("fullname").getValues().get(0)) <= 10);
- assertTrue(userTO.getResources().contains(RESOURCE_NAME_TESTDB));
- assertTrue(userTO.getResources().contains(RESOURCE_NAME_WS2));
-
- // Matching --> Update (no link)
- assertFalse(userTO.getResources().contains(RESOURCE_NAME_CSV));
-
- // check for user template
- userTO = readUser("test7");
- assertNotNull(userTO);
- assertEquals("TYPE_OTHER", userTO.getPlainAttrMap().get("type").getValues().get(0));
- assertEquals(3, userTO.getResources().size());
- assertTrue(userTO.getResources().contains(RESOURCE_NAME_TESTDB));
- assertTrue(userTO.getResources().contains(RESOURCE_NAME_WS2));
- assertEquals(1, userTO.getMemberships().size());
- assertTrue(userTO.getMemberships().get(0).getPlainAttrMap().containsKey("subscriptionDate"));
-
- // Unmatching --> Assign (link)
- assertTrue(userTO.getResources().contains(RESOURCE_NAME_CSV));
-
- userTO = readUser("test8");
- assertNotNull(userTO);
- assertEquals("TYPE_8", userTO.getPlainAttrMap().get("type").getValues().get(0));
-
- // check for sync results
- int usersPost = userService.list(1, 1).getTotalCount();
- assertNotNull(usersPost);
- assertEquals(usersPre + 9, usersPost);
-
- // Check for issue 215:
- // * expected disabled user test1
- // * expected enabled user test2
- userTO = readUser("test1");
- assertNotNull(userTO);
- assertEquals("suspended", userTO.getStatus());
-
- userTO = readUser("test3");
- assertNotNull(userTO);
- assertEquals("active", userTO.getStatus());
-
- // SYNCOPE-317
- execSyncTask(SYNC_TASK_ID, 50, false);
-
- final Set<Long> pushTaskIds = new HashSet<Long>();
- pushTaskIds.add(25L);
- pushTaskIds.add(26L);
-
- execSyncTasks(pushTaskIds, 50, false);
- // Matching --> UNLINK
- assertFalse(readUser("test9").getResources().contains(RESOURCE_NAME_CSV));
- assertFalse(readUser("test7").getResources().contains(RESOURCE_NAME_CSV));
- } finally {
- removeTestUsers();
- }
- }
-
- @Test
- public void reconcileFromDB() {
- // update sync task
- TaskExecTO execution = execSyncTask(7L, 50, false);
- assertNotNull(execution.getStatus());
- assertTrue(PropagationTaskExecStatus.valueOf(execution.getStatus()).isSuccessful());
-
- UserTO userTO = readUser("testuser1");
- assertNotNull(userTO);
- assertEquals("reconciled@syncope.apache.org", userTO.getPlainAttrMap().get("userId").getValues().get(0));
- assertEquals("suspended", userTO.getStatus());
-
- // enable user on external resource
- JdbcTemplate jdbcTemplate = new JdbcTemplate(testDataSource);
- jdbcTemplate.execute("UPDATE TEST SET STATUS=TRUE");
-
- // re-execute the same SyncTask: now user must be active
- execution = execSyncTask(7L, 50, false);
- assertNotNull(execution.getStatus());
- assertTrue(PropagationTaskExecStatus.valueOf(execution.getStatus()).isSuccessful());
-
- userTO = readUser("testuser1");
- assertNotNull(userTO);
- assertEquals("active", userTO.getStatus());
- }
-
- /**
- * Clean Syncope and LDAP resource status.
- */
- private void ldapCleanup() {
- PagedResult<RoleTO> matchingRoles = roleService.search(
- SyncopeClient.getRoleSearchConditionBuilder().is("name").equalTo("testLDAPGroup").query());
- if (matchingRoles.getSize() > 0) {
- for (RoleTO role : matchingRoles.getResult()) {
- roleService.bulkDeassociation(role.getKey(),
- ResourceDeassociationActionType.UNLINK,
- CollectionWrapper.wrap(RESOURCE_NAME_LDAP, ResourceName.class));
- roleService.delete(role.getKey());
- }
- }
- PagedResult<UserTO> matchingUsers = userService.search(
- SyncopeClient.getUserSearchConditionBuilder().is("username").equalTo("syncFromLDAP").query());
- if (matchingUsers.getSize() > 0) {
- for (UserTO user : matchingUsers.getResult()) {
- userService.bulkDeassociation(user.getKey(),
- ResourceDeassociationActionType.UNLINK,
- CollectionWrapper.wrap(RESOURCE_NAME_LDAP, ResourceName.class));
- userService.delete(user.getKey());
- }
- }
- }
-
- @Test
- public void reconcileFromLDAP() {
- // First of all, clear any potential conflict with existing user / role
- ldapCleanup();
-
- // Update sync task
- TaskExecTO execution = execSyncTask(11L, 50, false);
-
- // 1. verify execution status
- final String status = execution.getStatus();
- assertNotNull(status);
- assertTrue(PropagationTaskExecStatus.valueOf(status).isSuccessful());
-
- // 2. verify that synchronized role is found, with expected attributes
- final PagedResult<RoleTO> matchingRoles = roleService.search(
- SyncopeClient.getRoleSearchConditionBuilder().is("name").equalTo("testLDAPGroup").query());
- assertNotNull(matchingRoles);
- assertEquals(1, matchingRoles.getResult().size());
-
- final PagedResult<UserTO> matchingUsers = userService.search(
- SyncopeClient.getUserSearchConditionBuilder().is("username").equalTo("syncFromLDAP").query());
- assertNotNull(matchingUsers);
- assertEquals(1, matchingUsers.getResult().size());
-
- // Check for SYNCOPE-436
- assertEquals("syncFromLDAP",
- matchingUsers.getResult().get(0).getVirAttrMap().get("virtualReadOnly").getValues().get(0));
- // Check for SYNCOPE-270
- assertNotNull(matchingUsers.getResult().get(0).getPlainAttrMap().get("obscure"));
- // Check for SYNCOPE-123
- assertNotNull(matchingUsers.getResult().get(0).getPlainAttrMap().get("photo"));
-
- final RoleTO roleTO = matchingRoles.getResult().iterator().next();
- assertNotNull(roleTO);
- assertEquals("testLDAPGroup", roleTO.getName());
- assertEquals(8L, roleTO.getParent());
- assertEquals("true", roleTO.getPlainAttrMap().get("show").getValues().get(0));
- assertEquals(matchingUsers.getResult().iterator().next().getKey(), (long) roleTO.getUserOwner());
- assertNull(roleTO.getRoleOwner());
-
- // 3. verify that LDAP group membership is propagated as Syncope role membership
- final PagedResult<UserTO> members = userService.search(
- SyncopeClient.getUserSearchConditionBuilder().hasRoles(roleTO.getKey()).query());
- assertNotNull(members);
- assertEquals(1, members.getResult().size());
- }
-
- @Test
- public void issue196() {
- TaskExecTO exec = taskService.execute(6L, false);
- assertNotNull(exec);
- assertEquals(0, exec.getKey());
- assertNotNull(exec.getTask());
- }
-
- @Test
- public void dryRun() {
- TaskExecTO execution = execSyncTask(SYNC_TASK_ID, 50, true);
- assertEquals("Execution of task " + execution.getTask() + " failed with message " + execution.getMessage(),
- "SUCCESS", execution.getStatus());
- }
-
- @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);
- }
-
- @Test
- public void issueSYNCOPE68() {
- //-----------------------------
- // Create a new user ... it should be updated applying sync policy
- //-----------------------------
- UserTO userTO = new UserTO();
- userTO.setPassword("password123");
- userTO.setUsername("testuser2");
-
- userTO.getPlainAttrs().add(attrTO("firstname", "testuser2"));
- userTO.getPlainAttrs().add(attrTO("surname", "testuser2"));
- userTO.getPlainAttrs().add(attrTO("type", "a type"));
- userTO.getPlainAttrs().add(attrTO("fullname", "a type"));
- userTO.getPlainAttrs().add(attrTO("userId", "testuser2@syncope.apache.org"));
- userTO.getPlainAttrs().add(attrTO("email", "testuser2@syncope.apache.org"));
-
- userTO.getResources().add(RESOURCE_NAME_NOPROPAGATION2);
- userTO.getResources().add(RESOURCE_NAME_NOPROPAGATION4);
-
- MembershipTO membershipTO = new MembershipTO();
- membershipTO.setRoleId(7L);
-
- userTO.getMemberships().add(membershipTO);
-
- userTO = createUser(userTO);
- assertNotNull(userTO);
- assertEquals("testuser2", userTO.getUsername());
- assertEquals(1, userTO.getMemberships().size());
- assertEquals(3, userTO.getResources().size());
- //-----------------------------
-
- try {
- //-----------------------------
- // add user template
- //-----------------------------
- UserTO template = new UserTO();
-
- membershipTO = new MembershipTO();
- membershipTO.setRoleId(10L);
-
- template.getMemberships().add(membershipTO);
-
- template.getResources().add(RESOURCE_NAME_NOPROPAGATION4);
- //-----------------------------
-
- // Update sync task
- SyncTaskTO task = taskService.read(9L);
- assertNotNull(task);
-
- task.setUserTemplate(template);
-
- taskService.update(task.getKey(), task);
- SyncTaskTO actual = taskService.read(task.getKey());
- assertNotNull(actual);
- assertEquals(task.getKey(), actual.getKey());
- assertFalse(actual.getUserTemplate().getResources().isEmpty());
- assertFalse(actual.getUserTemplate().getMemberships().isEmpty());
-
- TaskExecTO execution = execSyncTask(actual.getKey(), 50, false);
- final String status = execution.getStatus();
- assertNotNull(status);
- assertTrue(PropagationTaskExecStatus.valueOf(status).isSuccessful());
-
- userTO = readUser("testuser2");
- assertNotNull(userTO);
- assertEquals("testuser2@syncope.apache.org", userTO.getPlainAttrMap().get("userId").getValues().get(0));
- assertEquals(2, userTO.getMemberships().size());
- assertEquals(4, userTO.getResources().size());
- } finally {
- UserTO dUserTO = deleteUser(userTO.getKey());
- assertNotNull(dUserTO);
- }
- }
-
- @Test
- public void issueSYNCOPE144() {
- SchedTaskTO task = new SchedTaskTO();
- task.setName("issueSYNCOPE144");
- task.setDescription("issueSYNCOPE144 Description");
- task.setJobClassName(SyncJob.class.getName());
-
- Response response = taskService.create(task);
- SchedTaskTO actual = getObject(response.getLocation(), TaskService.class, SchedTaskTO.class);
- assertNotNull(actual);
- assertEquals("issueSYNCOPE144", actual.getName());
- assertEquals("issueSYNCOPE144 Description", actual.getDescription());
-
- task = taskService.read(actual.getKey());
- assertNotNull(task);
- assertEquals("issueSYNCOPE144", task.getName());
- assertEquals("issueSYNCOPE144 Description", task.getDescription());
-
- task.setName("issueSYNCOPE144_2");
- task.setDescription("issueSYNCOPE144 Description_2");
-
- response = taskService.create(task);
- actual = getObject(response.getLocation(), TaskService.class, SchedTaskTO.class);
- assertNotNull(actual);
- assertEquals("issueSYNCOPE144_2", actual.getName());
- assertEquals("issueSYNCOPE144 Description_2", actual.getDescription());
- }
-
- @Test
- public void issueSYNCOPE230() {
- // 1. read SyncTask for resource-db-sync (table TESTSYNC on external H2)
- execSyncTask(10L, 50, false);
-
- // 3. read e-mail address for user created by the SyncTask first execution
- UserTO userTO = readUser("issuesyncope230");
- assertNotNull(userTO);
- String email = userTO.getPlainAttrMap().get("email").getValues().iterator().next();
- assertNotNull(email);
-
- // 4. update TESTSYNC on external H2 by changing e-mail address
- JdbcTemplate jdbcTemplate = new JdbcTemplate(testDataSource);
- jdbcTemplate.execute("UPDATE TESTSYNC SET email='updatedSYNCOPE230@syncope.apache.org'");
-
- // 5. re-execute the SyncTask
- execSyncTask(10L, 50, false);
-
- // 6. verify that the e-mail was updated
- userTO = readUser("issuesyncope230");
- assertNotNull(userTO);
- email = userTO.getPlainAttrMap().get("email").getValues().iterator().next();
- assertNotNull(email);
- assertEquals("updatedSYNCOPE230@syncope.apache.org", email);
- }
-
- private 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);
- }
-
- private 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 (final Long id : taskKeys) {
- futures.add(service.submit(new ThreadExec(this, id, maxWaitSeconds, dryRun)));
- }
-
- final Map<Long, TaskExecTO> res = new HashMap<>();
-
- for (Future<TaskExecTO> f : futures) {
- TaskExecTO taskExecTO = f.get(100, TimeUnit.SECONDS);
- res.put(taskExecTO.getTask(), taskExecTO);
- }
-
- service.shutdownNow();
-
- return res;
- }
-
- @Test
- public void issueSYNCOPE272() {
- removeTestUsers();
-
- // create user with testdb resource
- UserTO userTO = UserITCase.getUniqueSampleTO("syncope272@syncope.apache.org");
- userTO.getResources().add(RESOURCE_NAME_TESTDB);
-
- userTO = createUser(userTO);
- try {
- assertNotNull(userTO);
- assertEquals(1, userTO.getPropagationStatusTOs().size());
- assertTrue(userTO.getPropagationStatusTOs().get(0).getStatus().isSuccessful());
-
- TaskExecTO taskExecTO = execSyncTask(24L, 50, false);
-
- assertNotNull(taskExecTO.getStatus());
- assertTrue(PropagationTaskExecStatus.valueOf(taskExecTO.getStatus()).isSuccessful());
-
- userTO = userService.read(userTO.getKey());
- assertNotNull(userTO);
- assertNotNull(userTO.getPlainAttrMap().get("firstname").getValues().get(0));
- } finally {
- removeTestUsers();
- }
- }
-
- @Test
- public void issueSYNCOPE258() {
- // -----------------------------
- // Add a custom correlation rule
- // -----------------------------
- SyncPolicyTO policyTO = policyService.read(9L);
- policyTO.getSpecification().setUserJavaRule(TestSyncRule.class.getName());
-
- policyService.update(policyTO.getKey(), policyTO);
- // -----------------------------
-
- SyncTaskTO task = new SyncTaskTO();
- task.setName("Test Sync Rule");
- task.setResource(RESOURCE_NAME_WS2);
- task.setFullReconciliation(true);
- task.setPerformCreate(true);
- task.setPerformDelete(true);
- task.setPerformUpdate(true);
-
- Response response = taskService.create(task);
- SyncTaskTO actual = getObject(response.getLocation(), TaskService.class, SyncTaskTO.class);
- assertNotNull(actual);
-
- UserTO userTO = UserITCase.getUniqueSampleTO("s258_1@apache.org");
- userTO.getResources().clear();
- userTO.getResources().add(RESOURCE_NAME_WS2);
-
- createUser(userTO);
-
- userTO = UserITCase.getUniqueSampleTO("s258_2@apache.org");
- userTO.getResources().clear();
- userTO.getResources().add(RESOURCE_NAME_WS2);
-
- userTO = createUser(userTO);
-
- // change email in order to unmatch the second user
- UserMod userMod = new UserMod();
- userMod.setKey(userTO.getKey());
- userMod.getPlainAttrsToRemove().add("email");
- userMod.getPlainAttrsToUpdate().add(attrMod("email", "s258@apache.org"));
-
- userService.update(userMod.getKey(), userMod);
-
- execSyncTask(actual.getKey(), 50, false);
-
- SyncTaskTO executed = taskService.read(actual.getKey());
- assertEquals(1, executed.getExecutions().size());
-
- // asser for just one match
- assertTrue(executed.getExecutions().get(0).getMessage().substring(0, 55) + "...",
- executed.getExecutions().get(0).getMessage().contains("[updated/failures]: 1/0"));
- }
-
- @Test
- public void issueSYNCOPE307() {
- UserTO userTO = UserITCase.getUniqueSampleTO("s307@apache.org");
-
- AttrTO csvuserid = new AttrTO();
- csvuserid.setSchema("csvuserid");
- userTO.getDerAttrs().add(csvuserid);
-
- userTO.getResources().clear();
- userTO.getResources().add(RESOURCE_NAME_WS2);
- userTO.getResources().add(RESOURCE_NAME_CSV);
-
- userTO = createUser(userTO);
- assertNotNull(userTO);
-
- userTO = userService.read(userTO.getKey());
- assertEquals("virtualvalue", userTO.getVirAttrMap().get("virtualdata").getValues().get(0));
-
- // Update sync task
- SyncTaskTO task = taskService.read(12L);
- assertNotNull(task);
-
- // add user template
- UserTO template = new UserTO();
- template.getResources().add(RESOURCE_NAME_DBVIRATTR);
-
- AttrTO userId = attrTO("userId", "'s307@apache.org'");
- template.getPlainAttrs().add(userId);
-
- AttrTO email = attrTO("email", "'s307@apache.org'");
- template.getPlainAttrs().add(email);
-
- task.setUserTemplate(template);
-
- taskService.update(task.getKey(), task);
- execSyncTask(task.getKey(), 50, false);
-
- // check for sync policy
- userTO = userService.read(userTO.getKey());
- assertEquals("virtualvalue", userTO.getVirAttrMap().get("virtualdata").getValues().get(0));
-
- try {
- final JdbcTemplate jdbcTemplate = new JdbcTemplate(testDataSource);
-
- String value = jdbcTemplate.queryForObject(
- "SELECT USERNAME FROM testsync WHERE ID=?", String.class, userTO.getKey());
- assertEquals("virtualvalue", value);
- } catch (EmptyResultDataAccessException e) {
- assertTrue(false);
- }
- }
-
- @Test
- public void bulkAction() {
- final PagedResult<PropagationTaskTO> before = taskService.list(TaskType.PROPAGATION);
-
- // create user with testdb resource
- final UserTO userTO = UserITCase.getUniqueSampleTO("taskBulk@apache.org");
- userTO.getResources().add(RESOURCE_NAME_TESTDB);
- createUser(userTO);
-
- final List<PropagationTaskTO> after = new ArrayList<PropagationTaskTO>(
- taskService.<PropagationTaskTO>list(TaskType.PROPAGATION).getResult());
-
- after.removeAll(before.getResult());
-
- assertFalse(after.isEmpty());
-
- final BulkAction bulkAction = new BulkAction();
- bulkAction.setOperation(BulkAction.Type.DELETE);
-
- for (AbstractTaskTO taskTO : after) {
- bulkAction.getTargets().add(String.valueOf(taskTO.getKey()));
- }
-
- taskService.bulk(bulkAction);
-
- assertFalse(taskService.list(TaskType.PROPAGATION).getResult().containsAll(after));
- }
-
- @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 issueSYNCOPE313DB() throws Exception {
- // 1. create user in DB
- UserTO user = UserITCase.getUniqueSampleTO("syncope313-db@syncope.apache.org");
- user.setPassword("security");
- user.getResources().add(RESOURCE_NAME_TESTDB);
- user = createUser(user);
- assertNotNull(user);
- assertFalse(user.getResources().isEmpty());
-
- // 2. Check that the DB resource has the correct password
- final JdbcTemplate jdbcTemplate = new JdbcTemplate(testDataSource);
- String value = jdbcTemplate.queryForObject(
- "SELECT PASSWORD FROM test WHERE ID=?", String.class, user.getUsername());
- assertEquals(Encryptor.getInstance().encode("security", CipherAlgorithm.SHA1), value.toUpperCase());
-
- // 3. Update the password in the DB
- String newPassword = Encryptor.getInstance().encode("new-security", CipherAlgorithm.SHA1);
- jdbcTemplate.execute(
- "UPDATE test set PASSWORD='" + newPassword + "' where ID='" + user.getUsername() + "'");
-
- // 4. Sync the user from the resource
- SyncTaskTO syncTask = new SyncTaskTO();
- syncTask.setName("DB Sync Task");
- syncTask.setPerformCreate(true);
- syncTask.setPerformUpdate(true);
- syncTask.setFullReconciliation(true);
- syncTask.setResource(RESOURCE_NAME_TESTDB);
- syncTask.getActionsClassNames().add(DBPasswordSyncActions.class.getName());
- Response taskResponse = taskService.create(syncTask);
-
- SyncTaskTO actual = getObject(taskResponse.getLocation(), TaskService.class, SyncTaskTO.class);
- assertNotNull(actual);
-
- syncTask = taskService.read(actual.getKey());
- assertNotNull(syncTask);
- assertEquals(actual.getKey(), syncTask.getKey());
- assertEquals(actual.getJobClassName(), syncTask.getJobClassName());
-
- TaskExecTO execution = execSyncTask(syncTask.getKey(), 50, false);
- final String status = execution.getStatus();
- assertNotNull(status);
- assertTrue(PropagationTaskExecStatus.valueOf(status).isSuccessful());
-
- // 5. Test the sync'd user
- UserTO updatedUser = userService.read(user.getKey());
- assertEquals(newPassword, updatedUser.getPassword());
-
- // 6. Delete SyncTask + user
- taskService.delete(syncTask.getKey());
- deleteUser(user.getKey());
- }
-
- @Test
- public void issueSYNCOPE313LDAP() throws Exception {
- // First of all, clear any potential conflict with existing user / role
- ldapCleanup();
-
- // 1. create user in LDAP
- UserTO user = UserITCase.getUniqueSampleTO("syncope313-ldap@syncope.apache.org");
- user.setPassword("security");
- user.getResources().add(RESOURCE_NAME_LDAP);
- user = createUser(user);
- assertNotNull(user);
- assertFalse(user.getResources().isEmpty());
-
- // 2. request to change password only on Syncope and not on LDAP
- UserMod userMod = new UserMod();
- userMod.setKey(user.getKey());
- userMod.setPassword("new-security");
- StatusMod pwdPropRequest = new StatusMod();
- pwdPropRequest.setOnSyncope(true);
- pwdPropRequest.getResourceNames().clear();
- userMod.setPwdPropRequest(pwdPropRequest);
- updateUser(userMod);
-
- // 3. Check that the Syncope user now has the changed password
- UserTO updatedUser = userService.read(user.getKey());
- String encodedNewPassword = Encryptor.getInstance().encode("new-security", CipherAlgorithm.SHA1);
- assertEquals(encodedNewPassword, updatedUser.getPassword());
-
- // 4. Check that the LDAP resource has the old password
- ConnObjectTO connObject =
- resourceService.getConnectorObject(RESOURCE_NAME_LDAP, SubjectType.USER, user.getKey());
- assertNotNull(getLdapRemoteObject(
- connObject.getPlainAttrMap().get(Name.NAME).getValues().get(0),
- "security",
- connObject.getPlainAttrMap().get(Name.NAME).getValues().get(0)));
-
- // 5. Update the LDAP Connector to retrieve passwords
- ResourceTO ldapResource = resourceService.read(RESOURCE_NAME_LDAP);
- ConnInstanceTO resourceConnector = connectorService.read(ldapResource.getConnectorId());
- ConnConfProperty property = resourceConnector.getConfigurationMap().get("retrievePasswordsWithSearch");
- property.getValues().clear();
- property.getValues().add(Boolean.TRUE);
- connectorService.update(ldapResource.getConnectorId(), resourceConnector);
-
- // 6. Sync the user from the resource
- SyncTaskTO syncTask = new SyncTaskTO();
- syncTask.setName("LDAP Sync Task");
- syncTask.setPerformCreate(true);
- syncTask.setPerformUpdate(true);
- syncTask.setFullReconciliation(true);
- syncTask.setResource(RESOURCE_NAME_LDAP);
- syncTask.getActionsClassNames().add(LDAPPasswordSyncActions.class.getName());
- Response taskResponse = taskService.create(syncTask);
-
- SyncTaskTO actual = getObject(taskResponse.getLocation(), TaskService.class, SyncTaskTO.class);
- assertNotNull(actual);
-
- syncTask = taskService.read(actual.getKey());
- assertNotNull(syncTask);
- assertEquals(actual.getKey(), syncTask.getKey());
- assertEquals(actual.getJobClassName(), syncTask.getJobClassName());
-
- TaskExecTO execution = execSyncTask(syncTask.getKey(), 50, false);
- final String status = execution.getStatus();
- assertNotNull(status);
- assertTrue(PropagationTaskExecStatus.valueOf(status).isSuccessful());
-
- // 7. Test the sync'd user
- String syncedPassword = Encryptor.getInstance().encode("security", CipherAlgorithm.SHA1);
- updatedUser = userService.read(user.getKey());
- assertEquals(syncedPassword, updatedUser.getPassword());
-
- // 8. Delete SyncTask + user + reset the connector
- taskService.delete(syncTask.getKey());
- property.getValues().clear();
- property.getValues().add(Boolean.FALSE);
- connectorService.update(ldapResource.getConnectorId(), resourceConnector);
- deleteUser(updatedUser.getKey());
- }
-
- @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.getRAttrTemplates().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);
- }
- }
- }
-}
http://git-wip-us.apache.org/repos/asf/syncope/blob/6f24e817/syncope620/server/logic/src/main/java/org/apache/syncope/server/logic/ConfigurationLogic.java
----------------------------------------------------------------------
diff --git a/syncope620/server/logic/src/main/java/org/apache/syncope/server/logic/ConfigurationLogic.java b/syncope620/server/logic/src/main/java/org/apache/syncope/server/logic/ConfigurationLogic.java
index ac6b816..72b9eab 100644
--- a/syncope620/server/logic/src/main/java/org/apache/syncope/server/logic/ConfigurationLogic.java
+++ b/syncope620/server/logic/src/main/java/org/apache/syncope/server/logic/ConfigurationLogic.java
@@ -29,7 +29,8 @@ import org.apache.syncope.server.persistence.api.dao.PlainSchemaDAO;
import org.apache.syncope.server.persistence.api.entity.conf.CPlainAttr;
import org.apache.syncope.server.persistence.api.entity.conf.CPlainSchema;
import org.apache.syncope.server.provisioning.api.data.ConfigurationDataBinder;
-import org.apache.syncope.server.logic.init.WorkflowAdapterLoader;
+import org.apache.syncope.server.workflow.api.RoleWorkflowAdapter;
+import org.apache.syncope.server.workflow.api.UserWorkflowAdapter;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.stereotype.Component;
@@ -51,7 +52,10 @@ public class ConfigurationLogic extends AbstractTransactionalLogic<ConfTO> {
private ContentExporter exporter;
@Autowired
- private WorkflowAdapterLoader wfAdapterLoader;
+ private UserWorkflowAdapter uwfAdapter;
+
+ @Autowired
+ private RoleWorkflowAdapter rwfAdapter;
@PreAuthorize("hasRole('CONFIGURATION_DELETE')")
public void delete(final String key) {
@@ -92,7 +96,7 @@ public class ConfigurationLogic extends AbstractTransactionalLogic<ConfTO> {
@Transactional(readOnly = true)
public void export(final OutputStream os) {
try {
- exporter.export(os, wfAdapterLoader.getPrefix());
+ exporter.export(os, uwfAdapter.getPrefix(), rwfAdapter.getPrefix());
LOG.debug("Database content successfully exported");
} catch (Exception e) {
LOG.error("While exporting database content", e);
http://git-wip-us.apache.org/repos/asf/syncope/blob/6f24e817/syncope620/server/logic/src/main/java/org/apache/syncope/server/logic/init/LogicInitializer.java
----------------------------------------------------------------------
diff --git a/syncope620/server/logic/src/main/java/org/apache/syncope/server/logic/init/LogicInitializer.java b/syncope620/server/logic/src/main/java/org/apache/syncope/server/logic/init/LogicInitializer.java
index 7a17121..e988def 100644
--- a/syncope620/server/logic/src/main/java/org/apache/syncope/server/logic/init/LogicInitializer.java
+++ b/syncope620/server/logic/src/main/java/org/apache/syncope/server/logic/init/LogicInitializer.java
@@ -24,11 +24,13 @@ import java.util.Comparator;
import java.util.List;
import java.util.Map;
import org.apache.syncope.server.persistence.api.SyncopeLoader;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.aop.support.AopUtils;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.BeanFactoryAware;
import org.springframework.beans.factory.InitializingBean;
-import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.support.DefaultListableBeanFactory;
import org.springframework.stereotype.Component;
@@ -38,8 +40,7 @@ import org.springframework.stereotype.Component;
@Component
public class LogicInitializer implements InitializingBean, BeanFactoryAware {
- @Autowired
- private WorkflowAdapterLoader workflowAdapterLoader;
+ private static final Logger LOG = LoggerFactory.getLogger(LogicInitializer.class);
private DefaultListableBeanFactory beanFactory;
@@ -53,21 +54,19 @@ public class LogicInitializer implements InitializingBean, BeanFactoryAware {
Map<String, SyncopeLoader> loaderMap = beanFactory.getBeansOfType(SyncopeLoader.class);
List<SyncopeLoader> loaders = new ArrayList<>(loaderMap.values());
- Collections.sort(loaders, new PriorityComparator());
+ Collections.sort(loaders, new Comparator<SyncopeLoader>() {
+ @Override
+ public int compare(final SyncopeLoader o1, final SyncopeLoader o2) {
+ return o1.getPriority().compareTo(o2.getPriority());
+ }
+ });
+
+ LOG.debug("Starting initialization...");
for (SyncopeLoader loader : loaders) {
+ LOG.debug("Invoking {} with priority {}", AopUtils.getTargetClass(loader).getName(), loader.getPriority());
loader.load();
}
-
- workflowAdapterLoader.init();
- }
-
- private static class PriorityComparator implements Comparator<SyncopeLoader> {
-
- @Override
- public int compare(final SyncopeLoader o1, final SyncopeLoader o2) {
- return o1.getPriority().compareTo(o2.getPriority());
- }
-
+ LOG.debug("Initialization completed");
}
}
http://git-wip-us.apache.org/repos/asf/syncope/blob/6f24e817/syncope620/server/logic/src/main/java/org/apache/syncope/server/logic/init/WorkflowAdapterLoader.java
----------------------------------------------------------------------
diff --git a/syncope620/server/logic/src/main/java/org/apache/syncope/server/logic/init/WorkflowAdapterLoader.java b/syncope620/server/logic/src/main/java/org/apache/syncope/server/logic/init/WorkflowAdapterLoader.java
deleted file mode 100644
index fb9cbe7..0000000
--- a/syncope620/server/logic/src/main/java/org/apache/syncope/server/logic/init/WorkflowAdapterLoader.java
+++ /dev/null
@@ -1,95 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.syncope.server.logic.init;
-
-import org.apache.syncope.server.persistence.api.SyncopeLoader;
-import org.apache.syncope.server.workflow.api.RoleWorkflowAdapter;
-import org.apache.syncope.server.workflow.api.UserWorkflowAdapter;
-import org.apache.syncope.server.workflow.api.WorkflowDefinitionLoader;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.springframework.beans.BeansException;
-import org.springframework.beans.factory.BeanFactory;
-import org.springframework.beans.factory.BeanFactoryAware;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.beans.factory.support.AbstractBeanDefinition;
-import org.springframework.beans.factory.support.DefaultListableBeanFactory;
-import org.springframework.stereotype.Component;
-
-@Component
-public class WorkflowAdapterLoader implements BeanFactoryAware, SyncopeLoader {
-
- private static final Logger LOG = LoggerFactory.getLogger(WorkflowAdapterLoader.class);
-
- @Autowired
- private UserWorkflowAdapter uwfAdapter;
-
- @Autowired
- private RoleWorkflowAdapter rwfAdapter;
-
- private DefaultListableBeanFactory beanFactory;
-
- private WorkflowDefinitionLoader wfLoader;
-
- @Override
- public void setBeanFactory(final BeanFactory beanFactory) throws BeansException {
- this.beanFactory = (DefaultListableBeanFactory) beanFactory;
- }
-
- private void lazyInit() {
- if (wfLoader == null) {
- if (uwfAdapter.getDefinitionLoaderClass() != null) {
- wfLoader = (WorkflowDefinitionLoader) beanFactory.createBean(
- uwfAdapter.getDefinitionLoaderClass(), AbstractBeanDefinition.AUTOWIRE_BY_TYPE, false);
- }
- if (rwfAdapter.getDefinitionLoaderClass() != null) {
- wfLoader = (WorkflowDefinitionLoader) beanFactory.createBean(
- rwfAdapter.getDefinitionLoaderClass(), AbstractBeanDefinition.AUTOWIRE_BY_TYPE, false);
- }
- }
- }
-
- public String getPrefix() {
- lazyInit();
- return wfLoader == null ? null : wfLoader.getPrefix();
- }
-
- public void init() {
- lazyInit();
- if (wfLoader != null) {
- wfLoader.init();
- }
- }
-
- @Override
- public Integer getPriority() {
- return Integer.MIN_VALUE;
- }
-
- @Override
- public void load() {
- lazyInit();
- if (wfLoader == null) {
- LOG.debug("The configured workflow adapter does not need loading");
- } else {
- LOG.debug("Loading workflow adapter by {}", wfLoader.getClass().getName());
- wfLoader.load();
- }
- }
-}
http://git-wip-us.apache.org/repos/asf/syncope/blob/6f24e817/syncope620/server/persistence-api/src/main/java/org/apache/syncope/server/persistence/api/content/ContentExporter.java
----------------------------------------------------------------------
diff --git a/syncope620/server/persistence-api/src/main/java/org/apache/syncope/server/persistence/api/content/ContentExporter.java b/syncope620/server/persistence-api/src/main/java/org/apache/syncope/server/persistence/api/content/ContentExporter.java
index c5b3866..76534e1 100644
--- a/syncope620/server/persistence-api/src/main/java/org/apache/syncope/server/persistence/api/content/ContentExporter.java
+++ b/syncope620/server/persistence-api/src/main/java/org/apache/syncope/server/persistence/api/content/ContentExporter.java
@@ -24,5 +24,6 @@ import org.xml.sax.SAXException;
public interface ContentExporter {
- void export(OutputStream output, String wfTablePrefix) throws SAXException, TransformerConfigurationException;
+ void export(OutputStream output, String uwfPrefix, String rwfPrefix)
+ throws SAXException, TransformerConfigurationException;
}
http://git-wip-us.apache.org/repos/asf/syncope/blob/6f24e817/syncope620/server/persistence-jpa/src/main/java/org/apache/syncope/server/persistence/jpa/content/XMLContentExporter.java
----------------------------------------------------------------------
diff --git a/syncope620/server/persistence-jpa/src/main/java/org/apache/syncope/server/persistence/jpa/content/XMLContentExporter.java b/syncope620/server/persistence-jpa/src/main/java/org/apache/syncope/server/persistence/jpa/content/XMLContentExporter.java
index 8a60151..8a87df1 100644
--- a/syncope620/server/persistence-jpa/src/main/java/org/apache/syncope/server/persistence/jpa/content/XMLContentExporter.java
+++ b/syncope620/server/persistence-jpa/src/main/java/org/apache/syncope/server/persistence/jpa/content/XMLContentExporter.java
@@ -320,11 +320,14 @@ public class XMLContentExporter extends AbstractContentDealer implements Content
}
@Override
- public void export(final OutputStream os, final String wfTablePrefix)
+ public void export(final OutputStream os, final String uwfPrefix, String rwfPrefix)
throws SAXException, TransformerConfigurationException {
- if (StringUtils.isNotBlank(wfTablePrefix)) {
- TABLE_PREFIXES_TO_BE_EXCLUDED.add(wfTablePrefix);
+ if (StringUtils.isNotBlank(uwfPrefix)) {
+ TABLE_PREFIXES_TO_BE_EXCLUDED.add(uwfPrefix);
+ }
+ if (StringUtils.isNotBlank(rwfPrefix)) {
+ TABLE_PREFIXES_TO_BE_EXCLUDED.add(rwfPrefix);
}
StreamResult streamResult = new StreamResult(os);
http://git-wip-us.apache.org/repos/asf/syncope/blob/6f24e817/syncope620/server/workflow-activiti/src/main/java/org/apache/syncope/server/workflow/activiti/ActivitiDefinitionLoader.java
----------------------------------------------------------------------
diff --git a/syncope620/server/workflow-activiti/src/main/java/org/apache/syncope/server/workflow/activiti/ActivitiDefinitionLoader.java b/syncope620/server/workflow-activiti/src/main/java/org/apache/syncope/server/workflow/activiti/ActivitiDefinitionLoader.java
index 04ffdb6..4d81a4e 100644
--- a/syncope620/server/workflow-activiti/src/main/java/org/apache/syncope/server/workflow/activiti/ActivitiDefinitionLoader.java
+++ b/syncope620/server/workflow-activiti/src/main/java/org/apache/syncope/server/workflow/activiti/ActivitiDefinitionLoader.java
@@ -32,12 +32,14 @@ import org.activiti.engine.repository.ProcessDefinition;
import org.activiti.spring.SpringProcessEngineConfiguration;
import org.apache.commons.io.IOUtils;
import org.apache.syncope.server.misc.spring.ResourceWithFallbackLoader;
-import org.apache.syncope.server.workflow.api.WorkflowDefinitionLoader;
+import org.apache.syncope.server.persistence.api.SyncopeLoader;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
-public class ActivitiDefinitionLoader implements WorkflowDefinitionLoader {
+@Component
+public class ActivitiDefinitionLoader implements SyncopeLoader {
private static final Logger LOG = LoggerFactory.getLogger(ActivitiDefinitionLoader.class);
@@ -54,16 +56,8 @@ public class ActivitiDefinitionLoader implements WorkflowDefinitionLoader {
private ActivitiImportUtils importUtils;
@Override
- public String getPrefix() {
- return "ACT_";
- }
-
- @Override
- public void init() {
- // jump to the next ID block
- for (int i = 0; i < conf.getIdBlockSize(); i++) {
- conf.getIdGenerator().getNextId();
- }
+ public Integer getPriority() {
+ return Integer.MIN_VALUE;
}
@Override
@@ -100,5 +94,10 @@ public class ActivitiDefinitionLoader implements WorkflowDefinitionLoader {
IOUtils.closeQuietly(wfIn);
}
}
+
+ // jump to the next ID block
+ for (int i = 0; i < conf.getIdBlockSize(); i++) {
+ conf.getIdGenerator().getNextId();
+ }
}
}
http://git-wip-us.apache.org/repos/asf/syncope/blob/6f24e817/syncope620/server/workflow-activiti/src/main/java/org/apache/syncope/server/workflow/activiti/ActivitiUserWorkflowAdapter.java
----------------------------------------------------------------------
diff --git a/syncope620/server/workflow-activiti/src/main/java/org/apache/syncope/server/workflow/activiti/ActivitiUserWorkflowAdapter.java b/syncope620/server/workflow-activiti/src/main/java/org/apache/syncope/server/workflow/activiti/ActivitiUserWorkflowAdapter.java
index 845362c..90dc106 100644
--- a/syncope620/server/workflow-activiti/src/main/java/org/apache/syncope/server/workflow/activiti/ActivitiUserWorkflowAdapter.java
+++ b/syncope620/server/workflow-activiti/src/main/java/org/apache/syncope/server/workflow/activiti/ActivitiUserWorkflowAdapter.java
@@ -76,7 +76,6 @@ import org.apache.syncope.server.provisioning.api.WorkflowResult;
import org.apache.syncope.server.provisioning.api.data.UserDataBinder;
import org.apache.syncope.server.workflow.api.WorkflowDefinitionFormat;
import org.apache.syncope.server.workflow.api.WorkflowException;
-import org.apache.syncope.server.workflow.api.WorkflowDefinitionLoader;
import org.apache.syncope.server.workflow.java.AbstractUserWorkflowAdapter;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -160,8 +159,8 @@ public class ActivitiUserWorkflowAdapter extends AbstractUserWorkflowAdapter {
private UserDataBinder userDataBinder;
@Override
- public Class<? extends WorkflowDefinitionLoader> getDefinitionLoaderClass() {
- return ActivitiDefinitionLoader.class;
+ public String getPrefix() {
+ return "ACT_";
}
private void throwException(final ActivitiException e, final String defaultMessage) {
http://git-wip-us.apache.org/repos/asf/syncope/blob/6f24e817/syncope620/server/workflow-api/src/main/java/org/apache/syncope/server/workflow/api/WorkflowAdapter.java
----------------------------------------------------------------------
diff --git a/syncope620/server/workflow-api/src/main/java/org/apache/syncope/server/workflow/api/WorkflowAdapter.java b/syncope620/server/workflow-api/src/main/java/org/apache/syncope/server/workflow/api/WorkflowAdapter.java
index 2c5d880..3388830 100644
--- a/syncope620/server/workflow-api/src/main/java/org/apache/syncope/server/workflow/api/WorkflowAdapter.java
+++ b/syncope620/server/workflow-api/src/main/java/org/apache/syncope/server/workflow/api/WorkflowAdapter.java
@@ -28,13 +28,9 @@ import org.apache.syncope.server.persistence.api.dao.NotFoundException;
public interface WorkflowAdapter {
/**
- * Give the class to be instantiated and invoked by SpringContextInitializer for loading anything needed by this
- * adapter.
- *
- * @return null if no init is needed or the WorkflowLoader class for handling initialization
- * @see org.apache.syncope.core.init.SpringContextInitializer
+ * @return any string that might be interpreted as "prefix"e; (say table prefix in SQL environments)
*/
- Class<? extends WorkflowDefinitionLoader> getDefinitionLoaderClass();
+ String getPrefix();
/**
* Export workflow definition.
http://git-wip-us.apache.org/repos/asf/syncope/blob/6f24e817/syncope620/server/workflow-api/src/main/java/org/apache/syncope/server/workflow/api/WorkflowDefinitionLoader.java
----------------------------------------------------------------------
diff --git a/syncope620/server/workflow-api/src/main/java/org/apache/syncope/server/workflow/api/WorkflowDefinitionLoader.java b/syncope620/server/workflow-api/src/main/java/org/apache/syncope/server/workflow/api/WorkflowDefinitionLoader.java
deleted file mode 100644
index 5a3d7f4..0000000
--- a/syncope620/server/workflow-api/src/main/java/org/apache/syncope/server/workflow/api/WorkflowDefinitionLoader.java
+++ /dev/null
@@ -1,29 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.syncope.server.workflow.api;
-
-public interface WorkflowDefinitionLoader {
-
- void load();
-
- void init();
-
- String getPrefix();
-
-}
http://git-wip-us.apache.org/repos/asf/syncope/blob/6f24e817/syncope620/server/workflow-java/src/main/java/org/apache/syncope/server/workflow/java/AbstractRoleWorkflowAdapter.java
----------------------------------------------------------------------
diff --git a/syncope620/server/workflow-java/src/main/java/org/apache/syncope/server/workflow/java/AbstractRoleWorkflowAdapter.java b/syncope620/server/workflow-java/src/main/java/org/apache/syncope/server/workflow/java/AbstractRoleWorkflowAdapter.java
index 95998e4..9c496e3 100644
--- a/syncope620/server/workflow-java/src/main/java/org/apache/syncope/server/workflow/java/AbstractRoleWorkflowAdapter.java
+++ b/syncope620/server/workflow-java/src/main/java/org/apache/syncope/server/workflow/java/AbstractRoleWorkflowAdapter.java
@@ -27,7 +27,6 @@ import org.apache.syncope.server.provisioning.api.WorkflowResult;
import org.apache.syncope.server.provisioning.api.data.RoleDataBinder;
import org.apache.syncope.server.workflow.api.RoleWorkflowAdapter;
import org.apache.syncope.server.workflow.api.WorkflowException;
-import org.apache.syncope.server.workflow.api.WorkflowDefinitionLoader;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;
@@ -44,7 +43,7 @@ public abstract class AbstractRoleWorkflowAdapter implements RoleWorkflowAdapter
protected EntityFactory entityFactory;
@Override
- public Class<? extends WorkflowDefinitionLoader> getDefinitionLoaderClass() {
+ public String getPrefix() {
return null;
}
http://git-wip-us.apache.org/repos/asf/syncope/blob/6f24e817/syncope620/server/workflow-java/src/main/java/org/apache/syncope/server/workflow/java/AbstractUserWorkflowAdapter.java
----------------------------------------------------------------------
diff --git a/syncope620/server/workflow-java/src/main/java/org/apache/syncope/server/workflow/java/AbstractUserWorkflowAdapter.java b/syncope620/server/workflow-java/src/main/java/org/apache/syncope/server/workflow/java/AbstractUserWorkflowAdapter.java
index ae13d0b..94b1a67 100644
--- a/syncope620/server/workflow-java/src/main/java/org/apache/syncope/server/workflow/java/AbstractUserWorkflowAdapter.java
+++ b/syncope620/server/workflow-java/src/main/java/org/apache/syncope/server/workflow/java/AbstractUserWorkflowAdapter.java
@@ -27,7 +27,6 @@ import org.apache.syncope.server.provisioning.api.WorkflowResult;
import org.apache.syncope.server.provisioning.api.data.UserDataBinder;
import org.apache.syncope.server.workflow.api.UserWorkflowAdapter;
import org.apache.syncope.server.workflow.api.WorkflowException;
-import org.apache.syncope.server.workflow.api.WorkflowDefinitionLoader;
import org.identityconnectors.common.Base64;
import org.identityconnectors.common.security.EncryptorFactory;
import org.springframework.beans.factory.annotation.Autowired;
@@ -56,7 +55,7 @@ public abstract class AbstractUserWorkflowAdapter implements UserWorkflowAdapter
}
@Override
- public Class<? extends WorkflowDefinitionLoader> getDefinitionLoaderClass() {
+ public String getPrefix() {
return null;
}
[2/2] syncope git commit: [SYNCOPE-620] Simplifying Activiti init +
splitting task IT cases
Posted by il...@apache.org.
[SYNCOPE-620] Simplifying Activiti init + splitting task IT cases
Project: http://git-wip-us.apache.org/repos/asf/syncope/repo
Commit: http://git-wip-us.apache.org/repos/asf/syncope/commit/6f24e817
Tree: http://git-wip-us.apache.org/repos/asf/syncope/tree/6f24e817
Diff: http://git-wip-us.apache.org/repos/asf/syncope/diff/6f24e817
Branch: refs/heads/2_0_X
Commit: 6f24e817019a627a6bfe8c6e36af56f04a237983
Parents: 16984bd
Author: Francesco Chicchiriccò <il...@apache.org>
Authored: Mon Jan 26 17:27:27 2015 +0100
Committer: Francesco Chicchiriccò <il...@apache.org>
Committed: Mon Jan 26 17:27:27 2015 +0100
----------------------------------------------------------------------
.../server/reference/AbstractTaskITCase.java | 138 ++
.../reference/NotificationTaskITCase.java | 156 ++
.../server/reference/PropagationTaskITCase.java | 150 ++
.../fit/server/reference/PushTaskITCase.java | 354 +++++
.../fit/server/reference/SchedTaskITCase.java | 107 ++
.../fit/server/reference/SyncTaskITCase.java | 694 +++++++++
.../fit/server/reference/TaskITCase.java | 1383 ------------------
.../server/logic/ConfigurationLogic.java | 10 +-
.../server/logic/init/LogicInitializer.java | 29 +-
.../logic/init/WorkflowAdapterLoader.java | 95 --
.../api/content/ContentExporter.java | 3 +-
.../jpa/content/XMLContentExporter.java | 9 +-
.../activiti/ActivitiDefinitionLoader.java | 23 +-
.../activiti/ActivitiUserWorkflowAdapter.java | 5 +-
.../server/workflow/api/WorkflowAdapter.java | 8 +-
.../workflow/api/WorkflowDefinitionLoader.java | 29 -
.../java/AbstractRoleWorkflowAdapter.java | 3 +-
.../java/AbstractUserWorkflowAdapter.java | 3 +-
18 files changed, 1645 insertions(+), 1554 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/syncope/blob/6f24e817/syncope620/fit/reference/src/test/java/org/apache/syncope/fit/server/reference/AbstractTaskITCase.java
----------------------------------------------------------------------
diff --git a/syncope620/fit/reference/src/test/java/org/apache/syncope/fit/server/reference/AbstractTaskITCase.java b/syncope620/fit/reference/src/test/java/org/apache/syncope/fit/server/reference/AbstractTaskITCase.java
new file mode 100644
index 0000000..afc9752
--- /dev/null
+++ b/syncope620/fit/reference/src/test/java/org/apache/syncope/fit/server/reference/AbstractTaskITCase.java
@@ -0,0 +1,138 @@
+/*
+ * 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.server.reference;
+
+import static org.apache.syncope.fit.server.reference.AbstractITCase.taskService;
+import static org.junit.Assert.assertEquals;
+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.TaskExecTO;
+import org.apache.syncope.common.lib.to.UserTO;
+
+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;
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/syncope/blob/6f24e817/syncope620/fit/reference/src/test/java/org/apache/syncope/fit/server/reference/NotificationTaskITCase.java
----------------------------------------------------------------------
diff --git a/syncope620/fit/reference/src/test/java/org/apache/syncope/fit/server/reference/NotificationTaskITCase.java b/syncope620/fit/reference/src/test/java/org/apache/syncope/fit/server/reference/NotificationTaskITCase.java
new file mode 100644
index 0000000..4cd302b
--- /dev/null
+++ b/syncope620/fit/reference/src/test/java/org/apache/syncope/fit/server/reference/NotificationTaskITCase.java
@@ -0,0 +1,156 @@
+/*
+ * 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.server.reference;
+
+import static org.apache.syncope.fit.server.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.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/6f24e817/syncope620/fit/reference/src/test/java/org/apache/syncope/fit/server/reference/PropagationTaskITCase.java
----------------------------------------------------------------------
diff --git a/syncope620/fit/reference/src/test/java/org/apache/syncope/fit/server/reference/PropagationTaskITCase.java b/syncope620/fit/reference/src/test/java/org/apache/syncope/fit/server/reference/PropagationTaskITCase.java
new file mode 100644
index 0000000..a79e1d8
--- /dev/null
+++ b/syncope620/fit/reference/src/test/java/org/apache/syncope/fit/server/reference/PropagationTaskITCase.java
@@ -0,0 +1,150 @@
+/*
+ * 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.server.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 java.util.ArrayList;
+import java.util.List;
+import javax.ws.rs.core.Response;
+import org.apache.syncope.common.lib.SyncopeClientException;
+import org.apache.syncope.common.lib.to.AbstractTaskTO;
+import org.apache.syncope.common.lib.to.BulkAction;
+import org.apache.syncope.common.lib.to.PagedResult;
+import org.apache.syncope.common.lib.to.PropagationTaskTO;
+import org.apache.syncope.common.lib.to.ReportExecTO;
+import org.apache.syncope.common.lib.to.TaskExecTO;
+import org.apache.syncope.common.lib.to.UserTO;
+import org.apache.syncope.common.lib.types.PropagationTaskExecStatus;
+import org.apache.syncope.common.lib.types.TaskType;
+import org.junit.FixMethodOrder;
+import org.junit.Test;
+import org.junit.runners.MethodSorters;
+
+@FixMethodOrder(MethodSorters.JVM)
+public class PropagationTaskITCase extends AbstractTaskITCase {
+
+ @Test
+ public void paginatedList() {
+ PagedResult<PropagationTaskTO> tasks = taskService.list(TaskType.PROPAGATION, 1, 2);
+
+ assertNotNull(tasks);
+ assertFalse(tasks.getResult().isEmpty());
+ assertEquals(2, tasks.getResult().size());
+
+ for (AbstractTaskTO task : tasks.getResult()) {
+ assertNotNull(task);
+ }
+
+ tasks = taskService.list(TaskType.PROPAGATION, 2, 2);
+
+ assertNotNull(tasks);
+ assertFalse(tasks.getResult().isEmpty());
+
+ for (AbstractTaskTO task : tasks.getResult()) {
+ assertNotNull(task);
+ }
+
+ tasks = taskService.list(TaskType.PROPAGATION, 1000, 2);
+
+ assertNotNull(tasks);
+ assertTrue(tasks.getResult().isEmpty());
+ }
+
+ @Test
+ public void read() {
+ final PropagationTaskTO taskTO = taskService.read(3L);
+ assertNotNull(taskTO);
+ assertNotNull(taskTO.getExecutions());
+ assertTrue(taskTO.getExecutions().isEmpty());
+ }
+
+ @Test
+ public void readExecution() {
+ TaskExecTO taskTO = taskService.readExecution(6L);
+ assertNotNull(taskTO);
+ }
+
+ @Test
+ public void deal() {
+ // Currently test is not re-runnable.
+ // To successfully run test second time it is necessary to restart cargo
+ try {
+ taskService.delete(0L);
+ } catch (SyncopeClientException e) {
+ assertEquals(Response.Status.NOT_FOUND, e.getType().getResponseStatus());
+ }
+ TaskExecTO exec = taskService.execute(1L, false);
+ assertEquals(PropagationTaskExecStatus.SUBMITTED.name(), exec.getStatus());
+
+ ReportExecTO report = new ReportExecTO();
+ report.setStatus(PropagationTaskExecStatus.SUCCESS.name());
+ report.setMessage("OK");
+ taskService.report(exec.getKey(), report);
+ exec = taskService.readExecution(exec.getKey());
+ assertEquals(PropagationTaskExecStatus.SUCCESS.name(), exec.getStatus());
+ assertEquals("OK", exec.getMessage());
+
+ taskService.delete(1L);
+ try {
+ taskService.readExecution(exec.getKey());
+ } catch (SyncopeClientException e) {
+ assertEquals(Response.Status.NOT_FOUND, e.getType().getResponseStatus());
+ }
+ }
+
+ @Test
+ public void issue196() {
+ TaskExecTO exec = taskService.execute(6L, false);
+ assertNotNull(exec);
+ assertEquals(0, exec.getKey());
+ assertNotNull(exec.getTask());
+ }
+
+ @Test
+ public void bulkAction() {
+ final PagedResult<PropagationTaskTO> before = taskService.list(TaskType.PROPAGATION);
+
+ // create user with testdb resource
+ final UserTO userTO = UserITCase.getUniqueSampleTO("taskBulk@apache.org");
+ userTO.getResources().add(RESOURCE_NAME_TESTDB);
+ createUser(userTO);
+
+ final List<PropagationTaskTO> after = new ArrayList<>(
+ taskService.<PropagationTaskTO>list(TaskType.PROPAGATION).getResult());
+
+ after.removeAll(before.getResult());
+
+ assertFalse(after.isEmpty());
+
+ final BulkAction bulkAction = new BulkAction();
+ bulkAction.setOperation(BulkAction.Type.DELETE);
+
+ for (AbstractTaskTO taskTO : after) {
+ bulkAction.getTargets().add(String.valueOf(taskTO.getKey()));
+ }
+
+ taskService.bulk(bulkAction);
+
+ assertFalse(taskService.list(TaskType.PROPAGATION).getResult().containsAll(after));
+ }
+}
http://git-wip-us.apache.org/repos/asf/syncope/blob/6f24e817/syncope620/fit/reference/src/test/java/org/apache/syncope/fit/server/reference/PushTaskITCase.java
----------------------------------------------------------------------
diff --git a/syncope620/fit/reference/src/test/java/org/apache/syncope/fit/server/reference/PushTaskITCase.java b/syncope620/fit/reference/src/test/java/org/apache/syncope/fit/server/reference/PushTaskITCase.java
new file mode 100644
index 0000000..f845997
--- /dev/null
+++ b/syncope620/fit/reference/src/test/java/org/apache/syncope/fit/server/reference/PushTaskITCase.java
@@ -0,0 +1,354 @@
+/*
+ * 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.server.reference;
+
+import static org.apache.syncope.fit.server.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.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.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.UnmatchingRule;
+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.getRAttrTemplates().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);
+ }
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/syncope/blob/6f24e817/syncope620/fit/reference/src/test/java/org/apache/syncope/fit/server/reference/SchedTaskITCase.java
----------------------------------------------------------------------
diff --git a/syncope620/fit/reference/src/test/java/org/apache/syncope/fit/server/reference/SchedTaskITCase.java b/syncope620/fit/reference/src/test/java/org/apache/syncope/fit/server/reference/SchedTaskITCase.java
new file mode 100644
index 0000000..424ca08
--- /dev/null
+++ b/syncope620/fit/reference/src/test/java/org/apache/syncope/fit/server/reference/SchedTaskITCase.java
@@ -0,0 +1,107 @@
+/*
+ * 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.server.reference;
+
+import static org.apache.syncope.fit.server.reference.AbstractITCase.taskService;
+import static org.apache.syncope.fit.server.reference.AbstractTaskITCase.SCHED_TASK_ID;
+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.fail;
+
+import java.util.List;
+import javax.ws.rs.core.Response;
+import org.apache.syncope.common.lib.to.AbstractTaskTO;
+import org.apache.syncope.common.lib.to.PagedResult;
+import org.apache.syncope.common.lib.to.PushTaskTO;
+import org.apache.syncope.common.lib.to.SchedTaskTO;
+import org.apache.syncope.common.lib.to.SyncTaskTO;
+import org.apache.syncope.common.lib.types.TaskType;
+import org.apache.syncope.common.rest.api.service.TaskService;
+import org.apache.syncope.server.provisioning.api.job.SyncJob;
+import org.junit.FixMethodOrder;
+import org.junit.Test;
+import org.junit.runners.MethodSorters;
+
+@FixMethodOrder(MethodSorters.JVM)
+public class SchedTaskITCase extends AbstractTaskITCase {
+
+ @Test
+ public void getJobClasses() {
+ List<String> jobClasses = syncopeService.info().getTaskJobs();
+ assertNotNull(jobClasses);
+ assertFalse(jobClasses.isEmpty());
+ }
+
+ @Test
+ public void list() {
+ final PagedResult<SchedTaskTO> tasks = taskService.list(TaskType.SCHEDULED);
+ assertFalse(tasks.getResult().isEmpty());
+ for (AbstractTaskTO task : tasks.getResult()) {
+ if (!(task instanceof SchedTaskTO) || task instanceof SyncTaskTO || task instanceof PushTaskTO) {
+ fail();
+ }
+ }
+ }
+
+ @Test
+ public void update() {
+ SchedTaskTO task = taskService.read(SCHED_TASK_ID);
+ assertNotNull(task);
+
+ final SchedTaskTO taskMod = new SchedTaskTO();
+ taskMod.setKey(5);
+ taskMod.setCronExpression(null);
+
+ taskService.update(taskMod.getKey(), taskMod);
+ SchedTaskTO actual = taskService.read(taskMod.getKey());
+ assertNotNull(actual);
+ assertEquals(task.getKey(), actual.getKey());
+ assertNull(actual.getCronExpression());
+ }
+
+ @Test
+ public void issueSYNCOPE144() {
+ SchedTaskTO task = new SchedTaskTO();
+ task.setName("issueSYNCOPE144");
+ task.setDescription("issueSYNCOPE144 Description");
+ task.setJobClassName(SyncJob.class.getName());
+
+ Response response = taskService.create(task);
+ SchedTaskTO actual = getObject(response.getLocation(), TaskService.class, SchedTaskTO.class);
+ assertNotNull(actual);
+ assertEquals("issueSYNCOPE144", actual.getName());
+ assertEquals("issueSYNCOPE144 Description", actual.getDescription());
+
+ task = taskService.read(actual.getKey());
+ assertNotNull(task);
+ assertEquals("issueSYNCOPE144", task.getName());
+ assertEquals("issueSYNCOPE144 Description", task.getDescription());
+
+ task.setName("issueSYNCOPE144_2");
+ task.setDescription("issueSYNCOPE144 Description_2");
+
+ response = taskService.create(task);
+ actual = getObject(response.getLocation(), TaskService.class, SchedTaskTO.class);
+ assertNotNull(actual);
+ assertEquals("issueSYNCOPE144_2", actual.getName());
+ assertEquals("issueSYNCOPE144 Description_2", actual.getDescription());
+ }
+}
http://git-wip-us.apache.org/repos/asf/syncope/blob/6f24e817/syncope620/fit/reference/src/test/java/org/apache/syncope/fit/server/reference/SyncTaskITCase.java
----------------------------------------------------------------------
diff --git a/syncope620/fit/reference/src/test/java/org/apache/syncope/fit/server/reference/SyncTaskITCase.java b/syncope620/fit/reference/src/test/java/org/apache/syncope/fit/server/reference/SyncTaskITCase.java
new file mode 100644
index 0000000..7b66d26
--- /dev/null
+++ b/syncope620/fit/reference/src/test/java/org/apache/syncope/fit/server/reference/SyncTaskITCase.java
@@ -0,0 +1,694 @@
+/*
+ * 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.server.reference;
+
+import static org.apache.syncope.fit.server.reference.AbstractITCase.RESOURCE_NAME_TESTDB;
+import static org.apache.syncope.fit.server.reference.AbstractITCase.RESOURCE_NAME_WS2;
+import static org.apache.syncope.fit.server.reference.AbstractITCase.roleService;
+import static org.apache.syncope.fit.server.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.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.mod.StatusMod;
+import org.apache.syncope.common.lib.mod.UserMod;
+import org.apache.syncope.common.lib.to.AbstractTaskTO;
+import org.apache.syncope.common.lib.to.AttrTO;
+import org.apache.syncope.common.lib.to.ConnInstanceTO;
+import org.apache.syncope.common.lib.to.ConnObjectTO;
+import org.apache.syncope.common.lib.to.MembershipTO;
+import org.apache.syncope.common.lib.to.PagedResult;
+import org.apache.syncope.common.lib.to.ResourceTO;
+import org.apache.syncope.common.lib.to.RoleTO;
+import org.apache.syncope.common.lib.to.SyncPolicyTO;
+import org.apache.syncope.common.lib.to.SyncTaskTO;
+import org.apache.syncope.common.lib.to.TaskExecTO;
+import org.apache.syncope.common.lib.to.UserTO;
+import org.apache.syncope.common.lib.types.CipherAlgorithm;
+import org.apache.syncope.common.lib.types.ConnConfProperty;
+import org.apache.syncope.common.lib.types.PropagationTaskExecStatus;
+import org.apache.syncope.common.lib.types.ResourceDeassociationActionType;
+import org.apache.syncope.common.lib.types.SubjectType;
+import org.apache.syncope.common.lib.types.TaskType;
+import org.apache.syncope.common.lib.wrap.ResourceName;
+import org.apache.syncope.common.rest.api.CollectionWrapper;
+import org.apache.syncope.common.rest.api.service.TaskService;
+import org.apache.syncope.server.misc.security.Encryptor;
+import org.apache.syncope.server.provisioning.java.sync.DBPasswordSyncActions;
+import org.apache.syncope.server.provisioning.java.sync.LDAPPasswordSyncActions;
+import org.identityconnectors.framework.common.objects.Name;
+import org.junit.BeforeClass;
+import org.junit.FixMethodOrder;
+import org.junit.Test;
+import org.junit.runners.MethodSorters;
+import org.springframework.dao.EmptyResultDataAccessException;
+import org.springframework.jdbc.core.JdbcTemplate;
+
+@FixMethodOrder(MethodSorters.JVM)
+public class SyncTaskITCase extends AbstractTaskITCase {
+
+ @BeforeClass
+ public static void testSyncActionsSetup() {
+ SyncTaskTO syncTask = taskService.read(SYNC_TASK_ID);
+ syncTask.getActionsClassNames().add(TestSyncActions.class.getName());
+ taskService.update(SYNC_TASK_ID, syncTask);
+ }
+
+ @Test
+ public void getSyncActionsClasses() {
+ List<String> actions = syncopeService.info().getSyncActions();
+ assertNotNull(actions);
+ assertFalse(actions.isEmpty());
+ }
+
+ @Test
+ public void list() {
+ final PagedResult<SyncTaskTO> tasks = taskService.list(TaskType.SYNCHRONIZATION);
+ assertFalse(tasks.getResult().isEmpty());
+ for (AbstractTaskTO task : tasks.getResult()) {
+ if (!(task instanceof SyncTaskTO)) {
+ fail();
+ }
+ }
+ }
+
+ @Test
+ public void create() {
+ SyncTaskTO task = new SyncTaskTO();
+ task.setName("Test create Sync");
+ task.setResource(RESOURCE_NAME_WS2);
+
+ UserTO userTemplate = new UserTO();
+ userTemplate.getResources().add(RESOURCE_NAME_WS2);
+
+ MembershipTO membershipTO = new MembershipTO();
+ membershipTO.setRoleId(8L);
+ userTemplate.getMemberships().add(membershipTO);
+ task.setUserTemplate(userTemplate);
+
+ RoleTO roleTemplate = new RoleTO();
+ roleTemplate.getResources().add(RESOURCE_NAME_LDAP);
+ task.setRoleTemplate(roleTemplate);
+
+ Response response = taskService.create(task);
+ SyncTaskTO actual = getObject(response.getLocation(), TaskService.class, SyncTaskTO.class);
+ assertNotNull(actual);
+
+ task = taskService.read(actual.getKey());
+ assertNotNull(task);
+ assertEquals(actual.getKey(), task.getKey());
+ assertEquals(actual.getJobClassName(), task.getJobClassName());
+ assertEquals(userTemplate, task.getUserTemplate());
+ assertEquals(roleTemplate, task.getRoleTemplate());
+ }
+
+ @Test
+ public void sync() throws Exception {
+ removeTestUsers();
+
+ // -----------------------------
+ // Create a new user ... it should be updated applying sync policy
+ // -----------------------------
+ UserTO inUserTO = new UserTO();
+ inUserTO.setPassword("password123");
+ String userName = "test9";
+ inUserTO.setUsername(userName);
+ inUserTO.getPlainAttrs().add(attrTO("firstname", "nome9"));
+ inUserTO.getPlainAttrs().add(attrTO("surname", "cognome"));
+ inUserTO.getPlainAttrs().add(attrTO("type", "a type"));
+ inUserTO.getPlainAttrs().add(attrTO("fullname", "nome cognome"));
+ inUserTO.getPlainAttrs().add(attrTO("userId", "puccini@syncope.apache.org"));
+ inUserTO.getPlainAttrs().add(attrTO("email", "puccini@syncope.apache.org"));
+ inUserTO.getDerAttrs().add(attrTO("csvuserid", null));
+
+ inUserTO = createUser(inUserTO);
+ assertNotNull(inUserTO);
+ assertFalse(inUserTO.getResources().contains(RESOURCE_NAME_CSV));
+
+ // -----------------------------
+ try {
+ int usersPre = userService.list(1, 1).getTotalCount();
+ assertNotNull(usersPre);
+
+ execSyncTask(SYNC_TASK_ID, 50, false);
+
+ // after execution of the sync task the user data should be synced from
+ // csv datasource and processed by user template
+ UserTO userTO = userService.read(inUserTO.getKey());
+ assertNotNull(userTO);
+ assertEquals(userName, userTO.getUsername());
+ assertEquals(ActivitiDetector.isActivitiEnabledForUsers(syncopeService)
+ ? "active" : "created", userTO.getStatus());
+ assertEquals("test9@syncope.apache.org", userTO.getPlainAttrMap().get("email").getValues().get(0));
+ assertEquals("test9@syncope.apache.org", userTO.getPlainAttrMap().get("userId").getValues().get(0));
+ assertTrue(Integer.valueOf(userTO.getPlainAttrMap().get("fullname").getValues().get(0)) <= 10);
+ assertTrue(userTO.getResources().contains(RESOURCE_NAME_TESTDB));
+ assertTrue(userTO.getResources().contains(RESOURCE_NAME_WS2));
+
+ // Matching --> Update (no link)
+ assertFalse(userTO.getResources().contains(RESOURCE_NAME_CSV));
+
+ // check for user template
+ userTO = readUser("test7");
+ assertNotNull(userTO);
+ assertEquals("TYPE_OTHER", userTO.getPlainAttrMap().get("type").getValues().get(0));
+ assertEquals(3, userTO.getResources().size());
+ assertTrue(userTO.getResources().contains(RESOURCE_NAME_TESTDB));
+ assertTrue(userTO.getResources().contains(RESOURCE_NAME_WS2));
+ assertEquals(1, userTO.getMemberships().size());
+ assertTrue(userTO.getMemberships().get(0).getPlainAttrMap().containsKey("subscriptionDate"));
+
+ // Unmatching --> Assign (link)
+ assertTrue(userTO.getResources().contains(RESOURCE_NAME_CSV));
+
+ userTO = readUser("test8");
+ assertNotNull(userTO);
+ assertEquals("TYPE_8", userTO.getPlainAttrMap().get("type").getValues().get(0));
+
+ // check for sync results
+ int usersPost = userService.list(1, 1).getTotalCount();
+ assertNotNull(usersPost);
+ assertEquals(usersPre + 9, usersPost);
+
+ // Check for issue 215:
+ // * expected disabled user test1
+ // * expected enabled user test2
+ userTO = readUser("test1");
+ assertNotNull(userTO);
+ assertEquals("suspended", userTO.getStatus());
+
+ userTO = readUser("test3");
+ assertNotNull(userTO);
+ assertEquals("active", userTO.getStatus());
+
+ // SYNCOPE-317
+ execSyncTask(SYNC_TASK_ID, 50, false);
+
+ final Set<Long> pushTaskIds = new HashSet<>();
+ pushTaskIds.add(25L);
+ pushTaskIds.add(26L);
+
+ execSyncTasks(pushTaskIds, 50, false);
+ // Matching --> UNLINK
+ assertFalse(readUser("test9").getResources().contains(RESOURCE_NAME_CSV));
+ assertFalse(readUser("test7").getResources().contains(RESOURCE_NAME_CSV));
+ } finally {
+ removeTestUsers();
+ }
+ }
+
+ @Test
+ public void dryRun() {
+ TaskExecTO execution = execSyncTask(SYNC_TASK_ID, 50, true);
+ assertEquals("Execution of task " + execution.getTask() + " failed with message " + execution.getMessage(),
+ "SUCCESS", execution.getStatus());
+ }
+
+ @Test
+ public void reconcileFromDB() {
+ // update sync task
+ TaskExecTO execution = execSyncTask(7L, 50, false);
+ assertNotNull(execution.getStatus());
+ assertTrue(PropagationTaskExecStatus.valueOf(execution.getStatus()).isSuccessful());
+
+ UserTO userTO = readUser("testuser1");
+ assertNotNull(userTO);
+ assertEquals("reconciled@syncope.apache.org", userTO.getPlainAttrMap().get("userId").getValues().get(0));
+ assertEquals("suspended", userTO.getStatus());
+
+ // enable user on external resource
+ JdbcTemplate jdbcTemplate = new JdbcTemplate(testDataSource);
+ jdbcTemplate.execute("UPDATE TEST SET STATUS=TRUE");
+
+ // re-execute the same SyncTask: now user must be active
+ execution = execSyncTask(7L, 50, false);
+ assertNotNull(execution.getStatus());
+ assertTrue(PropagationTaskExecStatus.valueOf(execution.getStatus()).isSuccessful());
+
+ userTO = readUser("testuser1");
+ assertNotNull(userTO);
+ assertEquals("active", userTO.getStatus());
+ }
+
+ /**
+ * Clean Syncope and LDAP resource status.
+ */
+ private void ldapCleanup() {
+ PagedResult<RoleTO> matchingRoles = roleService.search(
+ SyncopeClient.getRoleSearchConditionBuilder().is("name").equalTo("testLDAPGroup").query());
+ if (matchingRoles.getSize() > 0) {
+ for (RoleTO role : matchingRoles.getResult()) {
+ roleService.bulkDeassociation(role.getKey(),
+ ResourceDeassociationActionType.UNLINK,
+ CollectionWrapper.wrap(RESOURCE_NAME_LDAP, ResourceName.class));
+ roleService.delete(role.getKey());
+ }
+ }
+ PagedResult<UserTO> matchingUsers = userService.search(
+ SyncopeClient.getUserSearchConditionBuilder().is("username").equalTo("syncFromLDAP").query());
+ if (matchingUsers.getSize() > 0) {
+ for (UserTO user : matchingUsers.getResult()) {
+ userService.bulkDeassociation(user.getKey(),
+ ResourceDeassociationActionType.UNLINK,
+ CollectionWrapper.wrap(RESOURCE_NAME_LDAP, ResourceName.class));
+ userService.delete(user.getKey());
+ }
+ }
+ }
+
+ @Test
+ public void reconcileFromLDAP() {
+ // First of all, clear any potential conflict with existing user / role
+ ldapCleanup();
+
+ // Update sync task
+ TaskExecTO execution = execSyncTask(11L, 50, false);
+
+ // 1. verify execution status
+ final String status = execution.getStatus();
+ assertNotNull(status);
+ assertTrue(PropagationTaskExecStatus.valueOf(status).isSuccessful());
+
+ // 2. verify that synchronized role is found, with expected attributes
+ final PagedResult<RoleTO> matchingRoles = roleService.search(
+ SyncopeClient.getRoleSearchConditionBuilder().is("name").equalTo("testLDAPGroup").query());
+ assertNotNull(matchingRoles);
+ assertEquals(1, matchingRoles.getResult().size());
+
+ final PagedResult<UserTO> matchingUsers = userService.search(
+ SyncopeClient.getUserSearchConditionBuilder().is("username").equalTo("syncFromLDAP").query());
+ assertNotNull(matchingUsers);
+ assertEquals(1, matchingUsers.getResult().size());
+
+ // Check for SYNCOPE-436
+ assertEquals("syncFromLDAP",
+ matchingUsers.getResult().get(0).getVirAttrMap().get("virtualReadOnly").getValues().get(0));
+ // Check for SYNCOPE-270
+ assertNotNull(matchingUsers.getResult().get(0).getPlainAttrMap().get("obscure"));
+ // Check for SYNCOPE-123
+ assertNotNull(matchingUsers.getResult().get(0).getPlainAttrMap().get("photo"));
+
+ final RoleTO roleTO = matchingRoles.getResult().iterator().next();
+ assertNotNull(roleTO);
+ assertEquals("testLDAPGroup", roleTO.getName());
+ assertEquals(8L, roleTO.getParent());
+ assertEquals("true", roleTO.getPlainAttrMap().get("show").getValues().get(0));
+ assertEquals(matchingUsers.getResult().iterator().next().getKey(), (long) roleTO.getUserOwner());
+ assertNull(roleTO.getRoleOwner());
+
+ // 3. verify that LDAP group membership is propagated as Syncope role membership
+ final PagedResult<UserTO> members = userService.search(
+ SyncopeClient.getUserSearchConditionBuilder().hasRoles(roleTO.getKey()).query());
+ assertNotNull(members);
+ assertEquals(1, members.getResult().size());
+ }
+
+ @Test
+ public void issueSYNCOPE68() {
+ //-----------------------------
+ // Create a new user ... it should be updated applying sync policy
+ //-----------------------------
+ UserTO userTO = new UserTO();
+ userTO.setPassword("password123");
+ userTO.setUsername("testuser2");
+
+ userTO.getPlainAttrs().add(attrTO("firstname", "testuser2"));
+ userTO.getPlainAttrs().add(attrTO("surname", "testuser2"));
+ userTO.getPlainAttrs().add(attrTO("type", "a type"));
+ userTO.getPlainAttrs().add(attrTO("fullname", "a type"));
+ userTO.getPlainAttrs().add(attrTO("userId", "testuser2@syncope.apache.org"));
+ userTO.getPlainAttrs().add(attrTO("email", "testuser2@syncope.apache.org"));
+
+ userTO.getResources().add(RESOURCE_NAME_NOPROPAGATION2);
+ userTO.getResources().add(RESOURCE_NAME_NOPROPAGATION4);
+
+ MembershipTO membershipTO = new MembershipTO();
+ membershipTO.setRoleId(7L);
+
+ userTO.getMemberships().add(membershipTO);
+
+ userTO = createUser(userTO);
+ assertNotNull(userTO);
+ assertEquals("testuser2", userTO.getUsername());
+ assertEquals(1, userTO.getMemberships().size());
+ assertEquals(3, userTO.getResources().size());
+ //-----------------------------
+
+ try {
+ //-----------------------------
+ // add user template
+ //-----------------------------
+ UserTO template = new UserTO();
+
+ membershipTO = new MembershipTO();
+ membershipTO.setRoleId(10L);
+
+ template.getMemberships().add(membershipTO);
+
+ template.getResources().add(RESOURCE_NAME_NOPROPAGATION4);
+ //-----------------------------
+
+ // Update sync task
+ SyncTaskTO task = taskService.read(9L);
+ assertNotNull(task);
+
+ task.setUserTemplate(template);
+
+ taskService.update(task.getKey(), task);
+ SyncTaskTO actual = taskService.read(task.getKey());
+ assertNotNull(actual);
+ assertEquals(task.getKey(), actual.getKey());
+ assertFalse(actual.getUserTemplate().getResources().isEmpty());
+ assertFalse(actual.getUserTemplate().getMemberships().isEmpty());
+
+ TaskExecTO execution = execSyncTask(actual.getKey(), 50, false);
+ final String status = execution.getStatus();
+ assertNotNull(status);
+ assertTrue(PropagationTaskExecStatus.valueOf(status).isSuccessful());
+
+ userTO = readUser("testuser2");
+ assertNotNull(userTO);
+ assertEquals("testuser2@syncope.apache.org", userTO.getPlainAttrMap().get("userId").getValues().get(0));
+ assertEquals(2, userTO.getMemberships().size());
+ assertEquals(4, userTO.getResources().size());
+ } finally {
+ UserTO dUserTO = deleteUser(userTO.getKey());
+ assertNotNull(dUserTO);
+ }
+ }
+
+ @Test
+ public void issueSYNCOPE230() {
+ // 1. read SyncTask for resource-db-sync (table TESTSYNC on external H2)
+ execSyncTask(10L, 50, false);
+
+ // 3. read e-mail address for user created by the SyncTask first execution
+ UserTO userTO = readUser("issuesyncope230");
+ assertNotNull(userTO);
+ String email = userTO.getPlainAttrMap().get("email").getValues().iterator().next();
+ assertNotNull(email);
+
+ // 4. update TESTSYNC on external H2 by changing e-mail address
+ JdbcTemplate jdbcTemplate = new JdbcTemplate(testDataSource);
+ jdbcTemplate.execute("UPDATE TESTSYNC SET email='updatedSYNCOPE230@syncope.apache.org'");
+
+ // 5. re-execute the SyncTask
+ execSyncTask(10L, 50, false);
+
+ // 6. verify that the e-mail was updated
+ userTO = readUser("issuesyncope230");
+ assertNotNull(userTO);
+ email = userTO.getPlainAttrMap().get("email").getValues().iterator().next();
+ assertNotNull(email);
+ assertEquals("updatedSYNCOPE230@syncope.apache.org", email);
+ }
+
+ @Test
+ public void issueSYNCOPE258() {
+ // -----------------------------
+ // Add a custom correlation rule
+ // -----------------------------
+ SyncPolicyTO policyTO = policyService.read(9L);
+ policyTO.getSpecification().setUserJavaRule(TestSyncRule.class.getName());
+
+ policyService.update(policyTO.getKey(), policyTO);
+ // -----------------------------
+
+ SyncTaskTO task = new SyncTaskTO();
+ task.setName("Test Sync Rule");
+ task.setResource(RESOURCE_NAME_WS2);
+ task.setFullReconciliation(true);
+ task.setPerformCreate(true);
+ task.setPerformDelete(true);
+ task.setPerformUpdate(true);
+
+ Response response = taskService.create(task);
+ SyncTaskTO actual = getObject(response.getLocation(), TaskService.class, SyncTaskTO.class);
+ assertNotNull(actual);
+
+ UserTO userTO = UserITCase.getUniqueSampleTO("s258_1@apache.org");
+ userTO.getResources().clear();
+ userTO.getResources().add(RESOURCE_NAME_WS2);
+
+ createUser(userTO);
+
+ userTO = UserITCase.getUniqueSampleTO("s258_2@apache.org");
+ userTO.getResources().clear();
+ userTO.getResources().add(RESOURCE_NAME_WS2);
+
+ userTO = createUser(userTO);
+
+ // change email in order to unmatch the second user
+ UserMod userMod = new UserMod();
+ userMod.setKey(userTO.getKey());
+ userMod.getPlainAttrsToRemove().add("email");
+ userMod.getPlainAttrsToUpdate().add(attrMod("email", "s258@apache.org"));
+
+ userService.update(userMod.getKey(), userMod);
+
+ execSyncTask(actual.getKey(), 50, false);
+
+ SyncTaskTO executed = taskService.read(actual.getKey());
+ assertEquals(1, executed.getExecutions().size());
+
+ // asser for just one match
+ assertTrue(executed.getExecutions().get(0).getMessage().substring(0, 55) + "...",
+ executed.getExecutions().get(0).getMessage().contains("[updated/failures]: 1/0"));
+ }
+
+ @Test
+ public void issueSYNCOPE272() {
+ removeTestUsers();
+
+ // create user with testdb resource
+ UserTO userTO = UserITCase.getUniqueSampleTO("syncope272@syncope.apache.org");
+ userTO.getResources().add(RESOURCE_NAME_TESTDB);
+
+ userTO = createUser(userTO);
+ try {
+ assertNotNull(userTO);
+ assertEquals(1, userTO.getPropagationStatusTOs().size());
+ assertTrue(userTO.getPropagationStatusTOs().get(0).getStatus().isSuccessful());
+
+ TaskExecTO taskExecTO = execSyncTask(24L, 50, false);
+
+ assertNotNull(taskExecTO.getStatus());
+ assertTrue(PropagationTaskExecStatus.valueOf(taskExecTO.getStatus()).isSuccessful());
+
+ userTO = userService.read(userTO.getKey());
+ assertNotNull(userTO);
+ assertNotNull(userTO.getPlainAttrMap().get("firstname").getValues().get(0));
+ } finally {
+ removeTestUsers();
+ }
+ }
+
+ @Test
+ public void issueSYNCOPE307() {
+ UserTO userTO = UserITCase.getUniqueSampleTO("s307@apache.org");
+
+ AttrTO csvuserid = new AttrTO();
+ csvuserid.setSchema("csvuserid");
+ userTO.getDerAttrs().add(csvuserid);
+
+ userTO.getResources().clear();
+ userTO.getResources().add(RESOURCE_NAME_WS2);
+ userTO.getResources().add(RESOURCE_NAME_CSV);
+
+ userTO = createUser(userTO);
+ assertNotNull(userTO);
+
+ userTO = userService.read(userTO.getKey());
+ assertEquals("virtualvalue", userTO.getVirAttrMap().get("virtualdata").getValues().get(0));
+
+ // Update sync task
+ SyncTaskTO task = taskService.read(12L);
+ assertNotNull(task);
+
+ // add user template
+ UserTO template = new UserTO();
+ template.getResources().add(RESOURCE_NAME_DBVIRATTR);
+
+ AttrTO userId = attrTO("userId", "'s307@apache.org'");
+ template.getPlainAttrs().add(userId);
+
+ AttrTO email = attrTO("email", "'s307@apache.org'");
+ template.getPlainAttrs().add(email);
+
+ task.setUserTemplate(template);
+
+ taskService.update(task.getKey(), task);
+ execSyncTask(task.getKey(), 50, false);
+
+ // check for sync policy
+ userTO = userService.read(userTO.getKey());
+ assertEquals("virtualvalue", userTO.getVirAttrMap().get("virtualdata").getValues().get(0));
+
+ try {
+ final JdbcTemplate jdbcTemplate = new JdbcTemplate(testDataSource);
+
+ String value = jdbcTemplate.queryForObject(
+ "SELECT USERNAME FROM testsync WHERE ID=?", String.class, userTO.getKey());
+ assertEquals("virtualvalue", value);
+ } catch (EmptyResultDataAccessException e) {
+ assertTrue(false);
+ }
+ }
+
+ @Test
+ public void issueSYNCOPE313DB() throws Exception {
+ // 1. create user in DB
+ UserTO user = UserITCase.getUniqueSampleTO("syncope313-db@syncope.apache.org");
+ user.setPassword("security");
+ user.getResources().add(RESOURCE_NAME_TESTDB);
+ user = createUser(user);
+ assertNotNull(user);
+ assertFalse(user.getResources().isEmpty());
+
+ // 2. Check that the DB resource has the correct password
+ final JdbcTemplate jdbcTemplate = new JdbcTemplate(testDataSource);
+ String value = jdbcTemplate.queryForObject(
+ "SELECT PASSWORD FROM test WHERE ID=?", String.class, user.getUsername());
+ assertEquals(Encryptor.getInstance().encode("security", CipherAlgorithm.SHA1), value.toUpperCase());
+
+ // 3. Update the password in the DB
+ String newPassword = Encryptor.getInstance().encode("new-security", CipherAlgorithm.SHA1);
+ jdbcTemplate.execute(
+ "UPDATE test set PASSWORD='" + newPassword + "' where ID='" + user.getUsername() + "'");
+
+ // 4. Sync the user from the resource
+ SyncTaskTO syncTask = new SyncTaskTO();
+ syncTask.setName("DB Sync Task");
+ syncTask.setPerformCreate(true);
+ syncTask.setPerformUpdate(true);
+ syncTask.setFullReconciliation(true);
+ syncTask.setResource(RESOURCE_NAME_TESTDB);
+ syncTask.getActionsClassNames().add(DBPasswordSyncActions.class.getName());
+ Response taskResponse = taskService.create(syncTask);
+
+ SyncTaskTO actual = getObject(taskResponse.getLocation(), TaskService.class, SyncTaskTO.class);
+ assertNotNull(actual);
+
+ syncTask = taskService.read(actual.getKey());
+ assertNotNull(syncTask);
+ assertEquals(actual.getKey(), syncTask.getKey());
+ assertEquals(actual.getJobClassName(), syncTask.getJobClassName());
+
+ TaskExecTO execution = execSyncTask(syncTask.getKey(), 50, false);
+ final String status = execution.getStatus();
+ assertNotNull(status);
+ assertTrue(PropagationTaskExecStatus.valueOf(status).isSuccessful());
+
+ // 5. Test the sync'd user
+ UserTO updatedUser = userService.read(user.getKey());
+ assertEquals(newPassword, updatedUser.getPassword());
+
+ // 6. Delete SyncTask + user
+ taskService.delete(syncTask.getKey());
+ deleteUser(user.getKey());
+ }
+
+ @Test
+ public void issueSYNCOPE313LDAP() throws Exception {
+ // First of all, clear any potential conflict with existing user / role
+ ldapCleanup();
+
+ // 1. create user in LDAP
+ UserTO user = UserITCase.getUniqueSampleTO("syncope313-ldap@syncope.apache.org");
+ user.setPassword("security");
+ user.getResources().add(RESOURCE_NAME_LDAP);
+ user = createUser(user);
+ assertNotNull(user);
+ assertFalse(user.getResources().isEmpty());
+
+ // 2. request to change password only on Syncope and not on LDAP
+ UserMod userMod = new UserMod();
+ userMod.setKey(user.getKey());
+ userMod.setPassword("new-security");
+ StatusMod pwdPropRequest = new StatusMod();
+ pwdPropRequest.setOnSyncope(true);
+ pwdPropRequest.getResourceNames().clear();
+ userMod.setPwdPropRequest(pwdPropRequest);
+ updateUser(userMod);
+
+ // 3. Check that the Syncope user now has the changed password
+ UserTO updatedUser = userService.read(user.getKey());
+ String encodedNewPassword = Encryptor.getInstance().encode("new-security", CipherAlgorithm.SHA1);
+ assertEquals(encodedNewPassword, updatedUser.getPassword());
+
+ // 4. Check that the LDAP resource has the old password
+ ConnObjectTO connObject =
+ resourceService.getConnectorObject(RESOURCE_NAME_LDAP, SubjectType.USER, user.getKey());
+ assertNotNull(getLdapRemoteObject(
+ connObject.getPlainAttrMap().get(Name.NAME).getValues().get(0),
+ "security",
+ connObject.getPlainAttrMap().get(Name.NAME).getValues().get(0)));
+
+ // 5. Update the LDAP Connector to retrieve passwords
+ ResourceTO ldapResource = resourceService.read(RESOURCE_NAME_LDAP);
+ ConnInstanceTO resourceConnector = connectorService.read(ldapResource.getConnectorId());
+ ConnConfProperty property = resourceConnector.getConfigurationMap().get("retrievePasswordsWithSearch");
+ property.getValues().clear();
+ property.getValues().add(Boolean.TRUE);
+ connectorService.update(ldapResource.getConnectorId(), resourceConnector);
+
+ // 6. Sync the user from the resource
+ SyncTaskTO syncTask = new SyncTaskTO();
+ syncTask.setName("LDAP Sync Task");
+ syncTask.setPerformCreate(true);
+ syncTask.setPerformUpdate(true);
+ syncTask.setFullReconciliation(true);
+ syncTask.setResource(RESOURCE_NAME_LDAP);
+ syncTask.getActionsClassNames().add(LDAPPasswordSyncActions.class.getName());
+ Response taskResponse = taskService.create(syncTask);
+
+ SyncTaskTO actual = getObject(taskResponse.getLocation(), TaskService.class, SyncTaskTO.class);
+ assertNotNull(actual);
+
+ syncTask = taskService.read(actual.getKey());
+ assertNotNull(syncTask);
+ assertEquals(actual.getKey(), syncTask.getKey());
+ assertEquals(actual.getJobClassName(), syncTask.getJobClassName());
+
+ TaskExecTO execution = execSyncTask(syncTask.getKey(), 50, false);
+ final String status = execution.getStatus();
+ assertNotNull(status);
+ assertTrue(PropagationTaskExecStatus.valueOf(status).isSuccessful());
+
+ // 7. Test the sync'd user
+ String syncedPassword = Encryptor.getInstance().encode("security", CipherAlgorithm.SHA1);
+ updatedUser = userService.read(user.getKey());
+ assertEquals(syncedPassword, updatedUser.getPassword());
+
+ // 8. Delete SyncTask + user + reset the connector
+ taskService.delete(syncTask.getKey());
+ property.getValues().clear();
+ property.getValues().add(Boolean.FALSE);
+ connectorService.update(ldapResource.getConnectorId(), resourceConnector);
+ deleteUser(updatedUser.getKey());
+ }
+}