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:37 UTC

[06/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/ConnectorITCase.java
----------------------------------------------------------------------
diff --git a/syncope620/fit/server-reference/src/test/java/org/apache/syncope/fit/server/reference/ConnectorITCase.java b/syncope620/fit/server-reference/src/test/java/org/apache/syncope/fit/server/reference/ConnectorITCase.java
new file mode 100644
index 0000000..83e0832
--- /dev/null
+++ b/syncope620/fit/server-reference/src/test/java/org/apache/syncope/fit/server/reference/ConnectorITCase.java
@@ -0,0 +1,730 @@
+/*
+ * 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.util.ArrayList;
+import java.util.EnumSet;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Properties;
+import java.util.Set;
+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.to.BulkAction;
+import org.apache.syncope.common.lib.to.ConnBundleTO;
+import org.apache.syncope.common.lib.to.ConnIdObjectClassTO;
+import org.apache.syncope.common.lib.to.ConnInstanceTO;
+import org.apache.syncope.common.lib.to.ConnPoolConfTO;
+import org.apache.syncope.common.lib.to.MappingItemTO;
+import org.apache.syncope.common.lib.to.MappingTO;
+import org.apache.syncope.common.lib.to.PlainSchemaTO;
+import org.apache.syncope.common.lib.to.ResourceTO;
+import org.apache.syncope.common.lib.types.ConnConfPropSchema;
+import org.apache.syncope.common.lib.types.ConnConfProperty;
+import org.apache.syncope.common.lib.types.ConnectorCapability;
+import org.apache.syncope.common.lib.types.IntMappingType;
+import org.apache.syncope.common.rest.api.service.ConnectorService;
+import org.apache.syncope.common.rest.api.service.ResourceService;
+import org.identityconnectors.common.security.GuardedString;
+import org.junit.BeforeClass;
+import org.junit.FixMethodOrder;
+import org.junit.Test;
+import org.junit.runners.MethodSorters;
+
+@FixMethodOrder(MethodSorters.JVM)
+public class ConnectorITCase extends AbstractITCase {
+
+    private static String connectorServerLocation;
+
+    private static String connidSoapVersion;
+
+    private static String connidDbTableVersion;
+
+    private static String testJDBCURL;
+
+    @BeforeClass
+    public static void setUpConnIdBundles() throws IOException {
+        InputStream propStream = null;
+        try {
+            Properties props = new Properties();
+            propStream = ConnectorITCase.class.getResourceAsStream("/connid.properties");
+            props.load(propStream);
+
+            for (String location : props.getProperty("connid.locations").split(",")) {
+                if (!location.startsWith("file")) {
+                    connectorServerLocation = location;
+                }
+            }
+
+            connidSoapVersion = props.getProperty("connid.soap.version");
+            connidDbTableVersion = props.getProperty("connid.db.table.version");
+
+            testJDBCURL = props.getProperty("testdb.url");
+        } catch (Exception e) {
+            LOG.error("Could not load /connid.properties", e);
+        } finally {
+            IOUtils.closeQuietly(propStream);
+        }
+        assertNotNull(connectorServerLocation);
+        assertNotNull(connidSoapVersion);
+        assertNotNull(connidDbTableVersion);
+        assertNotNull(testJDBCURL);
+    }
+
+    @Test(expected = SyncopeClientException.class)
+    public void createWithException() {
+        ConnInstanceTO connectorTO = new ConnInstanceTO();
+
+        Response response = connectorService.create(connectorTO);
+        if (response.getStatusInfo().getStatusCode() != Response.Status.CREATED.getStatusCode()) {
+            throw (RuntimeException) clientFactory.getExceptionMapper().fromResponse(response);
+        }
+    }
+
+    @Test
+    public void create() {
+        ConnInstanceTO connectorTO = new ConnInstanceTO();
+        connectorTO.setLocation(connectorService.read(100L).getLocation());
+        connectorTO.setVersion(connidSoapVersion);
+        connectorTO.setConnectorName("net.tirasa.connid.bundles.soap.WebServiceConnector");
+        connectorTO.setBundleName("net.tirasa.connid.bundles.soap");
+        connectorTO.setDisplayName("Display name");
+        connectorTO.setConnRequestTimeout(15);
+
+        // set the connector configuration using PropertyTO
+        Set<ConnConfProperty> conf = new HashSet<>();
+
+        ConnConfPropSchema endpointSchema = new ConnConfPropSchema();
+        endpointSchema.setName("endpoint");
+        endpointSchema.setType(String.class.getName());
+        endpointSchema.setRequired(true);
+        ConnConfProperty endpoint = new ConnConfProperty();
+        endpoint.setSchema(endpointSchema);
+        endpoint.getValues().add("http://localhost:8888/wssample/services");
+        endpoint.getValues().add("Provisioning");
+        conf.add(endpoint);
+
+        ConnConfPropSchema servicenameSchema = new ConnConfPropSchema();
+        servicenameSchema.setName("servicename");
+        servicenameSchema.setType(String.class.getName());
+        servicenameSchema.setRequired(true);
+        ConnConfProperty servicename = new ConnConfProperty();
+        servicename.setSchema(servicenameSchema);
+        conf.add(servicename);
+
+        // set connector configuration
+        connectorTO.getConfiguration().addAll(conf);
+
+        // set connector capabilities
+        connectorTO.getCapabilities().add(ConnectorCapability.TWO_PHASES_CREATE);
+        connectorTO.getCapabilities().add(ConnectorCapability.ONE_PHASE_CREATE);
+        connectorTO.getCapabilities().add(ConnectorCapability.TWO_PHASES_UPDATE);
+
+        // set connector pool conf
+        ConnPoolConfTO cpc = new ConnPoolConfTO();
+        cpc.setMaxObjects(1534);
+        connectorTO.setPoolConf(cpc);
+
+        Response response = connectorService.create(connectorTO);
+        if (response.getStatusInfo().getStatusCode() != Response.Status.CREATED.getStatusCode()) {
+            throw (RuntimeException) clientFactory.getExceptionMapper().fromResponse(response);
+        }
+
+        ConnInstanceTO actual = getObject(
+                response.getLocation(), ConnectorService.class, ConnInstanceTO.class);
+        assertNotNull(actual);
+
+        assertEquals(actual.getBundleName(), connectorTO.getBundleName());
+        assertEquals(actual.getConnectorName(), connectorTO.getConnectorName());
+        assertEquals(actual.getVersion(), connectorTO.getVersion());
+        assertEquals("Display name", actual.getDisplayName());
+        assertEquals(Integer.valueOf(15), actual.getConnRequestTimeout());
+        assertEquals(connectorTO.getCapabilities(), actual.getCapabilities());
+        assertNotNull(actual.getPoolConf());
+        assertEquals(1534, actual.getPoolConf().getMaxObjects().intValue());
+        assertEquals(10, actual.getPoolConf().getMaxIdle().intValue());
+
+        Throwable t = null;
+
+        // check update
+        actual.getCapabilities().remove(ConnectorCapability.TWO_PHASES_UPDATE);
+        actual.getPoolConf().setMaxObjects(null);
+
+        try {
+            connectorService.update(actual.getKey(), actual);
+            actual = connectorService.read(actual.getKey());
+        } catch (SyncopeClientException e) {
+            LOG.error("update failed", e);
+            t = e;
+        }
+
+        assertNull(t);
+        assertNotNull(actual);
+        assertEquals(EnumSet.of(ConnectorCapability.ONE_PHASE_CREATE, ConnectorCapability.TWO_PHASES_CREATE),
+                actual.getCapabilities());
+        assertEquals(10, actual.getPoolConf().getMaxObjects().intValue());
+
+        // check also for the deletion of the created object
+        try {
+            connectorService.delete(actual.getKey());
+        } catch (SyncopeClientException e) {
+            LOG.error("delete failed", e);
+            t = e;
+        }
+
+        assertNull(t);
+
+        // check the non existence
+        try {
+            connectorService.read(actual.getKey());
+        } catch (SyncopeClientException e) {
+            assertEquals(Response.Status.NOT_FOUND, e.getType().getResponseStatus());
+        }
+    }
+
+    @Test
+    public void update() {
+        ConnInstanceTO connectorTO = new ConnInstanceTO();
+
+        // set connector instance id
+        connectorTO.setKey(103L);
+
+        // set connector version
+        connectorTO.setVersion(connidSoapVersion);
+
+        // set connector name
+        connectorTO.setConnectorName("net.tirasa.connid.bundles.soap.WebServiceConnector");
+
+        // set bundle name
+        connectorTO.setBundleName("net.tirasa.connid.bundles.soap");
+
+        connectorTO.setConnRequestTimeout(20);
+
+        // set the connector configuration using PropertyTO
+        Set<ConnConfProperty> conf = new HashSet<ConnConfProperty>();
+
+        ConnConfPropSchema endpointSchema = new ConnConfPropSchema();
+        endpointSchema.setName("endpoint");
+        endpointSchema.setType(String.class.getName());
+        endpointSchema.setRequired(true);
+        ConnConfProperty endpoint = new ConnConfProperty();
+        endpoint.setSchema(endpointSchema);
+        endpoint.getValues().add("http://localhost:8888/wssample/services");
+        conf.add(endpoint);
+
+        ConnConfPropSchema servicenameSchema = new ConnConfPropSchema();
+        servicenameSchema.setName("servicename");
+        servicenameSchema.setType(String.class.getName());
+        servicenameSchema.setRequired(true);
+        ConnConfProperty servicename = new ConnConfProperty();
+        servicename.setSchema(servicenameSchema);
+        servicename.getValues().add("Provisioning");
+        conf.add(servicename);
+
+        // set connector configuration
+        connectorTO.getConfiguration().addAll(conf);
+
+        connectorService.update(connectorTO.getKey(), connectorTO);
+        ConnInstanceTO actual = connectorService.read(connectorTO.getKey());
+
+        assertNotNull(actual);
+
+        actual = connectorService.read(actual.getKey());
+
+        assertNotNull(actual);
+        assertEquals(actual.getBundleName(), connectorTO.getBundleName());
+        assertEquals(actual.getConnectorName(), connectorTO.getConnectorName());
+        assertEquals(actual.getVersion(), connectorTO.getVersion());
+        assertEquals(Integer.valueOf(20), actual.getConnRequestTimeout());
+    }
+
+    private List<ResourceTO> filter(final List<ResourceTO> input, final Long connectorKey) {
+        List<ResourceTO> result = new ArrayList<>();
+
+        for (ResourceTO resource : input) {
+            if (connectorKey.equals(resource.getConnectorId())) {
+                result.add(resource);
+            }
+        }
+
+        return result;
+    }
+
+    @Test
+    public void issueSYNCOPE10() {
+        // ----------------------------------
+        // Copy resource and connector in order to create new objects.
+        // ----------------------------------
+        // Retrieve a connector instance template.
+        ConnInstanceTO connInstanceTO = connectorService.read(103L);
+        assertNotNull(connInstanceTO);
+
+        // check for resource
+        List<ResourceTO> resources = filter(resourceService.list(), 103L);
+        assertEquals(4, resources.size());
+
+        // Retrieve a resource TO template.
+        ResourceTO resourceTO = resources.get(0);
+
+        // Make it new.
+        resourceTO.setKey("newAbout103");
+
+        // Make it new.
+        connInstanceTO.setKey(0);
+        connInstanceTO.setDisplayName("newDisplayName" + getUUIDString());
+        // ----------------------------------
+
+        // ----------------------------------
+        // Create a new connector instance.
+        // ----------------------------------
+        Response response = connectorService.create(connInstanceTO);
+        if (response.getStatusInfo().getStatusCode() != Response.Status.CREATED.getStatusCode()) {
+            throw (RuntimeException) clientFactory.getExceptionMapper().fromResponse(response);
+        }
+
+        connInstanceTO = getObject(response.getLocation(), ConnectorService.class, ConnInstanceTO.class);
+        assertNotNull(connInstanceTO);
+        assertFalse(connInstanceTO.getCapabilities().contains(ConnectorCapability.AUTHENTICATE));
+
+        long connId = connInstanceTO.getKey();
+
+        // Link resourceTO to the new connector instance.
+        resourceTO.setConnectorId(connId);
+        // ----------------------------------
+
+        // ----------------------------------
+        // Check for connector instance update after resource creation.
+        // ----------------------------------
+        response = resourceService.create(resourceTO);
+        resourceTO = getObject(response.getLocation(), ResourceService.class, ResourceTO.class);
+
+        assertNotNull(resourceTO);
+
+        resources = filter(resourceService.list(), connId);
+        assertEquals(1, resources.size());
+        // ----------------------------------
+
+        // ----------------------------------
+        // Check for spring bean.
+        // ----------------------------------
+        ConnInstanceTO connInstanceBean = connectorService.readByResource(resourceTO.getKey());
+        assertNotNull(connInstanceBean);
+        assertFalse(connInstanceBean.getCapabilities().contains(ConnectorCapability.AUTHENTICATE));
+        // ----------------------------------
+
+        // ----------------------------------
+        // Check for spring bean update after connector instance update.
+        // ----------------------------------
+        connInstanceTO.getCapabilities().add(ConnectorCapability.AUTHENTICATE);
+
+        connectorService.update(connInstanceTO.getKey(), connInstanceTO);
+        ConnInstanceTO actual = connectorService.read(connInstanceTO.getKey());
+        assertNotNull(actual);
+        assertTrue(connInstanceTO.getCapabilities().contains(ConnectorCapability.AUTHENTICATE));
+
+        // check for spring bean update
+        connInstanceBean = connectorService.readByResource(resourceTO.getKey());
+        assertTrue(connInstanceBean.getCapabilities().contains(ConnectorCapability.AUTHENTICATE));
+        // ----------------------------------
+    }
+
+    @Test
+    public void deleteWithException() {
+        try {
+            connectorService.delete(0L);
+        } catch (SyncopeClientException e) {
+            assertEquals(Response.Status.NOT_FOUND, e.getType().getResponseStatus());
+        }
+    }
+
+    @Test
+    public void list() {
+        List<ConnInstanceTO> connectorInstanceTOs = connectorService.list(null);
+        assertNotNull(connectorInstanceTOs);
+        assertFalse(connectorInstanceTOs.isEmpty());
+        for (ConnInstanceTO instance : connectorInstanceTOs) {
+            assertNotNull(instance);
+        }
+    }
+
+    @Test
+    public void read() {
+        ConnInstanceTO connectorInstanceTO = connectorService.read(100L);
+        assertNotNull(connectorInstanceTO);
+    }
+
+    @Test
+    public void getBundles() {
+        List<ConnBundleTO> bundles = connectorService.getBundles(null);
+        assertNotNull(bundles);
+        assertFalse(bundles.isEmpty());
+        for (ConnBundleTO bundle : bundles) {
+            assertNotNull(bundle);
+        }
+    }
+
+    @Test
+    public void getConnectorConfiguration() {
+        List<ConnConfProperty> props = connectorService.getConfigurationProperties(104L);
+        assertNotNull(props);
+        assertFalse(props.isEmpty());
+    }
+
+    @Test
+    public void checkHiddenProperty() {
+        ConnInstanceTO connInstanceTO = connectorService.read(100L);
+
+        boolean check = false;
+
+        for (ConnConfProperty prop : connInstanceTO.getConfiguration()) {
+            if ("receiveTimeout".equals(prop.getSchema().getName())) {
+                check = true;
+            }
+        }
+        assertTrue(check);
+    }
+
+    @Test
+    public void checkSelectedLanguage() {
+        // 1. Check Italian
+        List<ConnInstanceTO> connectorInstanceTOs = connectorService.list("it");
+
+        Map<String, ConnConfProperty> instanceConfMap;
+        for (ConnInstanceTO instance : connectorInstanceTOs) {
+            if ("net.tirasa.connid.bundles.db.table".equals(instance.getBundleName())) {
+                instanceConfMap = instance.getConfigurationMap();
+                assertEquals("Utente", instanceConfMap.get("user").getSchema().getDisplayName());
+            }
+        }
+
+        // 2. Check English (default)
+        connectorInstanceTOs = connectorService.list(null);
+
+        for (ConnInstanceTO instance : connectorInstanceTOs) {
+            if ("net.tirasa.connid.bundles.db.table".equals(instance.getBundleName())) {
+                instanceConfMap = instance.getConfigurationMap();
+                assertEquals("User", instanceConfMap.get("user").getSchema().getDisplayName());
+            }
+        }
+    }
+
+    @Test
+    public void validate() {
+        ConnInstanceTO connectorTO = new ConnInstanceTO();
+        connectorTO.setLocation(connectorServerLocation);
+        connectorTO.setVersion(connidDbTableVersion);
+        connectorTO.setConnectorName("net.tirasa.connid.bundles.db.table.DatabaseTableConnector");
+        connectorTO.setBundleName("net.tirasa.connid.bundles.db.table");
+        connectorTO.setDisplayName("H2Test");
+
+        // set the connector configuration using PropertyTO
+        Set<ConnConfProperty> conf = new HashSet<ConnConfProperty>();
+
+        ConnConfPropSchema jdbcDriverSchema = new ConnConfPropSchema();
+        jdbcDriverSchema.setName("jdbcDriver");
+        jdbcDriverSchema.setType(String.class.getName());
+        jdbcDriverSchema.setRequired(true);
+        ConnConfProperty jdbcDriver = new ConnConfProperty();
+        jdbcDriver.setSchema(jdbcDriverSchema);
+        jdbcDriver.getValues().add("org.h2.Driver");
+        conf.add(jdbcDriver);
+
+        ConnConfPropSchema jdbcUrlTemplateSchema = new ConnConfPropSchema();
+        jdbcUrlTemplateSchema.setName("jdbcUrlTemplate");
+        jdbcUrlTemplateSchema.setType(String.class.getName());
+        jdbcUrlTemplateSchema.setRequired(true);
+        ConnConfProperty jdbcUrlTemplate = new ConnConfProperty();
+        jdbcUrlTemplate.setSchema(jdbcUrlTemplateSchema);
+        jdbcUrlTemplate.getValues().add(testJDBCURL);
+        conf.add(jdbcUrlTemplate);
+
+        ConnConfPropSchema userSchema = new ConnConfPropSchema();
+        userSchema.setName("user");
+        userSchema.setType(String.class.getName());
+        userSchema.setRequired(false);
+        ConnConfProperty user = new ConnConfProperty();
+        user.setSchema(userSchema);
+        user.getValues().add("sa");
+        conf.add(user);
+
+        ConnConfPropSchema passwordSchema = new ConnConfPropSchema();
+        passwordSchema.setName("password");
+        passwordSchema.setType(GuardedString.class.getName());
+        passwordSchema.setRequired(true);
+        ConnConfProperty password = new ConnConfProperty();
+        password.setSchema(passwordSchema);
+        password.getValues().add("sa");
+        conf.add(password);
+
+        ConnConfPropSchema tableSchema = new ConnConfPropSchema();
+        tableSchema.setName("table");
+        tableSchema.setType(String.class.getName());
+        tableSchema.setRequired(true);
+        ConnConfProperty table = new ConnConfProperty();
+        table.setSchema(tableSchema);
+        table.getValues().add("test");
+        conf.add(table);
+
+        ConnConfPropSchema keyColumnSchema = new ConnConfPropSchema();
+        keyColumnSchema.setName("keyColumn");
+        keyColumnSchema.setType(String.class.getName());
+        keyColumnSchema.setRequired(true);
+        ConnConfProperty keyColumn = new ConnConfProperty();
+        keyColumn.setSchema(keyColumnSchema);
+        keyColumn.getValues().add("id");
+        conf.add(keyColumn);
+
+        ConnConfPropSchema passwordColumnSchema = new ConnConfPropSchema();
+        passwordColumnSchema.setName("passwordColumn");
+        passwordColumnSchema.setType(String.class.getName());
+        passwordColumnSchema.setRequired(true);
+        ConnConfProperty passwordColumn = new ConnConfProperty();
+        passwordColumn.setSchema(passwordColumnSchema);
+        passwordColumn.getValues().add("password");
+        conf.add(passwordColumn);
+
+        // set connector configuration
+        connectorTO.getConfiguration().addAll(conf);
+
+        assertTrue(connectorService.check(connectorTO));
+
+        conf.remove(password);
+        password.getValues().clear();
+        password.getValues().add("password");
+        conf.add(password);
+
+        assertFalse(connectorService.check(connectorTO));
+    }
+
+    @Test
+    public void getSchemaNames() {
+        ConnInstanceTO conn = connectorService.read(101L);
+
+        List<PlainSchemaTO> schemaNames = connectorService.getSchemaNames(conn.getKey(), conn, true);
+        assertNotNull(schemaNames);
+        assertFalse(schemaNames.isEmpty());
+        assertNotNull(schemaNames.get(0).getKey());
+        assertNull(schemaNames.get(0).getEnumerationValues());
+
+        schemaNames = connectorService.getSchemaNames(conn.getKey(), conn, false);
+
+        assertNotNull(schemaNames);
+        assertEquals(0, schemaNames.size());
+
+        conn = connectorService.read(104L);
+
+        // to be used with overridden properties
+        conn.getConfiguration().clear();
+
+        schemaNames = connectorService.getSchemaNames(conn.getKey(), conn, true);
+        assertNotNull(schemaNames);
+        assertFalse(schemaNames.isEmpty());
+    }
+
+    @Test
+    public void getSupportedObjectClasses() {
+        ConnInstanceTO ldap = connectorService.read(105L);
+        assertNotNull(ldap);
+
+        List<ConnIdObjectClassTO> objectClasses = connectorService.getSupportedObjectClasses(ldap.getKey(), ldap);
+        assertNotNull(objectClasses);
+        assertEquals(2, objectClasses.size());
+        assertTrue(objectClasses.contains(ConnIdObjectClassTO.ACCOUNT));
+        assertTrue(objectClasses.contains(ConnIdObjectClassTO.GROUP));
+
+        ConnInstanceTO csv = connectorService.read(104L);
+        assertNotNull(csv);
+
+        objectClasses = connectorService.getSupportedObjectClasses(csv.getKey(), csv);
+        assertNotNull(objectClasses);
+        assertEquals(1, objectClasses.size());
+        assertTrue(objectClasses.contains(ConnIdObjectClassTO.ACCOUNT));
+    }
+
+    @Test
+    public void issueSYNCOPE112() {
+        // ----------------------------------------
+        // Create a new connector
+        // ----------------------------------------
+        ConnInstanceTO connectorTO = new ConnInstanceTO();
+
+        connectorTO.setLocation(connectorService.read(100L).getLocation());
+
+        // set connector version
+        connectorTO.setVersion(connidSoapVersion);
+
+        // set connector name
+        connectorTO.setConnectorName("net.tirasa.connid.bundles.soap.WebServiceConnector");
+
+        // set bundle name
+        connectorTO.setBundleName("net.tirasa.connid.bundles.soap");
+
+        // set display name
+        connectorTO.setDisplayName("WSSoap");
+
+        // set the connector configuration using PropertyTO
+        Set<ConnConfProperty> conf = new HashSet<ConnConfProperty>();
+
+        ConnConfPropSchema userSchema = new ConnConfPropSchema();
+        userSchema.setName("endpoint");
+        userSchema.setType(String.class.getName());
+        userSchema.setRequired(true);
+        ConnConfProperty endpoint = new ConnConfProperty();
+        endpoint.setSchema(userSchema);
+        endpoint.getValues().add("http://localhost:9080/does_not_work");
+        endpoint.setOverridable(true);
+
+        ConnConfPropSchema keyColumnSchema = new ConnConfPropSchema();
+        keyColumnSchema.setName("servicename");
+        keyColumnSchema.setType(String.class.getName());
+        keyColumnSchema.setRequired(true);
+        ConnConfProperty servicename = new ConnConfProperty();
+        servicename.setSchema(keyColumnSchema);
+        servicename.getValues().add("net.tirasa.connid.bundles.soap.provisioning.interfaces.Provisioning");
+        servicename.setOverridable(false);
+
+        conf.add(endpoint);
+        conf.add(servicename);
+
+        // set connector configuration
+        connectorTO.getConfiguration().addAll(conf);
+
+        try {
+            assertFalse(connectorService.check(connectorTO));
+
+            Response response = connectorService.create(connectorTO);
+            if (response.getStatusInfo().getStatusCode() != Response.Status.CREATED.getStatusCode()) {
+                throw (RuntimeException) clientFactory.getExceptionMapper().fromResponse(response);
+            }
+
+            connectorTO = getObject(response.getLocation(), ConnectorService.class, ConnInstanceTO.class);
+            assertNotNull(connectorTO);
+            // ----------------------------------------
+
+            // ----------------------------------------
+            // create a resourceTO
+            // ----------------------------------------
+            String resourceName = "checkForPropOverriding";
+            ResourceTO resourceTO = new ResourceTO();
+
+            resourceTO.setKey(resourceName);
+            resourceTO.setConnectorId(connectorTO.getKey());
+
+            conf = new HashSet<ConnConfProperty>();
+            endpoint.getValues().clear();
+            endpoint.getValues().add("http://localhost:9080/wssample/services/provisioning");
+            conf.add(endpoint);
+
+            resourceTO.getConnConfProperties().addAll(conf);
+
+            MappingTO mapping = new MappingTO();
+            resourceTO.setUmapping(mapping);
+
+            MappingItemTO mapItem = new MappingItemTO();
+            mapItem.setExtAttrName("uid");
+            mapItem.setIntAttrName("userId");
+            mapItem.setIntMappingType(IntMappingType.UserPlainSchema);
+            mapItem.setAccountid(true);
+            mapping.setAccountIdItem(mapItem);
+            // ----------------------------------------
+
+            // ----------------------------------------
+            // Check connection without saving the resource ....
+            // ----------------------------------------
+            assertTrue(resourceService.check(resourceTO));
+            // ----------------------------------------
+        } finally {
+            // Remove connector from db to make test re-runnable
+            connectorService.delete(connectorTO.getKey());
+        }
+    }
+
+    @Test
+    public void reload() {
+        connectorService.reload();
+    }
+
+    @Test
+    public void bulkAction() {
+        final BulkAction bulkAction = new BulkAction();
+        bulkAction.setOperation(BulkAction.Type.DELETE);
+
+        ConnInstanceTO conn = connectorService.read(101L);
+
+        conn.setKey(0);
+        conn.setDisplayName("forBulk1");
+
+        bulkAction.getTargets().add(String.valueOf(getObject(
+                connectorService.create(conn).getLocation(), ConnectorService.class, ConnInstanceTO.class).getKey()));
+
+        conn.setDisplayName("forBulk2");
+
+        bulkAction.getTargets().add(String.valueOf(getObject(
+                connectorService.create(conn).getLocation(), ConnectorService.class, ConnInstanceTO.class).getKey()));
+
+        Iterator<String> iter = bulkAction.getTargets().iterator();
+
+        assertNotNull(connectorService.read(Long.valueOf(iter.next())));
+        assertNotNull(connectorService.read(Long.valueOf(iter.next())));
+
+        connectorService.bulk(bulkAction);
+
+        iter = bulkAction.getTargets().iterator();
+
+        try {
+            connectorService.read(Long.valueOf(iter.next()));
+            fail();
+        } catch (SyncopeClientException e) {
+            assertNotNull(e);
+        }
+
+        try {
+            connectorService.read(Long.valueOf(iter.next()));
+            fail();
+        } catch (SyncopeClientException e) {
+            assertNotNull(e);
+        }
+    }
+
+    @Test
+    public void issueSYNCOPE605() {
+
+        ConnInstanceTO connectorInstanceTO = connectorService.read(103L);
+        assertTrue(connectorInstanceTO.getCapabilities().isEmpty());
+
+        connectorInstanceTO.getCapabilities().add(ConnectorCapability.SEARCH);
+        connectorService.update(connectorInstanceTO.getKey(), connectorInstanceTO);
+
+        ConnInstanceTO updatedCapabilities = connectorService.read(connectorInstanceTO.getKey());
+        assertNotNull(updatedCapabilities.getCapabilities());
+        assertTrue(updatedCapabilities.getCapabilities().size() == 1);
+    }
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/32707b3b/syncope620/fit/server-reference/src/test/java/org/apache/syncope/fit/server/reference/DerSchemaITCase.java
----------------------------------------------------------------------
diff --git a/syncope620/fit/server-reference/src/test/java/org/apache/syncope/fit/server/reference/DerSchemaITCase.java b/syncope620/fit/server-reference/src/test/java/org/apache/syncope/fit/server/reference/DerSchemaITCase.java
new file mode 100644
index 0000000..9ac24ea
--- /dev/null
+++ b/syncope620/fit/server-reference/src/test/java/org/apache/syncope/fit/server/reference/DerSchemaITCase.java
@@ -0,0 +1,151 @@
+/*
+ * 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.util.List;
+import javax.ws.rs.core.Response;
+import org.apache.syncope.common.lib.SyncopeClientException;
+import org.apache.syncope.common.lib.to.DerSchemaTO;
+import org.apache.syncope.common.lib.types.AttributableType;
+import org.apache.syncope.common.lib.types.ClientExceptionType;
+import org.apache.syncope.common.lib.types.EntityViolationType;
+import org.apache.syncope.common.lib.types.SchemaType;
+import org.junit.FixMethodOrder;
+import org.junit.Test;
+import org.junit.runners.MethodSorters;
+
+@FixMethodOrder(MethodSorters.JVM)
+public class DerSchemaITCase extends AbstractITCase {
+
+    @Test
+    public void list() {
+        List<DerSchemaTO> derivedSchemas = schemaService.list(AttributableType.USER, SchemaType.DERIVED);
+        assertFalse(derivedSchemas.isEmpty());
+        for (DerSchemaTO derivedSchemaTO : derivedSchemas) {
+            assertNotNull(derivedSchemaTO);
+        }
+    }
+
+    @Test
+    public void read() {
+        DerSchemaTO derivedSchemaTO = schemaService.read(AttributableType.USER, SchemaType.DERIVED,
+                "cn");
+        assertNotNull(derivedSchemaTO);
+    }
+
+    @Test
+    public void create() {
+        DerSchemaTO schema = new DerSchemaTO();
+        schema.setKey("derived");
+        schema.setExpression("derived_sx + '_' + derived_dx");
+
+        DerSchemaTO actual = createSchema(AttributableType.USER, SchemaType.DERIVED, schema);
+        assertNotNull(actual);
+
+        actual = schemaService.read(AttributableType.USER, SchemaType.DERIVED, actual.getKey());
+        assertNotNull(actual);
+        assertEquals(actual.getExpression(), "derived_sx + '_' + derived_dx");
+    }
+
+    @Test
+    public void delete() {
+        DerSchemaTO schema = schemaService.read(AttributableType.ROLE, SchemaType.DERIVED, "rderiveddata");
+        assertNotNull(schema);
+
+        schemaService.delete(AttributableType.ROLE, SchemaType.DERIVED, schema.getKey());
+
+        try {
+            schemaService.read(AttributableType.ROLE, SchemaType.DERIVED, "rderiveddata");
+            fail();
+        } catch (SyncopeClientException e) {
+            assertEquals(ClientExceptionType.NotFound, e.getType());
+        } finally {
+            // Recreate schema to make test re-runnable
+            schema = createSchema(AttributableType.ROLE, SchemaType.DERIVED, schema);
+            assertNotNull(schema);
+        }
+    }
+
+    @Test
+    public void update() {
+        DerSchemaTO schema = schemaService.read(AttributableType.MEMBERSHIP, SchemaType.DERIVED,
+                "mderiveddata");
+        assertNotNull(schema);
+        assertEquals("mderived_sx + '-' + mderived_dx", schema.getExpression());
+        try {
+            schema.setExpression("mderived_sx + '.' + mderived_dx");
+
+            schemaService.update(AttributableType.MEMBERSHIP, SchemaType.DERIVED,
+                    schema.getKey(), schema);
+
+            schema = schemaService.read(AttributableType.MEMBERSHIP, SchemaType.DERIVED, "mderiveddata");
+            assertNotNull(schema);
+            assertEquals("mderived_sx + '.' + mderived_dx", schema.getExpression());
+        } finally {
+            // Set updated back to make test re-runnable
+            schema.setExpression("mderived_sx + '-' + mderived_dx");
+            schemaService.update(AttributableType.MEMBERSHIP, SchemaType.DERIVED,
+                    schema.getKey(), schema);
+        }
+    }
+
+    @Test
+    public void issueSYNCOPE323() {
+        DerSchemaTO actual = schemaService.read(AttributableType.ROLE, SchemaType.DERIVED, "rderiveddata");
+        assertNotNull(actual);
+
+        try {
+            createSchema(AttributableType.ROLE, SchemaType.DERIVED, actual);
+            fail();
+        } catch (SyncopeClientException e) {
+            assertEquals(Response.Status.CONFLICT, e.getType().getResponseStatus());
+            assertEquals(ClientExceptionType.EntityExists, e.getType());
+        }
+
+        actual.setKey(null);
+        try {
+            createSchema(AttributableType.ROLE, SchemaType.DERIVED, actual);
+            fail();
+        } catch (SyncopeClientException e) {
+            assertEquals(Response.Status.BAD_REQUEST, e.getType().getResponseStatus());
+            assertEquals(ClientExceptionType.RequiredValuesMissing, e.getType());
+        }
+    }
+
+    @Test
+    public void issueSYNCOPE418() {
+        DerSchemaTO schema = new DerSchemaTO();
+        schema.setKey("http://schemas.examples.org/security/authorization/organizationUnit");
+        schema.setExpression("derived_sx + '_' + derived_dx");
+
+        try {
+            createSchema(AttributableType.ROLE, SchemaType.DERIVED, schema);
+            fail();
+        } catch (SyncopeClientException e) {
+            assertEquals(ClientExceptionType.InvalidDerSchema, e.getType());
+            assertTrue(e.getElements().iterator().next().contains(EntityViolationType.InvalidName.name()));
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/32707b3b/syncope620/fit/server-reference/src/test/java/org/apache/syncope/fit/server/reference/LoggerITCase.java
----------------------------------------------------------------------
diff --git a/syncope620/fit/server-reference/src/test/java/org/apache/syncope/fit/server/reference/LoggerITCase.java b/syncope620/fit/server-reference/src/test/java/org/apache/syncope/fit/server/reference/LoggerITCase.java
new file mode 100644
index 0000000..68510bf
--- /dev/null
+++ b/syncope620/fit/server-reference/src/test/java/org/apache/syncope/fit/server/reference/LoggerITCase.java
@@ -0,0 +1,215 @@
+/*
+ * 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.assertTrue;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
+
+import java.text.ParseException;
+import java.util.List;
+import org.apache.syncope.common.lib.to.EventCategoryTO;
+import org.apache.syncope.common.lib.to.LoggerTO;
+import org.apache.syncope.common.lib.types.AttributableType;
+import org.apache.syncope.common.lib.types.AuditElements;
+import org.apache.syncope.common.lib.types.AuditElements.EventCategoryType;
+import org.apache.syncope.common.lib.types.AuditLoggerName;
+import org.apache.syncope.common.lib.types.LoggerLevel;
+import org.apache.syncope.common.lib.types.LoggerType;
+import org.apache.syncope.common.lib.types.ResourceOperation;
+import org.apache.syncope.common.rest.api.CollectionWrapper;
+import org.apache.syncope.server.logic.ReportLogic;
+import org.apache.syncope.server.logic.ResourceLogic;
+import org.apache.syncope.server.logic.RoleLogic;
+import org.apache.syncope.server.logic.UserLogic;
+import org.junit.FixMethodOrder;
+import org.junit.Test;
+import org.junit.runners.MethodSorters;
+
+@FixMethodOrder(MethodSorters.JVM)
+public class LoggerITCase extends AbstractITCase {
+
+    @Test
+    public void listLogs() {
+        List<LoggerTO> loggers = loggerService.list(LoggerType.LOG);
+        assertNotNull(loggers);
+        assertFalse(loggers.isEmpty());
+        for (LoggerTO logger : loggers) {
+            assertNotNull(logger);
+        }
+    }
+
+    @Test
+    public void listAudits() throws ParseException {
+        List<LoggerTO> audits = loggerService.list(LoggerType.AUDIT);
+
+        assertNotNull(audits);
+        assertFalse(audits.isEmpty());
+        for (LoggerTO audit : audits) {
+            assertNotNull(AuditLoggerName.fromLoggerName(audit.getKey()));
+        }
+    }
+
+    @Test
+    public void setLevel() {
+        List<LoggerTO> loggers = loggerService.list(LoggerType.LOG);
+        assertNotNull(loggers);
+        int startSize = loggers.size();
+
+        LoggerTO logger = new LoggerTO();
+        logger.setKey("TEST");
+        logger.setLevel(LoggerLevel.INFO);
+        loggerService.update(LoggerType.LOG, logger.getKey(), logger);
+        logger = loggerService.read(LoggerType.LOG, logger.getKey());
+        assertNotNull(logger);
+        assertEquals(LoggerLevel.INFO, logger.getLevel());
+
+        loggers = loggerService.list(LoggerType.LOG);
+        assertNotNull(loggers);
+        assertEquals(startSize + 1, loggers.size());
+
+        // TEST Delete
+        loggerService.delete(LoggerType.LOG, "TEST");
+        loggers = loggerService.list(LoggerType.LOG);
+        assertNotNull(loggers);
+        assertEquals(startSize, loggers.size());
+    }
+
+    @Test
+    public void enableDisableAudit() {
+        AuditLoggerName auditLoggerName = new AuditLoggerName(
+                EventCategoryType.REST,
+                ReportLogic.class.getSimpleName(),
+                null,
+                "deleteExecution",
+                AuditElements.Result.FAILURE);
+
+        List<AuditLoggerName> audits = CollectionWrapper.wrapLogger(loggerService.list(LoggerType.AUDIT));
+        assertNotNull(audits);
+        assertFalse(audits.contains(auditLoggerName));
+
+        LoggerTO loggerTO = new LoggerTO();
+        String name = auditLoggerName.toLoggerName();
+        loggerTO.setKey(name);
+        loggerTO.setLevel(LoggerLevel.DEBUG);
+        loggerService.update(LoggerType.AUDIT, name, loggerTO);
+
+        audits = CollectionWrapper.wrapLogger(loggerService.list(LoggerType.AUDIT));
+        assertNotNull(audits);
+        assertTrue(audits.contains(auditLoggerName));
+
+        loggerService.delete(LoggerType.AUDIT, auditLoggerName.toLoggerName());
+
+        audits = CollectionWrapper.wrapLogger(loggerService.list(LoggerType.AUDIT));
+        assertNotNull(audits);
+        assertFalse(audits.contains(auditLoggerName));
+    }
+
+    @Test
+    public void listAuditEvents() {
+        final List<EventCategoryTO> events = loggerService.events();
+
+        boolean found = false;
+
+        for (EventCategoryTO eventCategoryTO : events) {
+            if (UserLogic.class.getSimpleName().equals(eventCategoryTO.getCategory())) {
+                assertEquals(EventCategoryType.REST, eventCategoryTO.getType());
+                assertTrue(eventCategoryTO.getEvents().contains("create"));
+                assertTrue(eventCategoryTO.getEvents().contains("list"));
+                assertFalse(eventCategoryTO.getEvents().contains("doCreate"));
+                assertFalse(eventCategoryTO.getEvents().contains("setStatusOnWfAdapter"));
+                assertFalse(eventCategoryTO.getEvents().contains("resolveReference"));
+                found = true;
+            }
+        }
+        assertTrue(found);
+
+        found = false;
+        for (EventCategoryTO eventCategoryTO : events) {
+            if (RoleLogic.class.getSimpleName().equals(eventCategoryTO.getCategory())) {
+                assertEquals(EventCategoryType.REST, eventCategoryTO.getType());
+                assertTrue(eventCategoryTO.getEvents().contains("create"));
+                assertTrue(eventCategoryTO.getEvents().contains("list"));
+                assertFalse(eventCategoryTO.getEvents().contains("resolveReference"));
+                found = true;
+            }
+        }
+        assertTrue(found);
+
+        found = false;
+        for (EventCategoryTO eventCategoryTO : events) {
+            if (ResourceLogic.class.getSimpleName().equals(eventCategoryTO.getCategory())) {
+                assertEquals(EventCategoryType.REST, eventCategoryTO.getType());
+                assertTrue(eventCategoryTO.getEvents().contains("create"));
+                assertTrue(eventCategoryTO.getEvents().contains("read"));
+                assertTrue(eventCategoryTO.getEvents().contains("delete"));
+                assertFalse(eventCategoryTO.getEvents().contains("resolveReference"));
+                found = true;
+            }
+        }
+        assertTrue(found);
+
+        found = false;
+        for (EventCategoryTO eventCategoryTO : events) {
+            if (AttributableType.USER.name().toLowerCase().equals(eventCategoryTO.getCategory())) {
+                if (RESOURCE_NAME_LDAP.equals(eventCategoryTO.getSubcategory())
+                        && EventCategoryType.SYNCHRONIZATION == eventCategoryTO.getType()) {
+                    assertTrue(eventCategoryTO.getEvents().contains(ResourceOperation.CREATE.name().toLowerCase()));
+                    assertTrue(eventCategoryTO.getEvents().contains(ResourceOperation.UPDATE.name().toLowerCase()));
+                    assertTrue(eventCategoryTO.getEvents().contains(ResourceOperation.DELETE.name().toLowerCase()));
+                    found = true;
+                }
+            }
+        }
+        assertTrue(found);
+
+        found = false;
+        for (EventCategoryTO eventCategoryTO : events) {
+            if (AttributableType.USER.name().toLowerCase().equals(eventCategoryTO.getCategory())) {
+                if (RESOURCE_NAME_CSV.equals(eventCategoryTO.getSubcategory())
+                        && EventCategoryType.PROPAGATION == eventCategoryTO.getType()) {
+                    assertTrue(eventCategoryTO.getEvents().contains(ResourceOperation.CREATE.name().toLowerCase()));
+                    assertTrue(eventCategoryTO.getEvents().contains(ResourceOperation.UPDATE.name().toLowerCase()));
+                    assertTrue(eventCategoryTO.getEvents().contains(ResourceOperation.DELETE.name().toLowerCase()));
+                    found = true;
+                }
+            }
+        }
+        assertTrue(found);
+
+        found = false;
+        for (EventCategoryTO eventCategoryTO : events) {
+            if (EventCategoryType.TASK == eventCategoryTO.getType()
+                    && "SampleJob".equals(eventCategoryTO.getCategory())) {
+                found = true;
+            }
+        }
+        assertTrue(found);
+
+        found = false;
+        for (EventCategoryTO eventCategoryTO : events) {
+            if (EventCategoryType.TASK == eventCategoryTO.getType()
+                    && "SyncJob".equals(eventCategoryTO.getCategory())) {
+                found = true;
+            }
+        }
+        assertTrue(found);
+    }
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/32707b3b/syncope620/fit/server-reference/src/test/java/org/apache/syncope/fit/server/reference/NotificationITCase.java
----------------------------------------------------------------------
diff --git a/syncope620/fit/server-reference/src/test/java/org/apache/syncope/fit/server/reference/NotificationITCase.java b/syncope620/fit/server-reference/src/test/java/org/apache/syncope/fit/server/reference/NotificationITCase.java
new file mode 100644
index 0000000..cb09ea8
--- /dev/null
+++ b/syncope620/fit/server-reference/src/test/java/org/apache/syncope/fit/server/reference/NotificationITCase.java
@@ -0,0 +1,172 @@
+/*
+ * 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.fail;
+
+import java.util.List;
+import javax.ws.rs.core.Response;
+import org.apache.syncope.client.lib.SyncopeClient;
+import org.apache.syncope.common.lib.SyncopeClientException;
+import org.apache.syncope.common.lib.to.NotificationTO;
+import org.apache.syncope.common.lib.types.ClientExceptionType;
+import org.apache.syncope.common.lib.types.IntMappingType;
+import org.apache.syncope.common.lib.types.TraceLevel;
+import org.apache.syncope.common.rest.api.service.NotificationService;
+import org.junit.FixMethodOrder;
+import org.junit.Test;
+import org.junit.runners.MethodSorters;
+
+@FixMethodOrder(MethodSorters.JVM)
+public class NotificationITCase extends AbstractITCase {
+
+    private NotificationTO buildNotificationTO() {
+        NotificationTO notificationTO = new NotificationTO();
+        notificationTO.setTraceLevel(TraceLevel.SUMMARY);
+        notificationTO.getEvents().add("create");
+
+        notificationTO.setUserAbout(SyncopeClient.getUserSearchConditionBuilder().
+                is("fullname").equalTo("*o*").and("fullname").equalTo("*i*").query());
+
+        notificationTO.setRecipientAttrName("email");
+        notificationTO.setRecipientAttrType(IntMappingType.UserPlainSchema);
+
+        notificationTO.setSender("syncope@syncope.apache.org");
+        notificationTO.setSubject("Test notification");
+        notificationTO.setTemplate("test");
+        return notificationTO;
+    }
+
+    @Test
+    public void read() {
+        NotificationTO notificationTO = notificationService.read(10L);
+        assertNotNull(notificationTO);
+    }
+
+    @Test
+    public void list() {
+        List<NotificationTO> notificationTOs = notificationService.list();
+        assertNotNull(notificationTOs);
+        assertFalse(notificationTOs.isEmpty());
+        for (NotificationTO instance : notificationTOs) {
+            assertNotNull(instance);
+        }
+    }
+
+    @Test
+    public void create() {
+        NotificationTO notificationTO = buildNotificationTO();
+        notificationTO.setRecipients(SyncopeClient.getUserSearchConditionBuilder().hasRoles(7L).query());
+
+        Response response = notificationService.create(notificationTO);
+        NotificationTO actual = getObject(response.getLocation(), NotificationService.class,
+                NotificationTO.class);
+
+        assertNotNull(actual);
+        assertNotNull(actual.getKey());
+        notificationTO.setKey(actual.getKey());
+        assertEquals(actual, notificationTO);
+    }
+
+    @Test
+    public void update() {
+        NotificationTO notificationTO = notificationService.read(10L);
+        notificationTO.setRecipients(SyncopeClient.getUserSearchConditionBuilder().hasRoles(7L).query());
+
+        notificationService.update(notificationTO.getKey(), notificationTO);
+        NotificationTO actual = notificationService.read(notificationTO.getKey());
+        assertNotNull(actual);
+        assertEquals(actual, notificationTO);
+    }
+
+    @Test
+    public void delete() {
+        NotificationTO notification = buildNotificationTO();
+        notification.setSelfAsRecipient(true);
+        Response response = notificationService.create(notification);
+        notification = getObject(response.getLocation(), NotificationService.class, NotificationTO.class);
+
+        notificationService.delete(notification.getKey());
+
+        try {
+            notificationService.read(notification.getKey());
+            fail();
+        } catch (SyncopeClientException e) {
+            assertEquals(ClientExceptionType.NotFound, e.getType());
+        }
+    }
+
+    @Test
+    public void issueSYNCOPE83() {
+        NotificationTO notificationTO = buildNotificationTO();
+        notificationTO.setSelfAsRecipient(true);
+
+        NotificationTO actual = null;
+        try {
+            Response response = notificationService.create(notificationTO);
+            actual = getObject(response.getLocation(), NotificationService.class, NotificationTO.class);
+        } catch (SyncopeClientException e) {
+            assertNotNull(e);
+        }
+        assertNotNull(actual);
+        assertNotNull(actual.getKey());
+        notificationTO.setKey(actual.getKey());
+        assertEquals(actual, notificationTO);
+    }
+
+    @Test
+    public void issueSYNCOPE445() {
+        NotificationTO notificationTO = buildNotificationTO();
+        notificationTO.getStaticRecipients().add("syncope445@syncope.apache.org");
+
+        NotificationTO actual = null;
+        try {
+            Response response = notificationService.create(notificationTO);
+            actual = getObject(response.getLocation(), NotificationService.class, NotificationTO.class);
+        } catch (SyncopeClientException e) {
+            assertNotNull(e);
+        }
+        assertNotNull(actual);
+        assertNotNull(actual.getKey());
+        notificationTO.setKey(actual.getKey());
+        assertEquals(actual, notificationTO);
+    }
+
+    @Test
+    public void issueSYNCOPE446() {
+        NotificationTO notificationTO = buildNotificationTO();
+        notificationTO.getStaticRecipients().add("syncope446@syncope.apache.org");
+        notificationTO.setRoleAbout(SyncopeClient.getRoleSearchConditionBuilder().hasEntitlements("ROLE_READ").query());
+
+        NotificationTO actual = null;
+        try {
+            Response response = notificationService.create(notificationTO);
+            actual = getObject(response.getLocation(), NotificationService.class, NotificationTO.class);
+        } catch (SyncopeClientException e) {
+            assertNotNull(e);
+        }
+        assertNotNull(actual);
+        assertNotNull(actual.getKey());
+        notificationTO.setKey(actual.getKey());
+        assertEquals(actual, notificationTO);
+    }
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/32707b3b/syncope620/fit/server-reference/src/test/java/org/apache/syncope/fit/server/reference/NotificationTaskITCase.java
----------------------------------------------------------------------
diff --git a/syncope620/fit/server-reference/src/test/java/org/apache/syncope/fit/server/reference/NotificationTaskITCase.java b/syncope620/fit/server-reference/src/test/java/org/apache/syncope/fit/server/reference/NotificationTaskITCase.java
new file mode 100644
index 0000000..4cd302b
--- /dev/null
+++ b/syncope620/fit/server-reference/src/test/java/org/apache/syncope/fit/server/reference/NotificationTaskITCase.java
@@ -0,0 +1,156 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.syncope.fit.server.reference;
+
+import static org.apache.syncope.fit.server.reference.AbstractITCase.taskService;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+
+import javax.ws.rs.core.Response;
+import org.apache.syncope.client.lib.SyncopeClient;
+import org.apache.syncope.common.lib.to.MembershipTO;
+import org.apache.syncope.common.lib.to.NotificationTO;
+import org.apache.syncope.common.lib.to.NotificationTaskTO;
+import org.apache.syncope.common.lib.to.PagedResult;
+import org.apache.syncope.common.lib.to.TaskExecTO;
+import org.apache.syncope.common.lib.to.UserTO;
+import org.apache.syncope.common.lib.types.IntMappingType;
+import org.apache.syncope.common.lib.types.TaskType;
+import org.apache.syncope.common.lib.types.TraceLevel;
+import org.apache.syncope.common.rest.api.service.NotificationService;
+import org.junit.FixMethodOrder;
+import org.junit.Test;
+import org.junit.runners.MethodSorters;
+
+@FixMethodOrder(MethodSorters.JVM)
+public class NotificationTaskITCase extends AbstractTaskITCase {
+
+    @Test
+    public void issueSYNCOPE81() {
+        String sender = "syncope81@syncope.apache.org";
+        createNotificationTask(sender);
+        NotificationTaskTO taskTO = findNotificationTaskBySender(sender);
+        assertNotNull(taskTO);
+
+        assertTrue(taskTO.getExecutions().isEmpty());
+
+        // generate an execution in order to verify the deletion of a notification task with one or more executions
+        TaskExecTO execution = taskService.execute(taskTO.getKey(), false);
+        assertEquals("NOT_SENT", execution.getStatus());
+
+        int i = 0;
+        int maxit = 50;
+        int executions = 0;
+
+        // wait for task exec completion (executions incremented)
+        do {
+            try {
+                Thread.sleep(1000);
+            } catch (InterruptedException e) {
+            }
+
+            taskTO = taskService.read(taskTO.getKey());
+
+            assertNotNull(taskTO);
+            assertNotNull(taskTO.getExecutions());
+
+            i++;
+        } while (executions == taskTO.getExecutions().size() && i < maxit);
+
+        assertFalse(taskTO.getExecutions().isEmpty());
+
+        taskService.delete(taskTO.getKey());
+    }
+
+    @Test
+    public void issueSYNCOPE86() {
+        // 1. create notification task
+        String sender = "syncope86@syncope.apache.org";
+        createNotificationTask(sender);
+
+        // 2. get NotificationTaskTO for user just created
+        NotificationTaskTO taskTO = findNotificationTaskBySender(sender);
+        assertNotNull(taskTO);
+        assertTrue(taskTO.getExecutions().isEmpty());
+
+        try {
+            // 3. execute the generated NotificationTask
+            TaskExecTO execution = taskService.execute(taskTO.getKey(), false);
+            assertNotNull(execution);
+
+            // 4. verify
+            taskTO = taskService.read(taskTO.getKey());
+            assertNotNull(taskTO);
+            assertEquals(1, taskTO.getExecutions().size());
+        } finally {
+            // Remove execution to make test re-runnable
+            taskService.deleteExecution(taskTO.getExecutions().get(0).getKey());
+        }
+    }
+
+    private NotificationTaskTO findNotificationTaskBySender(final String sender) {
+        PagedResult<NotificationTaskTO> tasks = taskService.list(TaskType.NOTIFICATION);
+        assertNotNull(tasks);
+        assertFalse(tasks.getResult().isEmpty());
+        NotificationTaskTO taskTO = null;
+        for (NotificationTaskTO task : tasks.getResult()) {
+            if (sender.equals(task.getSender())) {
+                taskTO = task;
+            }
+        }
+        return taskTO;
+    }
+
+    private void createNotificationTask(final String sender) {
+        // 1. Create notification
+        NotificationTO notification = new NotificationTO();
+        notification.setTraceLevel(TraceLevel.FAILURES);
+        notification.getEvents().add("[REST]:[UserLogic]:[]:[create]:[SUCCESS]");
+
+        notification.setUserAbout(SyncopeClient.getUserSearchConditionBuilder().hasRoles(7L).query());
+
+        notification.setRecipients(SyncopeClient.getUserSearchConditionBuilder().hasRoles(8L).query());
+        notification.setSelfAsRecipient(true);
+
+        notification.setRecipientAttrName("email");
+        notification.setRecipientAttrType(IntMappingType.UserPlainSchema);
+
+        notification.setSender(sender);
+        String subject = "Test notification";
+        notification.setSubject(subject);
+        notification.setTemplate("optin");
+        notification.setActive(true);
+
+        Response response = notificationService.create(notification);
+        notification = getObject(response.getLocation(), NotificationService.class, NotificationTO.class);
+        assertNotNull(notification);
+
+        // 2. create user
+        UserTO userTO = UserITCase.getUniqueSampleTO("syncope@syncope.apache.org");
+        MembershipTO membershipTO = new MembershipTO();
+        membershipTO.setRoleId(7);
+        userTO.getMemberships().add(membershipTO);
+
+        userTO = createUser(userTO);
+        assertNotNull(userTO);
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/32707b3b/syncope620/fit/server-reference/src/test/java/org/apache/syncope/fit/server/reference/PlainSchemaITCase.java
----------------------------------------------------------------------
diff --git a/syncope620/fit/server-reference/src/test/java/org/apache/syncope/fit/server/reference/PlainSchemaITCase.java b/syncope620/fit/server-reference/src/test/java/org/apache/syncope/fit/server/reference/PlainSchemaITCase.java
new file mode 100644
index 0000000..448d1fa
--- /dev/null
+++ b/syncope620/fit/server-reference/src/test/java/org/apache/syncope/fit/server/reference/PlainSchemaITCase.java
@@ -0,0 +1,317 @@
+/*
+ * 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.List;
+import javax.ws.rs.core.Response;
+import org.apache.commons.lang3.SerializationUtils;
+import org.apache.syncope.common.lib.AttributableOperations;
+import org.apache.syncope.common.lib.SyncopeClientException;
+import org.apache.syncope.common.lib.mod.UserMod;
+import org.apache.syncope.common.lib.to.MembershipTO;
+import org.apache.syncope.common.lib.to.PlainSchemaTO;
+import org.apache.syncope.common.lib.to.UserTO;
+import org.apache.syncope.common.lib.types.AttrSchemaType;
+import org.apache.syncope.common.lib.types.AttributableType;
+import org.apache.syncope.common.lib.types.CipherAlgorithm;
+import org.apache.syncope.common.lib.types.ClientExceptionType;
+import org.apache.syncope.common.lib.types.EntityViolationType;
+import org.apache.syncope.common.lib.types.SchemaType;
+import org.apache.syncope.common.rest.api.service.SchemaService;
+import org.junit.FixMethodOrder;
+import org.junit.Test;
+import org.junit.runners.MethodSorters;
+
+@FixMethodOrder(MethodSorters.JVM)
+public class PlainSchemaITCase extends AbstractITCase {
+
+    private PlainSchemaTO buildPlainSchemaTO(final String name, final AttrSchemaType type) {
+        PlainSchemaTO schemaTO = new PlainSchemaTO();
+        schemaTO.setKey(name + getUUIDString());
+        schemaTO.setType(type);
+        return schemaTO;
+    }
+
+    @Test
+    public void create() {
+        PlainSchemaTO schemaTO = buildPlainSchemaTO("testAttribute", AttrSchemaType.String);
+        schemaTO.setMandatoryCondition("false");
+
+        PlainSchemaTO newPlainSchemaTO = createSchema(AttributableType.USER, SchemaType.PLAIN, schemaTO);
+        assertEquals(schemaTO, newPlainSchemaTO);
+
+        newPlainSchemaTO = createSchema(AttributableType.MEMBERSHIP, SchemaType.PLAIN, schemaTO);
+        assertEquals(schemaTO, newPlainSchemaTO);
+    }
+
+    @Test
+    public void createWithNotPermittedName() {
+        PlainSchemaTO schemaTO = new PlainSchemaTO();
+        schemaTO.setKey("failedLogins");
+        schemaTO.setType(AttrSchemaType.String);
+
+        try {
+            createSchema(AttributableType.USER, SchemaType.PLAIN, schemaTO);
+            fail("This should not be reacheable");
+        } catch (SyncopeClientException e) {
+            assertEquals(ClientExceptionType.InvalidPlainSchema, e.getType());
+
+            assertTrue(e.getElements().iterator().next().toString().
+                    contains(EntityViolationType.InvalidName.name()));
+        }
+    }
+
+    @Test
+    public void createREnumWithoutEnumeration() {
+        PlainSchemaTO schemaTO = new PlainSchemaTO();
+        schemaTO.setKey("enumcheck");
+        schemaTO.setType(AttrSchemaType.Enum);
+
+        try {
+            createSchema(AttributableType.ROLE, SchemaType.PLAIN, schemaTO);
+            fail("This should not be reacheable");
+        } catch (SyncopeClientException e) {
+            assertEquals(ClientExceptionType.InvalidPlainSchema, e.getType());
+
+            assertTrue(e.getElements().iterator().next().toString().
+                    contains(EntityViolationType.InvalidSchemaEnum.name()));
+        }
+    }
+
+    @Test
+    public void createUEnumWithoutEnumeration() {
+        PlainSchemaTO schemaTO = new PlainSchemaTO();
+        schemaTO.setKey("enumcheck");
+        schemaTO.setType(AttrSchemaType.Enum);
+
+        try {
+            createSchema(AttributableType.USER, SchemaType.PLAIN, schemaTO);
+            fail("This should not be reacheable");
+        } catch (SyncopeClientException e) {
+            assertEquals(ClientExceptionType.InvalidPlainSchema, e.getType());
+
+            assertTrue(e.getElements().iterator().next().contains(EntityViolationType.InvalidSchemaEnum.name()));
+        }
+    }
+
+    @Test
+    public void createEncrypted() {
+        PlainSchemaTO schemaTO = new PlainSchemaTO();
+        schemaTO.setKey("encrypted");
+        schemaTO.setType(AttrSchemaType.Encrypted);
+        schemaTO.setCipherAlgorithm(CipherAlgorithm.AES);
+        schemaTO.setSecretKey("huhadfhsjfsfsdkj!####");
+
+        createSchema(AttributableType.MEMBERSHIP, SchemaType.PLAIN, schemaTO);
+    }
+
+    @Test
+    public void createBinary() {
+        PlainSchemaTO schemaTO = new PlainSchemaTO();
+        schemaTO.setKey("x509certificate");
+        schemaTO.setType(AttrSchemaType.Binary);
+        schemaTO.setMimeType("application/x-x509-ca-cert");
+
+        createSchema(AttributableType.ROLE, SchemaType.PLAIN, schemaTO);
+    }
+
+    @Test
+    public void delete() {
+        PlainSchemaTO schemaTO = buildPlainSchemaTO("todelete", AttrSchemaType.String);
+        schemaTO.setMandatoryCondition("false");
+        createSchema(AttributableType.USER, SchemaType.PLAIN, schemaTO);
+
+        schemaService.delete(AttributableType.USER, SchemaType.PLAIN, schemaTO.getKey());
+        PlainSchemaTO firstname = null;
+        try {
+            firstname = schemaService.read(AttributableType.USER, SchemaType.PLAIN, schemaTO.getKey());
+        } catch (SyncopeClientException e) {
+            assertEquals(Response.Status.NOT_FOUND, e.getType().getResponseStatus());
+        }
+        assertNull(firstname);
+    }
+
+    @Test
+    public void list() {
+        List<PlainSchemaTO> userSchemas = schemaService.list(AttributableType.USER, SchemaType.PLAIN);
+        assertFalse(userSchemas.isEmpty());
+        for (PlainSchemaTO schemaTO : userSchemas) {
+            assertNotNull(schemaTO);
+        }
+
+        List<PlainSchemaTO> roleSchemas = schemaService.list(AttributableType.ROLE, SchemaType.PLAIN);
+        assertFalse(roleSchemas.isEmpty());
+        for (PlainSchemaTO schemaTO : roleSchemas) {
+            assertNotNull(schemaTO);
+        }
+
+        List<PlainSchemaTO> membershipSchemas = schemaService.list(AttributableType.MEMBERSHIP, SchemaType.PLAIN);
+        assertFalse(membershipSchemas.isEmpty());
+        for (PlainSchemaTO schemaTO : membershipSchemas) {
+            assertNotNull(schemaTO);
+        }
+    }
+
+    @Test
+    public void update() {
+        PlainSchemaTO schemaTO = schemaService.read(AttributableType.ROLE, SchemaType.PLAIN, "icon");
+        assertNotNull(schemaTO);
+
+        schemaService.update(AttributableType.ROLE, SchemaType.PLAIN, schemaTO.getKey(), schemaTO);
+        PlainSchemaTO updatedTO = schemaService.read(AttributableType.ROLE, SchemaType.PLAIN, "icon");
+        assertEquals(schemaTO, updatedTO);
+
+        updatedTO.setType(AttrSchemaType.Date);
+        try {
+            schemaService.update(AttributableType.ROLE, SchemaType.PLAIN, schemaTO.getKey(), updatedTO);
+            fail("This should not be reacheable");
+        } catch (SyncopeClientException e) {
+            assertEquals(ClientExceptionType.InvalidPlainSchema, e.getType());
+        }
+    }
+
+    @Test
+    public void issue258() {
+        PlainSchemaTO schemaTO = new PlainSchemaTO();
+        schemaTO.setKey("schema_issue258");
+        schemaTO.setType(AttrSchemaType.Double);
+
+        schemaTO = createSchema(AttributableType.USER, SchemaType.PLAIN, schemaTO);
+        assertNotNull(schemaTO);
+
+        UserTO userTO = UserITCase.getUniqueSampleTO("issue258@syncope.apache.org");
+        userTO.getPlainAttrs().add(attrTO(schemaTO.getKey(), "1.2"));
+
+        userTO = createUser(userTO);
+        assertNotNull(userTO);
+
+        schemaTO.setType(AttrSchemaType.Long);
+        try {
+            schemaService.update(AttributableType.USER, SchemaType.PLAIN, schemaTO.getKey(), schemaTO);
+            fail("This should not be reacheable");
+        } catch (SyncopeClientException e) {
+            assertEquals(ClientExceptionType.InvalidPlainSchema, e.getType());
+        }
+    }
+
+    @Test
+    public void issue259() {
+        PlainSchemaTO schemaTO = buildPlainSchemaTO("schema_issue259", AttrSchemaType.Double);
+        schemaTO.setUniqueConstraint(true);
+
+        schemaTO = createSchema(AttributableType.USER, SchemaType.PLAIN, schemaTO);
+        assertNotNull(schemaTO);
+
+        UserTO userTO = UserITCase.getUniqueSampleTO("issue259@syncope.apache.org");
+        userTO.getPlainAttrs().add(attrTO(schemaTO.getKey(), "1"));
+        userTO = createUser(userTO);
+        assertNotNull(userTO);
+
+        UserTO newUserTO = SerializationUtils.clone(userTO);
+        MembershipTO membership = new MembershipTO();
+        membership.setRoleId(2L);
+        newUserTO.getMemberships().add(membership);
+
+        UserMod userMod = AttributableOperations.diff(newUserTO, userTO);
+
+        userTO = userService.update(userMod.getKey(), userMod).readEntity(UserTO.class);
+        assertNotNull(userTO);
+    }
+
+    @Test
+    public void issue260() {
+        PlainSchemaTO schemaTO = buildPlainSchemaTO("schema_issue260", AttrSchemaType.Double);
+        schemaTO.setUniqueConstraint(true);
+
+        schemaTO = createSchema(AttributableType.USER, SchemaType.PLAIN, schemaTO);
+        assertNotNull(schemaTO);
+
+        UserTO userTO = UserITCase.getUniqueSampleTO("issue260@syncope.apache.org");
+        userTO.getPlainAttrs().add(attrTO(schemaTO.getKey(), "1.2"));
+        userTO = createUser(userTO);
+        assertNotNull(userTO);
+
+        schemaTO.setUniqueConstraint(false);
+        try {
+            schemaService.update(AttributableType.USER, SchemaType.PLAIN, schemaTO.getKey(), schemaTO);
+            fail("This should not be reacheable");
+        } catch (SyncopeClientException e) {
+            assertEquals(ClientExceptionType.InvalidPlainSchema, e.getType());
+        }
+    }
+
+    @Test
+    public void issueSYNCOPE323() {
+        PlainSchemaTO actual = schemaService.read(AttributableType.ROLE, SchemaType.PLAIN, "icon");
+        assertNotNull(actual);
+
+        try {
+            createSchema(AttributableType.ROLE, SchemaType.PLAIN, actual);
+            fail();
+        } catch (SyncopeClientException e) {
+            assertEquals(Response.Status.CONFLICT, e.getType().getResponseStatus());
+            assertEquals(ClientExceptionType.EntityExists, e.getType());
+        }
+
+        actual.setKey(null);
+        try {
+            createSchema(AttributableType.ROLE, SchemaType.PLAIN, actual);
+            fail();
+        } catch (SyncopeClientException e) {
+            assertEquals(Response.Status.BAD_REQUEST, e.getType().getResponseStatus());
+            assertEquals(ClientExceptionType.RequiredValuesMissing, e.getType());
+        }
+    }
+
+    @Test
+    public void issueSYNCOPE418() {
+        PlainSchemaTO schema = buildPlainSchemaTO("http://schemas.examples.org/security/authorization/organizationUnit",
+                AttrSchemaType.Double);
+
+        try {
+            createSchema(AttributableType.ROLE, SchemaType.PLAIN, schema);
+            fail();
+        } catch (SyncopeClientException e) {
+            assertEquals(ClientExceptionType.InvalidPlainSchema, e.getType());
+            assertTrue(e.getElements().iterator().next().contains(EntityViolationType.InvalidName.name()));
+        }
+    }
+
+    @Test
+    public void anonymous() {
+        SchemaService unauthenticated = clientFactory.createAnonymous().getService(SchemaService.class);
+        try {
+            unauthenticated.list(AttributableType.USER, SchemaType.VIRTUAL);
+            fail();
+        } catch (AccessControlException e) {
+            assertNotNull(e);
+        }
+
+        SchemaService anonymous = clientFactory.create(ANONYMOUS_UNAME, ANONYMOUS_KEY).getService(SchemaService.class);
+        assertFalse(anonymous.list(AttributableType.USER, SchemaType.VIRTUAL).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/PolicyITCase.java
----------------------------------------------------------------------
diff --git a/syncope620/fit/server-reference/src/test/java/org/apache/syncope/fit/server/reference/PolicyITCase.java b/syncope620/fit/server-reference/src/test/java/org/apache/syncope/fit/server/reference/PolicyITCase.java
new file mode 100644
index 0000000..c25dc7f
--- /dev/null
+++ b/syncope620/fit/server-reference/src/test/java/org/apache/syncope/fit/server/reference/PolicyITCase.java
@@ -0,0 +1,238 @@
+/*
+ * 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.util.Arrays;
+import java.util.List;
+import org.apache.syncope.common.lib.SyncopeClientException;
+import org.apache.syncope.common.lib.to.AccountPolicyTO;
+import org.apache.syncope.common.lib.to.PasswordPolicyTO;
+import org.apache.syncope.common.lib.to.SyncPolicyTO;
+import org.apache.syncope.common.lib.types.AccountPolicySpec;
+import org.apache.syncope.common.lib.types.ClientExceptionType;
+import org.apache.syncope.common.lib.types.PasswordPolicySpec;
+import org.apache.syncope.common.lib.types.PolicyType;
+import org.apache.syncope.common.lib.types.SyncPolicySpec;
+import org.junit.FixMethodOrder;
+import org.junit.Test;
+import org.junit.runners.MethodSorters;
+
+@FixMethodOrder(MethodSorters.JVM)
+public class PolicyITCase extends AbstractITCase {
+
+    private SyncPolicyTO buildSyncPolicyTO() {
+        SyncPolicyTO policy = new SyncPolicyTO();
+
+        SyncPolicySpec spec = new SyncPolicySpec();
+        spec.setUserJavaRule(TestSyncRule.class.getName());
+
+        policy.setSpecification(spec);
+        policy.setDescription("Sync policy");
+
+        return policy;
+    }
+
+    @Test
+    public void listByType() {
+        List<SyncPolicyTO> policyTOs = policyService.list(PolicyType.SYNC);
+
+        assertNotNull(policyTOs);
+        assertFalse(policyTOs.isEmpty());
+    }
+
+    @Test
+    public void getAccountPolicy() {
+        AccountPolicyTO policyTO = policyService.read(6L);
+
+        assertNotNull(policyTO);
+        assertTrue(policyTO.getUsedByResources().isEmpty());
+        assertEquals(Arrays.asList(6L, 7L, 10L, 14L), policyTO.getUsedByRoles());
+    }
+
+    @Test
+    public void getPasswordPolicy() {
+        PasswordPolicyTO policyTO = policyService.read(4L);
+
+        assertNotNull(policyTO);
+        assertTrue(policyTO.getUsedByResources().contains(RESOURCE_NAME_NOPROPAGATION));
+        assertEquals(Arrays.asList(6L, 7L, 10L, 8L), policyTO.getUsedByRoles());
+    }
+
+    @Test
+    public void getSyncPolicy() {
+        SyncPolicyTO policyTO = policyService.read(1L);
+
+        assertNotNull(policyTO);
+        assertTrue(policyTO.getUsedByRoles().isEmpty());
+    }
+
+    @Test
+    public void getGlobalAccountPolicy() {
+        AccountPolicyTO policyTO = policyService.readGlobal(PolicyType.ACCOUNT);
+
+        assertNotNull(policyTO);
+        assertEquals(PolicyType.GLOBAL_ACCOUNT, policyTO.getType());
+    }
+
+    @Test
+    public void getGlobalPasswordPolicy() {
+        PasswordPolicyTO policyTO = policyService.readGlobal(PolicyType.PASSWORD);
+
+        assertNotNull(policyTO);
+        assertEquals(PolicyType.GLOBAL_PASSWORD, policyTO.getType());
+        assertEquals(8, policyTO.getSpecification().getMinLength());
+        assertFalse(policyTO.getUsedByResources().contains(RESOURCE_NAME_NOPROPAGATION));
+    }
+
+    @Test
+    public void getGlobalSyncPolicy() {
+        SyncPolicyTO policyTO = policyService.readGlobal(PolicyType.SYNC);
+
+        assertNotNull(policyTO);
+        assertEquals(PolicyType.GLOBAL_SYNC, policyTO.getType());
+        assertFalse(policyTO.getUsedByResources().contains(RESOURCE_NAME_CSV));
+        assertFalse(policyTO.getUsedByResources().contains(RESOURCE_NAME_WS2));
+        assertTrue(policyTO.getUsedByRoles().isEmpty());
+    }
+
+    @Test
+    public void createWithException() {
+        PasswordPolicyTO policy = new PasswordPolicyTO(true);
+        policy.setSpecification(new PasswordPolicySpec());
+        policy.setDescription("global password policy");
+
+        try {
+            createPolicy(policy);
+            fail();
+        } catch (SyncopeClientException e) {
+            assertEquals(ClientExceptionType.InvalidPolicy, e.getType());
+        }
+    }
+
+    @Test
+    public void createMissingDescription() {
+        SyncPolicyTO policy = new SyncPolicyTO();
+        policy.setSpecification(new SyncPolicySpec());
+
+        try {
+            createPolicy(policy);
+            fail();
+        } catch (SyncopeClientException e) {
+            assertEquals(ClientExceptionType.InvalidPolicy, e.getType());
+        }
+    }
+
+    @Test
+    public void create() {
+        SyncPolicyTO policy = buildSyncPolicyTO();
+
+        SyncPolicyTO policyTO = createPolicy(policy);
+
+        assertNotNull(policyTO);
+        assertEquals(PolicyType.SYNC, policyTO.getType());
+        assertEquals(TestSyncRule.class.getName(), policyTO.getSpecification().getUserJavaRule());
+    }
+
+    @Test
+    public void update() {
+        // get global password
+        PasswordPolicyTO globalPolicy = policyService.read(2L);
+
+        PasswordPolicyTO policy = new PasswordPolicyTO();
+        policy.setDescription("A simple password policy");
+        policy.setSpecification(globalPolicy.getSpecification());
+
+        // create a new password policy using global password as a template
+        policy = createPolicy(policy);
+
+        // read new password policy
+        policy = policyService.read(policy.getKey());
+
+        assertNotNull("find to update did not work", policy);
+
+        PasswordPolicySpec policySpec = policy.getSpecification();
+        policySpec.setMaxLength(22);
+        policy.setSpecification(policySpec);
+
+        // update new password policy
+        policyService.update(policy.getKey(), policy);
+        policy = policyService.read(policy.getKey());
+
+        assertNotNull(policy);
+        assertEquals(PolicyType.PASSWORD, policy.getType());
+        assertEquals(22, policy.getSpecification().getMaxLength());
+        assertEquals(8, policy.getSpecification().getMinLength());
+    }
+
+    @Test
+    public void delete() {
+        SyncPolicyTO policy = buildSyncPolicyTO();
+
+        SyncPolicyTO policyTO = createPolicy(policy);
+        assertNotNull(policyTO);
+
+        policyService.delete(policyTO.getKey());
+
+        try {
+            policyService.read(policyTO.getKey());
+            fail();
+        } catch (SyncopeClientException e) {
+            assertNotNull(e);
+        }
+    }
+
+    @Test
+    public void getCorrelationRules() {
+        assertEquals(1, syncopeService.info().getSyncCorrelationRules().size());
+    }
+
+    @Test
+    public void issueSYNCOPE466() {
+        PasswordPolicyTO policy = policyService.read(4L);
+        assertEquals(PolicyType.PASSWORD, policy.getType());
+
+        policy.setType(PolicyType.GLOBAL_PASSWORD);
+        try {
+            policyService.update(policy.getKey(), policy);
+            fail();
+        } catch (SyncopeClientException e) {
+            assertEquals(ClientExceptionType.InvalidPolicy, e.getType());
+        }
+    }
+
+    @Test
+    public void issueSYNCOPE553() {
+        AccountPolicyTO policy = new AccountPolicyTO(false);
+        policy.setDescription("SYNCOPE553");
+
+        final AccountPolicySpec accountPolicySpec = new AccountPolicySpec();
+        accountPolicySpec.setMinLength(3);
+        accountPolicySpec.setMaxLength(8);
+        policy.setSpecification(accountPolicySpec);
+
+        policy = createPolicy(policy);
+        assertNotNull(policy);
+    }
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/32707b3b/syncope620/fit/server-reference/src/test/java/org/apache/syncope/fit/server/reference/PropagationTaskITCase.java
----------------------------------------------------------------------
diff --git a/syncope620/fit/server-reference/src/test/java/org/apache/syncope/fit/server/reference/PropagationTaskITCase.java b/syncope620/fit/server-reference/src/test/java/org/apache/syncope/fit/server/reference/PropagationTaskITCase.java
new file mode 100644
index 0000000..a79e1d8
--- /dev/null
+++ b/syncope620/fit/server-reference/src/test/java/org/apache/syncope/fit/server/reference/PropagationTaskITCase.java
@@ -0,0 +1,150 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.syncope.fit.server.reference;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+
+import java.util.ArrayList;
+import java.util.List;
+import javax.ws.rs.core.Response;
+import org.apache.syncope.common.lib.SyncopeClientException;
+import org.apache.syncope.common.lib.to.AbstractTaskTO;
+import org.apache.syncope.common.lib.to.BulkAction;
+import org.apache.syncope.common.lib.to.PagedResult;
+import org.apache.syncope.common.lib.to.PropagationTaskTO;
+import org.apache.syncope.common.lib.to.ReportExecTO;
+import org.apache.syncope.common.lib.to.TaskExecTO;
+import org.apache.syncope.common.lib.to.UserTO;
+import org.apache.syncope.common.lib.types.PropagationTaskExecStatus;
+import org.apache.syncope.common.lib.types.TaskType;
+import org.junit.FixMethodOrder;
+import org.junit.Test;
+import org.junit.runners.MethodSorters;
+
+@FixMethodOrder(MethodSorters.JVM)
+public class PropagationTaskITCase extends AbstractTaskITCase {
+
+    @Test
+    public void paginatedList() {
+        PagedResult<PropagationTaskTO> tasks = taskService.list(TaskType.PROPAGATION, 1, 2);
+
+        assertNotNull(tasks);
+        assertFalse(tasks.getResult().isEmpty());
+        assertEquals(2, tasks.getResult().size());
+
+        for (AbstractTaskTO task : tasks.getResult()) {
+            assertNotNull(task);
+        }
+
+        tasks = taskService.list(TaskType.PROPAGATION, 2, 2);
+
+        assertNotNull(tasks);
+        assertFalse(tasks.getResult().isEmpty());
+
+        for (AbstractTaskTO task : tasks.getResult()) {
+            assertNotNull(task);
+        }
+
+        tasks = taskService.list(TaskType.PROPAGATION, 1000, 2);
+
+        assertNotNull(tasks);
+        assertTrue(tasks.getResult().isEmpty());
+    }
+
+    @Test
+    public void read() {
+        final PropagationTaskTO taskTO = taskService.read(3L);
+        assertNotNull(taskTO);
+        assertNotNull(taskTO.getExecutions());
+        assertTrue(taskTO.getExecutions().isEmpty());
+    }
+
+    @Test
+    public void readExecution() {
+        TaskExecTO taskTO = taskService.readExecution(6L);
+        assertNotNull(taskTO);
+    }
+
+    @Test
+    public void deal() {
+        // Currently test is not re-runnable.
+        // To successfully run test second time it is necessary to restart cargo
+        try {
+            taskService.delete(0L);
+        } catch (SyncopeClientException e) {
+            assertEquals(Response.Status.NOT_FOUND, e.getType().getResponseStatus());
+        }
+        TaskExecTO exec = taskService.execute(1L, false);
+        assertEquals(PropagationTaskExecStatus.SUBMITTED.name(), exec.getStatus());
+
+        ReportExecTO report = new ReportExecTO();
+        report.setStatus(PropagationTaskExecStatus.SUCCESS.name());
+        report.setMessage("OK");
+        taskService.report(exec.getKey(), report);
+        exec = taskService.readExecution(exec.getKey());
+        assertEquals(PropagationTaskExecStatus.SUCCESS.name(), exec.getStatus());
+        assertEquals("OK", exec.getMessage());
+
+        taskService.delete(1L);
+        try {
+            taskService.readExecution(exec.getKey());
+        } catch (SyncopeClientException e) {
+            assertEquals(Response.Status.NOT_FOUND, e.getType().getResponseStatus());
+        }
+    }
+
+    @Test
+    public void issue196() {
+        TaskExecTO exec = taskService.execute(6L, false);
+        assertNotNull(exec);
+        assertEquals(0, exec.getKey());
+        assertNotNull(exec.getTask());
+    }
+
+    @Test
+    public void bulkAction() {
+        final PagedResult<PropagationTaskTO> before = taskService.list(TaskType.PROPAGATION);
+
+        // create user with testdb resource
+        final UserTO userTO = UserITCase.getUniqueSampleTO("taskBulk@apache.org");
+        userTO.getResources().add(RESOURCE_NAME_TESTDB);
+        createUser(userTO);
+
+        final List<PropagationTaskTO> after = new ArrayList<>(
+                taskService.<PropagationTaskTO>list(TaskType.PROPAGATION).getResult());
+
+        after.removeAll(before.getResult());
+
+        assertFalse(after.isEmpty());
+
+        final BulkAction bulkAction = new BulkAction();
+        bulkAction.setOperation(BulkAction.Type.DELETE);
+
+        for (AbstractTaskTO taskTO : after) {
+            bulkAction.getTargets().add(String.valueOf(taskTO.getKey()));
+        }
+
+        taskService.bulk(bulkAction);
+
+        assertFalse(taskService.list(TaskType.PROPAGATION).getResult().containsAll(after));
+    }
+}