You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@syncope.apache.org by fm...@apache.org on 2012/05/23 15:33:39 UTC

svn commit: r1341859 - in /incubator/syncope/trunk: build-tools/src/main/resources/ client/src/main/java/org/apache/syncope/client/util/ core/src/main/java/org/apache/syncope/core/util/ core/src/main/resources/META-INF/ core/src/test/java/org/apache/sy...

Author: fmartelli
Date: Wed May 23 13:33:37 2012
New Revision: 1341859

URL: http://svn.apache.org/viewvc?rev=1341859&view=rev
Log:
SYNCOPE-68 added incremental diff

Modified:
    incubator/syncope/trunk/build-tools/src/main/resources/testdb.sql
    incubator/syncope/trunk/client/src/main/java/org/apache/syncope/client/util/AttributableOperations.java
    incubator/syncope/trunk/core/src/main/java/org/apache/syncope/core/util/ConnObjectUtil.java
    incubator/syncope/trunk/core/src/main/resources/META-INF/orm.xml
    incubator/syncope/trunk/core/src/main/resources/META-INF/orm.xml.oracle
    incubator/syncope/trunk/core/src/test/java/org/apache/syncope/core/persistence/dao/EntitlementTest.java
    incubator/syncope/trunk/core/src/test/java/org/apache/syncope/core/persistence/dao/RoleTest.java
    incubator/syncope/trunk/core/src/test/java/org/apache/syncope/core/persistence/dao/TaskTest.java
    incubator/syncope/trunk/core/src/test/java/org/apache/syncope/core/persistence/relationships/ConnInstanceTest.java
    incubator/syncope/trunk/core/src/test/java/org/apache/syncope/core/rest/ConnInstanceTestITCase.java
    incubator/syncope/trunk/core/src/test/java/org/apache/syncope/core/rest/TaskTestITCase.java
    incubator/syncope/trunk/core/src/test/resources/content.xml

Modified: incubator/syncope/trunk/build-tools/src/main/resources/testdb.sql
URL: http://svn.apache.org/viewvc/incubator/syncope/trunk/build-tools/src/main/resources/testdb.sql?rev=1341859&r1=1341858&r2=1341859&view=diff
==============================================================================
--- incubator/syncope/trunk/build-tools/src/main/resources/testdb.sql (original)
+++ incubator/syncope/trunk/build-tools/src/main/resources/testdb.sql Wed May 23 13:33:37 2012
@@ -18,3 +18,12 @@ password VARCHAR(255) NOT NULL,
 status VARCHAR(5));
 
 INSERT INTO test VALUES ('testuser1', 'password', 'false');
+
+-- this table must be created in order to provide a specific test for issueSYNCOPE68
+DROP TABLE test2 IF EXISTS;
+CREATE TABLE test2 (
+id VARCHAR(50) PRIMARY KEY,
+password VARCHAR(255) NOT NULL,
+status VARCHAR(5));
+
+INSERT INTO test2 VALUES ('testuser2', 'password321', 'false');

Modified: incubator/syncope/trunk/client/src/main/java/org/apache/syncope/client/util/AttributableOperations.java
URL: http://svn.apache.org/viewvc/incubator/syncope/trunk/client/src/main/java/org/apache/syncope/client/util/AttributableOperations.java?rev=1341859&r1=1341858&r2=1341859&view=diff
==============================================================================
--- incubator/syncope/trunk/client/src/main/java/org/apache/syncope/client/util/AttributableOperations.java (original)
+++ incubator/syncope/trunk/client/src/main/java/org/apache/syncope/client/util/AttributableOperations.java Wed May 23 13:33:37 2012
@@ -99,8 +99,11 @@ public final class AttributableOperation
         }
     }
 
-    private static void diff(final AbstractAttributableTO updated, final AbstractAttributableTO original,
-            final AbstractAttributableMod result) {
+    private static void diff(
+            final AbstractAttributableTO updated,
+            final AbstractAttributableTO original,
+            final AbstractAttributableMod result,
+            final boolean incremental) {
 
         // 1. check same id
         if (updated.getId() != original.getId()) {
@@ -114,7 +117,10 @@ public final class AttributableOperation
 
         Set<String> originalAttrNames = new HashSet<String>(originalAttrs.keySet());
         originalAttrNames.removeAll(updatedAttrs.keySet());
-        result.setAttributesToBeRemoved(originalAttrNames);
+
+        if (!incremental) {
+            result.setAttributesToBeRemoved(originalAttrNames);
+        }
 
         Set<String> emptyUpdatedAttrs = new HashSet<String>();
         for (Map.Entry<String, AttributeTO> entry : updatedAttrs.entrySet()) {
@@ -136,7 +142,10 @@ public final class AttributableOperation
 
         originalAttrNames = new HashSet<String>(originalAttrs.keySet());
         originalAttrNames.removeAll(updatedAttrs.keySet());
-        result.setDerivedAttributesToBeRemoved(originalAttrNames);
+
+        if (!incremental) {
+            result.setDerivedAttributesToBeRemoved(originalAttrNames);
+        }
 
         Set<String> updatedAttrNames = new HashSet<String>(updatedAttrs.keySet());
         updatedAttrNames.removeAll(originalAttrs.keySet());
@@ -148,7 +157,10 @@ public final class AttributableOperation
 
         originalAttrNames = new HashSet<String>(originalAttrs.keySet());
         originalAttrNames.removeAll(updatedAttrs.keySet());
-        result.setVirtualAttributesToBeRemoved(originalAttrNames);
+
+        if (!incremental) {
+            result.setVirtualAttributesToBeRemoved(originalAttrNames);
+        }
 
         populate(updatedAttrs, originalAttrs, result, true);
 
@@ -160,7 +172,10 @@ public final class AttributableOperation
         result.setResourcesToBeAdded(updatedRes);
 
         originalRes.removeAll(updated.getResources());
-        result.setResourcesToBeRemoved(originalRes);
+
+        if (!incremental) {
+            result.setResourcesToBeRemoved(originalRes);
+        }
     }
 
     /**
@@ -171,9 +186,21 @@ public final class AttributableOperation
      * @return UserMod containing differences
      */
     public static UserMod diff(final UserTO updated, final UserTO original) {
+        return diff(updated, original, false);
+    }
+
+    /**
+     * Calculate modifications needed by first in order to be equal to second.
+     *
+     * @param updated updated UserTO
+     * @param original original UserTO
+     * @param incremental perform incremental diff (without removing existing info)
+     * @return UserMod containing differences
+     */
+    public static UserMod diff(final UserTO updated, final UserTO original, boolean incremental) {
         UserMod result = new UserMod();
 
-        diff(updated, original, result);
+        diff(updated, original, result, incremental);
 
         // 1. password
         if (original.getPassword() != null && !original.getPassword().equals(updated.getPassword())) {
@@ -196,7 +223,7 @@ public final class AttributableOperation
             membMod.setRole(entry.getValue().getRoleId());
 
             if (originalMembs.containsKey(entry.getKey())) {
-                diff(entry.getValue(), originalMembs.get(entry.getKey()), membMod);
+                diff(entry.getValue(), originalMembs.get(entry.getKey()), membMod, false);
             } else {
                 for (AttributeTO attr : entry.getValue().getAttributes()) {
 
@@ -232,10 +259,12 @@ public final class AttributableOperation
             }
         }
 
-        Set<Long> originalRoles = new HashSet<Long>(originalMembs.keySet());
-        originalRoles.removeAll(updatedMembs.keySet());
-        for (Long roleId : originalRoles) {
-            result.addMembershipToBeRemoved(originalMembs.get(roleId).getId());
+        if (!incremental) {
+            Set<Long> originalRoles = new HashSet<Long>(originalMembs.keySet());
+            originalRoles.removeAll(updatedMembs.keySet());
+            for (Long roleId : originalRoles) {
+                result.addMembershipToBeRemoved(originalMembs.get(roleId).getId());
+            }
         }
 
         return result;
@@ -251,7 +280,7 @@ public final class AttributableOperation
     public static RoleMod diff(final RoleTO updated, final RoleTO original) {
         RoleMod result = new RoleMod();
 
-        diff(updated, original, result);
+        diff(updated, original, result, false);
 
         // 1. inheritance
         result.setInheritAccountPolicy(updated.isInheritAccountPolicy());

Modified: incubator/syncope/trunk/core/src/main/java/org/apache/syncope/core/util/ConnObjectUtil.java
URL: http://svn.apache.org/viewvc/incubator/syncope/trunk/core/src/main/java/org/apache/syncope/core/util/ConnObjectUtil.java?rev=1341859&r1=1341858&r2=1341859&view=diff
==============================================================================
--- incubator/syncope/trunk/core/src/main/java/org/apache/syncope/core/util/ConnObjectUtil.java (original)
+++ incubator/syncope/trunk/core/src/main/java/org/apache/syncope/core/util/ConnObjectUtil.java Wed May 23 13:33:37 2012
@@ -121,7 +121,9 @@ public class ConnObjectUtil {
             }
         }
 
-        return AttributableOperations.diff(updated, original);
+        final UserMod userMod = AttributableOperations.diff(updated, original, true);
+
+        return userMod;
     }
 
     private UserTO getUserTOFromConnObject(final ConnectorObject obj, final SyncTask syncTask) {

Modified: incubator/syncope/trunk/core/src/main/resources/META-INF/orm.xml
URL: http://svn.apache.org/viewvc/incubator/syncope/trunk/core/src/main/resources/META-INF/orm.xml?rev=1341859&r1=1341858&r2=1341859&view=diff
==============================================================================
--- incubator/syncope/trunk/core/src/main/resources/META-INF/orm.xml (original)
+++ incubator/syncope/trunk/core/src/main/resources/META-INF/orm.xml Wed May 23 13:33:37 2012
@@ -41,7 +41,7 @@ under the License.
     <attributes>
       <id name="id">
         <generated-value generator="SEQ_SyncopeRole" strategy="TABLE"/>
-        <table-generator name="SEQ_SyncopeRole" pk-column-value="SEQ_SyncopeRole" initial-value="10"/>
+        <table-generator name="SEQ_SyncopeRole" pk-column-value="SEQ_SyncopeRole" initial-value="100"/>
       </id>
     </attributes>
   </entity>
@@ -50,7 +50,7 @@ under the License.
     <attributes>
       <id name="id">
         <generated-value generator="SEQ_Membership" strategy="TABLE"/>
-        <table-generator name="SEQ_Membership" pk-column-value="SEQ_Membership" initial-value="10"/>
+        <table-generator name="SEQ_Membership" pk-column-value="SEQ_Membership" initial-value="100"/>
       </id>
     </attributes>
   </entity>

Modified: incubator/syncope/trunk/core/src/main/resources/META-INF/orm.xml.oracle
URL: http://svn.apache.org/viewvc/incubator/syncope/trunk/core/src/main/resources/META-INF/orm.xml.oracle?rev=1341859&r1=1341858&r2=1341859&view=diff
==============================================================================
--- incubator/syncope/trunk/core/src/main/resources/META-INF/orm.xml.oracle (original)
+++ incubator/syncope/trunk/core/src/main/resources/META-INF/orm.xml.oracle Wed May 23 13:33:37 2012
@@ -41,7 +41,7 @@ under the License.
     <attributes>
       <id name="id">
         <generated-value generator="SEQ_SyncopeRole" strategy="TABLE"/>
-        <table-generator name="SEQ_SyncopeRole" pk-column-value="SEQ_SyncopeRole" initial-value="10"/>
+        <table-generator name="SEQ_SyncopeRole" pk-column-value="SEQ_SyncopeRole" initial-value="100"/>
       </id>
     </attributes>
   </entity>
@@ -50,7 +50,7 @@ under the License.
     <attributes>
       <id name="id">
         <generated-value generator="SEQ_Membership" strategy="TABLE"/>
-        <table-generator name="SEQ_Membership" pk-column-value="SEQ_Membership" initial-value="10"/>
+        <table-generator name="SEQ_Membership" pk-column-value="SEQ_Membership" initial-value="100"/>
       </id>
     </attributes>
   </entity>

Modified: incubator/syncope/trunk/core/src/test/java/org/apache/syncope/core/persistence/dao/EntitlementTest.java
URL: http://svn.apache.org/viewvc/incubator/syncope/trunk/core/src/test/java/org/apache/syncope/core/persistence/dao/EntitlementTest.java?rev=1341859&r1=1341858&r2=1341859&view=diff
==============================================================================
--- incubator/syncope/trunk/core/src/test/java/org/apache/syncope/core/persistence/dao/EntitlementTest.java (original)
+++ incubator/syncope/trunk/core/src/test/java/org/apache/syncope/core/persistence/dao/EntitlementTest.java Wed May 23 13:33:37 2012
@@ -43,7 +43,7 @@ public class EntitlementTest extends Abs
     public void findAll() {
         List<Entitlement> list = entitlementDAO.findAll();
         // 69 real entitlements + 9 role entitlements
-        assertEquals("did not get expected number of entitlements ", 78, list.size());
+        assertEquals("did not get expected number of entitlements ", 79, list.size());
     }
 
     @Test

Modified: incubator/syncope/trunk/core/src/test/java/org/apache/syncope/core/persistence/dao/RoleTest.java
URL: http://svn.apache.org/viewvc/incubator/syncope/trunk/core/src/test/java/org/apache/syncope/core/persistence/dao/RoleTest.java?rev=1341859&r1=1341858&r2=1341859&view=diff
==============================================================================
--- incubator/syncope/trunk/core/src/test/java/org/apache/syncope/core/persistence/dao/RoleTest.java (original)
+++ incubator/syncope/trunk/core/src/test/java/org/apache/syncope/core/persistence/dao/RoleTest.java Wed May 23 13:33:37 2012
@@ -43,7 +43,7 @@ public class RoleTest extends AbstractTe
     @Test
     public void findAll() {
         List<SyncopeRole> list = roleDAO.findAll();
-        assertEquals("did not get expected number of roles ", 9, list.size());
+        assertEquals("did not get expected number of roles ", 10, list.size());
     }
 
     @Test

Modified: incubator/syncope/trunk/core/src/test/java/org/apache/syncope/core/persistence/dao/TaskTest.java
URL: http://svn.apache.org/viewvc/incubator/syncope/trunk/core/src/test/java/org/apache/syncope/core/persistence/dao/TaskTest.java?rev=1341859&r1=1341858&r2=1341859&view=diff
==============================================================================
--- incubator/syncope/trunk/core/src/test/java/org/apache/syncope/core/persistence/dao/TaskTest.java (original)
+++ incubator/syncope/trunk/core/src/test/java/org/apache/syncope/core/persistence/dao/TaskTest.java Wed May 23 13:33:37 2012
@@ -71,7 +71,7 @@ public class TaskTest extends AbstractTe
         assertEquals(1, sclist.size());
 
         List<SyncTask> sylist = taskDAO.findAll(SyncTask.class);
-        assertEquals(2, sylist.size());
+        assertEquals(3, sylist.size());
 
         ExternalResource resource = resourceDAO.find("ws-target-resource-2");
         assertNotNull(resource);

Modified: incubator/syncope/trunk/core/src/test/java/org/apache/syncope/core/persistence/relationships/ConnInstanceTest.java
URL: http://svn.apache.org/viewvc/incubator/syncope/trunk/core/src/test/java/org/apache/syncope/core/persistence/relationships/ConnInstanceTest.java?rev=1341859&r1=1341858&r2=1341859&view=diff
==============================================================================
--- incubator/syncope/trunk/core/src/test/java/org/apache/syncope/core/persistence/relationships/ConnInstanceTest.java (original)
+++ incubator/syncope/trunk/core/src/test/java/org/apache/syncope/core/persistence/relationships/ConnInstanceTest.java Wed May 23 13:33:37 2012
@@ -63,7 +63,7 @@ public class ConnInstanceTest extends Ab
 
     /**
      * Connector change used to miss connector bean registration.
-     * 
+     *
      * http://code.google.com/p/syncope/issues/detail?id=176
      */
     @Test
@@ -74,8 +74,12 @@ public class ConnInstanceTest extends Ab
 
         List<ExternalResource> resources = connInstance.getResources();
         assertNotNull(resources);
-        assertEquals(1, resources.size());
-        assertEquals("ws-target-resource-nopropagation", resources.get(0).getName());
+        assertEquals(4, resources.size());
+        assertTrue(
+                "ws-target-resource-nopropagation".equalsIgnoreCase(resources.get(0).getName())
+                || "ws-target-resource-nopropagation".equalsIgnoreCase(resources.get(1).getName())
+                || "ws-target-resource-nopropagation".equalsIgnoreCase(resources.get(2).getName())
+                || "ws-target-resource-nopropagation".equalsIgnoreCase(resources.get(3).getName()));
 
         connInstance.addCapability(ConnectorCapability.SEARCH);
 
@@ -85,7 +89,11 @@ public class ConnInstanceTest extends Ab
 
         resources = connInstance.getResources();
         assertNotNull(resources);
-        assertEquals(1, resources.size());
-        assertEquals("ws-target-resource-nopropagation", resources.get(0).getName());
+        assertEquals(4, resources.size());
+        assertTrue(
+                "ws-target-resource-nopropagation".equalsIgnoreCase(resources.get(0).getName())
+                || "ws-target-resource-nopropagation".equalsIgnoreCase(resources.get(1).getName())
+                || "ws-target-resource-nopropagation".equalsIgnoreCase(resources.get(2).getName())
+                || "ws-target-resource-nopropagation".equalsIgnoreCase(resources.get(3).getName()));
     }
 }

Modified: incubator/syncope/trunk/core/src/test/java/org/apache/syncope/core/rest/ConnInstanceTestITCase.java
URL: http://svn.apache.org/viewvc/incubator/syncope/trunk/core/src/test/java/org/apache/syncope/core/rest/ConnInstanceTestITCase.java?rev=1341859&r1=1341858&r2=1341859&view=diff
==============================================================================
--- incubator/syncope/trunk/core/src/test/java/org/apache/syncope/core/rest/ConnInstanceTestITCase.java (original)
+++ incubator/syncope/trunk/core/src/test/java/org/apache/syncope/core/rest/ConnInstanceTestITCase.java Wed May 23 13:33:37 2012
@@ -161,10 +161,9 @@ public class ConnInstanceTestITCase exte
         // check also for the deletion of the created object
         try {
             ConnInstanceTO deletedConn = restTemplate.getForObject(
-                BASE_URL + "connector/delete/{connectorId}.json", 
-                ConnInstanceTO.class, 
-                String.valueOf(actual.getId())
-            );
+                    BASE_URL + "connector/delete/{connectorId}.json",
+                    ConnInstanceTO.class,
+                    String.valueOf(actual.getId()));
             assertNotNull(deletedConn);
         } catch (HttpStatusCodeException e) {
             LOG.error("delete failed", e);
@@ -175,8 +174,8 @@ public class ConnInstanceTestITCase exte
 
         // check the non existence
         try {
-            restTemplate.getForObject(BASE_URL + "connector/read/{connectorId}", ConnInstanceTO.class, String
-                    .valueOf(actual.getId()));
+            restTemplate.getForObject(BASE_URL + "connector/read/{connectorId}", ConnInstanceTO.class,
+                    String.valueOf(actual.getId()));
         } catch (HttpStatusCodeException e) {
             assertEquals(e.getStatusCode(), HttpStatus.NOT_FOUND);
         }
@@ -228,8 +227,8 @@ public class ConnInstanceTestITCase exte
 
         assertNotNull(actual);
 
-        actual = restTemplate.getForObject(BASE_URL + "connector/read/{connectorId}", ConnInstanceTO.class, String
-                .valueOf(actual.getId()));
+        actual = restTemplate.getForObject(BASE_URL + "connector/read/{connectorId}", ConnInstanceTO.class, String.
+                valueOf(actual.getId()));
 
         assertNotNull(actual);
         assertEquals(actual.getBundleName(), connectorTO.getBundleName());
@@ -243,8 +242,8 @@ public class ConnInstanceTestITCase exte
         // Copy resource and connector in order to create new objects.
         // ----------------------------------
         // Retrieve a connector instance template.
-        ConnInstanceTO connInstanceTO = restTemplate.getForObject(BASE_URL + "connector/read/{connectorId}",
-                ConnInstanceTO.class, 103L);
+        ConnInstanceTO connInstanceTO =
+                restTemplate.getForObject(BASE_URL + "connector/read/{connectorId}", ConnInstanceTO.class, 103L);
 
         assertNotNull(connInstanceTO);
 
@@ -252,7 +251,7 @@ public class ConnInstanceTestITCase exte
         List<ResourceTO> resources = Arrays.asList(restTemplate.getForObject(BASE_URL
                 + "resource/list.json?connInstanceId=103", ResourceTO[].class));
 
-        assertEquals(1, resources.size());
+        assertEquals(4, resources.size());
 
         // Retrieve a resource TO template.
         ResourceTO resourceTO = resources.get(0);
@@ -268,8 +267,8 @@ public class ConnInstanceTestITCase exte
         // ----------------------------------
         // Create a new connector instance.
         // ----------------------------------
-        connInstanceTO = restTemplate.postForObject(BASE_URL + "connector/create.json", connInstanceTO,
-                ConnInstanceTO.class);
+        connInstanceTO =
+                restTemplate.postForObject(BASE_URL + "connector/create.json", connInstanceTO, ConnInstanceTO.class);
 
         assertNotNull(connInstanceTO);
         assertTrue(connInstanceTO.getCapabilities().isEmpty());
@@ -522,8 +521,7 @@ public class ConnInstanceTestITCase exte
         assertNotNull(schemaNames);
         assertFalse(schemaNames.isEmpty());
 
-        schemaNames = Arrays.asList(restTemplate
-                .postForObject(BASE_URL + "connector/schema/list", conn, String[].class));
+        schemaNames = Arrays.asList(restTemplate.postForObject(BASE_URL + "connector/schema/list", conn, String[].class));
         assertNotNull(schemaNames);
         assertEquals(0, schemaNames.size());
 

Modified: incubator/syncope/trunk/core/src/test/java/org/apache/syncope/core/rest/TaskTestITCase.java
URL: http://svn.apache.org/viewvc/incubator/syncope/trunk/core/src/test/java/org/apache/syncope/core/rest/TaskTestITCase.java?rev=1341859&r1=1341858&r2=1341859&view=diff
==============================================================================
--- incubator/syncope/trunk/core/src/test/java/org/apache/syncope/core/rest/TaskTestITCase.java (original)
+++ incubator/syncope/trunk/core/src/test/java/org/apache/syncope/core/rest/TaskTestITCase.java Wed May 23 13:33:37 2012
@@ -570,4 +570,124 @@ public class TaskTestITCase extends Abst
         assertNotNull(taskTO);
         assertEquals(1, taskTO.getExecutions().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");
+
+        AttributeTO firstnameTO = new AttributeTO();
+        firstnameTO.setSchema("firstname");
+        firstnameTO.addValue("testuser2");
+        userTO.addAttribute(firstnameTO);
+
+        AttributeTO surnameTO = new AttributeTO();
+        surnameTO.setSchema("surname");
+        surnameTO.addValue("testuser2");
+        userTO.addAttribute(surnameTO);
+
+        AttributeTO typeTO = new AttributeTO();
+        typeTO.setSchema("type");
+        typeTO.addValue("a type");
+        userTO.addAttribute(typeTO);
+
+        AttributeTO fullnameTO = new AttributeTO();
+        fullnameTO.setSchema("fullname");
+        fullnameTO.addValue("testuser2");
+        userTO.addAttribute(fullnameTO);
+
+        AttributeTO userIdTO = new AttributeTO();
+        userIdTO.setSchema("userId");
+        userIdTO.addValue("testuser2@syncope.apache.org");
+        userTO.addAttribute(userIdTO);
+
+        AttributeTO emailTO = new AttributeTO();
+        emailTO.setSchema("email");
+        emailTO.addValue("testuser2@syncope.apache.org");
+        userTO.addAttribute(emailTO);
+
+        userTO.addResource("ws-target-resource-nopropagation2");
+        userTO.addResource("ws-target-resource-nopropagation4");
+
+        MembershipTO membershipTO = new MembershipTO();
+        membershipTO.setRoleId(7L);
+
+        userTO.addMembership(membershipTO);
+
+        userTO = restTemplate.postForObject(BASE_URL + "user/create", userTO, UserTO.class);
+        assertNotNull(userTO);
+        assertEquals("testuser2", userTO.getUsername());
+        assertEquals(1, userTO.getMemberships().size());
+        assertEquals(3, userTO.getResources().size());
+        //-----------------------------
+
+        //-----------------------------
+        //  add user template
+        //-----------------------------
+        UserTO template = new UserTO();
+
+        membershipTO = new MembershipTO();
+        membershipTO.setRoleId(10L);
+
+        template.addMembership(membershipTO);
+
+        template.addResource("ws-target-resource-nopropagation4");
+        //-----------------------------
+
+        // Update sync task
+        SyncTaskTO task = restTemplate.getForObject(BASE_URL + "task/read/{taskId}", SyncTaskTO.class, 9);
+        assertNotNull(task);
+
+        task.setUserTemplate(template);
+
+        SyncTaskTO actual = restTemplate.postForObject(BASE_URL + "task/update/sync", task, SyncTaskTO.class);
+        assertNotNull(actual);
+        assertEquals(task.getId(), actual.getId());
+        assertFalse(actual.getUserTemplate().getResources().isEmpty());
+        assertFalse(actual.getUserTemplate().getMemberships().isEmpty());
+
+        // read executions before sync (dryrun test could be executed before)
+        int preSyncSize = actual.getExecutions().size();
+
+        TaskExecTO execution =
+                restTemplate.postForObject(BASE_URL + "task/execute/{taskId}", null, TaskExecTO.class, actual.getId());
+        assertEquals("JOB_FIRED", execution.getStatus());
+
+        int i = 0;
+        int maxit = 20;
+
+        // wait for sync completion (executions incremented)
+        do {
+            try {
+                Thread.sleep(1000);
+            } catch (InterruptedException e) {
+            }
+
+            actual = restTemplate.getForObject(BASE_URL + "task/read/{taskId}", SyncTaskTO.class, actual.getId());
+
+            assertNotNull(actual);
+            assertNotNull(actual.getExecutions());
+
+            i++;
+
+        } while (preSyncSize == actual.getExecutions().size() && i < maxit);
+
+        assertEquals(1, actual.getExecutions().size());
+
+        final String status = actual.getExecutions().get(0).getStatus();
+        assertNotNull(status);
+        assertTrue(PropagationTaskExecStatus.valueOf(status).isSuccessful());
+
+        userTO = restTemplate.getForObject(BASE_URL + "user/readByUsername/{username}.json", UserTO.class, "testuser2");
+
+        assertNotNull(userTO);
+        assertEquals("testuser2@syncope.apache.org", userTO.getAttributeMap().get("userId").getValues().get(0));
+
+        assertEquals(2, userTO.getMemberships().size());
+        assertEquals(4, userTO.getResources().size());
+    }
 }

Modified: incubator/syncope/trunk/core/src/test/resources/content.xml
URL: http://svn.apache.org/viewvc/incubator/syncope/trunk/core/src/test/resources/content.xml?rev=1341859&r1=1341858&r2=1341859&view=diff
==============================================================================
--- incubator/syncope/trunk/core/src/test/resources/content.xml (original)
+++ incubator/syncope/trunk/core/src/test/resources/content.xml Wed May 23 13:33:37 2012
@@ -65,6 +65,10 @@ under the License.
                inheritVirtualAttributes="1"
                passwordPolicy_id="4"/>
   <SyncopeRole id="9" name="roleForWorkflowApproval" parent_id="1"/>
+  <SyncopeRole id="10"
+               name="managingConsultant" parent_id="6"
+               inheritAttributes="1" inheritDerivedAttributes="1" inheritVirtualAttributes="1"
+               inheritPasswordPolicy="1" inheritAccountPolicy="1"/>
 
   <Membership id="1" syncopeUser_id="1" syncopeRole_id="1"/>
   <Membership id="2" syncopeUser_id="2" syncopeRole_id="1"/>
@@ -235,6 +239,7 @@ under the License.
   <ConnInstance_capabilities ConnInstance_id="101" capabilities="TWO_PHASES_UPDATE"/>
   <ConnInstance_capabilities ConnInstance_id="101" capabilities="TWO_PHASES_DELETE"/>
   <ConnInstance_capabilities ConnInstance_id="101" capabilities="SEARCH"/>
+  <ConnInstance_capabilities ConnInstance_id="101" capabilities="SYNC"/>
 
   <ConnInstance id="102" displayName="ConnInstance102"
                 bundleName="org.connid.bundles.soap"
@@ -280,6 +285,14 @@ under the License.
   <ConnInstance_capabilities ConnInstance_id="105" capabilities="ONE_PHASE_DELETE"/>
   <ConnInstance_capabilities ConnInstance_id="105" capabilities="SEARCH"/>
   <ConnInstance_capabilities ConnInstance_id="105" capabilities="ONE_PHASE_CREATE"/>
+  
+  <ConnInstance id="106" displayName="H2-test2"
+                  bundleName="org.connid.bundles.db.table"
+                  connectorName="org.identityconnectors.databasetable.DatabaseTableConnector"
+                  version="${connid.db.table.version}"
+                  xmlConfiguration="%3Cset%3E%0A++%3Corg.apache.syncope.types.ConnConfProperty%3E%0A++++%3Cschema%3E%0A++++++%3Cname%3Euser%3C/name%3E%0A++++++%3Ctype%3Ejava.lang.String%3C/type%3E%0A++++++%3Crequired%3Efalse%3C/required%3E%0A++++%3C/schema%3E%0A%0A%3Cvalues%3E%0A%3Cjava.lang.String%3Esa%3C/java.lang.String%3E%0A%3C/values%3E%0A%0A++++%3Coverridable%3Efalse%3C/overridable%3E%0A++%3C/org.apache.syncope.types.ConnConfProperty%3E%0A%0A++%3Corg.apache.syncope.types.ConnConfProperty%3E%0A++++%3Cschema%3E%0A++++++%3Cname%3EenabledStatusValue%3C/name%3E%0A++++++%3Ctype%3Ejava.lang.String%3C/type%3E%0A++++++%3Crequired%3Efalse%3C/required%3E%0A++++%3C/schema%3E%0A%0A%3Cvalues%3E%0A%3Cjava.lang.String%3Etrue%3C/java.lang.String%3E%0A%3C/values%3E%0A%0A++++%3Coverridable%3Efalse%3C/overridable%3E%0A++%3C/org.apache.syncope.types.ConnConfProperty%3E%0A%0A++%3Corg.apache.syncope.types.ConnConfProperty%3E%0A++++%3Cschema%3E%0A++++++%3Cname%3EstatusColumn%3C/name%3E%0A++++
 ++%3Ctype%3Ejava.lang.String%3C/type%3E%0A++++++%3Crequired%3Efalse%3C/required%3E%0A++++%3C/schema%3E%0A%0A%3Cvalues%3E%0A%3Cjava.lang.String%3Estatus%3C/java.lang.String%3E%0A%3C/values%3E%0A%0A++++%3Coverridable%3Efalse%3C/overridable%3E%0A++%3C/org.apache.syncope.types.ConnConfProperty%3E%0A%0A++%3Corg.apache.syncope.types.ConnConfProperty%3E%0A++++%3Cschema%3E%0A++++++%3Cname%3EdisabledStatusValue%3C/name%3E%0A++++++%3Ctype%3Ejava.lang.String%3C/type%3E%0A++++++%3Crequired%3Efalse%3C/required%3E%0A++++%3C/schema%3E%0A%0A%3Cvalues%3E%0A%3Cjava.lang.String%3Efalse%3C/java.lang.String%3E%0A%3C/values%3E%0A%0A++++%3Coverridable%3Efalse%3C/overridable%3E%0A++%3C/org.apache.syncope.types.ConnConfProperty%3E%0A%0A++%3Corg.apache.syncope.types.ConnConfProperty%3E%0A++++%3Cschema%3E%0A++++++%3Cname%3EkeyColumn%3C/name%3E%0A++++++%3Ctype%3Ejava.lang.String%3C/type%3E%0A++++++%3Crequired%3Etrue%3C/required%3E%0A++++%3C/schema%3E%0A%0A%3Cvalues%3E%0A%3Cjava.lang.String%3Eid%3C/java
 .lang.String%3E%0A%3C/values%3E%0A%0A++++%3Coverridable%3Efalse%3C/overridable%3E%0A++%3C/org.apache.syncope.types.ConnConfProperty%3E%0A%0A++%3Corg.apache.syncope.types.ConnConfProperty%3E%0A++++%3Cschema%3E%0A++++++%3Cname%3EjdbcUrlTemplate%3C/name%3E%0A++++++%3Ctype%3Ejava.lang.String%3C/type%3E%0A++++++%3Crequired%3Efalse%3C/required%3E%0A++++%3C/schema%3E%0A%0A%3Cvalues%3E%0A%3Cjava.lang.String%3Ejdbc%3Ah2%3Atcp%3A//localhost%3A9092/testdb%3C/java.lang.String%3E%0A%3C/values%3E%0A%0A++++%3Coverridable%3Efalse%3C/overridable%3E%0A++%3C/org.apache.syncope.types.ConnConfProperty%3E%0A%0A++%3Corg.apache.syncope.types.ConnConfProperty%3E%0A++++%3Cschema%3E%0A++++++%3Cname%3EpasswordColumn%3C/name%3E%0A++++++%3Ctype%3Ejava.lang.String%3C/type%3E%0A++++++%3Crequired%3Efalse%3C/required%3E%0A++++%3C/schema%3E%0A%0A%3Cvalues%3E%0A%3Cjava.lang.String%3Epassword%3C/java.lang.String%3E%0A%3C/values%3E%0A%0A++++%3Coverridable%3Efalse%3C/overridable%3E%0A++%3C/org.apache.syncope.type
 s.ConnConfProperty%3E%0A%0A++%3Corg.apache.syncope.types.ConnConfProperty%3E%0A++++%3Cschema%3E%0A++++++%3Cname%3EdefaultStatusValue%3C/name%3E%0A++++++%3Ctype%3Ejava.lang.String%3C/type%3E%0A++++++%3Crequired%3Efalse%3C/required%3E%0A++++%3C/schema%3E%0A%0A%3Cvalues%3E%0A%3Cjava.lang.String%3Etrue%3C/java.lang.String%3E%0A%3C/values%3E%0A%0A++++%3Coverridable%3Efalse%3C/overridable%3E%0A++%3C/org.apache.syncope.types.ConnConfProperty%3E%0A%0A++%3Corg.apache.syncope.types.ConnConfProperty%3E%0A++++%3Cschema%3E%0A++++++%3Cname%3Etable%3C/name%3E%0A++++++%3Ctype%3Ejava.lang.String%3C/type%3E%0A++++++%3Crequired%3Etrue%3C/required%3E%0A++++%3C/schema%3E%0A%0A%3Cvalues%3E%0A%3Cjava.lang.String%3Etest2%3C/java.lang.String%3E%0A%3C/values%3E%0A%0A++++%3Coverridable%3Efalse%3C/overridable%3E%0A++%3C/org.apache.syncope.types.ConnConfProperty%3E%0A%0A++%3Corg.apache.syncope.types.ConnConfProperty%3E%0A++++%3Cschema%3E%0A++++++%3Cname%3Epassword%3C/name%3E%0A++++++%3Ctype%3Eorg.identi
 tyconnectors.common.security.GuardedString%3C/type%3E%0A++++++%3Crequired%3Efalse%3C/required%3E%0A++++%3C/schema%3E%0A%0A%3Cvalues%3E%0A%3Cjava.lang.String%3Esa%3C/java.lang.String%3E%0A%3C/values%3E%0A%0A++++%3Coverridable%3Efalse%3C/overridable%3E%0A++%3C/org.apache.syncope.types.ConnConfProperty%3E%0A%0A++%3Corg.apache.syncope.types.ConnConfProperty%3E%0A++++%3Cschema%3E%0A++++++%3Cname%3EjdbcDriver%3C/name%3E%0A++++++%3Ctype%3Ejava.lang.String%3C/type%3E%0A++++++%3Crequired%3Efalse%3C/required%3E%0A++++%3C/schema%3E%0A%0A%3Cvalues%3E%0A%3Cjava.lang.String%3Eorg.h2.Driver%3C/java.lang.String%3E%0A%3C/values%3E%0A%0A++++%3Coverridable%3Efalse%3C/overridable%3E%0A++%3C/org.apache.syncope.types.ConnConfProperty%3E%0A%0A++%3Corg.apache.syncope.types.ConnConfProperty%3E%0A++++%3Cschema%3E%0A++++++%3Cname%3EcipherAlgorithm%3C/name%3E%0A++++++%3Ctype%3Ejava.lang.String%3C/type%3E%0A++++++%3Crequired%3Etrue%3C/required%3E%0A++++%3C/schema%3E%0A%0A%3Cvalues%3E%0A%3Cjava.lang.Stri
 ng%3EMD5%3C/java.lang.String%3E%0A%3C/values%3E%0A%0A++++%3Coverridable%3Efalse%3C/overridable%3E%0A++%3C/org.apache.syncope.types.ConnConfProperty%3E%0A%0A++%3Corg.apache.syncope.types.ConnConfProperty%3E%0A++++%3Cschema%3E%0A++++++%3Cname%3EretrievePassword%3C/name%3E%0A++++++%3Ctype%3Ejava.lang.Boolean%3C/type%3E%0A++++++%3Crequired%3Efalse%3C/required%3E%0A++++%3C/schema%3E%0A%0A%3Cvalues%3E%0A%3Cjava.lang.String%3Etrue%3C/java.lang.String%3E%0A%3C/values%3E%0A%0A++++%3Coverridable%3Efalse%3C/overridable%3E%0A++%3C/org.apache.syncope.types.ConnConfProperty%3E%0A%3C/set%3E%0A"/>
+  <ConnInstance_capabilities ConnInstance_id="106" capabilities="SEARCH"/>
+  <ConnInstance_capabilities ConnInstance_id="106" capabilities="SYNC"/>
     
   <ExternalResource name="ws-target-resource-1" connector_id="100" forceMandatoryConstraint="0" propagationMode="TWO_PHASES"
                     propagationPriority="0" propagationPrimary="1" createTraceLevel="ALL" deleteTraceLevel="ALL" updateTraceLevel="ALL" syncTraceLevel="ALL"/>
@@ -293,10 +306,10 @@ under the License.
                     propagationPriority="2" propagationPrimary="0" createTraceLevel="ALL" deleteTraceLevel="ALL" updateTraceLevel="ALL" syncTraceLevel="ALL"/>
   <ExternalResource name="ws-target-resource-update" connector_id="100" forceMandatoryConstraint="1" propagationMode="TWO_PHASES"
                     propagationPriority="0" propagationPrimary="0" createTraceLevel="ALL" deleteTraceLevel="ALL" updateTraceLevel="ALL" syncTraceLevel="ALL"/>
-  <ExternalResource name="ws-target-resource-nopropagation" connector_id="103" forceMandatoryConstraint="1" propagationMode="TWO_PHASES"
-                    propagationPriority="0" propagationPrimary="0" createTraceLevel="ALL" deleteTraceLevel="ALL" updateTraceLevel="ALL" syncTraceLevel="ALL" passwordPolicy_id="4"/>
   <ExternalResource name="resource-testdb" connector_id="101" forceMandatoryConstraint="1" propagationMode="ONE_PHASE"
                     propagationPriority="0" propagationPrimary="0" createTraceLevel="ALL" deleteTraceLevel="ALL" updateTraceLevel="ALL" syncTraceLevel="ALL"/>
+  <ExternalResource name="resource-testdb2" connector_id="106" forceMandatoryConstraint="1" propagationMode="ONE_PHASE"
+                    propagationPriority="0" propagationPrimary="0" createTraceLevel="ALL" deleteTraceLevel="ALL" updateTraceLevel="ALL" syncTraceLevel="ALL"/>
   <ExternalResource name="resource-csv" connector_id="104" forceMandatoryConstraint="0" propagationMode="ONE_PHASE" syncPolicy_id="3"
                     propagationPriority="0" propagationPrimary="0" createTraceLevel="ALL" deleteTraceLevel="ALL" updateTraceLevel="ALL" syncTraceLevel="ALL"/>
   <ExternalResource name="ws-target-resource-update-resetsynctoken" connector_id="100" forceMandatoryConstraint="1" propagationMode="TWO_PHASES"
@@ -304,13 +317,25 @@ under the License.
   <ExternalResource name="resource-ldap" connector_id="105" forceMandatoryConstraint="1" propagationMode="ONE_PHASE"
                     propagationPriority="0" propagationPrimary="1" createTraceLevel="ALL" deleteTraceLevel="ALL" updateTraceLevel="ALL" syncTraceLevel="ALL"
                     accountlink="&apos;uid=&apos; + username + &apos;,ou=people,o=isp&apos;"/>
-                      
+  <ExternalResource name="ws-target-resource-nopropagation" connector_id="103" forceMandatoryConstraint="1" propagationMode="TWO_PHASES"
+                    propagationPriority="0" propagationPrimary="0" createTraceLevel="ALL" deleteTraceLevel="ALL" updateTraceLevel="ALL" syncTraceLevel="ALL" passwordPolicy_id="4"/>
+  
+  <!-- The following three resources has been added to verify the issue SYNCOPE-68 -->
+  <ExternalResource name="ws-target-resource-nopropagation2" connector_id="103" forceMandatoryConstraint="1" propagationMode="TWO_PHASES"
+                    propagationPriority="0" propagationPrimary="0" createTraceLevel="ALL" deleteTraceLevel="ALL" updateTraceLevel="ALL" syncTraceLevel="ALL" />
+  <ExternalResource name="ws-target-resource-nopropagation3" connector_id="103" forceMandatoryConstraint="1" propagationMode="TWO_PHASES"
+                    propagationPriority="0" propagationPrimary="0" createTraceLevel="ALL" deleteTraceLevel="ALL" updateTraceLevel="ALL" syncTraceLevel="ALL" />
+  <ExternalResource name="ws-target-resource-nopropagation4" connector_id="103" forceMandatoryConstraint="1" propagationMode="TWO_PHASES"
+                    propagationPriority="0" propagationPrimary="0" createTraceLevel="ALL" deleteTraceLevel="ALL" updateTraceLevel="ALL" syncTraceLevel="ALL" />
+                    
   <SyncopeUser_ExternalResource user_id="3" resource_name="ws-target-resource-delete" />
   <SyncopeRole_ExternalResource role_id="3" resource_name="ws-target-resource-list-mappings-1" />
   <SyncopeUser_ExternalResource user_id="3" resource_name="ws-target-resource-2" />
   <SyncopeRole_ExternalResource role_id="8" resource_name="ws-target-resource-2" />
   <SyncopeRole_ExternalResource role_id="3" resource_name="ws-target-resource-list-mappings-2" />
   <SyncopeUser_ExternalResource user_id="3" resource_name="ws-target-resource-1" />
+  <SyncopeRole_ExternalResource role_id="7" resource_name="ws-target-resource-nopropagation" />
+  <SyncopeRole_ExternalResource role_id="10" resource_name="ws-target-resource-nopropagation3" />
 
   <SchemaMapping id="99" extAttrName="userid"
                  resource_name="ws-target-resource-1"
@@ -396,15 +421,39 @@ under the License.
                  resource_name="ws-target-resource-nopropagation"
                  intAttrName="fullname" intMappingType="UserSchema" mandatoryCondition="true"
                  accountid="1" password="0"/>
+                 
+  <SchemaMapping id="116" extAttrName="name"
+                 resource_name="ws-target-resource-nopropagation2"
+                 intAttrName="fullname" intMappingType="UserSchema" mandatoryCondition="true"
+                 accountid="1" password="0"/>
+                 
+  <SchemaMapping id="117" extAttrName="name"
+                 resource_name="ws-target-resource-nopropagation3"
+                 intAttrName="fullname" intMappingType="UserSchema" mandatoryCondition="true"
+                 accountid="1" password="0"/>
+                 
+  <SchemaMapping id="118" extAttrName="name"
+                 resource_name="ws-target-resource-nopropagation4"
+                 intAttrName="fullname" intMappingType="UserSchema" mandatoryCondition="true"
+                 accountid="1" password="0"/>
                    
-  <SchemaMapping id="116" extAttrName="ID"
+  <SchemaMapping id="119" extAttrName="ID"
                  resource_name="resource-testdb"
                  intMappingType="Username" mandatoryCondition="true"
                  accountid="1" password="0"/>
-  <SchemaMapping id="117" extAttrName="PASSWORD"
+  <SchemaMapping id="120" extAttrName="PASSWORD"
                  resource_name="resource-testdb"
                  intMappingType="Password" mandatoryCondition="true"
                  accountid="0" password="1"/>
+                 
+  <SchemaMapping id="121" extAttrName="ID"
+                 resource_name="resource-testdb2"
+                 intMappingType="Username" mandatoryCondition="true"
+                 accountid="1" password="0"/>
+  <SchemaMapping id="122" extAttrName="PASSWORD"
+                 resource_name="resource-testdb2"
+                 intMappingType="Password" mandatoryCondition="true"
+                 accountid="0" password="1"/>
                    
   <SchemaMapping id="200" extAttrName="id"
                  resource_name="resource-csv"
@@ -494,6 +543,10 @@ under the License.
         jobClassName="org.apache.syncope.core.scheduling.SyncJob"/>
   <Task DTYPE="NotificationTask" id="8" sender="admin@prova.org" subject="Notification for SYNCOPE-81" 
         textBody="NOTIFICATION-81" htmlBody="NOTIFICATION-81" traceLevel="ALL"/>
+  <Task DTYPE="SyncTask" id="9" resource_name="resource-testdb2"
+        performCreate="1" performUpdate="1" performDelete="0" syncStatus="1" fullReconciliation="1"
+        jobClassName="org.apache.syncope.core.scheduling.SyncJob"/>
+        
   <NotificationTask_Recipients notificationtask_id="8" element="recipient@prova.org"/>
 
   <!-- Authentication and authorization -->
@@ -575,6 +628,7 @@ under the License.
   <Entitlement name="ROLE_7"/>
   <Entitlement name="ROLE_8"/>
   <Entitlement name="ROLE_9"/>
+  <Entitlement name="ROLE_10"/>
 
   <SyncopeRole_Entitlement entitlement_name="base" role_id="1"/>
   <SyncopeRole_Entitlement entitlement_name="advanced" role_id="1"/>