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/02/05 17:00:36 UTC

[05/52] syncope git commit: [SYNCOPE-620] Console (JAR) in, now time for console-reference

http://git-wip-us.apache.org/repos/asf/syncope/blob/32707b3b/syncope620/fit/server-reference/src/test/java/org/apache/syncope/fit/server/reference/PushTaskITCase.java
----------------------------------------------------------------------
diff --git a/syncope620/fit/server-reference/src/test/java/org/apache/syncope/fit/server/reference/PushTaskITCase.java b/syncope620/fit/server-reference/src/test/java/org/apache/syncope/fit/server/reference/PushTaskITCase.java
new file mode 100644
index 0000000..f845997
--- /dev/null
+++ b/syncope620/fit/server-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/32707b3b/syncope620/fit/server-reference/src/test/java/org/apache/syncope/fit/server/reference/ReportITCase.java
----------------------------------------------------------------------
diff --git a/syncope620/fit/server-reference/src/test/java/org/apache/syncope/fit/server/reference/ReportITCase.java b/syncope620/fit/server-reference/src/test/java/org/apache/syncope/fit/server/reference/ReportITCase.java
new file mode 100644
index 0000000..8102fe0
--- /dev/null
+++ b/syncope620/fit/server-reference/src/test/java/org/apache/syncope/fit/server/reference/ReportITCase.java
@@ -0,0 +1,252 @@
+/*
+ * 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 static org.junit.Assert.fail;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.List;
+import javax.ws.rs.core.HttpHeaders;
+import javax.ws.rs.core.Response;
+import org.apache.commons.io.IOUtils;
+import org.apache.syncope.common.lib.SyncopeClientException;
+import org.apache.syncope.common.lib.SyncopeConstants;
+import org.apache.syncope.common.lib.report.UserReportletConf;
+import org.apache.syncope.common.lib.to.PagedResult;
+import org.apache.syncope.common.lib.to.ReportExecTO;
+import org.apache.syncope.common.lib.to.ReportTO;
+import org.apache.syncope.common.lib.types.ReportExecExportFormat;
+import org.apache.syncope.common.lib.types.ReportExecStatus;
+import org.apache.syncope.common.lib.wrap.ReportletConfClass;
+import org.apache.syncope.common.rest.api.service.ReportService;
+import org.junit.FixMethodOrder;
+import org.junit.Test;
+import org.junit.runners.MethodSorters;
+
+@FixMethodOrder(MethodSorters.JVM)
+public class ReportITCase extends AbstractITCase {
+
+    private ReportTO createReport(final ReportTO report) {
+        Response response = reportService.create(report);
+        assertEquals(Response.Status.CREATED.getStatusCode(), response.getStatusInfo().getStatusCode());
+        return getObject(response.getLocation(), ReportService.class, ReportTO.class);
+    }
+
+    @Test
+    public void getReportletClasses() {
+        List<ReportletConfClass> reportletClasses = reportService.getReportletConfClasses();
+        assertNotNull(reportletClasses);
+        assertFalse(reportletClasses.isEmpty());
+    }
+
+    @Test
+    public void list() {
+        PagedResult<ReportTO> reports = reportService.list();
+        assertNotNull(reports);
+        assertFalse(reports.getResult().isEmpty());
+        for (ReportTO report : reports.getResult()) {
+            assertNotNull(report);
+        }
+    }
+
+    @Test
+    public void read() {
+        ReportTO reportTO = reportService.read(1L);
+
+        assertNotNull(reportTO);
+        assertNotNull(reportTO.getExecutions());
+        assertFalse(reportTO.getExecutions().isEmpty());
+    }
+
+    @Test
+    public void readExecution() {
+        ReportExecTO reportExecTO = reportService.readExecution(1L);
+        assertNotNull(reportExecTO);
+    }
+
+    @Test
+    public void create() {
+        ReportTO report = new ReportTO();
+        report.setName("testReportForCreate" + getUUIDString());
+        report.getReportletConfs().add(new UserReportletConf("first"));
+        report.getReportletConfs().add(new UserReportletConf("second"));
+
+        report = createReport(report);
+        assertNotNull(report);
+
+        ReportTO actual = reportService.read(report.getKey());
+        assertNotNull(actual);
+
+        assertEquals(actual, report);
+    }
+
+    @Test
+    public void update() {
+        ReportTO report = new ReportTO();
+        report.setName("testReportForUpdate" + getUUIDString());
+
+        report.getReportletConfs().add(new UserReportletConf("first"));
+        report.getReportletConfs().add(new UserReportletConf("second"));
+
+        report = createReport(report);
+        assertNotNull(report);
+        assertEquals(2, report.getReportletConfs().size());
+
+        report.getReportletConfs().add(new UserReportletConf("last"));
+
+        reportService.update(report.getKey(), report);
+        ReportTO updated = reportService.read(report.getKey());
+        assertNotNull(updated);
+        assertEquals(3, updated.getReportletConfs().size());
+    }
+
+    @Test
+    public void delete() {
+        ReportTO report = new ReportTO();
+        report.setName("testReportForDelete" + getUUIDString());
+        report.getReportletConfs().add(new UserReportletConf("first"));
+        report.getReportletConfs().add(new UserReportletConf("second"));
+
+        report = createReport(report);
+        assertNotNull(report);
+
+        reportService.delete(report.getKey());
+
+        try {
+            reportService.read(report.getKey());
+            fail();
+        } catch (SyncopeClientException e) {
+            assertEquals(Response.Status.NOT_FOUND, e.getType().getResponseStatus());
+        }
+    }
+
+    private void checkExport(final Long execId, final ReportExecExportFormat fmt) throws IOException {
+        final Response response = reportService.exportExecutionResult(execId, fmt);
+        assertNotNull(response);
+        assertEquals(Response.Status.OK.getStatusCode(), response.getStatusInfo().getStatusCode());
+        assertNotNull(response.getHeaderString(HttpHeaders.CONTENT_DISPOSITION));
+        assertTrue(response.getHeaderString(HttpHeaders.CONTENT_DISPOSITION).
+                endsWith("." + fmt.name().toLowerCase()));
+
+        Object entity = response.getEntity();
+        assertTrue(entity instanceof InputStream);
+        assertFalse(IOUtils.toString((InputStream) entity, SyncopeConstants.DEFAULT_ENCODING).isEmpty());
+    }
+
+    @Test
+    public void executeAndExport() throws IOException {
+        ReportTO reportTO = reportService.read(1L);
+        reportTO.setKey(0);
+        reportTO.setName("executeAndExport" + getUUIDString());
+        reportTO.getExecutions().clear();
+        reportTO = createReport(reportTO);
+        assertNotNull(reportTO);
+
+        ReportExecTO execution = reportService.execute(reportTO.getKey());
+        assertNotNull(execution);
+
+        int i = 0;
+        int maxit = 50;
+
+        // wait for report execution completion (executions incremented)
+        do {
+            try {
+                Thread.sleep(1000);
+            } catch (InterruptedException e) {
+            }
+
+            reportTO = reportService.read(reportTO.getKey());
+
+            assertNotNull(reportTO);
+            assertNotNull(reportTO.getExecutions());
+
+            i++;
+        } while (reportTO.getExecutions().isEmpty()
+                || (!ReportExecStatus.SUCCESS.name().equals(reportTO.getExecutions().get(0).getStatus()) && i < maxit));
+        assertEquals(ReportExecStatus.SUCCESS.name(), reportTO.getExecutions().get(0).getStatus());
+
+        long execId = reportTO.getExecutions().get(0).getKey();
+
+        checkExport(execId, ReportExecExportFormat.XML);
+        checkExport(execId, ReportExecExportFormat.HTML);
+        checkExport(execId, ReportExecExportFormat.PDF);
+        checkExport(execId, ReportExecExportFormat.RTF);
+        checkExport(execId, ReportExecExportFormat.CSV);
+    }
+
+    @Test
+    public void issueSYNCOPE43() {
+        ReportTO reportTO = new ReportTO();
+        reportTO.setName("issueSYNCOPE43" + getUUIDString());
+        reportTO = createReport(reportTO);
+        assertNotNull(reportTO);
+
+        ReportExecTO execution = reportService.execute(reportTO.getKey());
+        assertNotNull(execution);
+
+        int maxit = 50;
+        do {
+            try {
+                Thread.sleep(1000);
+            } catch (InterruptedException e) {
+            }
+
+            reportTO = reportService.read(reportTO.getKey());
+
+            maxit--;
+        } while (reportTO.getExecutions().isEmpty() && maxit > 0);
+
+        assertEquals(1, reportTO.getExecutions().size());
+    }
+
+    @Test
+    public void issueSYNCOPE102() throws IOException {
+        // Create
+        ReportTO reportTO = reportService.read(1L);
+        reportTO.setKey(0);
+        reportTO.setName("issueSYNCOPE102" + getUUIDString());
+        reportTO = createReport(reportTO);
+        assertNotNull(reportTO);
+
+        // Execute (multiple requests)
+        for (int i = 0; i < 10; i++) {
+            ReportExecTO execution = reportService.execute(reportTO.getKey());
+            assertNotNull(execution);
+        }
+
+        // Wait for one execution
+        int maxit = 50;
+        do {
+            try {
+                Thread.sleep(1000);
+            } catch (InterruptedException e) {
+            }
+
+            reportTO = reportService.read(reportTO.getKey());
+
+            maxit--;
+        } while (reportTO.getExecutions().isEmpty() && maxit > 0);
+        assertFalse(reportTO.getExecutions().isEmpty());
+    }
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/32707b3b/syncope620/fit/server-reference/src/test/java/org/apache/syncope/fit/server/reference/ResourceITCase.java
----------------------------------------------------------------------
diff --git a/syncope620/fit/server-reference/src/test/java/org/apache/syncope/fit/server/reference/ResourceITCase.java b/syncope620/fit/server-reference/src/test/java/org/apache/syncope/fit/server/reference/ResourceITCase.java
new file mode 100644
index 0000000..4b701c4
--- /dev/null
+++ b/syncope620/fit/server-reference/src/test/java/org/apache/syncope/fit/server/reference/ResourceITCase.java
@@ -0,0 +1,578 @@
+/*
+ * 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.security.AccessControlException;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+import javax.ws.rs.core.Response;
+import org.apache.syncope.common.lib.SyncopeClientException;
+import org.apache.syncope.common.lib.to.BulkAction;
+import org.apache.syncope.common.lib.to.MappingItemTO;
+import org.apache.syncope.common.lib.to.MappingTO;
+import org.apache.syncope.common.lib.to.ResourceTO;
+import org.apache.syncope.common.lib.types.ClientExceptionType;
+import org.apache.syncope.common.lib.types.ConnConfPropSchema;
+import org.apache.syncope.common.lib.types.ConnConfProperty;
+import org.apache.syncope.common.lib.types.EntityViolationType;
+import org.apache.syncope.common.lib.types.IntMappingType;
+import org.apache.syncope.common.lib.types.MappingPurpose;
+import org.apache.syncope.common.rest.api.service.ResourceService;
+import org.junit.FixMethodOrder;
+import org.junit.Test;
+import org.junit.runners.MethodSorters;
+
+@FixMethodOrder(MethodSorters.JVM)
+public class ResourceITCase extends AbstractITCase {
+
+    private ResourceTO buildResourceTO(final String resourceName) {
+        ResourceTO resourceTO = new ResourceTO();
+
+        resourceTO.setKey(resourceName);
+        resourceTO.setConnectorId(102L);
+
+        MappingTO mapping = new MappingTO();
+
+        MappingItemTO item = new MappingItemTO();
+        item.setExtAttrName("userId");
+        item.setIntAttrName("userId");
+        item.setIntMappingType(IntMappingType.UserPlainSchema);
+        item.setPurpose(MappingPurpose.BOTH);
+        mapping.addItem(item);
+
+        item = new MappingItemTO();
+        item.setExtAttrName("username");
+        item.setIntAttrName("fullname");
+        item.setIntMappingType(IntMappingType.UserId);
+        item.setPurpose(MappingPurpose.BOTH);
+        mapping.setAccountIdItem(item);
+
+        item = new MappingItemTO();
+        item.setExtAttrName("fullname");
+        item.setIntAttrName("cn");
+        item.setIntMappingType(IntMappingType.UserPlainSchema);
+        item.setAccountid(false);
+        item.setPurpose(MappingPurpose.BOTH);
+        mapping.addItem(item);
+
+        resourceTO.setUmapping(mapping);
+        return resourceTO;
+    }
+
+    @Test
+    public void getPropagationActionsClasses() {
+        List<String> actions = syncopeService.info().getPropagationActions();
+        assertNotNull(actions);
+        assertFalse(actions.isEmpty());
+    }
+
+    @Test
+    public void create() {
+        String resourceName = RESOURCE_NAME_CREATE;
+        ResourceTO resourceTO = buildResourceTO(resourceName);
+
+        Response response = resourceService.create(resourceTO);
+        ResourceTO actual = getObject(response.getLocation(), ResourceService.class, ResourceTO.class);
+        assertNotNull(actual);
+
+        // check for existence
+        actual = resourceService.read(resourceName);
+        assertNotNull(actual);
+    }
+
+    @Test
+    public void createOverridingProps() {
+        String resourceName = "overriding-conn-conf-target-resource-create";
+        ResourceTO resourceTO = new ResourceTO();
+
+        MappingTO mapping = new MappingTO();
+
+        MappingItemTO item = new MappingItemTO();
+        item.setExtAttrName("uid");
+        item.setIntAttrName("userId");
+        item.setIntMappingType(IntMappingType.UserPlainSchema);
+        item.setPurpose(MappingPurpose.BOTH);
+        mapping.addItem(item);
+
+        item = new MappingItemTO();
+        item.setExtAttrName("username");
+        item.setIntAttrName("fullname");
+        item.setIntMappingType(IntMappingType.UserId);
+        item.setAccountid(true);
+        item.setPurpose(MappingPurpose.BOTH);
+        mapping.setAccountIdItem(item);
+
+        item = new MappingItemTO();
+        item.setExtAttrName("fullname");
+        item.setIntAttrName("cn");
+        item.setIntMappingType(IntMappingType.UserPlainSchema);
+        item.setAccountid(false);
+        item.setPurpose(MappingPurpose.BOTH);
+        mapping.addItem(item);
+
+        resourceTO.setKey(resourceName);
+        resourceTO.setConnectorId(102L);
+
+        resourceTO.setUmapping(mapping);
+
+        ConnConfProperty p = new ConnConfProperty();
+        ConnConfPropSchema schema = new ConnConfPropSchema();
+        schema.setType("java.lang.String");
+        schema.setName("endpoint");
+        schema.setRequired(true);
+        p.setSchema(schema);
+        p.getValues().add("http://invalidurl/");
+
+        Set<ConnConfProperty> connectorConfigurationProperties = new HashSet<ConnConfProperty>(Arrays.asList(p));
+        resourceTO.getConnConfProperties().addAll(connectorConfigurationProperties);
+
+        Response response = resourceService.create(resourceTO);
+        ResourceTO actual = getObject(response.getLocation(), ResourceService.class, ResourceTO.class);
+        assertNotNull(actual);
+
+        // check the existence
+        actual = resourceService.read(resourceName);
+        assertNotNull(actual);
+    }
+
+    @Test
+    public void createWithSingleMappingItem() {
+        String resourceName = RESOURCE_NAME_CREATE_SINGLE;
+        ResourceTO resourceTO = new ResourceTO();
+        resourceTO.setKey(resourceName);
+        resourceTO.setConnectorId(102L);
+
+        MappingTO umapping = new MappingTO();
+
+        MappingItemTO item = new MappingItemTO();
+        item.setIntMappingType(IntMappingType.UserId);
+        item.setExtAttrName("userId");
+        item.setAccountid(true);
+        item.setPurpose(MappingPurpose.PROPAGATION);
+        umapping.setAccountIdItem(item);
+
+        resourceTO.setUmapping(umapping);
+
+        MappingTO rmapping = new MappingTO();
+
+        item = new MappingItemTO();
+        item.setIntMappingType(IntMappingType.RoleId);
+        item.setExtAttrName("roleId");
+        item.setAccountid(true);
+        item.setPurpose(MappingPurpose.SYNCHRONIZATION);
+        rmapping.setAccountIdItem(item);
+
+        resourceTO.setRmapping(rmapping);
+
+        Response response = resourceService.create(resourceTO);
+        ResourceTO actual = getObject(response.getLocation(), ResourceService.class, ResourceTO.class);
+
+        assertNotNull(actual);
+        assertNotNull(actual.getUmapping());
+        assertNotNull(actual.getUmapping().getItems());
+        assertNotNull(actual.getRmapping());
+        assertNotNull(actual.getRmapping().getItems());
+        assertEquals(MappingPurpose.SYNCHRONIZATION, actual.getRmapping().getAccountIdItem().getPurpose());
+        assertEquals(MappingPurpose.PROPAGATION, actual.getUmapping().getAccountIdItem().getPurpose());
+    }
+
+    @Test
+    public void createWithInvalidMapping() {
+        String resourceName = RESOURCE_NAME_CREATE_WRONG;
+        ResourceTO resourceTO = new ResourceTO();
+        resourceTO.setKey(resourceName);
+        resourceTO.setConnectorId(102L);
+
+        MappingTO mapping = new MappingTO();
+
+        MappingItemTO item = new MappingItemTO();
+        item.setIntMappingType(IntMappingType.UserId);
+        item.setExtAttrName("userId");
+        item.setAccountid(true);
+        mapping.setAccountIdItem(item);
+
+        item = new MappingItemTO();
+        item.setIntMappingType(IntMappingType.UserPlainSchema);
+        item.setExtAttrName("email");
+        // missing intAttrName ...
+        mapping.addItem(item);
+
+        resourceTO.setUmapping(mapping);
+
+        try {
+            createResource(resourceTO);
+            fail("Create should not have worked");
+        } catch (SyncopeClientException e) {
+            assertEquals(ClientExceptionType.RequiredValuesMissing, e.getType());
+            assertEquals("intAttrName", e.getElements().iterator().next());
+        }
+    }
+
+    @Test(expected = SyncopeClientException.class)
+    public void createWithoutExtAttr() {
+        String resourceName = RESOURCE_NAME_CREATE_WRONG;
+        ResourceTO resourceTO = new ResourceTO();
+        resourceTO.setKey(resourceName);
+        resourceTO.setConnectorId(102L);
+
+        MappingTO mapping = new MappingTO();
+
+        MappingItemTO item = new MappingItemTO();
+        item.setIntMappingType(IntMappingType.UserId);
+        item.setExtAttrName("userId");
+        item.setAccountid(true);
+        mapping.setAccountIdItem(item);
+
+        item = new MappingItemTO();
+        item.setIntMappingType(IntMappingType.UserPlainSchema);
+        item.setIntAttrName("usernane");
+        // missing extAttrName ...
+        mapping.addItem(item);
+
+        resourceTO.setUmapping(mapping);
+
+        createResource(resourceTO);
+    }
+
+    @Test
+    public void createWithPasswordPolicy() {
+        String resourceName = "res-with-password-policy";
+        ResourceTO resourceTO = new ResourceTO();
+        resourceTO.setKey(resourceName);
+        resourceTO.setConnectorId(102L);
+        resourceTO.setPasswordPolicy(4L);
+
+        MappingTO mapping = new MappingTO();
+
+        MappingItemTO item = new MappingItemTO();
+        item.setExtAttrName("userId");
+        item.setIntAttrName("userId");
+        item.setIntMappingType(IntMappingType.UserPlainSchema);
+        item.setAccountid(true);
+        item.setPurpose(MappingPurpose.BOTH);
+        mapping.setAccountIdItem(item);
+
+        resourceTO.setUmapping(mapping);
+
+        Response response = resourceService.create(resourceTO);
+        ResourceTO actual = getObject(response.getLocation(), ResourceService.class, ResourceTO.class);
+        assertNotNull(actual);
+
+        // check the existence
+        actual = resourceService.read(resourceName);
+        assertNotNull(actual);
+        assertNotNull(actual.getPasswordPolicy());
+        assertEquals(4L, (long) actual.getPasswordPolicy());
+    }
+
+    @Test
+    public void updateWithException() {
+        try {
+            ResourceTO resourceTO = new ResourceTO();
+            resourceTO.setKey("resourcenotfound");
+
+            resourceService.update(resourceTO.getKey(), resourceTO);
+        } catch (SyncopeClientException e) {
+            assertEquals(Response.Status.NOT_FOUND, e.getType().getResponseStatus());
+        }
+    }
+
+    @Test
+    public void update() {
+        String resourceName = RESOURCE_NAME_UPDATE;
+        ResourceTO resourceTO = new ResourceTO();
+        resourceTO.setKey(resourceName);
+        resourceTO.setConnectorId(101L);
+
+        MappingTO mapping = new MappingTO();
+
+        // Update with an existing and already assigned mapping
+        MappingItemTO item = new MappingItemTO();
+        item.setKey(112L);
+        item.setExtAttrName("test3");
+        item.setIntAttrName("fullname");
+        item.setIntMappingType(IntMappingType.UserPlainSchema);
+        item.setPurpose(MappingPurpose.BOTH);
+        mapping.addItem(item);
+
+        // Update defining new mappings
+        for (int i = 4; i < 6; i++) {
+            item = new MappingItemTO();
+            item.setExtAttrName("test" + i);
+            item.setIntAttrName("fullname");
+            item.setIntMappingType(IntMappingType.UserPlainSchema);
+            item.setPurpose(MappingPurpose.BOTH);
+            mapping.addItem(item);
+        }
+        item = new MappingItemTO();
+        item.setExtAttrName("username");
+        item.setIntAttrName("fullname");
+        item.setIntMappingType(IntMappingType.UserId);
+        item.setAccountid(true);
+        item.setPurpose(MappingPurpose.BOTH);
+        mapping.setAccountIdItem(item);
+
+        resourceTO.setUmapping(mapping);
+
+        resourceService.update(resourceTO.getKey(), resourceTO);
+        ResourceTO actual = resourceService.read(resourceTO.getKey());
+        assertNotNull(actual);
+
+        // check for existence
+        Collection<MappingItemTO> mapItems = actual.getUmapping().getItems();
+        assertNotNull(mapItems);
+        assertEquals(4, mapItems.size());
+    }
+
+    @Test
+    public void deleteWithException() {
+        try {
+            resourceService.delete("resourcenotfound");
+        } catch (SyncopeClientException e) {
+            assertEquals(Response.Status.NOT_FOUND, e.getType().getResponseStatus());
+        }
+    }
+
+    @Test
+    public void updateResetSyncToken() {
+        // create resource with sync token
+        String resourceName = RESOURCE_NAME_RESETSYNCTOKEN + getUUIDString();
+        ResourceTO pre = buildResourceTO(resourceName);
+        pre.setUsyncToken("test");
+        resourceService.create(pre);
+
+        pre.setUsyncToken(null);
+        resourceService.update(pre.getKey(), pre);
+        ResourceTO actual = resourceService.read(pre.getKey());
+        // check that the synctoken has been reset
+        assertNull(actual.getUsyncToken());
+    }
+
+    @Test
+    public void delete() {
+        String resourceName = "tobedeleted";
+
+        ResourceTO resource = buildResourceTO(resourceName);
+        Response response = resourceService.create(resource);
+        ResourceTO actual = getObject(response.getLocation(), ResourceService.class, ResourceTO.class);
+        assertNotNull(actual);
+
+        resourceService.delete(resourceName);
+
+        try {
+            resourceService.read(resourceName);
+        } catch (SyncopeClientException e) {
+            assertEquals(Response.Status.NOT_FOUND, e.getType().getResponseStatus());
+        }
+    }
+
+    @Test
+    public void list() {
+        List<ResourceTO> actuals = resourceService.list();
+        assertNotNull(actuals);
+        assertFalse(actuals.isEmpty());
+        for (ResourceTO resourceTO : actuals) {
+            assertNotNull(resourceTO);
+        }
+    }
+
+    @Test
+    public void read() {
+        ResourceTO actual = resourceService.read(RESOURCE_NAME_TESTDB);
+        assertNotNull(actual);
+    }
+
+    @Test
+    public void issueSYNCOPE323() {
+        ResourceTO actual = resourceService.read(RESOURCE_NAME_TESTDB);
+        assertNotNull(actual);
+
+        try {
+            createResource(actual);
+            fail();
+        } catch (SyncopeClientException e) {
+            assertEquals(Response.Status.CONFLICT, e.getType().getResponseStatus());
+            assertEquals(ClientExceptionType.EntityExists, e.getType());
+        }
+
+        actual.setKey(null);
+        try {
+            createResource(actual);
+            fail();
+        } catch (SyncopeClientException e) {
+            assertEquals(Response.Status.BAD_REQUEST, e.getType().getResponseStatus());
+            assertEquals(ClientExceptionType.RequiredValuesMissing, e.getType());
+        }
+    }
+
+    @Test
+    public void bulkAction() {
+        resourceService.create(buildResourceTO("forBulk1"));
+        resourceService.create(buildResourceTO("forBulk2"));
+
+        assertNotNull(resourceService.read("forBulk1"));
+        assertNotNull(resourceService.read("forBulk2"));
+
+        final BulkAction bulkAction = new BulkAction();
+        bulkAction.setOperation(BulkAction.Type.DELETE);
+
+        bulkAction.getTargets().add(String.valueOf("forBulk1"));
+        bulkAction.getTargets().add(String.valueOf("forBulk2"));
+
+        resourceService.bulk(bulkAction);
+
+        try {
+            resourceService.read("forBulk1");
+            fail();
+        } catch (SyncopeClientException e) {
+        }
+
+        try {
+            resourceService.read("forBulk2");
+            fail();
+        } catch (SyncopeClientException e) {
+        }
+    }
+
+    @Test
+    public void issueSYNCOPE360() {
+        final String name = "SYNCOPE360-" + getUUIDString();
+        resourceService.create(buildResourceTO(name));
+
+        ResourceTO resource = resourceService.read(name);
+        assertNotNull(resource);
+        assertNotNull(resource.getUmapping());
+
+        resource.setUmapping(new MappingTO());
+        resourceService.update(name, resource);
+
+        resource = resourceService.read(name);
+        assertNotNull(resource);
+        assertNull(resource.getUmapping());
+    }
+
+    @Test
+    public void issueSYNCOPE368() {
+        final String name = "SYNCOPE368-" + getUUIDString();
+
+        ResourceTO resourceTO = new ResourceTO();
+
+        resourceTO.setKey(name);
+        resourceTO.setConnectorId(105L);
+
+        MappingTO mapping = new MappingTO();
+
+        MappingItemTO item = new MappingItemTO();
+        item.setIntMappingType(IntMappingType.RoleName);
+        item.setExtAttrName("cn");
+        item.setPurpose(MappingPurpose.BOTH);
+        mapping.setAccountIdItem(item);
+
+        item = new MappingItemTO();
+        item.setIntMappingType(IntMappingType.RoleOwnerSchema);
+        item.setExtAttrName("owner");
+        item.setPurpose(MappingPurpose.BOTH);
+        mapping.addItem(item);
+
+        resourceTO.setRmapping(mapping);
+
+        resourceTO = createResource(resourceTO);
+        assertNotNull(resourceTO);
+        assertEquals(2, resourceTO.getRmapping().getItems().size());
+    }
+
+    @Test
+    public void issueSYNCOPE418() {
+        try {
+            resourceService.create(
+                    buildResourceTO("http://schemas.examples.org/security/authorization/organizationUnit"));
+            fail();
+        } catch (SyncopeClientException e) {
+            assertEquals(ClientExceptionType.InvalidExternalResource, e.getType());
+
+            assertTrue(e.getElements().iterator().next().toString().contains(EntityViolationType.InvalidName.name()));
+        }
+    }
+
+    @Test
+    public void anonymous() {
+        ResourceService unauthenticated = clientFactory.createAnonymous().getService(ResourceService.class);
+        try {
+            unauthenticated.list();
+            fail();
+        } catch (AccessControlException e) {
+            assertNotNull(e);
+        }
+
+        ResourceService anonymous = clientFactory.create(ANONYMOUS_UNAME, ANONYMOUS_KEY).
+                getService(ResourceService.class);
+        assertFalse(anonymous.list().isEmpty());
+    }
+
+    @Test
+    public void issueSYNCOPE493() {
+        // create resource with attribute mapping set to NONE and check its propagation
+        String resourceName = RESOURCE_NAME_CREATE_NONE;
+        ResourceTO resourceTO = new ResourceTO();
+        resourceTO.setKey(resourceName);
+        resourceTO.setConnectorId(102L);
+
+        MappingTO umapping = new MappingTO();
+
+        MappingItemTO item = new MappingItemTO();
+        item.setIntMappingType(IntMappingType.UserId);
+        item.setExtAttrName("userId");
+        item.setAccountid(true);
+        item.setPurpose(MappingPurpose.PROPAGATION);
+        umapping.setAccountIdItem(item);
+
+        MappingItemTO item2 = new MappingItemTO();
+        item2.setIntMappingType(IntMappingType.UserPlainSchema);
+        item2.setAccountid(false);
+        item2.setIntAttrName("gender");
+        item2.setExtAttrName("gender");
+        item2.setPurpose(MappingPurpose.NONE);
+        umapping.addItem(item2);
+
+        resourceTO.setUmapping(umapping);
+
+        Response response = resourceService.create(resourceTO);
+        ResourceTO actual = getObject(response.getLocation(), ResourceService.class, ResourceTO.class);
+
+        assertNotNull(actual);
+        assertNotNull(actual.getUmapping());
+        assertNotNull(actual.getUmapping().getItems());
+        assertEquals(MappingPurpose.PROPAGATION, actual.getUmapping().getAccountIdItem().getPurpose());
+        for (MappingItemTO itemTO : actual.getUmapping().getItems()) {
+            if ("gender".equals(itemTO.getIntAttrName())) {
+                assertEquals(MappingPurpose.NONE, itemTO.getPurpose());
+            }
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/32707b3b/syncope620/fit/server-reference/src/test/java/org/apache/syncope/fit/server/reference/RoleITCase.java
----------------------------------------------------------------------
diff --git a/syncope620/fit/server-reference/src/test/java/org/apache/syncope/fit/server/reference/RoleITCase.java b/syncope620/fit/server-reference/src/test/java/org/apache/syncope/fit/server/reference/RoleITCase.java
new file mode 100644
index 0000000..18646f5
--- /dev/null
+++ b/syncope620/fit/server-reference/src/test/java/org/apache/syncope/fit/server/reference/RoleITCase.java
@@ -0,0 +1,889 @@
+/*
+ * 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.io.IOException;
+import java.io.InputStream;
+import java.security.AccessControlException;
+import java.util.List;
+import javax.naming.NamingEnumeration;
+import javax.naming.NamingException;
+import javax.naming.directory.DirContext;
+import javax.naming.directory.SearchControls;
+import javax.naming.directory.SearchResult;
+import javax.ws.rs.core.Response;
+import org.apache.commons.io.IOUtils;
+import org.apache.commons.lang3.StringUtils;
+import org.apache.syncope.client.lib.SyncopeClient;
+import org.apache.syncope.common.lib.SyncopeClientException;
+import org.apache.syncope.common.lib.mod.ReferenceMod;
+import org.apache.syncope.common.lib.mod.RoleMod;
+import org.apache.syncope.common.lib.to.BulkActionResult;
+import org.apache.syncope.common.lib.to.ConnObjectTO;
+import org.apache.syncope.common.lib.to.MappingItemTO;
+import org.apache.syncope.common.lib.to.PagedResult;
+import org.apache.syncope.common.lib.to.PlainSchemaTO;
+import org.apache.syncope.common.lib.to.ResourceTO;
+import org.apache.syncope.common.lib.to.RoleTO;
+import org.apache.syncope.common.lib.to.UserTO;
+import org.apache.syncope.common.lib.types.AttributableType;
+import org.apache.syncope.common.lib.types.ClientExceptionType;
+import org.apache.syncope.common.lib.types.IntMappingType;
+import org.apache.syncope.common.lib.types.MappingPurpose;
+import org.apache.syncope.common.lib.types.ResourceAssociationActionType;
+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.wrap.ResourceName;
+import org.apache.syncope.common.rest.api.CollectionWrapper;
+import org.apache.syncope.common.rest.api.Preference;
+import org.apache.syncope.common.rest.api.RESTHeaders;
+import org.apache.syncope.common.rest.api.service.RoleService;
+import org.identityconnectors.framework.common.objects.Name;
+import org.junit.FixMethodOrder;
+import org.junit.Ignore;
+import org.junit.Test;
+import org.junit.runners.MethodSorters;
+
+@FixMethodOrder(MethodSorters.JVM)
+public class RoleITCase extends AbstractITCase {
+
+    private RoleTO buildBasicRoleTO(final String name) {
+        RoleTO roleTO = new RoleTO();
+        roleTO.setName(name + getUUIDString());
+        roleTO.setParent(8L);
+        return roleTO;
+    }
+
+    private RoleTO buildRoleTO(final String name) {
+        RoleTO roleTO = buildBasicRoleTO(name);
+
+        // verify inheritance password and account policies
+        roleTO.setInheritAccountPolicy(false);
+        // not inherited so setter execution shouldn't be ignored
+        roleTO.setAccountPolicy(6L);
+
+        roleTO.setInheritPasswordPolicy(true);
+        // inherited so setter execution should be ignored
+        roleTO.setPasswordPolicy(2L);
+
+        roleTO.getRAttrTemplates().add("icon");
+        roleTO.getPlainAttrs().add(attrTO("icon", "anIcon"));
+
+        roleTO.getResources().add(RESOURCE_NAME_LDAP);
+        return roleTO;
+    }
+
+    @Test
+    public void createWithException() {
+        RoleTO newRoleTO = new RoleTO();
+        newRoleTO.getPlainAttrs().add(attrTO("attr1", "value1"));
+
+        try {
+            createRole(newRoleTO);
+            fail();
+        } catch (SyncopeClientException e) {
+            assertEquals(ClientExceptionType.InvalidRole, e.getType());
+        }
+    }
+
+    @Test
+    @Ignore
+    public void create() {
+        RoleTO roleTO = buildRoleTO("lastRole");
+        roleTO.getRVirAttrTemplates().add("rvirtualdata");
+        roleTO.getVirAttrs().add(attrTO("rvirtualdata", "rvirtualvalue"));
+        roleTO.setRoleOwner(8L);
+
+        roleTO = createRole(roleTO);
+        assertNotNull(roleTO);
+
+        assertNotNull(roleTO.getVirAttrMap());
+        assertNotNull(roleTO.getVirAttrMap().get("rvirtualdata").getValues());
+        assertFalse(roleTO.getVirAttrMap().get("rvirtualdata").getValues().isEmpty());
+        assertEquals("rvirtualvalue", roleTO.getVirAttrMap().get("rvirtualdata").getValues().get(0));
+
+        assertNotNull(roleTO.getAccountPolicy());
+        assertEquals(6L, (long) roleTO.getAccountPolicy());
+
+        assertNotNull(roleTO.getPasswordPolicy());
+        assertEquals(4L, (long) roleTO.getPasswordPolicy());
+
+        assertTrue(roleTO.getResources().contains(RESOURCE_NAME_LDAP));
+
+        ConnObjectTO connObjectTO =
+                resourceService.getConnectorObject(RESOURCE_NAME_LDAP, SubjectType.ROLE, roleTO.getKey());
+        assertNotNull(connObjectTO);
+        assertNotNull(connObjectTO.getPlainAttrMap().get("owner"));
+
+        // SYNCOPE-515: remove ownership
+        final RoleMod roleMod = new RoleMod();
+        roleMod.setKey(roleTO.getKey());
+        roleMod.setRoleOwner(new ReferenceMod());
+
+        assertNull(updateRole(roleMod).getRoleOwner());
+    }
+
+    @Test
+    public void createWithPasswordPolicy() {
+        RoleTO roleTO = new RoleTO();
+        roleTO.setName("roleWithPassword" + getUUIDString());
+        roleTO.setParent(8L);
+        roleTO.setPasswordPolicy(4L);
+
+        RoleTO actual = createRole(roleTO);
+        assertNotNull(actual);
+
+        actual = roleService.read(actual.getKey());
+        assertNotNull(actual);
+        assertNotNull(actual.getPasswordPolicy());
+        assertEquals(4L, (long) actual.getPasswordPolicy());
+    }
+
+    @Test
+    public void delete() {
+        try {
+            roleService.delete(0L);
+        } catch (SyncopeClientException e) {
+            assertEquals(Response.Status.NOT_FOUND, e.getType().getResponseStatus());
+        }
+
+        RoleTO roleTO = new RoleTO();
+        roleTO.setName("toBeDeleted" + getUUIDString());
+        roleTO.setParent(8L);
+
+        roleTO.getResources().add(RESOURCE_NAME_LDAP);
+
+        roleTO = createRole(roleTO);
+        assertNotNull(roleTO);
+
+        RoleTO deletedRole = deleteRole(roleTO.getKey());
+        assertNotNull(deletedRole);
+
+        try {
+            roleService.read(deletedRole.getKey());
+        } catch (SyncopeClientException e) {
+            assertEquals(Response.Status.NOT_FOUND, e.getType().getResponseStatus());
+        }
+    }
+
+    @Test
+    public void list() {
+        PagedResult<RoleTO> roleTOs = roleService.list();
+        assertNotNull(roleTOs);
+        assertTrue(roleTOs.getResult().size() >= 8);
+        for (RoleTO roleTO : roleTOs.getResult()) {
+            assertNotNull(roleTO);
+        }
+    }
+
+    @Test
+    public void parent() {
+        RoleTO roleTO = roleService.parent(7L);
+
+        assertNotNull(roleTO);
+        assertEquals(roleTO.getKey(), 6L);
+    }
+
+    @Test
+    public void read() {
+        RoleTO roleTO = roleService.read(1L);
+
+        assertNotNull(roleTO);
+        assertNotNull(roleTO.getPlainAttrs());
+        assertFalse(roleTO.getPlainAttrs().isEmpty());
+    }
+
+    @Test
+    public void selfRead() {
+        UserTO userTO = userService.read(1L);
+        assertNotNull(userTO);
+
+        assertTrue(userTO.getMembershipMap().containsKey(1L));
+        assertFalse(userTO.getMembershipMap().containsKey(3L));
+
+        RoleService roleService2 = clientFactory.create("rossini", ADMIN_PWD).getService(RoleService.class);
+
+        try {
+            roleService2.readSelf(3L);
+            fail();
+        } catch (SyncopeClientException e) {
+            assertEquals(ClientExceptionType.UnauthorizedRole, e.getType());
+        }
+
+        RoleTO roleTO = roleService2.readSelf(1L);
+        assertNotNull(roleTO);
+        assertNotNull(roleTO.getPlainAttrs());
+        assertFalse(roleTO.getPlainAttrs().isEmpty());
+    }
+
+    @Test
+    public void update() {
+        RoleTO roleTO = buildRoleTO("latestRole" + getUUIDString());
+        roleTO.getRAttrTemplates().add("show");
+        roleTO = createRole(roleTO);
+
+        assertEquals(1, roleTO.getPlainAttrs().size());
+
+        assertNotNull(roleTO.getAccountPolicy());
+        assertEquals(6L, (long) roleTO.getAccountPolicy());
+
+        assertNotNull(roleTO.getPasswordPolicy());
+        assertEquals(4L, (long) roleTO.getPasswordPolicy());
+
+        RoleMod roleMod = new RoleMod();
+        roleMod.setKey(roleTO.getKey());
+        String modName = "finalRole" + getUUIDString();
+        roleMod.setName(modName);
+        roleMod.getPlainAttrsToUpdate().add(attrMod("show", "FALSE"));
+
+        // change password policy inheritance
+        roleMod.setInheritPasswordPolicy(Boolean.FALSE);
+
+        roleTO = updateRole(roleMod);
+
+        assertEquals(modName, roleTO.getName());
+        assertEquals(2, roleTO.getPlainAttrs().size());
+
+        // changes ignored because not requested (null ReferenceMod)
+        assertNotNull(roleTO.getAccountPolicy());
+        assertEquals(6L, (long) roleTO.getAccountPolicy());
+
+        // password policy null because not inherited
+        assertNull(roleTO.getPasswordPolicy());
+    }
+
+    @Test
+    public void updateRemovingVirAttribute() {
+        RoleTO roleTO = buildBasicRoleTO("withvirtual" + getUUIDString());
+        roleTO.getRVirAttrTemplates().add("rvirtualdata");
+        roleTO.getVirAttrs().add(attrTO("rvirtualdata", null));
+
+        roleTO = createRole(roleTO);
+
+        assertNotNull(roleTO);
+        assertEquals(1, roleTO.getVirAttrs().size());
+
+        final RoleMod roleMod = new RoleMod();
+        roleMod.setKey(roleTO.getKey());
+        roleMod.getVirAttrsToRemove().add("rvirtualdata");
+
+        roleTO = updateRole(roleMod);
+        assertNotNull(roleTO);
+        assertTrue(roleTO.getVirAttrs().isEmpty());
+    }
+
+    @Test
+    public void updateRemovingDerAttribute() {
+        RoleTO roleTO = buildBasicRoleTO("withderived" + getUUIDString());
+        roleTO.getRDerAttrTemplates().add("rderivedschema");
+        roleTO.getDerAttrs().add(attrTO("rderivedschema", null));
+
+        roleTO = createRole(roleTO);
+
+        assertNotNull(roleTO);
+        assertEquals(1, roleTO.getDerAttrs().size());
+
+        final RoleMod roleMod = new RoleMod();
+        roleMod.setKey(roleTO.getKey());
+        roleMod.getDerAttrsToRemove().add("rderivedschema");
+
+        roleTO = updateRole(roleMod);
+        assertNotNull(roleTO);
+        assertTrue(roleTO.getDerAttrs().isEmpty());
+    }
+
+    @Test
+    public void updateAsRoleOwner() {
+        // 1. read role as admin
+        RoleTO roleTO = roleService.read(7L);
+
+        // issue SYNCOPE-15
+        assertNotNull(roleTO.getCreationDate());
+        assertNotNull(roleTO.getLastChangeDate());
+        assertEquals("admin", roleTO.getCreator());
+        assertEquals("admin", roleTO.getLastModifier());
+
+        // 2. prepare update
+        RoleMod roleMod = new RoleMod();
+        roleMod.setKey(roleTO.getKey());
+        roleMod.setName("Managing Director");
+
+        // 3. try to update as verdi, not owner of role 7 - fail
+        RoleService roleService2 = clientFactory.create("verdi", ADMIN_PWD).getService(RoleService.class);
+
+        try {
+            roleService2.update(roleMod.getKey(), roleMod);
+            fail();
+        } catch (SyncopeClientException e) {
+            assertEquals(Response.Status.UNAUTHORIZED, e.getType().getResponseStatus());
+        } catch (AccessControlException e) {
+            assertNotNull(e);
+        }
+
+        // 4. update as puccini, owner of role 7 because owner of role 6 with inheritance - success
+        RoleService roleService3 = clientFactory.create("puccini", ADMIN_PWD).getService(RoleService.class);
+
+        roleTO = roleService3.update(roleMod.getKey(), roleMod).readEntity(RoleTO.class);
+        assertEquals("Managing Director", roleTO.getName());
+
+        // issue SYNCOPE-15
+        assertNotNull(roleTO.getCreationDate());
+        assertNotNull(roleTO.getLastChangeDate());
+        assertEquals("admin", roleTO.getCreator());
+        assertEquals("puccini", roleTO.getLastModifier());
+        assertTrue(roleTO.getCreationDate().before(roleTO.getLastChangeDate()));
+    }
+
+    /**
+     * Role rename used to fail in case of parent null.
+     *
+     * http://code.google.com/p/syncope/issues/detail?id=178
+     */
+    @Test
+    public void issue178() {
+        RoleTO roleTO = new RoleTO();
+        String roleName = "torename" + getUUIDString();
+        roleTO.setName(roleName);
+
+        RoleTO actual = createRole(roleTO);
+
+        assertNotNull(actual);
+        assertEquals(roleName, actual.getName());
+        assertEquals(0L, actual.getParent());
+
+        RoleMod roleMod = new RoleMod();
+        roleMod.setKey(actual.getKey());
+        String renamedRole = "renamed" + getUUIDString();
+        roleMod.setName(renamedRole);
+
+        actual = updateRole(roleMod);
+        assertNotNull(actual);
+        assertEquals(renamedRole, actual.getName());
+        assertEquals(0L, actual.getParent());
+    }
+
+    @Test
+    public void issueSYNCOPE228() {
+        RoleTO roleTO = buildRoleTO("issueSYNCOPE228");
+        roleTO.getEntitlements().add("USER_READ");
+        roleTO.getEntitlements().add("SCHEMA_READ");
+
+        roleTO = createRole(roleTO);
+        assertNotNull(roleTO);
+        assertNotNull(roleTO.getEntitlements());
+        assertFalse(roleTO.getEntitlements().isEmpty());
+
+        List<String> entitlements = roleTO.getEntitlements();
+
+        RoleMod roleMod = new RoleMod();
+        roleMod.setKey(roleTO.getKey());
+        roleMod.setInheritDerAttrs(Boolean.TRUE);
+
+        roleTO = updateRole(roleMod);
+        assertNotNull(roleTO);
+        assertEquals(entitlements, roleTO.getEntitlements());
+
+        roleMod = new RoleMod();
+        roleMod.setKey(roleTO.getKey());
+        roleMod.setModEntitlements(true);
+        roleMod.getEntitlements().clear();
+
+        roleTO = updateRole(roleMod);
+        assertNotNull(roleTO);
+        assertTrue(roleTO.getEntitlements().isEmpty());
+    }
+
+    @Test
+    public void unlink() {
+        RoleTO actual = createRole(buildRoleTO("unlink"));
+        assertNotNull(actual);
+
+        assertNotNull(resourceService.getConnectorObject(RESOURCE_NAME_LDAP, SubjectType.ROLE, actual.getKey()));
+
+        assertNotNull(roleService.bulkDeassociation(actual.getKey(),
+                ResourceDeassociationActionType.UNLINK,
+                CollectionWrapper.wrap(RESOURCE_NAME_LDAP, ResourceName.class)).
+                readEntity(BulkActionResult.class));
+
+        actual = roleService.read(actual.getKey());
+        assertNotNull(actual);
+        assertTrue(actual.getResources().isEmpty());
+
+        assertNotNull(resourceService.getConnectorObject(RESOURCE_NAME_LDAP, SubjectType.ROLE, actual.getKey()));
+    }
+
+    @Test
+    public void link() {
+        RoleTO roleTO = buildRoleTO("link");
+        roleTO.getResources().clear();
+
+        RoleTO actual = createRole(roleTO);
+        assertNotNull(actual);
+
+        try {
+            resourceService.getConnectorObject(RESOURCE_NAME_LDAP, SubjectType.ROLE, actual.getKey());
+            fail();
+        } catch (Exception e) {
+            assertNotNull(e);
+        }
+
+        assertNotNull(roleService.bulkAssociation(actual.getKey(),
+                ResourceAssociationActionType.LINK,
+                CollectionWrapper.wrap(RESOURCE_NAME_LDAP, ResourceName.class)).
+                readEntity(BulkActionResult.class));
+
+        actual = roleService.read(actual.getKey());
+        assertFalse(actual.getResources().isEmpty());
+
+        try {
+            resourceService.getConnectorObject(RESOURCE_NAME_LDAP, SubjectType.ROLE, actual.getKey());
+            fail();
+        } catch (Exception e) {
+            assertNotNull(e);
+        }
+    }
+
+    @Test
+    public void unassign() {
+        RoleTO actual = createRole(buildRoleTO("unassign"));
+        assertNotNull(actual);
+
+        assertNotNull(resourceService.getConnectorObject(RESOURCE_NAME_LDAP, SubjectType.ROLE, actual.getKey()));
+
+        assertNotNull(roleService.bulkDeassociation(actual.getKey(),
+                ResourceDeassociationActionType.UNASSIGN,
+                CollectionWrapper.wrap(RESOURCE_NAME_LDAP, ResourceName.class)).
+                readEntity(BulkActionResult.class));
+
+        actual = roleService.read(actual.getKey());
+        assertNotNull(actual);
+        assertTrue(actual.getResources().isEmpty());
+
+        try {
+            resourceService.getConnectorObject(RESOURCE_NAME_LDAP, SubjectType.ROLE, actual.getKey());
+            fail();
+        } catch (Exception e) {
+            assertNotNull(e);
+        }
+    }
+
+    @Test
+    public void assign() {
+        RoleTO roleTO = buildRoleTO("assign");
+        roleTO.getResources().clear();
+
+        RoleTO actual = createRole(roleTO);
+        assertNotNull(actual);
+
+        try {
+            resourceService.getConnectorObject(RESOURCE_NAME_LDAP, SubjectType.ROLE, actual.getKey());
+            fail();
+        } catch (Exception e) {
+            assertNotNull(e);
+        }
+
+        assertNotNull(roleService.bulkAssociation(actual.getKey(),
+                ResourceAssociationActionType.ASSIGN,
+                CollectionWrapper.wrap(RESOURCE_NAME_LDAP, ResourceName.class)).
+                readEntity(BulkActionResult.class));
+
+        actual = roleService.read(actual.getKey());
+        assertFalse(actual.getResources().isEmpty());
+        assertNotNull(resourceService.getConnectorObject(RESOURCE_NAME_LDAP, SubjectType.ROLE, actual.getKey()));
+    }
+
+    @Test
+    public void deprovision() {
+        RoleTO actual = createRole(buildRoleTO("deprovision"));
+        assertNotNull(actual);
+
+        assertNotNull(resourceService.getConnectorObject(RESOURCE_NAME_LDAP, SubjectType.ROLE, actual.getKey()));
+
+        assertNotNull(roleService.bulkDeassociation(actual.getKey(),
+                ResourceDeassociationActionType.DEPROVISION,
+                CollectionWrapper.wrap(RESOURCE_NAME_LDAP, ResourceName.class)).
+                readEntity(BulkActionResult.class));
+
+        actual = roleService.read(actual.getKey());
+        assertNotNull(actual);
+        assertFalse(actual.getResources().isEmpty());
+
+        try {
+            resourceService.getConnectorObject(RESOURCE_NAME_LDAP, SubjectType.ROLE, actual.getKey());
+            fail();
+        } catch (Exception e) {
+            assertNotNull(e);
+        }
+    }
+
+    @Test
+    public void provision() {
+        RoleTO roleTO = buildRoleTO("assign");
+        roleTO.getResources().clear();
+
+        RoleTO actual = createRole(roleTO);
+        assertNotNull(actual);
+
+        try {
+            resourceService.getConnectorObject(RESOURCE_NAME_LDAP, SubjectType.ROLE, actual.getKey());
+            fail();
+        } catch (Exception e) {
+            assertNotNull(e);
+        }
+
+        assertNotNull(roleService.bulkAssociation(actual.getKey(),
+                ResourceAssociationActionType.PROVISION,
+                CollectionWrapper.wrap(RESOURCE_NAME_LDAP, ResourceName.class)).
+                readEntity(BulkActionResult.class));
+
+        actual = roleService.read(actual.getKey());
+        assertTrue(actual.getResources().isEmpty());
+
+        assertNotNull(resourceService.getConnectorObject(RESOURCE_NAME_LDAP, SubjectType.ROLE, actual.getKey()));
+    }
+
+    @Test
+    public void deprovisionUnlinked() {
+        RoleTO roleTO = buildRoleTO("assign");
+        roleTO.getResources().clear();
+
+        RoleTO actual = createRole(roleTO);
+        assertNotNull(actual);
+
+        try {
+            resourceService.getConnectorObject(RESOURCE_NAME_LDAP, SubjectType.ROLE, actual.getKey());
+            fail();
+        } catch (Exception e) {
+            assertNotNull(e);
+        }
+
+        assertNotNull(roleService.bulkAssociation(actual.getKey(),
+                ResourceAssociationActionType.PROVISION,
+                CollectionWrapper.wrap("resource-ldap", ResourceName.class)).
+                readEntity(BulkActionResult.class));
+
+        actual = roleService.read(actual.getKey());
+        assertTrue(actual.getResources().isEmpty());
+
+        assertNotNull(resourceService.getConnectorObject(RESOURCE_NAME_LDAP, SubjectType.ROLE, actual.getKey()));
+
+        assertNotNull(roleService.bulkDeassociation(actual.getKey(),
+                ResourceDeassociationActionType.DEPROVISION,
+                CollectionWrapper.wrap(RESOURCE_NAME_LDAP, ResourceName.class)).
+                readEntity(BulkActionResult.class));
+
+        actual = roleService.read(actual.getKey());
+        assertNotNull(actual);
+        assertTrue(actual.getResources().isEmpty());
+
+        try {
+            resourceService.getConnectorObject(RESOURCE_NAME_LDAP, SubjectType.ROLE, actual.getKey());
+            fail();
+        } catch (Exception e) {
+            assertNotNull(e);
+        }
+    }
+
+    @Test
+    public void createWithMandatorySchemaNotTemplate() {
+        // 1. create a role mandatory schema
+        PlainSchemaTO badge = new PlainSchemaTO();
+        badge.setKey("badge");
+        badge.setMandatoryCondition("true");
+        schemaService.create(AttributableType.ROLE, SchemaType.PLAIN, badge);
+
+        // 2. create a role *without* an attribute for that schema: it works
+        RoleTO roleTO = buildRoleTO("lastRole");
+        assertFalse(roleTO.getPlainAttrMap().containsKey(badge.getKey()));
+        roleTO = createRole(roleTO);
+        assertNotNull(roleTO);
+        assertFalse(roleTO.getPlainAttrMap().containsKey(badge.getKey()));
+
+        // 3. add a template for badge to the role just created - 
+        // failure since no values are provided and it is mandatory
+        RoleMod roleMod = new RoleMod();
+        roleMod.setKey(roleTO.getKey());
+        roleMod.setModRAttrTemplates(true);
+        roleMod.getRPlainAttrTemplates().add("badge");
+
+        try {
+            updateRole(roleMod);
+            fail();
+        } catch (SyncopeClientException e) {
+            assertEquals(ClientExceptionType.RequiredValuesMissing, e.getType());
+        }
+
+        // 4. also add an actual attribute for badge - it will work        
+        roleMod.getPlainAttrsToUpdate().add(attrMod(badge.getKey(), "xxxxxxxxxx"));
+
+        roleTO = updateRole(roleMod);
+        assertNotNull(roleTO);
+        assertTrue(roleTO.getPlainAttrMap().containsKey(badge.getKey()));
+    }
+
+    @Test
+    public void anonymous() {
+        RoleService unauthenticated = clientFactory.createAnonymous().getService(RoleService.class);
+        try {
+            unauthenticated.list();
+            fail();
+        } catch (AccessControlException e) {
+            assertNotNull(e);
+        }
+
+        RoleService anonymous = clientFactory.create(ANONYMOUS_UNAME, ANONYMOUS_KEY).getService(RoleService.class);
+        assertFalse(anonymous.list().getResult().isEmpty());
+    }
+
+    @Test
+    public void noContent() throws IOException {
+        SyncopeClient noContentclient = clientFactory.create(ADMIN_UNAME, ADMIN_PWD);
+        RoleService noContentService = noContentclient.prefer(RoleService.class, Preference.RETURN_NO_CONTENT);
+
+        RoleTO role = buildRoleTO("noContent");
+
+        Response response = noContentService.create(role);
+        assertEquals(Response.Status.CREATED.getStatusCode(), response.getStatus());
+        assertEquals(Preference.RETURN_NO_CONTENT.toString(), response.getHeaderString(RESTHeaders.PREFERENCE_APPLIED));
+        assertEquals(StringUtils.EMPTY, IOUtils.toString((InputStream) response.getEntity()));
+
+        role = getObject(response.getLocation(), RoleService.class, RoleTO.class);
+        assertNotNull(role);
+
+        RoleMod roleMod = new RoleMod();
+        roleMod.getPlainAttrsToUpdate().add(attrMod("badge", "xxxxxxxxxx"));
+
+        response = noContentService.update(role.getKey(), roleMod);
+        assertEquals(Response.Status.NO_CONTENT.getStatusCode(), response.getStatus());
+        assertEquals(Preference.RETURN_NO_CONTENT.toString(), response.getHeaderString(RESTHeaders.PREFERENCE_APPLIED));
+        assertEquals(StringUtils.EMPTY, IOUtils.toString((InputStream) response.getEntity()));
+
+        response = noContentService.delete(role.getKey());
+        assertEquals(Response.Status.NO_CONTENT.getStatusCode(), response.getStatus());
+        assertEquals(Preference.RETURN_NO_CONTENT.toString(), response.getHeaderString(RESTHeaders.PREFERENCE_APPLIED));
+        assertEquals(StringUtils.EMPTY, IOUtils.toString((InputStream) response.getEntity()));
+    }
+
+    @Test
+    public void issueSYNCOPE455() {
+        final String parentName = "issueSYNCOPE455-PRole";
+        final String childName = "issueSYNCOPE455-CRole";
+
+        // 1. create parent role
+        RoleTO parent = buildBasicRoleTO(parentName);
+        parent.getResources().add(RESOURCE_NAME_LDAP);
+
+        parent = createRole(parent);
+        assertTrue(parent.getResources().contains(RESOURCE_NAME_LDAP));
+
+        final ConnObjectTO parentRemoteObject =
+                resourceService.getConnectorObject(RESOURCE_NAME_LDAP, SubjectType.ROLE, parent.getKey());
+        assertNotNull(parentRemoteObject);
+        assertNotNull(getLdapRemoteObject(parentRemoteObject.getPlainAttrMap().get(Name.NAME).getValues().get(0)));
+
+        // 2. create child role
+        RoleTO child = buildBasicRoleTO(childName);
+        child.getResources().add(RESOURCE_NAME_LDAP);
+        child.setParent(parent.getKey());
+
+        child = createRole(child);
+        assertTrue(child.getResources().contains(RESOURCE_NAME_LDAP));
+
+        final ConnObjectTO childRemoteObject =
+                resourceService.getConnectorObject(RESOURCE_NAME_LDAP, SubjectType.ROLE, child.getKey());
+        assertNotNull(childRemoteObject);
+        assertNotNull(getLdapRemoteObject(childRemoteObject.getPlainAttrMap().get(Name.NAME).getValues().get(0)));
+
+        // 3. remove parent role
+        roleService.delete(parent.getKey());
+
+        // 4. asserts for issue 455
+        try {
+            roleService.read(parent.getKey());
+            fail();
+        } catch (SyncopeClientException scce) {
+            assertNotNull(scce);
+        }
+
+        try {
+            roleService.read(child.getKey());
+            fail();
+        } catch (SyncopeClientException scce) {
+            assertNotNull(scce);
+        }
+
+        assertNull(getLdapRemoteObject(parentRemoteObject.getPlainAttrMap().get(Name.NAME).getValues().get(0)));
+        assertNull(getLdapRemoteObject(childRemoteObject.getPlainAttrMap().get(Name.NAME).getValues().get(0)));
+    }
+
+    @Test
+    public void issueSYNCOPE543() {
+        final String ancestorName = "issueSYNCOPE543-ARole";
+        final String parentName = "issueSYNCOPE543-PRole";
+        final String childName = "issueSYNCOPE543-CRole";
+
+        // 1. create ancestor role
+        RoleTO ancestor = buildBasicRoleTO(ancestorName);
+        ancestor.setParent(0L);
+        ancestor.getRAttrTemplates().add("icon");
+        ancestor.getPlainAttrs().add(attrTO("icon", "ancestorIcon"));
+        ancestor = createRole(ancestor);
+        assertEquals("ancestorIcon", ancestor.getPlainAttrMap().get("icon").getValues().get(0));
+
+        // 2. create parent role
+        RoleTO parent = buildBasicRoleTO(parentName);
+        parent.setParent(ancestor.getKey());
+        parent.getRAttrTemplates().add("icon");
+        parent.getPlainAttrs().add(attrTO("icon", "parentIcon"));
+        parent = createRole(parent);
+        assertEquals("parentIcon", parent.getPlainAttrMap().get("icon").getValues().get(0));
+
+        // 3. create child role
+        RoleTO child = buildBasicRoleTO(childName);
+        child.setParent(parent.getKey());
+        child.getRAttrTemplates().add("icon");
+        child.getPlainAttrs().add(attrTO("icon", "childIcon"));
+        child = createRole(child);
+        assertEquals("childIcon", child.getPlainAttrMap().get("icon").getValues().get(0));
+
+        final RoleMod roleChildMod = new RoleMod();
+        roleChildMod.setKey(child.getKey());
+        roleChildMod.setInheritPlainAttrs(Boolean.TRUE);
+        updateRole(roleChildMod);
+
+        child = roleService.read(child.getKey());
+        assertNotNull(child);
+        assertNotNull(child.getPlainAttrMap().get("icon").getValues());
+        assertEquals("parentIcon", child.getPlainAttrMap().get("icon").getValues().get(0));
+
+        final RoleMod roleParentMod = new RoleMod();
+        roleParentMod.setKey(parent.getKey());
+        roleParentMod.setInheritPlainAttrs(Boolean.TRUE);
+        updateRole(roleParentMod);
+
+        child = roleService.read(child.getKey());
+        assertNotNull(child);
+        assertNotNull(child.getPlainAttrMap().get("icon").getValues());
+        assertEquals("ancestorIcon", child.getPlainAttrMap().get("icon").getValues().get(0));
+
+        parent = roleService.read(parent.getKey());
+        assertNotNull(parent);
+        assertNotNull(parent.getPlainAttrMap().get("icon").getValues());
+        assertEquals("ancestorIcon", parent.getPlainAttrMap().get("icon").getValues().get(0));
+
+        roleParentMod.setInheritPlainAttrs(Boolean.FALSE);
+        updateRole(roleParentMod);
+
+        child = roleService.read(child.getKey());
+        assertNotNull(child);
+        assertNotNull(child.getPlainAttrMap().get("icon").getValues());
+        assertEquals("parentIcon", child.getPlainAttrMap().get("icon").getValues().get(0));
+    }
+
+    @Test
+    public void issueSYNCOPE632() {
+        RoleTO roleTO = null;
+        try {
+            // 1. create new LDAP resource having account id mapped to a derived attribute
+            ResourceTO newLDAP = resourceService.read(RESOURCE_NAME_LDAP);
+            newLDAP.setKey("new-ldap");
+            newLDAP.setPropagationPrimary(true);
+            MappingItemTO accountId = newLDAP.getRmapping().getAccountIdItem();
+            accountId.setIntMappingType(IntMappingType.RoleDerivedSchema);
+            accountId.setIntAttrName("displayProperty");
+            newLDAP.getRmapping().setAccountIdItem(accountId);
+            newLDAP.getRmapping().setAccountLink("'cn=' + displayProperty + ',ou=groups,o=isp'");
+
+            MappingItemTO description = new MappingItemTO();
+            description.setIntMappingType(IntMappingType.RoleId);
+            description.setExtAttrName("description");
+            description.setPurpose(MappingPurpose.BOTH);
+            newLDAP.getRmapping().addItem(description);
+
+            newLDAP = createResource(newLDAP);
+            assertNotNull(newLDAP);
+
+            // 2. create a role and give the resource created above
+            roleTO = buildRoleTO("lastRole");
+            roleTO.getRAttrTemplates().add("icon");
+            roleTO.getPlainAttrs().add(attrTO("icon", "anIcon"));
+            roleTO.getRAttrTemplates().add("show");
+            roleTO.getPlainAttrs().add(attrTO("show", "true"));
+            roleTO.getRDerAttrTemplates().add("displayProperty");
+            roleTO.getDerAttrs().add(attrTO("displayProperty", null));
+            roleTO.getResources().clear();
+            roleTO.getResources().add("new-ldap");
+
+            roleTO = createRole(roleTO);
+            assertNotNull(roleTO);
+
+            // 3. update the role
+            RoleMod roleMod = new RoleMod();
+            roleMod.setKey(roleTO.getKey());
+            roleMod.getPlainAttrsToRemove().add("icon");
+            roleMod.getPlainAttrsToUpdate().add(attrMod("icon", "anotherIcon"));
+
+            roleTO = updateRole(roleMod);
+            assertNotNull(roleTO);
+
+            // 4. check that a single group exists in LDAP for the role created and updated above
+            int entries = 0;
+            DirContext ctx = null;
+            try {
+                ctx = getLdapResourceDirContext(null, null);
+
+                SearchControls ctls = new SearchControls();
+                ctls.setReturningAttributes(new String[] { "*", "+" });
+                ctls.setSearchScope(SearchControls.SUBTREE_SCOPE);
+
+                NamingEnumeration<SearchResult> result =
+                        ctx.search("ou=groups,o=isp", "(description=" + roleTO.getKey() + ")", ctls);
+                while (result.hasMore()) {
+                    result.next();
+                    entries++;
+                }
+            } catch (Exception e) {
+                // ignore
+            } finally {
+                if (ctx != null) {
+                    try {
+                        ctx.close();
+                    } catch (NamingException e) {
+                        // ignore
+                    }
+                }
+            }
+
+            assertEquals(1, entries);
+        } finally {
+            if (roleTO != null) {
+                roleService.delete(roleTO.getKey());
+            }
+            resourceService.delete("new-ldap");
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/32707b3b/syncope620/fit/server-reference/src/test/java/org/apache/syncope/fit/server/reference/SchedTaskITCase.java
----------------------------------------------------------------------
diff --git a/syncope620/fit/server-reference/src/test/java/org/apache/syncope/fit/server/reference/SchedTaskITCase.java b/syncope620/fit/server-reference/src/test/java/org/apache/syncope/fit/server/reference/SchedTaskITCase.java
new file mode 100644
index 0000000..424ca08
--- /dev/null
+++ b/syncope620/fit/server-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());
+    }
+}