You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@syncope.apache.org by md...@apache.org on 2015/08/14 10:30:30 UTC

[01/31] syncope git commit: [SYNCOPE-652] Cleaning up OpenJPA slices

Repository: syncope
Updated Branches:
  refs/heads/SYNCOPE-156 62f5e4ed6 -> f0883ca5f


[SYNCOPE-652] Cleaning up OpenJPA slices


Project: http://git-wip-us.apache.org/repos/asf/syncope/repo
Commit: http://git-wip-us.apache.org/repos/asf/syncope/commit/b2e84011
Tree: http://git-wip-us.apache.org/repos/asf/syncope/tree/b2e84011
Diff: http://git-wip-us.apache.org/repos/asf/syncope/diff/b2e84011

Branch: refs/heads/SYNCOPE-156
Commit: b2e84011274c072130fae8c8f082f7394c27c1e1
Parents: 0d6187d
Author: Francesco Chicchiriccò <il...@apache.org>
Authored: Tue Jul 21 11:35:52 2015 +0200
Committer: Francesco Chicchiriccò <il...@apache.org>
Committed: Thu Aug 13 17:16:50 2015 +0200

----------------------------------------------------------------------
 .../syncope/common/lib/to/AbstractSchemaTO.java |  11 ++
 .../rest/api/service/AnyTypeClassService.java   |   2 +-
 .../apache/syncope/core/logic/SchemaLogic.java  |  33 ++--
 core/persistence-jpa/pom.xml                    |   4 -
 .../core/persistence/jpa/dao/AbstractDAO.java   |  38 +----
 .../persistence/jpa/dao/JPAAnyTypeClassDAO.java |  14 +-
 .../jpa/dao/JPAExternalResourceDAO.java         |   4 -
 .../persistence/jpa/entity/JPADerSchema.java    |   3 +-
 .../persistence/jpa/entity/JPAPlainSchema.java  |   3 +-
 .../persistence/jpa/entity/JPAVirSchema.java    |   3 +-
 .../jpa/slice/DomainDistributionPolicy.java     |  36 -----
 .../jpa/slice/DomainFinderTargetPolicy.java     |  38 -----
 .../jpa/slice/DomainQueryTargetPolicy.java      |  41 -----
 .../src/main/resources/persistence.properties   |   3 +-
 .../resources/persistenceContextEMFactory.xml   |  31 +---
 .../core/persistence/jpa/inner/TaskTest.java    |  27 ++++
 .../persistence/jpa/outer/AnyTypeClassTest.java |  36 +++++
 .../src/test/resources/persistence.properties   |   3 +-
 .../provisioning/api/data/SchemaDataBinder.java |  18 +--
 .../java/data/AnyTypeClassDataBinderImpl.java   |  27 +++-
 .../java/data/SchemaDataBinderImpl.java         | 155 ++++++++++++++-----
 .../fit/core/reference/AnyTypeClassITCase.java  |  24 ++-
 pom.xml                                         |  13 +-
 23 files changed, 292 insertions(+), 275 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/syncope/blob/b2e84011/common/lib/src/main/java/org/apache/syncope/common/lib/to/AbstractSchemaTO.java
----------------------------------------------------------------------
diff --git a/common/lib/src/main/java/org/apache/syncope/common/lib/to/AbstractSchemaTO.java b/common/lib/src/main/java/org/apache/syncope/common/lib/to/AbstractSchemaTO.java
index afd6e6b..f426f8c 100644
--- a/common/lib/src/main/java/org/apache/syncope/common/lib/to/AbstractSchemaTO.java
+++ b/common/lib/src/main/java/org/apache/syncope/common/lib/to/AbstractSchemaTO.java
@@ -35,6 +35,8 @@ public abstract class AbstractSchemaTO extends AbstractBaseBean {
 
     private String key;
 
+    private String anyTypeClass;
+
     public String getKey() {
         return key;
     }
@@ -43,4 +45,13 @@ public abstract class AbstractSchemaTO extends AbstractBaseBean {
     public void setKey(final String key) {
         this.key = key;
     }
+
+    public String getAnyTypeClass() {
+        return anyTypeClass;
+    }
+
+    public void setAnyTypeClass(final String anyTypeClass) {
+        this.anyTypeClass = anyTypeClass;
+    }
+
 }

http://git-wip-us.apache.org/repos/asf/syncope/blob/b2e84011/common/rest-api/src/main/java/org/apache/syncope/common/rest/api/service/AnyTypeClassService.java
----------------------------------------------------------------------
diff --git a/common/rest-api/src/main/java/org/apache/syncope/common/rest/api/service/AnyTypeClassService.java b/common/rest-api/src/main/java/org/apache/syncope/common/rest/api/service/AnyTypeClassService.java
index 18bf1c4..43c3d23 100644
--- a/common/rest-api/src/main/java/org/apache/syncope/common/rest/api/service/AnyTypeClassService.java
+++ b/common/rest-api/src/main/java/org/apache/syncope/common/rest/api/service/AnyTypeClassService.java
@@ -38,7 +38,7 @@ import org.apache.syncope.common.lib.to.AnyTypeClassTO;
 /**
  * REST operations for any type classes.
  */
-@Path("anyTypeClassClasses")
+@Path("anyTypeClasses")
 public interface AnyTypeClassService extends JAXRSService {
 
     /**

http://git-wip-us.apache.org/repos/asf/syncope/blob/b2e84011/core/logic/src/main/java/org/apache/syncope/core/logic/SchemaLogic.java
----------------------------------------------------------------------
diff --git a/core/logic/src/main/java/org/apache/syncope/core/logic/SchemaLogic.java b/core/logic/src/main/java/org/apache/syncope/core/logic/SchemaLogic.java
index befa8bf..3da4a76 100644
--- a/core/logic/src/main/java/org/apache/syncope/core/logic/SchemaLogic.java
+++ b/core/logic/src/main/java/org/apache/syncope/core/logic/SchemaLogic.java
@@ -39,7 +39,6 @@ import org.apache.syncope.core.persistence.api.dao.NotFoundException;
 import org.apache.syncope.core.persistence.api.dao.PlainSchemaDAO;
 import org.apache.syncope.core.persistence.api.dao.VirSchemaDAO;
 import org.apache.syncope.core.persistence.api.entity.DerSchema;
-import org.apache.syncope.core.persistence.api.entity.EntityFactory;
 import org.apache.syncope.core.persistence.api.entity.PlainSchema;
 import org.apache.syncope.core.persistence.api.entity.VirSchema;
 import org.apache.syncope.core.provisioning.api.data.SchemaDataBinder;
@@ -62,9 +61,6 @@ public class SchemaLogic extends AbstractTransactionalLogic<AbstractSchemaTO> {
     @Autowired
     private SchemaDataBinder binder;
 
-    @Autowired
-    private EntityFactory entityFactory;
-
     private boolean doesSchemaExist(final SchemaType schemaType, final String name) {
         boolean found;
 
@@ -104,27 +100,19 @@ public class SchemaLogic extends AbstractTransactionalLogic<AbstractSchemaTO> {
         T created;
         switch (schemaType) {
             case VIRTUAL:
-                VirSchema virSchema = entityFactory.newEntity(VirSchema.class);
-                binder.create((VirSchemaTO) schemaTO, virSchema);
-                virSchema = virSchemaDAO.save(virSchema);
+                VirSchema virSchema = virSchemaDAO.save(binder.create((VirSchemaTO) schemaTO));
                 created = (T) binder.getVirSchemaTO(virSchema);
                 break;
 
             case DERIVED:
-                DerSchema derSchema = entityFactory.newEntity(DerSchema.class);
-                binder.create((DerSchemaTO) schemaTO, derSchema);
-                derSchema = derSchemaDAO.save(derSchema);
-
+                DerSchema derSchema = derSchemaDAO.save(binder.create((DerSchemaTO) schemaTO));
                 created = (T) binder.getDerSchemaTO(derSchema);
                 break;
 
             case PLAIN:
             default:
-                PlainSchema normalSchema = entityFactory.newEntity(PlainSchema.class);
-                binder.create((PlainSchemaTO) schemaTO, normalSchema);
-                normalSchema = plainSchemaDAO.save(normalSchema);
-
-                created = (T) binder.getPlainSchemaTO(normalSchema);
+                PlainSchema plainSchema = plainSchemaDAO.save(binder.create((PlainSchemaTO) schemaTO));
+                created = (T) binder.getPlainSchemaTO(plainSchema);
         }
         return created;
     }
@@ -241,8 +229,7 @@ public class SchemaLogic extends AbstractTransactionalLogic<AbstractSchemaTO> {
                     throw new NotFoundException("Virtual Schema '" + schemaTO.getKey() + "'");
                 }
 
-                binder.update((VirSchemaTO) schemaTO, virSchema);
-                virSchemaDAO.save(virSchema);
+                virSchemaDAO.save(binder.update((VirSchemaTO) schemaTO, virSchema));
                 break;
 
             case DERIVED:
@@ -251,19 +238,17 @@ public class SchemaLogic extends AbstractTransactionalLogic<AbstractSchemaTO> {
                     throw new NotFoundException("Derived schema '" + schemaTO.getKey() + "'");
                 }
 
-                binder.update((DerSchemaTO) schemaTO, derSchema);
-                derSchemaDAO.save(derSchema);
+                derSchemaDAO.save(binder.update((DerSchemaTO) schemaTO, derSchema));
                 break;
 
             case PLAIN:
             default:
-                PlainSchema schema = plainSchemaDAO.find(schemaTO.getKey());
-                if (schema == null) {
+                PlainSchema plainSchema = plainSchemaDAO.find(schemaTO.getKey());
+                if (plainSchema == null) {
                     throw new NotFoundException("Schema '" + schemaTO.getKey() + "'");
                 }
 
-                binder.update((PlainSchemaTO) schemaTO, schema);
-                plainSchemaDAO.save(schema);
+                plainSchemaDAO.save(binder.update((PlainSchemaTO) schemaTO, plainSchema));
         }
     }
 

http://git-wip-us.apache.org/repos/asf/syncope/blob/b2e84011/core/persistence-jpa/pom.xml
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/pom.xml b/core/persistence-jpa/pom.xml
index 0ab9e82..f60f3da 100644
--- a/core/persistence-jpa/pom.xml
+++ b/core/persistence-jpa/pom.xml
@@ -55,10 +55,6 @@ under the License.
       <groupId>org.apache.openjpa</groupId>
       <artifactId>openjpa-persistence-jdbc</artifactId>
     </dependency>
-    <dependency>
-      <groupId>org.apache.openjpa</groupId>
-      <artifactId>openjpa-slice</artifactId>
-    </dependency>
     
     <dependency>
       <groupId>org.apache.commons</groupId>

http://git-wip-us.apache.org/repos/asf/syncope/blob/b2e84011/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/AbstractDAO.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/AbstractDAO.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/AbstractDAO.java
index c2d5ae6..f4916c7 100644
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/AbstractDAO.java
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/AbstractDAO.java
@@ -19,13 +19,10 @@
 package org.apache.syncope.core.persistence.jpa.dao;
 
 import java.util.List;
-import javax.persistence.CacheRetrieveMode;
-import javax.persistence.CacheStoreMode;
 import javax.persistence.EntityManager;
 import javax.persistence.PersistenceContext;
 import javax.persistence.PersistenceContextType;
 import org.apache.commons.lang3.StringUtils;
-import org.apache.openjpa.slice.SlicePersistence;
 import org.apache.syncope.common.lib.SyncopeConstants;
 import org.apache.syncope.core.persistence.api.dao.DAO;
 import org.apache.syncope.core.persistence.api.dao.search.OrderByClause;
@@ -41,38 +38,10 @@ public abstract class AbstractDAO<E extends Entity<KEY>, KEY> implements DAO<E,
 
     protected static final Logger LOG = LoggerFactory.getLogger(DAO.class);
 
-    private static final String CACHE_STORE_MODE = "javax.persistence.cache.storeMode";
-
-    private static final String CACHE_RETRIEVE_MODE = "javax.persistence.cache.retrieveMode";
-
     @Value("#{entityManager}")
     @PersistenceContext(type = PersistenceContextType.TRANSACTION)
     protected EntityManager entityManager;
 
-    protected CacheRetrieveMode getCacheRetrieveMode() {
-        return entityManager.getProperties().containsKey(CACHE_RETRIEVE_MODE)
-                ? (CacheRetrieveMode) entityManager.getProperties().get(CACHE_RETRIEVE_MODE)
-                : CacheRetrieveMode.BYPASS;
-    }
-
-    protected void setCacheRetrieveMode(final CacheRetrieveMode retrieveMode) {
-        if (retrieveMode != null) {
-            entityManager.getProperties().put(CACHE_RETRIEVE_MODE, retrieveMode);
-        }
-    }
-
-    protected CacheStoreMode getCacheStoreMode() {
-        return entityManager.getProperties().containsKey(CACHE_STORE_MODE)
-                ? (CacheStoreMode) entityManager.getProperties().get(CACHE_STORE_MODE)
-                : CacheStoreMode.BYPASS;
-    }
-
-    protected void setCacheStoreMode(final CacheStoreMode storeMode) {
-        if (storeMode != null) {
-            entityManager.getProperties().put(CACHE_STORE_MODE, storeMode);
-        }
-    }
-
     protected String toOrderByStatement(final Class<? extends Entity<KEY>> beanClass, final String prefix,
             final List<OrderByClause> orderByClauses) {
 
@@ -96,12 +65,7 @@ public abstract class AbstractDAO<E extends Entity<KEY>, KEY> implements DAO<E,
 
     @Override
     public String getDomain(final E entity) {
-        try {
-            return SlicePersistence.getSlice(entity);
-        } catch (Exception e) {
-            LOG.debug("While fetching slice for {}", entity, e);
-            return SyncopeConstants.MASTER_DOMAIN;
-        }
+        return SyncopeConstants.MASTER_DOMAIN;
     }
 
     @Override

http://git-wip-us.apache.org/repos/asf/syncope/blob/b2e84011/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAAnyTypeClassDAO.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAAnyTypeClassDAO.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAAnyTypeClassDAO.java
index 3339c9a..58b547d 100644
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAAnyTypeClassDAO.java
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAAnyTypeClassDAO.java
@@ -63,7 +63,19 @@ public class JPAAnyTypeClassDAO extends AbstractDAO<AnyTypeClass, String> implem
 
     @Override
     public AnyTypeClass save(final AnyTypeClass anyTypeClass) {
-        return entityManager.merge(anyTypeClass);
+        AnyTypeClass merge = entityManager.merge(anyTypeClass);
+
+        for (PlainSchema schema : merge.getPlainSchemas()) {
+            schema.setAnyTypeClass(merge);
+        }
+        for (DerSchema schema : merge.getDerSchemas()) {
+            schema.setAnyTypeClass(merge);
+        }
+        for (VirSchema schema : merge.getVirSchemas()) {
+            schema.setAnyTypeClass(merge);
+        }
+
+        return merge;
     }
 
     @Override

http://git-wip-us.apache.org/repos/asf/syncope/blob/b2e84011/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAExternalResourceDAO.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAExternalResourceDAO.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAExternalResourceDAO.java
index 35a5b00..17553a2 100644
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAExternalResourceDAO.java
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAExternalResourceDAO.java
@@ -33,7 +33,6 @@ import org.apache.syncope.core.persistence.api.dao.GroupDAO;
 import org.apache.syncope.core.persistence.api.dao.TaskDAO;
 import org.apache.syncope.core.persistence.api.dao.UserDAO;
 import org.apache.syncope.core.persistence.api.entity.AccountPolicy;
-import org.apache.syncope.core.persistence.api.entity.AnyUtilsFactory;
 import org.apache.syncope.core.persistence.api.entity.resource.ExternalResource;
 import org.apache.syncope.core.persistence.api.entity.resource.MappingItem;
 import org.apache.syncope.core.persistence.api.entity.Policy;
@@ -70,9 +69,6 @@ public class JPAExternalResourceDAO extends AbstractDAO<ExternalResource, String
     @Autowired
     private ConnectorRegistry connRegistry;
 
-    @Autowired
-    private AnyUtilsFactory anyUtilsFactory;
-
     @Override
     public ExternalResource find(final String name) {
         return entityManager.find(JPAExternalResource.class, name);

http://git-wip-us.apache.org/repos/asf/syncope/blob/b2e84011/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/JPADerSchema.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/JPADerSchema.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/JPADerSchema.java
index 62fc5d6..944afc4 100644
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/JPADerSchema.java
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/JPADerSchema.java
@@ -21,6 +21,7 @@ package org.apache.syncope.core.persistence.jpa.entity;
 import javax.persistence.Cacheable;
 import javax.persistence.Column;
 import javax.persistence.Entity;
+import javax.persistence.FetchType;
 import javax.persistence.Id;
 import javax.persistence.OneToOne;
 import javax.persistence.Table;
@@ -42,7 +43,7 @@ public class JPADerSchema extends AbstractEntity<String> implements DerSchema {
     @Id
     private String name;
 
-    @OneToOne
+    @OneToOne(fetch = FetchType.EAGER)
     private JPAAnyTypeClass anyTypeClass;
 
     @Column(nullable = false)

http://git-wip-us.apache.org/repos/asf/syncope/blob/b2e84011/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/JPAPlainSchema.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/JPAPlainSchema.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/JPAPlainSchema.java
index d4935e9..68eeacf 100644
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/JPAPlainSchema.java
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/JPAPlainSchema.java
@@ -24,6 +24,7 @@ import javax.persistence.Column;
 import javax.persistence.Entity;
 import javax.persistence.EnumType;
 import javax.persistence.Enumerated;
+import javax.persistence.FetchType;
 import javax.persistence.Id;
 import javax.persistence.Lob;
 import javax.persistence.OneToOne;
@@ -54,7 +55,7 @@ public class JPAPlainSchema extends AbstractEntity<String> implements PlainSchem
     @Id
     private String name;
 
-    @OneToOne
+    @OneToOne(fetch = FetchType.EAGER)
     private JPAAnyTypeClass anyTypeClass;
 
     @Column(nullable = false)

http://git-wip-us.apache.org/repos/asf/syncope/blob/b2e84011/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/JPAVirSchema.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/JPAVirSchema.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/JPAVirSchema.java
index d268aff..6c1dd73 100644
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/JPAVirSchema.java
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/JPAVirSchema.java
@@ -21,6 +21,7 @@ package org.apache.syncope.core.persistence.jpa.entity;
 import javax.persistence.Basic;
 import javax.persistence.Cacheable;
 import javax.persistence.Entity;
+import javax.persistence.FetchType;
 import javax.persistence.Id;
 import javax.persistence.OneToOne;
 import javax.persistence.Table;
@@ -44,7 +45,7 @@ public class JPAVirSchema extends AbstractEntity<String> implements VirSchema {
     @Id
     private String name;
 
-    @OneToOne
+    @OneToOne(fetch = FetchType.EAGER)
     private JPAAnyTypeClass anyTypeClass;
 
     @Basic

http://git-wip-us.apache.org/repos/asf/syncope/blob/b2e84011/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/slice/DomainDistributionPolicy.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/slice/DomainDistributionPolicy.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/slice/DomainDistributionPolicy.java
deleted file mode 100644
index 2e61b06..0000000
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/slice/DomainDistributionPolicy.java
+++ /dev/null
@@ -1,36 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.syncope.core.persistence.jpa.slice;
-
-import java.util.List;
-import org.apache.openjpa.slice.DistributionPolicy;
-import org.apache.syncope.common.lib.SyncopeConstants;
-import org.apache.syncope.core.misc.security.AuthContextUtils;
-import org.apache.syncope.core.persistence.api.entity.Domain;
-
-public class DomainDistributionPolicy implements DistributionPolicy {
-
-    @Override
-    public String distribute(final Object pc, final List<String> slices, final Object context) {
-        return (pc instanceof Domain)
-                ? SyncopeConstants.MASTER_DOMAIN
-                : AuthContextUtils.getDomain();
-    }
-
-}

http://git-wip-us.apache.org/repos/asf/syncope/blob/b2e84011/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/slice/DomainFinderTargetPolicy.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/slice/DomainFinderTargetPolicy.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/slice/DomainFinderTargetPolicy.java
deleted file mode 100644
index c6cad6e..0000000
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/slice/DomainFinderTargetPolicy.java
+++ /dev/null
@@ -1,38 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.syncope.core.persistence.jpa.slice;
-
-import java.util.List;
-import org.apache.openjpa.slice.FinderTargetPolicy;
-import org.apache.syncope.common.lib.SyncopeConstants;
-import org.apache.syncope.core.misc.security.AuthContextUtils;
-import org.apache.syncope.core.persistence.jpa.entity.JPADomain;
-
-public class DomainFinderTargetPolicy implements FinderTargetPolicy {
-
-    @Override
-    public String[] getTargets(final Class<?> cls, final Object oid, final List<String> slices, final Object context) {
-        return new String[] {
-            JPADomain.class.equals(cls)
-            ? SyncopeConstants.MASTER_DOMAIN
-            : AuthContextUtils.getDomain()
-        };
-    }
-
-}

http://git-wip-us.apache.org/repos/asf/syncope/blob/b2e84011/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/slice/DomainQueryTargetPolicy.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/slice/DomainQueryTargetPolicy.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/slice/DomainQueryTargetPolicy.java
deleted file mode 100644
index 193ef2b..0000000
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/slice/DomainQueryTargetPolicy.java
+++ /dev/null
@@ -1,41 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.syncope.core.persistence.jpa.slice;
-
-import java.util.List;
-import java.util.Map;
-import org.apache.openjpa.slice.QueryTargetPolicy;
-import org.apache.syncope.common.lib.SyncopeConstants;
-import org.apache.syncope.core.misc.security.AuthContextUtils;
-import org.apache.syncope.core.persistence.jpa.entity.JPADomain;
-
-public class DomainQueryTargetPolicy implements QueryTargetPolicy {
-
-    @Override
-    public String[] getTargets(final String query, final Map<Object, Object> params, final String language,
-            final List<String> slices, final Object context) {
-
-        return new String[] {
-            query.contains(JPADomain.class.getSimpleName())
-            ? SyncopeConstants.MASTER_DOMAIN
-            : AuthContextUtils.getDomain()
-        };
-    }
-
-}

http://git-wip-us.apache.org/repos/asf/syncope/blob/b2e84011/core/persistence-jpa/src/main/resources/persistence.properties
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/resources/persistence.properties b/core/persistence-jpa/src/main/resources/persistence.properties
index 054808d..57f1af0 100644
--- a/core/persistence-jpa/src/main/resources/persistence.properties
+++ b/core/persistence-jpa/src/main/resources/persistence.properties
@@ -26,4 +26,5 @@ jpa.orm=META-INF/spring-orm.xml
 quartz.jobstore=org.quartz.impl.jdbcjobstore.PostgreSQLDelegate
 quartz.sql=tables_postgres.sql
 audit.sql=audit.sql
-database.schema=
\ No newline at end of file
+database.schema=
+

http://git-wip-us.apache.org/repos/asf/syncope/blob/b2e84011/core/persistence-jpa/src/main/resources/persistenceContextEMFactory.xml
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/resources/persistenceContextEMFactory.xml b/core/persistence-jpa/src/main/resources/persistenceContextEMFactory.xml
index d3a7e45..5983ca6 100644
--- a/core/persistence-jpa/src/main/resources/persistenceContextEMFactory.xml
+++ b/core/persistence-jpa/src/main/resources/persistenceContextEMFactory.xml
@@ -21,7 +21,7 @@ under the License.
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:schemaLocation="http://www.springframework.org/schema/beans
                            http://www.springframework.org/schema/beans/spring-beans.xsd">
-  
+
   <bean id="entityManagerFactory"
         class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
     <property name="packagesToScan" value="org.apache.syncope.core.persistence.jpa.entity"/>
@@ -47,43 +47,22 @@ under the License.
     </property>
     <property name="jpaPropertyMap">
       <map>
-        <entry key="openjpa.Log" value="DefaultLevel=INFO, Runtime=TRACE, Tool=TRACE, SQL=TRACE"/>
-        
         <!--<entry key="openjpa.Log" value="SQL=TRACE"/>
         <entry key="openjpa.ConnectionFactoryProperties" 
         value="PrintParameters=true, PrettyPrint=true, PrettyPrintLineLength=80"/>-->
-        
+                                
         <entry key="openjpa.NontransactionalWrite" value="false"/>
         <entry key="openjpa.AutoDetach" value="close, commit, nontx-read, rollback"/>
 
         <entry key="openjpa.jdbc.SchemaFactory" value="native(ForeignKeys=true)"/>
         <entry key="openjpa.jdbc.MappingDefaults" 
                value="ForeignKeyDeleteAction=restrict, JoinForeignKeyDeleteAction=restrict"/>
-                        
+                
         <entry key="openjpa.DataCache" value="true"/>
-        <entry key="openjpa.QueryCache" value="false"/>
-        <entry key="openjpa.QueryCompilationCache" value="false"/>
+        <entry key="openjpa.QueryCache" value="true"/>
         <entry key="openjpa.RemoteCommitProvider" value="sjvm"/>
-        
-        <entry key="openjpa.BrokerFactory" value="slice"/>       
-        <entry key="openjpa.BrokerImpl" value="org.apache.openjpa.slice.DistributedBrokerImpl"/> 
-        <entry key="openjpa.slice.Lenient" value="false"/>
-        
-        <entry key="openjpa.slice.DistributionPolicy" 
-               value="org.apache.syncope.core.persistence.jpa.slice.DomainDistributionPolicy"/>
-        <entry key="openjpa.slice.QueryTargetPolicy" 
-               value="org.apache.syncope.core.persistence.jpa.slice.DomainQueryTargetPolicy"/>
-        <entry key="openjpa.slice.FinderTargetPolicy" 
-               value="org.apache.syncope.core.persistence.jpa.slice.DomainFinderTargetPolicy"/>
-
-        <entry key="openjpa.slice.Names" value="Master"/>        
-        <entry key="openjpa.slice.Master"  value="Master"/>
-        <entry key="openjpa.slice.Lenient" value="false"/>
-        
-        <entry key="openjpa.slice.Master.ConnectionFactory" value-ref="dataSource"/>
-        <entry key="openjpa.slice.Master.jdbc.DBDictionary" value="${jpa.dialect}"/>
       </map>
     </property>
   </bean>
 
-</beans>
+</beans>
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/syncope/blob/b2e84011/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/inner/TaskTest.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/inner/TaskTest.java b/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/inner/TaskTest.java
index 4f4b02c..a3bfedd 100644
--- a/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/inner/TaskTest.java
+++ b/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/inner/TaskTest.java
@@ -22,7 +22,9 @@ 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 java.util.Collections;
 import java.util.HashSet;
 import java.util.List;
 import java.util.Set;
@@ -33,8 +35,10 @@ import org.apache.syncope.common.lib.types.TaskType;
 import org.apache.syncope.core.persistence.api.dao.ExternalResourceDAO;
 import org.apache.syncope.core.persistence.api.dao.TaskDAO;
 import org.apache.syncope.core.persistence.api.dao.UserDAO;
+import org.apache.syncope.core.persistence.api.dao.search.OrderByClause;
 import org.apache.syncope.core.persistence.api.entity.resource.ExternalResource;
 import org.apache.syncope.core.persistence.api.entity.task.PropagationTask;
+import org.apache.syncope.core.persistence.api.entity.task.Task;
 import org.apache.syncope.core.persistence.api.entity.user.User;
 import org.apache.syncope.core.persistence.jpa.AbstractTest;
 import org.identityconnectors.framework.common.objects.Attribute;
@@ -63,6 +67,29 @@ public class TaskTest extends AbstractTest {
     }
 
     @Test
+    public void findPaginated() {
+        List<Task> tasks = taskDAO.findAll(1, 2, Collections.<OrderByClause>emptyList(), TaskType.PROPAGATION);
+        assertNotNull(tasks);
+        assertEquals(2, tasks.size());
+
+        for (Task task : tasks) {
+            assertNotNull(task);
+        }
+
+        tasks = taskDAO.findAll(2, 2, Collections.<OrderByClause>emptyList(), TaskType.PROPAGATION);
+        assertNotNull(tasks);
+        assertEquals(2, tasks.size());
+
+        for (Task task : tasks) {
+            assertNotNull(task);
+        }
+
+        tasks = taskDAO.findAll(1000, 2, Collections.<OrderByClause>emptyList(), TaskType.PROPAGATION);
+        assertNotNull(tasks);
+        assertTrue(tasks.isEmpty());
+    }
+
+    @Test
     public void findAll() {
         assertEquals(5, taskDAO.findAll(TaskType.PROPAGATION).size());
         assertEquals(1, taskDAO.findAll(TaskType.NOTIFICATION).size());

http://git-wip-us.apache.org/repos/asf/syncope/blob/b2e84011/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/outer/AnyTypeClassTest.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/outer/AnyTypeClassTest.java b/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/outer/AnyTypeClassTest.java
index 29b97a3..d0f0213 100644
--- a/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/outer/AnyTypeClassTest.java
+++ b/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/outer/AnyTypeClassTest.java
@@ -23,6 +23,8 @@ import static org.junit.Assert.assertNotNull;
 
 import static org.junit.Assert.assertTrue;
 
+import javax.persistence.EntityManager;
+import org.apache.syncope.common.lib.types.AttrSchemaType;
 import org.apache.syncope.core.persistence.api.dao.AnyTypeClassDAO;
 import org.apache.syncope.core.persistence.api.dao.PlainSchemaDAO;
 import org.apache.syncope.core.persistence.api.entity.AnyTypeClass;
@@ -41,6 +43,40 @@ public class AnyTypeClassTest extends AbstractTest {
     @Autowired
     private AnyTypeClassDAO anyTypeClassDAO;
 
+    @Autowired
+    private EntityManager entityManager;
+
+    @Test
+    public void create() {
+        PlainSchema newSchema = entityFactory.newEntity(PlainSchema.class);
+        newSchema.setKey("new_plain_schema");
+        newSchema.setType(AttrSchemaType.String);
+
+        plainSchemaDAO.save(newSchema);
+
+        plainSchemaDAO.flush();
+
+        newSchema = plainSchemaDAO.find(newSchema.getKey());
+        assertNotNull(newSchema);
+
+        AnyTypeClass newClass = entityFactory.newEntity(AnyTypeClass.class);
+        newClass.setKey("new class");
+        newClass.add(newSchema);
+
+        anyTypeClassDAO.save(newClass);
+
+        anyTypeClassDAO.flush();
+
+        newClass = anyTypeClassDAO.find(newClass.getKey());
+        assertNotNull(newClass);
+        assertEquals(1, newClass.getPlainSchemas().size());
+        assertEquals(newSchema, newClass.getPlainSchemas().get(0));
+        assertEquals(newClass, newClass.getPlainSchemas().get(0).getAnyTypeClass());
+
+        newSchema = plainSchemaDAO.find(newSchema.getKey());
+        assertNotNull(newSchema.getAnyTypeClass());
+    }
+
     @Test
     public void delete() {
         AnyTypeClass minimalUser = anyTypeClassDAO.find("minimal user");

http://git-wip-us.apache.org/repos/asf/syncope/blob/b2e84011/core/persistence-jpa/src/test/resources/persistence.properties
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/test/resources/persistence.properties b/core/persistence-jpa/src/test/resources/persistence.properties
index 6993a0b..31ea1b0 100644
--- a/core/persistence-jpa/src/test/resources/persistence.properties
+++ b/core/persistence-jpa/src/test/resources/persistence.properties
@@ -27,4 +27,5 @@ quartz.jobstore=org.quartz.impl.jdbcjobstore.StdJDBCDelegate
 quartz.scheduler.idleWaitTime=5000
 quartz.sql=tables_h2.sql
 audit.sql=audit.sql
-database.schema=
\ No newline at end of file
+database.schema=
+

http://git-wip-us.apache.org/repos/asf/syncope/blob/b2e84011/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/data/SchemaDataBinder.java
----------------------------------------------------------------------
diff --git a/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/data/SchemaDataBinder.java b/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/data/SchemaDataBinder.java
index dcb8f9f..b185ca8 100644
--- a/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/data/SchemaDataBinder.java
+++ b/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/data/SchemaDataBinder.java
@@ -27,22 +27,22 @@ import org.apache.syncope.core.persistence.api.entity.VirSchema;
 
 public interface SchemaDataBinder {
 
-    <T extends PlainSchema> void create(PlainSchemaTO schemaTO, T schema);
+    PlainSchema create(PlainSchemaTO schemaTO);
 
-    <T extends DerSchema> T create(DerSchemaTO derSchemaTO, T derSchema);
+    DerSchema create(DerSchemaTO schemaTO);
 
-    <T extends VirSchema> T create(VirSchemaTO virSchemaTO, T virSchema);
+    VirSchema create(VirSchemaTO schemaTO);
 
-    <T extends DerSchema> DerSchemaTO getDerSchemaTO(T derSchema);
+    DerSchemaTO getDerSchemaTO(DerSchema schema);
 
-    <T extends PlainSchema> PlainSchemaTO getPlainSchemaTO(T schema);
+    PlainSchemaTO getPlainSchemaTO(PlainSchema schema);
 
-    <T extends VirSchema> VirSchemaTO getVirSchemaTO(T virSchema);
+    VirSchemaTO getVirSchemaTO(VirSchema schema);
 
-    <T extends PlainSchema> void update(PlainSchemaTO schemaTO, T schema);
+    PlainSchema update(PlainSchemaTO schemaTO, PlainSchema schema);
 
-    <T extends DerSchema> T update(DerSchemaTO derSchemaTO, T derSchema);
+    DerSchema update(DerSchemaTO schemaTO, DerSchema derSchema);
 
-    <T extends VirSchema> T update(VirSchemaTO virSchemaTO, T virSchema);
+    VirSchema update(VirSchemaTO schemaTO, VirSchema virSchema);
 
 }

http://git-wip-us.apache.org/repos/asf/syncope/blob/b2e84011/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/AnyTypeClassDataBinderImpl.java
----------------------------------------------------------------------
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/AnyTypeClassDataBinderImpl.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/AnyTypeClassDataBinderImpl.java
index 5917190..8a33e12 100644
--- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/AnyTypeClassDataBinderImpl.java
+++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/AnyTypeClassDataBinderImpl.java
@@ -63,31 +63,46 @@ public class AnyTypeClassDataBinderImpl implements AnyTypeClassDataBinder {
             anyTypeClass.setKey(anyTypeClassTO.getKey());
         }
 
+        for (PlainSchema schema : plainSchemaDAO.findByAnyTypeClass(anyTypeClass)) {
+            schema.setAnyTypeClass(null);
+        }
+
         anyTypeClass.getPlainSchemas().clear();
         for (String schemaName : anyTypeClassTO.getPlainSchemas()) {
             PlainSchema schema = plainSchemaDAO.find(schemaName);
-            if (schema == null) {
-                LOG.debug("Invalid " + PlainSchema.class.getSimpleName() + "{}, ignoring...", schemaName);
+            if (schema == null || schema.getAnyTypeClass() != null) {
+                LOG.debug("Invalid or already in use" + PlainSchema.class.getSimpleName()
+                        + "{}, ignoring...", schemaName);
             } else {
                 anyTypeClass.add(schema);
             }
         }
 
+        for (DerSchema schema : derSchemaDAO.findByAnyTypeClass(anyTypeClass)) {
+            schema.setAnyTypeClass(null);
+        }
+
         anyTypeClass.getDerSchemas().clear();
         for (String schemaName : anyTypeClassTO.getDerSchemas()) {
             DerSchema schema = derSchemaDAO.find(schemaName);
-            if (schema == null) {
-                LOG.debug("Invalid " + DerSchema.class.getSimpleName() + "{}, ignoring...", schemaName);
+            if (schema == null || schema.getAnyTypeClass() != null) {
+                LOG.debug("Invalid or already in use" + DerSchema.class.getSimpleName()
+                        + "{}, ignoring...", schemaName);
             } else {
                 anyTypeClass.add(schema);
             }
         }
 
+        for (VirSchema schema : virSchemaDAO.findByAnyTypeClass(anyTypeClass)) {
+            schema.setAnyTypeClass(null);
+        }
+
         anyTypeClass.getVirSchemas().clear();
         for (String schemaName : anyTypeClassTO.getVirSchemas()) {
             VirSchema schema = virSchemaDAO.find(schemaName);
-            if (schema == null) {
-                LOG.debug("Invalid " + VirSchema.class.getSimpleName() + "{}, ignoring...", schemaName);
+            if (schema == null || schema.getAnyTypeClass() != null) {
+                LOG.debug("Invalid or already in use" + VirSchema.class.getSimpleName()
+                        + "{}, ignoring...", schemaName);
             } else {
                 anyTypeClass.add(schema);
             }

http://git-wip-us.apache.org/repos/asf/syncope/blob/b2e84011/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/SchemaDataBinderImpl.java
----------------------------------------------------------------------
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/SchemaDataBinderImpl.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/SchemaDataBinderImpl.java
index f20a265..0794f8c 100644
--- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/SchemaDataBinderImpl.java
+++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/SchemaDataBinderImpl.java
@@ -33,44 +33,88 @@ import org.apache.syncope.core.persistence.api.entity.PlainSchema;
 import org.apache.syncope.core.persistence.api.entity.VirSchema;
 import org.apache.syncope.core.misc.spring.BeanUtils;
 import org.apache.syncope.core.misc.jexl.JexlUtils;
+import org.apache.syncope.core.persistence.api.dao.AnyTypeClassDAO;
+import org.apache.syncope.core.persistence.api.dao.DerSchemaDAO;
+import org.apache.syncope.core.persistence.api.dao.VirSchemaDAO;
+import org.apache.syncope.core.persistence.api.entity.AnyTypeClass;
 import org.apache.syncope.core.persistence.api.entity.AnyUtils;
 import org.apache.syncope.core.persistence.api.entity.AnyUtilsFactory;
+import org.apache.syncope.core.persistence.api.entity.EntityFactory;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Component;
 
 @Component
 public class SchemaDataBinderImpl implements SchemaDataBinder {
 
+    private static final Logger LOG = LoggerFactory.getLogger(SchemaDataBinder.class);
+
+    private static final String[] IGNORE_PROPERTIES = { "anyTypeClass" };
+
+    @Autowired
+    private AnyTypeClassDAO anyTypeClassDAO;
+
     @Autowired
-    private PlainSchemaDAO schemaDAO;
+    private PlainSchemaDAO plainSchemaDAO;
+
+    @Autowired
+    private DerSchemaDAO derSchemaDAO;
+
+    @Autowired
+    private VirSchemaDAO virSchemaDAO;
+
+    @Autowired
+    private EntityFactory entityFactory;
 
     @Autowired
     private AnyUtilsFactory anyUtilsFactory;
 
     // --------------- PLAIN -----------------
-    private <T extends PlainSchema> void fill(final T schema, final PlainSchemaTO schemaTO) {
+    private PlainSchema fill(final PlainSchema schema, final PlainSchemaTO schemaTO) {
         if (!JexlUtils.isExpressionValid(schemaTO.getMandatoryCondition())) {
             SyncopeClientException sce = SyncopeClientException.build(ClientExceptionType.InvalidValues);
             sce.getElements().add(schemaTO.getMandatoryCondition());
             throw sce;
         }
 
-        BeanUtils.copyProperties(schemaTO, schema);
+        BeanUtils.copyProperties(schemaTO, schema, IGNORE_PROPERTIES);
+
+        PlainSchema merged = plainSchemaDAO.save(schema);
+
+        if (schemaTO.getAnyTypeClass() != null
+                && (merged.getAnyTypeClass() == null
+                || !schemaTO.getAnyTypeClass().equals(merged.getAnyTypeClass().getKey()))) {
+
+            AnyTypeClass anyTypeClass = anyTypeClassDAO.find(schemaTO.getAnyTypeClass());
+            if (anyTypeClass == null) {
+                LOG.debug("Invalid " + AnyTypeClass.class.getSimpleName()
+                        + "{}, ignoring...", schemaTO.getAnyTypeClass());
+            } else {
+                anyTypeClass.add(merged);
+                merged.setAnyTypeClass(anyTypeClass);
+            }
+        } else if (schemaTO.getAnyTypeClass() == null && merged.getAnyTypeClass() != null) {
+            merged.getAnyTypeClass().remove(merged);
+            merged.setAnyTypeClass(null);
+        }
+
+        return merged;
     }
 
     @Override
-    public <T extends PlainSchema> void create(final PlainSchemaTO schemaTO, final T schema) {
-        fill(schema, schemaTO);
+    public PlainSchema create(final PlainSchemaTO schemaTO) {
+        return fill(entityFactory.newEntity(PlainSchema.class), schemaTO);
     }
 
     @Override
-    public <T extends PlainSchema> void update(final PlainSchemaTO schemaTO, final T schema) {
+    public PlainSchema update(final PlainSchemaTO schemaTO, final PlainSchema schema) {
         SyncopeClientCompositeException scce = SyncopeClientException.buildComposite();
 
         boolean hasAttrs = false;
         for (AnyTypeKind anyTypeKind : AnyTypeKind.values()) {
             AnyUtils anyUtils = anyUtilsFactory.getInstance(anyTypeKind);
-            hasAttrs |= schemaDAO.findAttrs(schema, anyUtils.plainAttrClass()).isEmpty();
+            hasAttrs |= plainSchemaDAO.findAttrs(schema, anyUtils.plainAttrClass()).isEmpty();
         }
 
         if (hasAttrs) {
@@ -92,30 +136,31 @@ public class SchemaDataBinderImpl implements SchemaDataBinder {
             throw scce;
         }
 
-        fill(schema, schemaTO);
+        return fill(schema, schemaTO);
     }
 
     @Override
-    public <T extends PlainSchema> PlainSchemaTO getPlainSchemaTO(final T schema) {
+    public PlainSchemaTO getPlainSchemaTO(final PlainSchema schema) {
         PlainSchemaTO schemaTO = new PlainSchemaTO();
-        BeanUtils.copyProperties(schema, schemaTO);
+        BeanUtils.copyProperties(schema, schemaTO, IGNORE_PROPERTIES);
+        schemaTO.setAnyTypeClass(schema.getAnyTypeClass() == null ? null : schema.getAnyTypeClass().getKey());
 
         return schemaTO;
     }
 
     // --------------- DERIVED -----------------
-    private <T extends DerSchema> T populate(final T derSchema, final DerSchemaTO derSchemaTO) {
+    private DerSchema fill(final DerSchema schema, final DerSchemaTO schemaTO) {
         SyncopeClientCompositeException scce = SyncopeClientException.buildComposite();
 
-        if (StringUtils.isBlank(derSchemaTO.getExpression())) {
+        if (StringUtils.isBlank(schemaTO.getExpression())) {
             SyncopeClientException requiredValuesMissing =
                     SyncopeClientException.build(ClientExceptionType.RequiredValuesMissing);
             requiredValuesMissing.getElements().add("expression");
 
             scce.addException(requiredValuesMissing);
-        } else if (!JexlUtils.isExpressionValid(derSchemaTO.getExpression())) {
+        } else if (!JexlUtils.isExpressionValid(schemaTO.getExpression())) {
             SyncopeClientException e = SyncopeClientException.build(ClientExceptionType.InvalidValues);
-            e.getElements().add(derSchemaTO.getExpression());
+            e.getElements().add(schemaTO.getExpression());
 
             scce.addException(e);
         }
@@ -124,51 +169,91 @@ public class SchemaDataBinderImpl implements SchemaDataBinder {
             throw scce;
         }
 
-        BeanUtils.copyProperties(derSchemaTO, derSchema);
+        BeanUtils.copyProperties(schemaTO, schema, IGNORE_PROPERTIES);
+
+        DerSchema merged = derSchemaDAO.save(schema);
+
+        if (schemaTO.getAnyTypeClass() != null
+                && (merged.getAnyTypeClass() == null
+                || !schemaTO.getAnyTypeClass().equals(merged.getAnyTypeClass().getKey()))) {
+
+            AnyTypeClass anyTypeClass = anyTypeClassDAO.find(schemaTO.getAnyTypeClass());
+            if (anyTypeClass == null) {
+                LOG.debug("Invalid " + AnyTypeClass.class.getSimpleName()
+                        + "{}, ignoring...", schemaTO.getAnyTypeClass());
+            } else {
+                anyTypeClass.add(merged);
+                merged.setAnyTypeClass(anyTypeClass);
+            }
+        } else if (schemaTO.getAnyTypeClass() == null && merged.getAnyTypeClass() != null) {
+            merged.getAnyTypeClass().remove(merged);
+            merged.setAnyTypeClass(null);
+        }
 
-        return derSchema;
+        return merged;
     }
 
     @Override
-    public <T extends DerSchema> T create(final DerSchemaTO derSchemaTO, final T derSchema) {
-        return populate(derSchema, derSchemaTO);
+    public DerSchema create(final DerSchemaTO schemaTO) {
+        return fill(entityFactory.newEntity(DerSchema.class), schemaTO);
     }
 
     @Override
-    public <T extends DerSchema> T update(final DerSchemaTO derSchemaTO, final T derSchema) {
-        return populate(derSchema, derSchemaTO);
+    public DerSchema update(final DerSchemaTO schemaTO, final DerSchema schema) {
+        return fill(schema, schemaTO);
     }
 
     @Override
-    public <T extends DerSchema> DerSchemaTO getDerSchemaTO(final T derSchema) {
-        DerSchemaTO derSchemaTO = new DerSchemaTO();
-        BeanUtils.copyProperties(derSchema, derSchemaTO);
+    public DerSchemaTO getDerSchemaTO(final DerSchema schema) {
+        DerSchemaTO schemaTO = new DerSchemaTO();
+        BeanUtils.copyProperties(schema, schemaTO, IGNORE_PROPERTIES);
+        schemaTO.setAnyTypeClass(schema.getAnyTypeClass() == null ? null : schema.getAnyTypeClass().getKey());
 
-        return derSchemaTO;
+        return schemaTO;
     }
 
     // --------------- VIRTUAL -----------------
-    private <T extends VirSchema> T fill(final T virSchema, final VirSchemaTO virSchemaTO) {
-        BeanUtils.copyProperties(virSchemaTO, virSchema);
+    private VirSchema fill(final VirSchema schema, final VirSchemaTO schemaTO) {
+        BeanUtils.copyProperties(schemaTO, schema, IGNORE_PROPERTIES);
+
+        VirSchema merged = virSchemaDAO.save(schema);
+
+        if (schemaTO.getAnyTypeClass() != null
+                && (merged.getAnyTypeClass() == null
+                || !schemaTO.getAnyTypeClass().equals(merged.getAnyTypeClass().getKey()))) {
+
+            AnyTypeClass anyTypeClass = anyTypeClassDAO.find(schemaTO.getAnyTypeClass());
+            if (anyTypeClass == null) {
+                LOG.debug("Invalid " + AnyTypeClass.class.getSimpleName()
+                        + "{}, ignoring...", schemaTO.getAnyTypeClass());
+            } else {
+                anyTypeClass.add(merged);
+                merged.setAnyTypeClass(anyTypeClass);
+            }
+        } else if (schemaTO.getAnyTypeClass() == null && merged.getAnyTypeClass() != null) {
+            merged.getAnyTypeClass().remove(merged);
+            merged.setAnyTypeClass(null);
+        }
 
-        return virSchema;
+        return merged;
     }
 
     @Override
-    public <T extends VirSchema> T create(final VirSchemaTO virSchemaTO, final T virSchema) {
-        return fill(virSchema, virSchemaTO);
+    public VirSchema create(final VirSchemaTO schemaTO) {
+        return fill(entityFactory.newEntity(VirSchema.class), schemaTO);
     }
 
     @Override
-    public <T extends VirSchema> T update(final VirSchemaTO virSchemaTO, final T virSchema) {
-        return fill(virSchema, virSchemaTO);
+    public VirSchema update(final VirSchemaTO schemaTO, final VirSchema schema) {
+        return fill(schema, schemaTO);
     }
 
     @Override
-    public <T extends VirSchema> VirSchemaTO getVirSchemaTO(final T virSchema) {
-        VirSchemaTO virSchemaTO = new VirSchemaTO();
-        BeanUtils.copyProperties(virSchema, virSchemaTO);
+    public VirSchemaTO getVirSchemaTO(final VirSchema schema) {
+        VirSchemaTO schemaTO = new VirSchemaTO();
+        BeanUtils.copyProperties(schema, schemaTO, IGNORE_PROPERTIES);
+        schemaTO.setAnyTypeClass(schema.getAnyTypeClass() == null ? null : schema.getAnyTypeClass().getKey());
 
-        return virSchemaTO;
+        return schemaTO;
     }
 }

http://git-wip-us.apache.org/repos/asf/syncope/blob/b2e84011/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/AnyTypeClassITCase.java
----------------------------------------------------------------------
diff --git a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/AnyTypeClassITCase.java b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/AnyTypeClassITCase.java
index 557f4b3..6e88c71 100644
--- a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/AnyTypeClassITCase.java
+++ b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/AnyTypeClassITCase.java
@@ -21,6 +21,7 @@ package org.apache.syncope.fit.core.reference;
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertFalse;
 import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
 import static org.junit.Assert.assertTrue;
 import static org.junit.Assert.fail;
 
@@ -28,6 +29,7 @@ import java.util.List;
 import javax.ws.rs.core.Response;
 import org.apache.syncope.common.lib.SyncopeClientException;
 import org.apache.syncope.common.lib.to.AnyTypeClassTO;
+import org.apache.syncope.common.lib.to.DerSchemaTO;
 import org.apache.syncope.common.lib.to.PlainSchemaTO;
 import org.apache.syncope.common.lib.types.AttrSchemaType;
 import org.apache.syncope.common.lib.types.ClientExceptionType;
@@ -58,9 +60,21 @@ public class AnyTypeClassITCase extends AbstractITCase {
 
     @Test
     public void crud() {
+        // 1. create sample schemas
+        PlainSchemaTO plainSchema = new PlainSchemaTO();
+        plainSchema.setKey("new_plain_schema" + getUUIDString());
+        plainSchema.setType(AttrSchemaType.String);
+        plainSchema = createSchema(SchemaType.PLAIN, plainSchema);
+
+        DerSchemaTO derSchema = new DerSchemaTO();
+        derSchema.setKey("new_der_schema" + getUUIDString());
+        derSchema.setExpression(plainSchema.getKey() + " + '_' + derived_dx");
+        derSchema = createSchema(SchemaType.DERIVED, derSchema);
+
+        // 2. actual CRUD
         AnyTypeClassTO newClass = new AnyTypeClassTO();
         newClass.setKey("new class" + getUUIDString());
-        newClass.getPlainSchemas().add("firstname");
+        newClass.getPlainSchemas().add(plainSchema.getKey());
 
         Response response = anyTypeClassService.create(newClass);
         assertEquals(Response.Status.CREATED.getStatusCode(), response.getStatusInfo().getStatusCode());
@@ -71,7 +85,7 @@ public class AnyTypeClassITCase extends AbstractITCase {
         assertTrue(newClass.getDerSchemas().isEmpty());
         assertTrue(newClass.getVirSchemas().isEmpty());
 
-        newClass.getDerSchemas().add("cn");
+        newClass.getDerSchemas().add(derSchema.getKey());
         anyTypeClassService.update(newClass);
 
         newClass = anyTypeClassService.read(newClass.getKey());
@@ -80,6 +94,9 @@ public class AnyTypeClassITCase extends AbstractITCase {
         assertFalse(newClass.getDerSchemas().isEmpty());
         assertTrue(newClass.getVirSchemas().isEmpty());
 
+        assertEquals(newClass.getKey(), schemaService.read(SchemaType.PLAIN, plainSchema.getKey()).getAnyTypeClass());
+        assertEquals(newClass.getKey(), schemaService.read(SchemaType.DERIVED, derSchema.getKey()).getAnyTypeClass());
+
         anyTypeClassService.delete(newClass.getKey());
 
         try {
@@ -88,6 +105,9 @@ public class AnyTypeClassITCase extends AbstractITCase {
         } catch (SyncopeClientException e) {
             assertEquals(ClientExceptionType.NotFound, e.getType());
         }
+
+        assertNull(schemaService.read(SchemaType.PLAIN, plainSchema.getKey()).getAnyTypeClass());
+        assertNull(schemaService.read(SchemaType.DERIVED, derSchema.getKey()).getAnyTypeClass());
     }
 
     @Test

http://git-wip-us.apache.org/repos/asf/syncope/blob/b2e84011/pom.xml
----------------------------------------------------------------------
diff --git a/pom.xml b/pom.xml
index 7d722b3..bc1e2f4 100644
--- a/pom.xml
+++ b/pom.xml
@@ -335,7 +335,7 @@ under the License.
     <spring.version>4.1.7.RELEASE</spring.version>
     <spring-security.version>4.0.2.RELEASE</spring-security.version>
 
-    <openjpa.version>2.4.1-SNAPSHOT</openjpa.version>
+    <openjpa.version>2.4.0</openjpa.version>
     <commons-dbcp.version>2.1</commons-dbcp.version>
     <hibernate-validator.version>5.2.1.Final</hibernate-validator.version>
 
@@ -533,11 +533,6 @@ under the License.
         <artifactId>openjpa-persistence-jdbc</artifactId>
         <version>${openjpa.version}</version>
       </dependency>
-      <dependency>
-        <groupId>org.apache.openjpa</groupId>
-        <artifactId>openjpa-slice</artifactId>
-        <version>${openjpa.version}</version>
-      </dependency>
     
       <dependency>
         <groupId>org.apache.commons</groupId>
@@ -1112,6 +1107,12 @@ under the License.
         </plugin>
         
         <plugin>
+          <groupId>org.apache.cxf</groupId>
+          <artifactId>cxf-java2wadl-plugin</artifactId>
+          <version>${cxf.version}</version>
+        </plugin>
+        
+        <plugin>
           <groupId>org.apache.openjpa</groupId>
           <artifactId>openjpa-maven-plugin</artifactId>
           <version>${openjpa.version}</version>


[28/31] syncope git commit: Merge from 1_2_X

Posted by md...@apache.org.
Merge from 1_2_X


Project: http://git-wip-us.apache.org/repos/asf/syncope/repo
Commit: http://git-wip-us.apache.org/repos/asf/syncope/commit/ce015d13
Tree: http://git-wip-us.apache.org/repos/asf/syncope/tree/ce015d13
Diff: http://git-wip-us.apache.org/repos/asf/syncope/diff/ce015d13

Branch: refs/heads/SYNCOPE-156
Commit: ce015d1306d944b5b75797f1e7563884bf814100
Parents: e199fba dff48fd
Author: Francesco Chicchiriccò <il...@apache.org>
Authored: Thu Aug 13 17:49:49 2015 +0200
Committer: Francesco Chicchiriccò <il...@apache.org>
Committed: Thu Aug 13 17:49:49 2015 +0200

----------------------------------------------------------------------
 pom.xml | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/syncope/blob/ce015d13/pom.xml
----------------------------------------------------------------------
diff --cc pom.xml
index e5d21f4,a952b3c..b58c7e1
--- a/pom.xml
+++ b/pom.xml
@@@ -326,45 -335,60 +326,45 @@@ under the License
      <connid.ldap.version>1.4.0</connid.ldap.version>
      <connid.ad.version>1.2.3</connid.ad.version>
  
 -    <commons-jexl.version>2.1.1</commons-jexl.version>
 -    <commons-lang.version>3.3.2</commons-lang.version>
 -    <commons-codec.version>1.10</commons-codec.version>
 +    <cxf.version>3.1.2</cxf.version>
  
 -    <activiti.version>5.16.4</activiti.version>
 +    <camel.version>2.15.2</camel.version>	
  
 -    <aspectj.version>1.8.6</aspectj.version>
 +    <jackson.version>2.6.1</jackson.version>
  
 -    <cxf.version>3.0.6</cxf.version>	
 -    <spring.version>4.0.9.RELEASE</spring.version>
 -    <spring-security.version>3.2.8.RELEASE</spring-security.version>
 -    <jackson.version>2.4.6</jackson.version>
 -    <velocity.version>1.7</velocity.version>
 -    <velocitytools.version>2.0</velocitytools.version>
 -    <quartz.version>2.2.1</quartz.version>
 +    <spring.version>4.1.7.RELEASE</spring.version>
 +    <spring-security.version>4.0.2.RELEASE</spring-security.version>
  
 -    <openjpa.version>2.3.0</openjpa.version>
 -    <hibernate-validator.version>5.1.3.Final</hibernate-validator.version>
 -    <commons-dbcp.version>1.4</commons-dbcp.version>
 -    <commons.logging.version>1.1.3</commons.logging.version>
 +    <openjpa.version>2.4.0</openjpa.version>
 +    <commons-dbcp.version>2.1.1</commons-dbcp.version>
 +    <hibernate-validator.version>5.2.1.Final</hibernate-validator.version>
  
 -    <cocoon.version>3.0.0-alpha-3</cocoon.version>
 +    <jasypt.version>1.9.2</jasypt.version>
 +
 +    <quartz.version>2.2.1</quartz.version>
  
 -    <wicket.version>6.20.0</wicket.version>
 +    <cocoon.version>3.0.0-alpha-3</cocoon.version>
  
 -    <groovy.version>2.3.10</groovy.version>
 +    <groovy.version>2.4.4</groovy.version>
  
 -    <h2.version>1.4.188</h2.version>
 +    <activiti.version>5.18.0</activiti.version>
  
 -    <log4j.version>2.3</log4j.version>
      <slf4j.version>1.7.12</slf4j.version>
 +    <log4j.version>2.3</log4j.version>
      <disruptor.version>3.3.2</disruptor.version>
  
 -    <junit.version>4.11</junit.version>
 -    <selenium.version>2.46.0</selenium.version>
 -
 -    <apacheds.version>1.5.7</apacheds.version>
 -    
 -    <httpclient.version>4.3.6</httpclient.version>
 +    <commons-io.version>2.4</commons-io.version>
 +    <commons-codec.version>1.10</commons-codec.version>
 +    <commons-jexl.version>2.1.1</commons-jexl.version>
 +    <commons-lang.version>3.4</commons-lang.version>
 +    <commons-collection.version>4.0</commons-collection.version>
 +    <commons-logging.version>1.1.3</commons-logging.version>
  
-     <h2.version>1.4.187</h2.version>
 -    <tomcat.version>7.0.63</tomcat.version>
++    <h2.version>1.4.188</h2.version>
  
 -    <jasypt.version>1.9.2</jasypt.version>
 - 
 -    <jquery.version>1.11.1</jquery.version>
 -    <jquery-ui.version>1.10.4</jquery-ui.version>
 -    <highlightjs.version>8.0</highlightjs.version>
 -    <codemirror.version>3.23</codemirror.version>
 +    <junit.version>4.12</junit.version>
 +    <selenium.version>2.46.0</selenium.version>
  
 -    <izpack.version>5.0.3</izpack.version>
 -    <maven-invoker.version>2.1.1</maven-invoker.version>
 -    
 -    <jdeb.version>1.4</jdeb.version>
 - 
      <conf.directory>${project.build.directory}/test-classes</conf.directory>
      <bundles.directory>${project.build.directory}/bundles</bundles.directory>
      <connid.location>file:${bundles.directory}/</connid.location>


[19/31] syncope git commit: [SYNCOPE-652] Still several things to refine, but it starts taking shape

Posted by md...@apache.org.
http://git-wip-us.apache.org/repos/asf/syncope/blob/6dfedd8f/core/misc/src/main/java/org/apache/syncope/core/misc/policy/PolicyEnforcer.java
----------------------------------------------------------------------
diff --git a/core/misc/src/main/java/org/apache/syncope/core/misc/policy/PolicyEnforcer.java b/core/misc/src/main/java/org/apache/syncope/core/misc/policy/PolicyEnforcer.java
index c8274a4..86e6583 100644
--- a/core/misc/src/main/java/org/apache/syncope/core/misc/policy/PolicyEnforcer.java
+++ b/core/misc/src/main/java/org/apache/syncope/core/misc/policy/PolicyEnforcer.java
@@ -23,5 +23,13 @@ import org.apache.syncope.common.lib.types.PolicyType;
 
 public interface PolicyEnforcer<T extends PolicySpec, E> {
 
-    void enforce(final T policy, final PolicyType type, final E object);
+    /**
+     * Check the given entity to see if it conforms with the indicated policy.
+     *
+     * @param policy
+     * @param type
+     * @param entity
+     * @return whether user is to be suspended
+     */
+    boolean enforce(final T policy, final PolicyType type, final E entity);
 }

http://git-wip-us.apache.org/repos/asf/syncope/blob/6dfedd8f/core/misc/src/main/java/org/apache/syncope/core/misc/policy/PolicyEvaluator.java
----------------------------------------------------------------------
diff --git a/core/misc/src/main/java/org/apache/syncope/core/misc/policy/PolicyEvaluator.java b/core/misc/src/main/java/org/apache/syncope/core/misc/policy/PolicyEvaluator.java
index 52fa0d8..fd6abd2 100644
--- a/core/misc/src/main/java/org/apache/syncope/core/misc/policy/PolicyEvaluator.java
+++ b/core/misc/src/main/java/org/apache/syncope/core/misc/policy/PolicyEvaluator.java
@@ -34,9 +34,6 @@ import org.springframework.stereotype.Component;
 @Component
 public class PolicyEvaluator {
 
-    /**
-     * Logger.
-     */
     private static final Logger LOG = LoggerFactory.getLogger(PolicyEvaluator.class);
 
     @SuppressWarnings("unchecked")
@@ -54,7 +51,7 @@ public class PolicyEvaluator {
                 BeanUtils.copyProperties(ppSpec, evaluatedPPSpec, new String[] { "schemasNotPermitted" });
 
                 for (String schema : ppSpec.getSchemasNotPermitted()) {
-                    PlainAttr attr = any.getPlainAttr(schema);
+                    PlainAttr<?> attr = any.getPlainAttr(schema);
                     if (attr != null) {
                         List<String> values = attr.getValuesAsStrings();
                         if (values != null && !values.isEmpty()) {

http://git-wip-us.apache.org/repos/asf/syncope/blob/6dfedd8f/core/misc/src/main/java/org/apache/syncope/core/misc/security/AuthContextUtils.java
----------------------------------------------------------------------
diff --git a/core/misc/src/main/java/org/apache/syncope/core/misc/security/AuthContextUtils.java b/core/misc/src/main/java/org/apache/syncope/core/misc/security/AuthContextUtils.java
index 932627d..38240d9 100644
--- a/core/misc/src/main/java/org/apache/syncope/core/misc/security/AuthContextUtils.java
+++ b/core/misc/src/main/java/org/apache/syncope/core/misc/security/AuthContextUtils.java
@@ -18,12 +18,18 @@
  */
 package org.apache.syncope.core.misc.security;
 
+import java.util.ArrayList;
 import java.util.HashMap;
+import java.util.List;
 import java.util.Map;
 import java.util.Set;
+import org.apache.commons.collections4.CollectionUtils;
 import org.apache.commons.collections4.MapUtils;
+import org.apache.commons.collections4.Transformer;
 import org.apache.commons.lang3.StringUtils;
 import org.apache.syncope.common.lib.SyncopeConstants;
+import org.apache.syncope.common.lib.types.Entitlement;
+import org.apache.syncope.core.misc.spring.ApplicationContextProvider;
 import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
 import org.springframework.security.core.Authentication;
 import org.springframework.security.core.GrantedAuthority;
@@ -79,6 +85,27 @@ public final class AuthContextUtils {
         return domainKey;
     }
 
+    public static void setFakeAuth(final String domain) {
+        List<GrantedAuthority> authorities = CollectionUtils.collect(Entitlement.values(),
+                new Transformer<String, GrantedAuthority>() {
+
+                    @Override
+                    public GrantedAuthority transform(final String entitlement) {
+                        return new SyncopeGrantedAuthority(entitlement, SyncopeConstants.ROOT_REALM);
+                    }
+                }, new ArrayList<GrantedAuthority>());
+
+        UsernamePasswordAuthenticationToken auth = new UsernamePasswordAuthenticationToken(
+                new User(ApplicationContextProvider.getBeanFactory().getBean("adminUser", String.class),
+                        "FAKE_PASSWORD", authorities), "FAKE_PASSWORD", authorities);
+        auth.setDetails(new SyncopeAuthenticationDetails(domain));
+        SecurityContextHolder.getContext().setAuthentication(auth);
+    }
+
+    public static void clearFakeAuth() {
+        SecurityContextHolder.clearContext();
+    }
+
     /**
      * Private default constructor, for static-only classes.
      */

http://git-wip-us.apache.org/repos/asf/syncope/blob/6dfedd8f/core/misc/src/main/java/org/apache/syncope/core/misc/security/PasswordGenerator.java
----------------------------------------------------------------------
diff --git a/core/misc/src/main/java/org/apache/syncope/core/misc/security/PasswordGenerator.java b/core/misc/src/main/java/org/apache/syncope/core/misc/security/PasswordGenerator.java
index eab59bb..44635be 100644
--- a/core/misc/src/main/java/org/apache/syncope/core/misc/security/PasswordGenerator.java
+++ b/core/misc/src/main/java/org/apache/syncope/core/misc/security/PasswordGenerator.java
@@ -215,7 +215,7 @@ public class PasswordGenerator {
         String[] generatedPassword = new String[policySpec.getMinLength()];
 
         for (int i = 0; i < generatedPassword.length; i++) {
-            generatedPassword[i] = "";
+            generatedPassword[i] = StringUtils.EMPTY;
         }
 
         checkStartChar(generatedPassword, policySpec);
@@ -224,7 +224,6 @@ public class PasswordGenerator {
 
         checkRequired(generatedPassword, policySpec);
 
-        //filled empty chars
         for (int firstEmptyChar = firstEmptyChar(generatedPassword);
                 firstEmptyChar < generatedPassword.length - 1; firstEmptyChar++) {
 
@@ -252,6 +251,10 @@ public class PasswordGenerator {
         if (policySpec.isMustntStartWithNonAlpha()) {
             generatedPassword[0] = SecureRandomUtils.generateRandomLetter();
         }
+
+        if (StringUtils.EMPTY.equals(generatedPassword[0])) {
+            generatedPassword[0] = SecureRandomUtils.generateRandomLetter();
+        }
     }
 
     private void checkEndChar(final String[] generatedPassword, final PasswordPolicySpec policySpec) {
@@ -271,6 +274,10 @@ public class PasswordGenerator {
         if (policySpec.isMustntEndWithNonAlpha()) {
             generatedPassword[policySpec.getMinLength() - 1] = SecureRandomUtils.generateRandomLetter();
         }
+
+        if (StringUtils.EMPTY.equals(generatedPassword[policySpec.getMinLength() - 1])) {
+            generatedPassword[policySpec.getMinLength() - 1] = SecureRandomUtils.generateRandomLetter();
+        }
     }
 
     private int firstEmptyChar(final String[] generatedPStrings) {

http://git-wip-us.apache.org/repos/asf/syncope/blob/6dfedd8f/core/misc/src/main/java/org/apache/syncope/core/misc/security/SyncopeAuthenticationProvider.java
----------------------------------------------------------------------
diff --git a/core/misc/src/main/java/org/apache/syncope/core/misc/security/SyncopeAuthenticationProvider.java b/core/misc/src/main/java/org/apache/syncope/core/misc/security/SyncopeAuthenticationProvider.java
index 01abb93..f452128 100644
--- a/core/misc/src/main/java/org/apache/syncope/core/misc/security/SyncopeAuthenticationProvider.java
+++ b/core/misc/src/main/java/org/apache/syncope/core/misc/security/SyncopeAuthenticationProvider.java
@@ -191,23 +191,23 @@ public class SyncopeAuthenticationProvider implements AuthenticationProvider {
 
             auditManager.audit(
                     AuditElements.EventCategoryType.REST,
-                    "AuthenticationController",
+                    AuditElements.AUTHENTICATION_CATEGORY,
                     null,
-                    "login",
+                    AuditElements.LOGIN_EVENT,
                     Result.SUCCESS,
                     null,
                     authenticated,
                     authentication,
-                    "Successfully authenticated, with groups: " + token.getAuthorities());
+                    "Successfully authenticated, with entitlements: " + token.getAuthorities());
 
             LOG.debug("User {} successfully authenticated, with groups {}",
                     authentication.getPrincipal(), token.getAuthorities());
         } else {
             auditManager.audit(
                     AuditElements.EventCategoryType.REST,
-                    "AuthenticationController",
+                    AuditElements.AUTHENTICATION_CATEGORY,
                     null,
-                    "login",
+                    AuditElements.LOGIN_EVENT,
                     Result.FAILURE,
                     null,
                     authenticated,

http://git-wip-us.apache.org/repos/asf/syncope/blob/6dfedd8f/core/misc/src/main/java/org/apache/syncope/core/misc/security/SyncopeGrantedAuthority.java
----------------------------------------------------------------------
diff --git a/core/misc/src/main/java/org/apache/syncope/core/misc/security/SyncopeGrantedAuthority.java b/core/misc/src/main/java/org/apache/syncope/core/misc/security/SyncopeGrantedAuthority.java
index f8f974b..100de17 100644
--- a/core/misc/src/main/java/org/apache/syncope/core/misc/security/SyncopeGrantedAuthority.java
+++ b/core/misc/src/main/java/org/apache/syncope/core/misc/security/SyncopeGrantedAuthority.java
@@ -27,6 +27,8 @@ import org.apache.commons.collections4.CollectionUtils;
 import org.apache.commons.collections4.SetUtils;
 import org.apache.commons.lang3.builder.EqualsBuilder;
 import org.apache.commons.lang3.builder.HashCodeBuilder;
+import org.apache.commons.lang3.builder.ReflectionToStringBuilder;
+import org.apache.commons.lang3.builder.ToStringStyle;
 import org.apache.syncope.core.misc.RealmUtils;
 import org.springframework.security.core.GrantedAuthority;
 
@@ -80,4 +82,9 @@ public class SyncopeGrantedAuthority implements GrantedAuthority {
         return HashCodeBuilder.reflectionHashCode(this);
     }
 
+    @Override
+    public String toString() {
+        return ReflectionToStringBuilder.toString(this, ToStringStyle.MULTI_LINE_STYLE);
+    }
+
 }

http://git-wip-us.apache.org/repos/asf/syncope/blob/6dfedd8f/core/misc/src/main/java/org/apache/syncope/core/misc/spring/ApplicationContextProvider.java
----------------------------------------------------------------------
diff --git a/core/misc/src/main/java/org/apache/syncope/core/misc/spring/ApplicationContextProvider.java b/core/misc/src/main/java/org/apache/syncope/core/misc/spring/ApplicationContextProvider.java
index 1aa4367..e67dcd6 100644
--- a/core/misc/src/main/java/org/apache/syncope/core/misc/spring/ApplicationContextProvider.java
+++ b/core/misc/src/main/java/org/apache/syncope/core/misc/spring/ApplicationContextProvider.java
@@ -27,12 +27,22 @@ public class ApplicationContextProvider implements ApplicationContextAware {
 
     private static ConfigurableApplicationContext CTX;
 
+    private static DefaultListableBeanFactory BEAN_FACTORY;
+
     public static ConfigurableApplicationContext getApplicationContext() {
         return CTX;
     }
 
     public static DefaultListableBeanFactory getBeanFactory() {
-        return (DefaultListableBeanFactory) CTX.getBeanFactory();
+        return BEAN_FACTORY == null
+                ? CTX == null
+                        ? null
+                        : (DefaultListableBeanFactory) CTX.getBeanFactory()
+                : BEAN_FACTORY;
+    }
+
+    public static void setBeanFactory(final DefaultListableBeanFactory beanFactory) {
+        BEAN_FACTORY = beanFactory;
     }
 
     /**

http://git-wip-us.apache.org/repos/asf/syncope/blob/6dfedd8f/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/DomainsHolder.java
----------------------------------------------------------------------
diff --git a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/DomainsHolder.java b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/DomainsHolder.java
new file mode 100644
index 0000000..1d8e27c
--- /dev/null
+++ b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/DomainsHolder.java
@@ -0,0 +1,27 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.syncope.core.persistence.api;
+
+import java.util.Map;
+import javax.sql.DataSource;
+
+public interface DomainsHolder {
+
+    Map<String, DataSource> getDomains();
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/6dfedd8f/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/content/ContentExporter.java
----------------------------------------------------------------------
diff --git a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/content/ContentExporter.java b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/content/ContentExporter.java
index 67508f7..5ed50df 100644
--- a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/content/ContentExporter.java
+++ b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/content/ContentExporter.java
@@ -24,6 +24,6 @@ import org.xml.sax.SAXException;
 
 public interface ContentExporter {
 
-    void export(OutputStream output, String uwfPrefix, String rwfPrefix) 
+    void export(String domain, OutputStream output, String uwfPrefix, String rwfPrefix) 
             throws SAXException, TransformerConfigurationException;
 }

http://git-wip-us.apache.org/repos/asf/syncope/blob/6dfedd8f/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/DAO.java
----------------------------------------------------------------------
diff --git a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/DAO.java b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/DAO.java
index eb00a0d..4452890 100644
--- a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/DAO.java
+++ b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/DAO.java
@@ -22,8 +22,6 @@ import org.apache.syncope.core.persistence.api.entity.Entity;
 
 public interface DAO<E extends Entity<KEY>, KEY> {
 
-    String getDomain(E entity);
-
     void refresh(E entity);
 
     void detach(E entity);

http://git-wip-us.apache.org/repos/asf/syncope/blob/6dfedd8f/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/task/SchedTask.java
----------------------------------------------------------------------
diff --git a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/task/SchedTask.java b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/task/SchedTask.java
index 734194b..0913ee1 100644
--- a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/task/SchedTask.java
+++ b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/task/SchedTask.java
@@ -24,7 +24,7 @@ public interface SchedTask extends Task {
 
     String getDescription();
 
-    String getJobClassName();
+    String getJobDelegateClassName();
 
     String getName();
 
@@ -32,7 +32,7 @@ public interface SchedTask extends Task {
 
     void setDescription(String description);
 
-    void setJobClassName(String jobClassName);
+    void setJobDelegateClassName(String jobDelegateClassName);
 
     void setName(String name);
 }

http://git-wip-us.apache.org/repos/asf/syncope/blob/6dfedd8f/core/persistence-jpa/pom.xml
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/pom.xml b/core/persistence-jpa/pom.xml
index f60f3da..7f1ff38 100644
--- a/core/persistence-jpa/pom.xml
+++ b/core/persistence-jpa/pom.xml
@@ -80,6 +80,11 @@ under the License.
     </dependency>
       
     <dependency>
+      <groupId>org.aspectj</groupId>
+      <artifactId>aspectjweaver</artifactId>
+    </dependency>
+    
+    <dependency>
       <groupId>commons-io</groupId>
       <artifactId>commons-io</artifactId>
     </dependency>

http://git-wip-us.apache.org/repos/asf/syncope/blob/6dfedd8f/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/content/AbstractContentDealer.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/content/AbstractContentDealer.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/content/AbstractContentDealer.java
index 3bec6b1..9e44efe 100644
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/content/AbstractContentDealer.java
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/content/AbstractContentDealer.java
@@ -18,17 +18,10 @@
  */
 package org.apache.syncope.core.persistence.jpa.content;
 
-import java.io.IOException;
-import java.util.Properties;
-import javax.annotation.Resource;
-import javax.sql.DataSource;
-import org.apache.syncope.core.misc.spring.ResourceWithFallbackLoader;
+import org.apache.syncope.core.persistence.api.DomainsHolder;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.core.io.support.PropertiesLoaderUtils;
-import org.springframework.dao.DataAccessException;
-import org.springframework.jdbc.core.JdbcTemplate;
 
 public abstract class AbstractContentDealer {
 
@@ -36,53 +29,7 @@ public abstract class AbstractContentDealer {
 
     protected static final String ROOT_ELEMENT = "dataset";
 
-    @Resource(name = "database.schema")
-    protected String dbSchema;
-
-    @Resource(name = "indexesXML")
-    private ResourceWithFallbackLoader indexesXML;
-
-    @Resource(name = "viewsXML")
-    private ResourceWithFallbackLoader viewsXML;
-
     @Autowired
-    protected DataSource dataSource;
-
-    protected void createIndexes() throws IOException {
-        LOG.debug("Creating indexes");
-
-        JdbcTemplate jdbcTemplate = new JdbcTemplate(dataSource);
-
-        Properties indexes = PropertiesLoaderUtils.loadProperties(indexesXML.getResource());
-        for (String idx : indexes.stringPropertyNames()) {
-            LOG.debug("Creating index {}", indexes.get(idx).toString());
-
-            try {
-                jdbcTemplate.execute(indexes.get(idx).toString());
-            } catch (DataAccessException e) {
-                LOG.error("Could not create index ", e);
-            }
-        }
-
-        LOG.debug("Indexes created");
-    }
-
-    protected void createViews() throws IOException {
-        LOG.debug("Creating views");
-
-        JdbcTemplate jdbcTemplate = new JdbcTemplate(dataSource);
-
-        Properties views = PropertiesLoaderUtils.loadProperties(viewsXML.getResource());
-        for (String idx : views.stringPropertyNames()) {
-            LOG.debug("Creating view {}", views.get(idx).toString());
-
-            try {
-                jdbcTemplate.execute(views.get(idx).toString().replaceAll("\\n", " "));
-            } catch (DataAccessException e) {
-                LOG.error("Could not create view ", e);
-            }
-        }
+    protected DomainsHolder domainsHolder;
 
-        LOG.debug("Views created");
-    }
 }

http://git-wip-us.apache.org/repos/asf/syncope/blob/6dfedd8f/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/content/XMLContentExporter.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/content/XMLContentExporter.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/content/XMLContentExporter.java
index ea13072..17f4bce 100644
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/content/XMLContentExporter.java
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/content/XMLContentExporter.java
@@ -40,6 +40,7 @@ import java.util.Map;
 import java.util.Set;
 import java.util.TreeMap;
 import java.util.TreeSet;
+import javax.sql.DataSource;
 import javax.xml.transform.OutputKeys;
 import javax.xml.transform.Transformer;
 import javax.xml.transform.TransformerConfigurationException;
@@ -50,6 +51,7 @@ import org.apache.commons.io.IOUtils;
 import org.apache.commons.lang3.StringUtils;
 import org.apache.syncope.common.lib.SyncopeConstants;
 import org.apache.syncope.core.misc.DataFormat;
+import org.apache.syncope.core.misc.spring.ApplicationContextProvider;
 import org.apache.syncope.core.persistence.api.content.ContentExporter;
 import org.apache.syncope.core.persistence.jpa.entity.JPAReportExec;
 import org.apache.syncope.core.persistence.jpa.entity.anyobject.JPAADerAttr;
@@ -91,30 +93,13 @@ public class XMLContentExporter extends AbstractContentDealer implements Content
                 JPAARelationship.TABLE, JPAAMembership.TABLE, JPAURelationship.TABLE, JPAUMembership.TABLE
             }));
 
-    protected static final Set<String> TABLE_SUFFIXES_TO_BE_INCLUDED =
-            new HashSet<>(Arrays.asList(new String[] { "TEMPLATE" }));
-
     protected static final Map<String, String> TABLES_TO_BE_FILTERED =
             Collections.singletonMap("TASK", "DTYPE <> 'PropagationTask'");
 
     protected static final Map<String, Set<String>> COLUMNS_TO_BE_NULLIFIED =
             Collections.singletonMap("SYNCOPEGROUP", Collections.singleton("USEROWNER_ID"));
 
-    private boolean isTableAllowed(final String tableName) {
-        boolean allowed = true;
-        for (String prefix : TABLE_PREFIXES_TO_BE_EXCLUDED) {
-            if (tableName.toUpperCase().startsWith(prefix)) {
-                for (String suffix : TABLE_SUFFIXES_TO_BE_INCLUDED) {
-                    if (!tableName.toUpperCase().endsWith(suffix)) {
-                        allowed = false;
-                    }
-                }
-            }
-        }
-        return allowed;
-    }
-
-    private List<String> sortByForeignKeys(final Connection conn, final Set<String> tableNames)
+    private List<String> sortByForeignKeys(final String dbSchema, final Connection conn, final Set<String> tableNames)
             throws SQLException {
 
         Set<MultiParentNode<String>> roots = new HashSet<>();
@@ -325,7 +310,7 @@ public class XMLContentExporter extends AbstractContentDealer implements Content
     }
 
     @Override
-    public void export(final OutputStream os, final String uwfPrefix, final String rwfPrefix)
+    public void export(final String domain, final OutputStream os, final String uwfPrefix, final String rwfPrefix)
             throws SAXException, TransformerConfigurationException {
 
         if (StringUtils.isNotBlank(uwfPrefix)) {
@@ -346,6 +331,13 @@ public class XMLContentExporter extends AbstractContentDealer implements Content
         handler.startDocument();
         handler.startElement("", "", ROOT_ELEMENT, new AttributesImpl());
 
+        DataSource dataSource = domainsHolder.getDomains().get(domain);
+        if (dataSource == null) {
+            throw new IllegalArgumentException("Could not find DataSource for domain " + domain);
+        }
+
+        String dbSchema = ApplicationContextProvider.getBeanFactory().getBean(domain + "DatabaseSchema", String.class);
+
         Connection conn = null;
         ResultSet rs = null;
         try {
@@ -359,15 +351,13 @@ public class XMLContentExporter extends AbstractContentDealer implements Content
             while (rs.next()) {
                 String tableName = rs.getString("TABLE_NAME");
                 LOG.debug("Found table {}", tableName);
-                if (isTableAllowed(tableName)) {
-                    tableNames.add(tableName);
-                }
+                tableNames.add(tableName);
             }
 
             LOG.debug("Tables to be exported {}", tableNames);
 
             // then sort tables based on foreign keys and dump
-            for (String tableName : sortByForeignKeys(conn, tableNames)) {
+            for (String tableName : sortByForeignKeys(dbSchema, conn, tableNames)) {
                 try {
                     doExportTable(handler, conn, tableName, TABLES_TO_BE_FILTERED.get(tableName.toUpperCase()));
                 } catch (Exception e) {

http://git-wip-us.apache.org/repos/asf/syncope/blob/6dfedd8f/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/content/XMLContentLoader.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/content/XMLContentLoader.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/content/XMLContentLoader.java
index 086adfd..5d8cfc5 100644
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/content/XMLContentLoader.java
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/content/XMLContentLoader.java
@@ -20,17 +20,22 @@ package org.apache.syncope.core.persistence.jpa.content;
 
 import java.io.IOException;
 import java.io.InputStream;
+import java.util.Map;
+import java.util.Properties;
 import javax.annotation.Resource;
+import javax.sql.DataSource;
 import javax.xml.parsers.SAXParser;
 import javax.xml.parsers.SAXParserFactory;
 import org.apache.commons.io.IOUtils;
+import org.apache.syncope.core.misc.spring.ApplicationContextProvider;
+import org.apache.syncope.core.misc.spring.ResourceWithFallbackLoader;
 import org.apache.syncope.core.persistence.api.content.ContentLoader;
 import org.apache.syncope.core.persistence.jpa.entity.conf.JPAConf;
-import org.apache.syncope.core.misc.spring.ResourceWithFallbackLoader;
+import org.springframework.core.io.support.PropertiesLoaderUtils;
 import org.springframework.dao.DataAccessException;
 import org.springframework.jdbc.core.JdbcTemplate;
+import org.springframework.orm.jpa.EntityManagerFactoryUtils;
 import org.springframework.stereotype.Component;
-import org.springframework.transaction.annotation.Transactional;
 
 /**
  * Initialize Database with default content if no data is present already.
@@ -38,47 +43,59 @@ import org.springframework.transaction.annotation.Transactional;
 @Component
 public class XMLContentLoader extends AbstractContentDealer implements ContentLoader {
 
-    @Resource(name = "contentXML")
-    private ResourceWithFallbackLoader contentXML;
+    @Resource(name = "indexesXML")
+    private ResourceWithFallbackLoader indexesXML;
+
+    @Resource(name = "viewsXML")
+    private ResourceWithFallbackLoader viewsXML;
 
     @Override
     public Integer getPriority() {
         return 0;
     }
 
-    @Transactional
     @Override
     public void load() {
-        JdbcTemplate jdbcTemplate = new JdbcTemplate(dataSource);
-
-        boolean existingData;
-        try {
-            existingData = jdbcTemplate.queryForObject("SELECT COUNT(0) FROM " + JPAConf.TABLE, Integer.class) > 0;
-        } catch (DataAccessException e) {
-            LOG.error("Could not access to table " + JPAConf.TABLE, e);
-            existingData = true;
-        }
-
-        if (existingData) {
-            LOG.info("Data found in the database, leaving untouched");
-        } else {
-            LOG.info("Empty database found, loading default content");
+        for (Map.Entry<String, DataSource> entry : domainsHolder.getDomains().entrySet()) {
+            // create EntityManager so OpenJPA will build the SQL schema
+            EntityManagerFactoryUtils.findEntityManagerFactory(
+                    ApplicationContextProvider.getBeanFactory(), entry.getKey()).createEntityManager();
 
+            JdbcTemplate jdbcTemplate = new JdbcTemplate(entry.getValue());
+            boolean existingData;
             try {
-                loadDefaultContent();
-            } catch (Exception e) {
-                LOG.error("While loading default content", e);
+                existingData = jdbcTemplate.queryForObject("SELECT COUNT(0) FROM " + JPAConf.TABLE, Integer.class) > 0;
+            } catch (DataAccessException e) {
+                LOG.error("[{}] Could not access to table " + JPAConf.TABLE, entry.getKey(), e);
+                existingData = true;
             }
-            try {
-                createIndexes();
-                createViews();
-            } catch (IOException e) {
-                LOG.error("While creating indexes and views", e);
+
+            if (existingData) {
+                LOG.info("[{}] Data found in the database, leaving untouched", entry.getKey());
+            } else {
+                LOG.info("[{}] Empty database found, loading default content", entry.getKey());
+
+                try {
+                    ResourceWithFallbackLoader contentXML = ApplicationContextProvider.getBeanFactory().
+                            getBean(entry.getKey() + "ContentXML", ResourceWithFallbackLoader.class);
+                    loadDefaultContent(entry.getKey(), contentXML, entry.getValue());
+                } catch (Exception e) {
+                    LOG.error("[{}] While loading default content", entry.getKey(), e);
+                }
+                try {
+                    createIndexes(entry.getKey(), entry.getValue());
+                    createViews(entry.getKey(), entry.getValue());
+                } catch (IOException e) {
+                    LOG.error("[{}] While creating indexes and views", entry.getKey(), e);
+                }
             }
         }
     }
 
-    private void loadDefaultContent() throws Exception {
+    private void loadDefaultContent(
+            final String domain, final ResourceWithFallbackLoader contentXML, final DataSource dataSource)
+            throws Exception {
+
         SAXParserFactory factory = SAXParserFactory.newInstance();
         InputStream in = null;
         try {
@@ -86,9 +103,47 @@ public class XMLContentLoader extends AbstractContentDealer implements ContentLo
 
             SAXParser parser = factory.newSAXParser();
             parser.parse(in, new ContentLoaderHandler(dataSource, ROOT_ELEMENT));
-            LOG.debug("Default content successfully loaded");
+            LOG.debug("[{}] Default content successfully loaded", domain);
         } finally {
             IOUtils.closeQuietly(in);
         }
     }
+
+    private void createIndexes(final String domain, final DataSource dataSource) throws IOException {
+        LOG.debug("[{}] Creating indexes", domain);
+
+        JdbcTemplate jdbcTemplate = new JdbcTemplate(dataSource);
+
+        Properties indexes = PropertiesLoaderUtils.loadProperties(indexesXML.getResource());
+        for (String idx : indexes.stringPropertyNames()) {
+            LOG.debug("[{}] Creating index {}", domain, indexes.get(idx).toString());
+
+            try {
+                jdbcTemplate.execute(indexes.get(idx).toString());
+            } catch (DataAccessException e) {
+                LOG.error("[{}] Could not create index", domain, e);
+            }
+        }
+
+        LOG.debug("Indexes created");
+    }
+
+    private void createViews(final String domain, final DataSource dataSource) throws IOException {
+        LOG.debug("[{}] Creating views", domain);
+
+        JdbcTemplate jdbcTemplate = new JdbcTemplate(dataSource);
+
+        Properties views = PropertiesLoaderUtils.loadProperties(viewsXML.getResource());
+        for (String idx : views.stringPropertyNames()) {
+            LOG.debug("[{}] Creating view {}", domain, views.get(idx).toString());
+
+            try {
+                jdbcTemplate.execute(views.get(idx).toString().replaceAll("\\n", " "));
+            } catch (DataAccessException e) {
+                LOG.error("[{}] Could not create view", domain, e);
+            }
+        }
+
+        LOG.debug("Views created");
+    }
 }

http://git-wip-us.apache.org/repos/asf/syncope/blob/6dfedd8f/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/AbstractAnyDAO.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/AbstractAnyDAO.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/AbstractAnyDAO.java
index ef2161e..95f5b4e 100644
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/AbstractAnyDAO.java
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/AbstractAnyDAO.java
@@ -18,8 +18,6 @@
  */
 package org.apache.syncope.core.persistence.jpa.dao;
 
-import static org.apache.syncope.core.persistence.jpa.dao.AbstractDAO.LOG;
-
 import java.io.StringReader;
 import java.util.ArrayList;
 import java.util.Collections;
@@ -54,6 +52,7 @@ import org.apache.syncope.core.persistence.api.entity.resource.ExternalResource;
 import org.apache.syncope.core.persistence.api.entity.user.User;
 import org.apache.syncope.core.persistence.jpa.entity.AbstractPlainAttrValue;
 import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.transaction.annotation.Transactional;
 
 public abstract class AbstractAnyDAO<A extends Any<?, ?, ?>> extends AbstractDAO<A, Long> implements AnyDAO<A> {
 
@@ -81,6 +80,7 @@ public abstract class AbstractAnyDAO<A extends Any<?, ?, ?>> extends AbstractDAO
 
     protected abstract void securityChecks(A any);
 
+    @Transactional(readOnly = true)
     @Override
     public A authFind(final Long key) {
         if (key == null) {
@@ -98,16 +98,17 @@ public abstract class AbstractAnyDAO<A extends Any<?, ?, ?>> extends AbstractDAO
         return any;
     }
 
+    @Transactional(readOnly = true)
     @Override
     @SuppressWarnings("unchecked")
     public A find(final Long key) {
-        return (A) entityManager.find(getAnyUtils().anyClass(), key);
+        return (A) entityManager().find(getAnyUtils().anyClass(), key);
     }
 
     @SuppressWarnings("unchecked")
     @Override
     public A findByWorkflowId(final String workflowId) {
-        Query query = entityManager.createQuery("SELECT e FROM " + getAnyUtils().anyClass().getSimpleName()
+        Query query = entityManager().createQuery("SELECT e FROM " + getAnyUtils().anyClass().getSimpleName()
                 + " e WHERE e.workflowId = :workflowId", User.class);
         query.setParameter("workflowId", workflowId);
 
@@ -122,7 +123,7 @@ public abstract class AbstractAnyDAO<A extends Any<?, ?, ?>> extends AbstractDAO
     }
 
     private Query findByAttrValueQuery(final String entityName) {
-        return entityManager.createQuery("SELECT e FROM " + entityName + " e"
+        return entityManager().createQuery("SELECT e FROM " + entityName + " e"
                 + " WHERE e.attribute.schema.name = :schemaName AND (e.stringValue IS NOT NULL"
                 + " AND e.stringValue = :stringValue)"
                 + " OR (e.booleanValue IS NOT NULL AND e.booleanValue = :booleanValue)"
@@ -362,7 +363,7 @@ public abstract class AbstractAnyDAO<A extends Any<?, ?, ?>> extends AbstractDAO
             }
         }
 
-        Query query = entityManager.createNativeQuery(querystring.toString());
+        Query query = entityManager().createNativeQuery(querystring.toString());
 
         List<A> result = new ArrayList<>();
         for (Object anyKey : query.getResultList()) {
@@ -378,7 +379,7 @@ public abstract class AbstractAnyDAO<A extends Any<?, ?, ?>> extends AbstractDAO
     @SuppressWarnings("unchecked")
     @Override
     public List<A> findByResource(final ExternalResource resource) {
-        Query query = entityManager.createQuery(
+        Query query = entityManager().createQuery(
                 "SELECT e FROM " + getAnyUtils().anyClass().getSimpleName() + " e "
                 + "WHERE :resource MEMBER OF e.resources");
         query.setParameter("resource", resource);
@@ -414,7 +415,7 @@ public abstract class AbstractAnyDAO<A extends Any<?, ?, ?>> extends AbstractDAO
 
     @Override
     public A save(final A any) {
-        A merged = entityManager.merge(any);
+        A merged = entityManager().merge(any);
         for (VirAttr<?> virAttr : merged.getVirAttrs()) {
             virAttr.getValues().clear();
             virAttr.getValues().addAll(any.getVirAttr(virAttr.getSchema().getKey()).getValues());

http://git-wip-us.apache.org/repos/asf/syncope/blob/6dfedd8f/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/AbstractDAO.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/AbstractDAO.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/AbstractDAO.java
index f4916c7..e5c1d66 100644
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/AbstractDAO.java
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/AbstractDAO.java
@@ -20,17 +20,16 @@ package org.apache.syncope.core.persistence.jpa.dao;
 
 import java.util.List;
 import javax.persistence.EntityManager;
-import javax.persistence.PersistenceContext;
-import javax.persistence.PersistenceContextType;
 import org.apache.commons.lang3.StringUtils;
-import org.apache.syncope.common.lib.SyncopeConstants;
+import org.apache.syncope.core.misc.security.AuthContextUtils;
+import org.apache.syncope.core.misc.spring.ApplicationContextProvider;
 import org.apache.syncope.core.persistence.api.dao.DAO;
 import org.apache.syncope.core.persistence.api.dao.search.OrderByClause;
 import org.apache.syncope.core.persistence.api.entity.Entity;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.springframework.beans.factory.annotation.Configurable;
-import org.springframework.beans.factory.annotation.Value;
+import org.springframework.orm.jpa.EntityManagerFactoryUtils;
 import org.springframework.util.ReflectionUtils;
 
 @Configurable
@@ -38,9 +37,16 @@ public abstract class AbstractDAO<E extends Entity<KEY>, KEY> implements DAO<E,
 
     protected static final Logger LOG = LoggerFactory.getLogger(DAO.class);
 
-    @Value("#{entityManager}")
-    @PersistenceContext(type = PersistenceContextType.TRANSACTION)
-    protected EntityManager entityManager;
+    protected EntityManager entityManager() {
+        EntityManager entityManager = EntityManagerFactoryUtils.getTransactionalEntityManager(
+                EntityManagerFactoryUtils.findEntityManagerFactory(
+                        ApplicationContextProvider.getBeanFactory(), AuthContextUtils.getDomain()));
+        if (entityManager == null) {
+            throw new IllegalStateException("Could not find EntityManager for domain " + AuthContextUtils.getDomain());
+        }
+
+        return entityManager;
+    }
 
     protected String toOrderByStatement(final Class<? extends Entity<KEY>> beanClass, final String prefix,
             final List<OrderByClause> orderByClauses) {
@@ -64,27 +70,22 @@ public abstract class AbstractDAO<E extends Entity<KEY>, KEY> implements DAO<E,
     }
 
     @Override
-    public String getDomain(final E entity) {
-        return SyncopeConstants.MASTER_DOMAIN;
-    }
-
-    @Override
     public void refresh(final E entity) {
-        entityManager.refresh(entity);
+        entityManager().refresh(entity);
     }
 
     @Override
     public void detach(final E entity) {
-        entityManager.detach(entity);
+        entityManager().detach(entity);
     }
 
     @Override
     public void flush() {
-        entityManager.flush();
+        entityManager().flush();
     }
 
     @Override
     public void clear() {
-        entityManager.clear();
+        entityManager().clear();
     }
 }

http://git-wip-us.apache.org/repos/asf/syncope/blob/6dfedd8f/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAAnyObjectDAO.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAAnyObjectDAO.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAAnyObjectDAO.java
index 968f990..75b903d 100644
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAAnyObjectDAO.java
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAAnyObjectDAO.java
@@ -99,7 +99,7 @@ public class JPAAnyObjectDAO extends AbstractAnyDAO<AnyObject> implements AnyObj
 
     @Override
     public List<ARelationship> findARelationships(final AnyObject anyObject) {
-        TypedQuery<ARelationship> query = entityManager.createQuery(
+        TypedQuery<ARelationship> query = entityManager().createQuery(
                 "SELECT e FROM " + JPAARelationship.class.getSimpleName()
                 + " e WHERE e.rightEnd=:anyObject", ARelationship.class);
         query.setParameter("anyObject", anyObject);
@@ -109,7 +109,7 @@ public class JPAAnyObjectDAO extends AbstractAnyDAO<AnyObject> implements AnyObj
 
     @Override
     public List<URelationship> findURelationships(final AnyObject anyObject) {
-        TypedQuery<URelationship> query = entityManager.createQuery(
+        TypedQuery<URelationship> query = entityManager().createQuery(
                 "SELECT e FROM " + JPAURelationship.class.getSimpleName()
                 + " e WHERE e.rightEnd=:anyObject", URelationship.class);
         query.setParameter("anyObject", anyObject);
@@ -132,13 +132,13 @@ public class JPAAnyObjectDAO extends AbstractAnyDAO<AnyObject> implements AnyObj
             group.getADynMembership().remove(any);
         }
 
-        entityManager.remove(any);
+        entityManager().remove(any);
     }
 
     @Transactional(propagation = Propagation.REQUIRES_NEW, readOnly = true)
     @Override
     public List<Group> findDynGroupMemberships(final AnyObject anyObject) {
-        TypedQuery<Group> query = entityManager.createQuery(
+        TypedQuery<Group> query = entityManager().createQuery(
                 "SELECT e.group FROM " + JPAADynGroupMembership.class.getSimpleName()
                 + " e WHERE :anyObject MEMBER OF e.anyObjects", Group.class);
         query.setParameter("anyObject", anyObject);

http://git-wip-us.apache.org/repos/asf/syncope/blob/6dfedd8f/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAAnySearchDAO.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAAnySearchDAO.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAAnySearchDAO.java
index e0eae6a..2b422eb 100644
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAAnySearchDAO.java
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAAnySearchDAO.java
@@ -143,7 +143,7 @@ public class JPAAnySearchDAO extends AbstractDAO<Any<?, ?, ?>, Long> implements
         queryString.insert(0, "SELECT COUNT(any_id) FROM (");
         queryString.append(") count_any_id");
 
-        Query countQuery = entityManager.createNativeQuery(queryString.toString());
+        Query countQuery = entityManager().createNativeQuery(queryString.toString());
         fillWithParameters(countQuery, parameters);
 
         return ((Number) countQuery.getSingleResult()).intValue();
@@ -208,7 +208,7 @@ public class JPAAnySearchDAO extends AbstractDAO<Any<?, ?, ?>, Long> implements
             queryString.append(") u WHERE any_id=?").append(setParameter(parameters, any.getKey()));
 
             // 3. prepare the search query
-            Query query = entityManager.createNativeQuery(queryString.toString());
+            Query query = entityManager().createNativeQuery(queryString.toString());
 
             // 4. populate the search query with parameter values
             fillWithParameters(query, parameters);
@@ -371,7 +371,7 @@ public class JPAAnySearchDAO extends AbstractDAO<Any<?, ?, ?>, Long> implements
                 append(buildOrderBy(orderBySupport));
 
         // 3. prepare the search query
-        Query query = entityManager.createNativeQuery(queryString.toString());
+        Query query = entityManager().createNativeQuery(queryString.toString());
 
         // 4. page starts from 1, while setFirtResult() starts from 0
         query.setFirstResult(itemsPerPage * (page <= 0 ? 0 : page - 1));

http://git-wip-us.apache.org/repos/asf/syncope/blob/6dfedd8f/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAAnyTypeClassDAO.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAAnyTypeClassDAO.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAAnyTypeClassDAO.java
index 58b547d..9a01442 100644
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAAnyTypeClassDAO.java
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAAnyTypeClassDAO.java
@@ -51,19 +51,19 @@ public class JPAAnyTypeClassDAO extends AbstractDAO<AnyTypeClass, String> implem
 
     @Override
     public AnyTypeClass find(final String key) {
-        return entityManager.find(JPAAnyTypeClass.class, key);
+        return entityManager().find(JPAAnyTypeClass.class, key);
     }
 
     @Override
     public List<AnyTypeClass> findAll() {
-        TypedQuery<AnyTypeClass> query = entityManager.createQuery(
+        TypedQuery<AnyTypeClass> query = entityManager().createQuery(
                 "SELECT e FROM " + JPAAnyTypeClass.class.getSimpleName() + " e ", AnyTypeClass.class);
         return query.getResultList();
     }
 
     @Override
     public AnyTypeClass save(final AnyTypeClass anyTypeClass) {
-        AnyTypeClass merge = entityManager.merge(anyTypeClass);
+        AnyTypeClass merge = entityManager().merge(anyTypeClass);
 
         for (PlainSchema schema : merge.getPlainSchemas()) {
             schema.setAnyTypeClass(merge);
@@ -99,7 +99,7 @@ public class JPAAnyTypeClassDAO extends AbstractDAO<AnyTypeClass, String> implem
             type.remove(anyTypeClass);
         }
 
-        entityManager.remove(anyTypeClass);
+        entityManager().remove(anyTypeClass);
     }
 
 }

http://git-wip-us.apache.org/repos/asf/syncope/blob/6dfedd8f/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAAnyTypeDAO.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAAnyTypeDAO.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAAnyTypeDAO.java
index 4342811..cf87a3b 100644
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAAnyTypeDAO.java
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAAnyTypeDAO.java
@@ -32,7 +32,7 @@ public class JPAAnyTypeDAO extends AbstractDAO<AnyType, String> implements AnyTy
 
     @Override
     public AnyType find(final String key) {
-        return entityManager.find(JPAAnyType.class, key);
+        return entityManager().find(JPAAnyType.class, key);
     }
 
     @Override
@@ -50,7 +50,7 @@ public class JPAAnyTypeDAO extends AbstractDAO<AnyType, String> implements AnyTy
                 append(JPAAnyType.class.getSimpleName()).
                 append(" e WHERE :anyTypeClass MEMBER OF e.classes");
 
-        TypedQuery<AnyType> query = entityManager.createQuery(queryString.toString(), AnyType.class);
+        TypedQuery<AnyType> query = entityManager().createQuery(queryString.toString(), AnyType.class);
         query.setParameter("anyTypeClass", anyTypeClass);
 
         return query.getResultList();
@@ -58,14 +58,14 @@ public class JPAAnyTypeDAO extends AbstractDAO<AnyType, String> implements AnyTy
 
     @Override
     public List<AnyType> findAll() {
-        TypedQuery<AnyType> query = entityManager.createQuery(
+        TypedQuery<AnyType> query = entityManager().createQuery(
                 "SELECT e FROM " + JPAAnyType.class.getSimpleName() + " e ", AnyType.class);
         return query.getResultList();
     }
 
     @Override
     public AnyType save(final AnyType anyType) {
-        return entityManager.merge(anyType);
+        return entityManager().merge(anyType);
     }
 
     @Override
@@ -79,7 +79,7 @@ public class JPAAnyTypeDAO extends AbstractDAO<AnyType, String> implements AnyTy
             throw new IllegalArgumentException(key + " cannot be deleted");
         }
 
-        entityManager.remove(anyType);
+        entityManager().remove(anyType);
     }
 
 }

http://git-wip-us.apache.org/repos/asf/syncope/blob/6dfedd8f/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAConfDAO.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAConfDAO.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAConfDAO.java
index 7045a1a..4afe78e 100644
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAConfDAO.java
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAConfDAO.java
@@ -42,12 +42,12 @@ public class JPAConfDAO extends AbstractDAO<Conf, Long> implements ConfDAO {
 
     @Override
     public Conf get() {
-        Conf instance = entityManager.find(JPAConf.class, 1L);
+        Conf instance = entityManager().find(JPAConf.class, 1L);
         if (instance == null) {
             instance = new JPAConf();
             instance.setKey(1L);
 
-            instance = entityManager.merge(instance);
+            instance = entityManager().merge(instance);
         }
 
         return instance;
@@ -97,7 +97,7 @@ public class JPAConfDAO extends AbstractDAO<Conf, Long> implements ConfDAO {
         instance.add(attr);
         attr.setOwner(instance);
 
-        return entityManager.merge(instance);
+        return entityManager().merge(instance);
     }
 
     @Override
@@ -106,7 +106,7 @@ public class JPAConfDAO extends AbstractDAO<Conf, Long> implements ConfDAO {
         CPlainAttr attr = instance.getPlainAttr(key);
         if (attr != null) {
             instance.remove(attr);
-            instance = entityManager.merge(instance);
+            instance = entityManager().merge(instance);
         }
 
         return instance;

http://git-wip-us.apache.org/repos/asf/syncope/blob/6dfedd8f/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAConnInstanceDAO.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAConnInstanceDAO.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAConnInstanceDAO.java
index 453c363..eb027e9 100644
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAConnInstanceDAO.java
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAConnInstanceDAO.java
@@ -44,19 +44,19 @@ public class JPAConnInstanceDAO extends AbstractDAO<ConnInstance, Long> implemen
 
     @Override
     public ConnInstance find(final Long key) {
-        return entityManager.find(JPAConnInstance.class, key);
+        return entityManager().find(JPAConnInstance.class, key);
     }
 
     @Override
     public List<ConnInstance> findAll() {
-        TypedQuery<ConnInstance> query = entityManager.createQuery(
+        TypedQuery<ConnInstance> query = entityManager().createQuery(
                 "SELECT e FROM " + JPAConnInstance.class.getSimpleName() + " e", ConnInstance.class);
         return query.getResultList();
     }
 
     @Override
     public ConnInstance save(final ConnInstance connector) {
-        final ConnInstance merged = entityManager.merge(connector);
+        final ConnInstance merged = entityManager().merge(connector);
 
         for (ExternalResource resource : merged.getResources()) {
             try {
@@ -86,7 +86,7 @@ public class JPAConnInstanceDAO extends AbstractDAO<ConnInstance, Long> implemen
 
                 });
 
-        entityManager.remove(connInstance);
+        entityManager().remove(connInstance);
 
         connRegistry.unregisterConnector(key.toString());
     }

http://git-wip-us.apache.org/repos/asf/syncope/blob/6dfedd8f/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPADerAttrDAO.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPADerAttrDAO.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPADerAttrDAO.java
index 2162898..8dff203 100644
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPADerAttrDAO.java
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPADerAttrDAO.java
@@ -49,19 +49,19 @@ public class JPADerAttrDAO extends AbstractDAO<DerAttr<?>, Long> implements DerA
 
     @Override
     public <T extends DerAttr<?>> T find(final Long key, final Class<T> reference) {
-        return reference.cast(entityManager.find(getJPAEntityReference(reference), key));
+        return reference.cast(entityManager().find(getJPAEntityReference(reference), key));
     }
 
     @Override
     public <T extends DerAttr<?>> List<T> findAll(final Class<T> reference) {
-        TypedQuery<T> query = entityManager.createQuery(
+        TypedQuery<T> query = entityManager().createQuery(
                 "SELECT e FROM " + getJPAEntityReference(reference).getSimpleName() + " e", reference);
         return query.getResultList();
     }
 
     @Override
     public <T extends DerAttr<?>> T save(final T derAttr) {
-        return entityManager.merge(derAttr);
+        return entityManager().merge(derAttr);
     }
 
     @Override
@@ -81,6 +81,6 @@ public class JPADerAttrDAO extends AbstractDAO<DerAttr<?>, Long> implements DerA
             ((Any<?, T, ?>) derAttr.getOwner()).remove(derAttr);
         }
 
-        entityManager.remove(derAttr);
+        entityManager().remove(derAttr);
     }
 }

http://git-wip-us.apache.org/repos/asf/syncope/blob/6dfedd8f/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPADerSchemaDAO.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPADerSchemaDAO.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPADerSchemaDAO.java
index 18b6636..4ed17ca 100644
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPADerSchemaDAO.java
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPADerSchemaDAO.java
@@ -45,7 +45,7 @@ public class JPADerSchemaDAO extends AbstractDAO<DerSchema, String> implements D
 
     @Override
     public DerSchema find(final String key) {
-        return entityManager.find(JPADerSchema.class, key);
+        return entityManager().find(JPADerSchema.class, key);
     }
 
     @Override
@@ -54,7 +54,7 @@ public class JPADerSchemaDAO extends AbstractDAO<DerSchema, String> implements D
                 append(JPADerSchema.class.getSimpleName()).
                 append(" e WHERE e.anyTypeClass=:anyTypeClass");
 
-        TypedQuery<DerSchema> query = entityManager.createQuery(queryString.toString(), DerSchema.class);
+        TypedQuery<DerSchema> query = entityManager().createQuery(queryString.toString(), DerSchema.class);
         query.setParameter("anyTypeClass", anyTypeClass);
 
         return query.getResultList();
@@ -62,7 +62,7 @@ public class JPADerSchemaDAO extends AbstractDAO<DerSchema, String> implements D
 
     @Override
     public List<DerSchema> findAll() {
-        TypedQuery<DerSchema> query = entityManager.createQuery(
+        TypedQuery<DerSchema> query = entityManager().createQuery(
                 "SELECT e FROM " + JPADerSchema.class.getSimpleName() + " e", DerSchema.class);
         return query.getResultList();
     }
@@ -73,7 +73,7 @@ public class JPADerSchemaDAO extends AbstractDAO<DerSchema, String> implements D
                 append(((JPADerAttrDAO) derAttrDAO).getJPAEntityReference(reference).getSimpleName()).
                 append(" e WHERE e.schema=:schema");
 
-        TypedQuery<T> query = entityManager.createQuery(queryString.toString(), reference);
+        TypedQuery<T> query = entityManager().createQuery(queryString.toString(), reference);
         query.setParameter("schema", schema);
 
         return query.getResultList();
@@ -81,7 +81,7 @@ public class JPADerSchemaDAO extends AbstractDAO<DerSchema, String> implements D
 
     @Override
     public DerSchema save(final DerSchema derSchema) {
-        return entityManager.merge(derSchema);
+        return entityManager().merge(derSchema);
     }
 
     @Override
@@ -106,6 +106,6 @@ public class JPADerSchemaDAO extends AbstractDAO<DerSchema, String> implements D
             schema.getAnyTypeClass().remove(schema);
         }
 
-        entityManager.remove(schema);
+        entityManager().remove(schema);
     }
 }

http://git-wip-us.apache.org/repos/asf/syncope/blob/6dfedd8f/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPADomainDAO.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPADomainDAO.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPADomainDAO.java
index 37a4cd2..b3bb188 100644
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPADomainDAO.java
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPADomainDAO.java
@@ -30,19 +30,19 @@ public class JPADomainDAO extends AbstractDAO<Domain, String> implements DomainD
 
     @Override
     public Domain find(final String key) {
-        return entityManager.find(JPADomain.class, key);
+        return entityManager().find(JPADomain.class, key);
     }
 
     @Override
     public List<Domain> findAll() {
-        TypedQuery<Domain> query = entityManager.createQuery(
+        TypedQuery<Domain> query = entityManager().createQuery(
                 "SELECT e FROM " + JPADomain.class.getSimpleName() + " e ", Domain.class);
         return query.getResultList();
     }
 
     @Override
     public Domain save(final Domain anyTypeClass) {
-        return entityManager.merge(anyTypeClass);
+        return entityManager().merge(anyTypeClass);
     }
 
     @Override
@@ -52,6 +52,6 @@ public class JPADomainDAO extends AbstractDAO<Domain, String> implements DomainD
             return;
         }
 
-        entityManager.remove(domain);
+        entityManager().remove(domain);
     }
 }

http://git-wip-us.apache.org/repos/asf/syncope/blob/6dfedd8f/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAExternalResourceDAO.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAExternalResourceDAO.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAExternalResourceDAO.java
index 17553a2..4a8a759 100644
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAExternalResourceDAO.java
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAExternalResourceDAO.java
@@ -71,7 +71,7 @@ public class JPAExternalResourceDAO extends AbstractDAO<ExternalResource, String
 
     @Override
     public ExternalResource find(final String name) {
-        return entityManager.find(JPAExternalResource.class, name);
+        return entityManager().find(JPAExternalResource.class, name);
     }
 
     private StringBuilder getByPolicyQuery(final PolicyType type) {
@@ -99,7 +99,7 @@ public class JPAExternalResourceDAO extends AbstractDAO<ExternalResource, String
 
     @Override
     public List<ExternalResource> findByPolicy(final Policy policy) {
-        TypedQuery<ExternalResource> query = entityManager.createQuery(
+        TypedQuery<ExternalResource> query = entityManager().createQuery(
                 getByPolicyQuery(policy.getType()).append(" = :policy").toString(), ExternalResource.class);
         query.setParameter("policy", policy);
         return query.getResultList();
@@ -107,21 +107,21 @@ public class JPAExternalResourceDAO extends AbstractDAO<ExternalResource, String
 
     @Override
     public List<ExternalResource> findWithoutPolicy(final PolicyType type) {
-        TypedQuery<ExternalResource> query = entityManager.createQuery(
+        TypedQuery<ExternalResource> query = entityManager().createQuery(
                 getByPolicyQuery(type).append(" IS NULL").toString(), ExternalResource.class);
         return query.getResultList();
     }
 
     @Override
     public List<ExternalResource> findAll() {
-        TypedQuery<ExternalResource> query = entityManager.createQuery(
+        TypedQuery<ExternalResource> query = entityManager().createQuery(
                 "SELECT e FROM  " + JPAExternalResource.class.getSimpleName() + " e", ExternalResource.class);
         return query.getResultList();
     }
 
     @Override
     public List<ExternalResource> findAllByPriority() {
-        TypedQuery<ExternalResource> query = entityManager.createQuery(
+        TypedQuery<ExternalResource> query = entityManager().createQuery(
                 "SELECT e FROM  " + JPAExternalResource.class.getSimpleName() + " e ORDER BY e.propagationPriority",
                 ExternalResource.class);
         return query.getResultList();
@@ -138,7 +138,7 @@ public class JPAExternalResourceDAO extends AbstractDAO<ExternalResource, String
     @Override
     @Transactional(rollbackFor = { Throwable.class })
     public ExternalResource save(final ExternalResource resource) {
-        ExternalResource merged = entityManager.merge(resource);
+        ExternalResource merged = entityManager().merge(resource);
         try {
             connRegistry.registerConnector(merged);
         } catch (NotFoundException e) {
@@ -154,7 +154,7 @@ public class JPAExternalResourceDAO extends AbstractDAO<ExternalResource, String
             return;
         }
 
-        TypedQuery<MappingItem> query = entityManager.createQuery(
+        TypedQuery<MappingItem> query = entityManager().createQuery(
                 "SELECT m FROM " + JPAMappingItem.class.getSimpleName()
                 + " m WHERE m.intAttrName=:intAttrName AND m.intMappingType=:intMappingType", MappingItem.class);
         query.setParameter("intAttrName", intAttrName);
@@ -165,18 +165,18 @@ public class JPAExternalResourceDAO extends AbstractDAO<ExternalResource, String
             itemKeys.add(item.getKey());
         }
         for (Long itemKey : itemKeys) {
-            MappingItem item = entityManager.find(JPAMappingItem.class, itemKey);
+            MappingItem item = entityManager().find(JPAMappingItem.class, itemKey);
             if (item != null) {
                 item.getMapping().remove(item);
                 item.setMapping(null);
 
-                entityManager.remove(item);
+                entityManager().remove(item);
             }
         }
 
         // Make empty query cache for *MappingItem and related *Mapping
-        entityManager.getEntityManagerFactory().getCache().evict(JPAMappingItem.class);
-        entityManager.getEntityManagerFactory().getCache().evict(JPAMapping.class);
+        entityManager().getEntityManagerFactory().getCache().evict(JPAMappingItem.class);
+        entityManager().getEntityManagerFactory().getCache().evict(JPAMapping.class);
     }
 
     @Override
@@ -219,6 +219,6 @@ public class JPAExternalResourceDAO extends AbstractDAO<ExternalResource, String
             provision.setResource(null);
         }
 
-        entityManager.remove(resource);
+        entityManager().remove(resource);
     }
 }

http://git-wip-us.apache.org/repos/asf/syncope/blob/6dfedd8f/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAGroupDAO.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAGroupDAO.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAGroupDAO.java
index 22ce79e..368ea07 100644
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAGroupDAO.java
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAGroupDAO.java
@@ -88,7 +88,7 @@ public class JPAGroupDAO extends AbstractAnyDAO<Group> implements GroupDAO {
 
     @Override
     public Group find(final String name) {
-        TypedQuery<Group> query = entityManager.createQuery(
+        TypedQuery<Group> query = entityManager().createQuery(
                 "SELECT e FROM " + JPAGroup.class.getSimpleName() + " e WHERE e.name = :name", Group.class);
         query.setParameter("name", name);
 
@@ -116,7 +116,7 @@ public class JPAGroupDAO extends AbstractAnyDAO<Group> implements GroupDAO {
             queryString.append("OR e.groupOwner.id=").append(groupKey).append(' ');
         }
 
-        TypedQuery<Group> query = entityManager.createQuery(queryString.toString(), Group.class);
+        TypedQuery<Group> query = entityManager().createQuery(queryString.toString(), Group.class);
         query.setParameter("owner", owner);
 
         return query.getResultList();
@@ -133,7 +133,7 @@ public class JPAGroupDAO extends AbstractAnyDAO<Group> implements GroupDAO {
         StringBuilder queryString = new StringBuilder("SELECT e FROM ").append(JPAGroup.class.getSimpleName()).
                 append(" e WHERE e.groupOwner=:owner ");
 
-        TypedQuery<Group> query = entityManager.createQuery(queryString.toString(), Group.class);
+        TypedQuery<Group> query = entityManager().createQuery(queryString.toString(), Group.class);
         query.setParameter("owner", owner);
 
         return query.getResultList();
@@ -141,7 +141,7 @@ public class JPAGroupDAO extends AbstractAnyDAO<Group> implements GroupDAO {
 
     @Override
     public List<AMembership> findAMemberships(final Group group) {
-        TypedQuery<AMembership> query = entityManager.createQuery(
+        TypedQuery<AMembership> query = entityManager().createQuery(
                 "SELECT e FROM " + JPAAMembership.class.getSimpleName()
                 + " e WHERE e.rightEnd=:group", AMembership.class);
         query.setParameter("group", group);
@@ -151,7 +151,7 @@ public class JPAGroupDAO extends AbstractAnyDAO<Group> implements GroupDAO {
 
     @Override
     public List<UMembership> findUMemberships(final Group group) {
-        TypedQuery<UMembership> query = entityManager.createQuery(
+        TypedQuery<UMembership> query = entityManager().createQuery(
                 "SELECT e FROM " + JPAUMembership.class.getSimpleName()
                 + " e WHERE e.rightEnd=:group", UMembership.class);
         query.setParameter("group", group);
@@ -190,16 +190,16 @@ public class JPAGroupDAO extends AbstractAnyDAO<Group> implements GroupDAO {
             membership.getLeftEnd().remove(membership);
             anyObjectDAO.save(membership.getLeftEnd());
 
-            entityManager.remove(membership);
+            entityManager().remove(membership);
         }
         for (UMembership membership : findUMemberships(group)) {
             membership.getLeftEnd().remove(membership);
             userDAO.save(membership.getLeftEnd());
 
-            entityManager.remove(membership);
+            entityManager().remove(membership);
         }
 
-        entityManager.remove(group);
+        entityManager().remove(group);
     }
 
     private void populateTransitiveResources(

http://git-wip-us.apache.org/repos/asf/syncope/blob/6dfedd8f/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPALoggerDAO.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPALoggerDAO.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPALoggerDAO.java
index 327149f..9189e2a 100644
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPALoggerDAO.java
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPALoggerDAO.java
@@ -32,12 +32,12 @@ public class JPALoggerDAO extends AbstractDAO<Logger, String> implements LoggerD
 
     @Override
     public Logger find(final String key) {
-        return entityManager.find(JPALogger.class, key);
+        return entityManager().find(JPALogger.class, key);
     }
 
     @Override
     public List<Logger> findAll(final LoggerType type) {
-        TypedQuery<Logger> query = entityManager.createQuery(
+        TypedQuery<Logger> query = entityManager().createQuery(
                 "SELECT e FROM " + JPALogger.class.getSimpleName() + " e WHERE e.type=:type", Logger.class);
         query.setParameter("type", type);
         return query.getResultList();
@@ -49,12 +49,12 @@ public class JPALoggerDAO extends AbstractDAO<Logger, String> implements LoggerD
         if (LoggerType.AUDIT == logger.getType() && LoggerLevel.OFF != logger.getLevel()) {
             logger.setLevel(LoggerLevel.DEBUG);
         }
-        return entityManager.merge(logger);
+        return entityManager().merge(logger);
     }
 
     @Override
     public void delete(final Logger logger) {
-        entityManager.remove(logger);
+        entityManager().remove(logger);
     }
 
     @Override

http://git-wip-us.apache.org/repos/asf/syncope/blob/6dfedd8f/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPANotificationDAO.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPANotificationDAO.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPANotificationDAO.java
index b3b4b01..a43cf22 100644
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPANotificationDAO.java
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPANotificationDAO.java
@@ -30,23 +30,23 @@ public class JPANotificationDAO extends AbstractDAO<Notification, Long> implemen
 
     @Override
     public Notification find(final Long key) {
-        return entityManager.find(JPANotification.class, key);
+        return entityManager().find(JPANotification.class, key);
     }
 
     @Override
     public List<Notification> findAll() {
-        TypedQuery<Notification> query = entityManager.createQuery(
+        TypedQuery<Notification> query = entityManager().createQuery(
                 "SELECT e FROM " + JPANotification.class.getSimpleName() + " e", Notification.class);
         return query.getResultList();
     }
 
     @Override
     public Notification save(final Notification notification) {
-        return entityManager.merge(notification);
+        return entityManager().merge(notification);
     }
 
     @Override
     public void delete(final Long key) {
-        entityManager.remove(find(key));
+        entityManager().remove(find(key));
     }
 }

http://git-wip-us.apache.org/repos/asf/syncope/blob/6dfedd8f/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAPlainAttrDAO.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAPlainAttrDAO.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAPlainAttrDAO.java
index 5e232fd..d21d1f3 100644
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAPlainAttrDAO.java
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAPlainAttrDAO.java
@@ -51,7 +51,7 @@ public class JPAPlainAttrDAO extends AbstractDAO<PlainAttr<?>, Long> implements
 
     @Override
     public <T extends PlainAttr<?>> T find(final Long key, final Class<T> reference) {
-        return reference.cast(entityManager.find(getJPAEntityReference(reference), key));
+        return reference.cast(entityManager().find(getJPAEntityReference(reference), key));
     }
 
     @Override
@@ -71,6 +71,6 @@ public class JPAPlainAttrDAO extends AbstractDAO<PlainAttr<?>, Long> implements
             ((Any<T, ?, ?>) plainAttr.getOwner()).remove(plainAttr);
         }
 
-        entityManager.remove(plainAttr);
+        entityManager().remove(plainAttr);
     }
 }

http://git-wip-us.apache.org/repos/asf/syncope/blob/6dfedd8f/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAPlainAttrValueDAO.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAPlainAttrValueDAO.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAPlainAttrValueDAO.java
index 655decd..be2965c 100644
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAPlainAttrValueDAO.java
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAPlainAttrValueDAO.java
@@ -68,19 +68,19 @@ public class JPAPlainAttrValueDAO extends AbstractDAO<PlainAttrValue, Long> impl
 
     @Override
     public <T extends PlainAttrValue> T find(final Long key, final Class<T> reference) {
-        return reference.cast(entityManager.find(getJPAEntityReference(reference), key));
+        return reference.cast(entityManager().find(getJPAEntityReference(reference), key));
     }
 
     @Override
     public <T extends PlainAttrValue> List<T> findAll(final Class<T> reference) {
-        TypedQuery<T> query = entityManager.createQuery(
+        TypedQuery<T> query = entityManager().createQuery(
                 "SELECT e FROM " + getJPAEntityReference(reference).getSimpleName() + " e", reference);
         return query.getResultList();
     }
 
     @Override
     public <T extends PlainAttrValue> T save(final T attributeValue) {
-        return entityManager.merge(attributeValue);
+        return entityManager().merge(attributeValue);
     }
 
     @Override
@@ -99,6 +99,6 @@ public class JPAPlainAttrValueDAO extends AbstractDAO<PlainAttrValue, Long> impl
             attrValue.getAttr().remove(attrValue);
         }
 
-        entityManager.remove(attrValue);
+        entityManager().remove(attrValue);
     }
 }

http://git-wip-us.apache.org/repos/asf/syncope/blob/6dfedd8f/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAPlainSchemaDAO.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAPlainSchemaDAO.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAPlainSchemaDAO.java
index c3c94ce..47e8fe3 100644
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAPlainSchemaDAO.java
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAPlainSchemaDAO.java
@@ -45,7 +45,7 @@ public class JPAPlainSchemaDAO extends AbstractDAO<PlainSchema, String> implemen
 
     @Override
     public PlainSchema find(final String key) {
-        return entityManager.find(JPAPlainSchema.class, key);
+        return entityManager().find(JPAPlainSchema.class, key);
     }
 
     @Override
@@ -54,7 +54,7 @@ public class JPAPlainSchemaDAO extends AbstractDAO<PlainSchema, String> implemen
                 append(JPAPlainSchema.class.getSimpleName()).
                 append(" e WHERE e.anyTypeClass=:anyTypeClass");
 
-        TypedQuery<PlainSchema> query = entityManager.createQuery(queryString.toString(), PlainSchema.class);
+        TypedQuery<PlainSchema> query = entityManager().createQuery(queryString.toString(), PlainSchema.class);
         query.setParameter("anyTypeClass", anyTypeClass);
 
         return query.getResultList();
@@ -62,7 +62,7 @@ public class JPAPlainSchemaDAO extends AbstractDAO<PlainSchema, String> implemen
 
     @Override
     public List<PlainSchema> findAll() {
-        TypedQuery<PlainSchema> query = entityManager.createQuery(
+        TypedQuery<PlainSchema> query = entityManager().createQuery(
                 "SELECT e FROM " + JPAPlainSchema.class.getSimpleName() + " e", PlainSchema.class);
         return query.getResultList();
     }
@@ -73,7 +73,7 @@ public class JPAPlainSchemaDAO extends AbstractDAO<PlainSchema, String> implemen
                 append(((JPAPlainAttrDAO) plainAttrDAO).getJPAEntityReference(reference).getSimpleName()).
                 append(" e WHERE e.schema=:schema");
 
-        TypedQuery<T> query = entityManager.createQuery(queryString.toString(), reference);
+        TypedQuery<T> query = entityManager().createQuery(queryString.toString(), reference);
         query.setParameter("schema", schema);
 
         return query.getResultList();
@@ -81,7 +81,7 @@ public class JPAPlainSchemaDAO extends AbstractDAO<PlainSchema, String> implemen
 
     @Override
     public PlainSchema save(final PlainSchema schema) {
-        return entityManager.merge(schema);
+        return entityManager().merge(schema);
     }
 
     @Override
@@ -106,6 +106,6 @@ public class JPAPlainSchemaDAO extends AbstractDAO<PlainSchema, String> implemen
             schema.getAnyTypeClass().remove(schema);
         }
 
-        entityManager.remove(schema);
+        entityManager().remove(schema);
     }
 }

http://git-wip-us.apache.org/repos/asf/syncope/blob/6dfedd8f/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAPolicyDAO.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAPolicyDAO.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAPolicyDAO.java
index 176cfbd..ab0a8c5 100644
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAPolicyDAO.java
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAPolicyDAO.java
@@ -43,7 +43,7 @@ public class JPAPolicyDAO extends AbstractDAO<Policy, Long> implements PolicyDAO
     @Override
     @SuppressWarnings("unchecked")
     public <T extends Policy> T find(final Long key) {
-        final Query query = entityManager.createQuery(
+        final Query query = entityManager().createQuery(
                 "SELECT e FROM " + JPAPolicy.class.getSimpleName() + " e WHERE e.id=:id");
         query.setParameter("id", key);
 
@@ -56,7 +56,7 @@ public class JPAPolicyDAO extends AbstractDAO<Policy, Long> implements PolicyDAO
     @Override
     @SuppressWarnings("unchecked")
     public <T extends Policy> List<T> find(final PolicyType type) {
-        final Query query = entityManager.createQuery(
+        final Query query = entityManager().createQuery(
                 "SELECT e FROM " + JPAPolicy.class.getSimpleName() + " e WHERE e.type=:type");
         query.setParameter("type", type);
 
@@ -65,7 +65,7 @@ public class JPAPolicyDAO extends AbstractDAO<Policy, Long> implements PolicyDAO
 
     @Override
     public List<AccountPolicy> findByResource(final ExternalResource resource) {
-        TypedQuery<AccountPolicy> query = entityManager.createQuery(
+        TypedQuery<AccountPolicy> query = entityManager().createQuery(
                 "SELECT e FROM " + JPAAccountPolicy.class.getSimpleName() + " e "
                 + "WHERE :resource MEMBER OF e.resources", AccountPolicy.class);
         query.setParameter("resource", resource);
@@ -75,14 +75,14 @@ public class JPAPolicyDAO extends AbstractDAO<Policy, Long> implements PolicyDAO
 
     @Override
     public List<Policy> findAll() {
-        TypedQuery<Policy> query = entityManager.createQuery(
+        TypedQuery<Policy> query = entityManager().createQuery(
                 "SELECT e FROM " + JPAPolicy.class.getSimpleName() + " e", Policy.class);
         return query.getResultList();
     }
 
     @Override
     public <T extends Policy> T save(final T policy) {
-        return entityManager.merge(policy);
+        return entityManager().merge(policy);
     }
 
     @Override
@@ -95,6 +95,6 @@ public class JPAPolicyDAO extends AbstractDAO<Policy, Long> implements PolicyDAO
             }
         }
 
-        entityManager.remove(policy);
+        entityManager().remove(policy);
     }
 }

http://git-wip-us.apache.org/repos/asf/syncope/blob/6dfedd8f/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPARealmDAO.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPARealmDAO.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPARealmDAO.java
index f5625ee..36ce550 100644
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPARealmDAO.java
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPARealmDAO.java
@@ -50,7 +50,7 @@ public class JPARealmDAO extends AbstractDAO<Realm, Long> implements RealmDAO {
 
     @Override
     public Realm getRoot() {
-        TypedQuery<Realm> query = entityManager.createQuery(
+        TypedQuery<Realm> query = entityManager().createQuery(
                 "SELECT e FROM " + JPARealm.class.getSimpleName() + " e WHERE e.parent IS NULL", Realm.class);
 
         Realm result = null;
@@ -65,7 +65,7 @@ public class JPARealmDAO extends AbstractDAO<Realm, Long> implements RealmDAO {
 
     @Override
     public Realm find(final Long key) {
-        return entityManager.find(JPARealm.class, key);
+        return entityManager().find(JPARealm.class, key);
     }
 
     @Override
@@ -126,7 +126,7 @@ public class JPARealmDAO extends AbstractDAO<Realm, Long> implements RealmDAO {
                 append(JPARealm.class.getSimpleName()).append(" e WHERE e.").
                 append(policy instanceof AccountPolicy ? "accountPolicy" : "passwordPolicy").append("=:policy");
 
-        TypedQuery<Realm> query = entityManager.createQuery(queryString.toString(), Realm.class);
+        TypedQuery<Realm> query = entityManager().createQuery(queryString.toString(), Realm.class);
         query.setParameter("policy", policy);
 
         List<Realm> result = new ArrayList<>();
@@ -154,7 +154,7 @@ public class JPARealmDAO extends AbstractDAO<Realm, Long> implements RealmDAO {
 
     @Override
     public List<Realm> findChildren(final Realm realm) {
-        TypedQuery<Realm> query = entityManager.createQuery(
+        TypedQuery<Realm> query = entityManager().createQuery(
                 "SELECT e FROM " + JPARealm.class.getSimpleName() + " e WHERE e.parent=:realm", Realm.class);
         query.setParameter("realm", realm);
 
@@ -180,14 +180,14 @@ public class JPARealmDAO extends AbstractDAO<Realm, Long> implements RealmDAO {
 
     @Override
     public List<Realm> findAll() {
-        TypedQuery<Realm> query = entityManager.createQuery(
+        TypedQuery<Realm> query = entityManager().createQuery(
                 "SELECT e FROM " + JPARealm.class.getSimpleName() + " e ", Realm.class);
         return query.getResultList();
     }
 
     @Override
     public Realm save(final Realm realm) {
-        return entityManager.merge(realm);
+        return entityManager().merge(realm);
     }
 
     @Override
@@ -199,7 +199,7 @@ public class JPARealmDAO extends AbstractDAO<Realm, Long> implements RealmDAO {
 
             toBeDeleted.setParent(null);
 
-            entityManager.remove(toBeDeleted);
+            entityManager().remove(toBeDeleted);
         }
     }
 

http://git-wip-us.apache.org/repos/asf/syncope/blob/6dfedd8f/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPARelationshipTypeDAO.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPARelationshipTypeDAO.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPARelationshipTypeDAO.java
index 37ce107..5eb3951 100644
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPARelationshipTypeDAO.java
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPARelationshipTypeDAO.java
@@ -39,27 +39,27 @@ public class JPARelationshipTypeDAO extends AbstractDAO<RelationshipType, String
 
     @Override
     public RelationshipType find(final String key) {
-        return entityManager.find(JPARelationshipType.class, key);
+        return entityManager().find(JPARelationshipType.class, key);
     }
 
     @Override
     public List<RelationshipType> findAll() {
-        TypedQuery<RelationshipType> query = entityManager.createQuery(
+        TypedQuery<RelationshipType> query = entityManager().createQuery(
                 "SELECT e FROM " + JPARelationshipType.class.getSimpleName() + " e ", RelationshipType.class);
         return query.getResultList();
     }
 
     @Override
     public RelationshipType save(final RelationshipType anyType) {
-        return entityManager.merge(anyType);
+        return entityManager().merge(anyType);
     }
 
     private Collection<? extends Relationship<?, ?>> findRelationshipsByType(final RelationshipType type) {
-        TypedQuery<ARelationship> aquery = entityManager.createQuery(
+        TypedQuery<ARelationship> aquery = entityManager().createQuery(
                 "SELECT e FROM " + JPAARelationship.class.getSimpleName() + " e WHERE e.type=:type",
                 ARelationship.class);
         aquery.setParameter("type", type);
-        TypedQuery<URelationship> uquery = entityManager.createQuery(
+        TypedQuery<URelationship> uquery = entityManager().createQuery(
                 "SELECT e FROM " + JPAURelationship.class.getSimpleName() + " e WHERE e.type=:type",
                 URelationship.class);
         uquery.setParameter("type", type);
@@ -86,10 +86,10 @@ public class JPARelationshipTypeDAO extends AbstractDAO<RelationshipType, String
             }
 
             relationship.setLeftEnd(null);
-            entityManager.remove(relationship);
+            entityManager().remove(relationship);
         }
 
-        entityManager.remove(type);
+        entityManager().remove(type);
     }
 
 }


[06/31] syncope git commit: [SYNCOPE-652] Fixing test execution

Posted by md...@apache.org.
[SYNCOPE-652] Fixing test execution


Project: http://git-wip-us.apache.org/repos/asf/syncope/repo
Commit: http://git-wip-us.apache.org/repos/asf/syncope/commit/554b7259
Tree: http://git-wip-us.apache.org/repos/asf/syncope/tree/554b7259
Diff: http://git-wip-us.apache.org/repos/asf/syncope/diff/554b7259

Branch: refs/heads/SYNCOPE-156
Commit: 554b7259f23b1172453f3a78278109b15bc3d992
Parents: 74aed4a
Author: Francesco Chicchiriccò <il...@apache.org>
Authored: Thu Aug 13 16:18:20 2015 +0200
Committer: Francesco Chicchiriccò <il...@apache.org>
Committed: Thu Aug 13 17:16:51 2015 +0200

----------------------------------------------------------------------
 .../org/apache/syncope/core/logic/DomainLogic.java |  2 +-
 .../syncope/fit/core/reference/DomainITCase.java   | 17 ++++++++++-------
 2 files changed, 11 insertions(+), 8 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/syncope/blob/554b7259/core/logic/src/main/java/org/apache/syncope/core/logic/DomainLogic.java
----------------------------------------------------------------------
diff --git a/core/logic/src/main/java/org/apache/syncope/core/logic/DomainLogic.java b/core/logic/src/main/java/org/apache/syncope/core/logic/DomainLogic.java
index c946fb1..e95f70b 100644
--- a/core/logic/src/main/java/org/apache/syncope/core/logic/DomainLogic.java
+++ b/core/logic/src/main/java/org/apache/syncope/core/logic/DomainLogic.java
@@ -76,7 +76,7 @@ public class DomainLogic extends AbstractTransactionalLogic<DomainTO> {
             + "T(org.apache.syncope.common.lib.SyncopeConstants).MASTER_DOMAIN")
     public DomainTO create(final DomainTO domainTO) {
         if (!domainsHolder.getDomains().keySet().contains(domainTO.getKey())) {
-            throw new NotFoundException("No configuration is available for domain '" + domainTO.getKey());
+            throw new NotFoundException("No configuration is available for domain " + domainTO.getKey());
         }
 
         return binder.getDomainTO(domainDAO.save(binder.create(domainTO)));

http://git-wip-us.apache.org/repos/asf/syncope/blob/554b7259/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/DomainITCase.java
----------------------------------------------------------------------
diff --git a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/DomainITCase.java b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/DomainITCase.java
index e6b1984..51d4aaf 100644
--- a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/DomainITCase.java
+++ b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/DomainITCase.java
@@ -25,7 +25,6 @@ import static org.junit.Assert.fail;
 
 import java.security.AccessControlException;
 import java.util.List;
-import org.apache.commons.lang3.SerializationUtils;
 import org.apache.syncope.client.lib.SyncopeClientFactoryBean;
 import org.apache.syncope.common.lib.SyncopeClientException;
 import org.apache.syncope.common.lib.to.DomainTO;
@@ -63,11 +62,18 @@ public class DomainITCase extends AbstractITCase {
         }
     }
 
+    private void restoreTwo() {
+        DomainTO two = new DomainTO();
+        two.setKey("Two");
+        two.setAdminCipherAlgorithm(CipherAlgorithm.SHA);
+        two.setAdminPwd("password2");
+        domainService.create(two);
+    }
+
     @Test
     public void update() {
         DomainTO two = domainService.read("Two");
         assertNotNull(two);
-        DomainTO origTwo = SerializationUtils.clone(two);
 
         try {
             // 1. change admin pwd for domain Two
@@ -87,8 +93,7 @@ public class DomainITCase extends AbstractITCase {
             new SyncopeClientFactoryBean().setAddress(ADDRESS).setDomain("Two").
                     create(ADMIN_UNAME, "password3").self();
         } finally {
-            // restore old password
-            domainService.create(origTwo);
+            restoreTwo();
         }
     }
 
@@ -107,9 +112,7 @@ public class DomainITCase extends AbstractITCase {
                 assertEquals(ClientExceptionType.NotFound, e.getType());
             }
         } finally {
-            // restore old password
-            two.setAdminPwd("password2");
-            domainService.create(two);
+            restoreTwo();
         }
     }
 }


[10/31] syncope git commit: [SYNCOPE-652] Still several things to refine, but it starts taking shape

Posted by md...@apache.org.
http://git-wip-us.apache.org/repos/asf/syncope/blob/6dfedd8f/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/sync/SyncJobDelegate.java
----------------------------------------------------------------------
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/sync/SyncJobDelegate.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/sync/SyncJobDelegate.java
new file mode 100644
index 0000000..245a74a
--- /dev/null
+++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/sync/SyncJobDelegate.java
@@ -0,0 +1,221 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.syncope.core.provisioning.java.sync;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+import org.apache.commons.lang3.StringUtils;
+import org.apache.syncope.common.lib.types.SyncPolicySpec;
+import org.apache.syncope.core.misc.spring.ApplicationContextProvider;
+import org.apache.syncope.core.persistence.api.dao.GroupDAO;
+import org.apache.syncope.core.persistence.api.dao.NotFoundException;
+import org.apache.syncope.core.persistence.api.dao.UserDAO;
+import org.apache.syncope.core.persistence.api.entity.group.Group;
+import org.apache.syncope.core.persistence.api.entity.resource.Provision;
+import org.apache.syncope.core.persistence.api.entity.task.ProvisioningTask;
+import org.apache.syncope.core.persistence.api.entity.task.SyncTask;
+import org.apache.syncope.core.provisioning.api.Connector;
+import org.apache.syncope.core.provisioning.api.sync.AnyObjectSyncResultHandler;
+import org.apache.syncope.core.provisioning.api.sync.GroupSyncResultHandler;
+import org.apache.syncope.core.provisioning.api.sync.ProvisioningProfile;
+import org.apache.syncope.core.provisioning.api.sync.SyncActions;
+import org.apache.syncope.core.provisioning.api.sync.UserSyncResultHandler;
+import org.identityconnectors.framework.common.objects.SyncResultsHandler;
+import org.identityconnectors.framework.common.objects.SyncToken;
+import org.quartz.JobExecutionException;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.support.AbstractBeanDefinition;
+
+public class SyncJobDelegate extends AbstractProvisioningJobDelegate<SyncTask> {
+
+    @Autowired
+    private UserDAO userDAO;
+
+    @Autowired
+    private GroupDAO groupDAO;
+
+    @Autowired
+    protected SyncUtils syncUtils;
+
+    protected void setGroupOwners(final GroupSyncResultHandler ghandler) {
+        for (Map.Entry<Long, String> entry : ghandler.getGroupOwnerMap().entrySet()) {
+            Group group = groupDAO.find(entry.getKey());
+            if (group == null) {
+                throw new NotFoundException("Group " + entry.getKey());
+            }
+
+            if (StringUtils.isBlank(entry.getValue())) {
+                group.setGroupOwner(null);
+                group.setUserOwner(null);
+            } else {
+                Long userKey = syncUtils.findMatchingAnyKey(
+                        anyTypeDAO.findUser(),
+                        entry.getValue(),
+                        ghandler.getProfile().getTask().getResource(),
+                        ghandler.getProfile().getConnector());
+
+                if (userKey == null) {
+                    Long groupKey = syncUtils.findMatchingAnyKey(
+                            anyTypeDAO.findGroup(),
+                            entry.getValue(),
+                            ghandler.getProfile().getTask().getResource(),
+                            ghandler.getProfile().getConnector());
+
+                    if (groupKey != null) {
+                        group.setGroupOwner(groupDAO.find(groupKey));
+                    }
+                } else {
+                    group.setUserOwner(userDAO.find(userKey));
+                }
+            }
+
+            groupDAO.save(group);
+        }
+    }
+
+    @Override
+    protected String doExecuteProvisioning(
+            final SyncTask syncTask,
+            final Connector connector,
+            final boolean dryRun) throws JobExecutionException {
+
+        LOG.debug("Executing sync on {}", syncTask.getResource());
+
+        List<SyncActions> actions = new ArrayList<>();
+        for (String className : syncTask.getActionsClassNames()) {
+            try {
+                Class<?> actionsClass = Class.forName(className);
+                SyncActions syncActions = (SyncActions) ApplicationContextProvider.getBeanFactory().
+                        createBean(actionsClass, AbstractBeanDefinition.AUTOWIRE_BY_TYPE, true);
+
+                actions.add(syncActions);
+            } catch (Exception e) {
+                LOG.info("Class '{}' not found", className, e);
+            }
+        }
+
+        ProvisioningProfile<SyncTask, SyncActions> profile = new ProvisioningProfile<>(connector, syncTask);
+        profile.getActions().addAll(actions);
+        profile.setDryRun(dryRun);
+        profile.setResAct(getSyncPolicySpec(syncTask).getConflictResolutionAction());
+
+        // Prepare handler for SyncDelta objects (any objects)
+        AnyObjectSyncResultHandler ahandler =
+                (AnyObjectSyncResultHandler) ApplicationContextProvider.getBeanFactory().
+                createBean(AnyObjectSyncResultHandlerImpl.class, AbstractBeanDefinition.AUTOWIRE_BY_NAME, false);
+        ahandler.setProfile(profile);
+
+        // Prepare handler for SyncDelta objects (users)
+        UserSyncResultHandler uhandler =
+                (UserSyncResultHandler) ApplicationContextProvider.getBeanFactory().
+                createBean(UserSyncResultHandlerImpl.class, AbstractBeanDefinition.AUTOWIRE_BY_NAME, false);
+        uhandler.setProfile(profile);
+
+        // Prepare handler for SyncDelta objects (groups)
+        GroupSyncResultHandler ghandler =
+                (GroupSyncResultHandler) ApplicationContextProvider.getBeanFactory().
+                createBean(GroupSyncResultHandlerImpl.class, AbstractBeanDefinition.AUTOWIRE_BY_NAME, false);
+        ghandler.setProfile(profile);
+
+        if (!profile.isDryRun()) {
+            for (SyncActions action : actions) {
+                action.beforeAll(profile);
+            }
+        }
+
+        for (Provision provision : syncTask.getResource().getProvisions()) {
+            if (provision.getMapping() != null) {
+                SyncResultsHandler handler;
+                switch (provision.getAnyType().getKind()) {
+                    case USER:
+                        handler = uhandler;
+                        break;
+
+                    case GROUP:
+                        handler = ghandler;
+                        break;
+
+                    case ANY_OBJECT:
+                    default:
+                        handler = ahandler;
+                }
+
+                try {
+                    SyncToken latestSyncToken = null;
+                    if (!syncTask.isFullReconciliation()) {
+                        latestSyncToken = connector.getLatestSyncToken(provision.getObjectClass());
+                    }
+
+                    if (syncTask.isFullReconciliation()) {
+                        connector.getAllObjects(provision.getObjectClass(), handler,
+                                connector.getOperationOptions(provision.getMapping().getItems()));
+                    } else {
+                        connector.sync(provision.getObjectClass(), provision.getSyncToken(), handler,
+                                connector.getOperationOptions(provision.getMapping().getItems()));
+                    }
+
+                    if (!dryRun && !syncTask.isFullReconciliation()) {
+                        try {
+                            provision.setSyncToken(latestSyncToken);
+                            resourceDAO.save(provision.getResource());
+                        } catch (Exception e) {
+                            throw new JobExecutionException("While updating SyncToken", e);
+                        }
+                    }
+                } catch (Throwable t) {
+                    throw new JobExecutionException("While syncing on connector", t);
+                }
+            }
+        }
+
+        try {
+            setGroupOwners(ghandler);
+        } catch (Exception e) {
+            LOG.error("While setting group owners", e);
+        }
+
+        if (!profile.isDryRun()) {
+            for (SyncActions action : actions) {
+                action.afterAll(profile);
+            }
+        }
+
+        String result = createReport(profile.getResults(), syncTask.getResource().getSyncTraceLevel(), dryRun);
+
+        LOG.debug("Sync result: {}", result);
+
+        return result;
+    }
+
+    private SyncPolicySpec getSyncPolicySpec(final ProvisioningTask task) {
+        SyncPolicySpec syncPolicySpec;
+
+        if (task instanceof SyncTask) {
+            syncPolicySpec = task.getResource().getSyncPolicy() == null
+                    ? null
+                    : task.getResource().getSyncPolicy().getSpecification(SyncPolicySpec.class);
+        } else {
+            syncPolicySpec = null;
+        }
+
+        // step required because the call <policy>.getSpecification() could return a null value
+        return syncPolicySpec == null ? new SyncPolicySpec() : syncPolicySpec;
+    }
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/6dfedd8f/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/sync/SyncJobImpl.java
----------------------------------------------------------------------
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/sync/SyncJobImpl.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/sync/SyncJobImpl.java
deleted file mode 100644
index c52c3cf..0000000
--- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/sync/SyncJobImpl.java
+++ /dev/null
@@ -1,212 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.syncope.core.provisioning.java.sync;
-
-import java.util.Map;
-import org.apache.commons.lang3.StringUtils;
-import org.apache.syncope.common.lib.mod.ReferenceMod;
-import org.apache.syncope.common.lib.mod.GroupMod;
-import org.apache.syncope.common.lib.types.SyncPolicySpec;
-import org.apache.syncope.core.persistence.api.entity.task.ProvisioningTask;
-import org.apache.syncope.core.persistence.api.entity.task.SyncTask;
-import org.apache.syncope.core.provisioning.api.Connector;
-import org.apache.syncope.core.provisioning.api.sync.ProvisioningProfile;
-import org.apache.syncope.core.provisioning.api.sync.SyncActions;
-import org.apache.syncope.core.misc.spring.ApplicationContextProvider;
-import org.apache.syncope.core.persistence.api.entity.resource.Provision;
-import org.apache.syncope.core.provisioning.api.job.SyncJob;
-import org.apache.syncope.core.provisioning.api.sync.AnyObjectSyncResultHandler;
-import org.apache.syncope.core.provisioning.api.sync.GroupSyncResultHandler;
-import org.apache.syncope.core.provisioning.api.sync.UserSyncResultHandler;
-import org.apache.syncope.core.workflow.api.GroupWorkflowAdapter;
-import org.identityconnectors.framework.common.objects.SyncResultsHandler;
-import org.identityconnectors.framework.common.objects.SyncToken;
-import org.quartz.JobExecutionException;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.beans.factory.support.AbstractBeanDefinition;
-
-/**
- * Job for executing synchronization (from external resource) tasks.
- *
- * @see AbstractProvisioningJob
- * @see SyncTask
- */
-public class SyncJobImpl extends AbstractProvisioningJob<SyncTask, SyncActions> implements SyncJob {
-
-    /**
-     * Group workflow adapter.
-     */
-    @Autowired
-    private GroupWorkflowAdapter gwfAdapter;
-
-    @Autowired
-    protected SyncUtils syncUtils;
-
-    protected void setGroupOwners(final GroupSyncResultHandler ghandler) {
-        for (Map.Entry<Long, String> entry : ghandler.getGroupOwnerMap().entrySet()) {
-            GroupMod groupMod = new GroupMod();
-            groupMod.setKey(entry.getKey());
-
-            if (StringUtils.isBlank(entry.getValue())) {
-                groupMod.setGroupOwner(null);
-                groupMod.setUserOwner(null);
-            } else {
-                Long userKey = syncUtils.findMatchingAnyKey(
-                        anyTypeDAO.findUser(),
-                        entry.getValue(),
-                        ghandler.getProfile().getTask().getResource(),
-                        ghandler.getProfile().getConnector());
-
-                if (userKey == null) {
-                    Long groupKey = syncUtils.findMatchingAnyKey(
-                            anyTypeDAO.findGroup(),
-                            entry.getValue(),
-                            ghandler.getProfile().getTask().getResource(),
-                            ghandler.getProfile().getConnector());
-
-                    if (groupKey != null) {
-                        groupMod.setGroupOwner(new ReferenceMod(groupKey));
-                    }
-                } else {
-                    groupMod.setUserOwner(new ReferenceMod(userKey));
-                }
-            }
-
-            gwfAdapter.update(groupMod);
-        }
-    }
-
-    @Override
-    protected String executeWithSecurityContext(
-            final SyncTask syncTask,
-            final Connector connector,
-            final boolean dryRun) throws JobExecutionException {
-
-        LOG.debug("Executing sync on {}", syncTask.getResource());
-
-        ProvisioningProfile<SyncTask, SyncActions> profile = new ProvisioningProfile<>(connector, syncTask);
-        if (actions != null) {
-            profile.getActions().addAll(actions);
-        }
-        profile.setDryRun(dryRun);
-        profile.setResAct(getSyncPolicySpec(syncTask).getConflictResolutionAction());
-
-        // Prepare handler for SyncDelta objects (any objects)
-        AnyObjectSyncResultHandler ahandler =
-                (AnyObjectSyncResultHandler) ApplicationContextProvider.getApplicationContext().getBeanFactory().
-                createBean(AnyObjectSyncResultHandlerImpl.class, AbstractBeanDefinition.AUTOWIRE_BY_NAME, false);
-        ahandler.setProfile(profile);
-
-        // Prepare handler for SyncDelta objects (users)
-        UserSyncResultHandler uhandler =
-                (UserSyncResultHandler) ApplicationContextProvider.getApplicationContext().getBeanFactory().
-                createBean(UserSyncResultHandlerImpl.class, AbstractBeanDefinition.AUTOWIRE_BY_NAME, false);
-        uhandler.setProfile(profile);
-
-        // Prepare handler for SyncDelta objects (groups)
-        GroupSyncResultHandler ghandler =
-                (GroupSyncResultHandler) ApplicationContextProvider.getApplicationContext().getBeanFactory().
-                createBean(GroupSyncResultHandlerImpl.class, AbstractBeanDefinition.AUTOWIRE_BY_NAME, false);
-        ghandler.setProfile(profile);
-
-        if (actions != null && !profile.isDryRun()) {
-            for (SyncActions action : actions) {
-                action.beforeAll(profile);
-            }
-        }
-
-        for (Provision provision : syncTask.getResource().getProvisions()) {
-            if (provision.getMapping() != null) {
-                SyncResultsHandler handler;
-                switch (provision.getAnyType().getKind()) {
-                    case USER:
-                        handler = uhandler;
-                        break;
-
-                    case GROUP:
-                        handler = ghandler;
-                        break;
-
-                    case ANY_OBJECT:
-                    default:
-                        handler = ahandler;
-                }
-
-                try {
-                    SyncToken latestSyncToken = null;
-                    if (!syncTask.isFullReconciliation()) {
-                        latestSyncToken = connector.getLatestSyncToken(provision.getObjectClass());
-                    }
-
-                    if (syncTask.isFullReconciliation()) {
-                        connector.getAllObjects(provision.getObjectClass(), handler,
-                                connector.getOperationOptions(provision.getMapping().getItems()));
-                    } else {
-                        connector.sync(provision.getObjectClass(), provision.getSyncToken(), handler,
-                                connector.getOperationOptions(provision.getMapping().getItems()));
-                    }
-
-                    if (!dryRun && !syncTask.isFullReconciliation()) {
-                        try {
-                            provision.setSyncToken(latestSyncToken);
-                            resourceDAO.save(provision.getResource());
-                        } catch (Exception e) {
-                            throw new JobExecutionException("While updating SyncToken", e);
-                        }
-                    }
-                } catch (Throwable t) {
-                    throw new JobExecutionException("While syncing on connector", t);
-                }
-            }
-        }
-
-        try {
-            setGroupOwners(ghandler);
-        } catch (Exception e) {
-            LOG.error("While setting group owners", e);
-        }
-
-        if (actions != null && !profile.isDryRun()) {
-            for (SyncActions action : actions) {
-                action.afterAll(profile);
-            }
-        }
-
-        String result = createReport(profile.getResults(), syncTask.getResource().getSyncTraceLevel(), dryRun);
-
-        LOG.debug("Sync result: {}", result);
-
-        return result;
-    }
-
-    private SyncPolicySpec getSyncPolicySpec(final ProvisioningTask task) {
-        SyncPolicySpec syncPolicySpec;
-
-        if (task instanceof SyncTask) {
-            syncPolicySpec = task.getResource().getSyncPolicy() == null
-                    ? null
-                    : task.getResource().getSyncPolicy().getSpecification(SyncPolicySpec.class);
-        } else {
-            syncPolicySpec = null;
-        }
-
-        // step required because the call <policy>.getSpecification() could return a null value
-        return syncPolicySpec == null ? new SyncPolicySpec() : syncPolicySpec;
-    }
-}

http://git-wip-us.apache.org/repos/asf/syncope/blob/6dfedd8f/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/sync/SyncUtils.java
----------------------------------------------------------------------
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/sync/SyncUtils.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/sync/SyncUtils.java
index c3d11a9..dc5cdf0 100644
--- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/sync/SyncUtils.java
+++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/sync/SyncUtils.java
@@ -64,7 +64,9 @@ import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Component;
+import org.springframework.transaction.annotation.Transactional;
 
+@Transactional(readOnly = true)
 @Component
 public class SyncUtils {
 

http://git-wip-us.apache.org/repos/asf/syncope/blob/6dfedd8f/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/sync/UserSyncResultHandlerImpl.java
----------------------------------------------------------------------
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/sync/UserSyncResultHandlerImpl.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/sync/UserSyncResultHandlerImpl.java
index d5c41db..20a3673 100644
--- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/sync/UserSyncResultHandlerImpl.java
+++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/sync/UserSyncResultHandlerImpl.java
@@ -107,12 +107,11 @@ public class UserSyncResultHandlerImpl extends AbstractSyncResultHandler impleme
             final Long key,
             final boolean unlink) {
 
-        taskExecutor.execute(
-                propagationManager.getUserDeleteTasks(
-                        key, Collections.singleton(profile.getTask().getResource().getKey())));
+        taskExecutor.execute(propagationManager.getUserDeleteTasks(
+                key, Collections.singleton(profile.getTask().getResource().getKey())));
 
         if (unlink) {
-            final UserMod userMod = new UserMod();
+            UserMod userMod = new UserMod();
             userMod.setKey(key);
             userMod.getResourcesToRemove().add(profile.getTask().getResource().getKey());
         }

http://git-wip-us.apache.org/repos/asf/syncope/blob/6dfedd8f/core/provisioning-java/src/main/resources/provisioning.properties
----------------------------------------------------------------------
diff --git a/core/provisioning-java/src/main/resources/provisioning.properties b/core/provisioning-java/src/main/resources/provisioning.properties
index af1dd4b..59e5916 100644
--- a/core/provisioning-java/src/main/resources/provisioning.properties
+++ b/core/provisioning-java/src/main/resources/provisioning.properties
@@ -18,3 +18,6 @@ userProvisioningManager=org.apache.syncope.core.provisioning.java.DefaultUserPro
 groupProvisioningManager=org.apache.syncope.core.provisioning.java.DefaultGroupProvisioningManager
 anyObjectProvisioningManager=org.apache.syncope.core.provisioning.java.DefaultAnyObjectProvisioningManager
 virAttrCache=org.apache.syncope.core.provisioning.java.cache.MemoryVirAttrCache
+
+quartz.jobstore=org.quartz.impl.jdbcjobstore.PostgreSQLDelegate
+quartz.sql=tables_postgres.sql

http://git-wip-us.apache.org/repos/asf/syncope/blob/6dfedd8f/core/provisioning-java/src/main/resources/provisioningContext.xml
----------------------------------------------------------------------
diff --git a/core/provisioning-java/src/main/resources/provisioningContext.xml b/core/provisioning-java/src/main/resources/provisioningContext.xml
index 32120f4..2f0f617 100644
--- a/core/provisioning-java/src/main/resources/provisioningContext.xml
+++ b/core/provisioning-java/src/main/resources/provisioningContext.xml
@@ -35,14 +35,33 @@ under the License.
   <bean class="${groupProvisioningManager}"/>
   <bean class="${anyObjectProvisioningManager}"/>
 
+  <bean id="quartzDataSourceInit" class="org.springframework.jdbc.datasource.init.DataSourceInitializer">
+    <property name="dataSource" ref="MasterDataSource"/>
+    <property name="enabled" value="true"/>
+    <property name="databasePopulator">
+      <bean class="org.springframework.jdbc.datasource.init.ResourceDatabasePopulator">
+        <property name="continueOnError" value="true"/>
+        <property name="ignoreFailedDrops" value="true"/>
+        <property name="sqlScriptEncoding" value="UTF-8"/>
+        <property name="scripts">
+          <array>
+            <value type="org.springframework.core.io.Resource">
+              classpath:/quartz/${quartz.sql}
+            </value>
+          </array>
+        </property>
+      </bean>
+    </property>
+  </bean>
+
   <bean id="scheduler" class="org.springframework.scheduling.quartz.SchedulerFactoryBean"
-        lazy-init="false" depends-on="nonJPAdbInitializer">
+        lazy-init="false" depends-on="quartzDataSourceInit">
     <property name="autoStartup" value="true"/>
     <property name="applicationContextSchedulerContextKey" value="applicationContext"/>
     <property name="waitForJobsToCompleteOnShutdown" value="true"/>
     <property name="overwriteExistingJobs" value="true"/>
-    <property name="dataSource" ref="dataSource"/>
-    <property name="transactionManager" ref="transactionManager"/>
+    <property name="dataSource" ref="MasterDataSource"/>
+    <property name="transactionManager" ref="MasterTransactionManager"/>
     <property name="jobFactory">
       <bean class="org.apache.syncope.core.provisioning.java.job.SpringBeanJobFactory"/>
     </property>
@@ -104,7 +123,7 @@ under the License.
     <constructor-arg index="1" value="true"/>
   </bean>
 
-  <bean id="connIdBundleManager" class="org.apache.syncope.core.provisioning.java.ConnIdBundleManagerImpl" scope="singleton">
+  <bean id="connIdBundleManager" class="org.apache.syncope.core.provisioning.java.ConnIdBundleManagerImpl">
     <property name="stringLocations" value="${connid.locations}"/>
   </bean>
 

http://git-wip-us.apache.org/repos/asf/syncope/blob/6dfedd8f/core/provisioning-java/src/main/resources/quartz/tables_h2.sql
----------------------------------------------------------------------
diff --git a/core/provisioning-java/src/main/resources/quartz/tables_h2.sql b/core/provisioning-java/src/main/resources/quartz/tables_h2.sql
new file mode 100644
index 0000000..e798223
--- /dev/null
+++ b/core/provisioning-java/src/main/resources/quartz/tables_h2.sql
@@ -0,0 +1,266 @@
+-- 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.
+
+-- Thanks to Amir Kibbar and Peter Rietzler for contributing the schema for H2 database, 
+-- and verifying that it works with Quartz's StdJDBCDelegate
+--
+-- Note, Quartz depends on row-level locking which means you must use the MVCC=TRUE 
+-- setting on your H2 database, or you will experience dead-locks
+--
+--
+-- In your Quartz properties file, you'll need to set 
+-- org.quartz.jobStore.driverDelegateClass = org.quartz.impl.jdbcjobstore.StdJDBCDelegate
+
+CREATE TABLE QRTZ_CALENDARS (
+  SCHED_NAME VARCHAR(120) NOT NULL,
+  CALENDAR_NAME VARCHAR (200)  NOT NULL ,
+  CALENDAR IMAGE NOT NULL
+);
+
+CREATE TABLE QRTZ_CRON_TRIGGERS (
+  SCHED_NAME VARCHAR(120) NOT NULL,
+  TRIGGER_NAME VARCHAR (200)  NOT NULL ,
+  TRIGGER_GROUP VARCHAR (200)  NOT NULL ,
+  CRON_EXPRESSION VARCHAR (120)  NOT NULL ,
+  TIME_ZONE_ID VARCHAR (80) 
+);
+
+CREATE TABLE QRTZ_FIRED_TRIGGERS (
+  SCHED_NAME VARCHAR(120) NOT NULL,
+  ENTRY_ID VARCHAR (95)  NOT NULL ,
+  TRIGGER_NAME VARCHAR (200)  NOT NULL ,
+  TRIGGER_GROUP VARCHAR (200)  NOT NULL ,
+  INSTANCE_NAME VARCHAR (200)  NOT NULL ,
+  FIRED_TIME BIGINT NOT NULL ,
+  SCHED_TIME BIGINT NOT NULL ,
+  PRIORITY INTEGER NOT NULL ,
+  STATE VARCHAR (16)  NOT NULL,
+  JOB_NAME VARCHAR (200)  NULL ,
+  JOB_GROUP VARCHAR (200)  NULL ,
+  IS_NONCONCURRENT BOOLEAN  NULL ,
+  REQUESTS_RECOVERY BOOLEAN  NULL 
+);
+
+CREATE TABLE QRTZ_PAUSED_TRIGGER_GRPS (
+  SCHED_NAME VARCHAR(120) NOT NULL,
+  TRIGGER_GROUP VARCHAR (200)  NOT NULL 
+);
+
+CREATE TABLE QRTZ_SCHEDULER_STATE (
+  SCHED_NAME VARCHAR(120) NOT NULL,
+  INSTANCE_NAME VARCHAR (200)  NOT NULL ,
+  LAST_CHECKIN_TIME BIGINT NOT NULL ,
+  CHECKIN_INTERVAL BIGINT NOT NULL
+);
+
+CREATE TABLE QRTZ_LOCKS (
+  SCHED_NAME VARCHAR(120) NOT NULL,
+  LOCK_NAME VARCHAR (40)  NOT NULL 
+);
+
+CREATE TABLE QRTZ_JOB_DETAILS (
+  SCHED_NAME VARCHAR(120) NOT NULL,
+  JOB_NAME VARCHAR (200)  NOT NULL ,
+  JOB_GROUP VARCHAR (200)  NOT NULL ,
+  DESCRIPTION VARCHAR (250) NULL ,
+  JOB_CLASS_NAME VARCHAR (250)  NOT NULL ,
+  IS_DURABLE BOOLEAN  NOT NULL ,
+  IS_NONCONCURRENT BOOLEAN  NOT NULL ,
+  IS_UPDATE_DATA BOOLEAN  NOT NULL ,
+  REQUESTS_RECOVERY BOOLEAN  NOT NULL ,
+  JOB_DATA IMAGE NULL
+);
+
+CREATE TABLE QRTZ_SIMPLE_TRIGGERS (
+  SCHED_NAME VARCHAR(120) NOT NULL,
+  TRIGGER_NAME VARCHAR (200)  NOT NULL ,
+  TRIGGER_GROUP VARCHAR (200)  NOT NULL ,
+  REPEAT_COUNT BIGINT NOT NULL ,
+  REPEAT_INTERVAL BIGINT NOT NULL ,
+  TIMES_TRIGGERED BIGINT NOT NULL
+);
+
+CREATE TABLE qrtz_simprop_triggers
+  (          
+    SCHED_NAME VARCHAR(120) NOT NULL,
+    TRIGGER_NAME VARCHAR(200) NOT NULL,
+    TRIGGER_GROUP VARCHAR(200) NOT NULL,
+    STR_PROP_1 VARCHAR(512) NULL,
+    STR_PROP_2 VARCHAR(512) NULL,
+    STR_PROP_3 VARCHAR(512) NULL,
+    INT_PROP_1 INTEGER NULL,
+    INT_PROP_2 INTEGER NULL,
+    LONG_PROP_1 BIGINT NULL,
+    LONG_PROP_2 BIGINT NULL,
+    DEC_PROP_1 NUMERIC(13,4) NULL,
+    DEC_PROP_2 NUMERIC(13,4) NULL,
+    BOOL_PROP_1 BOOLEAN NULL,
+    BOOL_PROP_2 BOOLEAN NULL,
+);
+
+CREATE TABLE QRTZ_BLOB_TRIGGERS (
+  SCHED_NAME VARCHAR(120) NOT NULL,
+  TRIGGER_NAME VARCHAR (200)  NOT NULL ,
+  TRIGGER_GROUP VARCHAR (200)  NOT NULL ,
+  BLOB_DATA IMAGE NULL
+);
+
+CREATE TABLE QRTZ_TRIGGERS (
+  SCHED_NAME VARCHAR(120) NOT NULL,
+  TRIGGER_NAME VARCHAR (200)  NOT NULL ,
+  TRIGGER_GROUP VARCHAR (200)  NOT NULL ,
+  JOB_NAME VARCHAR (200)  NOT NULL ,
+  JOB_GROUP VARCHAR (200)  NOT NULL ,
+  DESCRIPTION VARCHAR (250) NULL ,
+  NEXT_FIRE_TIME BIGINT NULL ,
+  PREV_FIRE_TIME BIGINT NULL ,
+  PRIORITY INTEGER NULL ,
+  TRIGGER_STATE VARCHAR (16)  NOT NULL ,
+  TRIGGER_TYPE VARCHAR (8)  NOT NULL ,
+  START_TIME BIGINT NOT NULL ,
+  END_TIME BIGINT NULL ,
+  CALENDAR_NAME VARCHAR (200)  NULL ,
+  MISFIRE_INSTR SMALLINT NULL ,
+  JOB_DATA IMAGE NULL
+);
+
+ALTER TABLE QRTZ_CALENDARS  ADD
+  CONSTRAINT PK_QRTZ_CALENDARS PRIMARY KEY  
+  (
+    SCHED_NAME,
+    CALENDAR_NAME
+  );
+
+ALTER TABLE QRTZ_CRON_TRIGGERS  ADD
+  CONSTRAINT PK_QRTZ_CRON_TRIGGERS PRIMARY KEY  
+  (
+    SCHED_NAME,
+    TRIGGER_NAME,
+    TRIGGER_GROUP
+  );
+
+ALTER TABLE QRTZ_FIRED_TRIGGERS  ADD
+  CONSTRAINT PK_QRTZ_FIRED_TRIGGERS PRIMARY KEY  
+  (
+    SCHED_NAME,
+    ENTRY_ID
+  );
+
+ALTER TABLE QRTZ_PAUSED_TRIGGER_GRPS  ADD
+  CONSTRAINT PK_QRTZ_PAUSED_TRIGGER_GRPS PRIMARY KEY  
+  (
+    SCHED_NAME,
+    TRIGGER_GROUP
+  );
+
+ALTER TABLE QRTZ_SCHEDULER_STATE  ADD
+  CONSTRAINT PK_QRTZ_SCHEDULER_STATE PRIMARY KEY  
+  (
+    SCHED_NAME,
+    INSTANCE_NAME
+  );
+
+ALTER TABLE QRTZ_LOCKS  ADD
+  CONSTRAINT PK_QRTZ_LOCKS PRIMARY KEY  
+  (
+    SCHED_NAME,
+    LOCK_NAME
+  );
+
+ALTER TABLE QRTZ_JOB_DETAILS  ADD
+  CONSTRAINT PK_QRTZ_JOB_DETAILS PRIMARY KEY  
+  (
+    SCHED_NAME,
+    JOB_NAME,
+    JOB_GROUP
+  );
+
+ALTER TABLE QRTZ_SIMPLE_TRIGGERS  ADD
+  CONSTRAINT PK_QRTZ_SIMPLE_TRIGGERS PRIMARY KEY  
+  (
+    SCHED_NAME,
+    TRIGGER_NAME,
+    TRIGGER_GROUP
+  );
+
+ALTER TABLE QRTZ_SIMPROP_TRIGGERS  ADD
+  CONSTRAINT PK_QRTZ_SIMPROP_TRIGGERS PRIMARY KEY  
+  (
+    SCHED_NAME,
+    TRIGGER_NAME,
+    TRIGGER_GROUP
+  );
+
+ALTER TABLE QRTZ_TRIGGERS  ADD
+  CONSTRAINT PK_QRTZ_TRIGGERS PRIMARY KEY  
+  (
+    SCHED_NAME,
+    TRIGGER_NAME,
+    TRIGGER_GROUP
+  );
+
+ALTER TABLE QRTZ_CRON_TRIGGERS ADD
+  CONSTRAINT FK_QRTZ_CRON_TRIGGERS_QRTZ_TRIGGERS FOREIGN KEY
+  (
+    SCHED_NAME,
+    TRIGGER_NAME,
+    TRIGGER_GROUP
+  ) REFERENCES QRTZ_TRIGGERS (
+    SCHED_NAME,
+    TRIGGER_NAME,
+    TRIGGER_GROUP
+  ) ON DELETE CASCADE;
+
+
+ALTER TABLE QRTZ_SIMPLE_TRIGGERS ADD
+  CONSTRAINT FK_QRTZ_SIMPLE_TRIGGERS_QRTZ_TRIGGERS FOREIGN KEY
+  (
+    SCHED_NAME,
+    TRIGGER_NAME,
+    TRIGGER_GROUP
+  ) REFERENCES QRTZ_TRIGGERS (
+    SCHED_NAME,
+    TRIGGER_NAME,
+    TRIGGER_GROUP
+  ) ON DELETE CASCADE;
+
+ALTER TABLE QRTZ_SIMPROP_TRIGGERS ADD
+  CONSTRAINT FK_QRTZ_SIMPROP_TRIGGERS_QRTZ_TRIGGERS FOREIGN KEY
+  (
+    SCHED_NAME,
+    TRIGGER_NAME,
+    TRIGGER_GROUP
+  ) REFERENCES QRTZ_TRIGGERS (
+    SCHED_NAME,
+    TRIGGER_NAME,
+    TRIGGER_GROUP
+  ) ON DELETE CASCADE;
+
+
+ALTER TABLE QRTZ_TRIGGERS ADD
+  CONSTRAINT FK_QRTZ_TRIGGERS_QRTZ_JOB_DETAILS FOREIGN KEY
+  (
+    SCHED_NAME,
+    JOB_NAME,
+    JOB_GROUP
+  ) REFERENCES QRTZ_JOB_DETAILS (
+    SCHED_NAME,
+    JOB_NAME,
+    JOB_GROUP
+  );
+  
+COMMIT;

http://git-wip-us.apache.org/repos/asf/syncope/blob/6dfedd8f/core/provisioning-java/src/main/resources/quartz/tables_mariadb.sql
----------------------------------------------------------------------
diff --git a/core/provisioning-java/src/main/resources/quartz/tables_mariadb.sql b/core/provisioning-java/src/main/resources/quartz/tables_mariadb.sql
new file mode 100644
index 0000000..ebb8e59
--- /dev/null
+++ b/core/provisioning-java/src/main/resources/quartz/tables_mariadb.sql
@@ -0,0 +1,206 @@
+-- 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.
+
+--
+-- Quartz seems to work best with the driver mm.mysql-2.0.7-bin.jar
+--
+-- PLEASE consider using mysql with innodb tables to avoid locking issues
+--
+-- In your Quartz properties file, you'll need to set 
+-- org.quartz.jobStore.driverDelegateClass = org.quartz.impl.jdbcjobstore.StdJDBCDelegate
+--
+
+BEGIN;
+DROP TABLE IF EXISTS QRTZ_FIRED_TRIGGERS;
+DROP TABLE IF EXISTS QRTZ_PAUSED_TRIGGER_GRPS;
+DROP TABLE IF EXISTS QRTZ_SCHEDULER_STATE;
+DROP TABLE IF EXISTS QRTZ_LOCKS;
+DROP TABLE IF EXISTS QRTZ_SIMPLE_TRIGGERS;
+DROP TABLE IF EXISTS QRTZ_SIMPROP_TRIGGERS;
+DROP TABLE IF EXISTS QRTZ_CRON_TRIGGERS;
+DROP TABLE IF EXISTS QRTZ_BLOB_TRIGGERS;
+DROP TABLE IF EXISTS QRTZ_TRIGGERS;
+DROP TABLE IF EXISTS QRTZ_JOB_DETAILS;
+DROP TABLE IF EXISTS QRTZ_CALENDARS;
+COMMIT;
+
+
+BEGIN;
+CREATE TABLE QRTZ_JOB_DETAILS
+  (
+    SCHED_NAME VARCHAR(120) NOT NULL,
+    JOB_NAME  VARCHAR(200) NOT NULL,
+    JOB_GROUP VARCHAR(200) NOT NULL,
+    DESCRIPTION VARCHAR(250) NULL,
+    JOB_CLASS_NAME   VARCHAR(250) NOT NULL,
+    IS_DURABLE VARCHAR(1) NOT NULL,
+    IS_NONCONCURRENT VARCHAR(1) NOT NULL,
+    IS_UPDATE_DATA VARCHAR(1) NOT NULL,
+    REQUESTS_RECOVERY VARCHAR(1) NOT NULL,
+    JOB_DATA BLOB NULL,
+    PRIMARY KEY (SCHED_NAME,JOB_NAME,JOB_GROUP)
+);
+COMMIT;
+
+BEGIN;
+CREATE TABLE QRTZ_TRIGGERS
+  (
+    SCHED_NAME VARCHAR(120) NOT NULL,
+    TRIGGER_NAME VARCHAR(200) NOT NULL,
+    TRIGGER_GROUP VARCHAR(200) NOT NULL,
+    JOB_NAME  VARCHAR(200) NOT NULL,
+    JOB_GROUP VARCHAR(200) NOT NULL,
+    DESCRIPTION VARCHAR(250) NULL,
+    NEXT_FIRE_TIME BIGINT(13) NULL,
+    PREV_FIRE_TIME BIGINT(13) NULL,
+    PRIORITY INTEGER NULL,
+    TRIGGER_STATE VARCHAR(16) NOT NULL,
+    TRIGGER_TYPE VARCHAR(8) NOT NULL,
+    START_TIME BIGINT(13) NOT NULL,
+    END_TIME BIGINT(13) NULL,
+    CALENDAR_NAME VARCHAR(200) NULL,
+    MISFIRE_INSTR SMALLINT(2) NULL,
+    JOB_DATA BLOB NULL,
+    PRIMARY KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP),
+    FOREIGN KEY (SCHED_NAME,JOB_NAME,JOB_GROUP)
+        REFERENCES QRTZ_JOB_DETAILS(SCHED_NAME,JOB_NAME,JOB_GROUP)
+);
+COMMIT;
+
+BEGIN;
+CREATE TABLE QRTZ_SIMPLE_TRIGGERS
+  (
+    SCHED_NAME VARCHAR(120) NOT NULL,
+    TRIGGER_NAME VARCHAR(200) NOT NULL,
+    TRIGGER_GROUP VARCHAR(200) NOT NULL,
+    REPEAT_COUNT BIGINT(7) NOT NULL,
+    REPEAT_INTERVAL BIGINT(12) NOT NULL,
+    TIMES_TRIGGERED BIGINT(10) NOT NULL,
+    PRIMARY KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP),
+    FOREIGN KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP)
+        REFERENCES QRTZ_TRIGGERS(SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP)
+);
+COMMIT;
+
+BEGIN;
+CREATE TABLE QRTZ_CRON_TRIGGERS
+  (
+    SCHED_NAME VARCHAR(120) NOT NULL,
+    TRIGGER_NAME VARCHAR(200) NOT NULL,
+    TRIGGER_GROUP VARCHAR(200) NOT NULL,
+    CRON_EXPRESSION VARCHAR(200) NOT NULL,
+    TIME_ZONE_ID VARCHAR(80),
+    PRIMARY KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP),
+    FOREIGN KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP)
+        REFERENCES QRTZ_TRIGGERS(SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP)
+);
+COMMIT;
+
+BEGIN;
+CREATE TABLE QRTZ_SIMPROP_TRIGGERS
+  (          
+    SCHED_NAME VARCHAR(120) NOT NULL,
+    TRIGGER_NAME VARCHAR(200) NOT NULL,
+    TRIGGER_GROUP VARCHAR(200) NOT NULL,
+    STR_PROP_1 VARCHAR(512) NULL,
+    STR_PROP_2 VARCHAR(512) NULL,
+    STR_PROP_3 VARCHAR(512) NULL,
+    INT_PROP_1 INT NULL,
+    INT_PROP_2 INT NULL,
+    LONG_PROP_1 BIGINT NULL,
+    LONG_PROP_2 BIGINT NULL,
+    DEC_PROP_1 NUMERIC(13,4) NULL,
+    DEC_PROP_2 NUMERIC(13,4) NULL,
+    BOOL_PROP_1 VARCHAR(1) NULL,
+    BOOL_PROP_2 VARCHAR(1) NULL,
+    PRIMARY KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP),
+    FOREIGN KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP) 
+    REFERENCES QRTZ_TRIGGERS(SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP)
+);
+COMMIT;
+
+BEGIN;
+CREATE TABLE QRTZ_BLOB_TRIGGERS
+  (
+    SCHED_NAME VARCHAR(120) NOT NULL,
+    TRIGGER_NAME VARCHAR(200) NOT NULL,
+    TRIGGER_GROUP VARCHAR(200) NOT NULL,
+    BLOB_DATA BLOB NULL,
+    PRIMARY KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP),
+    FOREIGN KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP)
+        REFERENCES QRTZ_TRIGGERS(SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP)
+);
+COMMIT;
+
+BEGIN;
+CREATE TABLE QRTZ_CALENDARS
+  (
+    SCHED_NAME VARCHAR(120) NOT NULL,
+    CALENDAR_NAME  VARCHAR(200) NOT NULL,
+    CALENDAR BLOB NOT NULL,
+    PRIMARY KEY (SCHED_NAME,CALENDAR_NAME)
+);
+COMMIT;
+
+BEGIN;
+CREATE TABLE QRTZ_PAUSED_TRIGGER_GRPS
+  (
+    SCHED_NAME VARCHAR(120) NOT NULL,
+    TRIGGER_GROUP  VARCHAR(200) NOT NULL, 
+    PRIMARY KEY (SCHED_NAME,TRIGGER_GROUP)
+);
+COMMIT;
+
+BEGIN;
+CREATE TABLE QRTZ_FIRED_TRIGGERS
+  (
+    SCHED_NAME VARCHAR(120) NOT NULL,
+    ENTRY_ID VARCHAR(95) NOT NULL,
+    TRIGGER_NAME VARCHAR(200) NOT NULL,
+    TRIGGER_GROUP VARCHAR(200) NOT NULL,
+    INSTANCE_NAME VARCHAR(200) NOT NULL,
+    FIRED_TIME BIGINT(13) NOT NULL,
+    SCHED_TIME BIGINT(13) NOT NULL,
+    PRIORITY INTEGER NOT NULL,
+    STATE VARCHAR(16) NOT NULL,
+    JOB_NAME VARCHAR(200) NULL,
+    JOB_GROUP VARCHAR(200) NULL,
+    IS_NONCONCURRENT VARCHAR(1) NULL,
+    REQUESTS_RECOVERY VARCHAR(1) NULL,
+    PRIMARY KEY (SCHED_NAME,ENTRY_ID)
+);
+COMMIT;
+
+BEGIN;
+CREATE TABLE QRTZ_SCHEDULER_STATE
+  (
+    SCHED_NAME VARCHAR(120) NOT NULL,
+    INSTANCE_NAME VARCHAR(200) NOT NULL,
+    LAST_CHECKIN_TIME BIGINT(13) NOT NULL,
+    CHECKIN_INTERVAL BIGINT(13) NOT NULL,
+    PRIMARY KEY (SCHED_NAME,INSTANCE_NAME)
+);
+COMMIT;
+
+BEGIN;
+CREATE TABLE QRTZ_LOCKS
+  (
+    SCHED_NAME VARCHAR(120) NOT NULL,
+    LOCK_NAME  VARCHAR(40) NOT NULL, 
+    PRIMARY KEY (SCHED_NAME,LOCK_NAME)
+);
+COMMIT;

http://git-wip-us.apache.org/repos/asf/syncope/blob/6dfedd8f/core/provisioning-java/src/main/resources/quartz/tables_mysql.sql
----------------------------------------------------------------------
diff --git a/core/provisioning-java/src/main/resources/quartz/tables_mysql.sql b/core/provisioning-java/src/main/resources/quartz/tables_mysql.sql
new file mode 100644
index 0000000..ebb8e59
--- /dev/null
+++ b/core/provisioning-java/src/main/resources/quartz/tables_mysql.sql
@@ -0,0 +1,206 @@
+-- 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.
+
+--
+-- Quartz seems to work best with the driver mm.mysql-2.0.7-bin.jar
+--
+-- PLEASE consider using mysql with innodb tables to avoid locking issues
+--
+-- In your Quartz properties file, you'll need to set 
+-- org.quartz.jobStore.driverDelegateClass = org.quartz.impl.jdbcjobstore.StdJDBCDelegate
+--
+
+BEGIN;
+DROP TABLE IF EXISTS QRTZ_FIRED_TRIGGERS;
+DROP TABLE IF EXISTS QRTZ_PAUSED_TRIGGER_GRPS;
+DROP TABLE IF EXISTS QRTZ_SCHEDULER_STATE;
+DROP TABLE IF EXISTS QRTZ_LOCKS;
+DROP TABLE IF EXISTS QRTZ_SIMPLE_TRIGGERS;
+DROP TABLE IF EXISTS QRTZ_SIMPROP_TRIGGERS;
+DROP TABLE IF EXISTS QRTZ_CRON_TRIGGERS;
+DROP TABLE IF EXISTS QRTZ_BLOB_TRIGGERS;
+DROP TABLE IF EXISTS QRTZ_TRIGGERS;
+DROP TABLE IF EXISTS QRTZ_JOB_DETAILS;
+DROP TABLE IF EXISTS QRTZ_CALENDARS;
+COMMIT;
+
+
+BEGIN;
+CREATE TABLE QRTZ_JOB_DETAILS
+  (
+    SCHED_NAME VARCHAR(120) NOT NULL,
+    JOB_NAME  VARCHAR(200) NOT NULL,
+    JOB_GROUP VARCHAR(200) NOT NULL,
+    DESCRIPTION VARCHAR(250) NULL,
+    JOB_CLASS_NAME   VARCHAR(250) NOT NULL,
+    IS_DURABLE VARCHAR(1) NOT NULL,
+    IS_NONCONCURRENT VARCHAR(1) NOT NULL,
+    IS_UPDATE_DATA VARCHAR(1) NOT NULL,
+    REQUESTS_RECOVERY VARCHAR(1) NOT NULL,
+    JOB_DATA BLOB NULL,
+    PRIMARY KEY (SCHED_NAME,JOB_NAME,JOB_GROUP)
+);
+COMMIT;
+
+BEGIN;
+CREATE TABLE QRTZ_TRIGGERS
+  (
+    SCHED_NAME VARCHAR(120) NOT NULL,
+    TRIGGER_NAME VARCHAR(200) NOT NULL,
+    TRIGGER_GROUP VARCHAR(200) NOT NULL,
+    JOB_NAME  VARCHAR(200) NOT NULL,
+    JOB_GROUP VARCHAR(200) NOT NULL,
+    DESCRIPTION VARCHAR(250) NULL,
+    NEXT_FIRE_TIME BIGINT(13) NULL,
+    PREV_FIRE_TIME BIGINT(13) NULL,
+    PRIORITY INTEGER NULL,
+    TRIGGER_STATE VARCHAR(16) NOT NULL,
+    TRIGGER_TYPE VARCHAR(8) NOT NULL,
+    START_TIME BIGINT(13) NOT NULL,
+    END_TIME BIGINT(13) NULL,
+    CALENDAR_NAME VARCHAR(200) NULL,
+    MISFIRE_INSTR SMALLINT(2) NULL,
+    JOB_DATA BLOB NULL,
+    PRIMARY KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP),
+    FOREIGN KEY (SCHED_NAME,JOB_NAME,JOB_GROUP)
+        REFERENCES QRTZ_JOB_DETAILS(SCHED_NAME,JOB_NAME,JOB_GROUP)
+);
+COMMIT;
+
+BEGIN;
+CREATE TABLE QRTZ_SIMPLE_TRIGGERS
+  (
+    SCHED_NAME VARCHAR(120) NOT NULL,
+    TRIGGER_NAME VARCHAR(200) NOT NULL,
+    TRIGGER_GROUP VARCHAR(200) NOT NULL,
+    REPEAT_COUNT BIGINT(7) NOT NULL,
+    REPEAT_INTERVAL BIGINT(12) NOT NULL,
+    TIMES_TRIGGERED BIGINT(10) NOT NULL,
+    PRIMARY KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP),
+    FOREIGN KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP)
+        REFERENCES QRTZ_TRIGGERS(SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP)
+);
+COMMIT;
+
+BEGIN;
+CREATE TABLE QRTZ_CRON_TRIGGERS
+  (
+    SCHED_NAME VARCHAR(120) NOT NULL,
+    TRIGGER_NAME VARCHAR(200) NOT NULL,
+    TRIGGER_GROUP VARCHAR(200) NOT NULL,
+    CRON_EXPRESSION VARCHAR(200) NOT NULL,
+    TIME_ZONE_ID VARCHAR(80),
+    PRIMARY KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP),
+    FOREIGN KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP)
+        REFERENCES QRTZ_TRIGGERS(SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP)
+);
+COMMIT;
+
+BEGIN;
+CREATE TABLE QRTZ_SIMPROP_TRIGGERS
+  (          
+    SCHED_NAME VARCHAR(120) NOT NULL,
+    TRIGGER_NAME VARCHAR(200) NOT NULL,
+    TRIGGER_GROUP VARCHAR(200) NOT NULL,
+    STR_PROP_1 VARCHAR(512) NULL,
+    STR_PROP_2 VARCHAR(512) NULL,
+    STR_PROP_3 VARCHAR(512) NULL,
+    INT_PROP_1 INT NULL,
+    INT_PROP_2 INT NULL,
+    LONG_PROP_1 BIGINT NULL,
+    LONG_PROP_2 BIGINT NULL,
+    DEC_PROP_1 NUMERIC(13,4) NULL,
+    DEC_PROP_2 NUMERIC(13,4) NULL,
+    BOOL_PROP_1 VARCHAR(1) NULL,
+    BOOL_PROP_2 VARCHAR(1) NULL,
+    PRIMARY KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP),
+    FOREIGN KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP) 
+    REFERENCES QRTZ_TRIGGERS(SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP)
+);
+COMMIT;
+
+BEGIN;
+CREATE TABLE QRTZ_BLOB_TRIGGERS
+  (
+    SCHED_NAME VARCHAR(120) NOT NULL,
+    TRIGGER_NAME VARCHAR(200) NOT NULL,
+    TRIGGER_GROUP VARCHAR(200) NOT NULL,
+    BLOB_DATA BLOB NULL,
+    PRIMARY KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP),
+    FOREIGN KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP)
+        REFERENCES QRTZ_TRIGGERS(SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP)
+);
+COMMIT;
+
+BEGIN;
+CREATE TABLE QRTZ_CALENDARS
+  (
+    SCHED_NAME VARCHAR(120) NOT NULL,
+    CALENDAR_NAME  VARCHAR(200) NOT NULL,
+    CALENDAR BLOB NOT NULL,
+    PRIMARY KEY (SCHED_NAME,CALENDAR_NAME)
+);
+COMMIT;
+
+BEGIN;
+CREATE TABLE QRTZ_PAUSED_TRIGGER_GRPS
+  (
+    SCHED_NAME VARCHAR(120) NOT NULL,
+    TRIGGER_GROUP  VARCHAR(200) NOT NULL, 
+    PRIMARY KEY (SCHED_NAME,TRIGGER_GROUP)
+);
+COMMIT;
+
+BEGIN;
+CREATE TABLE QRTZ_FIRED_TRIGGERS
+  (
+    SCHED_NAME VARCHAR(120) NOT NULL,
+    ENTRY_ID VARCHAR(95) NOT NULL,
+    TRIGGER_NAME VARCHAR(200) NOT NULL,
+    TRIGGER_GROUP VARCHAR(200) NOT NULL,
+    INSTANCE_NAME VARCHAR(200) NOT NULL,
+    FIRED_TIME BIGINT(13) NOT NULL,
+    SCHED_TIME BIGINT(13) NOT NULL,
+    PRIORITY INTEGER NOT NULL,
+    STATE VARCHAR(16) NOT NULL,
+    JOB_NAME VARCHAR(200) NULL,
+    JOB_GROUP VARCHAR(200) NULL,
+    IS_NONCONCURRENT VARCHAR(1) NULL,
+    REQUESTS_RECOVERY VARCHAR(1) NULL,
+    PRIMARY KEY (SCHED_NAME,ENTRY_ID)
+);
+COMMIT;
+
+BEGIN;
+CREATE TABLE QRTZ_SCHEDULER_STATE
+  (
+    SCHED_NAME VARCHAR(120) NOT NULL,
+    INSTANCE_NAME VARCHAR(200) NOT NULL,
+    LAST_CHECKIN_TIME BIGINT(13) NOT NULL,
+    CHECKIN_INTERVAL BIGINT(13) NOT NULL,
+    PRIMARY KEY (SCHED_NAME,INSTANCE_NAME)
+);
+COMMIT;
+
+BEGIN;
+CREATE TABLE QRTZ_LOCKS
+  (
+    SCHED_NAME VARCHAR(120) NOT NULL,
+    LOCK_NAME  VARCHAR(40) NOT NULL, 
+    PRIMARY KEY (SCHED_NAME,LOCK_NAME)
+);
+COMMIT;

http://git-wip-us.apache.org/repos/asf/syncope/blob/6dfedd8f/core/provisioning-java/src/main/resources/quartz/tables_mysql_innodb.sql
----------------------------------------------------------------------
diff --git a/core/provisioning-java/src/main/resources/quartz/tables_mysql_innodb.sql b/core/provisioning-java/src/main/resources/quartz/tables_mysql_innodb.sql
new file mode 100644
index 0000000..c54493e
--- /dev/null
+++ b/core/provisioning-java/src/main/resources/quartz/tables_mysql_innodb.sql
@@ -0,0 +1,221 @@
+-- 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.
+
+--
+-- In your Quartz properties file, you'll need to set 
+-- org.quartz.jobStore.driverDelegateClass = org.quartz.impl.jdbcjobstore.StdJDBCDelegate
+--
+--
+-- By: Ron Cordell - roncordell
+-- I didn't see this anywhere, so I thought I'd post it here. This is the script from Quartz to create the tables in a MySQL database, modified to use INNODB instead of MYISAM.
+--
+
+BEGIN;
+DROP TABLE IF EXISTS QRTZ_FIRED_TRIGGERS;
+DROP TABLE IF EXISTS QRTZ_PAUSED_TRIGGER_GRPS;
+DROP TABLE IF EXISTS QRTZ_SCHEDULER_STATE;
+DROP TABLE IF EXISTS QRTZ_LOCKS;
+DROP TABLE IF EXISTS QRTZ_SIMPLE_TRIGGERS;
+DROP TABLE IF EXISTS QRTZ_SIMPROP_TRIGGERS;
+DROP TABLE IF EXISTS QRTZ_CRON_TRIGGERS;
+DROP TABLE IF EXISTS QRTZ_BLOB_TRIGGERS;
+DROP TABLE IF EXISTS QRTZ_TRIGGERS;
+DROP TABLE IF EXISTS QRTZ_JOB_DETAILS;
+DROP TABLE IF EXISTS QRTZ_CALENDARS;
+COMMIT;
+
+BEGIN;
+CREATE TABLE QRTZ_JOB_DETAILS(
+SCHED_NAME VARCHAR(120) NOT NULL,
+JOB_NAME VARCHAR(200) NOT NULL,
+JOB_GROUP VARCHAR(200) NOT NULL,
+DESCRIPTION VARCHAR(250) NULL,
+JOB_CLASS_NAME VARCHAR(250) NOT NULL,
+IS_DURABLE VARCHAR(1) NOT NULL,
+IS_NONCONCURRENT VARCHAR(1) NOT NULL,
+IS_UPDATE_DATA VARCHAR(1) NOT NULL,
+REQUESTS_RECOVERY VARCHAR(1) NOT NULL,
+JOB_DATA BLOB NULL,
+PRIMARY KEY (SCHED_NAME,JOB_NAME,JOB_GROUP))
+ENGINE=InnoDB;
+COMMIT;
+
+BEGIN;
+CREATE TABLE QRTZ_TRIGGERS (
+SCHED_NAME VARCHAR(120) NOT NULL,
+TRIGGER_NAME VARCHAR(200) NOT NULL,
+TRIGGER_GROUP VARCHAR(200) NOT NULL,
+JOB_NAME VARCHAR(200) NOT NULL,
+JOB_GROUP VARCHAR(200) NOT NULL,
+DESCRIPTION VARCHAR(250) NULL,
+NEXT_FIRE_TIME BIGINT(13) NULL,
+PREV_FIRE_TIME BIGINT(13) NULL,
+PRIORITY INTEGER NULL,
+TRIGGER_STATE VARCHAR(16) NOT NULL,
+TRIGGER_TYPE VARCHAR(8) NOT NULL,
+START_TIME BIGINT(13) NOT NULL,
+END_TIME BIGINT(13) NULL,
+CALENDAR_NAME VARCHAR(200) NULL,
+MISFIRE_INSTR SMALLINT(2) NULL,
+JOB_DATA BLOB NULL,
+PRIMARY KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP),
+FOREIGN KEY (SCHED_NAME,JOB_NAME,JOB_GROUP)
+REFERENCES QRTZ_JOB_DETAILS(SCHED_NAME,JOB_NAME,JOB_GROUP))
+ENGINE=InnoDB;
+COMMIT;
+
+BEGIN;
+CREATE TABLE QRTZ_SIMPLE_TRIGGERS (
+SCHED_NAME VARCHAR(120) NOT NULL,
+TRIGGER_NAME VARCHAR(200) NOT NULL,
+TRIGGER_GROUP VARCHAR(200) NOT NULL,
+REPEAT_COUNT BIGINT(7) NOT NULL,
+REPEAT_INTERVAL BIGINT(12) NOT NULL,
+TIMES_TRIGGERED BIGINT(10) NOT NULL,
+PRIMARY KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP),
+FOREIGN KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP)
+REFERENCES QRTZ_TRIGGERS(SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP))
+ENGINE=InnoDB;
+COMMIT;
+
+BEGIN;
+CREATE TABLE QRTZ_CRON_TRIGGERS (
+SCHED_NAME VARCHAR(120) NOT NULL,
+TRIGGER_NAME VARCHAR(200) NOT NULL,
+TRIGGER_GROUP VARCHAR(200) NOT NULL,
+CRON_EXPRESSION VARCHAR(120) NOT NULL,
+TIME_ZONE_ID VARCHAR(80),
+PRIMARY KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP),
+FOREIGN KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP)
+REFERENCES QRTZ_TRIGGERS(SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP))
+ENGINE=InnoDB;
+COMMIT;
+
+BEGIN;
+CREATE TABLE QRTZ_SIMPROP_TRIGGERS
+  (          
+    SCHED_NAME VARCHAR(120) NOT NULL,
+    TRIGGER_NAME VARCHAR(200) NOT NULL,
+    TRIGGER_GROUP VARCHAR(200) NOT NULL,
+    STR_PROP_1 VARCHAR(512) NULL,
+    STR_PROP_2 VARCHAR(512) NULL,
+    STR_PROP_3 VARCHAR(512) NULL,
+    INT_PROP_1 INT NULL,
+    INT_PROP_2 INT NULL,
+    LONG_PROP_1 BIGINT NULL,
+    LONG_PROP_2 BIGINT NULL,
+    DEC_PROP_1 NUMERIC(13,4) NULL,
+    DEC_PROP_2 NUMERIC(13,4) NULL,
+    BOOL_PROP_1 VARCHAR(1) NULL,
+    BOOL_PROP_2 VARCHAR(1) NULL,
+    PRIMARY KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP),
+    FOREIGN KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP) 
+    REFERENCES QRTZ_TRIGGERS(SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP))
+ENGINE=InnoDB;
+COMMIT;
+
+BEGIN;
+CREATE TABLE QRTZ_BLOB_TRIGGERS (
+SCHED_NAME VARCHAR(120) NOT NULL,
+TRIGGER_NAME VARCHAR(200) NOT NULL,
+TRIGGER_GROUP VARCHAR(200) NOT NULL,
+BLOB_DATA BLOB NULL,
+PRIMARY KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP),
+INDEX (SCHED_NAME,TRIGGER_NAME, TRIGGER_GROUP),
+FOREIGN KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP)
+REFERENCES QRTZ_TRIGGERS(SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP))
+ENGINE=InnoDB;
+COMMIT;
+
+BEGIN;
+CREATE TABLE QRTZ_CALENDARS (
+SCHED_NAME VARCHAR(120) NOT NULL,
+CALENDAR_NAME VARCHAR(200) NOT NULL,
+CALENDAR BLOB NOT NULL,
+PRIMARY KEY (SCHED_NAME,CALENDAR_NAME))
+ENGINE=InnoDB;
+COMMIT;
+
+BEGIN;
+CREATE TABLE QRTZ_PAUSED_TRIGGER_GRPS (
+SCHED_NAME VARCHAR(120) NOT NULL,
+TRIGGER_GROUP VARCHAR(200) NOT NULL,
+PRIMARY KEY (SCHED_NAME,TRIGGER_GROUP))
+ENGINE=InnoDB;
+COMMIT;
+
+BEGIN;
+CREATE TABLE QRTZ_FIRED_TRIGGERS (
+SCHED_NAME VARCHAR(120) NOT NULL,
+ENTRY_ID VARCHAR(95) NOT NULL,
+TRIGGER_NAME VARCHAR(200) NOT NULL,
+TRIGGER_GROUP VARCHAR(200) NOT NULL,
+INSTANCE_NAME VARCHAR(200) NOT NULL,
+FIRED_TIME BIGINT(13) NOT NULL,
+SCHED_TIME BIGINT(13) NOT NULL,
+PRIORITY INTEGER NOT NULL,
+STATE VARCHAR(16) NOT NULL,
+JOB_NAME VARCHAR(200) NULL,
+JOB_GROUP VARCHAR(200) NULL,
+IS_NONCONCURRENT VARCHAR(1) NULL,
+REQUESTS_RECOVERY VARCHAR(1) NULL,
+PRIMARY KEY (SCHED_NAME,ENTRY_ID))
+ENGINE=InnoDB;
+COMMIT;
+
+BEGIN;
+CREATE TABLE QRTZ_SCHEDULER_STATE (
+SCHED_NAME VARCHAR(120) NOT NULL,
+INSTANCE_NAME VARCHAR(200) NOT NULL,
+LAST_CHECKIN_TIME BIGINT(13) NOT NULL,
+CHECKIN_INTERVAL BIGINT(13) NOT NULL,
+PRIMARY KEY (SCHED_NAME,INSTANCE_NAME))
+ENGINE=InnoDB;
+COMMIT;
+
+BEGIN;
+CREATE TABLE QRTZ_LOCKS (
+SCHED_NAME VARCHAR(120) NOT NULL,
+LOCK_NAME VARCHAR(40) NOT NULL,
+PRIMARY KEY (SCHED_NAME,LOCK_NAME))
+ENGINE=InnoDB;
+COMMIT;
+
+BEGIN;
+CREATE INDEX IDX_QRTZ_J_REQ_RECOVERY ON QRTZ_JOB_DETAILS(SCHED_NAME,REQUESTS_RECOVERY);
+CREATE INDEX IDX_QRTZ_J_GRP ON QRTZ_JOB_DETAILS(SCHED_NAME,JOB_GROUP);
+
+CREATE INDEX IDX_QRTZ_T_J ON QRTZ_TRIGGERS(SCHED_NAME,JOB_NAME,JOB_GROUP);
+CREATE INDEX IDX_QRTZ_T_JG ON QRTZ_TRIGGERS(SCHED_NAME,JOB_GROUP);
+CREATE INDEX IDX_QRTZ_T_C ON QRTZ_TRIGGERS(SCHED_NAME,CALENDAR_NAME);
+CREATE INDEX IDX_QRTZ_T_G ON QRTZ_TRIGGERS(SCHED_NAME,TRIGGER_GROUP);
+CREATE INDEX IDX_QRTZ_T_STATE ON QRTZ_TRIGGERS(SCHED_NAME,TRIGGER_STATE);
+CREATE INDEX IDX_QRTZ_T_N_STATE ON QRTZ_TRIGGERS(SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP,TRIGGER_STATE);
+CREATE INDEX IDX_QRTZ_T_N_G_STATE ON QRTZ_TRIGGERS(SCHED_NAME,TRIGGER_GROUP,TRIGGER_STATE);
+CREATE INDEX IDX_QRTZ_T_NEXT_FIRE_TIME ON QRTZ_TRIGGERS(SCHED_NAME,NEXT_FIRE_TIME);
+CREATE INDEX IDX_QRTZ_T_NFT_ST ON QRTZ_TRIGGERS(SCHED_NAME,TRIGGER_STATE,NEXT_FIRE_TIME);
+CREATE INDEX IDX_QRTZ_T_NFT_MISFIRE ON QRTZ_TRIGGERS(SCHED_NAME,MISFIRE_INSTR,NEXT_FIRE_TIME);
+CREATE INDEX IDX_QRTZ_T_NFT_ST_MISFIRE ON QRTZ_TRIGGERS(SCHED_NAME,MISFIRE_INSTR,NEXT_FIRE_TIME,TRIGGER_STATE);
+CREATE INDEX IDX_QRTZ_T_NFT_ST_MISFIRE_GRP ON QRTZ_TRIGGERS(SCHED_NAME,MISFIRE_INSTR,NEXT_FIRE_TIME,TRIGGER_GROUP,TRIGGER_STATE);
+
+CREATE INDEX IDX_QRTZ_FT_TRIG_INST_NAME ON QRTZ_FIRED_TRIGGERS(SCHED_NAME,INSTANCE_NAME);
+CREATE INDEX IDX_QRTZ_FT_INST_JOB_REQ_RCVRY ON QRTZ_FIRED_TRIGGERS(SCHED_NAME,INSTANCE_NAME,REQUESTS_RECOVERY);
+CREATE INDEX IDX_QRTZ_FT_J_G ON QRTZ_FIRED_TRIGGERS(SCHED_NAME,JOB_NAME,JOB_GROUP);
+CREATE INDEX IDX_QRTZ_FT_JG ON QRTZ_FIRED_TRIGGERS(SCHED_NAME,JOB_GROUP);
+CREATE INDEX IDX_QRTZ_FT_T_G ON QRTZ_FIRED_TRIGGERS(SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP);
+CREATE INDEX IDX_QRTZ_FT_TG ON QRTZ_FIRED_TRIGGERS(SCHED_NAME,TRIGGER_GROUP);
+COMMIT;

http://git-wip-us.apache.org/repos/asf/syncope/blob/6dfedd8f/core/provisioning-java/src/main/resources/quartz/tables_oracle.sql
----------------------------------------------------------------------
diff --git a/core/provisioning-java/src/main/resources/quartz/tables_oracle.sql b/core/provisioning-java/src/main/resources/quartz/tables_oracle.sql
new file mode 100644
index 0000000..4384ac5
--- /dev/null
+++ b/core/provisioning-java/src/main/resources/quartz/tables_oracle.sql
@@ -0,0 +1,208 @@
+-- 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.
+
+--
+-- A hint submitted by a user: Oracle DB MUST be created as "shared" and the 
+-- job_queue_processes parameter  must be greater than 2
+-- However, these settings are pretty much standard after any
+-- Oracle install, so most users need not worry about this.
+--
+-- Many other users (including the primary author of Quartz) have had success
+-- runing in dedicated mode, so only consider the above as a hint ;-)
+--
+
+delete from qrtz_fired_triggers;
+delete from qrtz_simple_triggers;
+delete from qrtz_simprop_triggers;
+delete from qrtz_cron_triggers;
+delete from qrtz_blob_triggers;
+delete from qrtz_triggers;
+delete from qrtz_job_details;
+delete from qrtz_calendars;
+delete from qrtz_paused_trigger_grps;
+delete from qrtz_locks;
+delete from qrtz_scheduler_state;
+
+drop table qrtz_calendars;
+drop table qrtz_fired_triggers;
+drop table qrtz_blob_triggers;
+drop table qrtz_cron_triggers;
+drop table qrtz_simple_triggers;
+drop table qrtz_simprop_triggers;
+drop table qrtz_triggers;
+drop table qrtz_job_details;
+drop table qrtz_paused_trigger_grps;
+drop table qrtz_locks;
+drop table qrtz_scheduler_state;
+
+
+CREATE TABLE qrtz_job_details
+  (
+    SCHED_NAME VARCHAR2(120) NOT NULL,
+    JOB_NAME  VARCHAR2(200) NOT NULL,
+    JOB_GROUP VARCHAR2(200) NOT NULL,
+    DESCRIPTION VARCHAR2(250) NULL,
+    JOB_CLASS_NAME   VARCHAR2(250) NOT NULL, 
+    IS_DURABLE VARCHAR2(1) NOT NULL,
+    IS_NONCONCURRENT VARCHAR2(1) NOT NULL,
+    IS_UPDATE_DATA VARCHAR2(1) NOT NULL,
+    REQUESTS_RECOVERY VARCHAR2(1) NOT NULL,
+    JOB_DATA BLOB NULL,
+    CONSTRAINT QRTZ_JOB_DETAILS_PK PRIMARY KEY (SCHED_NAME,JOB_NAME,JOB_GROUP)
+);
+CREATE TABLE qrtz_triggers
+  (
+    SCHED_NAME VARCHAR2(120) NOT NULL,
+    TRIGGER_NAME VARCHAR2(200) NOT NULL,
+    TRIGGER_GROUP VARCHAR2(200) NOT NULL,
+    JOB_NAME  VARCHAR2(200) NOT NULL, 
+    JOB_GROUP VARCHAR2(200) NOT NULL,
+    DESCRIPTION VARCHAR2(250) NULL,
+    NEXT_FIRE_TIME NUMBER(13) NULL,
+    PREV_FIRE_TIME NUMBER(13) NULL,
+    PRIORITY NUMBER(13) NULL,
+    TRIGGER_STATE VARCHAR2(16) NOT NULL,
+    TRIGGER_TYPE VARCHAR2(8) NOT NULL,
+    START_TIME NUMBER(13) NOT NULL,
+    END_TIME NUMBER(13) NULL,
+    CALENDAR_NAME VARCHAR2(200) NULL,
+    MISFIRE_INSTR NUMBER(2) NULL,
+    JOB_DATA BLOB NULL,
+    CONSTRAINT QRTZ_TRIGGERS_PK PRIMARY KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP),
+    CONSTRAINT QRTZ_TRIGGER_TO_JOBS_FK FOREIGN KEY (SCHED_NAME,JOB_NAME,JOB_GROUP) 
+      REFERENCES QRTZ_JOB_DETAILS(SCHED_NAME,JOB_NAME,JOB_GROUP) 
+);
+CREATE TABLE qrtz_simple_triggers
+  (
+    SCHED_NAME VARCHAR2(120) NOT NULL,
+    TRIGGER_NAME VARCHAR2(200) NOT NULL,
+    TRIGGER_GROUP VARCHAR2(200) NOT NULL,
+    REPEAT_COUNT NUMBER(7) NOT NULL,
+    REPEAT_INTERVAL NUMBER(12) NOT NULL,
+    TIMES_TRIGGERED NUMBER(10) NOT NULL,
+    CONSTRAINT QRTZ_SIMPLE_TRIG_PK PRIMARY KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP),
+    CONSTRAINT QRTZ_SIMPLE_TRIG_TO_TRIG_FK FOREIGN KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP) 
+	REFERENCES QRTZ_TRIGGERS(SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP)
+);
+CREATE TABLE qrtz_cron_triggers
+  (
+    SCHED_NAME VARCHAR2(120) NOT NULL,
+    TRIGGER_NAME VARCHAR2(200) NOT NULL,
+    TRIGGER_GROUP VARCHAR2(200) NOT NULL,
+    CRON_EXPRESSION VARCHAR2(120) NOT NULL,
+    TIME_ZONE_ID VARCHAR2(80),
+    CONSTRAINT QRTZ_CRON_TRIG_PK PRIMARY KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP),
+    CONSTRAINT QRTZ_CRON_TRIG_TO_TRIG_FK FOREIGN KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP) 
+      REFERENCES QRTZ_TRIGGERS(SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP)
+);
+CREATE TABLE qrtz_simprop_triggers
+  (          
+    SCHED_NAME VARCHAR2(120) NOT NULL,
+    TRIGGER_NAME VARCHAR2(200) NOT NULL,
+    TRIGGER_GROUP VARCHAR2(200) NOT NULL,
+    STR_PROP_1 VARCHAR2(512) NULL,
+    STR_PROP_2 VARCHAR2(512) NULL,
+    STR_PROP_3 VARCHAR2(512) NULL,
+    INT_PROP_1 NUMBER(10) NULL,
+    INT_PROP_2 NUMBER(10) NULL,
+    LONG_PROP_1 NUMBER(13) NULL,
+    LONG_PROP_2 NUMBER(13) NULL,
+    DEC_PROP_1 NUMERIC(13,4) NULL,
+    DEC_PROP_2 NUMERIC(13,4) NULL,
+    BOOL_PROP_1 VARCHAR2(1) NULL,
+    BOOL_PROP_2 VARCHAR2(1) NULL,
+    CONSTRAINT QRTZ_SIMPROP_TRIG_PK PRIMARY KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP),
+    CONSTRAINT QRTZ_SIMPROP_TRIG_TO_TRIG_FK FOREIGN KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP) 
+      REFERENCES QRTZ_TRIGGERS(SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP)
+);
+CREATE TABLE qrtz_blob_triggers
+  (
+    SCHED_NAME VARCHAR2(120) NOT NULL,
+    TRIGGER_NAME VARCHAR2(200) NOT NULL,
+    TRIGGER_GROUP VARCHAR2(200) NOT NULL,
+    BLOB_DATA BLOB NULL,
+    CONSTRAINT QRTZ_BLOB_TRIG_PK PRIMARY KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP),
+    CONSTRAINT QRTZ_BLOB_TRIG_TO_TRIG_FK FOREIGN KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP) 
+        REFERENCES QRTZ_TRIGGERS(SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP)
+);
+CREATE TABLE qrtz_calendars
+  (
+    SCHED_NAME VARCHAR2(120) NOT NULL,
+    CALENDAR_NAME  VARCHAR2(200) NOT NULL, 
+    CALENDAR BLOB NOT NULL,
+    CONSTRAINT QRTZ_CALENDARS_PK PRIMARY KEY (SCHED_NAME,CALENDAR_NAME)
+);
+CREATE TABLE qrtz_paused_trigger_grps
+  (
+    SCHED_NAME VARCHAR2(120) NOT NULL,
+    TRIGGER_GROUP  VARCHAR2(200) NOT NULL, 
+    CONSTRAINT QRTZ_PAUSED_TRIG_GRPS_PK PRIMARY KEY (SCHED_NAME,TRIGGER_GROUP)
+);
+CREATE TABLE qrtz_fired_triggers 
+  (
+    SCHED_NAME VARCHAR2(120) NOT NULL,
+    ENTRY_ID VARCHAR2(95) NOT NULL,
+    TRIGGER_NAME VARCHAR2(200) NOT NULL,
+    TRIGGER_GROUP VARCHAR2(200) NOT NULL,
+    INSTANCE_NAME VARCHAR2(200) NOT NULL,
+    FIRED_TIME NUMBER(13) NOT NULL,
+    SCHED_TIME NUMBER(13) NOT NULL,
+    PRIORITY NUMBER(13) NOT NULL,
+    STATE VARCHAR2(16) NOT NULL,
+    JOB_NAME VARCHAR2(200) NULL,
+    JOB_GROUP VARCHAR2(200) NULL,
+    IS_NONCONCURRENT VARCHAR2(1) NULL,
+    REQUESTS_RECOVERY VARCHAR2(1) NULL,
+    CONSTRAINT QRTZ_FIRED_TRIGGER_PK PRIMARY KEY (SCHED_NAME,ENTRY_ID)
+);
+CREATE TABLE qrtz_scheduler_state 
+  (
+    SCHED_NAME VARCHAR2(120) NOT NULL,
+    INSTANCE_NAME VARCHAR2(200) NOT NULL,
+    LAST_CHECKIN_TIME NUMBER(13) NOT NULL,
+    CHECKIN_INTERVAL NUMBER(13) NOT NULL,
+    CONSTRAINT QRTZ_SCHEDULER_STATE_PK PRIMARY KEY (SCHED_NAME,INSTANCE_NAME)
+);
+CREATE TABLE qrtz_locks
+  (
+    SCHED_NAME VARCHAR2(120) NOT NULL,
+    LOCK_NAME  VARCHAR2(40) NOT NULL, 
+    CONSTRAINT QRTZ_LOCKS_PK PRIMARY KEY (SCHED_NAME,LOCK_NAME)
+);
+
+create index idx_qrtz_j_req_recovery on qrtz_job_details(SCHED_NAME,REQUESTS_RECOVERY);
+create index idx_qrtz_j_grp on qrtz_job_details(SCHED_NAME,JOB_GROUP);
+
+create index idx_qrtz_t_j on qrtz_triggers(SCHED_NAME,JOB_NAME,JOB_GROUP);
+create index idx_qrtz_t_jg on qrtz_triggers(SCHED_NAME,JOB_GROUP);
+create index idx_qrtz_t_c on qrtz_triggers(SCHED_NAME,CALENDAR_NAME);
+create index idx_qrtz_t_g on qrtz_triggers(SCHED_NAME,TRIGGER_GROUP);
+create index idx_qrtz_t_state on qrtz_triggers(SCHED_NAME,TRIGGER_STATE);
+create index idx_qrtz_t_n_state on qrtz_triggers(SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP,TRIGGER_STATE);
+create index idx_qrtz_t_n_g_state on qrtz_triggers(SCHED_NAME,TRIGGER_GROUP,TRIGGER_STATE);
+create index idx_qrtz_t_next_fire_time on qrtz_triggers(SCHED_NAME,NEXT_FIRE_TIME);
+create index idx_qrtz_t_nft_st on qrtz_triggers(SCHED_NAME,TRIGGER_STATE,NEXT_FIRE_TIME);
+create index idx_qrtz_t_nft_misfire on qrtz_triggers(SCHED_NAME,MISFIRE_INSTR,NEXT_FIRE_TIME);
+create index idx_qrtz_t_nft_st_misfire on qrtz_triggers(SCHED_NAME,MISFIRE_INSTR,NEXT_FIRE_TIME,TRIGGER_STATE);
+create index idx_qrtz_t_nft_st_misfire_grp on qrtz_triggers(SCHED_NAME,MISFIRE_INSTR,NEXT_FIRE_TIME,TRIGGER_GROUP,TRIGGER_STATE);
+
+create index idx_qrtz_ft_trig_inst_name on qrtz_fired_triggers(SCHED_NAME,INSTANCE_NAME);
+create index idx_qrtz_ft_inst_job_req_rcvry on qrtz_fired_triggers(SCHED_NAME,INSTANCE_NAME,REQUESTS_RECOVERY);
+create index idx_qrtz_ft_j_g on qrtz_fired_triggers(SCHED_NAME,JOB_NAME,JOB_GROUP);
+create index idx_qrtz_ft_jg on qrtz_fired_triggers(SCHED_NAME,JOB_GROUP);
+create index idx_qrtz_ft_t_g on qrtz_fired_triggers(SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP);
+create index idx_qrtz_ft_tg on qrtz_fired_triggers(SCHED_NAME,TRIGGER_GROUP);

http://git-wip-us.apache.org/repos/asf/syncope/blob/6dfedd8f/core/provisioning-java/src/main/resources/quartz/tables_postgres.sql
----------------------------------------------------------------------
diff --git a/core/provisioning-java/src/main/resources/quartz/tables_postgres.sql b/core/provisioning-java/src/main/resources/quartz/tables_postgres.sql
new file mode 100644
index 0000000..9b7800f
--- /dev/null
+++ b/core/provisioning-java/src/main/resources/quartz/tables_postgres.sql
@@ -0,0 +1,204 @@
+-- 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.
+
+-- Thanks to Patrick Lightbody for submitting this...
+--
+-- In your Quartz properties file, you'll need to set 
+-- org.quartz.jobStore.driverDelegateClass = org.quartz.impl.jdbcjobstore.PostgreSQLDelegate
+
+drop table qrtz_fired_triggers;
+DROP TABLE QRTZ_PAUSED_TRIGGER_GRPS;
+DROP TABLE QRTZ_SCHEDULER_STATE;
+DROP TABLE QRTZ_LOCKS;
+drop table qrtz_simple_triggers;
+drop table qrtz_cron_triggers;
+drop table qrtz_simprop_triggers;
+DROP TABLE QRTZ_BLOB_TRIGGERS;
+drop table qrtz_triggers;
+drop table qrtz_job_details;
+drop table qrtz_calendars;
+
+CREATE TABLE qrtz_job_details
+  (
+    SCHED_NAME VARCHAR(120) NOT NULL,
+    JOB_NAME  VARCHAR(200) NOT NULL,
+    JOB_GROUP VARCHAR(200) NOT NULL,
+    DESCRIPTION VARCHAR(250) NULL,
+    JOB_CLASS_NAME   VARCHAR(250) NOT NULL, 
+    IS_DURABLE BOOL NOT NULL,
+    IS_NONCONCURRENT BOOL NOT NULL,
+    IS_UPDATE_DATA BOOL NOT NULL,
+    REQUESTS_RECOVERY BOOL NOT NULL,
+    JOB_DATA BYTEA NULL,
+    PRIMARY KEY (SCHED_NAME,JOB_NAME,JOB_GROUP)
+);
+
+CREATE TABLE qrtz_triggers
+  (
+    SCHED_NAME VARCHAR(120) NOT NULL,
+    TRIGGER_NAME VARCHAR(200) NOT NULL,
+    TRIGGER_GROUP VARCHAR(200) NOT NULL,
+    JOB_NAME  VARCHAR(200) NOT NULL, 
+    JOB_GROUP VARCHAR(200) NOT NULL,
+    DESCRIPTION VARCHAR(250) NULL,
+    NEXT_FIRE_TIME BIGINT NULL,
+    PREV_FIRE_TIME BIGINT NULL,
+    PRIORITY INTEGER NULL,
+    TRIGGER_STATE VARCHAR(16) NOT NULL,
+    TRIGGER_TYPE VARCHAR(8) NOT NULL,
+    START_TIME BIGINT NOT NULL,
+    END_TIME BIGINT NULL,
+    CALENDAR_NAME VARCHAR(200) NULL,
+    MISFIRE_INSTR SMALLINT NULL,
+    JOB_DATA BYTEA NULL,
+    PRIMARY KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP),
+    FOREIGN KEY (SCHED_NAME,JOB_NAME,JOB_GROUP) 
+	REFERENCES QRTZ_JOB_DETAILS(SCHED_NAME,JOB_NAME,JOB_GROUP) 
+);
+
+CREATE TABLE qrtz_simple_triggers
+  (
+    SCHED_NAME VARCHAR(120) NOT NULL,
+    TRIGGER_NAME VARCHAR(200) NOT NULL,
+    TRIGGER_GROUP VARCHAR(200) NOT NULL,
+    REPEAT_COUNT BIGINT NOT NULL,
+    REPEAT_INTERVAL BIGINT NOT NULL,
+    TIMES_TRIGGERED BIGINT NOT NULL,
+    PRIMARY KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP),
+    FOREIGN KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP) 
+	REFERENCES QRTZ_TRIGGERS(SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP)
+);
+
+CREATE TABLE qrtz_cron_triggers
+  (
+    SCHED_NAME VARCHAR(120) NOT NULL,
+    TRIGGER_NAME VARCHAR(200) NOT NULL,
+    TRIGGER_GROUP VARCHAR(200) NOT NULL,
+    CRON_EXPRESSION VARCHAR(120) NOT NULL,
+    TIME_ZONE_ID VARCHAR(80),
+    PRIMARY KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP),
+    FOREIGN KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP) 
+	REFERENCES QRTZ_TRIGGERS(SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP)
+);
+
+CREATE TABLE qrtz_simprop_triggers
+  (          
+    SCHED_NAME VARCHAR(120) NOT NULL,
+    TRIGGER_NAME VARCHAR(200) NOT NULL,
+    TRIGGER_GROUP VARCHAR(200) NOT NULL,
+    STR_PROP_1 VARCHAR(512) NULL,
+    STR_PROP_2 VARCHAR(512) NULL,
+    STR_PROP_3 VARCHAR(512) NULL,
+    INT_PROP_1 INT NULL,
+    INT_PROP_2 INT NULL,
+    LONG_PROP_1 BIGINT NULL,
+    LONG_PROP_2 BIGINT NULL,
+    DEC_PROP_1 NUMERIC(13,4) NULL,
+    DEC_PROP_2 NUMERIC(13,4) NULL,
+    BOOL_PROP_1 BOOL NULL,
+    BOOL_PROP_2 BOOL NULL,
+    PRIMARY KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP),
+    FOREIGN KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP) 
+    REFERENCES QRTZ_TRIGGERS(SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP)
+);
+
+CREATE TABLE qrtz_blob_triggers
+  (
+    SCHED_NAME VARCHAR(120) NOT NULL,
+    TRIGGER_NAME VARCHAR(200) NOT NULL,
+    TRIGGER_GROUP VARCHAR(200) NOT NULL,
+    BLOB_DATA BYTEA NULL,
+    PRIMARY KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP),
+    FOREIGN KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP) 
+        REFERENCES QRTZ_TRIGGERS(SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP)
+);
+
+CREATE TABLE qrtz_calendars
+  (
+    SCHED_NAME VARCHAR(120) NOT NULL,
+    CALENDAR_NAME  VARCHAR(200) NOT NULL, 
+    CALENDAR BYTEA NOT NULL,
+    PRIMARY KEY (SCHED_NAME,CALENDAR_NAME)
+);
+
+
+CREATE TABLE qrtz_paused_trigger_grps
+  (
+    SCHED_NAME VARCHAR(120) NOT NULL,
+    TRIGGER_GROUP  VARCHAR(200) NOT NULL, 
+    PRIMARY KEY (SCHED_NAME,TRIGGER_GROUP)
+);
+
+CREATE TABLE qrtz_fired_triggers 
+  (
+    SCHED_NAME VARCHAR(120) NOT NULL,
+    ENTRY_ID VARCHAR(95) NOT NULL,
+    TRIGGER_NAME VARCHAR(200) NOT NULL,
+    TRIGGER_GROUP VARCHAR(200) NOT NULL,
+    INSTANCE_NAME VARCHAR(200) NOT NULL,
+    FIRED_TIME BIGINT NOT NULL,
+    SCHED_TIME BIGINT NOT NULL,
+    PRIORITY INTEGER NOT NULL,
+    STATE VARCHAR(16) NOT NULL,
+    JOB_NAME VARCHAR(200) NULL,
+    JOB_GROUP VARCHAR(200) NULL,
+    IS_NONCONCURRENT BOOL NULL,
+    REQUESTS_RECOVERY BOOL NULL,
+    PRIMARY KEY (SCHED_NAME,ENTRY_ID)
+);
+
+CREATE TABLE qrtz_scheduler_state 
+  (
+    SCHED_NAME VARCHAR(120) NOT NULL,
+    INSTANCE_NAME VARCHAR(200) NOT NULL,
+    LAST_CHECKIN_TIME BIGINT NOT NULL,
+    CHECKIN_INTERVAL BIGINT NOT NULL,
+    PRIMARY KEY (SCHED_NAME,INSTANCE_NAME)
+);
+
+CREATE TABLE qrtz_locks
+  (
+    SCHED_NAME VARCHAR(120) NOT NULL,
+    LOCK_NAME  VARCHAR(40) NOT NULL, 
+    PRIMARY KEY (SCHED_NAME,LOCK_NAME)
+);
+
+create index idx_qrtz_j_req_recovery on qrtz_job_details(SCHED_NAME,REQUESTS_RECOVERY);
+create index idx_qrtz_j_grp on qrtz_job_details(SCHED_NAME,JOB_GROUP);
+
+create index idx_qrtz_t_j on qrtz_triggers(SCHED_NAME,JOB_NAME,JOB_GROUP);
+create index idx_qrtz_t_jg on qrtz_triggers(SCHED_NAME,JOB_GROUP);
+create index idx_qrtz_t_c on qrtz_triggers(SCHED_NAME,CALENDAR_NAME);
+create index idx_qrtz_t_g on qrtz_triggers(SCHED_NAME,TRIGGER_GROUP);
+create index idx_qrtz_t_state on qrtz_triggers(SCHED_NAME,TRIGGER_STATE);
+create index idx_qrtz_t_n_state on qrtz_triggers(SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP,TRIGGER_STATE);
+create index idx_qrtz_t_n_g_state on qrtz_triggers(SCHED_NAME,TRIGGER_GROUP,TRIGGER_STATE);
+create index idx_qrtz_t_next_fire_time on qrtz_triggers(SCHED_NAME,NEXT_FIRE_TIME);
+create index idx_qrtz_t_nft_st on qrtz_triggers(SCHED_NAME,TRIGGER_STATE,NEXT_FIRE_TIME);
+create index idx_qrtz_t_nft_misfire on qrtz_triggers(SCHED_NAME,MISFIRE_INSTR,NEXT_FIRE_TIME);
+create index idx_qrtz_t_nft_st_misfire on qrtz_triggers(SCHED_NAME,MISFIRE_INSTR,NEXT_FIRE_TIME,TRIGGER_STATE);
+create index idx_qrtz_t_nft_st_misfire_grp on qrtz_triggers(SCHED_NAME,MISFIRE_INSTR,NEXT_FIRE_TIME,TRIGGER_GROUP,TRIGGER_STATE);
+
+create index idx_qrtz_ft_trig_inst_name on qrtz_fired_triggers(SCHED_NAME,INSTANCE_NAME);
+create index idx_qrtz_ft_inst_job_req_rcvry on qrtz_fired_triggers(SCHED_NAME,INSTANCE_NAME,REQUESTS_RECOVERY);
+create index idx_qrtz_ft_j_g on qrtz_fired_triggers(SCHED_NAME,JOB_NAME,JOB_GROUP);
+create index idx_qrtz_ft_jg on qrtz_fired_triggers(SCHED_NAME,JOB_GROUP);
+create index idx_qrtz_ft_t_g on qrtz_fired_triggers(SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP);
+create index idx_qrtz_ft_tg on qrtz_fired_triggers(SCHED_NAME,TRIGGER_GROUP);
+
+
+commit;

http://git-wip-us.apache.org/repos/asf/syncope/blob/6dfedd8f/core/provisioning-java/src/main/resources/quartz/tables_sqlServer.sql
----------------------------------------------------------------------
diff --git a/core/provisioning-java/src/main/resources/quartz/tables_sqlServer.sql b/core/provisioning-java/src/main/resources/quartz/tables_sqlServer.sql
new file mode 100644
index 0000000..288b990
--- /dev/null
+++ b/core/provisioning-java/src/main/resources/quartz/tables_sqlServer.sql
@@ -0,0 +1,296 @@
+-- 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.
+
+IF EXISTS (SELECT * FROM dbo.sysobjects WHERE id = OBJECT_ID(N'[dbo].[FK_QRTZ_TRIGGERS_QRTZ_JOB_DETAILS]') AND OBJECTPROPERTY(id, N'ISFOREIGNKEY') = 1)
+ALTER TABLE [dbo].[QRTZ_TRIGGERS] DROP CONSTRAINT FK_QRTZ_TRIGGERS_QRTZ_JOB_DETAILS;
+
+IF EXISTS (SELECT * FROM dbo.sysobjects WHERE id = OBJECT_ID(N'[dbo].[FK_QRTZ_CRON_TRIGGERS_QRTZ_TRIGGERS]') AND OBJECTPROPERTY(id, N'ISFOREIGNKEY') = 1)
+ALTER TABLE [dbo].[QRTZ_CRON_TRIGGERS] DROP CONSTRAINT FK_QRTZ_CRON_TRIGGERS_QRTZ_TRIGGERS;
+
+IF EXISTS (SELECT * FROM dbo.sysobjects WHERE id = OBJECT_ID(N'[dbo].[FK_QRTZ_SIMPLE_TRIGGERS_QRTZ_TRIGGERS]') AND OBJECTPROPERTY(id, N'ISFOREIGNKEY') = 1)
+ALTER TABLE [dbo].[QRTZ_SIMPLE_TRIGGERS] DROP CONSTRAINT FK_QRTZ_SIMPLE_TRIGGERS_QRTZ_TRIGGERS;
+
+IF EXISTS (SELECT * FROM dbo.sysobjects WHERE id = OBJECT_ID(N'[dbo].[FK_QRTZ_SIMPROP_TRIGGERS_QRTZ_TRIGGERS]') AND OBJECTPROPERTY(id, N'ISFOREIGNKEY') = 1)
+ALTER TABLE [dbo].[QRTZ_SIMPROP_TRIGGERS] DROP CONSTRAINT FK_QRTZ_SIMPROP_TRIGGERS_QRTZ_TRIGGERS;
+
+IF EXISTS (SELECT * FROM dbo.sysobjects WHERE id = OBJECT_ID(N'[dbo].[QRTZ_CALENDARS]') AND OBJECTPROPERTY(id, N'ISUSERTABLE') = 1)
+DROP TABLE [dbo].[QRTZ_CALENDARS];
+
+IF EXISTS (SELECT * FROM dbo.sysobjects WHERE id = OBJECT_ID(N'[dbo].[QRTZ_CRON_TRIGGERS]') AND OBJECTPROPERTY(id, N'ISUSERTABLE') = 1)
+DROP TABLE [dbo].[QRTZ_CRON_TRIGGERS];
+
+IF EXISTS (SELECT * FROM dbo.sysobjects WHERE id = OBJECT_ID(N'[dbo].[QRTZ_BLOB_TRIGGERS]') AND OBJECTPROPERTY(id, N'ISUSERTABLE') = 1)
+DROP TABLE [dbo].[QRTZ_BLOB_TRIGGERS];
+
+IF EXISTS (SELECT * FROM dbo.sysobjects WHERE id = OBJECT_ID(N'[dbo].[QRTZ_FIRED_TRIGGERS]') AND OBJECTPROPERTY(id, N'ISUSERTABLE') = 1)
+DROP TABLE [dbo].[QRTZ_FIRED_TRIGGERS];
+
+IF EXISTS (SELECT * FROM dbo.sysobjects WHERE id = OBJECT_ID(N'[dbo].[QRTZ_PAUSED_TRIGGER_GRPS]') AND OBJECTPROPERTY(id, N'ISUSERTABLE') = 1)
+DROP TABLE [dbo].[QRTZ_PAUSED_TRIGGER_GRPS];
+
+IF EXISTS (SELECT * FROM dbo.sysobjects WHERE id = OBJECT_ID(N'[dbo].[QRTZ_SCHEDULER_STATE]') AND OBJECTPROPERTY(id, N'ISUSERTABLE') = 1)
+DROP TABLE [dbo].[QRTZ_SCHEDULER_STATE];
+
+IF EXISTS (SELECT * FROM dbo.sysobjects WHERE id = OBJECT_ID(N'[dbo].[QRTZ_LOCKS]') AND OBJECTPROPERTY(id, N'ISUSERTABLE') = 1)
+DROP TABLE [dbo].[QRTZ_LOCKS];
+
+IF EXISTS (SELECT * FROM dbo.sysobjects WHERE id = OBJECT_ID(N'[dbo].[QRTZ_JOB_DETAILS]') AND OBJECTPROPERTY(id, N'ISUSERTABLE') = 1)
+DROP TABLE [dbo].[QRTZ_JOB_DETAILS];
+
+IF EXISTS (SELECT * FROM dbo.sysobjects WHERE id = OBJECT_ID(N'[dbo].[QRTZ_SIMPLE_TRIGGERS]') AND OBJECTPROPERTY(id, N'ISUSERTABLE') = 1)
+DROP TABLE [dbo].[QRTZ_SIMPLE_TRIGGERS];
+
+IF EXISTS (SELECT * FROM dbo.sysobjects WHERE id = OBJECT_ID(N'[dbo].[QRTZ_SIMPROP_TRIGGERS]') AND OBJECTPROPERTY(id, N'ISUSERTABLE') = 1)
+DROP TABLE [dbo].[QRTZ_SIMPROP_TRIGGERS];
+
+IF EXISTS (SELECT * FROM dbo.sysobjects WHERE id = OBJECT_ID(N'[dbo].[QRTZ_TRIGGERS]') AND OBJECTPROPERTY(id, N'ISUSERTABLE') = 1)
+DROP TABLE [dbo].[QRTZ_TRIGGERS];
+
+CREATE TABLE [dbo].[QRTZ_CALENDARS] (
+  [SCHED_NAME] [VARCHAR] (120)  NOT NULL ,
+  [CALENDAR_NAME] [VARCHAR] (200)  NOT NULL ,
+  [CALENDAR] [IMAGE] NOT NULL
+) ON [PRIMARY];
+
+CREATE TABLE [dbo].[QRTZ_CRON_TRIGGERS] (
+  [SCHED_NAME] [VARCHAR] (120)  NOT NULL ,
+  [TRIGGER_NAME] [VARCHAR] (200)  NOT NULL ,
+  [TRIGGER_GROUP] [VARCHAR] (200)  NOT NULL ,
+  [CRON_EXPRESSION] [VARCHAR] (120)  NOT NULL ,
+  [TIME_ZONE_ID] [VARCHAR] (80) 
+) ON [PRIMARY];
+
+CREATE TABLE [dbo].[QRTZ_FIRED_TRIGGERS] (
+  [SCHED_NAME] [VARCHAR] (120)  NOT NULL ,
+  [ENTRY_ID] [VARCHAR] (95)  NOT NULL ,
+  [TRIGGER_NAME] [VARCHAR] (200)  NOT NULL ,
+  [TRIGGER_GROUP] [VARCHAR] (200)  NOT NULL ,
+  [INSTANCE_NAME] [VARCHAR] (200)  NOT NULL ,
+  [FIRED_TIME] [BIGINT] NOT NULL ,
+  [SCHED_TIME] [BIGINT] NOT NULL ,
+  [PRIORITY] [INTEGER] NOT NULL ,
+  [STATE] [VARCHAR] (16)  NOT NULL,
+  [JOB_NAME] [VARCHAR] (200)  NULL ,
+  [JOB_GROUP] [VARCHAR] (200)  NULL ,
+  [IS_NONCONCURRENT] [VARCHAR] (1)  NULL ,
+  [REQUESTS_RECOVERY] [VARCHAR] (1)  NULL 
+) ON [PRIMARY];
+
+CREATE TABLE [dbo].[QRTZ_PAUSED_TRIGGER_GRPS] (
+  [SCHED_NAME] [VARCHAR] (120)  NOT NULL ,
+  [TRIGGER_GROUP] [VARCHAR] (200)  NOT NULL 
+) ON [PRIMARY];
+
+CREATE TABLE [dbo].[QRTZ_SCHEDULER_STATE] (
+  [SCHED_NAME] [VARCHAR] (120)  NOT NULL ,
+  [INSTANCE_NAME] [VARCHAR] (200)  NOT NULL ,
+  [LAST_CHECKIN_TIME] [BIGINT] NOT NULL ,
+  [CHECKIN_INTERVAL] [BIGINT] NOT NULL
+) ON [PRIMARY];
+
+CREATE TABLE [dbo].[QRTZ_LOCKS] (
+  [SCHED_NAME] [VARCHAR] (120)  NOT NULL ,
+  [LOCK_NAME] [VARCHAR] (40)  NOT NULL 
+) ON [PRIMARY];
+
+CREATE TABLE [dbo].[QRTZ_JOB_DETAILS] (
+  [SCHED_NAME] [VARCHAR] (120)  NOT NULL ,
+  [JOB_NAME] [VARCHAR] (200)  NOT NULL ,
+  [JOB_GROUP] [VARCHAR] (200)  NOT NULL ,
+  [DESCRIPTION] [VARCHAR] (250) NULL ,
+  [JOB_CLASS_NAME] [VARCHAR] (250)  NOT NULL ,
+  [IS_DURABLE] [VARCHAR] (1)  NOT NULL ,
+  [IS_NONCONCURRENT] [VARCHAR] (1)  NOT NULL ,
+  [IS_UPDATE_DATA] [VARCHAR] (1)  NOT NULL ,
+  [REQUESTS_RECOVERY] [VARCHAR] (1)  NOT NULL ,
+  [JOB_DATA] [IMAGE] NULL
+) ON [PRIMARY];
+
+CREATE TABLE [dbo].[QRTZ_SIMPLE_TRIGGERS] (
+  [SCHED_NAME] [VARCHAR] (120)  NOT NULL ,
+  [TRIGGER_NAME] [VARCHAR] (200)  NOT NULL ,
+  [TRIGGER_GROUP] [VARCHAR] (200)  NOT NULL ,
+  [REPEAT_COUNT] [BIGINT] NOT NULL ,
+  [REPEAT_INTERVAL] [BIGINT] NOT NULL ,
+  [TIMES_TRIGGERED] [BIGINT] NOT NULL
+) ON [PRIMARY];
+
+CREATE TABLE [dbo].[QRTZ_SIMPROP_TRIGGERS] (
+  [SCHED_NAME] [VARCHAR] (120)  NOT NULL ,
+  [TRIGGER_NAME] [VARCHAR] (200)  NOT NULL ,
+  [TRIGGER_GROUP] [VARCHAR] (200)  NOT NULL ,
+  [STR_PROP_1] [VARCHAR] (512) NULL,
+  [STR_PROP_2] [VARCHAR] (512) NULL,
+  [STR_PROP_3] [VARCHAR] (512) NULL,
+  [INT_PROP_1] [INT] NULL,
+  [INT_PROP_2] [INT] NULL,
+  [LONG_PROP_1] [BIGINT] NULL,
+  [LONG_PROP_2] [BIGINT] NULL,
+  [DEC_PROP_1] [NUMERIC] (13,4) NULL,
+  [DEC_PROP_2] [NUMERIC] (13,4) NULL,
+  [BOOL_PROP_1] [VARCHAR] (1) NULL,
+  [BOOL_PROP_2] [VARCHAR] (1) NULL,
+) ON [PRIMARY];
+
+CREATE TABLE [dbo].[QRTZ_BLOB_TRIGGERS] (
+  [SCHED_NAME] [VARCHAR] (120)  NOT NULL ,
+  [TRIGGER_NAME] [VARCHAR] (200)  NOT NULL ,
+  [TRIGGER_GROUP] [VARCHAR] (200)  NOT NULL ,
+  [BLOB_DATA] [IMAGE] NULL
+) ON [PRIMARY];
+
+CREATE TABLE [dbo].[QRTZ_TRIGGERS] (
+  [SCHED_NAME] [VARCHAR] (120)  NOT NULL ,
+  [TRIGGER_NAME] [VARCHAR] (200)  NOT NULL ,
+  [TRIGGER_GROUP] [VARCHAR] (200)  NOT NULL ,
+  [JOB_NAME] [VARCHAR] (200)  NOT NULL ,
+  [JOB_GROUP] [VARCHAR] (200)  NOT NULL ,
+  [DESCRIPTION] [VARCHAR] (250) NULL ,
+  [NEXT_FIRE_TIME] [BIGINT] NULL ,
+  [PREV_FIRE_TIME] [BIGINT] NULL ,
+  [PRIORITY] [INTEGER] NULL ,
+  [TRIGGER_STATE] [VARCHAR] (16)  NOT NULL ,
+  [TRIGGER_TYPE] [VARCHAR] (8)  NOT NULL ,
+  [START_TIME] [BIGINT] NOT NULL ,
+  [END_TIME] [BIGINT] NULL ,
+  [CALENDAR_NAME] [VARCHAR] (200)  NULL ,
+  [MISFIRE_INSTR] [SMALLINT] NULL ,
+  [JOB_DATA] [IMAGE] NULL
+) ON [PRIMARY];
+
+ALTER TABLE [dbo].[QRTZ_CALENDARS] WITH NOCHECK ADD
+  CONSTRAINT [PK_QRTZ_CALENDARS] PRIMARY KEY  CLUSTERED
+  (
+    [SCHED_NAME],
+    [CALENDAR_NAME]
+  )  ON [PRIMARY];
+
+ALTER TABLE [dbo].[QRTZ_CRON_TRIGGERS] WITH NOCHECK ADD
+  CONSTRAINT [PK_QRTZ_CRON_TRIGGERS] PRIMARY KEY  CLUSTERED
+  (
+    [SCHED_NAME],
+    [TRIGGER_NAME],
+    [TRIGGER_GROUP]
+  )  ON [PRIMARY];
+
+ALTER TABLE [dbo].[QRTZ_FIRED_TRIGGERS] WITH NOCHECK ADD
+  CONSTRAINT [PK_QRTZ_FIRED_TRIGGERS] PRIMARY KEY  CLUSTERED
+  (
+    [SCHED_NAME],
+    [ENTRY_ID]
+  )  ON [PRIMARY];
+
+ALTER TABLE [dbo].[QRTZ_PAUSED_TRIGGER_GRPS] WITH NOCHECK ADD
+  CONSTRAINT [PK_QRTZ_PAUSED_TRIGGER_GRPS] PRIMARY KEY  CLUSTERED
+  (
+    [SCHED_NAME],
+    [TRIGGER_GROUP]
+  )  ON [PRIMARY];
+
+ALTER TABLE [dbo].[QRTZ_SCHEDULER_STATE] WITH NOCHECK ADD
+  CONSTRAINT [PK_QRTZ_SCHEDULER_STATE] PRIMARY KEY  CLUSTERED
+  (
+    [SCHED_NAME],
+    [INSTANCE_NAME]
+  )  ON [PRIMARY];
+
+ALTER TABLE [dbo].[QRTZ_LOCKS] WITH NOCHECK ADD
+  CONSTRAINT [PK_QRTZ_LOCKS] PRIMARY KEY  CLUSTERED
+  (
+    [SCHED_NAME],
+    [LOCK_NAME]
+  )  ON [PRIMARY];
+
+ALTER TABLE [dbo].[QRTZ_JOB_DETAILS] WITH NOCHECK ADD
+  CONSTRAINT [PK_QRTZ_JOB_DETAILS] PRIMARY KEY  CLUSTERED
+  (
+    [SCHED_NAME],
+    [JOB_NAME],
+    [JOB_GROUP]
+  )  ON [PRIMARY];
+
+ALTER TABLE [dbo].[QRTZ_SIMPLE_TRIGGERS] WITH NOCHECK ADD
+  CONSTRAINT [PK_QRTZ_SIMPLE_TRIGGERS] PRIMARY KEY  CLUSTERED
+  (
+    [SCHED_NAME],
+    [TRIGGER_NAME],
+    [TRIGGER_GROUP]
+  )  ON [PRIMARY];
+
+ALTER TABLE [dbo].[QRTZ_SIMPROP_TRIGGERS] WITH NOCHECK ADD
+  CONSTRAINT [PK_QRTZ_SIMPROP_TRIGGERS] PRIMARY KEY  CLUSTERED
+  (
+    [SCHED_NAME],
+    [TRIGGER_NAME],
+    [TRIGGER_GROUP]
+  )  ON [PRIMARY];
+
+ALTER TABLE [dbo].[QRTZ_TRIGGERS] WITH NOCHECK ADD
+  CONSTRAINT [PK_QRTZ_TRIGGERS] PRIMARY KEY  CLUSTERED
+  (
+    [SCHED_NAME],
+    [TRIGGER_NAME],
+    [TRIGGER_GROUP]
+  )  ON [PRIMARY];
+
+ALTER TABLE [dbo].[QRTZ_CRON_TRIGGERS] ADD
+  CONSTRAINT [FK_QRTZ_CRON_TRIGGERS_QRTZ_TRIGGERS] FOREIGN KEY
+  (
+    [SCHED_NAME],
+    [TRIGGER_NAME],
+    [TRIGGER_GROUP]
+  ) REFERENCES [dbo].[QRTZ_TRIGGERS] (
+    [SCHED_NAME],
+    [TRIGGER_NAME],
+    [TRIGGER_GROUP]
+  ) ON DELETE CASCADE;
+
+ALTER TABLE [dbo].[QRTZ_SIMPLE_TRIGGERS] ADD
+  CONSTRAINT [FK_QRTZ_SIMPLE_TRIGGERS_QRTZ_TRIGGERS] FOREIGN KEY
+  (
+    [SCHED_NAME],
+    [TRIGGER_NAME],
+    [TRIGGER_GROUP]
+  ) REFERENCES [dbo].[QRTZ_TRIGGERS] (
+    [SCHED_NAME],
+    [TRIGGER_NAME],
+    [TRIGGER_GROUP]
+  ) ON DELETE CASCADE;
+
+ALTER TABLE [dbo].[QRTZ_SIMPROP_TRIGGERS] ADD
+  CONSTRAINT [FK_QRTZ_SIMPROP_TRIGGERS_QRTZ_TRIGGERS] FOREIGN KEY
+  (
+    [SCHED_NAME],
+    [TRIGGER_NAME],
+    [TRIGGER_GROUP]
+  ) REFERENCES [dbo].[QRTZ_TRIGGERS] (
+    [SCHED_NAME],
+    [TRIGGER_NAME],
+    [TRIGGER_GROUP]
+  ) ON DELETE CASCADE;
+
+ALTER TABLE [dbo].[QRTZ_TRIGGERS] ADD
+  CONSTRAINT [FK_QRTZ_TRIGGERS_QRTZ_JOB_DETAILS] FOREIGN KEY
+  (
+    [SCHED_NAME],
+    [JOB_NAME],
+    [JOB_GROUP]
+  ) REFERENCES [dbo].[QRTZ_JOB_DETAILS] (
+    [SCHED_NAME],
+    [JOB_NAME],
+    [JOB_GROUP]
+  );

http://git-wip-us.apache.org/repos/asf/syncope/blob/6dfedd8f/core/provisioning-java/src/test/java/org/apache/syncope/core/provisioning/java/AbstractTest.java
----------------------------------------------------------------------
diff --git a/core/provisioning-java/src/test/java/org/apache/syncope/core/provisioning/java/AbstractTest.java b/core/provisioning-java/src/test/java/org/apache/syncope/core/provisioning/java/AbstractTest.java
index e26f238..07bda8a 100644
--- a/core/provisioning-java/src/test/java/org/apache/syncope/core/provisioning/java/AbstractTest.java
+++ b/core/provisioning-java/src/test/java/org/apache/syncope/core/provisioning/java/AbstractTest.java
@@ -21,6 +21,7 @@ package org.apache.syncope.core.provisioning.java;
 import org.junit.runner.RunWith;
 import org.springframework.test.context.ContextConfiguration;
 import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
+import org.springframework.test.context.transaction.TransactionConfiguration;
 
 @RunWith(SpringJUnit4ClassRunner.class)
 @ContextConfiguration(locations = {
@@ -29,5 +30,6 @@ import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
     "classpath:workflowContext.xml",
     "classpath:provisioningTest.xml"
 })
+@TransactionConfiguration(transactionManager = "MasterTransactionManager")
 public abstract class AbstractTest {
 }

http://git-wip-us.apache.org/repos/asf/syncope/blob/6dfedd8f/core/provisioning-java/src/test/java/org/apache/syncope/core/provisioning/java/ConnectorManagerTest.java
----------------------------------------------------------------------
diff --git a/core/provisioning-java/src/test/java/org/apache/syncope/core/provisioning/java/ConnectorManagerTest.java b/core/provisioning-java/src/test/java/org/apache/syncope/core/provisioning/java/ConnectorManagerTest.java
index 138fee3..1a71b89 100644
--- a/core/provisioning-java/src/test/java/org/apache/syncope/core/provisioning/java/ConnectorManagerTest.java
+++ b/core/provisioning-java/src/test/java/org/apache/syncope/core/provisioning/java/ConnectorManagerTest.java
@@ -65,7 +65,7 @@ public class ConnectorManagerTest extends AbstractTest {
         }
 
         assertEquals(expected,
-                ApplicationContextProvider.getApplicationContext().
+                ApplicationContextProvider.getBeanFactory().
                 getBeanNamesForType(Connector.class, false, true).length);
     }
 }

http://git-wip-us.apache.org/repos/asf/syncope/blob/6dfedd8f/core/provisioning-java/src/test/java/org/apache/syncope/core/provisioning/java/TestInitializer.java
----------------------------------------------------------------------
diff --git a/core/provisioning-java/src/test/java/org/apache/syncope/core/provisioning/java/TestInitializer.java b/core/provisioning-java/src/test/java/org/apache/syncope/core/provisioning/java/TestInitializer.java
new file mode 100644
index 0000000..98392af
--- /dev/null
+++ b/core/provisioning-java/src/test/java/org/apache/syncope/core/provisioning/java/TestInitializer.java
@@ -0,0 +1,37 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.syncope.core.provisioning.java;
+
+import org.apache.syncope.core.persistence.api.content.ContentLoader;
+import org.springframework.beans.factory.InitializingBean;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+
+@Component
+public class TestInitializer implements InitializingBean {
+
+    @Autowired
+    private ContentLoader contentLoader;
+
+    @Override
+    public void afterPropertiesSet() throws Exception {
+        contentLoader.load();
+    }
+
+}


[24/31] syncope git commit: [SYNCOPE-652] More tests and console support

Posted by md...@apache.org.
[SYNCOPE-652] More tests and console support


Project: http://git-wip-us.apache.org/repos/asf/syncope/repo
Commit: http://git-wip-us.apache.org/repos/asf/syncope/commit/74aed4af
Tree: http://git-wip-us.apache.org/repos/asf/syncope/tree/74aed4af
Diff: http://git-wip-us.apache.org/repos/asf/syncope/diff/74aed4af

Branch: refs/heads/SYNCOPE-156
Commit: 74aed4af3b0ad072c7cab7e5b5eb196c050e7471
Parents: feba699
Author: Francesco Chicchiriccò <il...@apache.org>
Authored: Thu Aug 13 12:30:38 2015 +0200
Committer: Francesco Chicchiriccò <il...@apache.org>
Committed: Thu Aug 13 17:16:51 2015 +0200

----------------------------------------------------------------------
 .../client/console/SyncopeConsoleSession.java   |  43 +++-
 .../syncope/client/console/pages/BasePage.java  |   5 +-
 .../syncope/client/console/pages/Login.java     |  49 +++++
 .../syncope/client/console/pages/Realms.java    |   4 -
 .../client/console/rest/BaseRestClient.java     |   3 -
 .../client/console/rest/RealmRestClient.java    |   2 +-
 .../syncope/client/console/pages/BasePage.html  |   7 +
 .../syncope/client/console/pages/Login.html     |   1 +
 .../syncope/common/lib/types/Entitlement.java   |   2 -
 .../apache/syncope/core/logic/DomainLogic.java  |  11 +-
 .../apache/syncope/core/logic/LoggerLogic.java  |   9 +-
 .../syncope/core/logic/ResourceLogic.java       |   4 -
 .../core/misc/policy/AccountPolicyEnforcer.java |   3 +-
 .../misc/policy/PasswordPolicyEnforcer.java     |   3 +-
 .../core/misc/policy/PolicyEnforcer.java        |  35 ---
 .../core/misc/security/AuthDataAccessor.java    |   4 +-
 .../core/misc/security/PasswordGenerator.java   |   4 +-
 .../core/persistence/jpa/inner/DomainTest.java  |  88 ++++++++
 .../src/test/resources/domains/TwoContent.xml   |  10 +
 fit/core-reference/src/main/webapp/db.jsp       |   3 +-
 .../fit/core/reference/AbstractITCase.java      |  19 +-
 .../fit/core/reference/AbstractTaskITCase.java  |  18 +-
 .../fit/core/reference/ConnectorITCase.java     |   7 +-
 .../fit/core/reference/DomainITCase.java        | 115 ++++++++++
 .../fit/core/reference/MultitenancyITCase.java  | 214 +++++++++++++++++++
 .../fit/core/reference/PushTaskITCase.java      |  20 +-
 .../fit/core/reference/SyncTaskITCase.java      |  35 +--
 27 files changed, 602 insertions(+), 116 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/syncope/blob/74aed4af/client/console/src/main/java/org/apache/syncope/client/console/SyncopeConsoleSession.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/SyncopeConsoleSession.java b/client/console/src/main/java/org/apache/syncope/client/console/SyncopeConsoleSession.java
index 25394c7..8d71645 100644
--- a/client/console/src/main/java/org/apache/syncope/client/console/SyncopeConsoleSession.java
+++ b/client/console/src/main/java/org/apache/syncope/client/console/SyncopeConsoleSession.java
@@ -19,19 +19,27 @@
 package org.apache.syncope.client.console;
 
 import java.text.DateFormat;
+import java.util.ArrayList;
 import java.util.Collections;
 import java.util.HashMap;
+import java.util.List;
 import java.util.Locale;
 import java.util.Map;
 import java.util.Set;
 import javax.ws.rs.core.EntityTag;
 import javax.ws.rs.core.MediaType;
+import org.apache.commons.collections4.CollectionUtils;
+import org.apache.commons.collections4.Transformer;
+import org.apache.commons.lang3.StringUtils;
 import org.apache.commons.lang3.tuple.Pair;
 import org.apache.cxf.jaxrs.client.WebClient;
 import org.apache.syncope.client.lib.SyncopeClient;
 import org.apache.syncope.client.lib.SyncopeClientFactoryBean;
+import org.apache.syncope.common.lib.SyncopeConstants;
+import org.apache.syncope.common.lib.to.DomainTO;
 import org.apache.syncope.common.lib.to.SyncopeTO;
 import org.apache.syncope.common.lib.to.UserTO;
+import org.apache.syncope.common.rest.api.service.DomainService;
 import org.apache.syncope.common.rest.api.service.SyncopeService;
 import org.apache.wicket.Session;
 import org.apache.wicket.authroles.authentication.AuthenticatedWebSession;
@@ -51,12 +59,16 @@ public class SyncopeConsoleSession extends AuthenticatedWebSession {
 
     private static final Logger LOG = LoggerFactory.getLogger(SyncopeConsoleSession.class);
 
-    private final SyncopeClientFactoryBean clientFactory;
-
     private final String version;
 
     private final SyncopeTO syncopeTO;
 
+    private final List<String> domains;
+
+    private String domain;
+
+    private final SyncopeClientFactoryBean clientFactory;
+
     private final Map<Class<?>, Object> services = Collections.synchronizedMap(new HashMap<Class<?>, Object>());
 
     private SyncopeClient client;
@@ -88,7 +100,18 @@ public class SyncopeConsoleSession extends AuthenticatedWebSession {
 
         version = ctx.getBean("version", String.class);
 
-        syncopeTO = clientFactory.create(anonymousUser, anonymousKey).getService(SyncopeService.class).info();
+        SyncopeClient anonymousClient = clientFactory.create(anonymousUser, anonymousKey);
+        syncopeTO = anonymousClient.getService(SyncopeService.class).info();
+        domains = new ArrayList<>();
+        domains.add(SyncopeConstants.MASTER_DOMAIN);
+        CollectionUtils.collect(anonymousClient.getService(DomainService.class).list(),
+                new Transformer<DomainTO, String>() {
+
+                    @Override
+                    public String transform(final DomainTO domain) {
+                        return domain.getKey();
+                    }
+                }, domains);
     }
 
     public String getVersion() {
@@ -99,12 +122,24 @@ public class SyncopeConsoleSession extends AuthenticatedWebSession {
         return syncopeTO;
     }
 
+    public List<String> getDomains() {
+        return domains;
+    }
+
+    public void setDomain(final String domain) {
+        this.domain = domain;
+    }
+
+    public String getDomain() {
+        return StringUtils.isBlank(domain) ? SyncopeConstants.MASTER_DOMAIN : domain;
+    }
+
     @Override
     public boolean authenticate(final String username, final String password) {
         boolean authenticated = false;
 
         try {
-            client = clientFactory.create(username, password);
+            client = clientFactory.setDomain(getDomain()).create(username, password);
 
             Pair<Map<String, Set<String>>, UserTO> self = client.self();
             auth = self.getKey();

http://git-wip-us.apache.org/repos/asf/syncope/blob/74aed4af/client/console/src/main/java/org/apache/syncope/client/console/pages/BasePage.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/pages/BasePage.java b/client/console/src/main/java/org/apache/syncope/client/console/pages/BasePage.java
index 20c3458..a6e737b 100644
--- a/client/console/src/main/java/org/apache/syncope/client/console/pages/BasePage.java
+++ b/client/console/src/main/java/org/apache/syncope/client/console/pages/BasePage.java
@@ -92,11 +92,12 @@ public class BasePage extends AbstractBasePage implements IAjaxIndicatorAware {
         liContainer = new WebMarkupContainer(getLIContainerId("realms"));
         add(liContainer);
         liContainer.add(new BookmarkablePageLink<>("realms", Realms.class));
-        
+
         liContainer = new WebMarkupContainer(getLIContainerId("topology"));
         add(liContainer);
         liContainer.add(new BookmarkablePageLink<>("topology", Topology.class));
-        
+
+        add(new Label("domain", SyncopeConsoleSession.get().getDomain()));
         add(new BookmarkablePageLink<Page>("logout", Logout.class));
 
         // set 'active' menu item

http://git-wip-us.apache.org/repos/asf/syncope/blob/74aed4af/client/console/src/main/java/org/apache/syncope/client/console/pages/Login.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/pages/Login.java b/client/console/src/main/java/org/apache/syncope/client/console/pages/Login.java
index 8421b00..8d9d5ff 100644
--- a/client/console/src/main/java/org/apache/syncope/client/console/pages/Login.java
+++ b/client/console/src/main/java/org/apache/syncope/client/console/pages/Login.java
@@ -21,8 +21,10 @@ package org.apache.syncope.client.console.pages;
 import java.security.AccessControlException;
 import java.util.Locale;
 import org.apache.syncope.client.console.SyncopeConsoleApplication;
+import org.apache.syncope.client.console.SyncopeConsoleSession;
 import org.apache.syncope.client.console.commons.Constants;
 import org.apache.syncope.client.console.panels.NotificationPanel;
+import org.apache.syncope.common.lib.SyncopeConstants;
 import org.apache.wicket.ajax.AjaxRequestTarget;
 import org.apache.wicket.ajax.markup.html.form.AjaxButton;
 import org.apache.wicket.authentication.IAuthenticationStrategy;
@@ -56,6 +58,8 @@ public class Login extends WebPage {
 
     private final DropDownChoice<Locale> languageSelect;
 
+    private final DropDownChoice<String> domainSelect;
+
     public Login(final PageParameters parameters) {
         super(parameters);
         setStatelessHint(true);
@@ -76,6 +80,12 @@ public class Login extends WebPage {
         languageSelect = new LocaleDropDown("language");
         form.add(languageSelect);
 
+        domainSelect = new DomainDropDown("domain");
+        if (SyncopeConsoleSession.get().getDomains().size() == 1) {
+            domainSelect.setOutputMarkupPlaceholderTag(true);
+        }
+        form.add(domainSelect);
+
         AjaxButton submitButton = new AjaxButton("submit", new Model<>(getString("submit"))) {
 
             private static final long serialVersionUID = 429178684321093953L;
@@ -157,4 +167,43 @@ public class Login extends WebPage {
         }
     }
 
+    /**
+     * Inner class which implements (custom) Domain DropDownChoice component.
+     */
+    private class DomainDropDown extends DropDownChoice<String> {
+
+        private static final long serialVersionUID = -7401167913360133325L;
+
+        public DomainDropDown(final String id) {
+            super(id, SyncopeConsoleSession.get().getDomains());
+
+            setModel(new IModel<String>() {
+
+                private static final long serialVersionUID = -1124206668056084806L;
+
+                @Override
+                public String getObject() {
+                    return SyncopeConsoleSession.get().getDomain();
+                }
+
+                @Override
+                public void setObject(final String object) {
+                    SyncopeConsoleSession.get().setDomain(object);
+                }
+
+                @Override
+                public void detach() {
+                    // Empty.
+                }
+            });
+
+            // set default value to Master Domain
+            getModel().setObject(SyncopeConstants.MASTER_DOMAIN);
+        }
+
+        @Override
+        protected boolean wantOnSelectionChangedNotifications() {
+            return true;
+        }
+    }
 }

http://git-wip-us.apache.org/repos/asf/syncope/blob/74aed4af/client/console/src/main/java/org/apache/syncope/client/console/pages/Realms.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/pages/Realms.java b/client/console/src/main/java/org/apache/syncope/client/console/pages/Realms.java
index daee99c..011d519 100644
--- a/client/console/src/main/java/org/apache/syncope/client/console/pages/Realms.java
+++ b/client/console/src/main/java/org/apache/syncope/client/console/pages/Realms.java
@@ -40,15 +40,11 @@ import org.apache.wicket.markup.repeater.RepeatingView;
 import org.apache.wicket.model.PropertyModel;
 import org.apache.wicket.request.mapper.parameter.PageParameters;
 import org.apache.wicket.spring.injection.annot.SpringBean;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
 
 public class Realms extends BasePage {
 
     private static final long serialVersionUID = -1100228004207271270L;
 
-    protected static final Logger LOG = LoggerFactory.getLogger(Realms.class);
-
     @SpringBean
     private RealmRestClient realmRestClient;
 

http://git-wip-us.apache.org/repos/asf/syncope/blob/74aed4af/client/console/src/main/java/org/apache/syncope/client/console/rest/BaseRestClient.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/rest/BaseRestClient.java b/client/console/src/main/java/org/apache/syncope/client/console/rest/BaseRestClient.java
index 17b2d4f..0e6fe2c 100644
--- a/client/console/src/main/java/org/apache/syncope/client/console/rest/BaseRestClient.java
+++ b/client/console/src/main/java/org/apache/syncope/client/console/rest/BaseRestClient.java
@@ -28,9 +28,6 @@ import org.slf4j.LoggerFactory;
 
 public abstract class BaseRestClient implements Serializable {
 
-    /**
-     * Logger.
-     */
     protected static final Logger LOG = LoggerFactory.getLogger(BaseRestClient.class);
 
     private static final long serialVersionUID = 1523999867826481989L;

http://git-wip-us.apache.org/repos/asf/syncope/blob/74aed4af/client/console/src/main/java/org/apache/syncope/client/console/rest/RealmRestClient.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/rest/RealmRestClient.java b/client/console/src/main/java/org/apache/syncope/client/console/rest/RealmRestClient.java
index 06cba4d..6ea095d 100644
--- a/client/console/src/main/java/org/apache/syncope/client/console/rest/RealmRestClient.java
+++ b/client/console/src/main/java/org/apache/syncope/client/console/rest/RealmRestClient.java
@@ -25,7 +25,7 @@ import org.apache.syncope.common.rest.api.service.RealmService;
 import org.springframework.stereotype.Component;
 
 /**
- * Console client for invoking Rest Group's services.
+ * Console client for invoking REST Realm's services.
  */
 @Component
 public class RealmRestClient extends BaseRestClient {

http://git-wip-us.apache.org/repos/asf/syncope/blob/74aed4af/client/console/src/main/resources/org/apache/syncope/client/console/pages/BasePage.html
----------------------------------------------------------------------
diff --git a/client/console/src/main/resources/org/apache/syncope/client/console/pages/BasePage.html b/client/console/src/main/resources/org/apache/syncope/client/console/pages/BasePage.html
index b01e9d9..3a874b8 100644
--- a/client/console/src/main/resources/org/apache/syncope/client/console/pages/BasePage.html
+++ b/client/console/src/main/resources/org/apache/syncope/client/console/pages/BasePage.html
@@ -63,6 +63,13 @@ under the License.
           <a href="#" class="sidebar-toggle" data-toggle="offcanvas" role="button">
             <span class="sr-only">Toggle navigation</span>
           </a>
+          <ul class="nav navbar-nav">
+            <li>
+              <a href="#" class="dropdown-toggle">
+                <span class="hidden-xs"><label wicket:id="domain"/></span>
+              </a>
+            </li>
+          </ul>
           <div class="navbar-custom-menu">
             <ul class="nav navbar-nav">
 

http://git-wip-us.apache.org/repos/asf/syncope/blob/74aed4af/client/console/src/main/resources/org/apache/syncope/client/console/pages/Login.html
----------------------------------------------------------------------
diff --git a/client/console/src/main/resources/org/apache/syncope/client/console/pages/Login.html b/client/console/src/main/resources/org/apache/syncope/client/console/pages/Login.html
index 8eb150b..e6230db 100644
--- a/client/console/src/main/resources/org/apache/syncope/client/console/pages/Login.html
+++ b/client/console/src/main/resources/org/apache/syncope/client/console/pages/Login.html
@@ -51,6 +51,7 @@ under the License.
           <input type="password" wicket:id="password" id="password" class="form-control" 
                  wicket:message="placeholder:password" required="required" />
           <select wicket:id="language" id="language" class="selectpicker"/>
+          <select wicket:id="domain" id="domain" class="selectpicker"/>
           <button wicket:id="submit" type="submit" 
                   class="btn btn-lg btn-primary btn-block btn-signin"><wicket:message key="submit"/></button>
         </form>

http://git-wip-us.apache.org/repos/asf/syncope/blob/74aed4af/common/lib/src/main/java/org/apache/syncope/common/lib/types/Entitlement.java
----------------------------------------------------------------------
diff --git a/common/lib/src/main/java/org/apache/syncope/common/lib/types/Entitlement.java b/common/lib/src/main/java/org/apache/syncope/common/lib/types/Entitlement.java
index bf87c89..ccb4fce 100644
--- a/common/lib/src/main/java/org/apache/syncope/common/lib/types/Entitlement.java
+++ b/common/lib/src/main/java/org/apache/syncope/common/lib/types/Entitlement.java
@@ -28,8 +28,6 @@ public final class Entitlement {
 
     public static final String ANONYMOUS = "ANONYMOUS";
 
-    public static final String DOMAIN_LIST = "DOMAIN_LIST";
-
     public static final String DOMAIN_CREATE = "DOMAIN_CREATE";
 
     public static final String DOMAIN_READ = "DOMAIN_READ";

http://git-wip-us.apache.org/repos/asf/syncope/blob/74aed4af/core/logic/src/main/java/org/apache/syncope/core/logic/DomainLogic.java
----------------------------------------------------------------------
diff --git a/core/logic/src/main/java/org/apache/syncope/core/logic/DomainLogic.java b/core/logic/src/main/java/org/apache/syncope/core/logic/DomainLogic.java
index 58f717d..c946fb1 100644
--- a/core/logic/src/main/java/org/apache/syncope/core/logic/DomainLogic.java
+++ b/core/logic/src/main/java/org/apache/syncope/core/logic/DomainLogic.java
@@ -27,6 +27,7 @@ import org.apache.commons.lang3.ArrayUtils;
 import org.apache.commons.lang3.StringUtils;
 import org.apache.syncope.common.lib.to.DomainTO;
 import org.apache.syncope.common.lib.types.Entitlement;
+import org.apache.syncope.core.persistence.api.DomainsHolder;
 import org.apache.syncope.core.persistence.api.dao.NotFoundException;
 import org.apache.syncope.core.persistence.api.dao.DomainDAO;
 import org.apache.syncope.core.persistence.api.entity.Domain;
@@ -39,6 +40,9 @@ import org.springframework.stereotype.Component;
 public class DomainLogic extends AbstractTransactionalLogic<DomainTO> {
 
     @Autowired
+    private DomainsHolder domainsHolder;
+
+    @Autowired
     private DomainDataBinder binder;
 
     @Autowired
@@ -57,8 +61,7 @@ public class DomainLogic extends AbstractTransactionalLogic<DomainTO> {
         return binder.getDomainTO(domain);
     }
 
-    @PreAuthorize("hasRole('" + Entitlement.DOMAIN_LIST + "') and authentication.details.domain == "
-            + "T(org.apache.syncope.common.lib.SyncopeConstants).MASTER_DOMAIN")
+    @PreAuthorize("isAuthenticated()")
     public List<DomainTO> list() {
         return CollectionUtils.collect(domainDAO.findAll(), new Transformer<Domain, DomainTO>() {
 
@@ -72,6 +75,10 @@ public class DomainLogic extends AbstractTransactionalLogic<DomainTO> {
     @PreAuthorize("hasRole('" + Entitlement.DOMAIN_CREATE + "') and authentication.details.domain == "
             + "T(org.apache.syncope.common.lib.SyncopeConstants).MASTER_DOMAIN")
     public DomainTO create(final DomainTO domainTO) {
+        if (!domainsHolder.getDomains().keySet().contains(domainTO.getKey())) {
+            throw new NotFoundException("No configuration is available for domain '" + domainTO.getKey());
+        }
+
         return binder.getDomainTO(domainDAO.save(binder.create(domainTO)));
     }
 

http://git-wip-us.apache.org/repos/asf/syncope/blob/74aed4af/core/logic/src/main/java/org/apache/syncope/core/logic/LoggerLogic.java
----------------------------------------------------------------------
diff --git a/core/logic/src/main/java/org/apache/syncope/core/logic/LoggerLogic.java b/core/logic/src/main/java/org/apache/syncope/core/logic/LoggerLogic.java
index d407dba..d7a4dd7 100644
--- a/core/logic/src/main/java/org/apache/syncope/core/logic/LoggerLogic.java
+++ b/core/logic/src/main/java/org/apache/syncope/core/logic/LoggerLogic.java
@@ -99,7 +99,8 @@ public class LoggerLogic extends AbstractTransactionalLogic<LoggerTO> {
         }, new ArrayList<LoggerTO>());
     }
 
-    @PreAuthorize("hasRole('" + Entitlement.LOG_LIST + "')")
+    @PreAuthorize("hasRole('" + Entitlement.LOG_LIST + "') and authentication.details.domain == "
+            + "T(org.apache.syncope.common.lib.SyncopeConstants).MASTER_DOMAIN")
     @Transactional(readOnly = true)
     public List<LoggerTO> listLogs() {
         return list(LoggerType.LOG);
@@ -165,7 +166,8 @@ public class LoggerLogic extends AbstractTransactionalLogic<LoggerTO> {
         return result;
     }
 
-    @PreAuthorize("hasRole('" + Entitlement.LOG_SET_LEVEL + "')")
+    @PreAuthorize("hasRole('" + Entitlement.LOG_SET_LEVEL + "') and authentication.details.domain == "
+            + "T(org.apache.syncope.common.lib.SyncopeConstants).MASTER_DOMAIN")
     public LoggerTO setLogLevel(final String name, final Level level) {
         return setLevel(name, level, LoggerType.LOG);
     }
@@ -206,7 +208,8 @@ public class LoggerLogic extends AbstractTransactionalLogic<LoggerTO> {
         return loggerToDelete;
     }
 
-    @PreAuthorize("hasRole('" + Entitlement.LOG_DELETE + "')")
+    @PreAuthorize("hasRole('" + Entitlement.LOG_DELETE + "') and authentication.details.domain == "
+            + "T(org.apache.syncope.common.lib.SyncopeConstants).MASTER_DOMAIN")
     public LoggerTO deleteLog(final String name) {
         return delete(name, LoggerType.LOG);
     }

http://git-wip-us.apache.org/repos/asf/syncope/blob/74aed4af/core/logic/src/main/java/org/apache/syncope/core/logic/ResourceLogic.java
----------------------------------------------------------------------
diff --git a/core/logic/src/main/java/org/apache/syncope/core/logic/ResourceLogic.java b/core/logic/src/main/java/org/apache/syncope/core/logic/ResourceLogic.java
index df09b5f..f95f7ed 100644
--- a/core/logic/src/main/java/org/apache/syncope/core/logic/ResourceLogic.java
+++ b/core/logic/src/main/java/org/apache/syncope/core/logic/ResourceLogic.java
@@ -50,7 +50,6 @@ import org.apache.syncope.core.persistence.api.dao.AnyObjectDAO;
 import org.apache.syncope.core.persistence.api.dao.AnyTypeDAO;
 import org.apache.syncope.core.persistence.api.entity.Any;
 import org.apache.syncope.core.persistence.api.entity.AnyType;
-import org.apache.syncope.core.persistence.api.entity.AnyUtilsFactory;
 import org.apache.syncope.core.persistence.api.entity.resource.Provision;
 import org.identityconnectors.framework.common.objects.Attribute;
 import org.identityconnectors.framework.common.objects.AttributeUtil;
@@ -89,9 +88,6 @@ public class ResourceLogic extends AbstractTransactionalLogic<ResourceTO> {
     @Autowired
     private ConnectorFactory connFactory;
 
-    @Autowired
-    private AnyUtilsFactory anyUtilsFactory;
-
     @PreAuthorize("hasRole('" + Entitlement.RESOURCE_CREATE + "')")
     public ResourceTO create(final ResourceTO resourceTO) {
         if (StringUtils.isBlank(resourceTO.getKey())) {

http://git-wip-us.apache.org/repos/asf/syncope/blob/74aed4af/core/misc/src/main/java/org/apache/syncope/core/misc/policy/AccountPolicyEnforcer.java
----------------------------------------------------------------------
diff --git a/core/misc/src/main/java/org/apache/syncope/core/misc/policy/AccountPolicyEnforcer.java b/core/misc/src/main/java/org/apache/syncope/core/misc/policy/AccountPolicyEnforcer.java
index 13ddc84..23740d6 100644
--- a/core/misc/src/main/java/org/apache/syncope/core/misc/policy/AccountPolicyEnforcer.java
+++ b/core/misc/src/main/java/org/apache/syncope/core/misc/policy/AccountPolicyEnforcer.java
@@ -25,11 +25,10 @@ import org.apache.syncope.core.persistence.api.entity.user.User;
 import org.springframework.stereotype.Component;
 
 @Component
-public class AccountPolicyEnforcer implements PolicyEnforcer<AccountPolicySpec, User> {
+public class AccountPolicyEnforcer {
 
     private static final Pattern DEFAULT_PATTERN = Pattern.compile("[a-zA-Z0-9-_@. ]+");
 
-    @Override
     public boolean enforce(final AccountPolicySpec policy, final PolicyType type, final User user) {
         if (user.getUsername() == null) {
             throw new PolicyEnforceException("Invalid account");

http://git-wip-us.apache.org/repos/asf/syncope/blob/74aed4af/core/misc/src/main/java/org/apache/syncope/core/misc/policy/PasswordPolicyEnforcer.java
----------------------------------------------------------------------
diff --git a/core/misc/src/main/java/org/apache/syncope/core/misc/policy/PasswordPolicyEnforcer.java b/core/misc/src/main/java/org/apache/syncope/core/misc/policy/PasswordPolicyEnforcer.java
index 1313d2e..1458bf3 100644
--- a/core/misc/src/main/java/org/apache/syncope/core/misc/policy/PasswordPolicyEnforcer.java
+++ b/core/misc/src/main/java/org/apache/syncope/core/misc/policy/PasswordPolicyEnforcer.java
@@ -24,9 +24,8 @@ import org.apache.syncope.core.persistence.api.entity.user.User;
 import org.springframework.stereotype.Component;
 
 @Component
-public class PasswordPolicyEnforcer implements PolicyEnforcer<PasswordPolicySpec, User> {
+public class PasswordPolicyEnforcer {
 
-    @Override
     public boolean enforce(final PasswordPolicySpec policy, final PolicyType type, final User user) {
         final String clearPassword = user.getClearPassword();
         final String password = user.getPassword();

http://git-wip-us.apache.org/repos/asf/syncope/blob/74aed4af/core/misc/src/main/java/org/apache/syncope/core/misc/policy/PolicyEnforcer.java
----------------------------------------------------------------------
diff --git a/core/misc/src/main/java/org/apache/syncope/core/misc/policy/PolicyEnforcer.java b/core/misc/src/main/java/org/apache/syncope/core/misc/policy/PolicyEnforcer.java
deleted file mode 100644
index 86e6583..0000000
--- a/core/misc/src/main/java/org/apache/syncope/core/misc/policy/PolicyEnforcer.java
+++ /dev/null
@@ -1,35 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.syncope.core.misc.policy;
-
-import org.apache.syncope.common.lib.types.PolicySpec;
-import org.apache.syncope.common.lib.types.PolicyType;
-
-public interface PolicyEnforcer<T extends PolicySpec, E> {
-
-    /**
-     * Check the given entity to see if it conforms with the indicated policy.
-     *
-     * @param policy
-     * @param type
-     * @param entity
-     * @return whether user is to be suspended
-     */
-    boolean enforce(final T policy, final PolicyType type, final E entity);
-}

http://git-wip-us.apache.org/repos/asf/syncope/blob/74aed4af/core/misc/src/main/java/org/apache/syncope/core/misc/security/AuthDataAccessor.java
----------------------------------------------------------------------
diff --git a/core/misc/src/main/java/org/apache/syncope/core/misc/security/AuthDataAccessor.java b/core/misc/src/main/java/org/apache/syncope/core/misc/security/AuthDataAccessor.java
index 052cc30..f6324a1 100644
--- a/core/misc/src/main/java/org/apache/syncope/core/misc/security/AuthDataAccessor.java
+++ b/core/misc/src/main/java/org/apache/syncope/core/misc/security/AuthDataAccessor.java
@@ -44,7 +44,6 @@ import org.apache.syncope.core.persistence.api.dao.AnyTypeDAO;
 import org.apache.syncope.core.persistence.api.dao.ConfDAO;
 import org.apache.syncope.core.persistence.api.dao.DomainDAO;
 import org.apache.syncope.core.persistence.api.dao.GroupDAO;
-import org.apache.syncope.core.persistence.api.dao.NotFoundException;
 import org.apache.syncope.core.persistence.api.dao.RealmDAO;
 import org.apache.syncope.core.persistence.api.dao.UserDAO;
 import org.apache.syncope.core.persistence.api.entity.Domain;
@@ -59,6 +58,7 @@ import org.identityconnectors.framework.common.objects.Uid;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.security.authentication.AuthenticationServiceException;
 import org.springframework.security.authentication.DisabledException;
 import org.springframework.security.core.Authentication;
 import org.springframework.security.core.userdetails.UsernameNotFoundException;
@@ -110,7 +110,7 @@ public class AuthDataAccessor {
     public Domain findDomain(final String key) {
         Domain domain = domainDAO.find(key);
         if (domain == null) {
-            throw new NotFoundException("Could not find domain " + key);
+            throw new AuthenticationServiceException("Could not find domain " + key);
         }
         return domain;
     }

http://git-wip-us.apache.org/repos/asf/syncope/blob/74aed4af/core/misc/src/main/java/org/apache/syncope/core/misc/security/PasswordGenerator.java
----------------------------------------------------------------------
diff --git a/core/misc/src/main/java/org/apache/syncope/core/misc/security/PasswordGenerator.java b/core/misc/src/main/java/org/apache/syncope/core/misc/security/PasswordGenerator.java
index 44635be..9514f27 100644
--- a/core/misc/src/main/java/org/apache/syncope/core/misc/security/PasswordGenerator.java
+++ b/core/misc/src/main/java/org/apache/syncope/core/misc/security/PasswordGenerator.java
@@ -56,9 +56,7 @@ public class PasswordGenerator {
     @Autowired
     private RealmDAO realmDAO;
 
-    public String generate(final List<PasswordPolicySpec> ppSpecs)
-            throws InvalidPasswordPolicySpecException {
-
+    public String generate(final List<PasswordPolicySpec> ppSpecs) throws InvalidPasswordPolicySpecException {
         PasswordPolicySpec policySpec = merge(ppSpecs);
 
         check(policySpec);

http://git-wip-us.apache.org/repos/asf/syncope/blob/74aed4af/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/inner/DomainTest.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/inner/DomainTest.java b/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/inner/DomainTest.java
new file mode 100644
index 0000000..a447f29
--- /dev/null
+++ b/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/inner/DomainTest.java
@@ -0,0 +1,88 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.syncope.core.persistence.jpa.inner;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+
+import java.util.List;
+import org.apache.syncope.common.lib.types.CipherAlgorithm;
+import org.apache.syncope.core.persistence.api.dao.DomainDAO;
+import org.apache.syncope.core.persistence.api.entity.Domain;
+import org.apache.syncope.core.persistence.jpa.AbstractTest;
+import org.junit.Test;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.transaction.annotation.Transactional;
+
+@Transactional
+public class DomainTest extends AbstractTest {
+
+    @Autowired
+    private DomainDAO domainDAO;
+
+    @Test
+    public void find() {
+        Domain two = domainDAO.find("Two");
+        assertNotNull(two);
+        assertEquals(CipherAlgorithm.SHA, two.getAdminCipherAlgorithm());
+
+        assertNull(domainDAO.find("none"));
+    }
+
+    @Test
+    public void findAll() {
+        List<Domain> list = domainDAO.findAll();
+        assertNotNull(list);
+        assertFalse(list.isEmpty());
+        for (Domain domain : list) {
+            assertNotNull(domain);
+        }
+    }
+
+    @Test
+    public void save() {
+        Domain domain = entityFactory.newEntity(Domain.class);
+        domain.setKey("new");
+        domain.setPassword("password", CipherAlgorithm.SSHA512);
+
+        Domain actual = domainDAO.save(domain);
+        assertNotNull(actual);
+        assertEquals(CipherAlgorithm.SSHA512, actual.getAdminCipherAlgorithm());
+        assertNotEquals("password", actual.getAdminPwd());
+    }
+
+    @Test
+    public void delete() {
+        Domain domain = entityFactory.newEntity(Domain.class);
+        domain.setKey("todelete");
+        domain.setPassword("password", CipherAlgorithm.SSHA512);
+
+        Domain actual = domainDAO.save(domain);
+        assertNotNull(actual);
+
+        String key = actual.getKey();
+        assertNotNull(domainDAO.find(key));
+
+        domainDAO.delete(key);
+        assertNull(domainDAO.find(key));
+    }
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/74aed4af/core/persistence-jpa/src/test/resources/domains/TwoContent.xml
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/test/resources/domains/TwoContent.xml b/core/persistence-jpa/src/test/resources/domains/TwoContent.xml
index 92216fd..39cdae2 100644
--- a/core/persistence-jpa/src/test/resources/domains/TwoContent.xml
+++ b/core/persistence-jpa/src/test/resources/domains/TwoContent.xml
@@ -121,4 +121,14 @@ under the License.
                 traceLevel="FAILURES"/> 
   <Notification_events Notification_id="2" event="[CUSTOM]:[]:[]:[confirmPasswordReset]:[SUCCESS]"/>
 
+  <ConnInstance id="100" bundleName="net.tirasa.connid.bundles.ldap" displayName="LDAP"
+                location="${connid.location}"
+                connectorName="net.tirasa.connid.bundles.ldap.LdapConnector"
+                version="${connid.ldap.version}" 
+                jsonConf='[{"schema":{"name":"synchronizePasswords","displayName":"Enable Password Synchronization","helpMessage":"If true, the connector will synchronize passwords. The Password Capture Plugin needs to be installed for password synchronization to work.","type":"boolean","required":false,"order":0,"confidential":false,"defaultValues":null},"overridable":false,"values":["false"]},{"schema":{"name":"maintainLdapGroupMembership","displayName":"Maintain LDAP Group Membership","helpMessage":"When enabled and a user is renamed or deleted, update any LDAP groups to which the user belongs to reflect the new name. Otherwise, the LDAP resource must maintain referential integrity with respect to group membership.","type":"boolean","required":false,"order":0,"confidential":false,"defaultValues":null},"overridable":false,"values":["true"]},{"schema":{"name":"host","displayName":"Host","helpMessage":"The name or IP address of the host where the LDAP server is running.","type":"jav
 a.lang.String","required":false,"order":0,"confidential":false,"defaultValues":null},"overridable":false,"values":["localhost"]},{"schema":{"name":"passwordHashAlgorithm","displayName":"Password Hash Algorithm","helpMessage":"Indicates the algorithm that the Identity system should use to hash the password. Currently supported values are SSHA, SHA, SSHA1, and SHA1. A blank value indicates that the system will not hash passwords. This will cause cleartext passwords to be stored in LDAP unless the LDAP server performs the hash (Netscape Directory Server and iPlanet Directory Server do).","type":"java.lang.String","required":false,"order":0,"confidential":false,"defaultValues":null},"overridable":false,"values":["SHA"]},{"schema":{"name":"blockSize","displayName":"Block Size","helpMessage":"The maximum number of accounts that can be in a block when retrieving accounts in blocks.","type":"int","required":false,"order":0,"confidential":false,"defaultValues":null},"overridable":false,"valu
 es":[]},{"schema":{"name":"useBlocks","displayName":"Use Blocks","helpMessage":"When performing operations on large numbers of accounts, the accounts are processed in blocks to reduce the amount of memory used by the operation. Select this option to process accounts in blocks.","type":"boolean","required":false,"order":0,"confidential":false,"defaultValues":null},"overridable":false,"values":[false]},{"schema":{"name":"usePagedResultControl","displayName":"Use Paged Result Control","helpMessage":"When enabled, the LDAP Paged Results control is preferred over the VLV control when retrieving accounts.","type":"boolean","required":false,"order":0,"confidential":false,"defaultValues":null},"overridable":false,"values":["false"]},{"schema":{"name":"port","displayName":"TCP Port","helpMessage":"TCP/IP port number used to communicate with the LDAP server.","type":"int","required":false,"order":0,"confidential":false,"defaultValues":null},"overridable":false,"values":[1389]},{"schema":{"nam
 e":"vlvSortAttribute","displayName":"VLV Sort Attribute","helpMessage":"Specify the sort attribute to use for VLV indexes on the resource.","type":"java.lang.String","required":false,"order":0,"confidential":false,"defaultValues":null},"overridable":false,"values":[]},{"schema":{"name":"statusManagementClass","displayName":"Status management class ","helpMessage":"Class to be used to manage enabled/disabled status. If no class is specified then identity status management wont be possible.","type":"java.lang.String","required":false,"order":0,"confidential":false,"defaultValues":null},"overridable":false,"values":["net.tirasa.connid.bundles.ldap.commons.AttributeStatusManagement"]},{"schema":{"name":"accountObjectClasses","displayName":"Account Object Classes","helpMessage":"The object class or classes that will be used when creating new user objects in the LDAP tree. When entering more than one object class, each entry should be on its own line; do not use commas or semi-colons to s
 eparate multiple object classes. Some object classes may require that you specify all object classes in the class hierarchy.","type":"[Ljava.lang.String;","required":false,"order":0,"confidential":false,"defaultValues":null},"overridable":false,"values":["inetOrgPerson"]},{"schema":{"name":"accountUserNameAttributes","displayName":"Account User Name Attributes","helpMessage":"Attribute or attributes which holds the account user name. They will be used when authenticating to find the LDAP entry for the user name to authenticate.","type":"[Ljava.lang.String;","required":false,"order":0,"confidential":false,"defaultValues":null},"overridable":false,"values":["uid"]},{"schema":{"name":"baseContextsToSynchronize","displayName":"Base Contexts to Synchronize","helpMessage":"One or more starting points in the LDAP tree that will be used to determine if a change should be synchronized. The base contexts attribute will be used to synchronize a change if this property is not set.","type":"[Lja
 va.lang.String;","required":false,"order":0,"confidential":false,"defaultValues":null},"overridable":false,"values":["ou=people,o=isp","ou=groups,o=isp"]},{"schema":{"name":"accountSynchronizationFilter","displayName":"LDAP Filter for Accounts to Synchronize","helpMessage":"An optional LDAP filter for the objects to synchronize. Because the change log is for all objects, this filter updates only objects that match the specified filter. If you specify a filter, an object will be synchronized only if it matches the filter and includes a synchronized object class.","type":"java.lang.String","required":false,"order":0,"confidential":false,"defaultValues":null},"overridable":false,"values":[]},{"schema":{"name":"removeLogEntryObjectClassFromFilter","displayName":"Remove Log Entry Object Class from Filter","helpMessage":"If this property is set (the default), the filter used to fetch change log entries does not contain the \"changeLogEntry\" object class, expecting that there are no entri
 es of other object types in the change log.","type":"boolean","required":false,"order":0,"confidential":false,"defaultValues":null},"overridable":false,"values":["false"]},{"schema":{"name":"passwordDecryptionKey","displayName":"Password Decryption Key","helpMessage":"The key to decrypt passwords with when performing password synchronization.","type":"org.identityconnectors.common.security.GuardedByteArray","required":false,"order":0,"confidential":false,"defaultValues":null},"overridable":false,"values":[]},{"schema":{"name":"readSchema","displayName":"Read Schema","helpMessage":"If true, the connector will read the schema from the server. If false, the connector will provide a default schema based on the object classes in the configuration. This property must be true in order to use extended object classes.","type":"boolean","required":false,"order":0,"confidential":false,"defaultValues":null},"overridable":false,"values":["false"]},{"schema":{"name":"ssl","displayName":"SSL","hel
 pMessage":"Select the check box to connect to the LDAP server using SSL.","type":"boolean","required":false,"order":0,"confidential":false,"defaultValues":null},"overridable":false,"values":["false"]},{"schema":{"name":"passwordAttributeToSynchronize","displayName":"Password Attribute to Synchronize","helpMessage":"The name of the password attribute to synchronize when performing password synchronization.","type":"java.lang.String","required":false,"order":0,"confidential":false,"defaultValues":null},"overridable":false,"values":[]},{"schema":{"name":"accountSearchFilter","displayName":"LDAP Filter for Retrieving Accounts","helpMessage":"An optional LDAP filter to control which accounts are returned from the LDAP resource. If no filter is specified, only accounts that include all specified object classes are returned.","type":"java.lang.String","required":false,"order":0,"confidential":false,"defaultValues":null},"overridable":false,"values":["uid=*"]},{"schema":{"name":"passwordDec
 ryptionInitializationVector","displayName":"Password Decryption Initialization Vector","helpMessage":"The initialization vector to decrypt passwords with when performing password synchronization.","type":"org.identityconnectors.common.security.GuardedByteArray","required":false,"order":0,"confidential":false,"defaultValues":null},"overridable":false,"values":[]},{"schema":{"name":"groupMemberAttribute","displayName":"Group Member Attribute","helpMessage":"The name of the group attribute that will be updated with the distinguished name of the user when the user is added to the group.","type":"java.lang.String","required":false,"order":0,"confidential":false,"defaultValues":null},"overridable":false,"values":[]},{"schema":{"name":"failover","displayName":"Failover Servers","helpMessage":"List all servers that should be used for failover in case the preferred server fails. If the preferred server fails, JNDI will connect to the next available server in the list. List all servers in the
  form of \"ldap://ldap.example.com:389/\", which follows the standard LDAP v3 URLs described in RFC 2255. Only the host and port parts of the URL are relevant in this setting.","type":"[Ljava.lang.String;","required":false,"order":0,"confidential":false,"defaultValues":null},"overridable":false,"values":[]},{"schema":{"name":"modifiersNamesToFilterOut","displayName":"Filter Out Changes By","helpMessage":"The names (DNs) of directory administrators to filter from the changes. Changes with the attribute \"modifiersName\" that match entries in this list will be filtered out. The standard value is the administrator name used by this adapter, to prevent loops. Entries should be of the format \"cn=Directory Manager\".","type":"[Ljava.lang.String;","required":false,"order":0,"confidential":false,"defaultValues":null},"overridable":false,"values":[]},{"schema":{"name":"groupNameAttributes","displayName":"Group Name Attributes","helpMessage":"Attribute or attributes which holds the group nam
 e.","type":"[Ljava.lang.String;","required":false,"order":0,"confidential":false,"defaultValues":null},"overridable":false,"values":["cn"]},{"schema":{"name":"uidAttribute","displayName":"Uid Attribute","helpMessage":"The name of the LDAP attribute which is mapped to the Uid attribute.","type":"java.lang.String","required":false,"order":0,"confidential":false,"defaultValues":null},"overridable":false,"values":["cn"]},{"schema":{"name":"respectResourcePasswordPolicyChangeAfterReset","displayName":"Respect Resource Password Policy Change-After-Reset","helpMessage":"When this resource is specified in a Login Module (i.e., this resource is a pass-through authentication target) and the resource password policy is configured for change-after-reset, a user whose resource account password has been administratively reset will be required to change that password after successfully authenticating.","type":"boolean","required":false,"order":0,"confidential":false,"defaultValues":null},"overrida
 ble":false,"values":["false"]},{"schema":{"name":"filterWithOrInsteadOfAnd","displayName":"Filter with Or Instead of And","helpMessage":"Normally the the filter used to fetch change log entries is an and-based filter retrieving an interval of change entries. If this property is set, the filter will or together the required change numbers instead.","type":"boolean","required":false,"order":0,"confidential":false,"defaultValues":null},"overridable":false,"values":["false"]},{"schema":{"name":"principal","displayName":"Principal","helpMessage":"The distinguished name with which to authenticate to the LDAP server.","type":"java.lang.String","required":false,"order":0,"confidential":false,"defaultValues":null},"overridable":false,"values":["uid=admin,ou=system"]},{"schema":{"name":"changeLogBlockSize","displayName":"Change Log Block Size","helpMessage":"The number of change log entries to fetch per query.","type":"int","required":true,"order":0,"confidential":false,"defaultValues":null},
 "overridable":false,"values":[100]},{"schema":{"name":"baseContexts","displayName":"Base Contexts","helpMessage":"One or more starting points in the LDAP tree that will be used when searching the tree. Searches are performed when discovering users from the LDAP server or when looking for the groups of which a user is a member.","type":"[Ljava.lang.String;","required":false,"order":0,"confidential":false,"defaultValues":null},"overridable":false,"values":["ou=people,o=isp","ou=groups,o=isp"]},{"schema":{"name":"passwordAttribute","displayName":"Password Attribute","helpMessage":"The name of the LDAP attribute which holds the password. When changing an user password, the new password is set to this attribute.","type":"java.lang.String","required":false,"order":0,"confidential":false,"defaultValues":null},"overridable":false,"values":["userpassword"]},{"schema":{"name":"changeNumberAttribute","displayName":"Change Number Attribute","helpMessage":"The name of the change number attribute
  in the change log entry.","type":"java.lang.String","required":true,"order":0,"confidential":false,"defaultValues":null},"overridable":false,"values":["changeNumber"]},{"schema":{"name":"objectClassesToSynchronize","displayName":"Object Classes to Synchronize","helpMessage":"The object classes to synchronize. The change log is for all objects; this filters updates to just the listed object classes. You should not list the superclasses of an object class unless you intend to synchronize objects with any of the superclass values. For example, if only \"inetOrgPerson\" objects should be synchronized, but the superclasses of \"inetOrgPerson\" (\"person\", \"organizationalperson\" and \"top\") should be filtered out, then list only \"inetOrgPerson\" here. All objects in LDAP are subclassed from \"top\". For this reason, you should never list \"top\", otherwise no object would be filtered.","type":"[Ljava.lang.String;","required":true,"order":0,"confidential":false,"defaultValues":null},
 "overridable":false,"values":["inetOrgPerson","groupOfUniqueNames"]},{"schema":{"name":"credentials","displayName":"Password","helpMessage":"Password for the principal.","type":"org.identityconnectors.common.security.GuardedString","required":false,"order":0,"confidential":false,"defaultValues":null},"overridable":false,"values":["secret"]},{"schema":{"name":"attributesToSynchronize","displayName":"Attributes to Synchronize","helpMessage":"The names of the attributes to synchronize. This ignores updates from the change log if they do not update any of the named attributes. For example, if only \"department\" is listed, then only changes that affect \"department\" will be processed. All other updates are ignored. If blank (the default), then all changes are processed.","type":"[Ljava.lang.String;","required":false,"order":0,"confidential":false,"defaultValues":null},"overridable":false,"values":[]},{"schema":{"name":"maintainPosixGroupMembership","displayName":"Maintain POSIX Group M
 embership","helpMessage":"When enabled and a user is renamed or deleted, update any POSIX groups to which the user belongs to reflect the new name. Otherwise, the LDAP resource must maintain referential integrity with respect to group membership.","type":"boolean","required":false,"order":0,"confidential":false,"defaultValues":null},"overridable":false,"values":["truemaintainLdapGroupMembership"]}]'/>
+  <ConnInstance_capabilities ConnInstance_id="100" capability="ONE_PHASE_CREATE"/>
+  <ConnInstance_capabilities ConnInstance_id="100" capability="ONE_PHASE_UPDATE"/>
+  <ConnInstance_capabilities ConnInstance_id="100" capability="ONE_PHASE_DELETE"/>
+  <ConnInstance_capabilities ConnInstance_id="100" capability="SEARCH"/>
+  
 </dataset>

http://git-wip-us.apache.org/repos/asf/syncope/blob/74aed4af/fit/core-reference/src/main/webapp/db.jsp
----------------------------------------------------------------------
diff --git a/fit/core-reference/src/main/webapp/db.jsp b/fit/core-reference/src/main/webapp/db.jsp
index 2a4c6ac..e54d33e 100644
--- a/fit/core-reference/src/main/webapp/db.jsp
+++ b/fit/core-reference/src/main/webapp/db.jsp
@@ -30,7 +30,6 @@ under the License.
         } catch (SQLException e) {
             getServletConfig().getServletContext().log("Could not start H2 web console (datastore)", e);
         }
-
-        response.sendRedirect("http://localhost:8082");
     }
+    response.sendRedirect("http://localhost:8082");
 %>
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/syncope/blob/74aed4af/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/AbstractITCase.java
----------------------------------------------------------------------
diff --git a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/AbstractITCase.java b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/AbstractITCase.java
index 7c36611..871155a 100644
--- a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/AbstractITCase.java
+++ b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/AbstractITCase.java
@@ -56,6 +56,7 @@ import org.apache.syncope.common.rest.api.service.AnyTypeService;
 import org.apache.syncope.common.rest.api.service.CamelRouteService;
 import org.apache.syncope.common.rest.api.service.ConfigurationService;
 import org.apache.syncope.common.rest.api.service.ConnectorService;
+import org.apache.syncope.common.rest.api.service.DomainService;
 import org.apache.syncope.common.rest.api.service.LoggerService;
 import org.apache.syncope.common.rest.api.service.NotificationService;
 import org.apache.syncope.common.rest.api.service.PolicyService;
@@ -86,20 +87,15 @@ import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
 @ContextConfiguration(locations = { "classpath:testJDBCContext.xml" })
 public abstract class AbstractITCase {
 
-    /**
-     * Logger.
-     */
     protected static final Logger LOG = LoggerFactory.getLogger(AbstractITCase.class);
 
     protected static final String ADMIN_UNAME = "admin";
 
     protected static final String ADMIN_PWD = "password";
 
-    private static final String ADDRESS = "http://localhost:9080/syncope/rest";
+    protected static final String ADDRESS = "http://localhost:9080/syncope/rest";
 
-    private static final String ENV_KEY_CONTENT_TYPE = "jaxrsContentType";
-
-    protected static final SyncopeClientFactoryBean clientFactory = new SyncopeClientFactoryBean().setAddress(ADDRESS);
+    protected static final String ENV_KEY_CONTENT_TYPE = "jaxrsContentType";
 
     protected static final String RESOURCE_NAME_WS1 = "ws-target-resource-1";
 
@@ -151,10 +147,14 @@ public abstract class AbstractITCase {
 
     protected static String ANONYMOUS_KEY;
 
+    protected static SyncopeClientFactoryBean clientFactory;
+
     protected static SyncopeClient adminClient;
 
     protected static SyncopeService syncopeService;
 
+    protected static DomainService domainService;
+
     protected static AnyTypeClassService anyTypeClassService;
 
     protected static AnyTypeService anyTypeService;
@@ -224,7 +224,9 @@ public abstract class AbstractITCase {
 
     @BeforeClass
     public static void restSetup() {
-        final String envContentType = System.getProperty(ENV_KEY_CONTENT_TYPE);
+        clientFactory = new SyncopeClientFactoryBean().setAddress(ADDRESS);
+
+        String envContentType = System.getProperty(ENV_KEY_CONTENT_TYPE);
         if (StringUtils.isNotBlank(envContentType)) {
             clientFactory.setContentType(envContentType);
         }
@@ -233,6 +235,7 @@ public abstract class AbstractITCase {
         adminClient = clientFactory.create(ADMIN_UNAME, ADMIN_PWD);
 
         syncopeService = adminClient.getService(SyncopeService.class);
+        domainService = adminClient.getService(DomainService.class);
         anyTypeClassService = adminClient.getService(AnyTypeClassService.class);
         anyTypeService = adminClient.getService(AnyTypeService.class);
         relationshipTypeService = adminClient.getService(RelationshipTypeService.class);

http://git-wip-us.apache.org/repos/asf/syncope/blob/74aed4af/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/AbstractTaskITCase.java
----------------------------------------------------------------------
diff --git a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/AbstractTaskITCase.java b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/AbstractTaskITCase.java
index 37bf12c..2d9dae1 100644
--- a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/AbstractTaskITCase.java
+++ b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/AbstractTaskITCase.java
@@ -40,6 +40,7 @@ import org.apache.syncope.common.lib.to.PagedResult;
 import org.apache.syncope.common.lib.to.TaskExecTO;
 import org.apache.syncope.common.lib.to.UserTO;
 import org.apache.syncope.common.lib.types.TaskType;
+import org.apache.syncope.common.rest.api.service.TaskService;
 
 public abstract class AbstractTaskITCase extends AbstractITCase {
 
@@ -51,16 +52,19 @@ public abstract class AbstractTaskITCase extends AbstractITCase {
 
         private final AbstractTaskITCase test;
 
+        private final TaskService taskService;
+
         private final Long taskKey;
 
         private final int maxWaitSeconds;
 
         private final boolean dryRun;
 
-        public ThreadExec(
-                final AbstractTaskITCase test, final Long taskKey, final int maxWaitSeconds, final boolean dryRun) {
+        public ThreadExec(final AbstractTaskITCase test, final TaskService taskService, final Long taskKey,
+                final int maxWaitSeconds, final boolean dryRun) {
 
             this.test = test;
+            this.taskService = taskService;
             this.taskKey = taskKey;
             this.maxWaitSeconds = maxWaitSeconds;
             this.dryRun = dryRun;
@@ -68,7 +72,7 @@ public abstract class AbstractTaskITCase extends AbstractITCase {
 
         @Override
         public TaskExecTO call() throws Exception {
-            return test.execProvisioningTask(taskKey, maxWaitSeconds, dryRun);
+            return test.execProvisioningTask(taskService, taskKey, maxWaitSeconds, dryRun);
         }
     }
 
@@ -87,7 +91,9 @@ public abstract class AbstractTaskITCase extends AbstractITCase {
         }
     }
 
-    protected TaskExecTO execProvisioningTask(final Long taskKey, final int maxWaitSeconds, final boolean dryRun) {
+    public static TaskExecTO execProvisioningTask(
+            final TaskService taskService, final Long taskKey, final int maxWaitSeconds, final boolean dryRun) {
+
         AbstractTaskTO taskTO = taskService.read(taskKey);
         assertNotNull(taskTO);
         assertNotNull(taskTO.getExecutions());
@@ -119,14 +125,14 @@ public abstract class AbstractTaskITCase extends AbstractITCase {
         return taskTO.getExecutions().get(taskTO.getExecutions().size() - 1);
     }
 
-    protected Map<Long, TaskExecTO> execProvisioningTasks(
+    protected Map<Long, TaskExecTO> execProvisioningTasks(final TaskService taskService,
             final Set<Long> taskKeys, final int maxWaitSeconds, final boolean dryRun) throws Exception {
 
         ExecutorService service = Executors.newFixedThreadPool(taskKeys.size());
         List<Future<TaskExecTO>> futures = new ArrayList<>();
 
         for (Long key : taskKeys) {
-            futures.add(service.submit(new ThreadExec(this, key, maxWaitSeconds, dryRun)));
+            futures.add(service.submit(new ThreadExec(this, taskService, key, maxWaitSeconds, dryRun)));
         }
 
         Map<Long, TaskExecTO> res = new HashMap<>();

http://git-wip-us.apache.org/repos/asf/syncope/blob/74aed4af/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/ConnectorITCase.java
----------------------------------------------------------------------
diff --git a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/ConnectorITCase.java b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/ConnectorITCase.java
index 583e3d9..44ebf33 100644
--- a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/ConnectorITCase.java
+++ b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/ConnectorITCase.java
@@ -193,7 +193,7 @@ public class ConnectorITCase extends AbstractITCase {
         assertNotNull(actual);
         assertEquals(EnumSet.of(ConnectorCapability.ONE_PHASE_CREATE, ConnectorCapability.TWO_PHASES_CREATE),
                 actual.getCapabilities());
-        assertEquals(10, actual.getPoolConf().getMaxObjects().intValue());
+        assertEquals(10, actual.getPoolConf().getMaxObjects(), 0);
 
         // check also for the deletion of the created object
         try {
@@ -232,7 +232,7 @@ public class ConnectorITCase extends AbstractITCase {
         connectorTO.setConnRequestTimeout(20);
 
         // set the connector configuration using PropertyTO
-        Set<ConnConfProperty> conf = new HashSet<ConnConfProperty>();
+        Set<ConnConfProperty> conf = new HashSet<>();
 
         ConnConfPropSchema endpointSchema = new ConnConfPropSchema();
         endpointSchema.setName("endpoint");
@@ -685,7 +685,7 @@ public class ConnectorITCase extends AbstractITCase {
 
     @Test
     public void bulkAction() {
-        final BulkAction bulkAction = new BulkAction();
+        BulkAction bulkAction = new BulkAction();
         bulkAction.setType(BulkAction.Type.DELETE);
 
         ConnInstanceTO conn = connectorService.read(101L);
@@ -727,7 +727,6 @@ public class ConnectorITCase extends AbstractITCase {
 
     @Test
     public void issueSYNCOPE605() {
-
         ConnInstanceTO connectorInstanceTO = connectorService.read(103L);
         assertTrue(connectorInstanceTO.getCapabilities().isEmpty());
 

http://git-wip-us.apache.org/repos/asf/syncope/blob/74aed4af/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/DomainITCase.java
----------------------------------------------------------------------
diff --git a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/DomainITCase.java b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/DomainITCase.java
new file mode 100644
index 0000000..e6b1984
--- /dev/null
+++ b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/DomainITCase.java
@@ -0,0 +1,115 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.syncope.fit.core.reference;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.fail;
+
+import java.security.AccessControlException;
+import java.util.List;
+import org.apache.commons.lang3.SerializationUtils;
+import org.apache.syncope.client.lib.SyncopeClientFactoryBean;
+import org.apache.syncope.common.lib.SyncopeClientException;
+import org.apache.syncope.common.lib.to.DomainTO;
+import org.apache.syncope.common.lib.types.CipherAlgorithm;
+import org.apache.syncope.common.lib.types.ClientExceptionType;
+import org.junit.FixMethodOrder;
+import org.junit.Test;
+import org.junit.runners.MethodSorters;
+
+@FixMethodOrder(MethodSorters.JVM)
+public class DomainITCase extends AbstractITCase {
+
+    @Test
+    public void list() {
+        List<DomainTO> domains = domainService.list();
+        assertNotNull(domains);
+        assertFalse(domains.isEmpty());
+        for (DomainTO domain : domains) {
+            assertNotNull(domain);
+        }
+    }
+
+    @Test
+    public void create() {
+        DomainTO domain = new DomainTO();
+        domain.setKey("last");
+        domain.setAdminCipherAlgorithm(CipherAlgorithm.SSHA512);
+        domain.setAdminPwd("password");
+
+        try {
+            domainService.create(domain);
+            fail();
+        } catch (SyncopeClientException e) {
+            assertEquals(ClientExceptionType.NotFound, e.getType());
+        }
+    }
+
+    @Test
+    public void update() {
+        DomainTO two = domainService.read("Two");
+        assertNotNull(two);
+        DomainTO origTwo = SerializationUtils.clone(two);
+
+        try {
+            // 1. change admin pwd for domain Two
+            two.setAdminCipherAlgorithm(CipherAlgorithm.AES);
+            two.setAdminPwd("password3");
+            domainService.update(two);
+
+            // 2. attempt to access with old pwd -> fail
+            try {
+                new SyncopeClientFactoryBean().setAddress(ADDRESS).setDomain("Two").
+                        create(ADMIN_UNAME, "password2").self();
+            } catch (AccessControlException e) {
+                assertNotNull(e);
+            }
+
+            // 3. access with new pwd -> succeed
+            new SyncopeClientFactoryBean().setAddress(ADDRESS).setDomain("Two").
+                    create(ADMIN_UNAME, "password3").self();
+        } finally {
+            // restore old password
+            domainService.create(origTwo);
+        }
+    }
+
+    @Test
+    public void delete() {
+        DomainTO two = domainService.read("Two");
+        assertNotNull(two);
+
+        try {
+            domainService.delete(two.getKey());
+
+            try {
+                domainService.read(two.getKey());
+                fail();
+            } catch (SyncopeClientException e) {
+                assertEquals(ClientExceptionType.NotFound, e.getType());
+            }
+        } finally {
+            // restore old password
+            two.setAdminPwd("password2");
+            domainService.create(two);
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/74aed4af/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/MultitenancyITCase.java
----------------------------------------------------------------------
diff --git a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/MultitenancyITCase.java b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/MultitenancyITCase.java
new file mode 100644
index 0000000..dda5f52
--- /dev/null
+++ b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/MultitenancyITCase.java
@@ -0,0 +1,214 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.syncope.fit.core.reference;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.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.StringUtils;
+import org.apache.syncope.client.lib.SyncopeClient;
+import org.apache.syncope.client.lib.SyncopeClientFactoryBean;
+import org.apache.syncope.common.lib.SyncopeConstants;
+import org.apache.syncope.common.lib.to.ConnInstanceTO;
+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.ProvisionTO;
+import org.apache.syncope.common.lib.to.RealmTO;
+import org.apache.syncope.common.lib.to.ResourceTO;
+import org.apache.syncope.common.lib.to.SyncTaskTO;
+import org.apache.syncope.common.lib.to.TaskExecTO;
+import org.apache.syncope.common.lib.to.UserTO;
+import org.apache.syncope.common.lib.types.AnyTypeKind;
+import org.apache.syncope.common.lib.types.IntMappingType;
+import org.apache.syncope.common.lib.types.LoggerType;
+import org.apache.syncope.common.lib.types.MappingPurpose;
+import org.apache.syncope.common.lib.types.PropagationTaskExecStatus;
+import org.apache.syncope.common.lib.types.SchemaType;
+import org.apache.syncope.common.rest.api.service.ConnectorService;
+import org.apache.syncope.common.rest.api.service.DomainService;
+import org.apache.syncope.common.rest.api.service.LoggerService;
+import org.apache.syncope.common.rest.api.service.RealmService;
+import org.apache.syncope.common.rest.api.service.ResourceService;
+import org.apache.syncope.common.rest.api.service.SchemaService;
+import org.apache.syncope.common.rest.api.service.TaskService;
+import org.apache.syncope.common.rest.api.service.UserService;
+import org.identityconnectors.framework.common.objects.ObjectClass;
+import org.junit.BeforeClass;
+import org.junit.FixMethodOrder;
+import org.junit.Test;
+import org.junit.runners.MethodSorters;
+
+@FixMethodOrder(MethodSorters.JVM)
+public class MultitenancyITCase extends AbstractITCase {
+
+    @BeforeClass
+    public static void restSetup() {
+        clientFactory = new SyncopeClientFactoryBean().setAddress(ADDRESS).setDomain("Two");
+
+        String envContentType = System.getProperty(ENV_KEY_CONTENT_TYPE);
+        if (StringUtils.isNotBlank(envContentType)) {
+            clientFactory.setContentType(envContentType);
+        }
+        LOG.info("Performing IT with content type {}", clientFactory.getContentType().getMediaType());
+
+        adminClient = clientFactory.create(ADMIN_UNAME, "password2");
+    }
+
+    @Test
+    public void masterOnly() {
+        try {
+            adminClient.getService(DomainService.class).read("Two");
+            fail();
+        } catch (AccessControlException e) {
+            assertNotNull(e);
+        }
+
+        try {
+            adminClient.getService(LoggerService.class).list(LoggerType.LOG);
+            fail();
+        } catch (AccessControlException e) {
+            assertNotNull(e);
+        }
+
+        adminClient.getService(LoggerService.class).list(LoggerType.AUDIT);
+    }
+
+    @Test
+    public void readPlainSchemas() {
+        assertEquals(18, adminClient.getService(SchemaService.class).list(SchemaType.PLAIN).size());
+    }
+
+    @Test
+    public void readRealm() {
+        List<RealmTO> realms = adminClient.getService(RealmService.class).list();
+        assertEquals(1, realms.size());
+        assertEquals(SyncopeConstants.ROOT_REALM, realms.get(0).getName());
+    }
+
+    @Test
+    public void createUser() {
+        assertNull(adminClient.getService(RealmService.class).list().get(0).getPasswordPolicy());
+
+        UserTO user = new UserTO();
+        user.setRealm(SyncopeConstants.ROOT_REALM);
+        user.setUsername(getUUIDString());
+        user.setPassword("password");
+
+        Response response = adminClient.getService(UserService.class).create(user);
+        assertEquals(Response.Status.CREATED.getStatusCode(), response.getStatus());
+
+        user = response.readEntity(UserTO.class);
+        assertNotNull(user);
+    }
+
+    @Test
+    public void createResourceAndSync() {
+        // read connector
+        ConnInstanceTO conn = adminClient.getService(ConnectorService.class).read(100L);
+        assertNotNull(conn);
+        assertEquals("LDAP", conn.getDisplayName());
+
+        // prepare resource
+        ResourceTO resource = new ResourceTO();
+        resource.setKey("new-ldap-resource");
+        resource.setConnector(conn.getKey());
+
+        ProvisionTO provisionTO = new ProvisionTO();
+        provisionTO.setAnyType(AnyTypeKind.USER.name());
+        provisionTO.setObjectClass(ObjectClass.ACCOUNT_NAME);
+        resource.getProvisions().add(provisionTO);
+
+        MappingTO mapping = new MappingTO();
+        mapping.setConnObjectLink("'uid=' + username + ',ou=people,o=isp'");
+        provisionTO.setMapping(mapping);
+
+        MappingItemTO item = new MappingItemTO();
+        item.setIntAttrName("username");
+        item.setIntMappingType(IntMappingType.Username);
+        item.setExtAttrName("cn");
+        item.setPurpose(MappingPurpose.BOTH);
+        mapping.setConnObjectKeyItem(item);
+
+        item = new MappingItemTO();
+        item.setPassword(true);
+        item.setIntMappingType(IntMappingType.Password);
+        item.setExtAttrName("userPassword");
+        item.setPurpose(MappingPurpose.BOTH);
+        item.setMandatoryCondition("true");
+        mapping.add(item);
+
+        item = new MappingItemTO();
+        item.setIntMappingType(IntMappingType.UserKey);
+        item.setPurpose(MappingPurpose.BOTH);
+        item.setExtAttrName("sn");
+        item.setMandatoryCondition("true");
+        mapping.add(item);
+
+        item = new MappingItemTO();
+        item.setIntAttrName("email");
+        item.setIntMappingType(IntMappingType.UserPlainSchema);
+        item.setPurpose(MappingPurpose.BOTH);
+        item.setExtAttrName("mail");
+        mapping.add(item);
+
+        // create resource
+        Response response = adminClient.getService(ResourceService.class).create(resource);
+        assertEquals(Response.Status.CREATED.getStatusCode(), response.getStatus());
+        resource = adminClient.getService(ResourceService.class).read(resource.getKey());
+        assertNotNull(resource);
+
+        // create sync task
+        SyncTaskTO task = new SyncTaskTO();
+        task.setName("LDAP Sync Task");
+        task.setDestinationRealm("/");
+        task.setResource(resource.getKey());
+        task.setFullReconciliation(true);
+        task.setPerformCreate(true);
+
+        response = adminClient.getService(TaskService.class).create(task);
+        assertEquals(Response.Status.CREATED.getStatusCode(), response.getStatus());
+        task = adminClient.getService(TaskService.class).read(
+                Long.valueOf(StringUtils.substringAfterLast(response.getLocation().toASCIIString(), "/")));
+        assertNotNull(resource);
+
+        // synchronize
+        TaskExecTO execution = AbstractTaskITCase.execProvisioningTask(
+                adminClient.getService(TaskService.class), task.getKey(), 50, false);
+
+        // verify execution status
+        String status = execution.getStatus();
+        assertNotNull(status);
+        assertTrue(PropagationTaskExecStatus.valueOf(status).isSuccessful());
+
+        // verify that synchronized user is found
+        PagedResult<UserTO> matchingUsers = adminClient.getService(UserService.class).search(
+                SyncopeClient.getAnySearchQueryBuilder().realm(SyncopeConstants.ROOT_REALM).
+                fiql(SyncopeClient.getUserSearchConditionBuilder().is("username").equalTo("syncFromLDAP").query()).
+                build());
+        assertNotNull(matchingUsers);
+        assertEquals(1, matchingUsers.getResult().size());
+    }
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/74aed4af/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/PushTaskITCase.java
----------------------------------------------------------------------
diff --git a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/PushTaskITCase.java b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/PushTaskITCase.java
index ca9d8a4..dff129e 100644
--- a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/PushTaskITCase.java
+++ b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/PushTaskITCase.java
@@ -121,12 +121,12 @@ public class PushTaskITCase extends AbstractTaskITCase {
     public void pushMatchingUnmatchingGroups() {
         assertFalse(groupService.read(3L).getResources().contains(RESOURCE_NAME_LDAP));
 
-        execProvisioningTask(23L, 50, false);
+        execProvisioningTask(taskService, 23L, 50, false);
 
         assertNotNull(resourceService.readConnObject(RESOURCE_NAME_LDAP, AnyTypeKind.GROUP.name(), 3L));
         assertTrue(groupService.read(3L).getResources().contains(RESOURCE_NAME_LDAP));
 
-        execProvisioningTask(23L, 50, false);
+        execProvisioningTask(taskService, 23L, 50, false);
 
         assertNotNull(resourceService.readConnObject(RESOURCE_NAME_LDAP, AnyTypeKind.GROUP.name(), 3L));
         assertFalse(groupService.read(3L).getResources().contains(RESOURCE_NAME_LDAP));
@@ -145,7 +145,7 @@ public class PushTaskITCase extends AbstractTaskITCase {
         // ------------------------------------------
         // Unmatching --> Assign --> dryRuyn
         // ------------------------------------------
-        execProvisioningTask(13L, 50, true);
+        execProvisioningTask(taskService, 13L, 50, true);
         assertEquals(0, jdbcTemplate.queryForList("SELECT ID FROM test2 WHERE ID='vivaldi'").size());
         assertFalse(userService.read(3L).getResources().contains(RESOURCE_NAME_TESTDB2));
         // ------------------------------------------
@@ -155,7 +155,7 @@ public class PushTaskITCase extends AbstractTaskITCase {
         pushTaskIds.add(14L);
         pushTaskIds.add(15L);
         pushTaskIds.add(16L);
-        execProvisioningTasks(pushTaskIds, 50, false);
+        execProvisioningTasks(taskService, pushTaskIds, 50, false);
 
         // ------------------------------------------
         // Unatching --> Ignore
@@ -200,7 +200,7 @@ public class PushTaskITCase extends AbstractTaskITCase {
         // ------------------------------------------
         // Matching --> Deprovision --> dryRuyn
         // ------------------------------------------
-        execProvisioningTask(19L, 50, true);
+        execProvisioningTask(taskService, 19L, 50, true);
         assertTrue(userService.read(1L).getResources().contains(RESOURCE_NAME_TESTDB2));
         assertEquals(1, jdbcTemplate.queryForList("SELECT ID FROM test2 WHERE ID='rossini'").size());
         // ------------------------------------------
@@ -210,7 +210,7 @@ public class PushTaskITCase extends AbstractTaskITCase {
         pushTaskKeys.add(19L);
         pushTaskKeys.add(16L);
 
-        execProvisioningTasks(pushTaskKeys, 50, false);
+        execProvisioningTasks(taskService, pushTaskKeys, 50, false);
 
         // ------------------------------------------
         // Matching --> Deprovision && Ignore
@@ -231,7 +231,7 @@ public class PushTaskITCase extends AbstractTaskITCase {
         // ------------------------------------------
         // Matching --> Link
         // ------------------------------------------
-        execProvisioningTask(20L, 50, false);
+        execProvisioningTask(taskService, 20L, 50, false);
         assertTrue(userService.read(2L).getResources().contains(RESOURCE_NAME_TESTDB2));
         assertEquals(1, jdbcTemplate.queryForList("SELECT ID FROM test2 WHERE ID='verdi'").size());
         // ------------------------------------------
@@ -240,7 +240,7 @@ public class PushTaskITCase extends AbstractTaskITCase {
         pushTaskKeys.add(21L);
         pushTaskKeys.add(22L);
 
-        execProvisioningTasks(pushTaskKeys, 50, false);
+        execProvisioningTasks(taskService, pushTaskKeys, 50, false);
 
         // ------------------------------------------
         // Matching --> Unlink && Update
@@ -325,7 +325,7 @@ public class PushTaskITCase extends AbstractTaskITCase {
             assertNotNull(push);
 
             // execute the new task
-            TaskExecTO pushExec = execProvisioningTask(push.getKey(), 50, false);
+            TaskExecTO pushExec = execProvisioningTask(taskService, push.getKey(), 50, false);
             assertTrue(PropagationTaskExecStatus.valueOf(pushExec.getStatus()).isSuccessful());
         } finally {
             groupService.delete(groupTO.getKey());
@@ -373,7 +373,7 @@ public class PushTaskITCase extends AbstractTaskITCase {
         notification = getObject(responseNotification.getLocation(), NotificationService.class, NotificationTO.class);
         assertNotNull(notification);
 
-        execProvisioningTask(actual.getKey(), 50, false);
+        execProvisioningTask(taskService, actual.getKey(), 50, false);
 
         NotificationTaskTO taskTO = findNotificationTaskBySender("syncope648@syncope.apache.org");
         assertNotNull(taskTO);

http://git-wip-us.apache.org/repos/asf/syncope/blob/74aed4af/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/SyncTaskITCase.java
----------------------------------------------------------------------
diff --git a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/SyncTaskITCase.java b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/SyncTaskITCase.java
index 9f277fa..4313c00 100644
--- a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/SyncTaskITCase.java
+++ b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/SyncTaskITCase.java
@@ -163,7 +163,7 @@ public class SyncTaskITCase extends AbstractTaskITCase {
                     page(1).size(1).build()).getTotalCount();
             assertNotNull(usersPre);
 
-            execProvisioningTask(SYNC_TASK_ID, 50, false);
+            execProvisioningTask(taskService, SYNC_TASK_ID, 50, false);
 
             // after execution of the sync task the user data should have been synced from CSV
             // and processed by user template
@@ -234,7 +234,7 @@ public class SyncTaskITCase extends AbstractTaskITCase {
             Set<Long> otherSyncTaskKeys = new HashSet<>();
             otherSyncTaskKeys.add(25L);
             otherSyncTaskKeys.add(26L);
-            execProvisioningTasks(otherSyncTaskKeys, 50, false);
+            execProvisioningTasks(taskService, otherSyncTaskKeys, 50, false);
 
             // Matching --> UNLINK
             assertFalse(readUser("test9").getResources().contains(RESOURCE_NAME_CSV));
@@ -246,7 +246,7 @@ public class SyncTaskITCase extends AbstractTaskITCase {
 
     @Test
     public void dryRun() {
-        TaskExecTO execution = execProvisioningTask(SYNC_TASK_ID, 50, true);
+        TaskExecTO execution = execProvisioningTask(taskService, SYNC_TASK_ID, 50, true);
         assertEquals("Execution of task " + execution.getTask() + " failed with message " + execution.getMessage(),
                 "SUCCESS", execution.getStatus());
     }
@@ -254,7 +254,7 @@ public class SyncTaskITCase extends AbstractTaskITCase {
     @Test
     public void reconcileFromDB() {
         // update sync task
-        TaskExecTO execution = execProvisioningTask(7L, 50, false);
+        TaskExecTO execution = execProvisioningTask(taskService, 7L, 50, false);
         assertNotNull(execution.getStatus());
         assertTrue(PropagationTaskExecStatus.valueOf(execution.getStatus()).isSuccessful());
 
@@ -268,7 +268,7 @@ public class SyncTaskITCase extends AbstractTaskITCase {
         jdbcTemplate.execute("UPDATE TEST SET STATUS=TRUE");
 
         // re-execute the same SyncTask: now user must be active
-        execution = execProvisioningTask(7L, 50, false);
+        execution = execProvisioningTask(taskService, 7L, 50, false);
         assertNotNull(execution.getStatus());
         assertTrue(PropagationTaskExecStatus.valueOf(execution.getStatus()).isSuccessful());
 
@@ -313,14 +313,14 @@ public class SyncTaskITCase extends AbstractTaskITCase {
         ldapCleanup();
 
         // 0. synchronize
-        TaskExecTO execution = execProvisioningTask(11L, 50, false);
+        TaskExecTO execution = execProvisioningTask(taskService, 11L, 50, false);
 
         // 1. verify execution status
         String status = execution.getStatus();
         assertNotNull(status);
         assertTrue(PropagationTaskExecStatus.valueOf(status).isSuccessful());
 
-        // 2. verify that synchronized group is found, with expected attributes
+        // 2. verify that synchronized group is found
         PagedResult<GroupTO> matchingGroups = groupService.search(
                 SyncopeClient.getAnySearchQueryBuilder().realm(SyncopeConstants.ROOT_REALM).
                 fiql(SyncopeClient.getGroupSearchConditionBuilder().is("name").equalTo("testLDAPGroup").query()).
@@ -328,6 +328,7 @@ public class SyncTaskITCase extends AbstractTaskITCase {
         assertNotNull(matchingGroups);
         assertEquals(1, matchingGroups.getResult().size());
 
+        // 3. verify that synchronized user is found
         PagedResult<UserTO> matchingUsers = userService.search(
                 SyncopeClient.getAnySearchQueryBuilder().realm(SyncopeConstants.ROOT_REALM).
                 fiql(SyncopeClient.getUserSearchConditionBuilder().is("username").equalTo("syncFromLDAP").query()).
@@ -351,7 +352,7 @@ public class SyncTaskITCase extends AbstractTaskITCase {
         assertNull(groupTO.getGroupOwner());
 
         // SYNCOPE-317
-        execProvisioningTask(11L, 50, false);
+        execProvisioningTask(taskService, 11L, 50, false);
     }
 
     @Test
@@ -383,7 +384,7 @@ public class SyncTaskITCase extends AbstractTaskITCase {
         }
 
         // 3. synchronize
-        execProvisioningTask(28L, 50, false);
+        execProvisioningTask(taskService, 28L, 50, false);
 
         // 4. verify that printer was re-created in Syncope
         matchingPrinters = anyObjectService.search(
@@ -456,7 +457,7 @@ public class SyncTaskITCase extends AbstractTaskITCase {
             assertFalse(actual.getTemplates().get(AnyTypeKind.USER.name()).getResources().isEmpty());
             assertFalse(((UserTO) actual.getTemplates().get(AnyTypeKind.USER.name())).getMemberships().isEmpty());
 
-            TaskExecTO execution = execProvisioningTask(actual.getKey(), 50, false);
+            TaskExecTO execution = execProvisioningTask(taskService, actual.getKey(), 50, false);
             final String status = execution.getStatus();
             assertNotNull(status);
             assertTrue(PropagationTaskExecStatus.valueOf(status).isSuccessful());
@@ -475,7 +476,7 @@ public class SyncTaskITCase extends AbstractTaskITCase {
     @Test
     public void issueSYNCOPE230() {
         // 1. read SyncTask for resource-db-sync (table TESTSYNC on external H2)
-        execProvisioningTask(10L, 50, false);
+        execProvisioningTask(taskService, 10L, 50, false);
 
         // 3. read e-mail address for user created by the SyncTask first execution
         UserTO userTO = readUser("issuesyncope230");
@@ -488,7 +489,7 @@ public class SyncTaskITCase extends AbstractTaskITCase {
         jdbcTemplate.execute("UPDATE TESTSYNC SET email='updatedSYNCOPE230@syncope.apache.org'");
 
         // 5. re-execute the SyncTask
-        execProvisioningTask(10L, 50, false);
+        execProvisioningTask(taskService, 10L, 50, false);
 
         // 6. verify that the e-mail was updated
         userTO = readUser("issuesyncope230");
@@ -550,7 +551,7 @@ public class SyncTaskITCase extends AbstractTaskITCase {
 
         userService.update(userMod);
 
-        execProvisioningTask(actual.getKey(), 50, false);
+        execProvisioningTask(taskService, actual.getKey(), 50, false);
 
         SyncTaskTO executed = taskService.read(actual.getKey());
         assertEquals(1, executed.getExecutions().size());
@@ -574,7 +575,7 @@ public class SyncTaskITCase extends AbstractTaskITCase {
             assertEquals(1, userTO.getPropagationStatusTOs().size());
             assertTrue(userTO.getPropagationStatusTOs().get(0).getStatus().isSuccessful());
 
-            TaskExecTO taskExecTO = execProvisioningTask(24L, 50, false);
+            TaskExecTO taskExecTO = execProvisioningTask(taskService, 24L, 50, false);
 
             assertNotNull(taskExecTO.getStatus());
             assertTrue(PropagationTaskExecStatus.valueOf(taskExecTO.getStatus()).isSuccessful());
@@ -623,7 +624,7 @@ public class SyncTaskITCase extends AbstractTaskITCase {
         task.getTemplates().put(AnyTypeKind.USER.name(), template);
 
         taskService.update(task);
-        execProvisioningTask(task.getKey(), 50, false);
+        execProvisioningTask(taskService, task.getKey(), 50, false);
 
         // check for sync policy
         userTO = userService.read(userTO.getKey());
@@ -680,7 +681,7 @@ public class SyncTaskITCase extends AbstractTaskITCase {
         assertEquals(actual.getKey(), syncTask.getKey());
         assertEquals(actual.getJobDelegateClassName(), syncTask.getJobDelegateClassName());
 
-        TaskExecTO execution = execProvisioningTask(syncTask.getKey(), 50, false);
+        TaskExecTO execution = execProvisioningTask(taskService, syncTask.getKey(), 50, false);
         final String status = execution.getStatus();
         assertNotNull(status);
         assertTrue(PropagationTaskExecStatus.valueOf(status).isSuccessful());
@@ -757,7 +758,7 @@ public class SyncTaskITCase extends AbstractTaskITCase {
         assertEquals(actual.getKey(), syncTask.getKey());
         assertEquals(actual.getJobDelegateClassName(), syncTask.getJobDelegateClassName());
 
-        TaskExecTO execution = execProvisioningTask(syncTask.getKey(), 50, false);
+        TaskExecTO execution = execProvisioningTask(taskService, syncTask.getKey(), 50, false);
         String status = execution.getStatus();
         assertNotNull(status);
         assertTrue(PropagationTaskExecStatus.valueOf(status).isSuccessful());


[20/31] syncope git commit: [SYNCOPE-652] Still several things to refine, but it starts taking shape

Posted by md...@apache.org.
http://git-wip-us.apache.org/repos/asf/syncope/blob/6dfedd8f/core/logic/src/main/java/org/apache/syncope/core/logic/audit/AuditConnectionFactory.java
----------------------------------------------------------------------
diff --git a/core/logic/src/main/java/org/apache/syncope/core/logic/audit/AuditConnectionFactory.java b/core/logic/src/main/java/org/apache/syncope/core/logic/audit/AuditConnectionFactory.java
deleted file mode 100644
index b35c42d..0000000
--- a/core/logic/src/main/java/org/apache/syncope/core/logic/audit/AuditConnectionFactory.java
+++ /dev/null
@@ -1,159 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.syncope.core.logic.audit;
-
-import java.io.InputStream;
-import java.sql.Connection;
-import java.util.Properties;
-import javax.naming.Context;
-import javax.naming.InitialContext;
-import javax.rmi.PortableRemoteObject;
-import javax.sql.DataSource;
-import javax.xml.xpath.XPath;
-import javax.xml.xpath.XPathConstants;
-import javax.xml.xpath.XPathExpression;
-import javax.xml.xpath.XPathFactory;
-import org.apache.commons.dbcp2.BasicDataSource;
-import org.apache.commons.io.IOUtils;
-import org.springframework.core.io.ClassPathResource;
-import org.springframework.core.io.FileSystemResource;
-import org.springframework.core.io.Resource;
-import org.springframework.core.io.support.PropertiesLoaderUtils;
-import org.springframework.jdbc.datasource.DataSourceUtils;
-import org.springframework.jdbc.datasource.init.ResourceDatabasePopulator;
-import org.springframework.jdbc.datasource.init.ScriptUtils;
-import org.w3c.dom.Document;
-import org.w3c.dom.bootstrap.DOMImplementationRegistry;
-import org.w3c.dom.ls.DOMImplementationLS;
-import org.w3c.dom.ls.LSInput;
-import org.w3c.dom.ls.LSParser;
-
-/**
- * LOG4J SQL connection factory that first attempts to obtain a {@link javax.sql.DataSource} from the JNDI name
- * configured in Spring or, when not found, builds a new {@link javax.sql.DataSource DataSource} via Commons DBCP; if
- * any datasource if found, the SQL init script is used to populate the database.
- */
-public final class AuditConnectionFactory {
-
-    private static DataSource DATASOURCE;
-
-    private static final String PERSISTENCE_CONTEXT = "/persistenceContext.xml";
-
-    static {
-        // 1. Attempts to lookup for configured JNDI datasource (if present and available)
-        InputStream springConf = AuditConnectionFactory.class.getResourceAsStream(PERSISTENCE_CONTEXT);
-        String primary = null;
-        String fallback = null;
-        try {
-            DOMImplementationRegistry reg = DOMImplementationRegistry.newInstance();
-            DOMImplementationLS impl = (DOMImplementationLS) reg.getDOMImplementation("LS");
-            LSParser parser = impl.createLSParser(DOMImplementationLS.MODE_SYNCHRONOUS, null);
-            LSInput lsinput = impl.createLSInput();
-            lsinput.setByteStream(springConf);
-            Document source = parser.parse(lsinput);
-
-            XPathFactory xPathfactory = XPathFactory.newInstance();
-            XPath xpath = xPathfactory.newXPath();
-
-            XPathExpression expr = xpath.compile("//*[local-name()='bean' and @id='persistenceProperties']/"
-                    + "child::*[local-name()='property' and @name='primary']/@value");
-            primary = (String) expr.evaluate(source, XPathConstants.STRING);
-            expr = xpath.compile("//*[local-name()='bean' and @id='persistenceProperties']/"
-                    + "child::*[local-name()='property' and @name='fallback']/@value");
-            fallback = (String) expr.evaluate(source, XPathConstants.STRING);
-
-            expr = xpath.compile("//*[local-name()='property' and @name='jndiName']/@value");
-            String jndiName = (String) expr.evaluate(source, XPathConstants.STRING);
-
-            Context ctx = new InitialContext();
-            Object obj = ctx.lookup(jndiName);
-
-            DATASOURCE = (DataSource) PortableRemoteObject.narrow(obj, DataSource.class);
-        } catch (Exception e) {
-            // ignore
-        } finally {
-            IOUtils.closeQuietly(springConf);
-        }
-
-        // 2. Creates Commons DBCP datasource
-        String initSQLScript = null;
-        try {
-            Resource persistenceProperties = null;
-            if (primary != null) {
-                if (primary.startsWith("file:")) {
-                    persistenceProperties = new FileSystemResource(primary.substring(5));
-                }
-                if (primary.startsWith("classpath:")) {
-                    persistenceProperties = new ClassPathResource(primary.substring(10));
-                }
-            }
-            if ((persistenceProperties == null || !persistenceProperties.exists()) && fallback != null) {
-                if (fallback.startsWith("file:")) {
-                    persistenceProperties = new FileSystemResource(fallback.substring(5));
-                }
-                if (fallback.startsWith("classpath:")) {
-                    persistenceProperties = new ClassPathResource(fallback.substring(10));
-                }
-            }
-            Properties persistence = PropertiesLoaderUtils.loadProperties(persistenceProperties);
-
-            initSQLScript = persistence.getProperty("audit.sql");
-
-            if (DATASOURCE == null) {
-                BasicDataSource bds = new BasicDataSource();
-                bds.setDriverClassName(persistence.getProperty("jpa.driverClassName"));
-                bds.setUrl(persistence.getProperty("jpa.url"));
-                bds.setUsername(persistence.getProperty("jpa.username"));
-                bds.setPassword(persistence.getProperty("jpa.password"));
-
-                bds.setLogAbandoned(true);
-                bds.setRemoveAbandonedOnBorrow(true);
-                bds.setRemoveAbandonedOnMaintenance(true);
-
-                DATASOURCE = bds;
-            }
-        } catch (Exception e) {
-            throw new IllegalStateException("Audit datasource configuration failed", e);
-        }
-
-        // 3. Initializes the chosen datasource
-        ResourceDatabasePopulator populator = new ResourceDatabasePopulator();
-        populator.setScripts(new Resource[] { new ClassPathResource("/audit/" + initSQLScript) });
-        // forces no statement separation
-        populator.setSeparator(ScriptUtils.EOF_STATEMENT_SEPARATOR);
-        Connection conn = DataSourceUtils.getConnection(DATASOURCE);
-        try {
-            populator.populate(conn);
-        } finally {
-            DataSourceUtils.releaseConnection(conn, DATASOURCE);
-        }
-    }
-
-    public static Connection getConnection() {
-        if (DATASOURCE != null) {
-            return DataSourceUtils.getConnection(DATASOURCE);
-        }
-
-        throw new IllegalStateException("Audit dataSource init failed: check logs");
-    }
-
-    private AuditConnectionFactory() {
-        // empty constructor for static utility class
-    }
-}

http://git-wip-us.apache.org/repos/asf/syncope/blob/6dfedd8f/core/logic/src/main/java/org/apache/syncope/core/logic/init/ImplementationClassNamesLoader.java
----------------------------------------------------------------------
diff --git a/core/logic/src/main/java/org/apache/syncope/core/logic/init/ImplementationClassNamesLoader.java b/core/logic/src/main/java/org/apache/syncope/core/logic/init/ImplementationClassNamesLoader.java
index b22a54d..2bcd78f 100644
--- a/core/logic/src/main/java/org/apache/syncope/core/logic/init/ImplementationClassNamesLoader.java
+++ b/core/logic/src/main/java/org/apache/syncope/core/logic/init/ImplementationClassNamesLoader.java
@@ -25,9 +25,6 @@ import java.util.HashSet;
 import java.util.Map;
 import java.util.Set;
 import org.apache.commons.lang3.StringUtils;
-import org.apache.syncope.core.provisioning.api.job.PushJob;
-import org.apache.syncope.core.provisioning.api.job.SyncJob;
-import org.apache.syncope.core.provisioning.api.job.TaskJob;
 import org.apache.syncope.core.provisioning.api.propagation.PropagationActions;
 import org.apache.syncope.core.provisioning.api.sync.PushActions;
 import org.apache.syncope.core.provisioning.api.sync.SyncActions;
@@ -35,6 +32,9 @@ import org.apache.syncope.core.provisioning.api.sync.SyncCorrelationRule;
 import org.apache.syncope.core.logic.report.Reportlet;
 import org.apache.syncope.core.persistence.api.SyncopeLoader;
 import org.apache.syncope.core.persistence.api.attrvalue.validation.Validator;
+import org.apache.syncope.core.provisioning.api.job.SchedTaskJobDelegate;
+import org.apache.syncope.core.provisioning.java.sync.PushJobDelegate;
+import org.apache.syncope.core.provisioning.java.sync.SyncJobDelegate;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.springframework.beans.factory.config.BeanDefinition;
@@ -52,7 +52,7 @@ public class ImplementationClassNamesLoader implements SyncopeLoader {
     public enum Type {
 
         REPORTLET,
-        TASKJOB,
+        TASKJOBDELEGATE,
         PROPAGATION_ACTIONS,
         SYNC_ACTIONS,
         PUSH_ACTIONS,
@@ -83,7 +83,7 @@ public class ImplementationClassNamesLoader implements SyncopeLoader {
 
         ClassPathScanningCandidateComponentProvider scanner = new ClassPathScanningCandidateComponentProvider(false);
         scanner.addIncludeFilter(new AssignableTypeFilter(Reportlet.class));
-        scanner.addIncludeFilter(new AssignableTypeFilter(TaskJob.class));
+        scanner.addIncludeFilter(new AssignableTypeFilter(SchedTaskJobDelegate.class));
         scanner.addIncludeFilter(new AssignableTypeFilter(SyncActions.class));
         scanner.addIncludeFilter(new AssignableTypeFilter(PushActions.class));
         scanner.addIncludeFilter(new AssignableTypeFilter(SyncCorrelationRule.class));
@@ -102,11 +102,11 @@ public class ImplementationClassNamesLoader implements SyncopeLoader {
                     classNames.get(Type.REPORTLET).add(clazz.getName());
                 }
 
-                if (TaskJob.class.isAssignableFrom(clazz) && !isAbsractClazz
-                        && !SyncJob.class.isAssignableFrom(clazz)
-                        && !PushJob.class.isAssignableFrom(clazz)) {
+                if (SchedTaskJobDelegate.class.isAssignableFrom(clazz) && !isAbsractClazz
+                        && !SyncJobDelegate.class.isAssignableFrom(clazz)
+                        && !PushJobDelegate.class.isAssignableFrom(clazz)) {
 
-                    classNames.get(Type.TASKJOB).add(bd.getBeanClassName());
+                    classNames.get(Type.TASKJOBDELEGATE).add(bd.getBeanClassName());
                 }
 
                 if (SyncActions.class.isAssignableFrom(clazz) && !isAbsractClazz) {

http://git-wip-us.apache.org/repos/asf/syncope/blob/6dfedd8f/core/logic/src/main/java/org/apache/syncope/core/logic/init/JobInstanceLoaderImpl.java
----------------------------------------------------------------------
diff --git a/core/logic/src/main/java/org/apache/syncope/core/logic/init/JobInstanceLoaderImpl.java b/core/logic/src/main/java/org/apache/syncope/core/logic/init/JobInstanceLoaderImpl.java
index 6a8289a..3e7e90f 100644
--- a/core/logic/src/main/java/org/apache/syncope/core/logic/init/JobInstanceLoaderImpl.java
+++ b/core/logic/src/main/java/org/apache/syncope/core/logic/init/JobInstanceLoaderImpl.java
@@ -19,11 +19,13 @@
 package org.apache.syncope.core.logic.init;
 
 import java.text.ParseException;
-import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashMap;
 import java.util.HashSet;
-import java.util.List;
+import java.util.Map;
 import java.util.Set;
 import org.apache.commons.lang3.StringUtils;
+import org.apache.syncope.common.lib.SyncopeConstants;
 import org.apache.syncope.common.lib.types.TaskType;
 import org.apache.syncope.core.persistence.api.dao.ConfDAO;
 import org.apache.syncope.core.persistence.api.dao.NotFoundException;
@@ -37,17 +39,17 @@ import org.apache.syncope.core.persistence.api.entity.task.SyncTask;
 import org.apache.syncope.core.persistence.api.entity.task.Task;
 import org.apache.syncope.core.provisioning.api.job.JobInstanceLoader;
 import org.apache.syncope.core.provisioning.api.job.JobNamer;
-import org.apache.syncope.core.provisioning.api.job.SyncJob;
-import org.apache.syncope.core.provisioning.api.job.TaskJob;
-import org.apache.syncope.core.provisioning.api.sync.SyncActions;
 import org.apache.syncope.core.logic.notification.NotificationJob;
 import org.apache.syncope.core.logic.report.ReportJob;
+import org.apache.syncope.core.misc.security.AuthContextUtils;
 import org.apache.syncope.core.misc.spring.ApplicationContextProvider;
 import org.apache.syncope.core.persistence.api.SyncopeLoader;
-import org.apache.syncope.core.provisioning.api.job.PushJob;
-import org.apache.syncope.core.provisioning.java.sync.PushJobImpl;
-import org.apache.syncope.core.provisioning.java.sync.SyncJobImpl;
+import org.apache.syncope.core.persistence.api.DomainsHolder;
+import org.apache.syncope.core.provisioning.java.job.TaskJob;
+import org.apache.syncope.core.provisioning.java.sync.PushJobDelegate;
+import org.apache.syncope.core.provisioning.java.sync.SyncJobDelegate;
 import org.quartz.Job;
+import org.quartz.JobDataMap;
 import org.quartz.JobExecutionContext;
 import org.quartz.JobKey;
 import org.quartz.Scheduler;
@@ -70,6 +72,9 @@ public class JobInstanceLoaderImpl implements JobInstanceLoader, SyncopeLoader {
     private static final Logger LOG = LoggerFactory.getLogger(JobInstanceLoader.class);
 
     @Autowired
+    private DomainsHolder domainsHolder;
+
+    @Autowired
     private SchedulerFactoryBean scheduler;
 
     @Autowired
@@ -81,7 +86,8 @@ public class JobInstanceLoaderImpl implements JobInstanceLoader, SyncopeLoader {
     @Autowired
     private ConfDAO confDAO;
 
-    private void registerJob(final String jobName, final Job jobInstance, final String cronExpression)
+    private void registerJob(
+            final String jobName, final Job jobInstance, final String cronExpression, final Map<String, Object> jobMap)
             throws SchedulerException, ParseException {
 
         synchronized (scheduler.getScheduler()) {
@@ -112,6 +118,7 @@ public class JobInstanceLoaderImpl implements JobInstanceLoader, SyncopeLoader {
         jobDetail.setName(jobName);
         jobDetail.setGroup(Scheduler.DEFAULT_GROUP);
         jobDetail.setJobClass(jobInstance.getClass());
+        jobDetail.setJobDataMap(new JobDataMap(jobMap));
 
         // 3. Trigger
         if (cronExpression == null) {
@@ -127,12 +134,13 @@ public class JobInstanceLoaderImpl implements JobInstanceLoader, SyncopeLoader {
         }
     }
 
-    private Job createSpringBean(final Class<?> jobClass) {
-        Job jobInstance = null;
+    @SuppressWarnings("unchecked")
+    private <T> T createSpringBean(final Class<T> jobClass) {
+        T jobInstance = null;
         for (int i = 0; i < 5 && jobInstance == null; i++) {
             LOG.debug("{} attempt to create Spring bean for {}", i, jobClass);
             try {
-                jobInstance = (Job) ApplicationContextProvider.getBeanFactory().
+                jobInstance = (T) ApplicationContextProvider.getBeanFactory().
                         createBean(jobClass, AbstractBeanDefinition.AUTOWIRE_BY_TYPE, false);
                 LOG.debug("{} attempt to create Spring bean for {} succeeded", i, jobClass);
             } catch (BeanCreationException e) {
@@ -151,75 +159,43 @@ public class JobInstanceLoaderImpl implements JobInstanceLoader, SyncopeLoader {
         return jobInstance;
     }
 
-    @SuppressWarnings("unchecked")
     @Override
-    public void registerJob(final Task task, final String jobClassName, final String cronExpression)
-            throws ClassNotFoundException, SchedulerException, ParseException {
-
-        Class<?> jobClass = Class.forName(jobClassName);
-        if (SyncJob.class.equals(jobClass)) {
-            jobClass = SyncJobImpl.class;
-        } else if (PushJob.class.equals(jobClass)) {
-            jobClass = PushJobImpl.class;
-        }
-
-        Job jobInstance = createSpringBean(jobClass);
-        if (jobInstance instanceof TaskJob) {
-            ((TaskJob) jobInstance).setTaskId(task.getKey());
-        }
-
-        // In case of synchronization job/task retrieve and set synchronization actions:
-        // actions cannot be changed at runtime but connector and synchronization policies (reloaded at execution time).
-        if (jobInstance instanceof SyncJob && task instanceof SyncTask) {
-            final List<SyncActions> actions = new ArrayList<>();
-            for (String className : ((SyncTask) task).getActionsClassNames()) {
-                try {
-                    Class<?> actionsClass = Class.forName(className);
-
-                    SyncActions syncActions = (SyncActions) ApplicationContextProvider.getBeanFactory().
-                            createBean(actionsClass, AbstractBeanDefinition.AUTOWIRE_BY_TYPE, true);
-                    actions.add(syncActions);
-                } catch (Exception e) {
-                    LOG.info("Class '{}' not found", className, e);
-                }
-            }
+    public Map<String, Object> registerJob(final SchedTask task, final long interruptMaxRetries)
+            throws SchedulerException, ParseException {
 
-            ((SyncJob) jobInstance).setActions(actions);
-        }
+        TaskJob job = createSpringBean(TaskJob.class);
+        job.setTaskKey(task.getKey());
 
-        registerJob(JobNamer.getJobName(task), jobInstance, cronExpression);
-    }
+        String jobDelegateClassName = task instanceof SyncTask
+                ? SyncJobDelegate.class.getName()
+                : task instanceof PushTask
+                        ? PushJobDelegate.class.getName()
+                        : task.getJobDelegateClassName();
 
-    @Transactional(readOnly = true)
-    @Override
-    public void registerTaskJob(final Long taskKey)
-            throws ClassNotFoundException, SchedulerException, ParseException {
+        Map<String, Object> jobMap = new HashMap<>();
+        jobMap.put(JobInstanceLoader.DOMAIN, AuthContextUtils.getDomain());
+        jobMap.put(TaskJob.DELEGATE_CLASS_KEY, jobDelegateClassName);
+        jobMap.put(TaskJob.INTERRUPT_MAX_RETRIES_KEY, interruptMaxRetries);
 
-        SchedTask task = taskDAO.find(taskKey);
-        if (task == null) {
-            throw new NotFoundException("Task " + taskKey);
-        } else {
-            registerJob(task, task.getJobClassName(), task.getCronExpression());
-        }
+        registerJob(JobNamer.getJobName(task), job, task.getCronExpression(), jobMap);
+        return jobMap;
     }
 
     @Override
     public void registerJob(final Report report) throws SchedulerException, ParseException {
-        Job jobInstance = createSpringBean(ReportJob.class);
-        ((ReportJob) jobInstance).setReportKey(report.getKey());
+        ReportJob job = createSpringBean(ReportJob.class);
+        job.setReportKey(report.getKey());
+
+        Map<String, Object> jobMap = new HashMap<>();
+        jobMap.put(JobInstanceLoader.DOMAIN, AuthContextUtils.getDomain());
 
-        registerJob(JobNamer.getJobName(report), jobInstance, report.getCronExpression());
+        registerJob(JobNamer.getJobName(report), job, report.getCronExpression(), jobMap);
     }
 
-    @Transactional(readOnly = true)
-    @Override
-    public void registerReportJob(final Long reportKey) throws SchedulerException, ParseException {
-        Report report = reportDAO.find(reportKey);
-        if (report == null) {
-            throw new NotFoundException("Report " + reportKey);
-        } else {
-            registerJob(report);
-        }
+    private void registerNotificationJob(final String cronExpression) throws SchedulerException, ParseException {
+        NotificationJob job = createSpringBean(NotificationJob.class);
+
+        registerJob("taskNotificationJob", job, cronExpression, Collections.<String, Object>emptyMap());
     }
 
     private void unregisterJob(final String jobName) {
@@ -253,41 +229,62 @@ public class JobInstanceLoaderImpl implements JobInstanceLoader, SyncopeLoader {
     @Transactional
     @Override
     public void load() {
-        // 1. jobs for SchedTasks
-        Set<SchedTask> tasks = new HashSet<>(taskDAO.<SchedTask>findAll(TaskType.SCHEDULED));
-        tasks.addAll(taskDAO.<SyncTask>findAll(TaskType.SYNCHRONIZATION));
-        tasks.addAll(taskDAO.<PushTask>findAll(TaskType.PUSH));
-        for (SchedTask task : tasks) {
+        AuthContextUtils.setFakeAuth(SyncopeConstants.MASTER_DOMAIN);
+        String notificationJobCronExpression = StringUtils.EMPTY;
+        long interruptMaxRetries = 1;
+        try {
+            CPlainAttr notificationJobCronExp =
+                    confDAO.find("notificationjob.cronExpression", NotificationJob.DEFAULT_CRON_EXP);
+            if (!notificationJobCronExp.getValuesAsStrings().isEmpty()) {
+                notificationJobCronExpression = notificationJobCronExp.getValuesAsStrings().get(0);
+            }
+
+            interruptMaxRetries = confDAO.find("tasks.interruptMaxRetries", "1").getValues().get(0).getLongValue();
+        } finally {
+            AuthContextUtils.clearFakeAuth();
+        }
+
+        for (String domain : domainsHolder.getDomains().keySet()) {
+            AuthContextUtils.setFakeAuth(domain);
+
             try {
-                registerJob(task, task.getJobClassName(), task.getCronExpression());
-            } catch (Exception e) {
-                LOG.error("While loading job instance for task " + task.getKey(), e);
+                // 1. jobs for SchedTasks
+                Set<SchedTask> tasks = new HashSet<>(taskDAO.<SchedTask>findAll(TaskType.SCHEDULED));
+                tasks.addAll(taskDAO.<SyncTask>findAll(TaskType.SYNCHRONIZATION));
+                tasks.addAll(taskDAO.<PushTask>findAll(TaskType.PUSH));
+                for (SchedTask task : tasks) {
+                    try {
+                        registerJob(task, interruptMaxRetries);
+                    } catch (Exception e) {
+                        LOG.error("While loading job instance for task " + task.getKey(), e);
+                    }
+                }
+
+                // 2. ReportJobs
+                for (Report report : reportDAO.findAll()) {
+                    try {
+                        registerJob(report);
+                    } catch (Exception e) {
+                        LOG.error("While loading job instance for report " + report.getName(), e);
+                    }
+                }
+            } finally {
+                AuthContextUtils.clearFakeAuth();
             }
         }
 
-        // 2. NotificationJob
-        CPlainAttr notificationJobCronExp =
-                confDAO.find("notificationjob.cronExpression", NotificationJob.DEFAULT_CRON_EXP);
-        if (StringUtils.isBlank(notificationJobCronExp.getValuesAsStrings().get(0))) {
+        // 3. NotificationJob
+        if (StringUtils.isBlank(notificationJobCronExpression)) {
             LOG.debug("Empty value provided for NotificationJob's cron, not registering anything on Quartz");
         } else {
             LOG.debug("NotificationJob's cron expression: {} - registering Quartz job and trigger",
-                    notificationJobCronExp);
+                    notificationJobCronExpression);
 
             try {
-                registerJob(null, NotificationJob.class.getName(), notificationJobCronExp.getValuesAsStrings().get(0));
+                registerNotificationJob(notificationJobCronExpression);
             } catch (Exception e) {
                 LOG.error("While loading NotificationJob instance", e);
             }
         }
-
-        // 3. ReportJobs
-        for (Report report : reportDAO.findAll()) {
-            try {
-                registerJob(report);
-            } catch (Exception e) {
-                LOG.error("While loading job instance for report " + report.getName(), e);
-            }
-        }
     }
 }

http://git-wip-us.apache.org/repos/asf/syncope/blob/6dfedd8f/core/logic/src/main/java/org/apache/syncope/core/logic/init/LoggerLoader.java
----------------------------------------------------------------------
diff --git a/core/logic/src/main/java/org/apache/syncope/core/logic/init/LoggerLoader.java b/core/logic/src/main/java/org/apache/syncope/core/logic/init/LoggerLoader.java
index 447a92f..e86b46a 100644
--- a/core/logic/src/main/java/org/apache/syncope/core/logic/init/LoggerLoader.java
+++ b/core/logic/src/main/java/org/apache/syncope/core/logic/init/LoggerLoader.java
@@ -18,19 +18,30 @@
  */
 package org.apache.syncope.core.logic.init;
 
+import java.sql.Connection;
+import java.sql.SQLException;
 import java.util.HashMap;
 import java.util.Map;
+import javax.sql.DataSource;
+import org.apache.logging.log4j.Level;
 import org.apache.logging.log4j.LogManager;
+import org.apache.logging.log4j.core.Appender;
 import org.apache.logging.log4j.core.LoggerContext;
+import org.apache.logging.log4j.core.appender.db.jdbc.ColumnConfig;
+import org.apache.logging.log4j.core.appender.db.jdbc.ConnectionSource;
+import org.apache.logging.log4j.core.appender.db.jdbc.JdbcAppender;
 import org.apache.logging.log4j.core.config.LoggerConfig;
 import org.apache.syncope.common.lib.SyncopeConstants;
 import org.apache.syncope.common.lib.types.LoggerLevel;
 import org.apache.syncope.common.lib.types.LoggerType;
+import org.apache.syncope.core.misc.AuditManager;
+import org.apache.syncope.core.persistence.api.DomainsHolder;
 import org.apache.syncope.core.persistence.api.SyncopeLoader;
 import org.apache.syncope.core.persistence.api.dao.LoggerDAO;
 import org.apache.syncope.core.persistence.api.entity.EntityFactory;
 import org.apache.syncope.core.persistence.api.entity.Logger;
 import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.jdbc.datasource.DataSourceUtils;
 import org.springframework.stereotype.Component;
 import org.springframework.transaction.annotation.Transactional;
 
@@ -38,6 +49,9 @@ import org.springframework.transaction.annotation.Transactional;
 public class LoggerLoader implements SyncopeLoader {
 
     @Autowired
+    private DomainsHolder domainsHolder;
+
+    @Autowired
     private LoggerDAO loggerDAO;
 
     @Autowired
@@ -51,6 +65,39 @@ public class LoggerLoader implements SyncopeLoader {
     @Transactional
     @Override
     public void load() {
+        LoggerContext ctx = (LoggerContext) LogManager.getContext(false);
+
+        // 1. Audit table and DataSource for each configured domain
+        ColumnConfig[] columns = {
+            ColumnConfig.createColumnConfig(ctx.getConfiguration(), "EVENT_DATE", null, null, "true", null, null),
+            ColumnConfig.createColumnConfig(ctx.getConfiguration(), "LOGGER_LEVEL", "%level", null, null, null, null),
+            ColumnConfig.createColumnConfig(ctx.getConfiguration(), "LOGGER", "%logger", null, null, null, null),
+            ColumnConfig.createColumnConfig(ctx.getConfiguration(), "MESSAGE", "%message", null, null, null, null),
+            ColumnConfig.createColumnConfig(ctx.getConfiguration(), "THROWABLE", "%ex{full}", null, null, null, null)
+        };
+        for (Map.Entry<String, DataSource> entry : domainsHolder.getDomains().entrySet()) {
+            Appender appender = ctx.getConfiguration().getAppender("audit_for_" + entry.getKey());
+            if (appender == null) {
+                appender = JdbcAppender.createAppender(
+                        "audit_for_" + entry.getKey(),
+                        "false",
+                        null,
+                        new DataSourceConnectionSource(entry.getValue()),
+                        "0",
+                        "SYNCOPEAUDIT",
+                        columns);
+                appender.start();
+                ctx.getConfiguration().addAppender(appender);
+            }
+
+            LoggerConfig logConf = new LoggerConfig(
+                    AuditManager.getDomainAuditLoggerName(entry.getKey()), null, false);
+            logConf.addAppender(appender, Level.DEBUG, null);
+            ctx.getConfiguration().addLogger(AuditManager.getDomainAuditLoggerName(entry.getKey()), logConf);
+        }
+        ctx.updateLoggers();
+
+        // 2. Aligning log4j conf with database content
         Map<String, Logger> syncopeLoggers = new HashMap<>();
         for (Logger syncopeLogger : loggerDAO.findAll(LoggerType.LOG)) {
             syncopeLoggers.put(syncopeLogger.getKey(), syncopeLogger);
@@ -60,8 +107,6 @@ public class LoggerLoader implements SyncopeLoader {
             syncopeLoggers.put(syncopeLogger.getKey(), syncopeLogger);
         }
 
-        LoggerContext ctx = (LoggerContext) LogManager.getContext(false);
-
         /*
          * Traverse all defined log4j loggers: if there is a matching SyncopeLogger, set log4j level accordingly,
          * otherwise create a SyncopeLogger instance with given name and level.
@@ -95,4 +140,19 @@ public class LoggerLoader implements SyncopeLoader {
 
         ctx.updateLoggers();
     }
+
+    private static class DataSourceConnectionSource implements ConnectionSource {
+
+        private final DataSource dataSource;
+
+        public DataSourceConnectionSource(final DataSource dataSource) {
+            this.dataSource = dataSource;
+        }
+
+        @Override
+        public Connection getConnection() throws SQLException {
+            return DataSourceUtils.getConnection(dataSource);
+        }
+
+    }
 }

http://git-wip-us.apache.org/repos/asf/syncope/blob/6dfedd8f/core/logic/src/main/java/org/apache/syncope/core/logic/init/LogicInitializer.java
----------------------------------------------------------------------
diff --git a/core/logic/src/main/java/org/apache/syncope/core/logic/init/LogicInitializer.java b/core/logic/src/main/java/org/apache/syncope/core/logic/init/LogicInitializer.java
index 9ae6aa9..856fa13 100644
--- a/core/logic/src/main/java/org/apache/syncope/core/logic/init/LogicInitializer.java
+++ b/core/logic/src/main/java/org/apache/syncope/core/logic/init/LogicInitializer.java
@@ -23,6 +23,7 @@ import java.util.Collections;
 import java.util.Comparator;
 import java.util.List;
 import java.util.Map;
+import org.apache.syncope.core.misc.spring.ApplicationContextProvider;
 import org.apache.syncope.core.persistence.api.SyncopeLoader;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -61,6 +62,8 @@ public class LogicInitializer implements InitializingBean, BeanFactoryAware {
             }
         });
 
+        ApplicationContextProvider.setBeanFactory(beanFactory);
+
         LOG.debug("Starting initialization...");
         for (SyncopeLoader loader : loaders) {
             LOG.debug("Invoking {} with priority {}", AopUtils.getTargetClass(loader).getName(), loader.getPriority());

http://git-wip-us.apache.org/repos/asf/syncope/blob/6dfedd8f/core/logic/src/main/java/org/apache/syncope/core/logic/notification/NotificationJob.java
----------------------------------------------------------------------
diff --git a/core/logic/src/main/java/org/apache/syncope/core/logic/notification/NotificationJob.java b/core/logic/src/main/java/org/apache/syncope/core/logic/notification/NotificationJob.java
index 9e40ff1..a0f21f3 100644
--- a/core/logic/src/main/java/org/apache/syncope/core/logic/notification/NotificationJob.java
+++ b/core/logic/src/main/java/org/apache/syncope/core/logic/notification/NotificationJob.java
@@ -18,21 +18,8 @@
  */
 package org.apache.syncope.core.logic.notification;
 
-import java.util.Date;
-import java.util.Properties;
-import javax.mail.internet.MimeMessage;
-import org.apache.commons.lang3.StringUtils;
-import org.apache.syncope.common.lib.types.AuditElements;
-import org.apache.syncope.common.lib.types.AuditElements.Result;
-import org.apache.syncope.common.lib.types.TaskType;
-import org.apache.syncope.common.lib.types.TraceLevel;
-import org.apache.syncope.core.persistence.api.dao.TaskDAO;
-import org.apache.syncope.core.persistence.api.entity.EntityFactory;
-import org.apache.syncope.core.persistence.api.entity.task.NotificationTask;
-import org.apache.syncope.core.persistence.api.entity.task.TaskExec;
-import org.apache.syncope.core.misc.AuditManager;
-import org.apache.syncope.core.misc.ExceptionUtils2;
-import org.apache.syncope.core.provisioning.api.notification.NotificationManager;
+import org.apache.syncope.core.misc.security.AuthContextUtils;
+import org.apache.syncope.core.persistence.api.DomainsHolder;
 import org.quartz.DisallowConcurrentExecution;
 import org.quartz.Job;
 import org.quartz.JobExecutionContext;
@@ -40,15 +27,12 @@ import org.quartz.JobExecutionException;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.mail.javamail.JavaMailSender;
-import org.springframework.mail.javamail.JavaMailSenderImpl;
-import org.springframework.mail.javamail.MimeMessageHelper;
 import org.springframework.stereotype.Component;
 
 /**
  * Periodically checks for notification to send.
  *
- * @see NotificationTask
+ * @see org.apache.syncope.core.persistence.api.entity.task.NotificationTask
  */
 @Component
 @DisallowConcurrentExecution
@@ -63,221 +47,30 @@ public class NotificationJob implements Job {
 
     public static final String DEFAULT_CRON_EXP = "0 0/5 * * * ?";
 
-    /**
-     * Logger.
-     */
     private static final Logger LOG = LoggerFactory.getLogger(NotificationJob.class);
 
     @Autowired
-    private AuditManager auditManager;
+    private DomainsHolder domainsHolder;
 
     @Autowired
-    private NotificationManager notificationManager;
-
-    @Autowired
-    private JavaMailSender mailSender;
-
-    @Autowired
-    private EntityFactory entityFactory;
-
-    /**
-     * Task DAO.
-     */
-    @Autowired
-    private TaskDAO taskDAO;
-
-    private long maxRetries;
-
-    private void init() {
-        maxRetries = notificationManager.getMaxRetries();
-
-        if (mailSender instanceof JavaMailSenderImpl
-                && StringUtils.isNotBlank(((JavaMailSenderImpl) mailSender).getUsername())) {
-
-            Properties javaMailProperties = ((JavaMailSenderImpl) mailSender).getJavaMailProperties();
-            javaMailProperties.setProperty("mail.smtp.auth", "true");
-            ((JavaMailSenderImpl) mailSender).setJavaMailProperties(javaMailProperties);
-        }
-    }
-
-    public TaskExec executeSingle(final NotificationTask task) {
-        init();
-
-        TaskExec execution = entityFactory.newEntity(TaskExec.class);
-        execution.setTask(task);
-        execution.setStartDate(new Date());
-
-        boolean retryPossible = true;
-
-        if (StringUtils.isBlank(task.getSubject()) || task.getRecipients().isEmpty()
-                || StringUtils.isBlank(task.getHtmlBody()) || StringUtils.isBlank(task.getTextBody())) {
-
-            String message = "Could not fetch all required information for sending e-mails:\n"
-                    + task.getRecipients() + "\n"
-                    + task.getSender() + "\n"
-                    + task.getSubject() + "\n"
-                    + task.getHtmlBody() + "\n"
-                    + task.getTextBody();
-            LOG.error(message);
-
-            execution.setStatus(Status.NOT_SENT.name());
-            retryPossible = false;
-
-            if (task.getTraceLevel().ordinal() >= TraceLevel.FAILURES.ordinal()) {
-                execution.setMessage(message);
-            }
-        } else {
-            if (LOG.isDebugEnabled()) {
-                LOG.debug("About to send e-mails:\n"
-                        + task.getRecipients() + "\n"
-                        + task.getSender() + "\n"
-                        + task.getSubject() + "\n"
-                        + task.getHtmlBody() + "\n"
-                        + task.getTextBody() + "\n");
-            }
-
-            for (String to : task.getRecipients()) {
-                try {
-                    MimeMessage message = mailSender.createMimeMessage();
-                    MimeMessageHelper helper = new MimeMessageHelper(message, true);
-                    helper.setTo(to);
-                    helper.setFrom(task.getSender());
-                    helper.setSubject(task.getSubject());
-                    helper.setText(task.getTextBody(), task.getHtmlBody());
-
-                    mailSender.send(message);
-
-                    execution.setStatus(Status.SENT.name());
-
-                    StringBuilder report = new StringBuilder();
-                    switch (task.getTraceLevel()) {
-                        case ALL:
-                            report.append("FROM: ").append(task.getSender()).append('\n').
-                                    append("TO: ").append(to).append('\n').
-                                    append("SUBJECT: ").append(task.getSubject()).append('\n').append('\n').
-                                    append(task.getTextBody()).append('\n').append('\n').
-                                    append(task.getHtmlBody()).append('\n');
-                            break;
-
-                        case SUMMARY:
-                            report.append("E-mail sent to ").append(to).append('\n');
-                            break;
-
-                        case FAILURES:
-                        case NONE:
-                        default:
-                    }
-                    if (report.length() > 0) {
-                        execution.setMessage(report.toString());
-                    }
-
-                    auditManager.audit(
-                            AuditElements.EventCategoryType.TASK,
-                            "notification",
-                            null,
-                            "send",
-                            Result.SUCCESS,
-                            null,
-                            null,
-                            task,
-                            "Successfully sent notification to " + to);
-                } catch (Exception e) {
-                    LOG.error("Could not send e-mail", e);
-
-                    execution.setStatus(Status.NOT_SENT.name());
-                    if (task.getTraceLevel().ordinal() >= TraceLevel.FAILURES.ordinal()) {
-                        execution.setMessage(ExceptionUtils2.getFullStackTrace(e));
-                    }
-
-                    auditManager.audit(
-                            AuditElements.EventCategoryType.TASK,
-                            "notification",
-                            null,
-                            "send",
-                            Result.FAILURE,
-                            null,
-                            null,
-                            task,
-                            "Could not send notification to " + to, e);
-                }
-
-                execution.setEndDate(new Date());
-            }
-        }
-
-        if (hasToBeRegistered(execution)) {
-            execution = notificationManager.storeExec(execution);
-            if (retryPossible && (Status.valueOf(execution.getStatus()) == Status.NOT_SENT)) {
-                handleRetries(execution);
-            }
-        } else {
-            notificationManager.setTaskExecuted(execution.getTask().getKey(), true);
-        }
-
-        return execution;
-    }
+    private NotificationJobDelegate delegate;
 
     @Override
-    public void execute(final JobExecutionContext context)
-            throws JobExecutionException {
-
+    public void execute(final JobExecutionContext context) throws JobExecutionException {
         LOG.debug("Waking up...");
 
-        for (NotificationTask task : taskDAO.<NotificationTask>findToExec(TaskType.NOTIFICATION)) {
-            LOG.debug("Found notification task {} to be executed: starting...", task);
-            executeSingle(task);
-            LOG.debug("Notification task {} executed", task);
+        for (String domain : domainsHolder.getDomains().keySet()) {
+            AuthContextUtils.setFakeAuth(domain);
+            try {
+                delegate.execute();
+            } catch (Exception e) {
+                throw new JobExecutionException(e);
+            } finally {
+                AuthContextUtils.clearFakeAuth();
+            }
         }
 
         LOG.debug("Sleeping again...");
     }
 
-    private boolean hasToBeRegistered(final TaskExec execution) {
-        NotificationTask task = (NotificationTask) execution.getTask();
-
-        // True if either failed and failures have to be registered, or if ALL
-        // has to be registered.
-        return (Status.valueOf(execution.getStatus()) == Status.NOT_SENT
-                && task.getTraceLevel().ordinal() >= TraceLevel.FAILURES.ordinal())
-                || task.getTraceLevel() == TraceLevel.ALL;
-    }
-
-    private void handleRetries(final TaskExec execution) {
-        if (maxRetries <= 0) {
-            return;
-        }
-
-        long failedExecutionsCount = notificationManager.countExecutionsWithStatus(
-                execution.getTask().getKey(), Status.NOT_SENT.name());
-
-        if (failedExecutionsCount <= maxRetries) {
-            LOG.debug("Execution of notification task {} will be retried [{}/{}]",
-                    execution.getTask(), failedExecutionsCount, maxRetries);
-            notificationManager.setTaskExecuted(execution.getTask().getKey(), false);
-
-            auditManager.audit(
-                    AuditElements.EventCategoryType.TASK,
-                    "notification",
-                    null,
-                    "retry",
-                    Result.SUCCESS,
-                    null,
-                    null,
-                    execution,
-                    "Notification task " + execution.getTask().getKey() + " will be retried");
-        } else {
-            LOG.error("Maximum number of retries reached for task {} - giving up", execution.getTask());
-
-            auditManager.audit(
-                    AuditElements.EventCategoryType.TASK,
-                    "notification",
-                    null,
-                    "retry",
-                    Result.FAILURE,
-                    null,
-                    null,
-                    execution,
-                    "Giving up retries on notification task " + execution.getTask().getKey());
-        }
-    }
 }

http://git-wip-us.apache.org/repos/asf/syncope/blob/6dfedd8f/core/logic/src/main/java/org/apache/syncope/core/logic/notification/NotificationJobDelegate.java
----------------------------------------------------------------------
diff --git a/core/logic/src/main/java/org/apache/syncope/core/logic/notification/NotificationJobDelegate.java b/core/logic/src/main/java/org/apache/syncope/core/logic/notification/NotificationJobDelegate.java
new file mode 100644
index 0000000..aaebe77
--- /dev/null
+++ b/core/logic/src/main/java/org/apache/syncope/core/logic/notification/NotificationJobDelegate.java
@@ -0,0 +1,258 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.syncope.core.logic.notification;
+
+import java.util.Date;
+import java.util.Properties;
+import javax.mail.internet.MimeMessage;
+import org.apache.commons.lang3.StringUtils;
+import org.apache.syncope.common.lib.types.AuditElements;
+import org.apache.syncope.common.lib.types.TaskType;
+import org.apache.syncope.common.lib.types.TraceLevel;
+import org.apache.syncope.core.misc.AuditManager;
+import org.apache.syncope.core.misc.ExceptionUtils2;
+import org.apache.syncope.core.persistence.api.dao.TaskDAO;
+import org.apache.syncope.core.persistence.api.entity.EntityFactory;
+import org.apache.syncope.core.persistence.api.entity.task.NotificationTask;
+import org.apache.syncope.core.persistence.api.entity.task.TaskExec;
+import org.apache.syncope.core.provisioning.api.notification.NotificationManager;
+import org.quartz.JobExecutionException;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.mail.javamail.JavaMailSender;
+import org.springframework.mail.javamail.JavaMailSenderImpl;
+import org.springframework.mail.javamail.MimeMessageHelper;
+import org.springframework.stereotype.Component;
+import org.springframework.transaction.annotation.Transactional;
+
+@Component
+public class NotificationJobDelegate {
+
+    private static final Logger LOG = LoggerFactory.getLogger(NotificationJobDelegate.class);
+
+    /**
+     * Task DAO.
+     */
+    @Autowired
+    private TaskDAO taskDAO;
+
+    @Autowired
+    private JavaMailSender mailSender;
+
+    @Autowired
+    private EntityFactory entityFactory;
+
+    @Autowired
+    private AuditManager auditManager;
+
+    @Autowired
+    private NotificationManager notificationManager;
+
+    private long maxRetries;
+
+    private void init() {
+        maxRetries = notificationManager.getMaxRetries();
+
+        if (mailSender instanceof JavaMailSenderImpl
+                && StringUtils.isNotBlank(((JavaMailSenderImpl) mailSender).getUsername())) {
+
+            Properties javaMailProperties = ((JavaMailSenderImpl) mailSender).getJavaMailProperties();
+            javaMailProperties.setProperty("mail.smtp.auth", "true");
+            ((JavaMailSenderImpl) mailSender).setJavaMailProperties(javaMailProperties);
+        }
+    }
+
+    @Transactional
+    public TaskExec executeSingle(final NotificationTask task) {
+        init();
+
+        TaskExec execution = entityFactory.newEntity(TaskExec.class);
+        execution.setTask(task);
+        execution.setStartDate(new Date());
+
+        boolean retryPossible = true;
+
+        if (StringUtils.isBlank(task.getSubject()) || task.getRecipients().isEmpty()
+                || StringUtils.isBlank(task.getHtmlBody()) || StringUtils.isBlank(task.getTextBody())) {
+
+            String message = "Could not fetch all required information for sending e-mails:\n"
+                    + task.getRecipients() + "\n"
+                    + task.getSender() + "\n"
+                    + task.getSubject() + "\n"
+                    + task.getHtmlBody() + "\n"
+                    + task.getTextBody();
+            LOG.error(message);
+
+            execution.setStatus(NotificationJob.Status.NOT_SENT.name());
+            retryPossible = false;
+
+            if (task.getTraceLevel().ordinal() >= TraceLevel.FAILURES.ordinal()) {
+                execution.setMessage(message);
+            }
+        } else {
+            if (LOG.isDebugEnabled()) {
+                LOG.debug("About to send e-mails:\n"
+                        + task.getRecipients() + "\n"
+                        + task.getSender() + "\n"
+                        + task.getSubject() + "\n"
+                        + task.getHtmlBody() + "\n"
+                        + task.getTextBody() + "\n");
+            }
+
+            for (String to : task.getRecipients()) {
+                try {
+                    MimeMessage message = mailSender.createMimeMessage();
+                    MimeMessageHelper helper = new MimeMessageHelper(message, true);
+                    helper.setTo(to);
+                    helper.setFrom(task.getSender());
+                    helper.setSubject(task.getSubject());
+                    helper.setText(task.getTextBody(), task.getHtmlBody());
+
+                    mailSender.send(message);
+
+                    execution.setStatus(NotificationJob.Status.SENT.name());
+
+                    StringBuilder report = new StringBuilder();
+                    switch (task.getTraceLevel()) {
+                        case ALL:
+                            report.append("FROM: ").append(task.getSender()).append('\n').
+                                    append("TO: ").append(to).append('\n').
+                                    append("SUBJECT: ").append(task.getSubject()).append('\n').append('\n').
+                                    append(task.getTextBody()).append('\n').append('\n').
+                                    append(task.getHtmlBody()).append('\n');
+                            break;
+
+                        case SUMMARY:
+                            report.append("E-mail sent to ").append(to).append('\n');
+                            break;
+
+                        case FAILURES:
+                        case NONE:
+                        default:
+                    }
+                    if (report.length() > 0) {
+                        execution.setMessage(report.toString());
+                    }
+
+                    auditManager.audit(
+                            AuditElements.EventCategoryType.TASK,
+                            "notification",
+                            null,
+                            "send",
+                            AuditElements.Result.SUCCESS,
+                            null,
+                            null,
+                            task,
+                            "Successfully sent notification to " + to);
+                } catch (Exception e) {
+                    LOG.error("Could not send e-mail", e);
+
+                    execution.setStatus(NotificationJob.Status.NOT_SENT.name());
+                    if (task.getTraceLevel().ordinal() >= TraceLevel.FAILURES.ordinal()) {
+                        execution.setMessage(ExceptionUtils2.getFullStackTrace(e));
+                    }
+
+                    auditManager.audit(
+                            AuditElements.EventCategoryType.TASK,
+                            "notification",
+                            null,
+                            "send",
+                            AuditElements.Result.FAILURE,
+                            null,
+                            null,
+                            task,
+                            "Could not send notification to " + to, e);
+                }
+
+                execution.setEndDate(new Date());
+            }
+        }
+
+        if (hasToBeRegistered(execution)) {
+            execution = notificationManager.storeExec(execution);
+            if (retryPossible && (NotificationJob.Status.valueOf(execution.getStatus())
+                    == NotificationJob.Status.NOT_SENT)) {
+                handleRetries(execution);
+            }
+        } else {
+            notificationManager.setTaskExecuted(execution.getTask().getKey(), true);
+        }
+
+        return execution;
+    }
+
+    @Transactional
+    public void execute() throws JobExecutionException {
+        for (NotificationTask task : taskDAO.<NotificationTask>findToExec(TaskType.NOTIFICATION)) {
+            LOG.debug("Found notification task {} to be executed: starting...", task);
+            executeSingle(task);
+            LOG.debug("Notification task {} executed", task);
+        }
+    }
+
+    private boolean hasToBeRegistered(final TaskExec execution) {
+        NotificationTask task = (NotificationTask) execution.getTask();
+
+        // True if either failed and failures have to be registered, or if ALL
+        // has to be registered.
+        return (NotificationJob.Status.valueOf(execution.getStatus()) == NotificationJob.Status.NOT_SENT
+                && task.getTraceLevel().ordinal() >= TraceLevel.FAILURES.ordinal())
+                || task.getTraceLevel() == TraceLevel.ALL;
+    }
+
+    private void handleRetries(final TaskExec execution) {
+        if (maxRetries <= 0) {
+            return;
+        }
+
+        long failedExecutionsCount = notificationManager.countExecutionsWithStatus(
+                execution.getTask().getKey(), NotificationJob.Status.NOT_SENT.name());
+
+        if (failedExecutionsCount <= maxRetries) {
+            LOG.debug("Execution of notification task {} will be retried [{}/{}]",
+                    execution.getTask(), failedExecutionsCount, maxRetries);
+            notificationManager.setTaskExecuted(execution.getTask().getKey(), false);
+
+            auditManager.audit(
+                    AuditElements.EventCategoryType.TASK,
+                    "notification",
+                    null,
+                    "retry",
+                    AuditElements.Result.SUCCESS,
+                    null,
+                    null,
+                    execution,
+                    "Notification task " + execution.getTask().getKey() + " will be retried");
+        } else {
+            LOG.error("Maximum number of retries reached for task {} - giving up", execution.getTask());
+
+            auditManager.audit(
+                    AuditElements.EventCategoryType.TASK,
+                    "notification",
+                    null,
+                    "retry",
+                    AuditElements.Result.FAILURE,
+                    null,
+                    null,
+                    execution,
+                    "Giving up retries on notification task " + execution.getTask().getKey());
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/6dfedd8f/core/logic/src/main/java/org/apache/syncope/core/logic/report/ReportJob.java
----------------------------------------------------------------------
diff --git a/core/logic/src/main/java/org/apache/syncope/core/logic/report/ReportJob.java b/core/logic/src/main/java/org/apache/syncope/core/logic/report/ReportJob.java
index e07612a..8e5af91 100644
--- a/core/logic/src/main/java/org/apache/syncope/core/logic/report/ReportJob.java
+++ b/core/logic/src/main/java/org/apache/syncope/core/logic/report/ReportJob.java
@@ -18,74 +18,28 @@
  */
 package org.apache.syncope.core.logic.report;
 
-import java.io.ByteArrayOutputStream;
-import java.io.IOException;
-import java.util.Date;
-import java.util.zip.Deflater;
-import java.util.zip.ZipEntry;
-import java.util.zip.ZipOutputStream;
-import javax.xml.transform.OutputKeys;
-import javax.xml.transform.Transformer;
-import javax.xml.transform.sax.SAXTransformerFactory;
-import javax.xml.transform.sax.TransformerHandler;
-import javax.xml.transform.stream.StreamResult;
-import org.apache.commons.io.IOUtils;
-import org.apache.syncope.common.lib.SyncopeConstants;
-import org.apache.syncope.common.lib.report.ReportletConf;
-import org.apache.syncope.common.lib.types.ReportExecStatus;
-import org.apache.syncope.core.persistence.api.dao.ReportDAO;
-import org.apache.syncope.core.persistence.api.dao.ReportExecDAO;
-import org.apache.syncope.core.persistence.api.entity.EntityFactory;
-import org.apache.syncope.core.persistence.api.entity.Report;
-import org.apache.syncope.core.persistence.api.entity.ReportExec;
-import org.apache.syncope.core.logic.ReportLogic;
-import org.apache.syncope.core.misc.spring.ApplicationContextProvider;
-import org.apache.syncope.core.misc.ExceptionUtils2;
+import org.apache.syncope.core.misc.security.AuthContextUtils;
+import org.apache.syncope.core.provisioning.api.job.JobInstanceLoader;
 import org.quartz.DisallowConcurrentExecution;
 import org.quartz.Job;
 import org.quartz.JobExecutionContext;
 import org.quartz.JobExecutionException;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
 import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.beans.factory.support.AbstractBeanDefinition;
-import org.xml.sax.helpers.AttributesImpl;
 
 /**
  * Quartz job for executing a given report.
  */
-@SuppressWarnings("unchecked")
 @DisallowConcurrentExecution
 public class ReportJob implements Job {
 
     /**
-     * Logger.
-     */
-    private static final Logger LOG = LoggerFactory.getLogger(ReportJob.class);
-
-    /**
-     * Report DAO.
-     */
-    @Autowired
-    private ReportDAO reportDAO;
-
-    /**
-     * Report execution DAO.
-     */
-    @Autowired
-    private ReportExecDAO reportExecDAO;
-
-    @Autowired
-    private ReportLogic dataBinder;
-
-    @Autowired
-    private EntityFactory entityFactory;
-
-    /**
      * Key, set by the caller, for identifying the report to be executed.
      */
     private Long reportKey;
 
+    @Autowired
+    private ReportJobDelegate delegate;
+
     /**
      * Report id setter.
      *
@@ -95,109 +49,15 @@ public class ReportJob implements Job {
         this.reportKey = reportKey;
     }
 
-    @SuppressWarnings("rawtypes")
     @Override
     public void execute(final JobExecutionContext context) throws JobExecutionException {
-        Report report = reportDAO.find(reportKey);
-        if (report == null) {
-            throw new JobExecutionException("Report " + reportKey + " not found");
-        }
-
-        // 1. create execution
-        ReportExec execution = entityFactory.newEntity(ReportExec.class);
-        execution.setStatus(ReportExecStatus.STARTED);
-        execution.setStartDate(new Date());
-        execution.setReport(report);
-        execution = reportExecDAO.save(execution);
-
-        report.addExec(execution);
-        report = reportDAO.save(report);
-
-        // 2. define a SAX handler for generating result as XML
-        TransformerHandler handler;
-
-        ByteArrayOutputStream baos = new ByteArrayOutputStream();
-        ZipOutputStream zos = new ZipOutputStream(baos);
-        zos.setLevel(Deflater.BEST_COMPRESSION);
-        try {
-            SAXTransformerFactory tFactory = (SAXTransformerFactory) SAXTransformerFactory.newInstance();
-            handler = tFactory.newTransformerHandler();
-            Transformer serializer = handler.getTransformer();
-            serializer.setOutputProperty(OutputKeys.ENCODING, SyncopeConstants.DEFAULT_ENCODING);
-            serializer.setOutputProperty(OutputKeys.INDENT, "yes");
-
-            // a single ZipEntry in the ZipOutputStream
-            zos.putNextEntry(new ZipEntry(report.getName()));
-
-            // streaming SAX handler in a compressed byte array stream
-            handler.setResult(new StreamResult(zos));
-        } catch (Exception e) {
-            throw new JobExecutionException("While configuring for SAX generation", e, true);
-        }
-
-        execution.setStatus(ReportExecStatus.RUNNING);
-        execution = reportExecDAO.save(execution);
-
-        // 3. actual report execution
-        StringBuilder reportExecutionMessage = new StringBuilder();
+        AuthContextUtils.setFakeAuth(context.getMergedJobDataMap().getString(JobInstanceLoader.DOMAIN));
         try {
-            // report header
-            handler.startDocument();
-            AttributesImpl atts = new AttributesImpl();
-            atts.addAttribute("", "", ReportXMLConst.ATTR_NAME, ReportXMLConst.XSD_STRING, report.getName());
-            handler.startElement("", "", ReportXMLConst.ELEMENT_REPORT, atts);
-
-            // iterate over reportlet instances defined for this report
-            for (ReportletConf reportletConf : report.getReportletConfs()) {
-                Class<Reportlet> reportletClass =
-                        dataBinder.findReportletClassHavingConfClass(reportletConf.getClass());
-                if (reportletClass != null) {
-                    Reportlet<ReportletConf> autowired =
-                            (Reportlet<ReportletConf>) ApplicationContextProvider.getBeanFactory().
-                            createBean(reportletClass, AbstractBeanDefinition.AUTOWIRE_BY_TYPE, false);
-                    autowired.setConf(reportletConf);
-
-                    // invoke reportlet
-                    try {
-                        autowired.extract(handler);
-                    } catch (Exception e) {
-                        execution.setStatus(ReportExecStatus.FAILURE);
-
-                        Throwable t = e instanceof ReportException
-                                ? e.getCause()
-                                : e;
-                        reportExecutionMessage.
-                                append(ExceptionUtils2.getFullStackTrace(t)).
-                                append("\n==================\n");
-                    }
-                }
-            }
-
-            // report footer
-            handler.endElement("", "", ReportXMLConst.ELEMENT_REPORT);
-            handler.endDocument();
-
-            if (!ReportExecStatus.FAILURE.name().equals(execution.getStatus())) {
-                execution.setStatus(ReportExecStatus.SUCCESS);
-            }
+            delegate.execute(reportKey);
         } catch (Exception e) {
-            execution.setStatus(ReportExecStatus.FAILURE);
-            reportExecutionMessage.append(ExceptionUtils2.getFullStackTrace(e));
-
-            throw new JobExecutionException(e, true);
+            throw new JobExecutionException(e);
         } finally {
-            try {
-                zos.closeEntry();
-                IOUtils.closeQuietly(zos);
-                IOUtils.closeQuietly(baos);
-            } catch (IOException e) {
-                LOG.error("While closing StreamResult's backend", e);
-            }
-
-            execution.setExecResult(baos.toByteArray());
-            execution.setMessage(reportExecutionMessage.toString());
-            execution.setEndDate(new Date());
-            reportExecDAO.save(execution);
+            AuthContextUtils.clearFakeAuth();
         }
     }
 }

http://git-wip-us.apache.org/repos/asf/syncope/blob/6dfedd8f/core/logic/src/main/java/org/apache/syncope/core/logic/report/ReportJobDelegate.java
----------------------------------------------------------------------
diff --git a/core/logic/src/main/java/org/apache/syncope/core/logic/report/ReportJobDelegate.java b/core/logic/src/main/java/org/apache/syncope/core/logic/report/ReportJobDelegate.java
new file mode 100644
index 0000000..9920c1f
--- /dev/null
+++ b/core/logic/src/main/java/org/apache/syncope/core/logic/report/ReportJobDelegate.java
@@ -0,0 +1,181 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.syncope.core.logic.report;
+
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.util.Date;
+import java.util.zip.Deflater;
+import java.util.zip.ZipEntry;
+import java.util.zip.ZipOutputStream;
+import javax.xml.transform.OutputKeys;
+import javax.xml.transform.Transformer;
+import javax.xml.transform.sax.SAXTransformerFactory;
+import javax.xml.transform.sax.TransformerHandler;
+import javax.xml.transform.stream.StreamResult;
+import org.apache.commons.io.IOUtils;
+import org.apache.syncope.common.lib.SyncopeConstants;
+import org.apache.syncope.common.lib.report.ReportletConf;
+import org.apache.syncope.common.lib.types.ReportExecStatus;
+import org.apache.syncope.core.logic.ReportLogic;
+import org.apache.syncope.core.misc.ExceptionUtils2;
+import org.apache.syncope.core.misc.spring.ApplicationContextProvider;
+import org.apache.syncope.core.persistence.api.dao.ReportDAO;
+import org.apache.syncope.core.persistence.api.dao.ReportExecDAO;
+import org.apache.syncope.core.persistence.api.entity.EntityFactory;
+import org.apache.syncope.core.persistence.api.entity.Report;
+import org.apache.syncope.core.persistence.api.entity.ReportExec;
+import org.quartz.JobExecutionException;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.support.AbstractBeanDefinition;
+import org.springframework.stereotype.Component;
+import org.springframework.transaction.annotation.Transactional;
+import org.xml.sax.helpers.AttributesImpl;
+
+@Component
+public class ReportJobDelegate {
+
+    private static final Logger LOG = LoggerFactory.getLogger(ReportJobDelegate.class);
+
+    /**
+     * Report DAO.
+     */
+    @Autowired
+    private ReportDAO reportDAO;
+
+    /**
+     * Report execution DAO.
+     */
+    @Autowired
+    private ReportExecDAO reportExecDAO;
+
+    @Autowired
+    private EntityFactory entityFactory;
+
+    @Autowired
+    private ReportLogic dataBinder;
+
+    @Transactional
+    public void execute(final Long reportKey) throws JobExecutionException {
+        Report report = reportDAO.find(reportKey);
+        if (report == null) {
+            throw new JobExecutionException("Report " + reportKey + " not found");
+        }
+
+        // 1. create execution
+        ReportExec execution = entityFactory.newEntity(ReportExec.class);
+        execution.setStatus(ReportExecStatus.STARTED);
+        execution.setStartDate(new Date());
+        execution.setReport(report);
+        execution = reportExecDAO.save(execution);
+
+        report.addExec(execution);
+        report = reportDAO.save(report);
+
+        // 2. define a SAX handler for generating result as XML
+        TransformerHandler handler;
+
+        ByteArrayOutputStream baos = new ByteArrayOutputStream();
+        ZipOutputStream zos = new ZipOutputStream(baos);
+        zos.setLevel(Deflater.BEST_COMPRESSION);
+        try {
+            SAXTransformerFactory tFactory = (SAXTransformerFactory) SAXTransformerFactory.newInstance();
+            handler = tFactory.newTransformerHandler();
+            Transformer serializer = handler.getTransformer();
+            serializer.setOutputProperty(OutputKeys.ENCODING, SyncopeConstants.DEFAULT_ENCODING);
+            serializer.setOutputProperty(OutputKeys.INDENT, "yes");
+
+            // a single ZipEntry in the ZipOutputStream
+            zos.putNextEntry(new ZipEntry(report.getName()));
+
+            // streaming SAX handler in a compressed byte array stream
+            handler.setResult(new StreamResult(zos));
+        } catch (Exception e) {
+            throw new JobExecutionException("While configuring for SAX generation", e, true);
+        }
+
+        execution.setStatus(ReportExecStatus.RUNNING);
+        execution = reportExecDAO.save(execution);
+
+        // 3. actual report execution
+        StringBuilder reportExecutionMessage = new StringBuilder();
+        try {
+            // report header
+            handler.startDocument();
+            AttributesImpl atts = new AttributesImpl();
+            atts.addAttribute("", "", ReportXMLConst.ATTR_NAME, ReportXMLConst.XSD_STRING, report.getName());
+            handler.startElement("", "", ReportXMLConst.ELEMENT_REPORT, atts);
+
+            // iterate over reportlet instances defined for this report
+            for (ReportletConf reportletConf : report.getReportletConfs()) {
+                Class<Reportlet> reportletClass =
+                        dataBinder.findReportletClassHavingConfClass(reportletConf.getClass());
+                if (reportletClass != null) {
+                    @SuppressWarnings("unchecked")
+                    Reportlet<ReportletConf> autowired =
+                            (Reportlet<ReportletConf>) ApplicationContextProvider.getBeanFactory().
+                            createBean(reportletClass, AbstractBeanDefinition.AUTOWIRE_BY_TYPE, false);
+                    autowired.setConf(reportletConf);
+
+                    // invoke reportlet
+                    try {
+                        autowired.extract(handler);
+                    } catch (Exception e) {
+                        execution.setStatus(ReportExecStatus.FAILURE);
+
+                        Throwable t = e instanceof ReportException
+                                ? e.getCause()
+                                : e;
+                        reportExecutionMessage.
+                                append(ExceptionUtils2.getFullStackTrace(t)).
+                                append("\n==================\n");
+                    }
+                }
+            }
+
+            // report footer
+            handler.endElement("", "", ReportXMLConst.ELEMENT_REPORT);
+            handler.endDocument();
+
+            if (!ReportExecStatus.FAILURE.name().equals(execution.getStatus())) {
+                execution.setStatus(ReportExecStatus.SUCCESS);
+            }
+        } catch (Exception e) {
+            execution.setStatus(ReportExecStatus.FAILURE);
+            reportExecutionMessage.append(ExceptionUtils2.getFullStackTrace(e));
+
+            throw new JobExecutionException(e, true);
+        } finally {
+            try {
+                zos.closeEntry();
+                IOUtils.closeQuietly(zos);
+                IOUtils.closeQuietly(baos);
+            } catch (IOException e) {
+                LOG.error("While closing StreamResult's backend", e);
+            }
+
+            execution.setExecResult(baos.toByteArray());
+            execution.setMessage(reportExecutionMessage.toString());
+            execution.setEndDate(new Date());
+            reportExecDAO.save(execution);
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/6dfedd8f/core/logic/src/test/java/org/apache/syncope/core/logic/AbstractTest.java
----------------------------------------------------------------------
diff --git a/core/logic/src/test/java/org/apache/syncope/core/logic/AbstractTest.java b/core/logic/src/test/java/org/apache/syncope/core/logic/AbstractTest.java
index 161d0c1..d4b0fa4 100644
--- a/core/logic/src/test/java/org/apache/syncope/core/logic/AbstractTest.java
+++ b/core/logic/src/test/java/org/apache/syncope/core/logic/AbstractTest.java
@@ -23,7 +23,7 @@ import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.springframework.test.context.ContextConfiguration;
 import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
-import org.springframework.transaction.annotation.Transactional;
+import org.springframework.test.context.transaction.TransactionConfiguration;
 
 @RunWith(SpringJUnit4ClassRunner.class)
 @ContextConfiguration(locations = {
@@ -33,7 +33,7 @@ import org.springframework.transaction.annotation.Transactional;
     "classpath:persistenceTest.xml",
     "classpath:logicTest.xml"
 })
-@Transactional
+@TransactionConfiguration(transactionManager = "MasterTransactionManager")
 public abstract class AbstractTest {
 
     protected static final Logger LOG = LoggerFactory.getLogger(AbstractTest.class);

http://git-wip-us.apache.org/repos/asf/syncope/blob/6dfedd8f/core/logic/src/test/java/org/apache/syncope/core/logic/MappingTest.java
----------------------------------------------------------------------
diff --git a/core/logic/src/test/java/org/apache/syncope/core/logic/MappingTest.java b/core/logic/src/test/java/org/apache/syncope/core/logic/MappingTest.java
index 1f1dab7..770bac9 100644
--- a/core/logic/src/test/java/org/apache/syncope/core/logic/MappingTest.java
+++ b/core/logic/src/test/java/org/apache/syncope/core/logic/MappingTest.java
@@ -31,7 +31,9 @@ import org.apache.syncope.core.persistence.api.entity.user.User;
 import org.identityconnectors.framework.common.objects.Name;
 import org.junit.Test;
 import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.transaction.annotation.Transactional;
 
+@Transactional
 public class MappingTest extends AbstractTest {
 
     @Autowired

http://git-wip-us.apache.org/repos/asf/syncope/blob/6dfedd8f/core/logic/src/test/java/org/apache/syncope/core/logic/NotificationTest.java
----------------------------------------------------------------------
diff --git a/core/logic/src/test/java/org/apache/syncope/core/logic/NotificationTest.java b/core/logic/src/test/java/org/apache/syncope/core/logic/NotificationTest.java
index c5dc13c..6c208a2 100644
--- a/core/logic/src/test/java/org/apache/syncope/core/logic/NotificationTest.java
+++ b/core/logic/src/test/java/org/apache/syncope/core/logic/NotificationTest.java
@@ -79,7 +79,9 @@ import org.springframework.security.core.GrantedAuthority;
 import org.springframework.security.core.context.SecurityContextHolder;
 import org.springframework.security.core.userdetails.User;
 import org.springframework.security.core.userdetails.UserDetails;
+import org.springframework.transaction.annotation.Transactional;
 
+@Transactional
 public class NotificationTest extends AbstractTest {
 
     private static final String SMTP_HOST = "localhost";
@@ -164,7 +166,7 @@ public class NotificationTest extends AbstractTest {
     }
 
     private static UserTO getSampleTO(final String email) {
-        String uid = email;
+        String uid = UUID.randomUUID().toString().substring(0, 8) + email;
         UserTO userTO = new UserTO();
         userTO.setPassword("password123");
         userTO.setUsername(uid);
@@ -175,7 +177,7 @@ public class NotificationTest extends AbstractTest {
         userTO.getPlainAttrs().add(attributeTO("surname", "surname"));
         userTO.getPlainAttrs().add(attributeTO("type", "a type"));
         userTO.getPlainAttrs().add(attributeTO("userId", uid));
-        userTO.getPlainAttrs().add(attributeTO("email", uid));
+        userTO.getPlainAttrs().add(attributeTO("email", email));
         userTO.getPlainAttrs().add(attributeTO("loginDate", new SimpleDateFormat("yyyy-MM-dd").format(new Date())));
         userTO.getDerAttrs().add(attributeTO("cn", null));
         userTO.getVirAttrs().add(attributeTO("virtualdata", "virtualvalue"));

http://git-wip-us.apache.org/repos/asf/syncope/blob/6dfedd8f/core/logic/src/test/resources/logicTest.xml
----------------------------------------------------------------------
diff --git a/core/logic/src/test/resources/logicTest.xml b/core/logic/src/test/resources/logicTest.xml
index 3cf0ab0..2dca918 100644
--- a/core/logic/src/test/resources/logicTest.xml
+++ b/core/logic/src/test/resources/logicTest.xml
@@ -26,6 +26,7 @@ under the License.
     <property name="locations">
       <list>
         <value>classpath:persistence.properties</value>
+        <value>classpath:domains/*.properties</value>
         <value>classpath:security.properties</value>
         <value>classpath:connid.properties</value>
         <value>classpath:mail.properties</value>
@@ -37,10 +38,5 @@ under the License.
     <property name="ignoreResourceNotFound" value="true"/>
     <property name="ignoreUnresolvablePlaceholders" value="true"/>
   </bean>
-  
-  <bean id="contentXML" class="org.apache.syncope.core.misc.spring.ResourceWithFallbackLoader">
-    <property name="primary" value="file:${conf.directory}/content.xml"/>
-    <property name="fallback" value="classpath:content.xml"/>
-  </bean>
 
 </beans>

http://git-wip-us.apache.org/repos/asf/syncope/blob/6dfedd8f/core/misc/src/main/java/org/apache/syncope/core/misc/AuditManager.java
----------------------------------------------------------------------
diff --git a/core/misc/src/main/java/org/apache/syncope/core/misc/AuditManager.java b/core/misc/src/main/java/org/apache/syncope/core/misc/AuditManager.java
index a8d8aac..d370895 100644
--- a/core/misc/src/main/java/org/apache/syncope/core/misc/AuditManager.java
+++ b/core/misc/src/main/java/org/apache/syncope/core/misc/AuditManager.java
@@ -23,13 +23,18 @@ import org.apache.syncope.common.lib.types.AuditElements;
 import org.apache.syncope.common.lib.types.AuditElements.Result;
 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.core.misc.security.AuthContextUtils;
+import org.apache.syncope.core.misc.security.SyncopeAuthenticationDetails;
 import org.apache.syncope.core.persistence.api.dao.LoggerDAO;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
 import org.springframework.security.core.context.SecurityContext;
 import org.springframework.security.core.context.SecurityContextHolder;
 import org.springframework.stereotype.Component;
+import org.springframework.transaction.annotation.Transactional;
 
 @Component
 public class AuditManager {
@@ -39,6 +44,11 @@ public class AuditManager {
     @Autowired
     private LoggerDAO loggerDAO;
 
+    public static String getDomainAuditLoggerName(final String domain) {
+        return LoggerType.AUDIT.getPrefix() + "." + domain;
+    }
+
+    @Transactional(readOnly = true)
     public void audit(
             final AuditElements.EventCategoryType type,
             final String category,
@@ -88,13 +98,22 @@ public class AuditManager {
             if (syncopeLogger != null && syncopeLogger.getLevel() == LoggerLevel.DEBUG) {
                 StringBuilder auditMessage = new StringBuilder();
 
-                final SecurityContext ctx = SecurityContextHolder.getContext();
+                SecurityContext ctx = SecurityContextHolder.getContext();
                 if (ctx != null && ctx.getAuthentication() != null) {
                     auditMessage.append('[').append(ctx.getAuthentication().getName()).append("] ");
                 }
                 auditMessage.append(message);
 
-                final Logger logger = LoggerFactory.getLogger(auditLoggerName.toLoggerName());
+                String domain = AuthContextUtils.getDomain();
+                if (input != null && input.length > 0 && input[0] instanceof UsernamePasswordAuthenticationToken) {
+                    UsernamePasswordAuthenticationToken token =
+                            UsernamePasswordAuthenticationToken.class.cast(input[0]);
+                    if (token.getDetails() instanceof SyncopeAuthenticationDetails) {
+                        domain = SyncopeAuthenticationDetails.class.cast(token.getDetails()).getDomain();
+                    }
+                }
+
+                Logger logger = LoggerFactory.getLogger(getDomainAuditLoggerName(domain));
                 if (throwable == null) {
                     logger.debug(auditMessage.toString());
                 } else {

http://git-wip-us.apache.org/repos/asf/syncope/blob/6dfedd8f/core/misc/src/main/java/org/apache/syncope/core/misc/MappingUtils.java
----------------------------------------------------------------------
diff --git a/core/misc/src/main/java/org/apache/syncope/core/misc/MappingUtils.java b/core/misc/src/main/java/org/apache/syncope/core/misc/MappingUtils.java
index e655809..95a16b1 100644
--- a/core/misc/src/main/java/org/apache/syncope/core/misc/MappingUtils.java
+++ b/core/misc/src/main/java/org/apache/syncope/core/misc/MappingUtils.java
@@ -73,7 +73,7 @@ import org.identityconnectors.framework.common.objects.Name;
 import org.identityconnectors.framework.common.objects.OperationalAttributes;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
-import org.springframework.context.ConfigurableApplicationContext;
+import org.springframework.beans.factory.support.DefaultListableBeanFactory;
 
 public final class MappingUtils {
 
@@ -141,9 +141,9 @@ public final class MappingUtils {
         LOG.debug("Preparing resource attributes for {} with provision {} for attributes {}",
                 any, provision, any.getPlainAttrs());
 
-        ConfigurableApplicationContext context = ApplicationContextProvider.getApplicationContext();
-        VirAttrCache virAttrCache = context.getBean(VirAttrCache.class);
-        PasswordGenerator passwordGenerator = context.getBean(PasswordGenerator.class);
+        DefaultListableBeanFactory beanFactory = ApplicationContextProvider.getBeanFactory();
+        VirAttrCache virAttrCache = beanFactory.getBean(VirAttrCache.class);
+        PasswordGenerator passwordGenerator = beanFactory.getBean(PasswordGenerator.class);
 
         Set<Attribute> attributes = new HashSet<>();
         String connObjectKey = null;
@@ -227,9 +227,9 @@ public final class MappingUtils {
 
         List<Any<?, ?, ?>> anys = new ArrayList<>();
 
-        ConfigurableApplicationContext context = ApplicationContextProvider.getApplicationContext();
-        AnyUtilsFactory anyUtilsFactory = context.getBean(AnyUtilsFactory.class);
-        VirAttrHandler virAttrHandler = context.getBean(VirAttrHandler.class);
+        DefaultListableBeanFactory beanFactory = ApplicationContextProvider.getBeanFactory();
+        AnyUtilsFactory anyUtilsFactory = beanFactory.getBean(AnyUtilsFactory.class);
+        VirAttrHandler virAttrHandler = beanFactory.getBean(VirAttrHandler.class);
 
         switch (mapItem.getIntMappingType().getAnyTypeKind()) {
             case USER:
@@ -240,7 +240,7 @@ public final class MappingUtils {
 
             case GROUP:
                 if (any instanceof User) {
-                    UserDAO userDAO = context.getBean(UserDAO.class);
+                    UserDAO userDAO = beanFactory.getBean(UserDAO.class);
                     for (Group group : userDAO.findAllGroups((User) any)) {
                         virAttrHandler.retrieveVirAttrValues(group);
                         anys.add(group);
@@ -271,7 +271,7 @@ public final class MappingUtils {
             case UserPlainSchema:
             case GroupPlainSchema:
             case AnyObjectPlainSchema:
-                final PlainSchemaDAO plainSchemaDAO = context.getBean(PlainSchemaDAO.class);
+                PlainSchemaDAO plainSchemaDAO = beanFactory.getBean(PlainSchemaDAO.class);
                 schema = plainSchemaDAO.find(mapItem.getIntAttrName());
                 schemaType = schema == null ? AttrSchemaType.String : schema.getType();
                 break;
@@ -279,7 +279,7 @@ public final class MappingUtils {
             case UserVirtualSchema:
             case GroupVirtualSchema:
             case AnyObjectVirtualSchema:
-                VirSchemaDAO virSchemaDAO = context.getBean(VirSchemaDAO.class);
+                VirSchemaDAO virSchemaDAO = beanFactory.getBean(VirSchemaDAO.class);
                 VirSchema virSchema = virSchemaDAO.find(mapItem.getIntAttrName());
                 readOnlyVirSchema = (virSchema != null && virSchema.isReadonly());
                 schemaType = AttrSchemaType.String;
@@ -434,9 +434,9 @@ public final class MappingUtils {
         LOG.debug("Get attributes for '{}' and mapping type '{}'", anys, mappingItem.getIntMappingType());
 
         EntityFactory entityFactory =
-                ApplicationContextProvider.getApplicationContext().getBean(EntityFactory.class);
+                ApplicationContextProvider.getBeanFactory().getBean(EntityFactory.class);
         AnyUtilsFactory anyUtilsFactory =
-                ApplicationContextProvider.getApplicationContext().getBean(AnyUtilsFactory.class);
+                ApplicationContextProvider.getBeanFactory().getBean(AnyUtilsFactory.class);
         List<PlainAttrValue> values = new ArrayList<>();
         PlainAttrValue attrValue;
         switch (mappingItem.getIntMappingType()) {
@@ -551,7 +551,7 @@ public final class MappingUtils {
                 break;
 
             case GroupOwnerSchema:
-                AnyTypeDAO anyTypeDAO = ApplicationContextProvider.getApplicationContext().getBean(AnyTypeDAO.class);
+                AnyTypeDAO anyTypeDAO = ApplicationContextProvider.getBeanFactory().getBean(AnyTypeDAO.class);
                 Mapping uMapping = provision.getAnyType().equals(anyTypeDAO.findUser())
                         ? null
                         : provision.getMapping();

http://git-wip-us.apache.org/repos/asf/syncope/blob/6dfedd8f/core/misc/src/main/java/org/apache/syncope/core/misc/policy/AccountPolicyEnforcer.java
----------------------------------------------------------------------
diff --git a/core/misc/src/main/java/org/apache/syncope/core/misc/policy/AccountPolicyEnforcer.java b/core/misc/src/main/java/org/apache/syncope/core/misc/policy/AccountPolicyEnforcer.java
index 4b8faec..13ddc84 100644
--- a/core/misc/src/main/java/org/apache/syncope/core/misc/policy/AccountPolicyEnforcer.java
+++ b/core/misc/src/main/java/org/apache/syncope/core/misc/policy/AccountPolicyEnforcer.java
@@ -22,8 +22,6 @@ import java.util.regex.Pattern;
 import org.apache.syncope.common.lib.types.AccountPolicySpec;
 import org.apache.syncope.common.lib.types.PolicyType;
 import org.apache.syncope.core.persistence.api.entity.user.User;
-import org.apache.syncope.core.provisioning.api.UserSuspender;
-import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Component;
 
 @Component
@@ -31,11 +29,8 @@ public class AccountPolicyEnforcer implements PolicyEnforcer<AccountPolicySpec,
 
     private static final Pattern DEFAULT_PATTERN = Pattern.compile("[a-zA-Z0-9-_@. ]+");
 
-    @Autowired(required = false)
-    private UserSuspender userSuspender;
-
     @Override
-    public void enforce(final AccountPolicySpec policy, final PolicyType type, final User user) {
+    public boolean enforce(final AccountPolicySpec policy, final PolicyType type, final User user) {
         if (user.getUsername() == null) {
             throw new PolicyEnforceException("Invalid account");
         }
@@ -90,11 +85,7 @@ public class AccountPolicyEnforcer implements PolicyEnforcer<AccountPolicySpec,
         }
 
         // check for subsequent failed logins
-        if (userSuspender != null
-                && user.getFailedLogins() != null && policy.getMaxAuthenticationAttempts() > 0
-                && user.getFailedLogins() > policy.getMaxAuthenticationAttempts() && !user.isSuspended()) {
-
-            userSuspender.suspend(user, policy.isPropagateSuspension());
-        }
+        return (user.getFailedLogins() != null && policy.getMaxAuthenticationAttempts() > 0
+                && user.getFailedLogins() > policy.getMaxAuthenticationAttempts() && !user.isSuspended());
     }
 }

http://git-wip-us.apache.org/repos/asf/syncope/blob/6dfedd8f/core/misc/src/main/java/org/apache/syncope/core/misc/policy/PasswordPolicyEnforcer.java
----------------------------------------------------------------------
diff --git a/core/misc/src/main/java/org/apache/syncope/core/misc/policy/PasswordPolicyEnforcer.java b/core/misc/src/main/java/org/apache/syncope/core/misc/policy/PasswordPolicyEnforcer.java
index 41a6bb6..1313d2e 100644
--- a/core/misc/src/main/java/org/apache/syncope/core/misc/policy/PasswordPolicyEnforcer.java
+++ b/core/misc/src/main/java/org/apache/syncope/core/misc/policy/PasswordPolicyEnforcer.java
@@ -27,7 +27,7 @@ import org.springframework.stereotype.Component;
 public class PasswordPolicyEnforcer implements PolicyEnforcer<PasswordPolicySpec, User> {
 
     @Override
-    public void enforce(final PasswordPolicySpec policy, final PolicyType type, final User user) {
+    public boolean enforce(final PasswordPolicySpec policy, final PolicyType type, final User user) {
         final String clearPassword = user.getClearPassword();
         final String password = user.getPassword();
 
@@ -147,6 +147,8 @@ public class PasswordPolicyEnforcer implements PolicyEnforcer<PasswordPolicySpec
                 throw new PasswordPolicyException("Password mustn't end with a non-alphanumeric character");
             }
         }
+
+        return false;
     }
 
     private boolean checkForDigit(final String str) {


[26/31] syncope git commit: [SYNCOPE-652] Adjusting log management

Posted by md...@apache.org.
[SYNCOPE-652] Adjusting log management


Project: http://git-wip-us.apache.org/repos/asf/syncope/repo
Commit: http://git-wip-us.apache.org/repos/asf/syncope/commit/feba6991
Tree: http://git-wip-us.apache.org/repos/asf/syncope/tree/feba6991
Diff: http://git-wip-us.apache.org/repos/asf/syncope/diff/feba6991

Branch: refs/heads/SYNCOPE-156
Commit: feba6991edfa551d02bec421b2ec576e083755ec
Parents: bcb9a0d
Author: Francesco Chicchiriccò <il...@apache.org>
Authored: Tue Aug 11 16:19:14 2015 +0200
Committer: Francesco Chicchiriccò <il...@apache.org>
Committed: Thu Aug 13 17:16:51 2015 +0200

----------------------------------------------------------------------
 .../client/cli/commands/LoggerCommand.java      |   6 +-
 .../client/console/rest/LoggerRestClient.java   |  11 +-
 .../apache/syncope/common/lib/to/LoggerTO.java  |   2 +
 .../common/rest/api/service/LoggerService.java  |   6 +-
 core/logic/pom.xml                              |   7 +
 .../syncope/core/logic/init/LoggerAccessor.java |  95 +++++++++++++
 .../syncope/core/logic/init/LoggerLoader.java   |  65 ++-------
 .../apache/syncope/core/logic/AbstractTest.java |   1 -
 .../apache/syncope/core/logic/MappingTest.java  |  69 ----------
 core/logic/src/test/resources/logicTest.xml     |  19 ++-
 .../core/misc/security/AuthContextUtils.java    |  16 +++
 .../core/misc/security/AuthDataAccessor.java    |   6 +
 .../security/SyncopeAuthenticationProvider.java |  99 ++++++--------
 .../core/provisioning/java/MappingTest.java     |  69 ++++++++++
 .../java/ResourceDataBinderTest.java            | 130 ++++++++++++++++++
 .../java/data/ResourceDataBinderTest.java       | 132 -------------------
 .../rest/cxf/service/LoggerServiceImpl.java     |  10 +-
 .../src/main/resources/log4j2.xml               |   6 +
 .../fit/core/reference/LoggerITCase.java        |   7 +-
 19 files changed, 419 insertions(+), 337 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/syncope/blob/feba6991/client/cli/src/main/java/org/apache/syncope/client/cli/commands/LoggerCommand.java
----------------------------------------------------------------------
diff --git a/client/cli/src/main/java/org/apache/syncope/client/cli/commands/LoggerCommand.java b/client/cli/src/main/java/org/apache/syncope/client/cli/commands/LoggerCommand.java
index bbb826a..469e68a 100644
--- a/client/cli/src/main/java/org/apache/syncope/client/cli/commands/LoggerCommand.java
+++ b/client/cli/src/main/java/org/apache/syncope/client/cli/commands/LoggerCommand.java
@@ -105,7 +105,7 @@ public class LoggerCommand extends AbstractCommand {
                 final LoggerTO loggerTO = loggerService.read(LoggerType.LOG, log.getKey());
                 try {
                     loggerTO.setLevel(LoggerLevel.valueOf(log.getValue()));
-                    loggerService.update(LoggerType.LOG, loggerTO.getKey(), loggerTO);
+                    loggerService.update(LoggerType.LOG, loggerTO);
                     System.out.println(" - Logger " + loggerTO.getKey() + " new level -> " + loggerTO.getLevel());
                 } catch (final SyncopeClientException ex) {
                     System.out.println(" - Error: " + ex.getMessage());
@@ -121,7 +121,7 @@ public class LoggerCommand extends AbstractCommand {
             for (final LoggerTO loggerTO : loggerService.list(LoggerType.LOG)) {
                 try {
                     loggerTO.setLevel(LoggerLevel.valueOf(logLevel));
-                    loggerService.update(LoggerType.LOG, loggerTO.getKey(), loggerTO);
+                    loggerService.update(LoggerType.LOG, loggerTO);
                     System.out.println(" - Logger " + loggerTO.getKey() + " new level -> " + loggerTO.getLevel());
                 } catch (final SyncopeClientException ex) {
                     System.out.println(" - Error: " + ex.getMessage());
@@ -140,7 +140,7 @@ public class LoggerCommand extends AbstractCommand {
                 try {
                     loggerTO.setKey(entrySet.getKey());
                     loggerTO.setLevel(LoggerLevel.valueOf(entrySet.getValue()));
-                    loggerService.update(LoggerType.LOG, loggerTO.getKey(), loggerTO);
+                    loggerService.update(LoggerType.LOG, loggerTO);
                     System.out.println(" - Logger " + loggerTO.getKey() + " created with level -> " + loggerTO.
                             getLevel());
                 } catch (final SyncopeClientException ex) {

http://git-wip-us.apache.org/repos/asf/syncope/blob/feba6991/client/console/src/main/java/org/apache/syncope/client/console/rest/LoggerRestClient.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/rest/LoggerRestClient.java b/client/console/src/main/java/org/apache/syncope/client/console/rest/LoggerRestClient.java
index 318edcb..627e828 100644
--- a/client/console/src/main/java/org/apache/syncope/client/console/rest/LoggerRestClient.java
+++ b/client/console/src/main/java/org/apache/syncope/client/console/rest/LoggerRestClient.java
@@ -59,19 +59,18 @@ public class LoggerRestClient extends BaseRestClient {
         return result;
     }
 
-    public void setLogLevel(final String name, final LoggerLevel level) {
+    public void setLogLevel(final String key, final LoggerLevel level) {
         LoggerTO loggerTO = new LoggerTO();
-        loggerTO.setKey(name);
+        loggerTO.setKey(key);
         loggerTO.setLevel(level);
-        getService(LoggerService.class).update(LoggerType.LOG, name, loggerTO);
+        getService(LoggerService.class).update(LoggerType.LOG, loggerTO);
     }
 
     public void enableAudit(final AuditLoggerName auditLoggerName) {
-        String name = auditLoggerName.toLoggerName();
         LoggerTO loggerTO = new LoggerTO();
-        loggerTO.setKey(name);
+        loggerTO.setKey(auditLoggerName.toLoggerName());
         loggerTO.setLevel(LoggerLevel.DEBUG);
-        getService(LoggerService.class).update(LoggerType.AUDIT, name, loggerTO);
+        getService(LoggerService.class).update(LoggerType.AUDIT, loggerTO);
     }
 
     public void deleteLog(final String name) {

http://git-wip-us.apache.org/repos/asf/syncope/blob/feba6991/common/lib/src/main/java/org/apache/syncope/common/lib/to/LoggerTO.java
----------------------------------------------------------------------
diff --git a/common/lib/src/main/java/org/apache/syncope/common/lib/to/LoggerTO.java b/common/lib/src/main/java/org/apache/syncope/common/lib/to/LoggerTO.java
index 810a143..6e1ce1d 100644
--- a/common/lib/src/main/java/org/apache/syncope/common/lib/to/LoggerTO.java
+++ b/common/lib/src/main/java/org/apache/syncope/common/lib/to/LoggerTO.java
@@ -18,6 +18,7 @@
  */
 package org.apache.syncope.common.lib.to;
 
+import javax.ws.rs.PathParam;
 import javax.xml.bind.annotation.XmlRootElement;
 import javax.xml.bind.annotation.XmlType;
 import org.apache.syncope.common.lib.AbstractBaseBean;
@@ -41,6 +42,7 @@ public class LoggerTO extends AbstractBaseBean {
         this.level = level;
     }
 
+    @PathParam("key")
     public String getKey() {
         return key;
     }

http://git-wip-us.apache.org/repos/asf/syncope/blob/feba6991/common/rest-api/src/main/java/org/apache/syncope/common/rest/api/service/LoggerService.java
----------------------------------------------------------------------
diff --git a/common/rest-api/src/main/java/org/apache/syncope/common/rest/api/service/LoggerService.java b/common/rest-api/src/main/java/org/apache/syncope/common/rest/api/service/LoggerService.java
index 6ab40e7..3b89b7c 100644
--- a/common/rest-api/src/main/java/org/apache/syncope/common/rest/api/service/LoggerService.java
+++ b/common/rest-api/src/main/java/org/apache/syncope/common/rest/api/service/LoggerService.java
@@ -76,14 +76,12 @@ public interface LoggerService extends JAXRSService {
      * Creates or updates (if existing) the logger with matching name.
      *
      * @param type LoggerType to be selected
-     * @param name Logger name to be updated
      * @param logger Logger to be created or updated
      */
     @PUT
-    @Path("{type}/{name}")
+    @Path("{type}/{key}")
     @Consumes({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
-    void update(@NotNull @PathParam("type") LoggerType type, @NotNull @PathParam("name") String name,
-            @NotNull LoggerTO logger);
+    void update(@NotNull @PathParam("type") LoggerType type, @NotNull LoggerTO logger);
 
     /**
      * Deletes the logger with matching name.

http://git-wip-us.apache.org/repos/asf/syncope/blob/feba6991/core/logic/pom.xml
----------------------------------------------------------------------
diff --git a/core/logic/pom.xml b/core/logic/pom.xml
index 7ce109f..d652f3e 100644
--- a/core/logic/pom.xml
+++ b/core/logic/pom.xml
@@ -163,6 +163,13 @@ under the License.
         <directory>${basedir}/../persistence-jpa/src/test/resources</directory>
         <filtering>true</filtering>
       </testResource>
+      <testResource>
+        <directory>${basedir}/../provisioning-java/src/main/resources</directory>
+        <includes>
+          <include>connid.properties</include>
+        </includes>
+        <filtering>true</filtering>
+      </testResource>
     </testResources>
     
     <plugins>

http://git-wip-us.apache.org/repos/asf/syncope/blob/feba6991/core/logic/src/main/java/org/apache/syncope/core/logic/init/LoggerAccessor.java
----------------------------------------------------------------------
diff --git a/core/logic/src/main/java/org/apache/syncope/core/logic/init/LoggerAccessor.java b/core/logic/src/main/java/org/apache/syncope/core/logic/init/LoggerAccessor.java
new file mode 100644
index 0000000..e83a768
--- /dev/null
+++ b/core/logic/src/main/java/org/apache/syncope/core/logic/init/LoggerAccessor.java
@@ -0,0 +1,95 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.syncope.core.logic.init;
+
+import java.util.HashMap;
+import java.util.Map;
+import org.apache.logging.log4j.LogManager;
+import org.apache.logging.log4j.core.LoggerContext;
+import org.apache.logging.log4j.core.config.LoggerConfig;
+import org.apache.syncope.common.lib.SyncopeConstants;
+import org.apache.syncope.common.lib.types.LoggerLevel;
+import org.apache.syncope.common.lib.types.LoggerType;
+import org.apache.syncope.core.misc.security.AuthContextUtils;
+import org.apache.syncope.core.persistence.api.dao.LoggerDAO;
+import org.apache.syncope.core.persistence.api.entity.EntityFactory;
+import org.apache.syncope.core.persistence.api.entity.Logger;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+import org.springframework.transaction.annotation.Transactional;
+
+/**
+ * Domain-sensible (via {@code @Transactional} access to logger / audit data.
+ *
+ * @see LoggerLoader
+ */
+@Component
+public class LoggerAccessor {
+
+    @Autowired
+    private LoggerDAO loggerDAO;
+
+    @Autowired
+    private EntityFactory entityFactory;
+
+    @Transactional
+    public void synchronizeLog4J(final LoggerContext ctx) {
+        Map<String, Logger> syncopeLoggers = new HashMap<>();
+        if (SyncopeConstants.MASTER_DOMAIN.equals(AuthContextUtils.getDomain())) {
+            for (Logger syncopeLogger : loggerDAO.findAll(LoggerType.LOG)) {
+                syncopeLoggers.put(syncopeLogger.getKey(), syncopeLogger);
+            }
+        }
+        for (Logger syncopeLogger : loggerDAO.findAll(LoggerType.AUDIT)) {
+            syncopeLoggers.put(syncopeLogger.getKey(), syncopeLogger);
+        }
+
+        /*
+         * Traverse all defined log4j loggers: if there is a matching SyncopeLogger, set log4j level accordingly,
+         * otherwise create a SyncopeLogger instance with given name and level.
+         */
+        for (LoggerConfig logConf : ctx.getConfiguration().getLoggers().values()) {
+            if (!LogManager.ROOT_LOGGER_NAME.equals(logConf.getName()) && logConf.getLevel() != null) {
+                String loggerName = logConf.getName();
+                if (syncopeLoggers.containsKey(loggerName)) {
+                    logConf.setLevel(syncopeLoggers.get(loggerName).getLevel().getLevel());
+                    syncopeLoggers.remove(loggerName);
+                } else if (!loggerName.equals(LoggerType.AUDIT.getPrefix())) {
+                    Logger syncopeLogger = entityFactory.newEntity(Logger.class);
+                    syncopeLogger.setKey(loggerName);
+                    syncopeLogger.setLevel(LoggerLevel.fromLevel(logConf.getLevel()));
+                    syncopeLogger.setType(loggerName.startsWith(LoggerType.AUDIT.getPrefix())
+                            ? LoggerType.AUDIT
+                            : LoggerType.LOG);
+                    loggerDAO.save(syncopeLogger);
+                }
+            }
+        }
+
+        /*
+         * Foreach SyncopeLogger not found in log4j create a new log4j logger with given name and level.
+         */
+        for (Logger syncopeLogger : syncopeLoggers.values()) {
+            LoggerConfig logConf = ctx.getConfiguration().getLoggerConfig(syncopeLogger.getKey());
+            if (!LogManager.ROOT_LOGGER_NAME.equals(logConf.getName()) && logConf.getLevel() != null) {
+                logConf.setLevel(syncopeLogger.getLevel().getLevel());
+            }
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/feba6991/core/logic/src/main/java/org/apache/syncope/core/logic/init/LoggerLoader.java
----------------------------------------------------------------------
diff --git a/core/logic/src/main/java/org/apache/syncope/core/logic/init/LoggerLoader.java b/core/logic/src/main/java/org/apache/syncope/core/logic/init/LoggerLoader.java
index e86b46a..6187959 100644
--- a/core/logic/src/main/java/org/apache/syncope/core/logic/init/LoggerLoader.java
+++ b/core/logic/src/main/java/org/apache/syncope/core/logic/init/LoggerLoader.java
@@ -20,7 +20,6 @@ package org.apache.syncope.core.logic.init;
 
 import java.sql.Connection;
 import java.sql.SQLException;
-import java.util.HashMap;
 import java.util.Map;
 import javax.sql.DataSource;
 import org.apache.logging.log4j.Level;
@@ -31,15 +30,10 @@ import org.apache.logging.log4j.core.appender.db.jdbc.ColumnConfig;
 import org.apache.logging.log4j.core.appender.db.jdbc.ConnectionSource;
 import org.apache.logging.log4j.core.appender.db.jdbc.JdbcAppender;
 import org.apache.logging.log4j.core.config.LoggerConfig;
-import org.apache.syncope.common.lib.SyncopeConstants;
-import org.apache.syncope.common.lib.types.LoggerLevel;
-import org.apache.syncope.common.lib.types.LoggerType;
 import org.apache.syncope.core.misc.AuditManager;
+import org.apache.syncope.core.misc.security.AuthContextUtils;
 import org.apache.syncope.core.persistence.api.DomainsHolder;
 import org.apache.syncope.core.persistence.api.SyncopeLoader;
-import org.apache.syncope.core.persistence.api.dao.LoggerDAO;
-import org.apache.syncope.core.persistence.api.entity.EntityFactory;
-import org.apache.syncope.core.persistence.api.entity.Logger;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.jdbc.datasource.DataSourceUtils;
 import org.springframework.stereotype.Component;
@@ -52,10 +46,7 @@ public class LoggerLoader implements SyncopeLoader {
     private DomainsHolder domainsHolder;
 
     @Autowired
-    private LoggerDAO loggerDAO;
-
-    @Autowired
-    private EntityFactory entityFactory;
+    private LoggerAccessor loggerAccessor;
 
     @Override
     public Integer getPriority() {
@@ -65,9 +56,9 @@ public class LoggerLoader implements SyncopeLoader {
     @Transactional
     @Override
     public void load() {
-        LoggerContext ctx = (LoggerContext) LogManager.getContext(false);
+        final LoggerContext ctx = (LoggerContext) LogManager.getContext(false);
 
-        // 1. Audit table and DataSource for each configured domain
+        // Audit table and DataSource for each configured domain
         ColumnConfig[] columns = {
             ColumnConfig.createColumnConfig(ctx.getConfiguration(), "EVENT_DATE", null, null, "true", null, null),
             ColumnConfig.createColumnConfig(ctx.getConfiguration(), "LOGGER_LEVEL", "%level", null, null, null, null),
@@ -90,52 +81,18 @@ public class LoggerLoader implements SyncopeLoader {
                 ctx.getConfiguration().addAppender(appender);
             }
 
-            LoggerConfig logConf = new LoggerConfig(
-                    AuditManager.getDomainAuditLoggerName(entry.getKey()), null, false);
+            LoggerConfig logConf = new LoggerConfig(AuditManager.getDomainAuditLoggerName(entry.getKey()), null, false);
             logConf.addAppender(appender, Level.DEBUG, null);
             ctx.getConfiguration().addLogger(AuditManager.getDomainAuditLoggerName(entry.getKey()), logConf);
-        }
-        ctx.updateLoggers();
-
-        // 2. Aligning log4j conf with database content
-        Map<String, Logger> syncopeLoggers = new HashMap<>();
-        for (Logger syncopeLogger : loggerDAO.findAll(LoggerType.LOG)) {
-            syncopeLoggers.put(syncopeLogger.getKey(), syncopeLogger);
-        }
 
-        for (Logger syncopeLogger : loggerDAO.findAll(LoggerType.AUDIT)) {
-            syncopeLoggers.put(syncopeLogger.getKey(), syncopeLogger);
-        }
+            AuthContextUtils.execWithAuthContext(entry.getKey(), new AuthContextUtils.Executable<Void>() {
 
-        /*
-         * Traverse all defined log4j loggers: if there is a matching SyncopeLogger, set log4j level accordingly,
-         * otherwise create a SyncopeLogger instance with given name and level.
-         */
-        for (LoggerConfig logConf : ctx.getConfiguration().getLoggers().values()) {
-            final String loggerName = LogManager.ROOT_LOGGER_NAME.equals(logConf.getName())
-                    ? SyncopeConstants.ROOT_LOGGER : logConf.getName();
-            if (logConf.getLevel() != null) {
-                if (syncopeLoggers.containsKey(loggerName)) {
-                    logConf.setLevel(syncopeLoggers.get(loggerName).getLevel().getLevel());
-                    syncopeLoggers.remove(loggerName);
-                } else if (!loggerName.equals(LoggerType.AUDIT.getPrefix())) {
-                    Logger syncopeLogger = entityFactory.newEntity(Logger.class);
-                    syncopeLogger.setKey(loggerName);
-                    syncopeLogger.setLevel(LoggerLevel.fromLevel(logConf.getLevel()));
-                    syncopeLogger.setType(loggerName.startsWith(LoggerType.AUDIT.getPrefix())
-                            ? LoggerType.AUDIT
-                            : LoggerType.LOG);
-                    loggerDAO.save(syncopeLogger);
+                @Override
+                public Void exec() {
+                    loggerAccessor.synchronizeLog4J(ctx);
+                    return null;
                 }
-            }
-        }
-
-        /*
-         * Foreach SyncopeLogger not found in log4j create a new log4j logger with given name and level.
-         */
-        for (Logger syncopeLogger : syncopeLoggers.values()) {
-            LoggerConfig logConf = ctx.getConfiguration().getLoggerConfig(syncopeLogger.getKey());
-            logConf.setLevel(syncopeLogger.getLevel().getLevel());
+            });
         }
 
         ctx.updateLoggers();

http://git-wip-us.apache.org/repos/asf/syncope/blob/feba6991/core/logic/src/test/java/org/apache/syncope/core/logic/AbstractTest.java
----------------------------------------------------------------------
diff --git a/core/logic/src/test/java/org/apache/syncope/core/logic/AbstractTest.java b/core/logic/src/test/java/org/apache/syncope/core/logic/AbstractTest.java
index d4b0fa4..32ae367 100644
--- a/core/logic/src/test/java/org/apache/syncope/core/logic/AbstractTest.java
+++ b/core/logic/src/test/java/org/apache/syncope/core/logic/AbstractTest.java
@@ -30,7 +30,6 @@ import org.springframework.test.context.transaction.TransactionConfiguration;
     "classpath:provisioningContext.xml",
     "classpath:logicContext.xml",
     "classpath:workflowContext.xml",
-    "classpath:persistenceTest.xml",
     "classpath:logicTest.xml"
 })
 @TransactionConfiguration(transactionManager = "MasterTransactionManager")

http://git-wip-us.apache.org/repos/asf/syncope/blob/feba6991/core/logic/src/test/java/org/apache/syncope/core/logic/MappingTest.java
----------------------------------------------------------------------
diff --git a/core/logic/src/test/java/org/apache/syncope/core/logic/MappingTest.java b/core/logic/src/test/java/org/apache/syncope/core/logic/MappingTest.java
deleted file mode 100644
index 770bac9..0000000
--- a/core/logic/src/test/java/org/apache/syncope/core/logic/MappingTest.java
+++ /dev/null
@@ -1,69 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.syncope.core.logic;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertNotNull;
-
-import org.apache.syncope.core.misc.MappingUtils;
-import org.apache.syncope.core.persistence.api.dao.AnyTypeDAO;
-import org.apache.syncope.core.persistence.api.dao.ExternalResourceDAO;
-import org.apache.syncope.core.persistence.api.dao.UserDAO;
-import org.apache.syncope.core.persistence.api.entity.resource.ExternalResource;
-import org.apache.syncope.core.persistence.api.entity.resource.Provision;
-import org.apache.syncope.core.persistence.api.entity.user.User;
-import org.identityconnectors.framework.common.objects.Name;
-import org.junit.Test;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.transaction.annotation.Transactional;
-
-@Transactional
-public class MappingTest extends AbstractTest {
-
-    @Autowired
-    private ExternalResourceDAO resourceDAO;
-
-    @Autowired
-    private AnyTypeDAO anyTypeDAO;
-
-    @Autowired
-    private UserDAO userDAO;
-
-    @Test
-    public void connObjectLink() {
-        ExternalResource ldap = resourceDAO.find("resource-ldap");
-        assertNotNull(ldap);
-
-        Provision provision = ldap.getProvision(anyTypeDAO.findUser());
-        assertNotNull(provision);
-        assertNotNull(provision.getMapping());
-        assertNotNull(provision.getMapping().getConnObjectLink());
-
-        User user = userDAO.find("rossini");
-        assertNotNull(user);
-
-        Name name = MappingUtils.evaluateNAME(user, provision, user.getUsername());
-        assertEquals("uid=rossini,ou=people,o=isp", name.getNameValue());
-
-        provision.getMapping().setConnObjectLink("'uid=' + username + ',o=' + realm + ',ou=people,o=isp'");
-
-        name = MappingUtils.evaluateNAME(user, provision, user.getUsername());
-        assertEquals("uid=rossini,o=even,ou=people,o=isp", name.getNameValue());
-    }
-}

http://git-wip-us.apache.org/repos/asf/syncope/blob/feba6991/core/logic/src/test/resources/logicTest.xml
----------------------------------------------------------------------
diff --git a/core/logic/src/test/resources/logicTest.xml b/core/logic/src/test/resources/logicTest.xml
index 2dca918..fd6edd6 100644
--- a/core/logic/src/test/resources/logicTest.xml
+++ b/core/logic/src/test/resources/logicTest.xml
@@ -19,8 +19,11 @@ under the License.
 -->
 <beans xmlns="http://www.springframework.org/schema/beans"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+       xmlns:context="http://www.springframework.org/schema/context"
        xsi:schemaLocation="http://www.springframework.org/schema/beans
-                           http://www.springframework.org/schema/beans/spring-beans.xsd">
+                           http://www.springframework.org/schema/beans/spring-beans.xsd
+                           http://www.springframework.org/schema/context
+                           http://www.springframework.org/schema/context/spring-context.xsd">
     
   <bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
     <property name="locations">
@@ -39,4 +42,18 @@ under the License.
     <property name="ignoreUnresolvablePlaceholders" value="true"/>
   </bean>
 
+  <bean class="org.apache.syncope.core.misc.spring.ApplicationContextProvider"/>
+
+  <bean id="adminUser" class="java.lang.String">
+    <constructor-arg value="${adminUser}"/>
+  </bean>
+  <bean id="anonymousUser" class="java.lang.String">
+    <constructor-arg value="${anonymousUser}"/>
+  </bean>
+  
+  <context:component-scan base-package="org.apache.syncope.core.misc.policy"/>
+  <context:component-scan base-package="org.apache.syncope.core.misc.security"/>
+
+  <import resource="persistenceContext.xml"/>
+  
 </beans>

http://git-wip-us.apache.org/repos/asf/syncope/blob/feba6991/core/misc/src/main/java/org/apache/syncope/core/misc/security/AuthContextUtils.java
----------------------------------------------------------------------
diff --git a/core/misc/src/main/java/org/apache/syncope/core/misc/security/AuthContextUtils.java b/core/misc/src/main/java/org/apache/syncope/core/misc/security/AuthContextUtils.java
index 38240d9..4586ee3 100644
--- a/core/misc/src/main/java/org/apache/syncope/core/misc/security/AuthContextUtils.java
+++ b/core/misc/src/main/java/org/apache/syncope/core/misc/security/AuthContextUtils.java
@@ -39,6 +39,11 @@ import org.springframework.security.core.userdetails.User;
 
 public final class AuthContextUtils {
 
+    public interface Executable<T> {
+
+        T exec();
+    }
+
     public static String getUsername() {
         Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
         return authentication == null ? SyncopeConstants.UNAUTHENTICATED : authentication.getName();
@@ -106,6 +111,17 @@ public final class AuthContextUtils {
         SecurityContextHolder.clearContext();
     }
 
+    public static <T> T execWithAuthContext(final String domainKey, final Executable<T> executable) {
+        SecurityContext ctx = SecurityContextHolder.getContext();
+        setFakeAuth(domainKey);
+        try {
+            return executable.exec();
+        } finally {
+            clearFakeAuth();
+            SecurityContextHolder.setContext(ctx);
+        }
+    }
+
     /**
      * Private default constructor, for static-only classes.
      */

http://git-wip-us.apache.org/repos/asf/syncope/blob/feba6991/core/misc/src/main/java/org/apache/syncope/core/misc/security/AuthDataAccessor.java
----------------------------------------------------------------------
diff --git a/core/misc/src/main/java/org/apache/syncope/core/misc/security/AuthDataAccessor.java b/core/misc/src/main/java/org/apache/syncope/core/misc/security/AuthDataAccessor.java
index 7643f9d..052cc30 100644
--- a/core/misc/src/main/java/org/apache/syncope/core/misc/security/AuthDataAccessor.java
+++ b/core/misc/src/main/java/org/apache/syncope/core/misc/security/AuthDataAccessor.java
@@ -64,6 +64,12 @@ import org.springframework.security.core.Authentication;
 import org.springframework.security.core.userdetails.UsernameNotFoundException;
 import org.springframework.transaction.annotation.Transactional;
 
+/**
+ * Domain-sensible (via {@code @Transactional} access to authentication / authorization data.
+ *
+ * @see SyncopeAuthenticationProvider
+ * @see SyncopeAuthenticationDetails
+ */
 public class AuthDataAccessor {
 
     protected static final Logger LOG = LoggerFactory.getLogger(AuthDataAccessor.class);

http://git-wip-us.apache.org/repos/asf/syncope/blob/feba6991/core/misc/src/main/java/org/apache/syncope/core/misc/security/SyncopeAuthenticationProvider.java
----------------------------------------------------------------------
diff --git a/core/misc/src/main/java/org/apache/syncope/core/misc/security/SyncopeAuthenticationProvider.java b/core/misc/src/main/java/org/apache/syncope/core/misc/security/SyncopeAuthenticationProvider.java
index c8fa53d..ff7e453 100644
--- a/core/misc/src/main/java/org/apache/syncope/core/misc/security/SyncopeAuthenticationProvider.java
+++ b/core/misc/src/main/java/org/apache/syncope/core/misc/security/SyncopeAuthenticationProvider.java
@@ -25,6 +25,7 @@ import org.apache.syncope.common.lib.SyncopeConstants;
 import org.apache.syncope.common.lib.types.AuditElements;
 import org.apache.syncope.common.lib.types.AuditElements.Result;
 import org.apache.syncope.common.lib.types.CipherAlgorithm;
+import org.apache.syncope.core.misc.security.AuthContextUtils.Executable;
 import org.apache.syncope.core.persistence.api.entity.Domain;
 import org.apache.syncope.core.provisioning.api.UserProvisioningManager;
 import org.slf4j.Logger;
@@ -35,8 +36,6 @@ import org.springframework.security.authentication.AuthenticationProvider;
 import org.springframework.security.authentication.BadCredentialsException;
 import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
 import org.springframework.security.core.Authentication;
-import org.springframework.security.core.context.SecurityContext;
-import org.springframework.security.core.context.SecurityContextHolder;
 import org.springframework.security.core.userdetails.UserDetailsService;
 
 @Configurable
@@ -91,17 +90,6 @@ public class SyncopeAuthenticationProvider implements AuthenticationProvider {
         this.userDetailsService = syncopeUserDetailsService;
     }
 
-    protected <T> T execWithAuthContext(final String domainKey, final Executable<T> executable) {
-        SecurityContext ctx = SecurityContextHolder.getContext();
-        AuthContextUtils.setFakeAuth(domainKey);
-        try {
-            return executable.exec();
-        } finally {
-            AuthContextUtils.clearFakeAuth();
-            SecurityContextHolder.setContext(ctx);
-        }
-    }
-
     @Override
     public Authentication authenticate(final Authentication authentication) {
         String domainKey = SyncopeAuthenticationDetails.class.cast(authentication.getDetails()).getDomain();
@@ -121,22 +109,23 @@ public class SyncopeAuthenticationProvider implements AuthenticationProvider {
                         adminPassword);
             } else {
                 final String domainToFind = domainKey;
-                authenticated = execWithAuthContext(SyncopeConstants.MASTER_DOMAIN, new Executable<Boolean>() {
-
-                    @Override
-                    public Boolean exec() {
-                        Domain domain = dataAccessor.findDomain(domainToFind);
-
-                        return encryptor.verify(
-                                authentication.getCredentials().toString(),
-                                domain.getAdminCipherAlgorithm(),
-                                domain.getAdminPwd());
-                    }
-                });
+                authenticated = AuthContextUtils.execWithAuthContext(
+                        SyncopeConstants.MASTER_DOMAIN, new Executable<Boolean>() {
+
+                            @Override
+                            public Boolean exec() {
+                                Domain domain = dataAccessor.findDomain(domainToFind);
+
+                                return encryptor.verify(
+                                        authentication.getCredentials().toString(),
+                                        domain.getAdminCipherAlgorithm(),
+                                        domain.getAdminPwd());
+                            }
+                        });
             }
         } else {
             final Pair<Long, Boolean> authResult =
-                    execWithAuthContext(domainKey, new Executable<Pair<Long, Boolean>>() {
+                    AuthContextUtils.execWithAuthContext(domainKey, new Executable<Pair<Long, Boolean>>() {
 
                         @Override
                         public Pair<Long, Boolean> exec() {
@@ -145,7 +134,7 @@ public class SyncopeAuthenticationProvider implements AuthenticationProvider {
                     });
             authenticated = authResult.getValue();
             if (!authenticated) {
-                execWithAuthContext(domainKey, new Executable<Void>() {
+                AuthContextUtils.execWithAuthContext(domainKey, new Executable<Void>() {
 
                     @Override
                     public Void exec() {
@@ -159,35 +148,36 @@ public class SyncopeAuthenticationProvider implements AuthenticationProvider {
         final boolean isAuthenticated = authenticated;
         UsernamePasswordAuthenticationToken token;
         if (isAuthenticated) {
-            token = execWithAuthContext(domainKey, new Executable<UsernamePasswordAuthenticationToken>() {
-
-                @Override
-                public UsernamePasswordAuthenticationToken exec() {
-                    UsernamePasswordAuthenticationToken token = new UsernamePasswordAuthenticationToken(
-                            authentication.getPrincipal(),
-                            null,
-                            userDetailsService.loadUserByUsername(authentication.getPrincipal().toString()).
-                            getAuthorities());
-                    token.setDetails(authentication.getDetails());
+            token = AuthContextUtils.execWithAuthContext(
+                    domainKey, new Executable<UsernamePasswordAuthenticationToken>() {
 
-                    dataAccessor.audit(
-                            AuditElements.EventCategoryType.REST,
-                            AuditElements.AUTHENTICATION_CATEGORY,
-                            null,
-                            AuditElements.LOGIN_EVENT,
-                            Result.SUCCESS,
-                            null,
-                            isAuthenticated,
-                            authentication,
-                            "Successfully authenticated, with entitlements: " + token.getAuthorities());
-                    return token;
-                }
-            });
+                        @Override
+                        public UsernamePasswordAuthenticationToken exec() {
+                            UsernamePasswordAuthenticationToken token = new UsernamePasswordAuthenticationToken(
+                                    authentication.getPrincipal(),
+                                    null,
+                                    userDetailsService.loadUserByUsername(authentication.getPrincipal().toString()).
+                                    getAuthorities());
+                            token.setDetails(authentication.getDetails());
+
+                            dataAccessor.audit(
+                                    AuditElements.EventCategoryType.REST,
+                                    AuditElements.AUTHENTICATION_CATEGORY,
+                                    null,
+                                    AuditElements.LOGIN_EVENT,
+                                    Result.SUCCESS,
+                                    null,
+                                    isAuthenticated,
+                                    authentication,
+                                    "Successfully authenticated, with entitlements: " + token.getAuthorities());
+                            return token;
+                        }
+                    });
 
-            LOG.debug("User {} successfully authenticated, with groups {}",
+            LOG.debug("User {} successfully authenticated, with entitlements {}",
                     authentication.getPrincipal(), token.getAuthorities());
         } else {
-            execWithAuthContext(domainKey, new Executable<Void>() {
+            AuthContextUtils.execWithAuthContext(domainKey, new Executable<Void>() {
 
                 @Override
                 public Void exec() {
@@ -217,9 +207,4 @@ public class SyncopeAuthenticationProvider implements AuthenticationProvider {
     public boolean supports(final Class<? extends Object> type) {
         return type.equals(UsernamePasswordAuthenticationToken.class);
     }
-
-    protected interface Executable<T> {
-
-        T exec();
-    }
 }

http://git-wip-us.apache.org/repos/asf/syncope/blob/feba6991/core/provisioning-java/src/test/java/org/apache/syncope/core/provisioning/java/MappingTest.java
----------------------------------------------------------------------
diff --git a/core/provisioning-java/src/test/java/org/apache/syncope/core/provisioning/java/MappingTest.java b/core/provisioning-java/src/test/java/org/apache/syncope/core/provisioning/java/MappingTest.java
new file mode 100644
index 0000000..eb100f3
--- /dev/null
+++ b/core/provisioning-java/src/test/java/org/apache/syncope/core/provisioning/java/MappingTest.java
@@ -0,0 +1,69 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.syncope.core.provisioning.java;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+
+import org.apache.syncope.core.misc.MappingUtils;
+import org.apache.syncope.core.persistence.api.dao.AnyTypeDAO;
+import org.apache.syncope.core.persistence.api.dao.ExternalResourceDAO;
+import org.apache.syncope.core.persistence.api.dao.UserDAO;
+import org.apache.syncope.core.persistence.api.entity.resource.ExternalResource;
+import org.apache.syncope.core.persistence.api.entity.resource.Provision;
+import org.apache.syncope.core.persistence.api.entity.user.User;
+import org.identityconnectors.framework.common.objects.Name;
+import org.junit.Test;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.transaction.annotation.Transactional;
+
+@Transactional
+public class MappingTest extends AbstractTest {
+
+    @Autowired
+    private ExternalResourceDAO resourceDAO;
+
+    @Autowired
+    private AnyTypeDAO anyTypeDAO;
+
+    @Autowired
+    private UserDAO userDAO;
+
+    @Test
+    public void connObjectLink() {
+        ExternalResource ldap = resourceDAO.find("resource-ldap");
+        assertNotNull(ldap);
+
+        Provision provision = ldap.getProvision(anyTypeDAO.findUser());
+        assertNotNull(provision);
+        assertNotNull(provision.getMapping());
+        assertNotNull(provision.getMapping().getConnObjectLink());
+
+        User user = userDAO.find("rossini");
+        assertNotNull(user);
+
+        Name name = MappingUtils.evaluateNAME(user, provision, user.getUsername());
+        assertEquals("uid=rossini,ou=people,o=isp", name.getNameValue());
+
+        provision.getMapping().setConnObjectLink("'uid=' + username + ',o=' + realm + ',ou=people,o=isp'");
+
+        name = MappingUtils.evaluateNAME(user, provision, user.getUsername());
+        assertEquals("uid=rossini,o=even,ou=people,o=isp", name.getNameValue());
+    }
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/feba6991/core/provisioning-java/src/test/java/org/apache/syncope/core/provisioning/java/ResourceDataBinderTest.java
----------------------------------------------------------------------
diff --git a/core/provisioning-java/src/test/java/org/apache/syncope/core/provisioning/java/ResourceDataBinderTest.java b/core/provisioning-java/src/test/java/org/apache/syncope/core/provisioning/java/ResourceDataBinderTest.java
new file mode 100644
index 0000000..f0a706c
--- /dev/null
+++ b/core/provisioning-java/src/test/java/org/apache/syncope/core/provisioning/java/ResourceDataBinderTest.java
@@ -0,0 +1,130 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.syncope.core.provisioning.java;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+
+import java.util.HashSet;
+import java.util.Set;
+import org.apache.syncope.common.lib.to.MappingItemTO;
+import org.apache.syncope.common.lib.to.MappingTO;
+import org.apache.syncope.common.lib.to.ProvisionTO;
+import org.apache.syncope.common.lib.to.ResourceTO;
+import org.apache.syncope.common.lib.types.AnyTypeKind;
+import org.apache.syncope.common.lib.types.IntMappingType;
+import org.apache.syncope.common.lib.types.MappingPurpose;
+import org.apache.syncope.common.lib.types.PropagationMode;
+import org.apache.syncope.core.persistence.api.dao.AnyTypeDAO;
+import org.apache.syncope.core.persistence.api.dao.ExternalResourceDAO;
+import org.apache.syncope.core.persistence.api.dao.PlainSchemaDAO;
+import org.apache.syncope.core.persistence.api.entity.PlainSchema;
+import org.apache.syncope.core.persistence.api.entity.resource.ExternalResource;
+import org.apache.syncope.core.persistence.api.entity.resource.MappingItem;
+import org.apache.syncope.core.provisioning.api.data.ResourceDataBinder;
+import org.identityconnectors.framework.common.objects.ObjectClass;
+import org.junit.Test;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.transaction.annotation.Transactional;
+
+@Transactional
+public class ResourceDataBinderTest extends AbstractTest {
+
+    @Autowired
+    private AnyTypeDAO anyTypeDAO;
+
+    @Autowired
+    private ExternalResourceDAO resourceDAO;
+
+    @Autowired
+    private ResourceDataBinder resourceDataBinder;
+
+    @Autowired
+    private PlainSchemaDAO plainSchemaDAO;
+
+    @Test
+    public void issue42() {
+        PlainSchema userId = plainSchemaDAO.find("userId");
+
+        Set<MappingItem> beforeUserIdMappings = new HashSet<>();
+        for (ExternalResource res : resourceDAO.findAll()) {
+            if (res.getProvision(anyTypeDAO.findUser()) != null
+                    && res.getProvision(anyTypeDAO.findUser()).getMapping() != null) {
+
+                for (MappingItem mapItem : res.getProvision(anyTypeDAO.findUser()).getMapping().getItems()) {
+                    if (userId.getKey().equals(mapItem.getIntAttrName())) {
+                        beforeUserIdMappings.add(mapItem);
+                    }
+                }
+            }
+        }
+
+        ResourceTO resourceTO = new ResourceTO();
+        resourceTO.setKey("resource-issue42");
+        resourceTO.setConnector(100L);
+        resourceTO.setPropagationMode(PropagationMode.ONE_PHASE);
+        resourceTO.setEnforceMandatoryCondition(true);
+
+        ProvisionTO provisionTO = new ProvisionTO();
+        provisionTO.setAnyType(AnyTypeKind.USER.name());
+        provisionTO.setObjectClass(ObjectClass.ACCOUNT_NAME);
+        resourceTO.getProvisions().add(provisionTO);
+
+        MappingTO mapping = new MappingTO();
+        provisionTO.setMapping(mapping);
+
+        MappingItemTO item = new MappingItemTO();
+        item.setIntAttrName("userId");
+        item.setIntMappingType(IntMappingType.UserPlainSchema);
+        item.setExtAttrName("campo1");
+        item.setConnObjectKey(true);
+        item.setMandatoryCondition("false");
+        item.setPurpose(MappingPurpose.BOTH);
+        mapping.setConnObjectKeyItem(item);
+
+        ExternalResource resource = resourceDataBinder.create(resourceTO);
+        resource = resourceDAO.save(resource);
+        assertNotNull(resource);
+        assertNotNull(resource.getProvision(anyTypeDAO.findUser()).getMapping());
+        assertEquals(1, resource.getProvision(anyTypeDAO.findUser()).getMapping().getItems().size());
+
+        resourceDAO.flush();
+
+        ExternalResource actual = resourceDAO.find("resource-issue42");
+        assertNotNull(actual);
+        assertEquals(resource, actual);
+
+        userId = plainSchemaDAO.find("userId");
+
+        Set<MappingItem> afterUserIdMappings = new HashSet<>();
+        for (ExternalResource res : resourceDAO.findAll()) {
+            if (res.getProvision(anyTypeDAO.findUser()) != null
+                    && res.getProvision(anyTypeDAO.findUser()).getMapping() != null) {
+
+                for (MappingItem mapItem : res.getProvision(anyTypeDAO.findUser()).getMapping().getItems()) {
+                    if (userId.getKey().equals(mapItem.getIntAttrName())) {
+                        afterUserIdMappings.add(mapItem);
+                    }
+                }
+            }
+        }
+
+        assertEquals(beforeUserIdMappings.size(), afterUserIdMappings.size() - 1);
+    }
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/feba6991/core/provisioning-java/src/test/java/org/apache/syncope/core/provisioning/java/data/ResourceDataBinderTest.java
----------------------------------------------------------------------
diff --git a/core/provisioning-java/src/test/java/org/apache/syncope/core/provisioning/java/data/ResourceDataBinderTest.java b/core/provisioning-java/src/test/java/org/apache/syncope/core/provisioning/java/data/ResourceDataBinderTest.java
deleted file mode 100644
index f2eb839..0000000
--- a/core/provisioning-java/src/test/java/org/apache/syncope/core/provisioning/java/data/ResourceDataBinderTest.java
+++ /dev/null
@@ -1,132 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.syncope.core.provisioning.java.data;
-
-import org.apache.syncope.core.provisioning.java.AbstractTest;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertNotNull;
-
-import java.util.HashSet;
-import java.util.Set;
-import org.apache.syncope.common.lib.to.MappingItemTO;
-import org.apache.syncope.common.lib.to.MappingTO;
-import org.apache.syncope.common.lib.to.ProvisionTO;
-import org.apache.syncope.common.lib.to.ResourceTO;
-import org.apache.syncope.common.lib.types.AnyTypeKind;
-import org.apache.syncope.common.lib.types.IntMappingType;
-import org.apache.syncope.common.lib.types.MappingPurpose;
-import org.apache.syncope.common.lib.types.PropagationMode;
-import org.apache.syncope.core.persistence.api.dao.AnyTypeDAO;
-import org.apache.syncope.core.persistence.api.dao.ExternalResourceDAO;
-import org.apache.syncope.core.persistence.api.dao.PlainSchemaDAO;
-import org.apache.syncope.core.persistence.api.entity.PlainSchema;
-import org.apache.syncope.core.persistence.api.entity.resource.ExternalResource;
-import org.apache.syncope.core.persistence.api.entity.resource.MappingItem;
-import org.apache.syncope.core.provisioning.api.data.ResourceDataBinder;
-import org.identityconnectors.framework.common.objects.ObjectClass;
-import org.junit.Test;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.transaction.annotation.Transactional;
-
-@Transactional
-public class ResourceDataBinderTest extends AbstractTest {
-
-    @Autowired
-    private AnyTypeDAO anyTypeDAO;
-
-    @Autowired
-    private ExternalResourceDAO resourceDAO;
-
-    @Autowired
-    private ResourceDataBinder resourceDataBinder;
-
-    @Autowired
-    private PlainSchemaDAO plainSchemaDAO;
-
-    @Test
-    public void issue42() {
-        PlainSchema userId = plainSchemaDAO.find("userId");
-
-        Set<MappingItem> beforeUserIdMappings = new HashSet<>();
-        for (ExternalResource res : resourceDAO.findAll()) {
-            if (res.getProvision(anyTypeDAO.findUser()) != null
-                    && res.getProvision(anyTypeDAO.findUser()).getMapping() != null) {
-
-                for (MappingItem mapItem : res.getProvision(anyTypeDAO.findUser()).getMapping().getItems()) {
-                    if (userId.getKey().equals(mapItem.getIntAttrName())) {
-                        beforeUserIdMappings.add(mapItem);
-                    }
-                }
-            }
-        }
-
-        ResourceTO resourceTO = new ResourceTO();
-        resourceTO.setKey("resource-issue42");
-        resourceTO.setConnector(100L);
-        resourceTO.setPropagationMode(PropagationMode.ONE_PHASE);
-        resourceTO.setEnforceMandatoryCondition(true);
-
-        ProvisionTO provisionTO = new ProvisionTO();
-        provisionTO.setAnyType(AnyTypeKind.USER.name());
-        provisionTO.setObjectClass(ObjectClass.ACCOUNT_NAME);
-        resourceTO.getProvisions().add(provisionTO);
-
-        MappingTO mapping = new MappingTO();
-        provisionTO.setMapping(mapping);
-
-        MappingItemTO item = new MappingItemTO();
-        item.setIntAttrName("userId");
-        item.setIntMappingType(IntMappingType.UserPlainSchema);
-        item.setExtAttrName("campo1");
-        item.setConnObjectKey(true);
-        item.setMandatoryCondition("false");
-        item.setPurpose(MappingPurpose.BOTH);
-        mapping.setConnObjectKeyItem(item);
-
-        ExternalResource resource = resourceDataBinder.create(resourceTO);
-        resource = resourceDAO.save(resource);
-        assertNotNull(resource);
-        assertNotNull(resource.getProvision(anyTypeDAO.findUser()).getMapping());
-        assertEquals(1, resource.getProvision(anyTypeDAO.findUser()).getMapping().getItems().size());
-
-        resourceDAO.flush();
-
-        ExternalResource actual = resourceDAO.find("resource-issue42");
-        assertNotNull(actual);
-        assertEquals(resource, actual);
-
-        userId = plainSchemaDAO.find("userId");
-
-        Set<MappingItem> afterUserIdMappings = new HashSet<>();
-        for (ExternalResource res : resourceDAO.findAll()) {
-            if (res.getProvision(anyTypeDAO.findUser()) != null
-                    && res.getProvision(anyTypeDAO.findUser()).getMapping() != null) {
-
-                for (MappingItem mapItem : res.getProvision(anyTypeDAO.findUser()).getMapping().getItems()) {
-                    if (userId.getKey().equals(mapItem.getIntAttrName())) {
-                        afterUserIdMappings.add(mapItem);
-                    }
-                }
-            }
-        }
-
-        assertEquals(beforeUserIdMappings.size(), afterUserIdMappings.size() - 1);
-    }
-}

http://git-wip-us.apache.org/repos/asf/syncope/blob/feba6991/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/LoggerServiceImpl.java
----------------------------------------------------------------------
diff --git a/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/LoggerServiceImpl.java b/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/LoggerServiceImpl.java
index 2ae9136..4379754 100644
--- a/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/LoggerServiceImpl.java
+++ b/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/LoggerServiceImpl.java
@@ -48,9 +48,7 @@ public class LoggerServiceImpl extends AbstractServiceImpl implements LoggerServ
             case AUDIT:
                 try {
                     logic.disableAudit(AuditLoggerName.fromLoggerName(name));
-                } catch (IllegalArgumentException e) {
-                    throw new BadRequestException(e);
-                } catch (ParseException e) {
+                } catch (IllegalArgumentException | ParseException e) {
                     throw new BadRequestException(e);
                 }
                 break;
@@ -88,15 +86,15 @@ public class LoggerServiceImpl extends AbstractServiceImpl implements LoggerServ
     }
 
     @Override
-    public void update(final LoggerType type, final String name, final LoggerTO logger) {
+    public void update(final LoggerType type, final LoggerTO logger) {
         switch (type) {
             case LOG:
-                logic.setLogLevel(name, logger.getLevel().getLevel());
+                logic.setLogLevel(logger.getKey(), logger.getLevel().getLevel());
                 break;
 
             case AUDIT:
                 try {
-                    logic.enableAudit(AuditLoggerName.fromLoggerName(name));
+                    logic.enableAudit(AuditLoggerName.fromLoggerName(logger.getKey()));
                 } catch (Exception e) {
                     throw new BadRequestException(e);
                 }

http://git-wip-us.apache.org/repos/asf/syncope/blob/feba6991/fit/core-reference/src/main/resources/log4j2.xml
----------------------------------------------------------------------
diff --git a/fit/core-reference/src/main/resources/log4j2.xml b/fit/core-reference/src/main/resources/log4j2.xml
index b50d9cb..df1de40 100644
--- a/fit/core-reference/src/main/resources/log4j2.xml
+++ b/fit/core-reference/src/main/resources/log4j2.xml
@@ -103,6 +103,9 @@ under the License.
       <appender-ref ref="connid"/>
     </asyncLogger>
     
+    <asyncLogger name="org.apache.syncope" additivity="false" level="ERROR">
+      <appender-ref ref="main"/>
+    </asyncLogger>
     <asyncLogger name="org.apache.syncope.core.provisioning" additivity="false" level="INFO">
       <appender-ref ref="main"/>
     </asyncLogger>
@@ -115,6 +118,9 @@ under the License.
     <asyncLogger name="org.quartz" additivity="false" level="INFO">
       <appender-ref ref="main"/>
     </asyncLogger>
+    <asyncLogger name="org.activiti" additivity="false" level="ERROR">
+      <appender-ref ref="main"/>
+    </asyncLogger>
     <asyncLogger name="org.apache.camel" additivity="false" level="ERROR">
       <appender-ref ref="main"/>
     </asyncLogger>

http://git-wip-us.apache.org/repos/asf/syncope/blob/feba6991/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/LoggerITCase.java
----------------------------------------------------------------------
diff --git a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/LoggerITCase.java b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/LoggerITCase.java
index 40fe8a1..fb93618 100644
--- a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/LoggerITCase.java
+++ b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/LoggerITCase.java
@@ -76,7 +76,7 @@ public class LoggerITCase extends AbstractITCase {
         LoggerTO logger = new LoggerTO();
         logger.setKey("TEST");
         logger.setLevel(LoggerLevel.INFO);
-        loggerService.update(LoggerType.LOG, logger.getKey(), logger);
+        loggerService.update(LoggerType.LOG, logger);
         logger = loggerService.read(LoggerType.LOG, logger.getKey());
         assertNotNull(logger);
         assertEquals(LoggerLevel.INFO, logger.getLevel());
@@ -106,10 +106,9 @@ public class LoggerITCase extends AbstractITCase {
         assertFalse(audits.contains(auditLoggerName));
 
         LoggerTO loggerTO = new LoggerTO();
-        String name = auditLoggerName.toLoggerName();
-        loggerTO.setKey(name);
+        loggerTO.setKey(auditLoggerName.toLoggerName());
         loggerTO.setLevel(LoggerLevel.DEBUG);
-        loggerService.update(LoggerType.AUDIT, name, loggerTO);
+        loggerService.update(LoggerType.AUDIT, loggerTO);
 
         audits = CollectionWrapper.wrapLogger(loggerService.list(LoggerType.AUDIT));
         assertNotNull(audits);


[21/31] syncope git commit: [SYNCOPE-652] Still several things to refine, but it starts taking shape

Posted by md...@apache.org.
[SYNCOPE-652] Still several things to refine, but it starts taking shape


Project: http://git-wip-us.apache.org/repos/asf/syncope/repo
Commit: http://git-wip-us.apache.org/repos/asf/syncope/commit/6dfedd8f
Tree: http://git-wip-us.apache.org/repos/asf/syncope/tree/6dfedd8f
Diff: http://git-wip-us.apache.org/repos/asf/syncope/diff/6dfedd8f

Branch: refs/heads/SYNCOPE-156
Commit: 6dfedd8f334c8d9b50aca076b0c53eab004081e7
Parents: b2e8401
Author: Francesco Chicchiriccò <il...@apache.org>
Authored: Sun Aug 2 07:44:52 2015 +0200
Committer: Francesco Chicchiriccò <il...@apache.org>
Committed: Thu Aug 13 17:16:51 2015 +0200

----------------------------------------------------------------------
 .travis.yml                                     |    9 +-
 .../console/pages/BulkActionModalPage.java      |   12 +-
 .../client/console/rest/GroupRestClient.java    |   14 +-
 .../client/console/rest/UserRestClient.java     |   14 +-
 .../client/console/pages/Configuration.java     |    2 -
 .../syncope/common/lib/to/BulkAction.java       |   10 +-
 .../syncope/common/lib/to/SchedTaskTO.java      |   10 +-
 .../common/lib/types/AbstractPolicySpec.java    |   19 +
 .../syncope/common/lib/types/AuditElements.java |    8 +
 .../syncope/common/lib/types/LoggerType.java    |    5 +-
 .../lib/types/ResourceAssociationAction.java    |   39 +
 .../types/ResourceAssociationActionType.java    |   39 -
 .../common/rest/api/CollectionWrapper.java      |    8 +-
 .../common/rest/api/service/AnyService.java     |    8 +-
 core/logic/pom.xml                              |   22 +
 .../syncope/core/logic/AnyObjectLogic.java      |   57 +-
 .../syncope/core/logic/ConfigurationLogic.java  |    3 +-
 .../apache/syncope/core/logic/GroupLogic.java   |   58 +-
 .../apache/syncope/core/logic/LoggerLogic.java  |   24 +-
 .../apache/syncope/core/logic/SyncopeLogic.java |    2 +-
 .../apache/syncope/core/logic/TaskLogic.java    |   76 +-
 .../apache/syncope/core/logic/UserLogic.java    |   67 +-
 .../logic/audit/AuditConnectionFactory.java     |  159 ---
 .../init/ImplementationClassNamesLoader.java    |   18 +-
 .../core/logic/init/JobInstanceLoaderImpl.java  |  181 ++-
 .../syncope/core/logic/init/LoggerLoader.java   |   64 +-
 .../core/logic/init/LogicInitializer.java       |    3 +
 .../logic/notification/NotificationJob.java     |  237 +---
 .../notification/NotificationJobDelegate.java   |  258 ++++
 .../syncope/core/logic/report/ReportJob.java    |  158 +--
 .../core/logic/report/ReportJobDelegate.java    |  181 +++
 .../apache/syncope/core/logic/AbstractTest.java |    4 +-
 .../apache/syncope/core/logic/MappingTest.java  |    2 +
 .../syncope/core/logic/NotificationTest.java    |    6 +-
 core/logic/src/test/resources/logicTest.xml     |    6 +-
 .../apache/syncope/core/misc/AuditManager.java  |   23 +-
 .../apache/syncope/core/misc/MappingUtils.java  |   26 +-
 .../core/misc/policy/AccountPolicyEnforcer.java |   15 +-
 .../misc/policy/PasswordPolicyEnforcer.java     |    4 +-
 .../core/misc/policy/PolicyEnforcer.java        |   10 +-
 .../core/misc/policy/PolicyEvaluator.java       |    5 +-
 .../core/misc/security/AuthContextUtils.java    |   27 +
 .../core/misc/security/PasswordGenerator.java   |   11 +-
 .../security/SyncopeAuthenticationProvider.java |   10 +-
 .../misc/security/SyncopeGrantedAuthority.java  |    7 +
 .../misc/spring/ApplicationContextProvider.java |   12 +-
 .../core/persistence/api/DomainsHolder.java     |   27 +
 .../api/content/ContentExporter.java            |    2 +-
 .../syncope/core/persistence/api/dao/DAO.java   |    2 -
 .../persistence/api/entity/task/SchedTask.java  |    4 +-
 core/persistence-jpa/pom.xml                    |    5 +
 .../jpa/content/AbstractContentDealer.java      |   57 +-
 .../jpa/content/XMLContentExporter.java         |   36 +-
 .../jpa/content/XMLContentLoader.java           |  113 +-
 .../persistence/jpa/dao/AbstractAnyDAO.java     |   17 +-
 .../core/persistence/jpa/dao/AbstractDAO.java   |   33 +-
 .../persistence/jpa/dao/JPAAnyObjectDAO.java    |    8 +-
 .../persistence/jpa/dao/JPAAnySearchDAO.java    |    6 +-
 .../persistence/jpa/dao/JPAAnyTypeClassDAO.java |    8 +-
 .../core/persistence/jpa/dao/JPAAnyTypeDAO.java |   10 +-
 .../core/persistence/jpa/dao/JPAConfDAO.java    |    8 +-
 .../persistence/jpa/dao/JPAConnInstanceDAO.java |    8 +-
 .../core/persistence/jpa/dao/JPADerAttrDAO.java |    8 +-
 .../persistence/jpa/dao/JPADerSchemaDAO.java    |   12 +-
 .../core/persistence/jpa/dao/JPADomainDAO.java  |    8 +-
 .../jpa/dao/JPAExternalResourceDAO.java         |   24 +-
 .../core/persistence/jpa/dao/JPAGroupDAO.java   |   16 +-
 .../core/persistence/jpa/dao/JPALoggerDAO.java  |    8 +-
 .../persistence/jpa/dao/JPANotificationDAO.java |    8 +-
 .../persistence/jpa/dao/JPAPlainAttrDAO.java    |    4 +-
 .../jpa/dao/JPAPlainAttrValueDAO.java           |    8 +-
 .../persistence/jpa/dao/JPAPlainSchemaDAO.java  |   12 +-
 .../core/persistence/jpa/dao/JPAPolicyDAO.java  |   12 +-
 .../core/persistence/jpa/dao/JPARealmDAO.java   |   14 +-
 .../jpa/dao/JPARelationshipTypeDAO.java         |   14 +-
 .../core/persistence/jpa/dao/JPAReportDAO.java  |   13 +-
 .../persistence/jpa/dao/JPAReportExecDAO.java   |   10 +-
 .../core/persistence/jpa/dao/JPARoleDAO.java    |   12 +-
 .../jpa/dao/JPASecurityQuestionDAO.java         |    8 +-
 .../core/persistence/jpa/dao/JPATaskDAO.java    |   15 +-
 .../persistence/jpa/dao/JPATaskExecDAO.java     |   10 +-
 .../core/persistence/jpa/dao/JPAUserDAO.java    |  181 ++-
 .../core/persistence/jpa/dao/JPAVirAttrDAO.java |    8 +-
 .../persistence/jpa/dao/JPAVirSchemaDAO.java    |   12 +-
 .../persistence/jpa/entity/group/JPAGroup.java  |    2 +-
 .../entity/task/AbstractProvisioningTask.java   |    6 +-
 .../jpa/entity/task/JPAPushTask.java            |    3 +-
 .../jpa/entity/task/JPASchedTask.java           |   11 +-
 .../jpa/entity/task/JPASyncTask.java            |    3 +-
 .../persistence/jpa/entity/user/JPAUser.java    |   10 +-
 .../spring/CommonEntityManagerFactoryConf.java  |  107 ++
 .../spring/DomainEntityManagerFactoryBean.java  |   45 +
 .../spring/DomainTransactionInterceptor.java    |   70 ++
 .../jpa/spring/SpringComponentReplacer.java     |   42 +
 .../entity/EntityValidationListener.java        |    2 +-
 .../entity/ProvisioningTaskValidator.java       |   14 +-
 .../validation/entity/SchedTaskValidator.java   |   44 +-
 .../jpa/validation/entity/UserCheck.java        |   41 -
 .../jpa/validation/entity/UserValidator.java    |  199 ---
 .../src/main/resources/audit/audit.sql          |    4 +-
 .../src/main/resources/content.xml              |  117 --
 .../src/main/resources/domains.xml              |   56 +
 .../main/resources/domains/Master.properties    |   28 +
 .../main/resources/domains/MasterContent.xml    |  124 ++
 .../src/main/resources/domains/MasterDomain.xml |  125 ++
 .../src/main/resources/persistence.properties   |   13 -
 .../src/main/resources/persistenceContext.xml   |   93 +-
 .../resources/persistenceContextEMFactory.xml   |   68 --
 .../src/main/resources/quartz/tables_h2.sql     |  266 ----
 .../main/resources/quartz/tables_mariadb.sql    |  206 ----
 .../src/main/resources/quartz/tables_mysql.sql  |  206 ----
 .../resources/quartz/tables_mysql_innodb.sql    |  221 ----
 .../src/main/resources/quartz/tables_oracle.sql |  208 ----
 .../main/resources/quartz/tables_postgres.sql   |  204 ----
 .../main/resources/quartz/tables_sqlServer.sql  |  296 -----
 .../core/persistence/jpa/AbstractTest.java      |   16 +
 .../persistence/jpa/inner/MultitenancyTest.java |  111 ++
 .../core/persistence/jpa/inner/UserTest.java    |    4 +-
 .../persistence/jpa/outer/AnyTypeClassTest.java |    4 -
 .../core/persistence/jpa/outer/GroupTest.java   |   11 +-
 .../persistence/jpa/outer/ResourceTest.java     |    5 +-
 .../core/persistence/jpa/outer/RoleTest.java    |    8 +-
 .../resources/META-INF/persistence-enhance.xml  |    2 +-
 .../src/test/resources/content.xml              | 1138 ------------------
 .../test/resources/domains/Master.properties    |   28 +
 .../test/resources/domains/MasterContent.xml    | 1131 +++++++++++++++++
 .../src/test/resources/domains/Two.properties   |   28 +
 .../src/test/resources/domains/TwoContent.xml   |  124 ++
 .../src/test/resources/domains/TwoDomain.xml    |  125 ++
 .../src/test/resources/persistence.properties   |   31 -
 .../src/test/resources/persistenceTest.xml      |    1 +
 .../api/AnyObjectProvisioningManager.java       |    5 +
 .../api/GroupProvisioningManager.java           |    3 +
 .../api/UserProvisioningManager.java            |   11 +-
 .../provisioning/api/job/JobInstanceLoader.java |   12 +-
 .../core/provisioning/api/job/JobNamer.java     |   10 +-
 .../provisioning/api/job/ProvisioningJob.java   |   28 -
 .../core/provisioning/api/job/PushJob.java      |   26 -
 .../api/job/SchedTaskJobDelegate.java           |   26 +
 .../core/provisioning/api/job/SyncJob.java      |   26 -
 .../core/provisioning/api/job/TaskJob.java      |   43 -
 .../api/propagation/PropagationManager.java     |    5 +-
 core/provisioning-java/pom.xml                  |    7 +
 .../provisioning/java/ConnectorFacadeProxy.java |    2 +-
 .../provisioning/java/ConnectorManager.java     |    2 +-
 .../DefaultAnyObjectProvisioningManager.java    |   46 +-
 .../java/DefaultGroupProvisioningManager.java   |   62 +-
 .../java/DefaultUserProvisioningManager.java    |  120 +-
 .../provisioning/java/UserSuspenderImpl.java    |    2 +-
 .../java/data/AbstractAnyDataBinder.java        |   18 +-
 .../java/data/AnyObjectDataBinderImpl.java      |    2 -
 .../java/data/ConfigurationDataBinderImpl.java  |    2 -
 .../java/data/TaskDataBinderImpl.java           |    8 +-
 .../java/job/AbstractSchedTaskJobDelegate.java  |  144 +++
 .../provisioning/java/job/AbstractTaskJob.java  |  216 ----
 .../java/job/AbstractTransactionalTaskJob.java  |   35 -
 .../core/provisioning/java/job/SampleJob.java   |   52 -
 .../java/job/SpringBeanJobFactory.java          |   12 +-
 .../core/provisioning/java/job/TaskJob.java     |  119 ++
 .../propagation/PropagationManagerImpl.java     |    6 +-
 .../java/sync/AbstractProvisioningJob.java      |  480 --------
 .../sync/AbstractProvisioningJobDelegate.java   |  434 +++++++
 .../java/sync/AbstractPushResultHandler.java    |    3 +-
 .../java/sync/AbstractSyncResultHandler.java    |    6 +-
 .../java/sync/AbstractSyncopeResultHandler.java |    2 +-
 .../provisioning/java/sync/PushJobDelegate.java |  192 +++
 .../provisioning/java/sync/PushJobImpl.java     |  189 ---
 .../provisioning/java/sync/SyncJobDelegate.java |  221 ++++
 .../provisioning/java/sync/SyncJobImpl.java     |  212 ----
 .../core/provisioning/java/sync/SyncUtils.java  |    2 +
 .../java/sync/UserSyncResultHandlerImpl.java    |    7 +-
 .../src/main/resources/provisioning.properties  |    3 +
 .../src/main/resources/provisioningContext.xml  |   27 +-
 .../src/main/resources/quartz/tables_h2.sql     |  266 ++++
 .../main/resources/quartz/tables_mariadb.sql    |  206 ++++
 .../src/main/resources/quartz/tables_mysql.sql  |  206 ++++
 .../resources/quartz/tables_mysql_innodb.sql    |  221 ++++
 .../src/main/resources/quartz/tables_oracle.sql |  208 ++++
 .../main/resources/quartz/tables_postgres.sql   |  204 ++++
 .../main/resources/quartz/tables_sqlServer.sql  |  296 +++++
 .../core/provisioning/java/AbstractTest.java    |    2 +
 .../provisioning/java/ConnectorManagerTest.java |    2 +-
 .../core/provisioning/java/TestInitializer.java |   37 +
 .../src/test/resources/provisioningTest.xml     |    7 +-
 .../rest/cxf/service/AbstractAnyService.java    |   14 +-
 .../rest/cxf/service/ConnectorServiceImpl.java  |    2 +-
 .../rest/cxf/service/ResourceServiceImpl.java   |    2 +-
 .../core/rest/cxf/service/TaskServiceImpl.java  |    2 +-
 .../activiti/ActivitiDefinitionLoader.java      |   67 +-
 .../workflow/activiti/ActivitiImportUtils.java  |   35 +-
 .../activiti/ActivitiUserWorkflowAdapter.java   |  134 +--
 .../activiti/spring/DomainProcessEngine.java    |  102 ++
 .../spring/DomainProcessEngineFactoryBean.java  |  104 ++
 .../task/AbstractActivitiServiceTask.java       |    7 +-
 .../workflow/activiti/task/AutoActivate.java    |    2 +-
 .../core/workflow/activiti/task/Create.java     |    8 +-
 .../core/workflow/activiti/task/Delete.java     |    5 +-
 .../workflow/activiti/task/GenerateToken.java   |    5 +-
 .../core/workflow/activiti/task/Notify.java     |    9 +-
 .../workflow/activiti/task/PasswordReset.java   |   11 +-
 .../core/workflow/activiti/task/Update.java     |   12 +-
 .../main/resources/workflowActivitiContext.xml  |   17 +-
 .../core/workflow/api/UserWorkflowAdapter.java  |    6 +-
 .../java/AbstractAnyObjectWorkflowAdapter.java  |    3 +-
 .../java/AbstractGroupWorkflowAdapter.java      |    3 +-
 .../java/AbstractUserWorkflowAdapter.java       |    3 +-
 .../java/DefaultUserWorkflowAdapter.java        |    2 -
 .../core/logic/init/CamelRouteLoader.java       |   28 +-
 .../persistence/jpa/dao/JPACamelRouteDAO.java   |   10 +-
 .../CamelAnyObjectProvisioningManager.java      |   19 +
 .../camel/CamelGroupProvisioningManager.java    |   23 +-
 .../camel/CamelUserProvisioningManager.java     |   59 +-
 .../processor/AnyObjectCreateProcessor.java     |    2 +-
 .../processor/AnyObjectDeleteProcessor.java     |    2 +-
 .../AnyObjectDeprovisionProcessor.java          |    2 +-
 .../processor/AnyObjectProvisionProcessor.java  |   77 ++
 .../processor/AnyObjectUpdateProcessor.java     |    2 +-
 .../camel/processor/GroupCreateProcessor.java   |    2 +-
 .../camel/processor/GroupDeleteProcessor.java   |    2 +-
 .../processor/GroupDeprovisionProcessor.java    |    4 +-
 .../processor/GroupProvisionProcessor.java      |   77 ++
 .../camel/processor/GroupUpdateProcessor.java   |    2 +-
 .../processor/UserConfirmPwdResetProcessor.java |    7 +-
 .../camel/processor/UserCreateProcessor.java    |    2 +-
 .../camel/processor/UserDeleteProcessor.java    |    2 +-
 .../processor/UserDeprovisionProcessor.java     |    2 +-
 .../camel/processor/UserProvisionProcessor.java |   98 ++
 .../processor/UserSetStatusInSyncProcessor.java |    2 +-
 .../UserStatusPropagationProcessor.java         |   13 +-
 .../processor/UserUpdateInSyncProcessor.java    |    2 +-
 .../camel/processor/UserUpdateProcessor.java    |    2 +-
 .../src/main/resources/anyObjectRoutes.xml      |    6 +
 .../src/main/resources/groupRoutes.xml          |    6 +
 .../src/main/resources/userRoutes.xml           |    8 +-
 fit/core-reference/pom.xml                      |   12 +-
 .../fit/core/reference/TestSampleJob.java       |   64 -
 .../core/reference/TestSampleJobDelegate.java   |   64 +
 .../main/resources/all/provisioning.properties  |    6 +-
 .../src/main/resources/coreContext.xml          |    2 +
 .../src/main/resources/log4j2.xml               |   35 +-
 .../src/main/resources/provisioning.properties  |    4 +
 .../src/main/webapp/cacheStats.jsp              |    5 +-
 .../fit/core/reference/AnyTypeITCase.java       |    1 -
 .../core/reference/AuthenticationITCase.java    |   10 +-
 .../fit/core/reference/CamelRouteITCase.java    |    5 +-
 .../fit/core/reference/ConnectorITCase.java     |    2 +-
 .../core/reference/ExceptionMapperITCase.java   |    3 +-
 .../syncope/fit/core/reference/GroupITCase.java |   24 +-
 .../fit/core/reference/LoggerITCase.java        |    4 +-
 .../core/reference/PropagationTaskITCase.java   |    2 +-
 .../fit/core/reference/PushTaskITCase.java      |    5 +-
 .../fit/core/reference/ResourceITCase.java      |    2 +-
 .../fit/core/reference/SchedTaskITCase.java     |    5 +-
 .../fit/core/reference/SyncTaskITCase.java      |   26 +-
 .../syncope/fit/core/reference/UserITCase.java  |   54 +-
 255 files changed, 7694 insertions(+), 6435 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/syncope/blob/6dfedd8f/.travis.yml
----------------------------------------------------------------------
diff --git a/.travis.yml b/.travis.yml
index e17fd2c..4ec5ae7 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -13,13 +13,18 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
+cache:
+  directories:
+  - $HOME/.m2
 language: java
 jdk:
   - openjdk7
 # default install is mvn install --quiet -DskipTests=true
 install: mvn --show-version --quiet -P all,skipTests
 #invoker.streamLogs: we cannot access to log files through Travis web ui, so display everything in the console
-#script: mvn --show-version --quiet clean install -Dinvoker.streamLogs=true
-script: mvn --show-version --quiet -PskipTests -Dinvoker.streamLogs=true
+script:
+  - sudo rm /etc/mavenrc
+  - export MAVEN_OPTS="-Xmx2469m -XX:MaxPermSize=512m"
+  - mvn --show-version --quiet clean install -Dinvoker.streamLogs=true
 notifications:
   webhooks: http://rovere.tirasa.net/cgi-bin/travis.cgi

http://git-wip-us.apache.org/repos/asf/syncope/blob/6dfedd8f/client/console/src/main/java/org/apache/syncope/client/console/pages/BulkActionModalPage.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/pages/BulkActionModalPage.java b/client/console/src/main/java/org/apache/syncope/client/console/pages/BulkActionModalPage.java
index 6172639..5c1d31f 100644
--- a/client/console/src/main/java/org/apache/syncope/client/console/pages/BulkActionModalPage.java
+++ b/client/console/src/main/java/org/apache/syncope/client/console/pages/BulkActionModalPage.java
@@ -101,19 +101,19 @@ public class BulkActionModalPage<T, S> extends BaseModalPage {
 
             switch (action) {
                 case DELETE:
-                    bulkAction.setOperation(BulkAction.Type.DELETE);
+                    bulkAction.setType(BulkAction.Type.DELETE);
                     break;
                 case SUSPEND:
-                    bulkAction.setOperation(BulkAction.Type.SUSPEND);
+                    bulkAction.setType(BulkAction.Type.SUSPEND);
                     break;
                 case REACTIVATE:
-                    bulkAction.setOperation(BulkAction.Type.REACTIVATE);
+                    bulkAction.setType(BulkAction.Type.REACTIVATE);
                     break;
                 case EXECUTE:
-                    bulkAction.setOperation(BulkAction.Type.EXECUTE);
+                    bulkAction.setType(BulkAction.Type.EXECUTE);
                     break;
                 case DRYRUN:
-                    bulkAction.setOperation(BulkAction.Type.DRYRUN);
+                    bulkAction.setType(BulkAction.Type.DRYRUN);
                     break;
                 default:
                     LOG.error("Bulk action type not supported");
@@ -133,7 +133,7 @@ public class BulkActionModalPage<T, S> extends BaseModalPage {
                     } catch (NoSuchMethodException | SecurityException | IllegalAccessException 
                             | IllegalArgumentException | InvocationTargetException e) {
                         error(getString(Constants.ERROR)
-                                + ": Operation " + bulkAction.getOperation() + " not supported");
+                                + ": Operation " + bulkAction.getType() + " not supported");
                         feedbackPanel.refresh(target);
                     }
 

http://git-wip-us.apache.org/repos/asf/syncope/blob/6dfedd8f/client/console/src/main/java/org/apache/syncope/client/console/rest/GroupRestClient.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/rest/GroupRestClient.java b/client/console/src/main/java/org/apache/syncope/client/console/rest/GroupRestClient.java
index 512e08f..4644fc0 100644
--- a/client/console/src/main/java/org/apache/syncope/client/console/rest/GroupRestClient.java
+++ b/client/console/src/main/java/org/apache/syncope/client/console/rest/GroupRestClient.java
@@ -31,7 +31,7 @@ import org.apache.syncope.common.lib.to.BulkActionResult;
 import org.apache.syncope.common.lib.to.ConnObjectTO;
 import org.apache.syncope.common.lib.to.GroupTO;
 import org.apache.syncope.common.lib.types.AnyTypeKind;
-import org.apache.syncope.common.lib.types.ResourceAssociationActionType;
+import org.apache.syncope.common.lib.types.ResourceAssociationAction;
 import org.apache.syncope.common.lib.types.ResourceDeassociationActionType;
 import org.apache.syncope.common.lib.wrap.ResourceKey;
 import org.apache.syncope.common.rest.api.CollectionWrapper;
@@ -123,7 +123,7 @@ public class GroupRestClient extends AbstractAnyRestClient {
     public void unlink(final String etag, final long groupKey, final List<StatusBean> statuses) {
         synchronized (this) {
             GroupService service = getService(etag, GroupService.class);
-            service.bulkDeassociation(groupKey, ResourceDeassociationActionType.UNLINK,
+            service.deassociate(groupKey, ResourceDeassociationActionType.UNLINK,
                     CollectionWrapper.wrap(StatusUtils.buildStatusMod(statuses).getResourceNames(),
                             ResourceKey.class));
             resetClient(GroupService.class);
@@ -137,7 +137,7 @@ public class GroupRestClient extends AbstractAnyRestClient {
             ResourceAssociationMod associationMod = new ResourceAssociationMod();
             associationMod.getTargetResources().addAll(
                     CollectionWrapper.wrap(StatusUtils.buildStatusMod(statuses).getResourceNames(), ResourceKey.class));
-            service.bulkAssociation(groupKey, ResourceAssociationActionType.LINK, associationMod);
+            service.associate(groupKey, ResourceAssociationAction.LINK, associationMod);
 
             resetClient(GroupService.class);
         }
@@ -147,7 +147,7 @@ public class GroupRestClient extends AbstractAnyRestClient {
         BulkActionResult result;
         synchronized (this) {
             GroupService service = getService(etag, GroupService.class);
-            result = service.bulkDeassociation(groupKey, ResourceDeassociationActionType.DEPROVISION,
+            result = service.deassociate(groupKey, ResourceDeassociationActionType.DEPROVISION,
                     CollectionWrapper.wrap(StatusUtils.buildStatusMod(statuses).getResourceNames(),
                             ResourceKey.class)).
                     readEntity(BulkActionResult.class);
@@ -165,7 +165,7 @@ public class GroupRestClient extends AbstractAnyRestClient {
             associationMod.getTargetResources().addAll(
                     CollectionWrapper.wrap(StatusUtils.buildStatusMod(statuses).getResourceNames(), ResourceKey.class));
 
-            result = service.bulkAssociation(groupKey, ResourceAssociationActionType.PROVISION, associationMod).
+            result = service.associate(groupKey, ResourceAssociationAction.PROVISION, associationMod).
                     readEntity(BulkActionResult.class);
             resetClient(GroupService.class);
         }
@@ -176,7 +176,7 @@ public class GroupRestClient extends AbstractAnyRestClient {
         BulkActionResult result;
         synchronized (this) {
             GroupService service = getService(etag, GroupService.class);
-            result = service.bulkDeassociation(groupKey, ResourceDeassociationActionType.UNASSIGN,
+            result = service.deassociate(groupKey, ResourceDeassociationActionType.UNASSIGN,
                     CollectionWrapper.wrap(StatusUtils.buildStatusMod(statuses).getResourceNames(),
                             ResourceKey.class)).
                     readEntity(BulkActionResult.class);
@@ -194,7 +194,7 @@ public class GroupRestClient extends AbstractAnyRestClient {
             associationMod.getTargetResources().addAll(
                     CollectionWrapper.wrap(StatusUtils.buildStatusMod(statuses).getResourceNames(), ResourceKey.class));
 
-            result = service.bulkAssociation(groupKey, ResourceAssociationActionType.ASSIGN, associationMod).
+            result = service.associate(groupKey, ResourceAssociationAction.ASSIGN, associationMod).
                     readEntity(BulkActionResult.class);
 
             resetClient(GroupService.class);

http://git-wip-us.apache.org/repos/asf/syncope/blob/6dfedd8f/client/console/src/main/java/org/apache/syncope/client/console/rest/UserRestClient.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/rest/UserRestClient.java b/client/console/src/main/java/org/apache/syncope/client/console/rest/UserRestClient.java
index 338851d..5c5c062 100644
--- a/client/console/src/main/java/org/apache/syncope/client/console/rest/UserRestClient.java
+++ b/client/console/src/main/java/org/apache/syncope/client/console/rest/UserRestClient.java
@@ -32,7 +32,7 @@ import org.apache.syncope.common.lib.to.BulkActionResult;
 import org.apache.syncope.common.lib.to.ConnObjectTO;
 import org.apache.syncope.common.lib.to.UserTO;
 import org.apache.syncope.common.lib.types.AnyTypeKind;
-import org.apache.syncope.common.lib.types.ResourceAssociationActionType;
+import org.apache.syncope.common.lib.types.ResourceAssociationAction;
 import org.apache.syncope.common.lib.types.ResourceDeassociationActionType;
 import org.apache.syncope.common.lib.wrap.ResourceKey;
 import org.apache.syncope.common.rest.api.CollectionWrapper;
@@ -150,7 +150,7 @@ public class UserRestClient extends AbstractAnyRestClient {
     public void unlink(final String etag, final long userKey, final List<StatusBean> statuses) {
         synchronized (this) {
             UserService service = getService(etag, UserService.class);
-            service.bulkDeassociation(userKey, ResourceDeassociationActionType.UNLINK,
+            service.deassociate(userKey, ResourceDeassociationActionType.UNLINK,
                     CollectionWrapper.wrap(StatusUtils.buildStatusMod(statuses).getResourceNames(),
                             ResourceKey.class));
             resetClient(UserService.class);
@@ -164,7 +164,7 @@ public class UserRestClient extends AbstractAnyRestClient {
             ResourceAssociationMod associationMod = new ResourceAssociationMod();
             associationMod.getTargetResources().addAll(
                     CollectionWrapper.wrap(StatusUtils.buildStatusMod(statuses).getResourceNames(), ResourceKey.class));
-            service.bulkAssociation(userKey, ResourceAssociationActionType.LINK, associationMod);
+            service.associate(userKey, ResourceAssociationAction.LINK, associationMod);
 
             resetClient(UserService.class);
         }
@@ -174,7 +174,7 @@ public class UserRestClient extends AbstractAnyRestClient {
         BulkActionResult result;
         synchronized (this) {
             UserService service = getService(etag, UserService.class);
-            result = service.bulkDeassociation(userKey, ResourceDeassociationActionType.DEPROVISION,
+            result = service.deassociate(userKey, ResourceDeassociationActionType.DEPROVISION,
                     CollectionWrapper.wrap(StatusUtils.buildStatusMod(statuses).getResourceNames(),
                             ResourceKey.class)).
                     readEntity(BulkActionResult.class);
@@ -196,7 +196,7 @@ public class UserRestClient extends AbstractAnyRestClient {
             associationMod.setChangePwd(changepwd);
             associationMod.setPassword(password);
 
-            result = service.bulkAssociation(userKey, ResourceAssociationActionType.PROVISION, associationMod).
+            result = service.associate(userKey, ResourceAssociationAction.PROVISION, associationMod).
                     readEntity(BulkActionResult.class);
             resetClient(UserService.class);
         }
@@ -207,7 +207,7 @@ public class UserRestClient extends AbstractAnyRestClient {
         BulkActionResult result;
         synchronized (this) {
             UserService service = getService(etag, UserService.class);
-            result = service.bulkDeassociation(userKey, ResourceDeassociationActionType.UNASSIGN,
+            result = service.deassociate(userKey, ResourceDeassociationActionType.UNASSIGN,
                     CollectionWrapper.wrap(StatusUtils.buildStatusMod(statuses).getResourceNames(),
                             ResourceKey.class)).
                     readEntity(BulkActionResult.class);
@@ -229,7 +229,7 @@ public class UserRestClient extends AbstractAnyRestClient {
             associationMod.setChangePwd(changepwd);
             associationMod.setPassword(password);
 
-            result = service.bulkAssociation(userKey, ResourceAssociationActionType.ASSIGN, associationMod).
+            result = service.associate(userKey, ResourceAssociationAction.ASSIGN, associationMod).
                     readEntity(BulkActionResult.class);
             resetClient(UserService.class);
         }

http://git-wip-us.apache.org/repos/asf/syncope/blob/6dfedd8f/client/old_console/src/main/java/org/apache/syncope/client/console/pages/Configuration.java
----------------------------------------------------------------------
diff --git a/client/old_console/src/main/java/org/apache/syncope/client/console/pages/Configuration.java b/client/old_console/src/main/java/org/apache/syncope/client/console/pages/Configuration.java
index 9f8c734..bb6fcdf 100644
--- a/client/old_console/src/main/java/org/apache/syncope/client/console/pages/Configuration.java
+++ b/client/old_console/src/main/java/org/apache/syncope/client/console/pages/Configuration.java
@@ -18,8 +18,6 @@
  */
 package org.apache.syncope.client.console.pages;
 
-import static org.apache.syncope.client.console.pages.AbstractBasePage.LOG;
-
 import java.io.File;
 import java.io.Serializable;
 import java.util.ArrayList;

http://git-wip-us.apache.org/repos/asf/syncope/blob/6dfedd8f/common/lib/src/main/java/org/apache/syncope/common/lib/to/BulkAction.java
----------------------------------------------------------------------
diff --git a/common/lib/src/main/java/org/apache/syncope/common/lib/to/BulkAction.java b/common/lib/src/main/java/org/apache/syncope/common/lib/to/BulkAction.java
index a514dcb..5b46616 100644
--- a/common/lib/src/main/java/org/apache/syncope/common/lib/to/BulkAction.java
+++ b/common/lib/src/main/java/org/apache/syncope/common/lib/to/BulkAction.java
@@ -46,19 +46,19 @@ public class BulkAction extends AbstractBaseBean {
 
     }
 
-    private Type operation;
+    private Type type;
 
     /**
      * Serialized identifiers.
      */
     private final List<String> targets = new ArrayList<>();
 
-    public Type getOperation() {
-        return operation;
+    public Type getType() {
+        return type;
     }
 
-    public void setOperation(final Type operation) {
-        this.operation = operation;
+    public void setType(final Type type) {
+        this.type = type;
     }
 
     @XmlElementWrapper(name = "targets")

http://git-wip-us.apache.org/repos/asf/syncope/blob/6dfedd8f/common/lib/src/main/java/org/apache/syncope/common/lib/to/SchedTaskTO.java
----------------------------------------------------------------------
diff --git a/common/lib/src/main/java/org/apache/syncope/common/lib/to/SchedTaskTO.java b/common/lib/src/main/java/org/apache/syncope/common/lib/to/SchedTaskTO.java
index abea52d..08e4c53 100644
--- a/common/lib/src/main/java/org/apache/syncope/common/lib/to/SchedTaskTO.java
+++ b/common/lib/src/main/java/org/apache/syncope/common/lib/to/SchedTaskTO.java
@@ -33,7 +33,7 @@ public class SchedTaskTO extends AbstractTaskTO {
 
     private String cronExpression;
 
-    private String jobClassName;
+    private String jobDelegateClassName;
 
     private String name;
 
@@ -51,12 +51,12 @@ public class SchedTaskTO extends AbstractTaskTO {
         this.cronExpression = cronExpression;
     }
 
-    public String getJobClassName() {
-        return jobClassName;
+    public String getJobDelegateClassName() {
+        return jobDelegateClassName;
     }
 
-    public void setJobClassName(final String jobClassName) {
-        this.jobClassName = jobClassName;
+    public void setJobDelegateClassName(final String jobDelegateClassName) {
+        this.jobDelegateClassName = jobDelegateClassName;
     }
 
     @SuppressWarnings("CPD-START")

http://git-wip-us.apache.org/repos/asf/syncope/blob/6dfedd8f/common/lib/src/main/java/org/apache/syncope/common/lib/types/AbstractPolicySpec.java
----------------------------------------------------------------------
diff --git a/common/lib/src/main/java/org/apache/syncope/common/lib/types/AbstractPolicySpec.java b/common/lib/src/main/java/org/apache/syncope/common/lib/types/AbstractPolicySpec.java
index 5f2fd1e..e1e7333 100644
--- a/common/lib/src/main/java/org/apache/syncope/common/lib/types/AbstractPolicySpec.java
+++ b/common/lib/src/main/java/org/apache/syncope/common/lib/types/AbstractPolicySpec.java
@@ -24,6 +24,10 @@ import java.util.List;
 import javax.xml.bind.annotation.XmlElement;
 import javax.xml.bind.annotation.XmlElementWrapper;
 import javax.xml.bind.annotation.XmlType;
+import org.apache.commons.lang3.builder.EqualsBuilder;
+import org.apache.commons.lang3.builder.HashCodeBuilder;
+import org.apache.commons.lang3.builder.ReflectionToStringBuilder;
+import org.apache.commons.lang3.builder.ToStringStyle;
 import org.apache.syncope.common.lib.annotation.SchemaList;
 
 @XmlType
@@ -80,4 +84,19 @@ public abstract class AbstractPolicySpec implements PolicySpec {
         return suffixesNotPermitted;
     }
 
+    @Override
+    public boolean equals(final Object obj) {
+        return EqualsBuilder.reflectionEquals(this, obj);
+    }
+
+    @Override
+    public int hashCode() {
+        return HashCodeBuilder.reflectionHashCode(this);
+    }
+
+    @Override
+    public String toString() {
+        return ReflectionToStringBuilder.toString(this, ToStringStyle.MULTI_LINE_STYLE);
+    }
+
 }

http://git-wip-us.apache.org/repos/asf/syncope/blob/6dfedd8f/common/lib/src/main/java/org/apache/syncope/common/lib/types/AuditElements.java
----------------------------------------------------------------------
diff --git a/common/lib/src/main/java/org/apache/syncope/common/lib/types/AuditElements.java b/common/lib/src/main/java/org/apache/syncope/common/lib/types/AuditElements.java
index 323ea09..c3d4af5 100644
--- a/common/lib/src/main/java/org/apache/syncope/common/lib/types/AuditElements.java
+++ b/common/lib/src/main/java/org/apache/syncope/common/lib/types/AuditElements.java
@@ -26,6 +26,10 @@ public final class AuditElements implements Serializable {
 
     private static final long serialVersionUID = -4385059255522273254L;
 
+    public static final String AUTHENTICATION_CATEGORY = "Authentication";
+
+    public static final String LOGIN_EVENT = "login";
+
     @XmlEnum
     public enum EventCategoryType {
 
@@ -55,4 +59,8 @@ public final class AuditElements implements Serializable {
         FAILURE
 
     }
+
+    private AuditElements() {
+        // private constructor for static utility class
+    }
 }

http://git-wip-us.apache.org/repos/asf/syncope/blob/6dfedd8f/common/lib/src/main/java/org/apache/syncope/common/lib/types/LoggerType.java
----------------------------------------------------------------------
diff --git a/common/lib/src/main/java/org/apache/syncope/common/lib/types/LoggerType.java b/common/lib/src/main/java/org/apache/syncope/common/lib/types/LoggerType.java
index f77ed81..f129a7d 100644
--- a/common/lib/src/main/java/org/apache/syncope/common/lib/types/LoggerType.java
+++ b/common/lib/src/main/java/org/apache/syncope/common/lib/types/LoggerType.java
@@ -19,6 +19,7 @@
 package org.apache.syncope.common.lib.types;
 
 import javax.xml.bind.annotation.XmlEnum;
+import org.apache.commons.lang3.StringUtils;
 
 @XmlEnum
 public enum LoggerType {
@@ -26,7 +27,7 @@ public enum LoggerType {
     /**
      * This type describes a common logger used to handle system and application events.
      */
-    LOG(""),
+    LOG(StringUtils.EMPTY),
     /**
      * Audit logger only focus on security related events, usually logging how did what and when.
      * In case of a security incident audit loggers should allow an administrator to recall all
@@ -34,7 +35,7 @@ public enum LoggerType {
      */
     AUDIT("syncope.audit");
 
-    private String prefix;
+    private final String prefix;
 
     LoggerType(final String prefix) {
         this.prefix = prefix;

http://git-wip-us.apache.org/repos/asf/syncope/blob/6dfedd8f/common/lib/src/main/java/org/apache/syncope/common/lib/types/ResourceAssociationAction.java
----------------------------------------------------------------------
diff --git a/common/lib/src/main/java/org/apache/syncope/common/lib/types/ResourceAssociationAction.java b/common/lib/src/main/java/org/apache/syncope/common/lib/types/ResourceAssociationAction.java
new file mode 100644
index 0000000..efbe0ef
--- /dev/null
+++ b/common/lib/src/main/java/org/apache/syncope/common/lib/types/ResourceAssociationAction.java
@@ -0,0 +1,39 @@
+/*
+ * 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.common.lib.types;
+
+import javax.xml.bind.annotation.XmlEnum;
+
+@XmlEnum
+public enum ResourceAssociationAction {
+
+    /**
+     * Link user/group/any object on Syncope and external resource(s) without any propagation.
+     */
+    LINK,
+    /**
+     * Send user/group/any object data to external resource(s).
+     */
+    PROVISION,
+    /**
+     * Assign (link + provision) external resource(s) to user/group/any object.
+     */
+    ASSIGN
+
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/6dfedd8f/common/lib/src/main/java/org/apache/syncope/common/lib/types/ResourceAssociationActionType.java
----------------------------------------------------------------------
diff --git a/common/lib/src/main/java/org/apache/syncope/common/lib/types/ResourceAssociationActionType.java b/common/lib/src/main/java/org/apache/syncope/common/lib/types/ResourceAssociationActionType.java
deleted file mode 100644
index 3d7955d..0000000
--- a/common/lib/src/main/java/org/apache/syncope/common/lib/types/ResourceAssociationActionType.java
+++ /dev/null
@@ -1,39 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.syncope.common.lib.types;
-
-import javax.xml.bind.annotation.XmlEnum;
-
-@XmlEnum
-public enum ResourceAssociationActionType {
-
-    /**
-     * Add association between user/group on Syncope and external resource(s) without any propagation.
-     */
-    LINK,
-    /**
-     * Add user/group into external resource(s).
-     */
-    PROVISION,
-    /**
-     * Assign (link + provision) external resource(s) with user/group.
-     */
-    ASSIGN
-
-}

http://git-wip-us.apache.org/repos/asf/syncope/blob/6dfedd8f/common/rest-api/src/main/java/org/apache/syncope/common/rest/api/CollectionWrapper.java
----------------------------------------------------------------------
diff --git a/common/rest-api/src/main/java/org/apache/syncope/common/rest/api/CollectionWrapper.java b/common/rest-api/src/main/java/org/apache/syncope/common/rest/api/CollectionWrapper.java
index 94bf21f..3cdf1fa 100644
--- a/common/rest-api/src/main/java/org/apache/syncope/common/rest/api/CollectionWrapper.java
+++ b/common/rest-api/src/main/java/org/apache/syncope/common/rest/api/CollectionWrapper.java
@@ -57,9 +57,9 @@ public final class CollectionWrapper {
 
     public static List<AuditLoggerName> wrapLogger(final Collection<LoggerTO> logger) {
         List<AuditLoggerName> respons = new ArrayList<>();
-        for (LoggerTO l : logger) {
+        for (LoggerTO loggerTO : logger) {
             try {
-                respons.add(AuditLoggerName.fromLoggerName(l.getKey()));
+                respons.add(AuditLoggerName.fromLoggerName(loggerTO.getKey()));
             } catch (Exception ignore) {
                 // ignore
             }
@@ -69,9 +69,9 @@ public final class CollectionWrapper {
 
     public static List<LoggerTO> unwrapLogger(final Collection<AuditLoggerName> auditNames) {
         List<LoggerTO> respons = new ArrayList<>();
-        for (AuditLoggerName l : auditNames) {
+        for (AuditLoggerName name : auditNames) {
             LoggerTO loggerTO = new LoggerTO();
-            loggerTO.setKey(l.toLoggerName());
+            loggerTO.setKey(name.toLoggerName());
             loggerTO.setLevel(LoggerLevel.DEBUG);
             respons.add(loggerTO);
         }

http://git-wip-us.apache.org/repos/asf/syncope/blob/6dfedd8f/common/rest-api/src/main/java/org/apache/syncope/common/rest/api/service/AnyService.java
----------------------------------------------------------------------
diff --git a/common/rest-api/src/main/java/org/apache/syncope/common/rest/api/service/AnyService.java b/common/rest-api/src/main/java/org/apache/syncope/common/rest/api/service/AnyService.java
index 93167cb..1c0fda2 100644
--- a/common/rest-api/src/main/java/org/apache/syncope/common/rest/api/service/AnyService.java
+++ b/common/rest-api/src/main/java/org/apache/syncope/common/rest/api/service/AnyService.java
@@ -39,7 +39,7 @@ import org.apache.syncope.common.lib.to.AnyTO;
 import org.apache.syncope.common.lib.to.BulkAction;
 import org.apache.syncope.common.lib.to.BulkActionResult;
 import org.apache.syncope.common.lib.to.PagedResult;
-import org.apache.syncope.common.lib.types.ResourceAssociationActionType;
+import org.apache.syncope.common.lib.types.ResourceAssociationAction;
 import org.apache.syncope.common.lib.types.ResourceDeassociationActionType;
 import org.apache.syncope.common.lib.wrap.ResourceKey;
 import org.apache.syncope.common.rest.api.beans.AnyListQuery;
@@ -150,7 +150,7 @@ public interface AnyService<TO extends AnyTO, MOD extends AnyMod> extends JAXRSS
     @Path("{key}/deassociate/{type}")
     @Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
     @Consumes({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
-    Response bulkDeassociation(
+    Response deassociate(
             @NotNull @PathParam("key") Long key,
             @NotNull @PathParam("type") ResourceDeassociationActionType type,
             @NotNull List<ResourceKey> resourceNames);
@@ -171,9 +171,9 @@ public interface AnyService<TO extends AnyTO, MOD extends AnyMod> extends JAXRSS
     @Path("{key}/associate/{type}")
     @Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
     @Consumes({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
-    Response bulkAssociation(
+    Response associate(
             @NotNull @PathParam("key") Long key,
-            @NotNull @PathParam("type") ResourceAssociationActionType type,
+            @NotNull @PathParam("type") ResourceAssociationAction type,
             @NotNull ResourceAssociationMod associationMod);
 
     /**

http://git-wip-us.apache.org/repos/asf/syncope/blob/6dfedd8f/core/logic/pom.xml
----------------------------------------------------------------------
diff --git a/core/logic/pom.xml b/core/logic/pom.xml
index 60ba05f..7ce109f 100644
--- a/core/logic/pom.xml
+++ b/core/logic/pom.xml
@@ -153,6 +153,13 @@ under the License.
         <filtering>true</filtering>
       </testResource>
       <testResource>
+        <directory>${basedir}/../persistence-jpa/src/main/resources</directory>
+        <includes>
+          <include>persistence.properties</include>
+        </includes>
+        <filtering>true</filtering>
+      </testResource>
+      <testResource>
         <directory>${basedir}/../persistence-jpa/src/test/resources</directory>
         <filtering>true</filtering>
       </testResource>
@@ -161,6 +168,21 @@ under the License.
     <plugins>
       <plugin>
         <groupId>org.apache.maven.plugins</groupId>
+        <artifactId>maven-dependency-plugin</artifactId>
+        <inherited>true</inherited>
+        <executions>
+          <execution>
+            <id>set-bundles</id>
+            <phase>process-test-resources</phase>
+            <goals>
+              <goal>copy</goal>
+            </goals>
+          </execution>
+        </executions>
+      </plugin>
+      
+      <plugin>
+        <groupId>org.apache.maven.plugins</groupId>
         <artifactId>maven-checkstyle-plugin</artifactId>
       </plugin>
     </plugins>

http://git-wip-us.apache.org/repos/asf/syncope/blob/6dfedd8f/core/logic/src/main/java/org/apache/syncope/core/logic/AnyObjectLogic.java
----------------------------------------------------------------------
diff --git a/core/logic/src/main/java/org/apache/syncope/core/logic/AnyObjectLogic.java b/core/logic/src/main/java/org/apache/syncope/core/logic/AnyObjectLogic.java
index 05db8b5..38927ce 100644
--- a/core/logic/src/main/java/org/apache/syncope/core/logic/AnyObjectLogic.java
+++ b/core/logic/src/main/java/org/apache/syncope/core/logic/AnyObjectLogic.java
@@ -55,7 +55,6 @@ import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.security.access.prepost.PreAuthorize;
 import org.springframework.stereotype.Component;
 import org.springframework.transaction.annotation.Transactional;
-import org.springframework.transaction.interceptor.TransactionInterceptor;
 
 /**
  * Note that this controller does not extend {@link AbstractTransactionalLogic}, hence does not provide any
@@ -96,7 +95,7 @@ public class AnyObjectLogic extends AbstractAnyLogic<AnyObjectTO, AnyObjectMod>
     }
 
     @PreAuthorize("isAuthenticated()")
-    @Transactional(readOnly = true, rollbackFor = { Throwable.class })
+    @Transactional(readOnly = true)
     @Override
     public int count(final List<String> realms) {
         return anyObjectDAO.count(getEffectiveRealms(SyncopeConstants.FULL_ADMIN_REALMS, realms));
@@ -133,7 +132,7 @@ public class AnyObjectLogic extends AbstractAnyLogic<AnyObjectTO, AnyObjectMod>
     }
 
     @PreAuthorize("hasRole('" + Entitlement.ANY_OBJECT_SEARCH + "')")
-    @Transactional(readOnly = true, rollbackFor = { Throwable.class })
+    @Transactional(readOnly = true)
     @Override
     public int searchCount(final SearchCond searchCondition, final List<String> realms) {
         return searchDAO.count(
@@ -142,7 +141,7 @@ public class AnyObjectLogic extends AbstractAnyLogic<AnyObjectTO, AnyObjectMod>
     }
 
     @PreAuthorize("hasRole('" + Entitlement.ANY_OBJECT_SEARCH + "')")
-    @Transactional(readOnly = true, rollbackFor = { Throwable.class })
+    @Transactional(readOnly = true)
     @Override
     public List<AnyObjectTO> search(final SearchCond searchCondition, final int page, final int size,
             final List<OrderByClause> orderBy, final List<String> realms, final boolean details) {
@@ -239,29 +238,26 @@ public class AnyObjectLogic extends AbstractAnyLogic<AnyObjectTO, AnyObjectMod>
     }
 
     @PreAuthorize("hasRole('" + Entitlement.ANY_OBJECT_UPDATE + "')")
-    @Transactional(rollbackFor = { Throwable.class })
     @Override
     public AnyObjectTO unlink(final Long anyObjectKey, final Collection<String> resources) {
         AnyObjectMod anyObjectMod = new AnyObjectMod();
         anyObjectMod.setKey(anyObjectKey);
         anyObjectMod.getResourcesToRemove().addAll(resources);
-        final Long updatedResult = provisioningManager.unlink(anyObjectMod);
 
-        return binder.getAnyObjectTO(updatedResult);
+        return binder.getAnyObjectTO(provisioningManager.unlink(anyObjectMod));
     }
 
     @PreAuthorize("hasRole('" + Entitlement.ANY_OBJECT_UPDATE + "')")
-    @Transactional(rollbackFor = { Throwable.class })
     @Override
     public AnyObjectTO link(final Long anyObjectKey, final Collection<String> resources) {
         AnyObjectMod anyObjectMod = new AnyObjectMod();
         anyObjectMod.setKey(anyObjectKey);
         anyObjectMod.getResourcesToAdd().addAll(resources);
+
         return binder.getAnyObjectTO(provisioningManager.link(anyObjectMod));
     }
 
     @PreAuthorize("hasRole('" + Entitlement.ANY_OBJECT_UPDATE + "')")
-    @Transactional(rollbackFor = { Throwable.class })
     @Override
     public AnyObjectTO unassign(final Long anyObjectKey, final Collection<String> resources) {
         AnyObjectMod anyObjectMod = new AnyObjectMod();
@@ -271,44 +267,41 @@ public class AnyObjectLogic extends AbstractAnyLogic<AnyObjectTO, AnyObjectMod>
     }
 
     @PreAuthorize("hasRole('" + Entitlement.ANY_OBJECT_UPDATE + "')")
-    @Transactional(rollbackFor = { Throwable.class })
     @Override
-    public AnyObjectTO assign(final Long anyObjectKey, final Collection<String> resources,
-            final boolean changePwd, final String password) {
+    public AnyObjectTO assign(
+            final Long key,
+            final Collection<String> resources,
+            final boolean changepwd,
+            final String password) {
 
-        AnyObjectMod userMod = new AnyObjectMod();
-        userMod.setKey(anyObjectKey);
-        userMod.getResourcesToAdd().addAll(resources);
-        return update(userMod);
+        AnyObjectMod anyObjectMod = new AnyObjectMod();
+        anyObjectMod.setKey(key);
+        anyObjectMod.getResourcesToAdd().addAll(resources);
+
+        return update(anyObjectMod);
     }
 
     @PreAuthorize("hasRole('" + Entitlement.ANY_OBJECT_UPDATE + "')")
-    @Transactional(rollbackFor = { Throwable.class })
     @Override
-    public AnyObjectTO deprovision(final Long anyObjectKey, final Collection<String> resources) {
-        AnyObject anyObject = anyObjectDAO.authFind(anyObjectKey);
+    public AnyObjectTO deprovision(final Long key, final Collection<String> resources) {
+        List<PropagationStatus> statuses = provisioningManager.deprovision(key, resources);
 
-        List<PropagationStatus> statuses = provisioningManager.deprovision(anyObjectKey, resources);
-
-        AnyObjectTO updatedTO = binder.getAnyObjectTO(anyObject, true);
+        AnyObjectTO updatedTO = binder.getAnyObjectTO(key);
         updatedTO.getPropagationStatusTOs().addAll(statuses);
         return updatedTO;
     }
 
     @PreAuthorize("hasRole('" + Entitlement.ANY_OBJECT_UPDATE + "')")
-    @Transactional(rollbackFor = { Throwable.class })
     @Override
-    public AnyObjectTO provision(final Long anyObjectKey, final Collection<String> resources,
-            final boolean changePwd, final String password) {
-
-        AnyObjectTO original = binder.getAnyObjectTO(anyObjectKey);
+    public AnyObjectTO provision(
+            final Long key,
+            final Collection<String> resources,
+            final boolean changePwd,
+            final String password) {
 
-        //trick: assign and retrieve propagation statuses ...
-        original.getPropagationStatusTOs().addAll(
-                assign(anyObjectKey, resources, changePwd, password).getPropagationStatusTOs());
+        AnyObjectTO original = binder.getAnyObjectTO(key);
+        original.getPropagationStatusTOs().addAll(provisioningManager.provision(key, resources));
 
-        // .... rollback.
-        TransactionInterceptor.currentTransactionStatus().setRollbackOnly();
         return original;
     }
 

http://git-wip-us.apache.org/repos/asf/syncope/blob/6dfedd8f/core/logic/src/main/java/org/apache/syncope/core/logic/ConfigurationLogic.java
----------------------------------------------------------------------
diff --git a/core/logic/src/main/java/org/apache/syncope/core/logic/ConfigurationLogic.java b/core/logic/src/main/java/org/apache/syncope/core/logic/ConfigurationLogic.java
index 7d28c88..1598498 100644
--- a/core/logic/src/main/java/org/apache/syncope/core/logic/ConfigurationLogic.java
+++ b/core/logic/src/main/java/org/apache/syncope/core/logic/ConfigurationLogic.java
@@ -23,6 +23,7 @@ import java.lang.reflect.Method;
 import org.apache.syncope.common.lib.to.AttrTO;
 import org.apache.syncope.common.lib.to.ConfTO;
 import org.apache.syncope.common.lib.types.Entitlement;
+import org.apache.syncope.core.misc.security.AuthContextUtils;
 import org.apache.syncope.core.persistence.api.content.ContentExporter;
 import org.apache.syncope.core.persistence.api.dao.ConfDAO;
 import org.apache.syncope.core.persistence.api.dao.NotFoundException;
@@ -97,7 +98,7 @@ public class ConfigurationLogic extends AbstractTransactionalLogic<ConfTO> {
     @Transactional(readOnly = true)
     public void export(final OutputStream os) {
         try {
-            exporter.export(os, uwfAdapter.getPrefix(), gwfAdapter.getPrefix());
+            exporter.export(AuthContextUtils.getDomain(), os, uwfAdapter.getPrefix(), gwfAdapter.getPrefix());
             LOG.debug("Database content successfully exported");
         } catch (Exception e) {
             LOG.error("While exporting database content", e);

http://git-wip-us.apache.org/repos/asf/syncope/blob/6dfedd8f/core/logic/src/main/java/org/apache/syncope/core/logic/GroupLogic.java
----------------------------------------------------------------------
diff --git a/core/logic/src/main/java/org/apache/syncope/core/logic/GroupLogic.java b/core/logic/src/main/java/org/apache/syncope/core/logic/GroupLogic.java
index f476210..33b0447 100644
--- a/core/logic/src/main/java/org/apache/syncope/core/logic/GroupLogic.java
+++ b/core/logic/src/main/java/org/apache/syncope/core/logic/GroupLogic.java
@@ -56,7 +56,6 @@ import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.security.access.prepost.PreAuthorize;
 import org.springframework.stereotype.Component;
 import org.springframework.transaction.annotation.Transactional;
-import org.springframework.transaction.interceptor.TransactionInterceptor;
 
 /**
  * Note that this controller does not extend {@link AbstractTransactionalLogic}, hence does not provide any
@@ -114,7 +113,7 @@ public class GroupLogic extends AbstractAnyLogic<GroupTO, GroupMod> {
     }
 
     @PreAuthorize("isAuthenticated()")
-    @Transactional(readOnly = true, rollbackFor = { Throwable.class })
+    @Transactional(readOnly = true)
     @Override
     public int count(final List<String> realms) {
         return groupDAO.count(getEffectiveRealms(SyncopeConstants.FULL_ADMIN_REALMS, realms));
@@ -140,7 +139,7 @@ public class GroupLogic extends AbstractAnyLogic<GroupTO, GroupMod> {
     }
 
     @PreAuthorize("hasRole('" + Entitlement.GROUP_SEARCH + "')")
-    @Transactional(readOnly = true, rollbackFor = { Throwable.class })
+    @Transactional(readOnly = true)
     @Override
     public int searchCount(final SearchCond searchCondition, final List<String> realms) {
         return searchDAO.count(
@@ -149,7 +148,7 @@ public class GroupLogic extends AbstractAnyLogic<GroupTO, GroupMod> {
     }
 
     @PreAuthorize("hasRole('" + Entitlement.GROUP_SEARCH + "')")
-    @Transactional(readOnly = true, rollbackFor = { Throwable.class })
+    @Transactional(readOnly = true)
     @Override
     public List<GroupTO> search(final SearchCond searchCondition, final int page, final int size,
             final List<OrderByClause> orderBy, final List<String> realms, final boolean details) {
@@ -256,75 +255,70 @@ public class GroupLogic extends AbstractAnyLogic<GroupTO, GroupMod> {
     }
 
     @PreAuthorize("hasRole('" + Entitlement.GROUP_UPDATE + "')")
-    @Transactional(rollbackFor = { Throwable.class })
     @Override
     public GroupTO unlink(final Long groupKey, final Collection<String> resources) {
-        final GroupMod groupMod = new GroupMod();
+        GroupMod groupMod = new GroupMod();
         groupMod.setKey(groupKey);
         groupMod.getResourcesToRemove().addAll(resources);
-        final Long updatedResult = provisioningManager.unlink(groupMod);
 
-        return binder.getGroupTO(updatedResult);
+        return binder.getGroupTO(provisioningManager.unlink(groupMod));
     }
 
     @PreAuthorize("hasRole('" + Entitlement.GROUP_UPDATE + "')")
-    @Transactional(rollbackFor = { Throwable.class })
     @Override
     public GroupTO link(final Long groupKey, final Collection<String> resources) {
-        final GroupMod groupMod = new GroupMod();
+        GroupMod groupMod = new GroupMod();
         groupMod.setKey(groupKey);
         groupMod.getResourcesToAdd().addAll(resources);
+
         return binder.getGroupTO(provisioningManager.link(groupMod));
     }
 
     @PreAuthorize("hasRole('" + Entitlement.GROUP_UPDATE + "')")
-    @Transactional(rollbackFor = { Throwable.class })
     @Override
     public GroupTO unassign(final Long groupKey, final Collection<String> resources) {
-        final GroupMod groupMod = new GroupMod();
+        GroupMod groupMod = new GroupMod();
         groupMod.setKey(groupKey);
         groupMod.getResourcesToRemove().addAll(resources);
         return update(groupMod);
     }
 
     @PreAuthorize("hasRole('" + Entitlement.GROUP_UPDATE + "')")
-    @Transactional(rollbackFor = { Throwable.class })
     @Override
     public GroupTO assign(
-            final Long groupKey, final Collection<String> resources, final boolean changePwd, final String password) {
+            final Long key,
+            final Collection<String> resources,
+            final boolean changepwd,
+            final String password) {
 
-        final GroupMod userMod = new GroupMod();
-        userMod.setKey(groupKey);
-        userMod.getResourcesToAdd().addAll(resources);
-        return update(userMod);
+        GroupMod groupMod = new GroupMod();
+        groupMod.setKey(key);
+        groupMod.getResourcesToAdd().addAll(resources);
+
+        return update(groupMod);
     }
 
     @PreAuthorize("hasRole('" + Entitlement.GROUP_UPDATE + "')")
-    @Transactional(rollbackFor = { Throwable.class })
     @Override
-    public GroupTO deprovision(final Long groupKey, final Collection<String> resources) {
-        final Group group = groupDAO.authFind(groupKey);
-
-        List<PropagationStatus> statuses = provisioningManager.deprovision(groupKey, resources);
+    public GroupTO deprovision(final Long key, final Collection<String> resources) {
+        List<PropagationStatus> statuses = provisioningManager.deprovision(key, resources);
 
-        GroupTO updatedTO = binder.getGroupTO(group, true);
+        GroupTO updatedTO = binder.getGroupTO(key);
         updatedTO.getPropagationStatusTOs().addAll(statuses);
         return updatedTO;
     }
 
     @PreAuthorize("hasRole('" + Entitlement.GROUP_UPDATE + "')")
-    @Transactional(rollbackFor = { Throwable.class })
     @Override
     public GroupTO provision(
-            final Long groupKey, final Collection<String> resources, final boolean changePwd, final String password) {
-        GroupTO original = binder.getGroupTO(groupKey);
+            final Long key,
+            final Collection<String> resources,
+            final boolean changePwd,
+            final String password) {
 
-        //trick: assign and retrieve propagation statuses ...
-        original.getPropagationStatusTOs().addAll(
-                assign(groupKey, resources, changePwd, password).getPropagationStatusTOs());
+        GroupTO original = binder.getGroupTO(key);
+        original.getPropagationStatusTOs().addAll(provisioningManager.provision(key, resources));
 
-        // .... rollback.
-        TransactionInterceptor.currentTransactionStatus().setRollbackOnly();
         return original;
     }
 

http://git-wip-us.apache.org/repos/asf/syncope/blob/6dfedd8f/core/logic/src/main/java/org/apache/syncope/core/logic/LoggerLogic.java
----------------------------------------------------------------------
diff --git a/core/logic/src/main/java/org/apache/syncope/core/logic/LoggerLogic.java b/core/logic/src/main/java/org/apache/syncope/core/logic/LoggerLogic.java
index 4b5aac8..d407dba 100644
--- a/core/logic/src/main/java/org/apache/syncope/core/logic/LoggerLogic.java
+++ b/core/logic/src/main/java/org/apache/syncope/core/logic/LoggerLogic.java
@@ -46,6 +46,7 @@ import org.apache.syncope.common.lib.types.ResourceOperation;
 import org.apache.syncope.common.lib.types.TaskType;
 import org.apache.syncope.common.lib.types.UnmatchingRule;
 import org.apache.syncope.common.lib.types.AnyTypeKind;
+import org.apache.syncope.common.lib.types.AuditElements;
 import org.apache.syncope.common.lib.types.Entitlement;
 import org.apache.syncope.core.persistence.api.dao.ExternalResourceDAO;
 import org.apache.syncope.core.persistence.api.dao.LoggerDAO;
@@ -55,8 +56,9 @@ import org.apache.syncope.core.persistence.api.entity.EntityFactory;
 import org.apache.syncope.core.persistence.api.entity.resource.ExternalResource;
 import org.apache.syncope.core.persistence.api.entity.Logger;
 import org.apache.syncope.core.persistence.api.entity.task.SchedTask;
-import org.apache.syncope.core.persistence.api.entity.task.SyncTask;
 import org.apache.syncope.core.misc.spring.BeanUtils;
+import org.apache.syncope.core.provisioning.java.sync.PushJobDelegate;
+import org.apache.syncope.core.provisioning.java.sync.SyncJobDelegate;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.core.io.Resource;
 import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
@@ -255,10 +257,10 @@ public class LoggerLogic extends AbstractTransactionalLogic<LoggerTO> {
                 }
             }
 
-            //SYNCOPE-608
+            // SYNCOPE-608
             EventCategoryTO authenticationControllerEvents = new EventCategoryTO();
-            authenticationControllerEvents.setCategory("AuthenticationController");
-            authenticationControllerEvents.getEvents().add("login");
+            authenticationControllerEvents.setCategory(AuditElements.AUTHENTICATION_CATEGORY);
+            authenticationControllerEvents.getEvents().add(AuditElements.LOGIN_EVENT);
             events.add(authenticationControllerEvents);
 
             events.add(new EventCategoryTO(EventCategoryType.PROPAGATION));
@@ -305,15 +307,17 @@ public class LoggerLogic extends AbstractTransactionalLogic<LoggerTO> {
 
             for (SchedTask task : taskDAO.<SchedTask>findAll(TaskType.SCHEDULED)) {
                 EventCategoryTO eventCategoryTO = new EventCategoryTO(EventCategoryType.TASK);
-                eventCategoryTO.setCategory(Class.forName(task.getJobClassName()).getSimpleName());
+                eventCategoryTO.setCategory(Class.forName(task.getJobDelegateClassName()).getSimpleName());
                 events.add(eventCategoryTO);
             }
 
-            for (SyncTask task : taskDAO.<SyncTask>findAll(TaskType.SYNCHRONIZATION)) {
-                EventCategoryTO eventCategoryTO = new EventCategoryTO(EventCategoryType.TASK);
-                eventCategoryTO.setCategory(Class.forName(task.getJobClassName()).getSimpleName());
-                events.add(eventCategoryTO);
-            }
+            EventCategoryTO eventCategoryTO = new EventCategoryTO(EventCategoryType.TASK);
+            eventCategoryTO.setCategory(SyncJobDelegate.class.getSimpleName());
+            events.add(eventCategoryTO);
+
+            eventCategoryTO = new EventCategoryTO(EventCategoryType.TASK);
+            eventCategoryTO.setCategory(PushJobDelegate.class.getSimpleName());
+            events.add(eventCategoryTO);
         } catch (Exception e) {
             LOG.error("Failure retrieving audit/notification events", e);
         }

http://git-wip-us.apache.org/repos/asf/syncope/blob/6dfedd8f/core/logic/src/main/java/org/apache/syncope/core/logic/SyncopeLogic.java
----------------------------------------------------------------------
diff --git a/core/logic/src/main/java/org/apache/syncope/core/logic/SyncopeLogic.java b/core/logic/src/main/java/org/apache/syncope/core/logic/SyncopeLogic.java
index bc8fb0f..8dd20a8 100644
--- a/core/logic/src/main/java/org/apache/syncope/core/logic/SyncopeLogic.java
+++ b/core/logic/src/main/java/org/apache/syncope/core/logic/SyncopeLogic.java
@@ -131,7 +131,7 @@ public class SyncopeLogic extends AbstractLogic<SyncopeTO> {
         syncopeTO.getReportlets().addAll(
                 classNamesLoader.getClassNames(ImplementationClassNamesLoader.Type.REPORTLET));
         syncopeTO.getTaskJobs().addAll(
-                classNamesLoader.getClassNames(ImplementationClassNamesLoader.Type.TASKJOB));
+                classNamesLoader.getClassNames(ImplementationClassNamesLoader.Type.TASKJOBDELEGATE));
         syncopeTO.getPropagationActions().addAll(
                 classNamesLoader.getClassNames(ImplementationClassNamesLoader.Type.PROPAGATION_ACTIONS));
         syncopeTO.getSyncActions().addAll(

http://git-wip-us.apache.org/repos/asf/syncope/blob/6dfedd8f/core/logic/src/main/java/org/apache/syncope/core/logic/TaskLogic.java
----------------------------------------------------------------------
diff --git a/core/logic/src/main/java/org/apache/syncope/core/logic/TaskLogic.java b/core/logic/src/main/java/org/apache/syncope/core/logic/TaskLogic.java
index 82dc8d1..9c119f3 100644
--- a/core/logic/src/main/java/org/apache/syncope/core/logic/TaskLogic.java
+++ b/core/logic/src/main/java/org/apache/syncope/core/logic/TaskLogic.java
@@ -22,6 +22,7 @@ import java.lang.reflect.Method;
 import java.util.ArrayList;
 import java.util.Date;
 import java.util.List;
+import java.util.Map;
 import org.apache.commons.collections4.CollectionUtils;
 import org.apache.commons.collections4.Transformer;
 import org.apache.commons.lang3.ArrayUtils;
@@ -51,15 +52,15 @@ import org.apache.syncope.core.persistence.api.entity.task.TaskUtils;
 import org.apache.syncope.core.persistence.api.entity.task.TaskUtilsFactory;
 import org.apache.syncope.core.provisioning.api.data.TaskDataBinder;
 import org.apache.syncope.core.provisioning.api.job.JobNamer;
-import org.apache.syncope.core.provisioning.api.job.TaskJob;
 import org.apache.syncope.core.provisioning.api.propagation.PropagationTaskExecutor;
 import org.apache.syncope.core.provisioning.api.job.JobInstanceLoader;
-import org.apache.syncope.core.logic.notification.NotificationJob;
+import org.apache.syncope.core.logic.notification.NotificationJobDelegate;
+import org.apache.syncope.core.persistence.api.dao.ConfDAO;
+import org.apache.syncope.core.provisioning.java.job.TaskJob;
 import org.quartz.JobDataMap;
 import org.quartz.JobKey;
 import org.quartz.Scheduler;
 import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.scheduling.quartz.SchedulerFactoryBean;
 import org.springframework.security.access.prepost.PreAuthorize;
 import org.springframework.stereotype.Component;
 
@@ -73,21 +74,21 @@ public class TaskLogic extends AbstractJobLogic<AbstractTaskTO> {
     private TaskExecDAO taskExecDAO;
 
     @Autowired
+    private ConfDAO confDAO;
+
+    @Autowired
     private TaskDataBinder binder;
 
     @Autowired
     private PropagationTaskExecutor taskExecutor;
 
     @Autowired
-    private NotificationJob notificationJob;
+    private NotificationJobDelegate notificationJobDelegate;
 
     @Autowired
     private JobInstanceLoader jobInstanceLoader;
 
     @Autowired
-    private SchedulerFactoryBean scheduler;
-
-    @Autowired
     private TaskUtilsFactory taskUtilsFactory;
 
     @PreAuthorize("hasRole('" + Entitlement.TASK_CREATE + "')")
@@ -98,7 +99,9 @@ public class TaskLogic extends AbstractJobLogic<AbstractTaskTO> {
         task = taskDAO.save(task);
 
         try {
-            jobInstanceLoader.registerJob(task, task.getJobClassName(), task.getCronExpression());
+            jobInstanceLoader.registerJob(
+                    task,
+                    confDAO.find("tasks.interruptMaxRetries", "1").getValues().get(0).getLongValue());
         } catch (Exception e) {
             LOG.error("While registering quartz job for task " + task.getKey(), e);
 
@@ -128,7 +131,9 @@ public class TaskLogic extends AbstractJobLogic<AbstractTaskTO> {
         task = taskDAO.save(task);
 
         try {
-            jobInstanceLoader.registerJob(task, task.getJobClassName(), task.getCronExpression());
+            jobInstanceLoader.registerJob(
+                    task,
+                    confDAO.find("tasks.interruptMaxRetries", "1").getValues().get(0).getLongValue());
         } catch (Exception e) {
             LOG.error("While registering quartz job for task " + task.getKey(), e);
 
@@ -163,28 +168,28 @@ public class TaskLogic extends AbstractJobLogic<AbstractTaskTO> {
     }
 
     @PreAuthorize("hasRole('" + Entitlement.TASK_READ + "')")
-    public <T extends AbstractTaskTO> T read(final Long taskId) {
-        Task task = taskDAO.find(taskId);
+    public <T extends AbstractTaskTO> T read(final Long taskKey) {
+        Task task = taskDAO.find(taskKey);
         if (task == null) {
-            throw new NotFoundException("Task " + taskId);
+            throw new NotFoundException("Task " + taskKey);
         }
         return binder.getTaskTO(task, taskUtilsFactory.getInstance(task));
     }
 
     @PreAuthorize("hasRole('" + Entitlement.TASK_READ + "')")
-    public TaskExecTO readExecution(final Long executionId) {
-        TaskExec taskExec = taskExecDAO.find(executionId);
+    public TaskExecTO readExecution(final Long execKey) {
+        TaskExec taskExec = taskExecDAO.find(execKey);
         if (taskExec == null) {
-            throw new NotFoundException("Task execution " + executionId);
+            throw new NotFoundException("Task execution " + execKey);
         }
         return binder.getTaskExecTO(taskExec);
     }
 
     @PreAuthorize("hasRole('" + Entitlement.TASK_EXECUTE + "')")
-    public TaskExecTO execute(final Long taskId, final boolean dryRun) {
-        Task task = taskDAO.find(taskId);
+    public TaskExecTO execute(final Long taskKey, final boolean dryRun) {
+        Task task = taskDAO.find(taskKey);
         if (task == null) {
-            throw new NotFoundException("Task " + taskId);
+            throw new NotFoundException("Task " + taskKey);
         }
         TaskUtils taskUtils = taskUtilsFactory.getInstance(task);
 
@@ -196,7 +201,7 @@ public class TaskLogic extends AbstractJobLogic<AbstractTaskTO> {
                 break;
 
             case NOTIFICATION:
-                final TaskExec notExec = notificationJob.executeSingle((NotificationTask) task);
+                final TaskExec notExec = notificationJobDelegate.executeSingle((NotificationTask) task);
                 result = binder.getTaskExecTO(notExec);
                 break;
 
@@ -204,15 +209,14 @@ public class TaskLogic extends AbstractJobLogic<AbstractTaskTO> {
             case SYNCHRONIZATION:
             case PUSH:
                 try {
-                    jobInstanceLoader.registerJob(task,
-                            ((SchedTask) task).getJobClassName(),
-                            ((SchedTask) task).getCronExpression());
-
-                    JobDataMap map = new JobDataMap();
-                    map.put(TaskJob.DRY_RUN_JOBDETAIL_KEY, dryRun);
+                    Map<String, Object> jobDataMap = jobInstanceLoader.registerJob(
+                            (SchedTask) task,
+                            confDAO.find("tasks.interruptMaxRetries", "1").getValues().get(0).getLongValue());
 
+                    jobDataMap.put(TaskJob.DRY_RUN_JOBDETAIL_KEY, dryRun);
                     scheduler.getScheduler().triggerJob(
-                            new JobKey(JobNamer.getJobName(task), Scheduler.DEFAULT_GROUP), map);
+                            new JobKey(JobNamer.getJobName(task), Scheduler.DEFAULT_GROUP),
+                            new JobDataMap(jobDataMap));
                 } catch (Exception e) {
                     LOG.error("While executing task {}", task, e);
 
@@ -222,7 +226,7 @@ public class TaskLogic extends AbstractJobLogic<AbstractTaskTO> {
                 }
 
                 result = new TaskExecTO();
-                result.setTask(taskId);
+                result.setTask(taskKey);
                 result.setStartDate(new Date());
                 result.setStatus("JOB_FIRED");
                 result.setMessage("Job fired; waiting for results...");
@@ -235,10 +239,10 @@ public class TaskLogic extends AbstractJobLogic<AbstractTaskTO> {
     }
 
     @PreAuthorize("hasRole('" + Entitlement.TASK_READ + "')")
-    public TaskExecTO report(final Long executionId, final PropagationTaskExecStatus status, final String message) {
-        TaskExec exec = taskExecDAO.find(executionId);
+    public TaskExecTO report(final Long execKey, final PropagationTaskExecStatus status, final String message) {
+        TaskExec exec = taskExecDAO.find(execKey);
         if (exec == null) {
-            throw new NotFoundException("Task execution " + executionId);
+            throw new NotFoundException("Task execution " + execKey);
         }
 
         SyncopeClientException sce = SyncopeClientException.build(ClientExceptionType.InvalidPropagationTaskExecReport);
@@ -277,10 +281,10 @@ public class TaskLogic extends AbstractJobLogic<AbstractTaskTO> {
     }
 
     @PreAuthorize("hasRole('" + Entitlement.TASK_DELETE + "')")
-    public <T extends AbstractTaskTO> T delete(final Long taskId) {
-        Task task = taskDAO.find(taskId);
+    public <T extends AbstractTaskTO> T delete(final Long taskKey) {
+        Task task = taskDAO.find(taskKey);
         if (task == null) {
-            throw new NotFoundException("Task " + taskId);
+            throw new NotFoundException("Task " + taskKey);
         }
         TaskUtils taskUtils = taskUtilsFactory.getInstance(task);
 
@@ -298,10 +302,10 @@ public class TaskLogic extends AbstractJobLogic<AbstractTaskTO> {
     }
 
     @PreAuthorize("hasRole('" + Entitlement.TASK_DELETE + "')")
-    public TaskExecTO deleteExecution(final Long executionId) {
-        TaskExec taskExec = taskExecDAO.find(executionId);
+    public TaskExecTO deleteExecution(final Long execKey) {
+        TaskExec taskExec = taskExecDAO.find(execKey);
         if (taskExec == null) {
-            throw new NotFoundException("Task execution " + executionId);
+            throw new NotFoundException("Task execution " + execKey);
         }
 
         TaskExecTO taskExecutionToDelete = binder.getTaskExecTO(taskExec);

http://git-wip-us.apache.org/repos/asf/syncope/blob/6dfedd8f/core/logic/src/main/java/org/apache/syncope/core/logic/UserLogic.java
----------------------------------------------------------------------
diff --git a/core/logic/src/main/java/org/apache/syncope/core/logic/UserLogic.java b/core/logic/src/main/java/org/apache/syncope/core/logic/UserLogic.java
index 3aec28c..28e7401 100644
--- a/core/logic/src/main/java/org/apache/syncope/core/logic/UserLogic.java
+++ b/core/logic/src/main/java/org/apache/syncope/core/logic/UserLogic.java
@@ -60,7 +60,6 @@ import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.security.access.prepost.PreAuthorize;
 import org.springframework.stereotype.Component;
 import org.springframework.transaction.annotation.Transactional;
-import org.springframework.transaction.interceptor.TransactionInterceptor;
 
 /**
  * Note that this controller does not extend {@link AbstractTransactionalLogic}, hence does not provide any
@@ -100,17 +99,19 @@ public class UserLogic extends AbstractAnyLogic<UserTO, UserMod> {
     protected SyncopeLogic syncopeLogic;
 
     @PreAuthorize("hasRole('" + Entitlement.USER_READ + "')")
+    @Transactional(readOnly = true)
     public String getUsername(final Long key) {
         return binder.getUserTO(key).getUsername();
     }
 
     @PreAuthorize("hasRole('" + Entitlement.USER_READ + "')")
+    @Transactional(readOnly = true)
     public Long getKey(final String username) {
         return binder.getUserTO(username).getKey();
     }
 
     @PreAuthorize("hasRole('" + Entitlement.USER_LIST + "')")
-    @Transactional(readOnly = true, rollbackFor = { Throwable.class })
+    @Transactional(readOnly = true)
     @Override
     public int count(final List<String> realms) {
         return userDAO.count(
@@ -118,7 +119,7 @@ public class UserLogic extends AbstractAnyLogic<UserTO, UserMod> {
     }
 
     @PreAuthorize("hasRole('" + Entitlement.USER_LIST + "')")
-    @Transactional(readOnly = true, rollbackFor = { Throwable.class })
+    @Transactional(readOnly = true)
     @Override
     public List<UserTO> list(
             final int page, final int size, final List<OrderByClause> orderBy,
@@ -152,7 +153,7 @@ public class UserLogic extends AbstractAnyLogic<UserTO, UserMod> {
     }
 
     @PreAuthorize("hasRole('" + Entitlement.USER_SEARCH + "')")
-    @Transactional(readOnly = true, rollbackFor = { Throwable.class })
+    @Transactional(readOnly = true)
     @Override
     public int searchCount(final SearchCond searchCondition, final List<String> realms) {
         return searchDAO.count(
@@ -161,7 +162,7 @@ public class UserLogic extends AbstractAnyLogic<UserTO, UserMod> {
     }
 
     @PreAuthorize("hasRole('" + Entitlement.USER_SEARCH + "')")
-    @Transactional(readOnly = true, rollbackFor = { Throwable.class })
+    @Transactional(readOnly = true)
     @Override
     public List<UserTO> search(final SearchCond searchCondition, final int page, final int size,
             final List<OrderByClause> orderBy, final List<String> realms, final boolean details) {
@@ -242,22 +243,21 @@ public class UserLogic extends AbstractAnyLogic<UserTO, UserMod> {
         return updatedTO;
     }
 
-    protected Map.Entry<Long, List<PropagationStatus>> setStatusOnWfAdapter(final User user,
-            final StatusMod statusMod) {
+    protected Map.Entry<Long, List<PropagationStatus>> setStatusOnWfAdapter(final StatusMod statusMod) {
         Map.Entry<Long, List<PropagationStatus>> updated;
 
         switch (statusMod.getType()) {
             case SUSPEND:
-                updated = provisioningManager.suspend(user, statusMod);
+                updated = provisioningManager.suspend(statusMod);
                 break;
 
             case REACTIVATE:
-                updated = provisioningManager.reactivate(user, statusMod);
+                updated = provisioningManager.reactivate(statusMod);
                 break;
 
             case ACTIVATE:
             default:
-                updated = provisioningManager.activate(user, statusMod);
+                updated = provisioningManager.activate(statusMod);
                 break;
 
         }
@@ -266,11 +266,8 @@ public class UserLogic extends AbstractAnyLogic<UserTO, UserMod> {
     }
 
     @PreAuthorize("hasRole('" + Entitlement.USER_UPDATE + "')")
-    @Transactional(rollbackFor = { Throwable.class })
     public UserTO status(final StatusMod statusMod) {
-        User user = userDAO.authFind(statusMod.getKey());
-
-        Map.Entry<Long, List<PropagationStatus>> updated = setStatusOnWfAdapter(user, statusMod);
+        Map.Entry<Long, List<PropagationStatus>> updated = setStatusOnWfAdapter(statusMod);
         final UserTO savedTO = binder.getUserTO(updated.getKey());
         savedTO.getPropagationStatusTOs().addAll(updated.getValue());
         return savedTO;
@@ -304,7 +301,7 @@ public class UserLogic extends AbstractAnyLogic<UserTO, UserMod> {
         if (user == null) {
             throw new NotFoundException("User with token " + token);
         }
-        provisioningManager.confirmPasswordReset(user, token, password);
+        provisioningManager.confirmPasswordReset(user.getKey(), token, password);
     }
 
     @PreAuthorize("isAuthenticated() and not(hasRole('" + Entitlement.ANONYMOUS + "'))")
@@ -332,9 +329,8 @@ public class UserLogic extends AbstractAnyLogic<UserTO, UserMod> {
 
         List<PropagationStatus> statuses = provisioningManager.delete(key);
 
-        final UserTO deletedTO;
-        User deleted = userDAO.find(key);
-        if (deleted == null) {
+        UserTO deletedTO;
+        if (userDAO.find(key) == null) {
             deletedTO = new UserTO();
             deletedTO.setKey(key);
         } else {
@@ -346,39 +342,35 @@ public class UserLogic extends AbstractAnyLogic<UserTO, UserMod> {
     }
 
     @PreAuthorize("hasRole('" + Entitlement.USER_UPDATE + "')")
-    @Transactional(rollbackFor = { Throwable.class })
     @Override
     public UserTO unlink(final Long key, final Collection<String> resources) {
-        final UserMod userMod = new UserMod();
+        UserMod userMod = new UserMod();
         userMod.setKey(key);
         userMod.getResourcesToRemove().addAll(resources);
-        Long updatedKey = provisioningManager.unlink(userMod);
 
-        return binder.getUserTO(updatedKey);
+        return binder.getUserTO(provisioningManager.unlink(userMod));
     }
 
     @PreAuthorize("hasRole('" + Entitlement.USER_UPDATE + "')")
-    @Transactional(rollbackFor = { Throwable.class })
     @Override
     public UserTO link(final Long key, final Collection<String> resources) {
-        final UserMod userMod = new UserMod();
+        UserMod userMod = new UserMod();
         userMod.setKey(key);
         userMod.getResourcesToAdd().addAll(resources);
+
         return binder.getUserTO(provisioningManager.link(userMod));
     }
 
     @PreAuthorize("hasRole('" + Entitlement.USER_UPDATE + "')")
-    @Transactional(rollbackFor = { Throwable.class })
     @Override
     public UserTO unassign(final Long key, final Collection<String> resources) {
-        final UserMod userMod = new UserMod();
+        UserMod userMod = new UserMod();
         userMod.setKey(key);
         userMod.getResourcesToRemove().addAll(resources);
         return update(userMod);
     }
 
     @PreAuthorize("hasRole('" + Entitlement.USER_UPDATE + "')")
-    @Transactional(rollbackFor = { Throwable.class })
     @Override
     public UserTO assign(
             final Long key,
@@ -386,7 +378,7 @@ public class UserLogic extends AbstractAnyLogic<UserTO, UserMod> {
             final boolean changepwd,
             final String password) {
 
-        final UserMod userMod = new UserMod();
+        UserMod userMod = new UserMod();
         userMod.setKey(key);
         userMod.getResourcesToAdd().addAll(resources);
 
@@ -402,20 +394,16 @@ public class UserLogic extends AbstractAnyLogic<UserTO, UserMod> {
     }
 
     @PreAuthorize("hasRole('" + Entitlement.USER_UPDATE + "')")
-    @Transactional(rollbackFor = { Throwable.class })
     @Override
     public UserTO deprovision(final Long key, final Collection<String> resources) {
-        User user = userDAO.authFind(key);
-
         List<PropagationStatus> statuses = provisioningManager.deprovision(key, resources);
 
-        final UserTO updatedUserTO = binder.getUserTO(user, true);
-        updatedUserTO.getPropagationStatusTOs().addAll(statuses);
-        return updatedUserTO;
+        UserTO updatedTO = binder.getUserTO(key);
+        updatedTO.getPropagationStatusTOs().addAll(statuses);
+        return updatedTO;
     }
 
     @PreAuthorize("hasRole('" + Entitlement.USER_UPDATE + "')")
-    @Transactional(readOnly = true)
     @Override
     public UserTO provision(
             final Long key,
@@ -423,14 +411,9 @@ public class UserLogic extends AbstractAnyLogic<UserTO, UserMod> {
             final boolean changePwd,
             final String password) {
 
-        final UserTO original = binder.getUserTO(key);
-
-        //trick: assign and retrieve propagation statuses ...
-        original.getPropagationStatusTOs().addAll(
-                assign(key, resources, changePwd, password).getPropagationStatusTOs());
+        UserTO original = binder.getUserTO(key);
+        original.getPropagationStatusTOs().addAll(provisioningManager.provision(key, changePwd, password, resources));
 
-        // .... rollback.
-        TransactionInterceptor.currentTransactionStatus().setRollbackOnly();
         return original;
     }
 


[08/31] syncope git commit: [SYNCOPE-652] Still several things to refine, but it starts taking shape

Posted by md...@apache.org.
http://git-wip-us.apache.org/repos/asf/syncope/blob/6dfedd8f/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/CamelUserProvisioningManager.java
----------------------------------------------------------------------
diff --git a/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/CamelUserProvisioningManager.java b/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/CamelUserProvisioningManager.java
index 8f0d9d2..8b5ad89 100644
--- a/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/CamelUserProvisioningManager.java
+++ b/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/CamelUserProvisioningManager.java
@@ -147,19 +147,19 @@ public class CamelUserProvisioningManager extends AbstractCamelProvisioningManag
 
     @Override
     @SuppressWarnings("unchecked")
-    public Pair<Long, List<PropagationStatus>> activate(final User user, final StatusMod statusMod) {
+    public Pair<Long, List<PropagationStatus>> activate(final StatusMod statusMod) {
         PollingConsumer pollingConsumer = getConsumer("direct:statusPort");
 
         Map<String, Object> props = new HashMap<>();
         props.put("token", statusMod.getToken());
-        props.put("user", user);
+        props.put("userKey", statusMod.getKey());
         props.put("statusMod", statusMod);
 
         if (statusMod.isOnSyncope()) {
-            sendMessage("direct:activateUser", user.getKey(), props);
+            sendMessage("direct:activateUser", statusMod.getKey(), props);
         } else {
             WorkflowResult<Long> updated =
-                    new WorkflowResult<>(user.getKey(), null, statusMod.getType().name().toLowerCase());
+                    new WorkflowResult<>(statusMod.getKey(), null, statusMod.getType().name().toLowerCase());
             sendMessage("direct:userStatusPropagation", updated, props);
         }
 
@@ -174,18 +174,18 @@ public class CamelUserProvisioningManager extends AbstractCamelProvisioningManag
 
     @Override
     @SuppressWarnings("unchecked")
-    public Pair<Long, List<PropagationStatus>> reactivate(final User user, final StatusMod statusMod) {
+    public Pair<Long, List<PropagationStatus>> reactivate(final StatusMod statusMod) {
         PollingConsumer pollingConsumer = getConsumer("direct:statusPort");
 
         Map<String, Object> props = new HashMap<>();
-        props.put("user", user);
+        props.put("userKey", statusMod.getKey());
         props.put("statusMod", statusMod);
 
         if (statusMod.isOnSyncope()) {
-            sendMessage("direct:reactivateUser", user.getKey(), props);
+            sendMessage("direct:reactivateUser", statusMod.getKey(), props);
         } else {
             WorkflowResult<Long> updated =
-                    new WorkflowResult<>(user.getKey(), null, statusMod.getType().name().toLowerCase());
+                    new WorkflowResult<>(statusMod.getKey(), null, statusMod.getType().name().toLowerCase());
             sendMessage("direct:userStatusPropagation", updated, props);
         }
 
@@ -200,18 +200,18 @@ public class CamelUserProvisioningManager extends AbstractCamelProvisioningManag
 
     @Override
     @SuppressWarnings("unchecked")
-    public Pair<Long, List<PropagationStatus>> suspend(final User user, final StatusMod statusMod) {
+    public Pair<Long, List<PropagationStatus>> suspend(final StatusMod statusMod) {
         PollingConsumer pollingConsumer = getConsumer("direct:statusPort");
 
         Map<String, Object> props = new HashMap<>();
-        props.put("user", user);
+        props.put("userKey", statusMod.getKey());
         props.put("statusMod", statusMod);
 
         if (statusMod.isOnSyncope()) {
-            sendMessage("direct:suspendUser", user.getKey(), props);
+            sendMessage("direct:suspendUser", statusMod.getKey(), props);
         } else {
             WorkflowResult<Long> updated =
-                    new WorkflowResult<>(user.getKey(), null, statusMod.getType().name().toLowerCase());
+                    new WorkflowResult<>(statusMod.getKey(), null, statusMod.getType().name().toLowerCase());
             sendMessage("direct:userStatusPropagation", updated, props);
         }
 
@@ -242,6 +242,30 @@ public class CamelUserProvisioningManager extends AbstractCamelProvisioningManag
 
     @Override
     @SuppressWarnings("unchecked")
+    public List<PropagationStatus> provision(
+            final Long key, final boolean changePwd, final String password, final Collection<String> resources) {
+
+        PollingConsumer pollingConsumer = getConsumer("direct:provisionPort");
+
+        Map<String, Object> props = new HashMap<>();
+        props.put("key", key);
+        props.put("changePwd", changePwd);
+        props.put("password", password);
+        props.put("resources", resources);
+
+        sendMessage("direct:provisionUser", key, props);
+
+        Exchange exchange = pollingConsumer.receive();
+
+        if (exchange.getProperty(Exchange.EXCEPTION_CAUGHT) != null) {
+            throw (RuntimeException) exchange.getProperty(Exchange.EXCEPTION_CAUGHT);
+        }
+
+        return exchange.getIn().getBody(List.class);
+    }
+
+    @Override
+    @SuppressWarnings("unchecked")
     public List<PropagationStatus> deprovision(final Long user, final Collection<String> resources) {
         PollingConsumer pollingConsumer = getConsumer("direct:deprovisionPort");
 
@@ -268,7 +292,7 @@ public class CamelUserProvisioningManager extends AbstractCamelProvisioningManag
         PollingConsumer pollingConsumer = getConsumer("direct:updateInSyncPort");
 
         Map<String, Object> props = new HashMap<>();
-        props.put("key", key);
+        props.put("userKey", key);
         props.put("result", result);
         props.put("enabled", enabled);
         props.put("excludedResources", excludedResources);
@@ -301,7 +325,7 @@ public class CamelUserProvisioningManager extends AbstractCamelProvisioningManag
         Map<String, Object> props = new HashMap<>();
         props.put("propagate", propagate);
 
-        sendMessage("direct:innerSuspendUser", user, props);
+        sendMessage("direct:innerSuspendUser", user.getKey(), props);
 
         Exchange exchange = pollingConsumer.receive();
 
@@ -324,16 +348,15 @@ public class CamelUserProvisioningManager extends AbstractCamelProvisioningManag
     }
 
     @Override
-    public void confirmPasswordReset(final User user, final String token, final String password) {
+    public void confirmPasswordReset(final Long key, final String token, final String password) {
         PollingConsumer pollingConsumer = getConsumer("direct:confirmPwdResetPort");
 
         Map<String, Object> props = new HashMap<>();
-        props.put("user", user);
-        props.put("userKey", user.getKey());
+        props.put("userKey", key);
         props.put("token", token);
         props.put("password", password);
 
-        sendMessage("direct:confirmPwdReset", user, props);
+        sendMessage("direct:confirmPwdReset", key, props);
 
         Exchange exchange = pollingConsumer.receive();
 

http://git-wip-us.apache.org/repos/asf/syncope/blob/6dfedd8f/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/processor/AnyObjectCreateProcessor.java
----------------------------------------------------------------------
diff --git a/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/processor/AnyObjectCreateProcessor.java b/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/processor/AnyObjectCreateProcessor.java
index 2f2e41e..6316230 100644
--- a/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/processor/AnyObjectCreateProcessor.java
+++ b/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/processor/AnyObjectCreateProcessor.java
@@ -57,7 +57,7 @@ public class AnyObjectCreateProcessor implements Processor {
         List<PropagationTask> tasks =
                 propagationManager.getAnyObjectCreateTasks(created, any.getVirAttrs(), excludedResource);
         PropagationReporter propagationReporter =
-                ApplicationContextProvider.getApplicationContext().getBean(PropagationReporter.class);
+                ApplicationContextProvider.getBeanFactory().getBean(PropagationReporter.class);
         try {
             taskExecutor.execute(tasks, propagationReporter);
         } catch (PropagationException e) {

http://git-wip-us.apache.org/repos/asf/syncope/blob/6dfedd8f/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/processor/AnyObjectDeleteProcessor.java
----------------------------------------------------------------------
diff --git a/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/processor/AnyObjectDeleteProcessor.java b/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/processor/AnyObjectDeleteProcessor.java
index d1c9243..5045ab7 100644
--- a/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/processor/AnyObjectDeleteProcessor.java
+++ b/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/processor/AnyObjectDeleteProcessor.java
@@ -69,7 +69,7 @@ public class AnyObjectDeleteProcessor implements Processor {
         }
 
         PropagationReporter propagationReporter =
-                ApplicationContextProvider.getApplicationContext().getBean(PropagationReporter.class);
+                ApplicationContextProvider.getBeanFactory().getBean(PropagationReporter.class);
         try {
             taskExecutor.execute(tasks, propagationReporter);
         } catch (PropagationException e) {

http://git-wip-us.apache.org/repos/asf/syncope/blob/6dfedd8f/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/processor/AnyObjectDeprovisionProcessor.java
----------------------------------------------------------------------
diff --git a/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/processor/AnyObjectDeprovisionProcessor.java b/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/processor/AnyObjectDeprovisionProcessor.java
index c56ab90..5836a9f 100644
--- a/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/processor/AnyObjectDeprovisionProcessor.java
+++ b/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/processor/AnyObjectDeprovisionProcessor.java
@@ -64,7 +64,7 @@ public class AnyObjectDeprovisionProcessor implements Processor {
         List<PropagationTask> tasks =
                 propagationManager.getAnyObjectDeleteTasks(anyObjectKey, new HashSet<>(resources), noPropResourceNames);
         PropagationReporter propagationReporter =
-                ApplicationContextProvider.getApplicationContext().getBean(PropagationReporter.class);
+                ApplicationContextProvider.getBeanFactory().getBean(PropagationReporter.class);
         try {
             taskExecutor.execute(tasks, propagationReporter);
         } catch (PropagationException e) {

http://git-wip-us.apache.org/repos/asf/syncope/blob/6dfedd8f/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/processor/AnyObjectProvisionProcessor.java
----------------------------------------------------------------------
diff --git a/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/processor/AnyObjectProvisionProcessor.java b/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/processor/AnyObjectProvisionProcessor.java
new file mode 100644
index 0000000..ff9466d
--- /dev/null
+++ b/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/processor/AnyObjectProvisionProcessor.java
@@ -0,0 +1,77 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.syncope.core.provisioning.camel.processor;
+
+import java.util.List;
+import org.apache.camel.Exchange;
+import org.apache.camel.Processor;
+import org.apache.syncope.common.lib.types.PropagationByResource;
+import org.apache.syncope.common.lib.types.ResourceOperation;
+import org.apache.syncope.core.misc.spring.ApplicationContextProvider;
+import org.apache.syncope.core.persistence.api.dao.AnyObjectDAO;
+import org.apache.syncope.core.persistence.api.entity.task.PropagationTask;
+import org.apache.syncope.core.provisioning.api.WorkflowResult;
+import org.apache.syncope.core.provisioning.api.propagation.PropagationException;
+import org.apache.syncope.core.provisioning.api.propagation.PropagationManager;
+import org.apache.syncope.core.provisioning.api.propagation.PropagationReporter;
+import org.apache.syncope.core.provisioning.api.propagation.PropagationTaskExecutor;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+
+@Component
+public class AnyObjectProvisionProcessor implements Processor {
+
+    private static final Logger LOG = LoggerFactory.getLogger(AnyObjectProvisionProcessor.class);
+
+    @Autowired
+    protected PropagationManager propagationManager;
+
+    @Autowired
+    protected PropagationTaskExecutor taskExecutor;
+
+    @Autowired
+    protected AnyObjectDAO anyObjectDAO;
+
+    @SuppressWarnings("unchecked")
+    @Override
+    public void process(final Exchange exchange) {
+        Long key = exchange.getIn().getBody(Long.class);
+        List<String> resources = exchange.getProperty("resources", List.class);
+
+        PropagationByResource propByRes = new PropagationByResource();
+        propByRes.addAll(ResourceOperation.UPDATE, resources);
+
+        WorkflowResult<Long> wfResult = new WorkflowResult<>(key, propByRes, "update");
+
+        List<PropagationTask> tasks = propagationManager.getAnyObjectUpdateTasks(wfResult, null, null, null);
+        PropagationReporter propagationReporter =
+                ApplicationContextProvider.getBeanFactory().getBean(PropagationReporter.class);
+        try {
+            taskExecutor.execute(tasks, propagationReporter);
+        } catch (PropagationException e) {
+            LOG.error("Error propagation primary resource", e);
+            propagationReporter.onPrimaryResourceFailure(tasks);
+        }
+
+        exchange.getOut().setBody(propagationReporter.getStatuses());
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/6dfedd8f/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/processor/AnyObjectUpdateProcessor.java
----------------------------------------------------------------------
diff --git a/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/processor/AnyObjectUpdateProcessor.java b/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/processor/AnyObjectUpdateProcessor.java
index 2979e97..04009ef 100644
--- a/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/processor/AnyObjectUpdateProcessor.java
+++ b/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/processor/AnyObjectUpdateProcessor.java
@@ -76,7 +76,7 @@ public class AnyObjectUpdateProcessor implements Processor {
         }
 
         PropagationReporter propagationReporter =
-                ApplicationContextProvider.getApplicationContext().getBean(PropagationReporter.class);
+                ApplicationContextProvider.getBeanFactory().getBean(PropagationReporter.class);
         try {
             taskExecutor.execute(tasks, propagationReporter);
         } catch (PropagationException e) {

http://git-wip-us.apache.org/repos/asf/syncope/blob/6dfedd8f/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/processor/GroupCreateProcessor.java
----------------------------------------------------------------------
diff --git a/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/processor/GroupCreateProcessor.java b/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/processor/GroupCreateProcessor.java
index 4ab62e3..0fb7058 100644
--- a/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/processor/GroupCreateProcessor.java
+++ b/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/processor/GroupCreateProcessor.java
@@ -57,7 +57,7 @@ public class GroupCreateProcessor implements Processor {
         List<PropagationTask> tasks =
                 propagationManager.getGroupCreateTasks(created, any.getVirAttrs(), excludedResource);
         PropagationReporter propagationReporter =
-                ApplicationContextProvider.getApplicationContext().getBean(PropagationReporter.class);
+                ApplicationContextProvider.getBeanFactory().getBean(PropagationReporter.class);
         try {
             taskExecutor.execute(tasks, propagationReporter);
         } catch (PropagationException e) {

http://git-wip-us.apache.org/repos/asf/syncope/blob/6dfedd8f/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/processor/GroupDeleteProcessor.java
----------------------------------------------------------------------
diff --git a/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/processor/GroupDeleteProcessor.java b/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/processor/GroupDeleteProcessor.java
index 8643f6a..00b71d4 100644
--- a/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/processor/GroupDeleteProcessor.java
+++ b/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/processor/GroupDeleteProcessor.java
@@ -90,7 +90,7 @@ public class GroupDeleteProcessor implements Processor {
         }
 
         PropagationReporter propagationReporter =
-                ApplicationContextProvider.getApplicationContext().getBean(PropagationReporter.class);
+                ApplicationContextProvider.getBeanFactory().getBean(PropagationReporter.class);
         try {
             taskExecutor.execute(tasks, propagationReporter);
         } catch (PropagationException e) {

http://git-wip-us.apache.org/repos/asf/syncope/blob/6dfedd8f/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/processor/GroupDeprovisionProcessor.java
----------------------------------------------------------------------
diff --git a/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/processor/GroupDeprovisionProcessor.java b/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/processor/GroupDeprovisionProcessor.java
index 5b21325..cd36bfb 100644
--- a/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/processor/GroupDeprovisionProcessor.java
+++ b/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/processor/GroupDeprovisionProcessor.java
@@ -40,7 +40,7 @@ import org.springframework.stereotype.Component;
 @Component
 public class GroupDeprovisionProcessor implements Processor {
 
-    private static final Logger LOG = LoggerFactory.getLogger(UserDeprovisionProcessor.class);
+    private static final Logger LOG = LoggerFactory.getLogger(GroupDeprovisionProcessor.class);
 
     @Autowired
     protected PropagationManager propagationManager;
@@ -64,7 +64,7 @@ public class GroupDeprovisionProcessor implements Processor {
         List<PropagationTask> tasks =
                 propagationManager.getGroupDeleteTasks(groupKey, new HashSet<>(resources), noPropResourceNames);
         PropagationReporter propagationReporter =
-                ApplicationContextProvider.getApplicationContext().getBean(PropagationReporter.class);
+                ApplicationContextProvider.getBeanFactory().getBean(PropagationReporter.class);
         try {
             taskExecutor.execute(tasks, propagationReporter);
         } catch (PropagationException e) {

http://git-wip-us.apache.org/repos/asf/syncope/blob/6dfedd8f/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/processor/GroupProvisionProcessor.java
----------------------------------------------------------------------
diff --git a/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/processor/GroupProvisionProcessor.java b/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/processor/GroupProvisionProcessor.java
new file mode 100644
index 0000000..23f47a7
--- /dev/null
+++ b/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/processor/GroupProvisionProcessor.java
@@ -0,0 +1,77 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.syncope.core.provisioning.camel.processor;
+
+import java.util.List;
+import org.apache.camel.Exchange;
+import org.apache.camel.Processor;
+import org.apache.syncope.common.lib.types.PropagationByResource;
+import org.apache.syncope.common.lib.types.ResourceOperation;
+import org.apache.syncope.core.misc.spring.ApplicationContextProvider;
+import org.apache.syncope.core.persistence.api.dao.GroupDAO;
+import org.apache.syncope.core.persistence.api.entity.task.PropagationTask;
+import org.apache.syncope.core.provisioning.api.WorkflowResult;
+import org.apache.syncope.core.provisioning.api.propagation.PropagationException;
+import org.apache.syncope.core.provisioning.api.propagation.PropagationManager;
+import org.apache.syncope.core.provisioning.api.propagation.PropagationReporter;
+import org.apache.syncope.core.provisioning.api.propagation.PropagationTaskExecutor;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+
+@Component
+public class GroupProvisionProcessor implements Processor {
+
+    private static final Logger LOG = LoggerFactory.getLogger(GroupProvisionProcessor.class);
+
+    @Autowired
+    protected PropagationManager propagationManager;
+
+    @Autowired
+    protected PropagationTaskExecutor taskExecutor;
+
+    @Autowired
+    protected GroupDAO groupDAO;
+
+    @SuppressWarnings("unchecked")
+    @Override
+    public void process(final Exchange exchange) {
+        Long key = exchange.getIn().getBody(Long.class);
+        List<String> resources = exchange.getProperty("resources", List.class);
+
+        PropagationByResource propByRes = new PropagationByResource();
+        propByRes.addAll(ResourceOperation.UPDATE, resources);
+
+        WorkflowResult<Long> wfResult = new WorkflowResult<>(key, propByRes, "update");
+
+        List<PropagationTask> tasks = propagationManager.getGroupUpdateTasks(wfResult, null, null, null);
+        PropagationReporter propagationReporter =
+                ApplicationContextProvider.getBeanFactory().getBean(PropagationReporter.class);
+        try {
+            taskExecutor.execute(tasks, propagationReporter);
+        } catch (PropagationException e) {
+            LOG.error("Error propagation primary resource", e);
+            propagationReporter.onPrimaryResourceFailure(tasks);
+        }
+
+        exchange.getOut().setBody(propagationReporter.getStatuses());
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/6dfedd8f/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/processor/GroupUpdateProcessor.java
----------------------------------------------------------------------
diff --git a/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/processor/GroupUpdateProcessor.java b/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/processor/GroupUpdateProcessor.java
index 2aaec2a..1bdbb6c 100644
--- a/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/processor/GroupUpdateProcessor.java
+++ b/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/processor/GroupUpdateProcessor.java
@@ -76,7 +76,7 @@ public class GroupUpdateProcessor implements Processor {
         }
 
         PropagationReporter propagationReporter =
-                ApplicationContextProvider.getApplicationContext().getBean(PropagationReporter.class);
+                ApplicationContextProvider.getBeanFactory().getBean(PropagationReporter.class);
         try {
             taskExecutor.execute(tasks, propagationReporter);
         } catch (PropagationException e) {

http://git-wip-us.apache.org/repos/asf/syncope/blob/6dfedd8f/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/processor/UserConfirmPwdResetProcessor.java
----------------------------------------------------------------------
diff --git a/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/processor/UserConfirmPwdResetProcessor.java b/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/processor/UserConfirmPwdResetProcessor.java
index f0c6851..a586f09 100644
--- a/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/processor/UserConfirmPwdResetProcessor.java
+++ b/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/processor/UserConfirmPwdResetProcessor.java
@@ -26,7 +26,6 @@ import org.apache.commons.lang3.tuple.Pair;
 import org.apache.syncope.common.lib.mod.UserMod;
 import org.apache.syncope.core.misc.spring.ApplicationContextProvider;
 import org.apache.syncope.core.persistence.api.entity.task.PropagationTask;
-import org.apache.syncope.core.persistence.api.entity.user.User;
 import org.apache.syncope.core.provisioning.api.WorkflowResult;
 import org.apache.syncope.core.provisioning.api.propagation.PropagationException;
 import org.apache.syncope.core.provisioning.api.propagation.PropagationManager;
@@ -50,10 +49,10 @@ public class UserConfirmPwdResetProcessor implements Processor {
 
     @Override
     public void process(final Exchange exchange) {
-        User user = exchange.getProperty("user", User.class);
+        Long key = exchange.getProperty("userKey", Long.class);
 
         UserMod userMod = new UserMod();
-        userMod.setKey(user.getKey());
+        userMod.setKey(key);
         userMod.setPassword(exchange.getProperty("password", String.class));
 
         List<PropagationTask> tasks = propagationManager.getUserUpdateTasks(
@@ -61,7 +60,7 @@ public class UserConfirmPwdResetProcessor implements Processor {
                         new ImmutablePair<UserMod, Boolean>(userMod, null), null, "confirmPasswordReset"),
                 true, null);
         PropagationReporter propReporter =
-                ApplicationContextProvider.getApplicationContext().getBean(PropagationReporter.class);
+                ApplicationContextProvider.getBeanFactory().getBean(PropagationReporter.class);
         try {
             taskExecutor.execute(tasks, propReporter);
         } catch (PropagationException e) {

http://git-wip-us.apache.org/repos/asf/syncope/blob/6dfedd8f/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/processor/UserCreateProcessor.java
----------------------------------------------------------------------
diff --git a/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/processor/UserCreateProcessor.java b/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/processor/UserCreateProcessor.java
index 791a32a..ea06c9d 100644
--- a/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/processor/UserCreateProcessor.java
+++ b/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/processor/UserCreateProcessor.java
@@ -65,7 +65,7 @@ public class UserCreateProcessor implements Processor {
                     actual.getVirAttrs(),
                     excludedResources);
             PropagationReporter propagationReporter =
-                    ApplicationContextProvider.getApplicationContext().getBean(PropagationReporter.class);
+                    ApplicationContextProvider.getBeanFactory().getBean(PropagationReporter.class);
             try {
                 taskExecutor.execute(tasks, propagationReporter);
             } catch (PropagationException e) {

http://git-wip-us.apache.org/repos/asf/syncope/blob/6dfedd8f/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/processor/UserDeleteProcessor.java
----------------------------------------------------------------------
diff --git a/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/processor/UserDeleteProcessor.java b/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/processor/UserDeleteProcessor.java
index 8d94d76..b6218a9 100644
--- a/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/processor/UserDeleteProcessor.java
+++ b/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/processor/UserDeleteProcessor.java
@@ -58,7 +58,7 @@ public class UserDeleteProcessor implements Processor {
         List<PropagationTask> tasks = propagationManager.getUserDeleteTasks(userKey, excludedResource);
 
         PropagationReporter propagationReporter =
-                ApplicationContextProvider.getApplicationContext().getBean(PropagationReporter.class);
+                ApplicationContextProvider.getBeanFactory().getBean(PropagationReporter.class);
         try {
             taskExecutor.execute(tasks, propagationReporter);
         } catch (PropagationException e) {

http://git-wip-us.apache.org/repos/asf/syncope/blob/6dfedd8f/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/processor/UserDeprovisionProcessor.java
----------------------------------------------------------------------
diff --git a/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/processor/UserDeprovisionProcessor.java b/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/processor/UserDeprovisionProcessor.java
index 3060569..642870a 100644
--- a/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/processor/UserDeprovisionProcessor.java
+++ b/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/processor/UserDeprovisionProcessor.java
@@ -63,7 +63,7 @@ public class UserDeprovisionProcessor implements Processor {
                 new HashSet<>(resources),
                 CollectionUtils.removeAll(userDAO.findAllResourceNames(user), resources));
         PropagationReporter propagationReporter =
-                ApplicationContextProvider.getApplicationContext().getBean(PropagationReporter.class);
+                ApplicationContextProvider.getBeanFactory().getBean(PropagationReporter.class);
         try {
             taskExecutor.execute(tasks, propagationReporter);
         } catch (PropagationException e) {

http://git-wip-us.apache.org/repos/asf/syncope/blob/6dfedd8f/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/processor/UserProvisionProcessor.java
----------------------------------------------------------------------
diff --git a/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/processor/UserProvisionProcessor.java b/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/processor/UserProvisionProcessor.java
new file mode 100644
index 0000000..f85c373
--- /dev/null
+++ b/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/processor/UserProvisionProcessor.java
@@ -0,0 +1,98 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.syncope.core.provisioning.camel.processor;
+
+import java.util.List;
+import org.apache.camel.Exchange;
+import org.apache.camel.Processor;
+import org.apache.commons.lang3.tuple.ImmutablePair;
+import org.apache.commons.lang3.tuple.Pair;
+import org.apache.syncope.common.lib.mod.StatusMod;
+import org.apache.syncope.common.lib.mod.UserMod;
+import org.apache.syncope.common.lib.types.PropagationByResource;
+import org.apache.syncope.common.lib.types.ResourceOperation;
+import org.apache.syncope.core.misc.spring.ApplicationContextProvider;
+import org.apache.syncope.core.persistence.api.dao.UserDAO;
+import org.apache.syncope.core.persistence.api.entity.task.PropagationTask;
+import org.apache.syncope.core.provisioning.api.WorkflowResult;
+import org.apache.syncope.core.provisioning.api.propagation.PropagationException;
+import org.apache.syncope.core.provisioning.api.propagation.PropagationManager;
+import org.apache.syncope.core.provisioning.api.propagation.PropagationReporter;
+import org.apache.syncope.core.provisioning.api.propagation.PropagationTaskExecutor;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+
+@Component
+public class UserProvisionProcessor implements Processor {
+
+    private static final Logger LOG = LoggerFactory.getLogger(UserProvisionProcessor.class);
+
+    @Autowired
+    protected PropagationManager propagationManager;
+
+    @Autowired
+    protected PropagationTaskExecutor taskExecutor;
+
+    @Autowired
+    protected UserDAO userDAO;
+
+    @Override
+    public void process(final Exchange exchange) {
+        Long key = exchange.getIn().getBody(Long.class);
+        Boolean changePwd = exchange.getProperty("changePwd", Boolean.class);
+        String password = exchange.getProperty("password", String.class);
+        @SuppressWarnings("unchecked")
+        List<String> resources = exchange.getProperty("resources", List.class);
+
+        UserMod userMod = new UserMod();
+        userMod.setKey(key);
+        userMod.getResourcesToAdd().addAll(resources);
+
+        if (changePwd) {
+            StatusMod statusMod = new StatusMod();
+            statusMod.setOnSyncope(false);
+            statusMod.getResourceNames().addAll(resources);
+            userMod.setPwdPropRequest(statusMod);
+            userMod.setPassword(password);
+        }
+
+        PropagationByResource propByRes = new PropagationByResource();
+        for (String resource : resources) {
+            propByRes.add(ResourceOperation.UPDATE, resource);
+        }
+
+        WorkflowResult<Pair<UserMod, Boolean>> wfResult = new WorkflowResult<Pair<UserMod, Boolean>>(
+                ImmutablePair.of(userMod, (Boolean) null), propByRes, "update");
+
+        List<PropagationTask> tasks = propagationManager.getUserUpdateTasks(wfResult, changePwd, null);
+        PropagationReporter propagationReporter =
+                ApplicationContextProvider.getBeanFactory().getBean(PropagationReporter.class);
+        try {
+            taskExecutor.execute(tasks, propagationReporter);
+        } catch (PropagationException e) {
+            LOG.error("Error propagation primary resource", e);
+            propagationReporter.onPrimaryResourceFailure(tasks);
+        }
+
+        exchange.getOut().setBody(propagationReporter.getStatuses());
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/6dfedd8f/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/processor/UserSetStatusInSyncProcessor.java
----------------------------------------------------------------------
diff --git a/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/processor/UserSetStatusInSyncProcessor.java b/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/processor/UserSetStatusInSyncProcessor.java
index cf9d709..75ab027 100644
--- a/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/processor/UserSetStatusInSyncProcessor.java
+++ b/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/processor/UserSetStatusInSyncProcessor.java
@@ -44,7 +44,7 @@ public class UserSetStatusInSyncProcessor implements Processor {
         WorkflowResult<Map.Entry<UserMod, Boolean>> updated = (WorkflowResult) exchange.getIn().getBody();
 
         Boolean enabled = exchange.getProperty("enabled", Boolean.class);
-        Long key = exchange.getProperty("key", Long.class);
+        Long key = exchange.getProperty("userKey", Long.class);
 
         if (enabled != null) {
             User user = userDAO.find(key);

http://git-wip-us.apache.org/repos/asf/syncope/blob/6dfedd8f/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/processor/UserStatusPropagationProcessor.java
----------------------------------------------------------------------
diff --git a/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/processor/UserStatusPropagationProcessor.java b/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/processor/UserStatusPropagationProcessor.java
index cb0bb82..cbc8fb7 100644
--- a/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/processor/UserStatusPropagationProcessor.java
+++ b/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/processor/UserStatusPropagationProcessor.java
@@ -28,7 +28,6 @@ import org.apache.syncope.common.lib.mod.StatusMod;
 import org.apache.syncope.core.misc.spring.ApplicationContextProvider;
 import org.apache.syncope.core.persistence.api.dao.UserDAO;
 import org.apache.syncope.core.persistence.api.entity.task.PropagationTask;
-import org.apache.syncope.core.persistence.api.entity.user.User;
 import org.apache.syncope.core.provisioning.api.WorkflowResult;
 import org.apache.syncope.core.provisioning.api.propagation.PropagationException;
 import org.apache.syncope.core.provisioning.api.propagation.PropagationManager;
@@ -52,22 +51,22 @@ public class UserStatusPropagationProcessor implements Processor {
 
     @Autowired
     protected UserDAO userDAO;
-    
+
     @SuppressWarnings("unchecked")
     @Override
     public void process(final Exchange exchange) {
         WorkflowResult<Long> updated = (WorkflowResult) exchange.getIn().getBody();
 
-        User user = exchange.getProperty("user", User.class);
+        Long key = exchange.getProperty("userKey", Long.class);
         StatusMod statusMod = exchange.getProperty("statusMod", StatusMod.class);
 
-        Collection<String> resourcesToBeExcluded =
-                CollectionUtils.removeAll(userDAO.findAllResourceNames(user), statusMod.getResourceNames());
+        Collection<String> resourcesToBeExcluded = CollectionUtils.removeAll(
+                userDAO.findAllResourceNames(userDAO.find(key)), statusMod.getResourceNames());
 
         List<PropagationTask> tasks = propagationManager.getUserUpdateTasks(
-                user, statusMod.getType() != StatusMod.ModType.SUSPEND, resourcesToBeExcluded);
+                key, statusMod.getType() != StatusMod.ModType.SUSPEND, resourcesToBeExcluded);
         PropagationReporter propReporter =
-                ApplicationContextProvider.getApplicationContext().getBean(PropagationReporter.class);
+                ApplicationContextProvider.getBeanFactory().getBean(PropagationReporter.class);
         try {
             taskExecutor.execute(tasks, propReporter);
         } catch (PropagationException e) {

http://git-wip-us.apache.org/repos/asf/syncope/blob/6dfedd8f/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/processor/UserUpdateInSyncProcessor.java
----------------------------------------------------------------------
diff --git a/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/processor/UserUpdateInSyncProcessor.java b/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/processor/UserUpdateInSyncProcessor.java
index 829999f..dcd271d 100644
--- a/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/processor/UserUpdateInSyncProcessor.java
+++ b/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/processor/UserUpdateInSyncProcessor.java
@@ -55,7 +55,7 @@ public class UserUpdateInSyncProcessor implements Processor {
         Set<String> excludedResources = exchange.getProperty("excludedResources", Set.class);
 
         PropagationReporter propagationReporter =
-                ApplicationContextProvider.getApplicationContext().getBean(PropagationReporter.class);
+                ApplicationContextProvider.getBeanFactory().getBean(PropagationReporter.class);
 
         List<PropagationTask> tasks = propagationManager.getUserUpdateTasks(updated, updated.getResult().getKey().
                 getPassword() != null, excludedResources);

http://git-wip-us.apache.org/repos/asf/syncope/blob/6dfedd8f/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/processor/UserUpdateProcessor.java
----------------------------------------------------------------------
diff --git a/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/processor/UserUpdateProcessor.java b/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/processor/UserUpdateProcessor.java
index e71a15a..1dc19f5 100644
--- a/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/processor/UserUpdateProcessor.java
+++ b/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/processor/UserUpdateProcessor.java
@@ -74,7 +74,7 @@ public class UserUpdateProcessor implements Processor {
         }
 
         PropagationReporter propagationReporter =
-                ApplicationContextProvider.getApplicationContext().getBean(PropagationReporter.class);
+                ApplicationContextProvider.getBeanFactory().getBean(PropagationReporter.class);
         if (!tasks.isEmpty()) {
             try {
                 taskExecutor.execute(tasks, propagationReporter);

http://git-wip-us.apache.org/repos/asf/syncope/blob/6dfedd8f/ext/camel/provisioning-camel/src/main/resources/anyObjectRoutes.xml
----------------------------------------------------------------------
diff --git a/ext/camel/provisioning-camel/src/main/resources/anyObjectRoutes.xml b/ext/camel/provisioning-camel/src/main/resources/anyObjectRoutes.xml
index de4df0b..9cbde16 100644
--- a/ext/camel/provisioning-camel/src/main/resources/anyObjectRoutes.xml
+++ b/ext/camel/provisioning-camel/src/main/resources/anyObjectRoutes.xml
@@ -112,6 +112,12 @@ under the License.
     </doTry>            
   </route>
         
+  <route id="provisionAnyObject">
+    <from uri="direct:provisionAnyObject"/>            
+    <process ref="anyObjectProvisionProcessor"/>
+    <to uri="direct:provisionAnyObjectPort"/>              
+  </route>
+
   <route id="deprovisionAnyObject">
     <from uri="direct:deprovisionAnyObject"/>            
     <process ref="anyObjectDeprovisionProcessor"/>

http://git-wip-us.apache.org/repos/asf/syncope/blob/6dfedd8f/ext/camel/provisioning-camel/src/main/resources/groupRoutes.xml
----------------------------------------------------------------------
diff --git a/ext/camel/provisioning-camel/src/main/resources/groupRoutes.xml b/ext/camel/provisioning-camel/src/main/resources/groupRoutes.xml
index f897f90..ac64345 100644
--- a/ext/camel/provisioning-camel/src/main/resources/groupRoutes.xml
+++ b/ext/camel/provisioning-camel/src/main/resources/groupRoutes.xml
@@ -131,6 +131,12 @@ under the License.
     </doTry>            
   </route>
         
+  <route id="provisionGroup">
+    <from uri="direct:provisionGroup"/>            
+    <process ref="groupProvisionProcessor"/>
+    <to uri="direct:provisionGroupPort"/>              
+  </route>
+
   <route id="deprovisionGroup">
     <from uri="direct:deprovisionGroup"/>            
     <process ref="groupDeprovisionProcessor"/>

http://git-wip-us.apache.org/repos/asf/syncope/blob/6dfedd8f/ext/camel/provisioning-camel/src/main/resources/userRoutes.xml
----------------------------------------------------------------------
diff --git a/ext/camel/provisioning-camel/src/main/resources/userRoutes.xml b/ext/camel/provisioning-camel/src/main/resources/userRoutes.xml
index 06e68d1..aca6a46 100644
--- a/ext/camel/provisioning-camel/src/main/resources/userRoutes.xml
+++ b/ext/camel/provisioning-camel/src/main/resources/userRoutes.xml
@@ -185,7 +185,13 @@ under the License.
     <process ref="userStatusPropagationProcessor"/>
     <to uri="direct:statusPort"/> 
   </route>
-        
+    
+  <route id="provisionUser">
+    <from uri="direct:provisionUser"/>            
+    <process ref="userProvisionProcessor"/>
+    <to uri="direct:provisionPort"/>              
+  </route>
+                
   <route id="deprovisionUser">
     <from uri="direct:deprovisionUser"/>            
     <process ref="userDeprovisionProcessor"/>

http://git-wip-us.apache.org/repos/asf/syncope/blob/6dfedd8f/fit/core-reference/pom.xml
----------------------------------------------------------------------
diff --git a/fit/core-reference/pom.xml b/fit/core-reference/pom.xml
index 166a394..d7e27dc 100644
--- a/fit/core-reference/pom.xml
+++ b/fit/core-reference/pom.xml
@@ -261,7 +261,7 @@ under the License.
             </deployable>
             <deployable>
               <location>${project.build.directory}/${project.build.finalName}</location>
-              <pingURL>http://localhost:${cargo.servlet.port}/syncope/db.jsp</pingURL>
+              <pingURL>http://localhost:${cargo.servlet.port}/syncope/cacheStats.jsp</pingURL>
               <pingTimeout>60000</pingTimeout>
               <properties>
                 <context>syncope</context>
@@ -310,14 +310,18 @@ under the License.
         <filtering>true</filtering>
       </resource>
       <resource>
-        <directory>${basedir}/../../core/persistence-jpa/src/test/resources</directory>
+        <directory>${basedir}/../../core/persistence-jpa/src/main/resources</directory>
         <includes>
-          <include>content.xml</include>
           <include>persistence.properties</include>
         </includes>
         <filtering>true</filtering>
       </resource>
       <resource>
+        <directory>${basedir}/../../core/persistence-jpa/src/test/resources/domains</directory>
+        <targetPath>${project.build.directory}/classes/domains</targetPath>
+        <filtering>true</filtering>
+      </resource>
+      <resource>
         <directory>${basedir}/../../core/misc/src/main/resources</directory>
         <includes>
           <include>security.properties</include>
@@ -803,7 +807,7 @@ under the License.
                 <transformationSet>
                   <dir>${project.build.directory}/classes</dir>
                   <includes>
-                    <include>content.xml</include>
+                    <include>domains/MasterContent.xml</include>
                   </includes>
                   <outputDir>${project.build.directory}/classes</outputDir>
                   <stylesheet>${basedir}/src/test/resources/addActivitiToContent.xsl</stylesheet>

http://git-wip-us.apache.org/repos/asf/syncope/blob/6dfedd8f/fit/core-reference/src/main/java/org/apache/syncope/fit/core/reference/TestSampleJob.java
----------------------------------------------------------------------
diff --git a/fit/core-reference/src/main/java/org/apache/syncope/fit/core/reference/TestSampleJob.java b/fit/core-reference/src/main/java/org/apache/syncope/fit/core/reference/TestSampleJob.java
deleted file mode 100644
index a8f7184..0000000
--- a/fit/core-reference/src/main/java/org/apache/syncope/fit/core/reference/TestSampleJob.java
+++ /dev/null
@@ -1,64 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.syncope.fit.core.reference;
-
-import java.util.Date;
-import org.apache.syncope.core.persistence.api.entity.task.SchedTask;
-import org.apache.syncope.core.persistence.api.entity.task.TaskExec;
-import org.apache.syncope.core.provisioning.java.job.AbstractTaskJob;
-import org.quartz.JobExecutionException;
-
-/**
- * Sample implementation for execution a scheduled task.
- *
- * @see SchedTask
- */
-public class TestSampleJob extends AbstractTaskJob {
-
-    @Override
-    protected String doExecute(final boolean dryRun) throws JobExecutionException {
-        if (!(task instanceof SchedTask)) {
-            throw new JobExecutionException("Task " + taskId + " isn't a SchedTask");
-        }
-
-        for (int i = 0; i < 10; i++) {
-            LOG.debug("TestSampleJob#doExecute round {} time {}", i, new Date().toString());
-            try {
-                Thread.sleep(1000);
-            } catch (InterruptedException ex) {
-                throw new JobExecutionException("Job interrupted");
-            }
-        }
-
-        final SchedTask schedTask = (SchedTask) this.task;
-
-        LOG.info("TestSampleJob {}running [SchedTask {}]", (dryRun
-                ? "dry "
-                : ""), schedTask.getKey());
-
-        return (dryRun
-                ? "DRY "
-                : "") + "RUNNING";
-    }
-
-    @Override
-    protected boolean hasToBeRegistered(final TaskExec execution) {
-        return true;
-    }
-}

http://git-wip-us.apache.org/repos/asf/syncope/blob/6dfedd8f/fit/core-reference/src/main/java/org/apache/syncope/fit/core/reference/TestSampleJobDelegate.java
----------------------------------------------------------------------
diff --git a/fit/core-reference/src/main/java/org/apache/syncope/fit/core/reference/TestSampleJobDelegate.java b/fit/core-reference/src/main/java/org/apache/syncope/fit/core/reference/TestSampleJobDelegate.java
new file mode 100644
index 0000000..1c58a04
--- /dev/null
+++ b/fit/core-reference/src/main/java/org/apache/syncope/fit/core/reference/TestSampleJobDelegate.java
@@ -0,0 +1,64 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.syncope.fit.core.reference;
+
+import java.util.Date;
+import org.apache.syncope.core.persistence.api.entity.task.SchedTask;
+import org.apache.syncope.core.persistence.api.entity.task.TaskExec;
+import org.apache.syncope.core.provisioning.java.job.AbstractSchedTaskJobDelegate;
+import org.quartz.JobExecutionException;
+
+/**
+ * Sample implementation for execution a scheduled task.
+ *
+ * @see SchedTask
+ */
+public class TestSampleJobDelegate extends AbstractSchedTaskJobDelegate {
+
+    @Override
+    protected String doExecute(final boolean dryRun) throws JobExecutionException {
+        if (!(task instanceof SchedTask)) {
+            throw new JobExecutionException("Task " + task.getKey() + " isn't a SchedTask");
+        }
+
+        for (int i = 0; i < 10; i++) {
+            LOG.debug("TestSampleJob#doExecute round {} time {}", i, new Date().toString());
+            try {
+                Thread.sleep(1000);
+            } catch (InterruptedException ex) {
+                throw new JobExecutionException("Job interrupted");
+            }
+        }
+
+        final SchedTask schedTask = (SchedTask) this.task;
+
+        LOG.info("TestSampleJob {}running [SchedTask {}]", (dryRun
+                ? "dry "
+                : ""), schedTask.getKey());
+
+        return (dryRun
+                ? "DRY "
+                : "") + "RUNNING";
+    }
+
+    @Override
+    protected boolean hasToBeRegistered(final TaskExec execution) {
+        return true;
+    }
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/6dfedd8f/fit/core-reference/src/main/resources/all/provisioning.properties
----------------------------------------------------------------------
diff --git a/fit/core-reference/src/main/resources/all/provisioning.properties b/fit/core-reference/src/main/resources/all/provisioning.properties
index 4d0ecaf..015ca72 100644
--- a/fit/core-reference/src/main/resources/all/provisioning.properties
+++ b/fit/core-reference/src/main/resources/all/provisioning.properties
@@ -18,4 +18,8 @@ camel.directory=${conf.directory}
 userProvisioningManager=org.apache.syncope.core.provisioning.camel.CamelUserProvisioningManager
 groupProvisioningManager=org.apache.syncope.core.provisioning.camel.CamelGroupProvisioningManager
 anyObjectProvisioningManager=org.apache.syncope.core.provisioning.java.DefaultAnyObjectProvisioningManager
-virAttrCache=org.apache.syncope.core.provisioning.java.cache.MemoryVirAttrCache
\ No newline at end of file
+virAttrCache=org.apache.syncope.core.provisioning.java.cache.MemoryVirAttrCache
+
+quartz.jobstore=org.quartz.impl.jdbcjobstore.StdJDBCDelegate
+quartz.sql=tables_h2.sql
+quartz.scheduler.idleWaitTime=5000

http://git-wip-us.apache.org/repos/asf/syncope/blob/6dfedd8f/fit/core-reference/src/main/resources/coreContext.xml
----------------------------------------------------------------------
diff --git a/fit/core-reference/src/main/resources/coreContext.xml b/fit/core-reference/src/main/resources/coreContext.xml
index bbc4c4f..ecdb57d 100644
--- a/fit/core-reference/src/main/resources/coreContext.xml
+++ b/fit/core-reference/src/main/resources/coreContext.xml
@@ -29,6 +29,7 @@ under the License.
     <property name="locations">
       <list>
         <value>file:${conf.directory}/persistence.properties</value>
+        <value>file:${conf.directory}/domains/*.properties</value>
         <value>file:${conf.directory}/security.properties</value>
         <value>file:${conf.directory}/connid.properties</value>
         <value>file:${conf.directory}/mail.properties</value>
@@ -42,6 +43,7 @@ under the License.
     <property name="locations">
       <list>
         <value>classpath:persistence.properties</value>
+        <value>classpath:domains/*.properties</value>
         <value>classpath:security.properties</value>
         <value>classpath:connid.properties</value>
         <value>classpath:mail.properties</value>

http://git-wip-us.apache.org/repos/asf/syncope/blob/6dfedd8f/fit/core-reference/src/main/resources/log4j2.xml
----------------------------------------------------------------------
diff --git a/fit/core-reference/src/main/resources/log4j2.xml b/fit/core-reference/src/main/resources/log4j2.xml
index 46d15f5..b50d9cb 100644
--- a/fit/core-reference/src/main/resources/log4j2.xml
+++ b/fit/core-reference/src/main/resources/log4j2.xml
@@ -21,8 +21,8 @@ under the License.
 
   <appenders>
     
-    <RollingRandomAccessFile name="main" fileName="${log.directory}/server.log"
-                             filePattern="${log.directory}/server-%d{yyyy-MM-dd}.log.gz"
+    <RollingRandomAccessFile name="main" fileName="${log.directory}/core.log"
+                             filePattern="${log.directory}/core-%d{yyyy-MM-dd}.log.gz"
                              immediateFlush="false" append="true">
       <PatternLayout>
         <pattern>%d{HH:mm:ss.SSS} %-5level %logger - %msg%n</pattern>
@@ -33,8 +33,8 @@ under the License.
       </Policies>
     </RollingRandomAccessFile>
 
-    <RollingRandomAccessFile name="persistence" fileName="${log.directory}/server-persistence.log"
-                             filePattern="${log.directory}/server-persistence-%d{yyyy-MM-dd}.log.gz"
+    <RollingRandomAccessFile name="persistence" fileName="${log.directory}/core-persistence.log"
+                             filePattern="${log.directory}/core-persistence-%d{yyyy-MM-dd}.log.gz"
                              immediateFlush="false" append="true">
       <PatternLayout>
         <pattern>%d{HH:mm:ss.SSS} %-5level %logger - %msg%n</pattern>
@@ -45,8 +45,8 @@ under the License.
       </Policies>
     </RollingRandomAccessFile>
 
-    <RollingRandomAccessFile name="rest" fileName="${log.directory}/server-rest.log"
-                             filePattern="${log.directory}/server-rest-%d{yyyy-MM-dd}.log.gz"
+    <RollingRandomAccessFile name="rest" fileName="${log.directory}/core-rest.log"
+                             filePattern="${log.directory}/core-rest-%d{yyyy-MM-dd}.log.gz"
                              immediateFlush="false" append="true">
       <PatternLayout>
         <pattern>%d{HH:mm:ss.SSS} %-5level %logger - %msg%n</pattern>
@@ -57,8 +57,8 @@ under the License.
       </Policies>
     </RollingRandomAccessFile>
 
-    <RollingRandomAccessFile name="connid" fileName="${log.directory}/server-connid.log"
-                             filePattern="${log.directory}/server-connid-%d{yyyy-MM-dd}.log.gz"
+    <RollingRandomAccessFile name="connid" fileName="${log.directory}/core-connid.log"
+                             filePattern="${log.directory}/core-connid-%d{yyyy-MM-dd}.log.gz"
                              immediateFlush="false" append="true">
       <PatternLayout>
         <pattern>%d{HH:mm:ss.SSS} %-5level %msg%n</pattern>
@@ -68,17 +68,7 @@ under the License.
         <SizeBasedTriggeringPolicy size="250 MB"/>
       </Policies>
     </RollingRandomAccessFile>
-
-    <!-- Audit -->    
-    <Jdbc name="audit" tableName="SYNCOPEAUDIT">
-      <ConnectionFactory class="org.apache.syncope.core.logic.audit.AuditConnectionFactory" method="getConnection"/>
-      <Column name="EVENT_DATE" isEventTimestamp="true"/>
-      <Column name="LOGGER_LEVEL" pattern="%level" isUnicode="false"/>
-      <Column name="LOGGER" pattern="%logger" isUnicode="false"/>
-      <Column name="MESSAGE" pattern="%message" isUnicode="false"/>
-      <Column name="THROWABLE" pattern="%ex{full}" isUnicode="false"/>
-    </Jdbc>
-
+    
   </appenders>
   
   <loggers>
@@ -122,13 +112,12 @@ under the License.
     <asyncLogger name="org.springframework" additivity="false" level="INFO">
       <appender-ref ref="main"/>
     </asyncLogger>
+    <asyncLogger name="org.quartz" additivity="false" level="INFO">
+      <appender-ref ref="main"/>
+    </asyncLogger>
     <asyncLogger name="org.apache.camel" additivity="false" level="ERROR">
       <appender-ref ref="main"/>
     </asyncLogger>
-         
-    <logger name="syncope.audit" additivity="false" level="DEBUG">
-      <appender-ref ref="audit"/>
-    </logger>
     
     <root level="INFO">
       <appender-ref ref="main"/>

http://git-wip-us.apache.org/repos/asf/syncope/blob/6dfedd8f/fit/core-reference/src/main/resources/provisioning.properties
----------------------------------------------------------------------
diff --git a/fit/core-reference/src/main/resources/provisioning.properties b/fit/core-reference/src/main/resources/provisioning.properties
index af1dd4b..a67787f 100644
--- a/fit/core-reference/src/main/resources/provisioning.properties
+++ b/fit/core-reference/src/main/resources/provisioning.properties
@@ -18,3 +18,7 @@ userProvisioningManager=org.apache.syncope.core.provisioning.java.DefaultUserPro
 groupProvisioningManager=org.apache.syncope.core.provisioning.java.DefaultGroupProvisioningManager
 anyObjectProvisioningManager=org.apache.syncope.core.provisioning.java.DefaultAnyObjectProvisioningManager
 virAttrCache=org.apache.syncope.core.provisioning.java.cache.MemoryVirAttrCache
+
+quartz.jobstore=org.quartz.impl.jdbcjobstore.StdJDBCDelegate
+quartz.sql=tables_h2.sql
+quartz.scheduler.idleWaitTime=5000
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/syncope/blob/6dfedd8f/fit/core-reference/src/main/webapp/cacheStats.jsp
----------------------------------------------------------------------
diff --git a/fit/core-reference/src/main/webapp/cacheStats.jsp b/fit/core-reference/src/main/webapp/cacheStats.jsp
index 4e4bf1b..ba380c5 100644
--- a/fit/core-reference/src/main/webapp/cacheStats.jsp
+++ b/fit/core-reference/src/main/webapp/cacheStats.jsp
@@ -16,6 +16,7 @@ KIND, either express or implied.  See the License for the
 specific language governing permissions and limitations
 under the License.
 --%>
+<%@page import="org.springframework.beans.factory.support.DefaultListableBeanFactory"%>
 <%@page import="org.apache.syncope.common.lib.SyncopeConstants"%>
 <%@page import="org.apache.syncope.core.misc.spring.ApplicationContextProvider"%>
 <%@page contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
@@ -72,9 +73,9 @@ under the License.
   <body>
     <p/>
     <%
-        ConfigurableApplicationContext context = ApplicationContextProvider.getApplicationContext();
+        DefaultListableBeanFactory beanFactory = ApplicationContextProvider.getBeanFactory();
 
-        EntityManagerFactory emf = context.getBean(EntityManagerFactory.class);
+        EntityManagerFactory emf = beanFactory.getBean("MasterEntityManagerFactory", EntityManagerFactory.class);
         OpenJPAEntityManagerFactory oemf = OpenJPAPersistence.cast(emf);
 
         QueryStatistics<QueryKey> queryStatistics =

http://git-wip-us.apache.org/repos/asf/syncope/blob/6dfedd8f/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/AnyTypeITCase.java
----------------------------------------------------------------------
diff --git a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/AnyTypeITCase.java b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/AnyTypeITCase.java
index 9fdc1e4..58b1004 100644
--- a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/AnyTypeITCase.java
+++ b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/AnyTypeITCase.java
@@ -18,7 +18,6 @@
  */
 package org.apache.syncope.fit.core.reference;
 
-import static org.apache.syncope.fit.core.reference.AbstractITCase.getUUIDString;
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertFalse;
 import static org.junit.Assert.assertNotNull;

http://git-wip-us.apache.org/repos/asf/syncope/blob/6dfedd8f/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/AuthenticationITCase.java
----------------------------------------------------------------------
diff --git a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/AuthenticationITCase.java b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/AuthenticationITCase.java
index a756401..9d810b6 100644
--- a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/AuthenticationITCase.java
+++ b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/AuthenticationITCase.java
@@ -258,17 +258,17 @@ public class AuthenticationITCase extends AbstractITCase {
         assertEquals(0, getFailedLogins(userService4, userId));
     }
 
-    @Test
+    //@Test
     public void checkUserSuspension() {
         UserTO userTO = UserITCase.getUniqueSampleTO("checkSuspension@syncope.apache.org");
         userTO.setRealm("/odd");
         userTO.getRoles().add(2L);
 
         userTO = createUser(userTO);
-        long userId = userTO.getKey();
+        long userKey = userTO.getKey();
         assertNotNull(userTO);
 
-        assertEquals(0, getFailedLogins(userService, userId));
+        assertEquals(0, getFailedLogins(userService, userKey));
 
         // authentications failed ...
         SyncopeClient badPwdClient = clientFactory.create(userTO.getUsername(), "wrongpwd1");
@@ -276,7 +276,7 @@ public class AuthenticationITCase extends AbstractITCase {
         assertReadFails(badPwdClient);
         assertReadFails(badPwdClient);
 
-        assertEquals(3, getFailedLogins(userService, userId));
+        assertEquals(3, getFailedLogins(userService, userKey));
 
         // last authentication before suspension
         assertReadFails(badPwdClient);
@@ -352,7 +352,7 @@ public class AuthenticationITCase extends AbstractITCase {
         assertNotNull(user);
 
         // 2. unlink the resource from the created user
-        assertNotNull(userService.bulkDeassociation(user.getKey(),
+        assertNotNull(userService.deassociate(user.getKey(),
                 ResourceDeassociationActionType.UNLINK,
                 CollectionWrapper.wrap(RESOURCE_NAME_TESTDB, ResourceKey.class)).
                 readEntity(BulkActionResult.class));

http://git-wip-us.apache.org/repos/asf/syncope/blob/6dfedd8f/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/CamelRouteITCase.java
----------------------------------------------------------------------
diff --git a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/CamelRouteITCase.java b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/CamelRouteITCase.java
index 1a086e2..1904baf 100644
--- a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/CamelRouteITCase.java
+++ b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/CamelRouteITCase.java
@@ -18,7 +18,6 @@
  */
 package org.apache.syncope.fit.core.reference;
 
-import static org.apache.syncope.fit.core.reference.AbstractITCase.anyTypeClassService;
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertNotNull;
 
@@ -46,7 +45,7 @@ public class CamelRouteITCase extends AbstractITCase {
 
         List<CamelRouteTO> userRoutes = camelRouteService.list(AnyTypeKind.USER);
         assertNotNull(userRoutes);
-        assertEquals(15, userRoutes.size());
+        assertEquals(16, userRoutes.size());
         for (CamelRouteTO route : userRoutes) {
             assertNotNull(route.getContent());
         }
@@ -58,7 +57,7 @@ public class CamelRouteITCase extends AbstractITCase {
 
         List<CamelRouteTO> groupRoutes = camelRouteService.list(AnyTypeKind.GROUP);
         assertNotNull(groupRoutes);
-        assertEquals(7, groupRoutes.size());
+        assertEquals(8, groupRoutes.size());
         for (CamelRouteTO route : groupRoutes) {
             assertNotNull(route.getContent());
         }

http://git-wip-us.apache.org/repos/asf/syncope/blob/6dfedd8f/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/ConnectorITCase.java
----------------------------------------------------------------------
diff --git a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/ConnectorITCase.java b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/ConnectorITCase.java
index 60842b9..583e3d9 100644
--- a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/ConnectorITCase.java
+++ b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/ConnectorITCase.java
@@ -686,7 +686,7 @@ public class ConnectorITCase extends AbstractITCase {
     @Test
     public void bulkAction() {
         final BulkAction bulkAction = new BulkAction();
-        bulkAction.setOperation(BulkAction.Type.DELETE);
+        bulkAction.setType(BulkAction.Type.DELETE);
 
         ConnInstanceTO conn = connectorService.read(101L);
 

http://git-wip-us.apache.org/repos/asf/syncope/blob/6dfedd8f/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/ExceptionMapperITCase.java
----------------------------------------------------------------------
diff --git a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/ExceptionMapperITCase.java b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/ExceptionMapperITCase.java
index ae823e1..924a24b 100644
--- a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/ExceptionMapperITCase.java
+++ b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/ExceptionMapperITCase.java
@@ -18,7 +18,6 @@
  */
 package org.apache.syncope.fit.core.reference;
 
-import static org.apache.syncope.fit.core.reference.AbstractITCase.anyTypeClassService;
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.fail;
 
@@ -105,7 +104,7 @@ public class ExceptionMapperITCase extends AbstractITCase {
             fail();
         } catch (Exception e) {
             String message = ERROR_MESSAGES.getProperty("errMessage.UniqueConstraintViolation");
-            assertEquals(e.getMessage(), "DataIntegrityViolation [" + message + "]");
+            assertEquals("EntityExists [" + message + "]", e.getMessage());
         }
     }
 

http://git-wip-us.apache.org/repos/asf/syncope/blob/6dfedd8f/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/GroupITCase.java
----------------------------------------------------------------------
diff --git a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/GroupITCase.java b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/GroupITCase.java
index 855f25b..7fece69 100644
--- a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/GroupITCase.java
+++ b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/GroupITCase.java
@@ -60,7 +60,7 @@ import org.apache.syncope.common.lib.types.AnyTypeKind;
 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.ResourceAssociationAction;
 import org.apache.syncope.common.lib.types.ResourceDeassociationActionType;
 import org.apache.syncope.common.lib.types.SchemaType;
 import org.apache.syncope.common.lib.wrap.ResourceKey;
@@ -323,7 +323,7 @@ public class GroupITCase extends AbstractITCase {
 
         assertNotNull(resourceService.readConnObject(RESOURCE_NAME_LDAP, AnyTypeKind.GROUP.name(), actual.getKey()));
 
-        assertNotNull(groupService.bulkDeassociation(actual.getKey(),
+        assertNotNull(groupService.deassociate(actual.getKey(),
                 ResourceDeassociationActionType.UNLINK,
                 CollectionWrapper.wrap(RESOURCE_NAME_LDAP, ResourceKey.class)).
                 readEntity(BulkActionResult.class));
@@ -352,7 +352,7 @@ public class GroupITCase extends AbstractITCase {
 
         ResourceAssociationMod associationMod = new ResourceAssociationMod();
         associationMod.getTargetResources().addAll(CollectionWrapper.wrap(RESOURCE_NAME_LDAP, ResourceKey.class));
-        assertNotNull(groupService.bulkAssociation(actual.getKey(), ResourceAssociationActionType.LINK, associationMod).
+        assertNotNull(groupService.associate(actual.getKey(), ResourceAssociationAction.LINK, associationMod).
                 readEntity(BulkActionResult.class));
 
         actual = groupService.read(actual.getKey());
@@ -373,7 +373,7 @@ public class GroupITCase extends AbstractITCase {
 
         assertNotNull(resourceService.readConnObject(RESOURCE_NAME_LDAP, AnyTypeKind.GROUP.name(), actual.getKey()));
 
-        assertNotNull(groupService.bulkDeassociation(actual.getKey(),
+        assertNotNull(groupService.deassociate(actual.getKey(),
                 ResourceDeassociationActionType.UNASSIGN,
                 CollectionWrapper.wrap(RESOURCE_NAME_LDAP, ResourceKey.class)).
                 readEntity(BulkActionResult.class));
@@ -407,8 +407,8 @@ public class GroupITCase extends AbstractITCase {
 
         ResourceAssociationMod associationMod = new ResourceAssociationMod();
         associationMod.getTargetResources().addAll(CollectionWrapper.wrap(RESOURCE_NAME_LDAP, ResourceKey.class));
-        assertNotNull(groupService.bulkAssociation(actual.getKey(),
-                ResourceAssociationActionType.ASSIGN, associationMod).
+        assertNotNull(groupService.associate(actual.getKey(),
+                ResourceAssociationAction.ASSIGN, associationMod).
                 readEntity(BulkActionResult.class));
 
         actual = groupService.read(actual.getKey());
@@ -424,7 +424,7 @@ public class GroupITCase extends AbstractITCase {
 
         assertNotNull(resourceService.readConnObject(RESOURCE_NAME_LDAP, AnyTypeKind.GROUP.name(), actual.getKey()));
 
-        assertNotNull(groupService.bulkDeassociation(actual.getKey(),
+        assertNotNull(groupService.deassociate(actual.getKey(),
                 ResourceDeassociationActionType.DEPROVISION,
                 CollectionWrapper.wrap(RESOURCE_NAME_LDAP, ResourceKey.class)).
                 readEntity(BulkActionResult.class));
@@ -458,8 +458,8 @@ public class GroupITCase extends AbstractITCase {
 
         ResourceAssociationMod associationMod = new ResourceAssociationMod();
         associationMod.getTargetResources().addAll(CollectionWrapper.wrap(RESOURCE_NAME_LDAP, ResourceKey.class));
-        assertNotNull(groupService.bulkAssociation(actual.getKey(),
-                ResourceAssociationActionType.PROVISION, associationMod).
+        assertNotNull(groupService.associate(actual.getKey(),
+                ResourceAssociationAction.PROVISION, associationMod).
                 readEntity(BulkActionResult.class));
 
         actual = groupService.read(actual.getKey());
@@ -485,8 +485,8 @@ public class GroupITCase extends AbstractITCase {
 
         ResourceAssociationMod associationMod = new ResourceAssociationMod();
         associationMod.getTargetResources().addAll(CollectionWrapper.wrap(RESOURCE_NAME_LDAP, ResourceKey.class));
-        assertNotNull(groupService.bulkAssociation(actual.getKey(),
-                ResourceAssociationActionType.PROVISION, associationMod).
+        assertNotNull(groupService.associate(actual.getKey(),
+                ResourceAssociationAction.PROVISION, associationMod).
                 readEntity(BulkActionResult.class));
 
         actual = groupService.read(actual.getKey());
@@ -494,7 +494,7 @@ public class GroupITCase extends AbstractITCase {
 
         assertNotNull(resourceService.readConnObject(RESOURCE_NAME_LDAP, AnyTypeKind.GROUP.name(), actual.getKey()));
 
-        assertNotNull(groupService.bulkDeassociation(actual.getKey(),
+        assertNotNull(groupService.deassociate(actual.getKey(),
                 ResourceDeassociationActionType.DEPROVISION,
                 CollectionWrapper.wrap(RESOURCE_NAME_LDAP, ResourceKey.class)).
                 readEntity(BulkActionResult.class));

http://git-wip-us.apache.org/repos/asf/syncope/blob/6dfedd8f/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/LoggerITCase.java
----------------------------------------------------------------------
diff --git a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/LoggerITCase.java b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/LoggerITCase.java
index 2ed8449..40fe8a1 100644
--- a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/LoggerITCase.java
+++ b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/LoggerITCase.java
@@ -197,7 +197,7 @@ public class LoggerITCase extends AbstractITCase {
         found = false;
         for (EventCategoryTO eventCategoryTO : events) {
             if (EventCategoryType.TASK == eventCategoryTO.getType()
-                    && "SampleJob".equals(eventCategoryTO.getCategory())) {
+                    && "TestSampleJobDelegate".equals(eventCategoryTO.getCategory())) {
                 found = true;
             }
         }
@@ -206,7 +206,7 @@ public class LoggerITCase extends AbstractITCase {
         found = false;
         for (EventCategoryTO eventCategoryTO : events) {
             if (EventCategoryType.TASK == eventCategoryTO.getType()
-                    && "SyncJob".equals(eventCategoryTO.getCategory())) {
+                    && "SyncJobDelegate".equals(eventCategoryTO.getCategory())) {
                 found = true;
             }
         }

http://git-wip-us.apache.org/repos/asf/syncope/blob/6dfedd8f/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/PropagationTaskITCase.java
----------------------------------------------------------------------
diff --git a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/PropagationTaskITCase.java b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/PropagationTaskITCase.java
index 66185f5..56abdb8 100644
--- a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/PropagationTaskITCase.java
+++ b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/PropagationTaskITCase.java
@@ -141,7 +141,7 @@ public class PropagationTaskITCase extends AbstractTaskITCase {
         assertFalse(after.isEmpty());
 
         BulkAction bulkAction = new BulkAction();
-        bulkAction.setOperation(BulkAction.Type.DELETE);
+        bulkAction.setType(BulkAction.Type.DELETE);
 
         for (PropagationTaskTO taskTO : after) {
             bulkAction.getTargets().add(String.valueOf(taskTO.getKey()));

http://git-wip-us.apache.org/repos/asf/syncope/blob/6dfedd8f/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/PushTaskITCase.java
----------------------------------------------------------------------
diff --git a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/PushTaskITCase.java b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/PushTaskITCase.java
index 9a169c3..ca9d8a4 100644
--- a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/PushTaskITCase.java
+++ b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/PushTaskITCase.java
@@ -18,7 +18,6 @@
  */
 package org.apache.syncope.fit.core.reference;
 
-import static org.apache.syncope.fit.core.reference.AbstractITCase.anyTypeClassService;
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertFalse;
 import static org.junit.Assert.assertNotNull;
@@ -109,7 +108,7 @@ public class PushTaskITCase extends AbstractTaskITCase {
         task = taskService.read(actual.getKey());
         assertNotNull(task);
         assertEquals(task.getKey(), actual.getKey());
-        assertEquals(task.getJobClassName(), actual.getJobClassName());
+        assertEquals(task.getJobDelegateClassName(), actual.getJobDelegateClassName());
         assertEquals(task.getFilters().get(AnyTypeKind.USER.name()),
                 actual.getFilters().get(AnyTypeKind.USER.name()));
         assertEquals(task.getFilters().get(AnyTypeKind.GROUP.name()),
@@ -194,7 +193,7 @@ public class PushTaskITCase extends AbstractTaskITCase {
         assertTrue(userService.read(1L).getResources().contains(RESOURCE_NAME_TESTDB2));
         assertFalse(userService.read(2L).getResources().contains(RESOURCE_NAME_TESTDB2));
 
-        final JdbcTemplate jdbcTemplate = new JdbcTemplate(testDataSource);
+        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());
 

http://git-wip-us.apache.org/repos/asf/syncope/blob/6dfedd8f/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/ResourceITCase.java
----------------------------------------------------------------------
diff --git a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/ResourceITCase.java b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/ResourceITCase.java
index c0e1790..6242d96 100644
--- a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/ResourceITCase.java
+++ b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/ResourceITCase.java
@@ -481,7 +481,7 @@ public class ResourceITCase extends AbstractITCase {
         assertNotNull(resourceService.read("forBulk2"));
 
         final BulkAction bulkAction = new BulkAction();
-        bulkAction.setOperation(BulkAction.Type.DELETE);
+        bulkAction.setType(BulkAction.Type.DELETE);
 
         bulkAction.getTargets().add(String.valueOf("forBulk1"));
         bulkAction.getTargets().add(String.valueOf("forBulk2"));

http://git-wip-us.apache.org/repos/asf/syncope/blob/6dfedd8f/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/SchedTaskITCase.java
----------------------------------------------------------------------
diff --git a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/SchedTaskITCase.java b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/SchedTaskITCase.java
index b65aa72..30425f9 100644
--- a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/SchedTaskITCase.java
+++ b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/SchedTaskITCase.java
@@ -38,7 +38,6 @@ import org.apache.syncope.common.lib.types.JobAction;
 import org.apache.syncope.common.lib.types.JobStatusType;
 import org.apache.syncope.common.lib.types.TaskType;
 import org.apache.syncope.common.rest.api.service.TaskService;
-import org.apache.syncope.core.provisioning.api.job.SyncJob;
 import org.junit.FixMethodOrder;
 import org.junit.Test;
 import org.junit.runners.MethodSorters;
@@ -86,7 +85,7 @@ public class SchedTaskITCase extends AbstractTaskITCase {
         SchedTaskTO task = new SchedTaskTO();
         task.setName("issueSYNCOPE144");
         task.setDescription("issueSYNCOPE144 Description");
-        task.setJobClassName(SyncJob.class.getName());
+        task.setJobDelegateClassName(TestSampleJobDelegate.class.getName());
 
         Response response = taskService.create(task);
         SchedTaskTO actual = getObject(response.getLocation(), TaskService.class, SchedTaskTO.class);
@@ -117,7 +116,7 @@ public class SchedTaskITCase extends AbstractTaskITCase {
         SchedTaskTO task = new SchedTaskTO();
         task.setName("issueSYNCOPE660");
         task.setDescription("issueSYNCOPE660 Description");
-        task.setJobClassName(TestSampleJob.class.getName());
+        task.setJobDelegateClassName(TestSampleJobDelegate.class.getName());
 
         Response response = taskService.create(task);
         task = getObject(response.getLocation(), TaskService.class, SchedTaskTO.class);


[25/31] syncope git commit: [SYNCOPE-119] Adding test for delegated admin (user) CRUD

Posted by md...@apache.org.
[SYNCOPE-119] Adding test for delegated admin (user) CRUD


Project: http://git-wip-us.apache.org/repos/asf/syncope/repo
Commit: http://git-wip-us.apache.org/repos/asf/syncope/commit/bcb9a0d7
Tree: http://git-wip-us.apache.org/repos/asf/syncope/tree/bcb9a0d7
Diff: http://git-wip-us.apache.org/repos/asf/syncope/diff/bcb9a0d7

Branch: refs/heads/SYNCOPE-156
Commit: bcb9a0d7b0a792eba87046853510376cf4e58131
Parents: 5cf6aae
Author: Francesco Chicchiriccò <il...@apache.org>
Authored: Tue Aug 11 12:51:57 2015 +0200
Committer: Francesco Chicchiriccò <il...@apache.org>
Committed: Thu Aug 13 17:16:51 2015 +0200

----------------------------------------------------------------------
 .../syncope/common/lib/types/Entitlement.java   |   2 -
 .../syncope/core/logic/AbstractAnyLogic.java    |  25 +++-
 .../syncope/core/logic/AnyObjectLogic.java      | 114 ++++++++++------
 .../apache/syncope/core/logic/GroupLogic.java   | 134 +++++++++++++------
 .../apache/syncope/core/logic/UserLogic.java    | 108 ++++++++++++---
 .../apache/syncope/core/misc/RealmUtils.java    |   4 +-
 .../misc/security/UnauthorizedException.java    |   5 +-
 .../core/persistence/jpa/dao/JPARoleDAO.java    |   9 ++
 .../core/persistence/jpa/outer/RoleTest.java    |  33 +++++
 .../rest/cxf/service/UserSelfServiceImpl.java   |   6 +-
 .../core/reference/AuthenticationITCase.java    |  91 ++++++++++++-
 11 files changed, 426 insertions(+), 105 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/syncope/blob/bcb9a0d7/common/lib/src/main/java/org/apache/syncope/common/lib/types/Entitlement.java
----------------------------------------------------------------------
diff --git a/common/lib/src/main/java/org/apache/syncope/common/lib/types/Entitlement.java b/common/lib/src/main/java/org/apache/syncope/common/lib/types/Entitlement.java
index 85befc6..bf87c89 100644
--- a/common/lib/src/main/java/org/apache/syncope/common/lib/types/Entitlement.java
+++ b/common/lib/src/main/java/org/apache/syncope/common/lib/types/Entitlement.java
@@ -108,8 +108,6 @@ public final class Entitlement {
 
     public static final String USER_DELETE = "USER_DELETE";
 
-    public static final String USER_VIEW = "USER_VIEW";
-
     public static final String GROUP_SEARCH = "GROUP_SEARCH";
 
     public static final String GROUP_CREATE = "GROUP_CREATE";

http://git-wip-us.apache.org/repos/asf/syncope/blob/bcb9a0d7/core/logic/src/main/java/org/apache/syncope/core/logic/AbstractAnyLogic.java
----------------------------------------------------------------------
diff --git a/core/logic/src/main/java/org/apache/syncope/core/logic/AbstractAnyLogic.java b/core/logic/src/main/java/org/apache/syncope/core/logic/AbstractAnyLogic.java
index 6f66113..7a6cfdd 100644
--- a/core/logic/src/main/java/org/apache/syncope/core/logic/AbstractAnyLogic.java
+++ b/core/logic/src/main/java/org/apache/syncope/core/logic/AbstractAnyLogic.java
@@ -26,7 +26,9 @@ import org.apache.commons.collections4.CollectionUtils;
 import org.apache.commons.collections4.Predicate;
 import org.apache.syncope.common.lib.mod.AnyMod;
 import org.apache.syncope.common.lib.to.AnyTO;
+import org.apache.syncope.common.lib.types.AnyTypeKind;
 import org.apache.syncope.core.misc.RealmUtils;
+import org.apache.syncope.core.misc.security.UnauthorizedException;
 import org.apache.syncope.core.persistence.api.dao.search.OrderByClause;
 import org.apache.syncope.core.persistence.api.dao.search.SearchCond;
 
@@ -57,8 +59,8 @@ public abstract class AbstractAnyLogic<TO extends AnyTO, MOD extends AnyMod>
     protected Set<String> getEffectiveRealms(
             final Set<String> allowedRealms, final Collection<String> requestedRealms) {
 
-        final Set<String> allowed = RealmUtils.normalize(allowedRealms);
-        final Set<String> requested = RealmUtils.normalize(requestedRealms);
+        Set<String> allowed = RealmUtils.normalize(allowedRealms);
+        Set<String> requested = RealmUtils.normalize(requestedRealms);
 
         Set<String> effective = new HashSet<>();
         CollectionUtils.select(requested, new StartsWithPredicate(allowed), effective);
@@ -67,6 +69,25 @@ public abstract class AbstractAnyLogic<TO extends AnyTO, MOD extends AnyMod>
         return effective;
     }
 
+    protected void securityChecks(final Set<String> effectiveRealms, final String realm, final Long key) {
+        if (!CollectionUtils.exists(effectiveRealms, new Predicate<String>() {
+
+            @Override
+            public boolean evaluate(final String ownedRealm) {
+                return realm.startsWith(ownedRealm);
+            }
+        })) {
+
+            throw new UnauthorizedException(
+                    this instanceof UserLogic
+                            ? AnyTypeKind.USER
+                            : this instanceof GroupLogic
+                                    ? AnyTypeKind.GROUP
+                                    : AnyTypeKind.ANY_OBJECT,
+                    key);
+        }
+    }
+
     public abstract TO read(Long key);
 
     public abstract int count(List<String> realms);

http://git-wip-us.apache.org/repos/asf/syncope/blob/bcb9a0d7/core/logic/src/main/java/org/apache/syncope/core/logic/AnyObjectLogic.java
----------------------------------------------------------------------
diff --git a/core/logic/src/main/java/org/apache/syncope/core/logic/AnyObjectLogic.java b/core/logic/src/main/java/org/apache/syncope/core/logic/AnyObjectLogic.java
index 38927ce..0b0cb74 100644
--- a/core/logic/src/main/java/org/apache/syncope/core/logic/AnyObjectLogic.java
+++ b/core/logic/src/main/java/org/apache/syncope/core/logic/AnyObjectLogic.java
@@ -22,6 +22,7 @@ import java.lang.reflect.Method;
 import java.util.ArrayList;
 import java.util.Collection;
 import java.util.Collections;
+import java.util.HashSet;
 import java.util.List;
 import java.util.Map;
 import java.util.Set;
@@ -46,9 +47,7 @@ import org.apache.syncope.core.provisioning.api.data.AnyObjectDataBinder;
 import org.apache.syncope.core.provisioning.api.propagation.PropagationManager;
 import org.apache.syncope.core.provisioning.api.propagation.PropagationTaskExecutor;
 import org.apache.syncope.core.misc.security.AuthContextUtils;
-import org.apache.syncope.core.misc.security.UnauthorizedException;
 import org.apache.syncope.core.persistence.api.dao.AnySearchDAO;
-import org.apache.syncope.core.persistence.api.dao.NotFoundException;
 import org.apache.syncope.core.persistence.api.entity.anyobject.AnyObject;
 import org.apache.syncope.core.provisioning.api.AnyTransformer;
 import org.springframework.beans.factory.annotation.Autowired;
@@ -90,8 +89,8 @@ public class AnyObjectLogic extends AbstractAnyLogic<AnyObjectTO, AnyObjectMod>
     @PreAuthorize("hasRole('" + Entitlement.ANY_OBJECT_READ + "')")
     @Transactional(readOnly = true)
     @Override
-    public AnyObjectTO read(final Long anyObjectKey) {
-        return binder.getAnyObjectTO(anyObjectKey);
+    public AnyObjectTO read(final Long key) {
+        return binder.getAnyObjectTO(key);
     }
 
     @PreAuthorize("isAuthenticated()")
@@ -164,12 +163,11 @@ public class AnyObjectLogic extends AbstractAnyLogic<AnyObjectTO, AnyObjectMod>
         if (anyObjectTO.getRealm() == null) {
             throw SyncopeClientException.build(ClientExceptionType.InvalidRealm);
         }
+        // security checks
         Set<String> effectiveRealms = getEffectiveRealms(
                 AuthContextUtils.getAuthorizations().get(Entitlement.ANY_OBJECT_CREATE),
                 Collections.singleton(anyObjectTO.getRealm()));
-        if (effectiveRealms.isEmpty()) {
-            throw new UnauthorizedException(AnyTypeKind.ANY_OBJECT, null);
-        }
+        securityChecks(effectiveRealms, anyObjectTO.getRealm(), null);
 
         // Any transformation (if configured)
         AnyObjectTO actual = attrTransformer.transform(anyObjectTO);
@@ -191,21 +189,25 @@ public class AnyObjectLogic extends AbstractAnyLogic<AnyObjectTO, AnyObjectMod>
     @PreAuthorize("hasRole('" + Entitlement.ANY_OBJECT_UPDATE + "')")
     @Override
     public AnyObjectTO update(final AnyObjectMod anyObjectMod) {
-        AnyObject anyObject = anyObjectDAO.authFind(anyObjectMod.getKey());
-        if (anyObject == null) {
-            throw new NotFoundException("AnyObject with key " + anyObjectMod.getKey());
+        // Any transformation (if configured)
+        AnyObjectMod actual = attrTransformer.transform(anyObjectMod);
+        LOG.debug("Transformed: {}", actual);
+
+        // security checks
+        AnyObjectTO toUpdate = binder.getAnyObjectTO(anyObjectMod.getKey());
+        Set<String> requestedRealms = new HashSet<>();
+        requestedRealms.add(toUpdate.getRealm());
+        if (StringUtils.isNotBlank(actual.getRealm())) {
+            requestedRealms.add(actual.getRealm());
         }
         Set<String> effectiveRealms = getEffectiveRealms(
                 AuthContextUtils.getAuthorizations().get(Entitlement.ANY_OBJECT_UPDATE),
-                Collections.singleton(anyObject.getRealm().getFullPath()));
-        if (effectiveRealms.isEmpty()) {
-            throw new UnauthorizedException(AnyTypeKind.ANY_OBJECT, anyObject.getKey());
+                requestedRealms);
+        securityChecks(effectiveRealms, toUpdate.getRealm(), toUpdate.getKey());
+        if (StringUtils.isNotBlank(actual.getRealm())) {
+            securityChecks(effectiveRealms, actual.getRealm(), toUpdate.getKey());
         }
 
-        // Any transformation (if configured)
-        AnyObjectMod actual = attrTransformer.transform(anyObjectMod);
-        LOG.debug("Transformed: {}", actual);
-
         Map.Entry<Long, List<PropagationStatus>> updated = provisioningManager.update(anyObjectMod);
 
         AnyObjectTO updatedTO = binder.getAnyObjectTO(updated.getKey());
@@ -215,22 +217,18 @@ public class AnyObjectLogic extends AbstractAnyLogic<AnyObjectTO, AnyObjectMod>
 
     @PreAuthorize("hasRole('" + Entitlement.ANY_OBJECT_DELETE + "')")
     @Override
-    public AnyObjectTO delete(final Long anyObjectKey) {
-        AnyObject anyObject = anyObjectDAO.authFind(anyObjectKey);
-        if (anyObject == null) {
-            throw new NotFoundException("AnyObject with key " + anyObjectKey);
-        }
+    public AnyObjectTO delete(final Long key) {
+        // security checks
+        AnyObjectTO toDelete = binder.getAnyObjectTO(key);
         Set<String> effectiveRealms = getEffectiveRealms(
-                AuthContextUtils.getAuthorizations().get(Entitlement.ANY_OBJECT_UPDATE),
-                Collections.singleton(anyObject.getRealm().getFullPath()));
-        if (effectiveRealms.isEmpty()) {
-            throw new UnauthorizedException(AnyTypeKind.ANY_OBJECT, anyObject.getKey());
-        }
+                AuthContextUtils.getAuthorizations().get(Entitlement.ANY_OBJECT_DELETE),
+                Collections.singleton(toDelete.getRealm()));
+        securityChecks(effectiveRealms, toDelete.getRealm(), toDelete.getKey());
 
-        List<PropagationStatus> statuses = provisioningManager.delete(anyObjectKey);
+        List<PropagationStatus> statuses = provisioningManager.delete(key);
 
         AnyObjectTO anyObjectTO = new AnyObjectTO();
-        anyObjectTO.setKey(anyObjectKey);
+        anyObjectTO.setKey(key);
 
         anyObjectTO.getPropagationStatusTOs().addAll(statuses);
 
@@ -239,9 +237,16 @@ public class AnyObjectLogic extends AbstractAnyLogic<AnyObjectTO, AnyObjectMod>
 
     @PreAuthorize("hasRole('" + Entitlement.ANY_OBJECT_UPDATE + "')")
     @Override
-    public AnyObjectTO unlink(final Long anyObjectKey, final Collection<String> resources) {
+    public AnyObjectTO unlink(final Long key, final Collection<String> resources) {
+        // security checks
+        AnyObjectTO anyObject = binder.getAnyObjectTO(key);
+        Set<String> effectiveRealms = getEffectiveRealms(
+                AuthContextUtils.getAuthorizations().get(Entitlement.ANY_OBJECT_UPDATE),
+                Collections.singleton(anyObject.getRealm()));
+        securityChecks(effectiveRealms, anyObject.getRealm(), anyObject.getKey());
+
         AnyObjectMod anyObjectMod = new AnyObjectMod();
-        anyObjectMod.setKey(anyObjectKey);
+        anyObjectMod.setKey(key);
         anyObjectMod.getResourcesToRemove().addAll(resources);
 
         return binder.getAnyObjectTO(provisioningManager.unlink(anyObjectMod));
@@ -249,9 +254,16 @@ public class AnyObjectLogic extends AbstractAnyLogic<AnyObjectTO, AnyObjectMod>
 
     @PreAuthorize("hasRole('" + Entitlement.ANY_OBJECT_UPDATE + "')")
     @Override
-    public AnyObjectTO link(final Long anyObjectKey, final Collection<String> resources) {
+    public AnyObjectTO link(final Long key, final Collection<String> resources) {
+        // security checks
+        AnyObjectTO anyObject = binder.getAnyObjectTO(key);
+        Set<String> effectiveRealms = getEffectiveRealms(
+                AuthContextUtils.getAuthorizations().get(Entitlement.ANY_OBJECT_UPDATE),
+                Collections.singleton(anyObject.getRealm()));
+        securityChecks(effectiveRealms, anyObject.getRealm(), anyObject.getKey());
+
         AnyObjectMod anyObjectMod = new AnyObjectMod();
-        anyObjectMod.setKey(anyObjectKey);
+        anyObjectMod.setKey(key);
         anyObjectMod.getResourcesToAdd().addAll(resources);
 
         return binder.getAnyObjectTO(provisioningManager.link(anyObjectMod));
@@ -259,9 +271,16 @@ public class AnyObjectLogic extends AbstractAnyLogic<AnyObjectTO, AnyObjectMod>
 
     @PreAuthorize("hasRole('" + Entitlement.ANY_OBJECT_UPDATE + "')")
     @Override
-    public AnyObjectTO unassign(final Long anyObjectKey, final Collection<String> resources) {
+    public AnyObjectTO unassign(final Long key, final Collection<String> resources) {
+        // security checks
+        AnyObjectTO anyObject = binder.getAnyObjectTO(key);
+        Set<String> effectiveRealms = getEffectiveRealms(
+                AuthContextUtils.getAuthorizations().get(Entitlement.ANY_OBJECT_UPDATE),
+                Collections.singleton(anyObject.getRealm()));
+        securityChecks(effectiveRealms, anyObject.getRealm(), anyObject.getKey());
+
         AnyObjectMod anyObjectMod = new AnyObjectMod();
-        anyObjectMod.setKey(anyObjectKey);
+        anyObjectMod.setKey(key);
         anyObjectMod.getResourcesToRemove().addAll(resources);
         return update(anyObjectMod);
     }
@@ -274,6 +293,13 @@ public class AnyObjectLogic extends AbstractAnyLogic<AnyObjectTO, AnyObjectMod>
             final boolean changepwd,
             final String password) {
 
+        // security checks
+        AnyObjectTO anyObject = binder.getAnyObjectTO(key);
+        Set<String> effectiveRealms = getEffectiveRealms(
+                AuthContextUtils.getAuthorizations().get(Entitlement.ANY_OBJECT_UPDATE),
+                Collections.singleton(anyObject.getRealm()));
+        securityChecks(effectiveRealms, anyObject.getRealm(), anyObject.getKey());
+
         AnyObjectMod anyObjectMod = new AnyObjectMod();
         anyObjectMod.setKey(key);
         anyObjectMod.getResourcesToAdd().addAll(resources);
@@ -284,6 +310,13 @@ public class AnyObjectLogic extends AbstractAnyLogic<AnyObjectTO, AnyObjectMod>
     @PreAuthorize("hasRole('" + Entitlement.ANY_OBJECT_UPDATE + "')")
     @Override
     public AnyObjectTO deprovision(final Long key, final Collection<String> resources) {
+        // security checks
+        AnyObjectTO anyObject = binder.getAnyObjectTO(key);
+        Set<String> effectiveRealms = getEffectiveRealms(
+                AuthContextUtils.getAuthorizations().get(Entitlement.ANY_OBJECT_UPDATE),
+                Collections.singleton(anyObject.getRealm()));
+        securityChecks(effectiveRealms, anyObject.getRealm(), anyObject.getKey());
+
         List<PropagationStatus> statuses = provisioningManager.deprovision(key, resources);
 
         AnyObjectTO updatedTO = binder.getAnyObjectTO(key);
@@ -299,10 +332,15 @@ public class AnyObjectLogic extends AbstractAnyLogic<AnyObjectTO, AnyObjectMod>
             final boolean changePwd,
             final String password) {
 
-        AnyObjectTO original = binder.getAnyObjectTO(key);
-        original.getPropagationStatusTOs().addAll(provisioningManager.provision(key, resources));
+        // security checks
+        AnyObjectTO anyObject = binder.getAnyObjectTO(key);
+        Set<String> effectiveRealms = getEffectiveRealms(
+                AuthContextUtils.getAuthorizations().get(Entitlement.ANY_OBJECT_UPDATE),
+                Collections.singleton(anyObject.getRealm()));
+        securityChecks(effectiveRealms, anyObject.getRealm(), anyObject.getKey());
 
-        return original;
+        anyObject.getPropagationStatusTOs().addAll(provisioningManager.provision(key, resources));
+        return anyObject;
     }
 
     @Override

http://git-wip-us.apache.org/repos/asf/syncope/blob/bcb9a0d7/core/logic/src/main/java/org/apache/syncope/core/logic/GroupLogic.java
----------------------------------------------------------------------
diff --git a/core/logic/src/main/java/org/apache/syncope/core/logic/GroupLogic.java b/core/logic/src/main/java/org/apache/syncope/core/logic/GroupLogic.java
index 33b0447..1c3d7f5 100644
--- a/core/logic/src/main/java/org/apache/syncope/core/logic/GroupLogic.java
+++ b/core/logic/src/main/java/org/apache/syncope/core/logic/GroupLogic.java
@@ -22,13 +22,16 @@ import java.lang.reflect.Method;
 import java.util.ArrayList;
 import java.util.Collection;
 import java.util.Collections;
+import java.util.HashSet;
 import java.util.List;
 import java.util.Map;
 import java.util.Set;
 import javax.annotation.Resource;
 import org.apache.commons.collections4.CollectionUtils;
+import org.apache.commons.collections4.Predicate;
 import org.apache.commons.collections4.Transformer;
 import org.apache.commons.lang3.ArrayUtils;
+import org.apache.commons.lang3.StringUtils;
 import org.apache.syncope.common.lib.SyncopeClientException;
 import org.apache.syncope.common.lib.SyncopeConstants;
 import org.apache.syncope.common.lib.mod.GroupMod;
@@ -50,7 +53,6 @@ import org.apache.syncope.core.provisioning.api.propagation.PropagationTaskExecu
 import org.apache.syncope.core.misc.security.AuthContextUtils;
 import org.apache.syncope.core.misc.security.UnauthorizedException;
 import org.apache.syncope.core.persistence.api.dao.AnySearchDAO;
-import org.apache.syncope.core.persistence.api.dao.NotFoundException;
 import org.apache.syncope.core.provisioning.api.AnyTransformer;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.security.access.prepost.PreAuthorize;
@@ -91,11 +93,25 @@ public class GroupLogic extends AbstractAnyLogic<GroupTO, GroupMod> {
     @Autowired
     protected GroupProvisioningManager provisioningManager;
 
+    @Override
+    protected void securityChecks(final Set<String> effectiveRealms, final String realm, final Long key) {
+        if (!CollectionUtils.exists(effectiveRealms, new Predicate<String>() {
+
+            @Override
+            public boolean evaluate(final String ownedRealm) {
+                return realm.startsWith(ownedRealm) || ownedRealm.equals(RealmUtils.getGroupOwnerRealm(realm, key));
+            }
+        })) {
+
+            throw new UnauthorizedException(AnyTypeKind.GROUP, key);
+        }
+    }
+
     @PreAuthorize("hasRole('" + Entitlement.GROUP_READ + "')")
     @Transactional(readOnly = true)
     @Override
-    public GroupTO read(final Long groupKey) {
-        return binder.getGroupTO(groupKey);
+    public GroupTO read(final Long key) {
+        return binder.getGroupTO(key);
     }
 
     @PreAuthorize("isAuthenticated() and not(hasRole('" + Entitlement.ANONYMOUS + "'))")
@@ -153,7 +169,7 @@ public class GroupLogic extends AbstractAnyLogic<GroupTO, GroupMod> {
     public List<GroupTO> search(final SearchCond searchCondition, final int page, final int size,
             final List<OrderByClause> orderBy, final List<String> realms, final boolean details) {
 
-        final List<Group> matchingGroups = searchDAO.search(
+        List<Group> matchingGroups = searchDAO.search(
                 getEffectiveRealms(AuthContextUtils.getAuthorizations().get(Entitlement.GROUP_SEARCH), realms),
                 searchCondition, page, size, orderBy, AnyTypeKind.GROUP);
         return CollectionUtils.collect(matchingGroups, new Transformer<Group, GroupTO>() {
@@ -169,15 +185,13 @@ public class GroupLogic extends AbstractAnyLogic<GroupTO, GroupMod> {
     @Override
     public GroupTO create(final GroupTO groupTO) {
         if (groupTO.getRealm() == null) {
-            SyncopeClientException sce = SyncopeClientException.build(ClientExceptionType.InvalidRealm);
-            throw sce;
+            throw SyncopeClientException.build(ClientExceptionType.InvalidRealm);
         }
+        // security checks
         Set<String> effectiveRealms = getEffectiveRealms(
                 AuthContextUtils.getAuthorizations().get(Entitlement.GROUP_CREATE),
                 Collections.singleton(groupTO.getRealm()));
-        if (effectiveRealms.isEmpty()) {
-            throw new UnauthorizedException(AnyTypeKind.GROUP, null);
-        }
+        securityChecks(effectiveRealms, groupTO.getRealm(), null);
 
         // Any transformation (if configured)
         GroupTO actual = attrTransformer.transform(groupTO);
@@ -195,21 +209,25 @@ public class GroupLogic extends AbstractAnyLogic<GroupTO, GroupMod> {
     @PreAuthorize("hasRole('" + Entitlement.GROUP_UPDATE + "')")
     @Override
     public GroupTO update(final GroupMod groupMod) {
-        Group group = groupDAO.authFind(groupMod.getKey());
-        if (group == null) {
-            throw new NotFoundException("Group with key " + groupMod.getKey());
+        // Any transformation (if configured)
+        GroupMod actual = attrTransformer.transform(groupMod);
+        LOG.debug("Transformed: {}", actual);
+
+        // security checks
+        GroupTO toUpdate = binder.getGroupTO(groupMod.getKey());
+        Set<String> requestedRealms = new HashSet<>();
+        requestedRealms.add(toUpdate.getRealm());
+        if (StringUtils.isNotBlank(actual.getRealm())) {
+            requestedRealms.add(actual.getRealm());
         }
         Set<String> effectiveRealms = getEffectiveRealms(
                 AuthContextUtils.getAuthorizations().get(Entitlement.GROUP_UPDATE),
-                Collections.singleton(RealmUtils.getGroupOwnerRealm(group.getRealm().getFullPath(), group.getKey())));
-        if (effectiveRealms.isEmpty()) {
-            throw new UnauthorizedException(AnyTypeKind.GROUP, group.getKey());
+                requestedRealms);
+        securityChecks(effectiveRealms, toUpdate.getRealm(), toUpdate.getKey());
+        if (StringUtils.isNotBlank(actual.getRealm())) {
+            securityChecks(effectiveRealms, actual.getRealm(), toUpdate.getKey());
         }
 
-        // Any transformation (if configured)
-        GroupMod actual = attrTransformer.transform(groupMod);
-        LOG.debug("Transformed: {}", actual);
-
         Map.Entry<Long, List<PropagationStatus>> updated = provisioningManager.update(groupMod);
 
         GroupTO updatedTO = binder.getGroupTO(updated.getKey());
@@ -219,19 +237,15 @@ public class GroupLogic extends AbstractAnyLogic<GroupTO, GroupMod> {
 
     @PreAuthorize("hasRole('" + Entitlement.GROUP_DELETE + "')")
     @Override
-    public GroupTO delete(final Long groupKey) {
-        Group group = groupDAO.authFind(groupKey);
-        if (group == null) {
-            throw new NotFoundException("Group with key " + groupKey);
-        }
+    public GroupTO delete(final Long key) {
+        // security checks
+        GroupTO toDelete = binder.getGroupTO(key);
         Set<String> effectiveRealms = getEffectiveRealms(
                 AuthContextUtils.getAuthorizations().get(Entitlement.GROUP_DELETE),
-                Collections.singleton(RealmUtils.getGroupOwnerRealm(group.getRealm().getFullPath(), group.getKey())));
-        if (effectiveRealms.isEmpty()) {
-            throw new UnauthorizedException(AnyTypeKind.GROUP, group.getKey());
-        }
+                Collections.singleton(toDelete.getRealm()));
+        securityChecks(effectiveRealms, toDelete.getRealm(), toDelete.getKey());
 
-        List<Group> ownedGroups = groupDAO.findOwnedByGroup(groupKey);
+        List<Group> ownedGroups = groupDAO.findOwnedByGroup(key);
         if (!ownedGroups.isEmpty()) {
             SyncopeClientException sce = SyncopeClientException.build(ClientExceptionType.GroupOwnership);
             sce.getElements().addAll(CollectionUtils.collect(ownedGroups, new Transformer<Group, String>() {
@@ -244,10 +258,10 @@ public class GroupLogic extends AbstractAnyLogic<GroupTO, GroupMod> {
             throw sce;
         }
 
-        List<PropagationStatus> statuses = provisioningManager.delete(groupKey);
+        List<PropagationStatus> statuses = provisioningManager.delete(key);
 
         GroupTO groupTO = new GroupTO();
-        groupTO.setKey(groupKey);
+        groupTO.setKey(key);
 
         groupTO.getPropagationStatusTOs().addAll(statuses);
 
@@ -256,9 +270,16 @@ public class GroupLogic extends AbstractAnyLogic<GroupTO, GroupMod> {
 
     @PreAuthorize("hasRole('" + Entitlement.GROUP_UPDATE + "')")
     @Override
-    public GroupTO unlink(final Long groupKey, final Collection<String> resources) {
+    public GroupTO unlink(final Long key, final Collection<String> resources) {
+        // security checks
+        GroupTO group = binder.getGroupTO(key);
+        Set<String> effectiveRealms = getEffectiveRealms(
+                AuthContextUtils.getAuthorizations().get(Entitlement.GROUP_UPDATE),
+                Collections.singleton(group.getRealm()));
+        securityChecks(effectiveRealms, group.getRealm(), group.getKey());
+
         GroupMod groupMod = new GroupMod();
-        groupMod.setKey(groupKey);
+        groupMod.setKey(key);
         groupMod.getResourcesToRemove().addAll(resources);
 
         return binder.getGroupTO(provisioningManager.unlink(groupMod));
@@ -266,9 +287,16 @@ public class GroupLogic extends AbstractAnyLogic<GroupTO, GroupMod> {
 
     @PreAuthorize("hasRole('" + Entitlement.GROUP_UPDATE + "')")
     @Override
-    public GroupTO link(final Long groupKey, final Collection<String> resources) {
+    public GroupTO link(final Long key, final Collection<String> resources) {
+        // security checks
+        GroupTO group = binder.getGroupTO(key);
+        Set<String> effectiveRealms = getEffectiveRealms(
+                AuthContextUtils.getAuthorizations().get(Entitlement.GROUP_UPDATE),
+                Collections.singleton(group.getRealm()));
+        securityChecks(effectiveRealms, group.getRealm(), group.getKey());
+
         GroupMod groupMod = new GroupMod();
-        groupMod.setKey(groupKey);
+        groupMod.setKey(key);
         groupMod.getResourcesToAdd().addAll(resources);
 
         return binder.getGroupTO(provisioningManager.link(groupMod));
@@ -276,9 +304,16 @@ public class GroupLogic extends AbstractAnyLogic<GroupTO, GroupMod> {
 
     @PreAuthorize("hasRole('" + Entitlement.GROUP_UPDATE + "')")
     @Override
-    public GroupTO unassign(final Long groupKey, final Collection<String> resources) {
+    public GroupTO unassign(final Long key, final Collection<String> resources) {
+        // security checks
+        GroupTO group = binder.getGroupTO(key);
+        Set<String> effectiveRealms = getEffectiveRealms(
+                AuthContextUtils.getAuthorizations().get(Entitlement.GROUP_UPDATE),
+                Collections.singleton(group.getRealm()));
+        securityChecks(effectiveRealms, group.getRealm(), group.getKey());
+
         GroupMod groupMod = new GroupMod();
-        groupMod.setKey(groupKey);
+        groupMod.setKey(key);
         groupMod.getResourcesToRemove().addAll(resources);
         return update(groupMod);
     }
@@ -291,6 +326,13 @@ public class GroupLogic extends AbstractAnyLogic<GroupTO, GroupMod> {
             final boolean changepwd,
             final String password) {
 
+        // security checks
+        GroupTO group = binder.getGroupTO(key);
+        Set<String> effectiveRealms = getEffectiveRealms(
+                AuthContextUtils.getAuthorizations().get(Entitlement.GROUP_UPDATE),
+                Collections.singleton(group.getRealm()));
+        securityChecks(effectiveRealms, group.getRealm(), group.getKey());
+
         GroupMod groupMod = new GroupMod();
         groupMod.setKey(key);
         groupMod.getResourcesToAdd().addAll(resources);
@@ -301,6 +343,13 @@ public class GroupLogic extends AbstractAnyLogic<GroupTO, GroupMod> {
     @PreAuthorize("hasRole('" + Entitlement.GROUP_UPDATE + "')")
     @Override
     public GroupTO deprovision(final Long key, final Collection<String> resources) {
+        // security checks
+        GroupTO group = binder.getGroupTO(key);
+        Set<String> effectiveRealms = getEffectiveRealms(
+                AuthContextUtils.getAuthorizations().get(Entitlement.GROUP_UPDATE),
+                Collections.singleton(group.getRealm()));
+        securityChecks(effectiveRealms, group.getRealm(), group.getKey());
+
         List<PropagationStatus> statuses = provisioningManager.deprovision(key, resources);
 
         GroupTO updatedTO = binder.getGroupTO(key);
@@ -316,10 +365,15 @@ public class GroupLogic extends AbstractAnyLogic<GroupTO, GroupMod> {
             final boolean changePwd,
             final String password) {
 
-        GroupTO original = binder.getGroupTO(key);
-        original.getPropagationStatusTOs().addAll(provisioningManager.provision(key, resources));
+        // security checks
+        GroupTO group = binder.getGroupTO(key);
+        Set<String> effectiveRealms = getEffectiveRealms(
+                AuthContextUtils.getAuthorizations().get(Entitlement.GROUP_UPDATE),
+                Collections.singleton(group.getRealm()));
+        securityChecks(effectiveRealms, group.getRealm(), group.getKey());
 
-        return original;
+        group.getPropagationStatusTOs().addAll(provisioningManager.provision(key, resources));
+        return group;
     }
 
     @Override

http://git-wip-us.apache.org/repos/asf/syncope/blob/bcb9a0d7/core/logic/src/main/java/org/apache/syncope/core/logic/UserLogic.java
----------------------------------------------------------------------
diff --git a/core/logic/src/main/java/org/apache/syncope/core/logic/UserLogic.java b/core/logic/src/main/java/org/apache/syncope/core/logic/UserLogic.java
index 28e7401..ff87d6b 100644
--- a/core/logic/src/main/java/org/apache/syncope/core/logic/UserLogic.java
+++ b/core/logic/src/main/java/org/apache/syncope/core/logic/UserLogic.java
@@ -23,12 +23,14 @@ import java.security.AccessControlException;
 import java.util.ArrayList;
 import java.util.Collection;
 import java.util.Collections;
+import java.util.HashSet;
 import java.util.List;
 import java.util.Map;
 import java.util.Set;
 import org.apache.commons.collections4.CollectionUtils;
 import org.apache.commons.collections4.Transformer;
 import org.apache.commons.lang3.ArrayUtils;
+import org.apache.commons.lang3.StringUtils;
 import org.apache.commons.lang3.tuple.ImmutablePair;
 import org.apache.commons.lang3.tuple.Pair;
 import org.apache.syncope.common.lib.SyncopeClientException;
@@ -51,7 +53,6 @@ import org.apache.syncope.core.provisioning.api.data.UserDataBinder;
 import org.apache.syncope.core.provisioning.api.propagation.PropagationManager;
 import org.apache.syncope.core.provisioning.api.propagation.PropagationTaskExecutor;
 import org.apache.syncope.core.misc.security.AuthContextUtils;
-import org.apache.syncope.core.misc.security.UnauthorizedException;
 import org.apache.syncope.core.misc.serialization.POJOHelper;
 import org.apache.syncope.core.persistence.api.dao.AnySearchDAO;
 import org.apache.syncope.core.provisioning.api.AnyTransformer;
@@ -180,7 +181,7 @@ public class UserLogic extends AbstractAnyLogic<UserTO, UserMod> {
     }
 
     @PreAuthorize("isAnonymous() or hasRole('" + Entitlement.ANONYMOUS + "')")
-    public UserTO createSelf(final UserTO userTO, final boolean storePassword) {
+    public UserTO selfCreate(final UserTO userTO, final boolean storePassword) {
         return doCreate(userTO, storePassword);
     }
 
@@ -193,15 +194,13 @@ public class UserLogic extends AbstractAnyLogic<UserTO, UserMod> {
     @PreAuthorize("hasRole('" + Entitlement.USER_CREATE + "')")
     public UserTO create(final UserTO userTO, final boolean storePassword) {
         if (userTO.getRealm() == null) {
-            SyncopeClientException sce = SyncopeClientException.build(ClientExceptionType.InvalidRealm);
-            throw sce;
+            throw SyncopeClientException.build(ClientExceptionType.InvalidRealm);
         }
+        // security checks
         Set<String> effectiveRealms = getEffectiveRealms(
                 AuthContextUtils.getAuthorizations().get(Entitlement.USER_CREATE),
                 Collections.singleton(userTO.getRealm()));
-        if (effectiveRealms.isEmpty()) {
-            throw new UnauthorizedException(AnyTypeKind.USER, null);
-        }
+        securityChecks(effectiveRealms, userTO.getRealm(), null);
 
         return doCreate(userTO, storePassword);
     }
@@ -219,14 +218,14 @@ public class UserLogic extends AbstractAnyLogic<UserTO, UserMod> {
     }
 
     @PreAuthorize("isAuthenticated() and not(hasRole('" + Entitlement.ANONYMOUS + "'))")
-    public UserTO updateSelf(final UserMod userMod) {
+    public UserTO selfUpdate(final UserMod userMod) {
         UserTO userTO = binder.getAuthenticatedUserTO();
 
         if (userTO.getKey() != userMod.getKey()) {
             throw new AccessControlException("Not allowed for user with key " + userMod.getKey());
         }
 
-        return update(userMod);
+        return doUpdate(userMod);
     }
 
     @PreAuthorize("hasRole('" + Entitlement.USER_UPDATE + "')")
@@ -236,7 +235,26 @@ public class UserLogic extends AbstractAnyLogic<UserTO, UserMod> {
         UserMod actual = anyTransformer.transform(userMod);
         LOG.debug("Transformed: {}", actual);
 
-        Map.Entry<Long, List<PropagationStatus>> updated = provisioningManager.update(actual);
+        // security checks
+        UserTO toUpdate = binder.getUserTO(userMod.getKey());
+        Set<String> requestedRealms = new HashSet<>();
+        requestedRealms.add(toUpdate.getRealm());
+        if (StringUtils.isNotBlank(actual.getRealm())) {
+            requestedRealms.add(actual.getRealm());
+        }
+        Set<String> effectiveRealms = getEffectiveRealms(
+                AuthContextUtils.getAuthorizations().get(Entitlement.USER_UPDATE),
+                requestedRealms);
+        securityChecks(effectiveRealms, toUpdate.getRealm(), toUpdate.getKey());
+        if (StringUtils.isNotBlank(actual.getRealm())) {
+            securityChecks(effectiveRealms, actual.getRealm(), toUpdate.getKey());
+        }
+
+        return doUpdate(actual);
+    }
+
+    protected UserTO doUpdate(final UserMod userMod) {
+        Map.Entry<Long, List<PropagationStatus>> updated = provisioningManager.update(userMod);
 
         UserTO updatedTO = binder.getUserTO(updated.getKey());
         updatedTO.getPropagationStatusTOs().addAll(updated.getValue());
@@ -267,8 +285,15 @@ public class UserLogic extends AbstractAnyLogic<UserTO, UserMod> {
 
     @PreAuthorize("hasRole('" + Entitlement.USER_UPDATE + "')")
     public UserTO status(final StatusMod statusMod) {
+        // security checks
+        UserTO toUpdate = binder.getUserTO(statusMod.getKey());
+        Set<String> effectiveRealms = getEffectiveRealms(
+                AuthContextUtils.getAuthorizations().get(Entitlement.USER_UPDATE),
+                Collections.singleton(toUpdate.getRealm()));
+        securityChecks(effectiveRealms, toUpdate.getRealm(), toUpdate.getKey());
+
         Map.Entry<Long, List<PropagationStatus>> updated = setStatusOnWfAdapter(statusMod);
-        final UserTO savedTO = binder.getUserTO(updated.getKey());
+        UserTO savedTO = binder.getUserTO(updated.getKey());
         savedTO.getPropagationStatusTOs().addAll(updated.getValue());
         return savedTO;
     }
@@ -305,15 +330,26 @@ public class UserLogic extends AbstractAnyLogic<UserTO, UserMod> {
     }
 
     @PreAuthorize("isAuthenticated() and not(hasRole('" + Entitlement.ANONYMOUS + "'))")
-    public UserTO deleteSelf() {
+    public UserTO selfDelete() {
         UserTO userTO = binder.getAuthenticatedUserTO();
 
-        return delete(userTO.getKey());
+        return doDelete(userTO.getKey());
     }
 
     @PreAuthorize("hasRole('" + Entitlement.USER_DELETE + "')")
     @Override
     public UserTO delete(final Long key) {
+        // security checks
+        UserTO toDelete = binder.getUserTO(key);
+        Set<String> effectiveRealms = getEffectiveRealms(
+                AuthContextUtils.getAuthorizations().get(Entitlement.USER_DELETE),
+                Collections.singleton(toDelete.getRealm()));
+        securityChecks(effectiveRealms, toDelete.getRealm(), toDelete.getKey());
+
+        return doDelete(key);
+    }
+
+    protected UserTO doDelete(final Long key) {
         List<Group> ownedGroups = groupDAO.findOwnedByUser(key);
         if (!ownedGroups.isEmpty()) {
             SyncopeClientException sce = SyncopeClientException.build(ClientExceptionType.GroupOwnership);
@@ -344,6 +380,13 @@ public class UserLogic extends AbstractAnyLogic<UserTO, UserMod> {
     @PreAuthorize("hasRole('" + Entitlement.USER_UPDATE + "')")
     @Override
     public UserTO unlink(final Long key, final Collection<String> resources) {
+        // security checks
+        UserTO user = binder.getUserTO(key);
+        Set<String> effectiveRealms = getEffectiveRealms(
+                AuthContextUtils.getAuthorizations().get(Entitlement.USER_UPDATE),
+                Collections.singleton(user.getRealm()));
+        securityChecks(effectiveRealms, user.getRealm(), user.getKey());
+
         UserMod userMod = new UserMod();
         userMod.setKey(key);
         userMod.getResourcesToRemove().addAll(resources);
@@ -354,6 +397,13 @@ public class UserLogic extends AbstractAnyLogic<UserTO, UserMod> {
     @PreAuthorize("hasRole('" + Entitlement.USER_UPDATE + "')")
     @Override
     public UserTO link(final Long key, final Collection<String> resources) {
+        // security checks
+        UserTO user = binder.getUserTO(key);
+        Set<String> effectiveRealms = getEffectiveRealms(
+                AuthContextUtils.getAuthorizations().get(Entitlement.USER_UPDATE),
+                Collections.singleton(user.getRealm()));
+        securityChecks(effectiveRealms, user.getRealm(), user.getKey());
+
         UserMod userMod = new UserMod();
         userMod.setKey(key);
         userMod.getResourcesToAdd().addAll(resources);
@@ -364,6 +414,13 @@ public class UserLogic extends AbstractAnyLogic<UserTO, UserMod> {
     @PreAuthorize("hasRole('" + Entitlement.USER_UPDATE + "')")
     @Override
     public UserTO unassign(final Long key, final Collection<String> resources) {
+        // security checks
+        UserTO user = binder.getUserTO(key);
+        Set<String> effectiveRealms = getEffectiveRealms(
+                AuthContextUtils.getAuthorizations().get(Entitlement.USER_UPDATE),
+                Collections.singleton(user.getRealm()));
+        securityChecks(effectiveRealms, user.getRealm(), user.getKey());
+
         UserMod userMod = new UserMod();
         userMod.setKey(key);
         userMod.getResourcesToRemove().addAll(resources);
@@ -378,6 +435,13 @@ public class UserLogic extends AbstractAnyLogic<UserTO, UserMod> {
             final boolean changepwd,
             final String password) {
 
+        // security checks
+        UserTO user = binder.getUserTO(key);
+        Set<String> effectiveRealms = getEffectiveRealms(
+                AuthContextUtils.getAuthorizations().get(Entitlement.USER_UPDATE),
+                Collections.singleton(user.getRealm()));
+        securityChecks(effectiveRealms, user.getRealm(), user.getKey());
+
         UserMod userMod = new UserMod();
         userMod.setKey(key);
         userMod.getResourcesToAdd().addAll(resources);
@@ -396,6 +460,13 @@ public class UserLogic extends AbstractAnyLogic<UserTO, UserMod> {
     @PreAuthorize("hasRole('" + Entitlement.USER_UPDATE + "')")
     @Override
     public UserTO deprovision(final Long key, final Collection<String> resources) {
+        // security checks
+        UserTO user = binder.getUserTO(key);
+        Set<String> effectiveRealms = getEffectiveRealms(
+                AuthContextUtils.getAuthorizations().get(Entitlement.USER_UPDATE),
+                Collections.singleton(user.getRealm()));
+        securityChecks(effectiveRealms, user.getRealm(), user.getKey());
+
         List<PropagationStatus> statuses = provisioningManager.deprovision(key, resources);
 
         UserTO updatedTO = binder.getUserTO(key);
@@ -411,10 +482,15 @@ public class UserLogic extends AbstractAnyLogic<UserTO, UserMod> {
             final boolean changePwd,
             final String password) {
 
-        UserTO original = binder.getUserTO(key);
-        original.getPropagationStatusTOs().addAll(provisioningManager.provision(key, changePwd, password, resources));
+        // security checks
+        UserTO user = binder.getUserTO(key);
+        Set<String> effectiveRealms = getEffectiveRealms(
+                AuthContextUtils.getAuthorizations().get(Entitlement.USER_UPDATE),
+                Collections.singleton(user.getRealm()));
+        securityChecks(effectiveRealms, user.getRealm(), user.getKey());
 
-        return original;
+        user.getPropagationStatusTOs().addAll(provisioningManager.provision(key, changePwd, password, resources));
+        return user;
     }
 
     @Override

http://git-wip-us.apache.org/repos/asf/syncope/blob/bcb9a0d7/core/misc/src/main/java/org/apache/syncope/core/misc/RealmUtils.java
----------------------------------------------------------------------
diff --git a/core/misc/src/main/java/org/apache/syncope/core/misc/RealmUtils.java b/core/misc/src/main/java/org/apache/syncope/core/misc/RealmUtils.java
index 7a921ee..d8bacdb 100644
--- a/core/misc/src/main/java/org/apache/syncope/core/misc/RealmUtils.java
+++ b/core/misc/src/main/java/org/apache/syncope/core/misc/RealmUtils.java
@@ -24,8 +24,8 @@ import java.util.Set;
 
 public final class RealmUtils {
 
-    public static String getGroupOwnerRealm(final String realmPath, final Long groupId) {
-        return realmPath + "@" + groupId;
+    public static String getGroupOwnerRealm(final String realmPath, final Long groupKey) {
+        return realmPath + "@" + groupKey;
     }
 
     public static boolean normalizingAddTo(final Set<String> realms, final String newRealm) {

http://git-wip-us.apache.org/repos/asf/syncope/blob/bcb9a0d7/core/misc/src/main/java/org/apache/syncope/core/misc/security/UnauthorizedException.java
----------------------------------------------------------------------
diff --git a/core/misc/src/main/java/org/apache/syncope/core/misc/security/UnauthorizedException.java b/core/misc/src/main/java/org/apache/syncope/core/misc/security/UnauthorizedException.java
index e5c2815..b2054cb 100644
--- a/core/misc/src/main/java/org/apache/syncope/core/misc/security/UnauthorizedException.java
+++ b/core/misc/src/main/java/org/apache/syncope/core/misc/security/UnauthorizedException.java
@@ -25,6 +25,9 @@ public class UnauthorizedException extends RuntimeException {
     private static final long serialVersionUID = 7540587364235915081L;
 
     public UnauthorizedException(final AnyTypeKind type, final Long key) {
-        super("Missing entitlement or realm administration for " + type + " " + key);
+        super("Missing entitlement or realm administration for "
+                + (key == null
+                        ? "new " + type
+                        : type + " " + key));
     }
 }

http://git-wip-us.apache.org/repos/asf/syncope/blob/bcb9a0d7/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPARoleDAO.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPARoleDAO.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPARoleDAO.java
index 6fb5ec3..168241f 100644
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPARoleDAO.java
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPARoleDAO.java
@@ -30,6 +30,7 @@ import org.apache.syncope.core.persistence.api.entity.Realm;
 import org.apache.syncope.core.persistence.api.entity.Role;
 import org.apache.syncope.core.persistence.api.entity.user.User;
 import org.apache.syncope.core.persistence.jpa.entity.JPARole;
+import org.apache.syncope.core.persistence.jpa.entity.user.JPAUser;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Repository;
 import org.springframework.transaction.annotation.Propagation;
@@ -95,6 +96,14 @@ public class JPARoleDAO extends AbstractDAO<Role, Long> implements RoleDAO {
 
     @Override
     public void delete(final Role role) {
+        TypedQuery<User> query = entityManager().createQuery(
+                "SELECT e FROM " + JPAUser.class.getSimpleName() + " e WHERE :role MEMBER OF e.roles", User.class);
+        query.setParameter("role", role);
+
+        for (User user : query.getResultList()) {
+            user.remove(role);
+        }
+
         entityManager().remove(role);
     }
 

http://git-wip-us.apache.org/repos/asf/syncope/blob/bcb9a0d7/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/outer/RoleTest.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/outer/RoleTest.java b/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/outer/RoleTest.java
index c9c7ef2..9764e07 100644
--- a/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/outer/RoleTest.java
+++ b/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/outer/RoleTest.java
@@ -160,4 +160,37 @@ public class RoleTest extends AbstractTest {
         dynRoleMemberships = findDynRoleMemberships(user);
         assertTrue(dynRoleMemberships.isEmpty());
     }
+
+    @Test
+    public void delete() {
+        // 0. create role
+        Role role = entityFactory.newEntity(Role.class);
+        role.setName("new");
+        role.addRealm(realmDAO.getRoot());
+        role.addRealm(realmDAO.find("/even/two"));
+        role.getEntitlements().add(Entitlement.LOG_LIST);
+        role.getEntitlements().add(Entitlement.LOG_SET_LEVEL);
+
+        role = roleDAO.save(role);
+        assertNotNull(role);
+
+        // 1. create user and assign that role
+        User user = entityFactory.newEntity(User.class);
+        user.setUsername("username");
+        user.setRealm(realmDAO.find("/even/two"));
+        user.add(role);
+
+        user = userDAO.save(user);
+        assertNotNull(user);
+
+        // 2. remove role
+        roleDAO.delete(role);
+
+        userDAO.flush();
+
+        // 3. verify that role was removed from user
+        user = userDAO.find(user.getKey());
+        assertNotNull(user);
+        assertTrue(user.getRoles().isEmpty());
+    }
 }

http://git-wip-us.apache.org/repos/asf/syncope/blob/bcb9a0d7/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/UserSelfServiceImpl.java
----------------------------------------------------------------------
diff --git a/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/UserSelfServiceImpl.java b/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/UserSelfServiceImpl.java
index 18013d2..4930bbb 100644
--- a/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/UserSelfServiceImpl.java
+++ b/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/UserSelfServiceImpl.java
@@ -48,7 +48,7 @@ public class UserSelfServiceImpl extends AbstractServiceImpl implements UserSelf
             throw sce;
         }
 
-        UserTO created = logic.createSelf(userTO, storePassword);
+        UserTO created = logic.selfCreate(userTO, storePassword);
         return createResponse(created.getKey(), created);
     }
 
@@ -64,13 +64,13 @@ public class UserSelfServiceImpl extends AbstractServiceImpl implements UserSelf
 
     @Override
     public Response update(final UserMod userMod) {
-        UserTO updated = logic.updateSelf(userMod);
+        UserTO updated = logic.selfUpdate(userMod);
         return modificationResponse(updated);
     }
 
     @Override
     public Response delete() {
-        UserTO deleted = logic.deleteSelf();
+        UserTO deleted = logic.selfDelete();
         return modificationResponse(deleted);
     }
 

http://git-wip-us.apache.org/repos/asf/syncope/blob/bcb9a0d7/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/AuthenticationITCase.java
----------------------------------------------------------------------
diff --git a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/AuthenticationITCase.java b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/AuthenticationITCase.java
index 6378631..cdfd1b1 100644
--- a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/AuthenticationITCase.java
+++ b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/AuthenticationITCase.java
@@ -28,7 +28,7 @@ import java.security.AccessControlException;
 import java.util.HashSet;
 import java.util.Map;
 import java.util.Set;
-
+import javax.ws.rs.core.Response;
 import org.apache.commons.collections4.CollectionUtils;
 import org.apache.commons.collections4.Predicate;
 import org.apache.commons.collections4.Transformer;
@@ -54,6 +54,7 @@ import org.apache.syncope.common.lib.types.ResourceDeassociationActionType;
 import org.apache.syncope.common.lib.types.SchemaType;
 import org.apache.syncope.common.lib.wrap.ResourceKey;
 import org.apache.syncope.common.rest.api.CollectionWrapper;
+import org.apache.syncope.common.rest.api.RESTHeaders;
 import org.apache.syncope.common.rest.api.service.SchemaService;
 import org.apache.syncope.common.rest.api.service.UserService;
 import org.apache.syncope.core.misc.security.Encryptor;
@@ -234,6 +235,94 @@ public class AuthenticationITCase extends AbstractITCase {
     }
 
     @Test
+    public void delegatedUserCRUD() {
+        Long roleKey = null;
+        Long delegatedAdminKey = null;
+        try {
+            // 1. create role for full user administration, under realm /even/two
+            RoleTO role = new RoleTO();
+            role.setName("Delegated user admin");
+            role.getEntitlements().add(Entitlement.USER_CREATE);
+            role.getEntitlements().add(Entitlement.USER_UPDATE);
+            role.getEntitlements().add(Entitlement.USER_DELETE);
+            role.getEntitlements().add(Entitlement.USER_LIST);
+            role.getEntitlements().add(Entitlement.USER_READ);
+            role.getRealms().add("/even/two");
+
+            roleKey = Long.valueOf(roleService.create(role).getHeaderString(RESTHeaders.RESOURCE_KEY));
+            assertNotNull(roleKey);
+
+            // 2. as admin, create delegated admin user, and assign the role just created
+            UserTO delegatedAdmin = UserITCase.getUniqueSampleTO("admin@syncope.apache.org");
+            delegatedAdmin.getRoles().add(roleKey);
+            delegatedAdmin = createUser(delegatedAdmin);
+            delegatedAdminKey = delegatedAdmin.getKey();
+
+            // 3. instantiate a delegate user service client, for further operatins
+            UserService delegatedUserService =
+                    clientFactory.create(delegatedAdmin.getUsername(), "password123").getService(UserService.class);
+
+            // 4. as delegated, create user under realm / -> fail
+            UserTO user = UserITCase.getUniqueSampleTO("delegated@syncope.apache.org");
+            try {
+                delegatedUserService.create(user);
+                fail();
+            } catch (SyncopeClientException e) {
+                assertEquals(ClientExceptionType.Unauthorized, e.getType());
+            }
+
+            // 5. set realm to /even/two -> succeed
+            user.setRealm("/even/two");
+
+            Response response = delegatedUserService.create(user);
+            assertEquals(Response.Status.CREATED.getStatusCode(), response.getStatus());
+
+            user = response.readEntity(UserTO.class);
+            assertEquals("surname", user.getPlainAttrMap().get("surname").getValues().get(0));
+
+            // 5. as delegated, update user attempting to move under realm / -> fail
+            UserMod userMod = new UserMod();
+            userMod.setKey(user.getKey());
+            userMod.setRealm("/odd");
+            userMod.getPlainAttrsToRemove().add("surname");
+            userMod.getPlainAttrsToUpdate().add(attrMod("surname", "surname2"));
+
+            try {
+                delegatedUserService.update(userMod);
+                fail();
+            } catch (SyncopeClientException e) {
+                assertEquals(ClientExceptionType.Unauthorized, e.getType());
+            }
+
+            // 6. revert realm change -> succeed
+            userMod.setRealm(null);
+
+            response = delegatedUserService.update(userMod);
+            assertEquals(Response.Status.OK.getStatusCode(), response.getStatus());
+
+            user = response.readEntity(UserTO.class);
+            assertEquals("surname2", user.getPlainAttrMap().get("surname").getValues().get(0));
+
+            // 7. as delegated, delete user
+            delegatedUserService.delete(user.getKey());
+
+            try {
+                userService.read(user.getKey());
+                fail();
+            } catch (SyncopeClientException e) {
+                assertEquals(ClientExceptionType.NotFound, e.getType());
+            }
+        } finally {
+            if (roleKey != null) {
+                roleService.delete(roleKey);
+            }
+            if (delegatedAdminKey != null) {
+                userService.delete(delegatedAdminKey);
+            }
+        }
+    }
+
+    @Test
     public void checkFailedLogins() {
         UserTO userTO = UserITCase.getUniqueSampleTO("checkFailedLogin@syncope.apache.org");
         userTO.getRoles().add(2L);


[16/31] syncope git commit: [SYNCOPE-652] Still several things to refine, but it starts taking shape

Posted by md...@apache.org.
http://git-wip-us.apache.org/repos/asf/syncope/blob/6dfedd8f/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/inner/MultitenancyTest.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/inner/MultitenancyTest.java b/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/inner/MultitenancyTest.java
new file mode 100644
index 0000000..a39de84
--- /dev/null
+++ b/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/inner/MultitenancyTest.java
@@ -0,0 +1,111 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.syncope.core.persistence.jpa.inner;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
+
+import java.util.ArrayList;
+import java.util.List;
+import org.apache.commons.collections4.CollectionUtils;
+import org.apache.commons.collections4.Transformer;
+import org.apache.syncope.common.lib.SyncopeConstants;
+import org.apache.syncope.common.lib.types.CipherAlgorithm;
+import org.apache.syncope.common.lib.types.Entitlement;
+import org.apache.syncope.core.misc.security.SyncopeAuthenticationDetails;
+import org.apache.syncope.core.misc.security.SyncopeGrantedAuthority;
+import org.apache.syncope.core.persistence.api.dao.PlainSchemaDAO;
+import org.apache.syncope.core.persistence.api.dao.RealmDAO;
+import org.apache.syncope.core.persistence.api.dao.UserDAO;
+import org.apache.syncope.core.persistence.api.entity.user.User;
+import org.apache.syncope.core.persistence.jpa.AbstractTest;
+import org.junit.AfterClass;
+import org.junit.BeforeClass;
+import org.junit.Test;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
+import org.springframework.security.core.GrantedAuthority;
+import org.springframework.security.core.context.SecurityContextHolder;
+import org.springframework.test.context.transaction.TransactionConfiguration;
+import org.springframework.transaction.annotation.Transactional;
+
+@TransactionConfiguration(transactionManager = "TwoTransactionManager")
+@Transactional
+public class MultitenancyTest extends AbstractTest {
+
+    @Autowired
+    private PlainSchemaDAO plainSchemaDAO;
+
+    @Autowired
+    private RealmDAO realmDAO;
+
+    @Autowired
+    private UserDAO userDAO;
+
+    @BeforeClass
+    public static void setAuthContext() {
+        List<GrantedAuthority> authorities = CollectionUtils.collect(Entitlement.values(),
+                new Transformer<String, GrantedAuthority>() {
+
+                    @Override
+                    public GrantedAuthority transform(final String entitlement) {
+                        return new SyncopeGrantedAuthority(entitlement, SyncopeConstants.ROOT_REALM);
+                    }
+                }, new ArrayList<GrantedAuthority>());
+
+        UsernamePasswordAuthenticationToken auth = new UsernamePasswordAuthenticationToken(
+                new org.springframework.security.core.userdetails.User(
+                        "admin", "FAKE_PASSWORD", authorities), "FAKE_PASSWORD", authorities);
+        auth.setDetails(new SyncopeAuthenticationDetails("Two"));
+        SecurityContextHolder.getContext().setAuthentication(auth);
+    }
+
+    @AfterClass
+    public static void unsetAuthContext() {
+        SecurityContextHolder.getContext().setAuthentication(null);
+    }
+
+    @Test
+    public void readPlainSchemas() {
+        assertEquals(18, plainSchemaDAO.findAll().size());
+    }
+
+    @Test
+    public void readRealm() {
+        assertEquals(1, realmDAO.findAll().size());
+        assertEquals(realmDAO.getRoot(), realmDAO.findAll().get(0));
+    }
+
+    @Test
+    public void createUser() {
+        assertNull(realmDAO.getRoot().getPasswordPolicy());
+        assertTrue(userDAO.findAll(SyncopeConstants.FULL_ADMIN_REALMS, 1, 1000).isEmpty());
+
+        User user = entityFactory.newEntity(User.class);
+        user.setRealm(realmDAO.getRoot());
+        user.setPassword("password", CipherAlgorithm.SHA256);
+        user.setUsername("username");
+
+        User actual = userDAO.save(user);
+        assertNotNull("expected save to work", actual);
+        assertEquals(0, actual.getPasswordHistory().size());
+    }
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/6dfedd8f/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/inner/UserTest.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/inner/UserTest.java b/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/inner/UserTest.java
index a709638..a7e0d83 100644
--- a/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/inner/UserTest.java
+++ b/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/inner/UserTest.java
@@ -142,6 +142,7 @@ public class UserTest extends AbstractTest {
         User user = entityFactory.newEntity(User.class);
         user.setUsername("username");
         user.setRealm(realmDAO.find("/even/two"));
+        user.setCreator("admin");
         user.setCreationDate(new Date());
 
         user.setPassword("pass", CipherAlgorithm.SHA256);
@@ -153,7 +154,7 @@ public class UserTest extends AbstractTest {
             assertNotNull(e);
         }
 
-        user.setPassword("password", CipherAlgorithm.SHA256);
+        user.setPassword("password123", CipherAlgorithm.SHA256);
 
         user.setUsername("username!");
 
@@ -186,6 +187,7 @@ public class UserTest extends AbstractTest {
         User user = entityFactory.newEntity(User.class);
         user.setUsername("username");
         user.setRealm(realmDAO.find("/even/two"));
+        user.setCreator("admin");
         user.setCreationDate(new Date());
 
         user.setPassword("password123", CipherAlgorithm.AES);

http://git-wip-us.apache.org/repos/asf/syncope/blob/6dfedd8f/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/outer/AnyTypeClassTest.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/outer/AnyTypeClassTest.java b/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/outer/AnyTypeClassTest.java
index d0f0213..c9e00bb 100644
--- a/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/outer/AnyTypeClassTest.java
+++ b/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/outer/AnyTypeClassTest.java
@@ -23,7 +23,6 @@ import static org.junit.Assert.assertNotNull;
 
 import static org.junit.Assert.assertTrue;
 
-import javax.persistence.EntityManager;
 import org.apache.syncope.common.lib.types.AttrSchemaType;
 import org.apache.syncope.core.persistence.api.dao.AnyTypeClassDAO;
 import org.apache.syncope.core.persistence.api.dao.PlainSchemaDAO;
@@ -43,9 +42,6 @@ public class AnyTypeClassTest extends AbstractTest {
     @Autowired
     private AnyTypeClassDAO anyTypeClassDAO;
 
-    @Autowired
-    private EntityManager entityManager;
-
     @Test
     public void create() {
         PlainSchema newSchema = entityFactory.newEntity(PlainSchema.class);

http://git-wip-us.apache.org/repos/asf/syncope/blob/6dfedd8f/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/outer/GroupTest.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/outer/GroupTest.java b/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/outer/GroupTest.java
index d208106..0777854 100644
--- a/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/outer/GroupTest.java
+++ b/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/outer/GroupTest.java
@@ -63,9 +63,6 @@ import org.springframework.transaction.annotation.Transactional;
 public class GroupTest extends AbstractTest {
 
     @Autowired
-    private EntityManager entityManager;
-
-    @Autowired
     private AnyTypeDAO anyTypeDAO;
 
     @Autowired
@@ -144,7 +141,7 @@ public class GroupTest extends AbstractTest {
      * this test class is architected.
      */
     private Collection<Group> findDynGroupMemberships(final User user) {
-        TypedQuery<Group> query = entityManager.createQuery(
+        TypedQuery<Group> query = entityManager().createQuery(
                 "SELECT e.group FROM " + JPAUDynGroupMembership.class.getSimpleName()
                 + " e WHERE :user MEMBER OF e.users", Group.class);
         query.setParameter("user", user);
@@ -226,7 +223,7 @@ public class GroupTest extends AbstractTest {
 
         groupDAO.flush();
 
-        assertNull(entityManager.find(JPAUDynGroupMembership.class, dynMembershipKey));
+        assertNull(entityManager().find(JPAUDynGroupMembership.class, dynMembershipKey));
 
         dynGroupMemberships = findDynGroupMemberships(user);
         assertTrue(dynGroupMemberships.isEmpty());
@@ -238,7 +235,7 @@ public class GroupTest extends AbstractTest {
      * this test class is architected.
      */
     private List<Group> findDynGroupMemberships(final AnyObject anyObject) {
-        TypedQuery<Group> query = entityManager.createQuery(
+        TypedQuery<Group> query = entityManager().createQuery(
                 "SELECT e.group FROM " + JPAADynGroupMembership.class.getSimpleName()
                 + " e WHERE :anyObject MEMBER OF e.anyObjects", Group.class);
         query.setParameter("anyObject", anyObject);
@@ -319,7 +316,7 @@ public class GroupTest extends AbstractTest {
 
         groupDAO.flush();
 
-        assertNull(entityManager.find(JPAADynGroupMembership.class, dynMembershipKey));
+        assertNull(entityManager().find(JPAADynGroupMembership.class, dynMembershipKey));
 
         dynGroupMemberships = findDynGroupMemberships(anyObject);
         assertTrue(dynGroupMemberships.isEmpty());

http://git-wip-us.apache.org/repos/asf/syncope/blob/6dfedd8f/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/outer/ResourceTest.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/outer/ResourceTest.java b/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/outer/ResourceTest.java
index d092f3d..0e9c8db 100644
--- a/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/outer/ResourceTest.java
+++ b/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/outer/ResourceTest.java
@@ -57,9 +57,6 @@ import org.springframework.transaction.annotation.Transactional;
 public class ResourceTest extends AbstractTest {
 
     @Autowired
-    private EntityManager entityManager;
-
-    @Autowired
     private ExternalResourceDAO resourceDAO;
 
     @Autowired
@@ -279,7 +276,7 @@ public class ResourceTest extends AbstractTest {
         resourceDAO.flush();
 
         for (Long itemId : itemKeys) {
-            assertNull(entityManager.find(JPAMappingItem.class, itemId));
+            assertNull(entityManager().find(JPAMappingItem.class, itemId));
         }
     }
 

http://git-wip-us.apache.org/repos/asf/syncope/blob/6dfedd8f/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/outer/RoleTest.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/outer/RoleTest.java b/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/outer/RoleTest.java
index 11b572c..c9c7ef2 100644
--- a/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/outer/RoleTest.java
+++ b/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/outer/RoleTest.java
@@ -26,7 +26,6 @@ import static org.junit.Assert.assertTrue;
 import java.util.Arrays;
 import java.util.Collection;
 import java.util.HashSet;
-import javax.persistence.EntityManager;
 import javax.persistence.TypedQuery;
 import org.apache.commons.collections4.CollectionUtils;
 import org.apache.commons.collections4.Transformer;
@@ -51,9 +50,6 @@ import org.springframework.transaction.annotation.Transactional;
 public class RoleTest extends AbstractTest {
 
     @Autowired
-    private EntityManager entityManager;
-
-    @Autowired
     private RoleDAO roleDAO;
 
     @Autowired
@@ -74,7 +70,7 @@ public class RoleTest extends AbstractTest {
      * this test class is architected.
      */
     private Collection<Role> findDynRoleMemberships(final User user) {
-        TypedQuery<Role> query = entityManager.createQuery(
+        TypedQuery<Role> query = entityManager().createQuery(
                 "SELECT e.role FROM " + JPADynRoleMembership.class.getSimpleName()
                 + " e WHERE :user MEMBER OF e.users", Role.class);
         query.setParameter("user", user);
@@ -159,7 +155,7 @@ public class RoleTest extends AbstractTest {
 
         roleDAO.flush();
 
-        assertNull(entityManager.find(JPADynRoleMembership.class, dynMembershipKey));
+        assertNull(entityManager().find(JPADynRoleMembership.class, dynMembershipKey));
 
         dynRoleMemberships = findDynRoleMemberships(user);
         assertTrue(dynRoleMemberships.isEmpty());

http://git-wip-us.apache.org/repos/asf/syncope/blob/6dfedd8f/core/persistence-jpa/src/test/resources/META-INF/persistence-enhance.xml
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/test/resources/META-INF/persistence-enhance.xml b/core/persistence-jpa/src/test/resources/META-INF/persistence-enhance.xml
index 8407b06..6b72247 100644
--- a/core/persistence-jpa/src/test/resources/META-INF/persistence-enhance.xml
+++ b/core/persistence-jpa/src/test/resources/META-INF/persistence-enhance.xml
@@ -23,7 +23,7 @@ under the License.
                                  http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd"
              version="2.0">
   
-  <persistence-unit name="syncopePersistenceUnit">
+  <persistence-unit name="Master">
     <mapping-file>META-INF/spring-orm.xml</mapping-file>
     <validation-mode>NONE</validation-mode>    
   </persistence-unit>


[04/31] syncope git commit: [SYNCOPE-652] Preliminary work (still struggling with OpenJPA slices)

Posted by md...@apache.org.
[SYNCOPE-652] Preliminary work (still struggling with OpenJPA slices)


Project: http://git-wip-us.apache.org/repos/asf/syncope/repo
Commit: http://git-wip-us.apache.org/repos/asf/syncope/commit/252b1510
Tree: http://git-wip-us.apache.org/repos/asf/syncope/tree/252b1510
Diff: http://git-wip-us.apache.org/repos/asf/syncope/diff/252b1510

Branch: refs/heads/SYNCOPE-156
Commit: 252b1510dcced12abca84c14c77288cf48d9d32e
Parents: ba7f1a5
Author: Francesco Chicchiriccò <il...@apache.org>
Authored: Fri Jul 17 12:05:06 2015 +0200
Committer: Francesco Chicchiriccò <il...@apache.org>
Committed: Thu Aug 13 17:16:50 2015 +0200

----------------------------------------------------------------------
 .travis.yml                                     |   3 +-
 .../client/lib/SyncopeClientFactoryBean.java    |  32 +++--
 .../syncope/common/lib/SyncopeConstants.java    |   2 +
 .../syncope/common/lib/jaxb/package-info.java   |  23 ++++
 .../apache/syncope/common/lib/to/DomainTO.java  |  62 +++++++++
 .../syncope/common/lib/types/Entitlement.java   |  10 ++
 .../syncope/common/rest/api/RESTHeaders.java    |   2 +
 .../common/rest/api/service/DomainService.java  |  96 +++++++++++++
 .../syncope/core/logic/AbstractLogic.java       |   3 -
 .../syncope/core/logic/AnyTypeClassLogic.java   |  36 ++---
 .../apache/syncope/core/logic/AnyTypeLogic.java |   2 +-
 .../apache/syncope/core/logic/DomainLogic.java  | 136 +++++++++++++++++++
 .../apache/syncope/core/logic/GroupLogic.java   |   2 +-
 core/misc/pom.xml                               |   7 +-
 .../core/misc/security/AuthContextUtils.java    |  23 +++-
 .../security/SyncopeAuthenticationDetails.java  |  86 ++++++++++++
 .../SyncopeAuthenticationDetailsSource.java     |  32 +++++
 .../security/SyncopeAuthenticationProvider.java |  51 ++++---
 .../misc/src/main/resources/securityContext.xml |   5 +-
 .../syncope/core/persistence/api/dao/DAO.java   |   2 +
 .../core/persistence/api/dao/DomainDAO.java     |  33 +++++
 .../core/persistence/api/entity/Domain.java     |  32 +++++
 core/persistence-jpa/pom.xml                    |  11 +-
 .../core/persistence/jpa/dao/AbstractDAO.java   |  12 ++
 .../persistence/jpa/dao/JPAAnySearchDAO.java    |   9 +-
 .../core/persistence/jpa/dao/JPADomainDAO.java  |  57 ++++++++
 .../core/persistence/jpa/dao/JPAUserDAO.java    |   4 +-
 .../jpa/entity/AnnotatedEntityListener.java     |   2 +-
 .../core/persistence/jpa/entity/JPADomain.java  |  79 +++++++++++
 .../jpa/entity/JPAEntityFactory.java            |   5 +-
 .../jpa/slice/DomainDistributionPolicy.java     |  36 +++++
 .../jpa/slice/DomainFinderTargetPolicy.java     |  38 ++++++
 .../jpa/slice/DomainQueryTargetPolicy.java      |  41 ++++++
 .../jpa/validation/entity/DomainCheck.java      |  41 ++++++
 .../jpa/validation/entity/DomainValidator.java  |  42 ++++++
 .../src/main/resources/persistence.properties   |   4 +-
 .../resources/persistenceContextEMFactory.xml   |  32 ++++-
 .../core/persistence/jpa/inner/UserTest.java    |  16 +--
 .../src/test/resources/persistence.properties   |   4 +-
 .../provisioning/api/data/DomainDataBinder.java |  31 +++++
 core/provisioning-java/pom.xml                  |   6 +
 .../java/data/DomainDataBinderImpl.java         |  70 ++++++++++
 .../java/data/UserDataBinderImpl.java           |   8 +-
 .../java/sync/AbstractProvisioningJob.java      |  22 +--
 .../syncope/core/rest/cxf/AddDomainFilter.java  |  39 ++++++
 .../syncope/core/rest/cxf/AddETagFilter.java    |  48 +++++++
 .../core/rest/cxf/service/AddETagFilter.java    |  50 -------
 .../rest/cxf/service/DomainServiceImpl.java     |  66 +++++++++
 .../src/main/resources/restCXFContext.xml       |   6 +-
 .../activiti/ActivitiUserWorkflowAdapter.java   |  10 +-
 fit/core-reference/pom.xml                      |   2 +-
 pom.xml                                         |   9 +-
 52 files changed, 1326 insertions(+), 154 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/syncope/blob/252b1510/.travis.yml
----------------------------------------------------------------------
diff --git a/.travis.yml b/.travis.yml
index 0e6f5c4..e17fd2c 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -19,6 +19,7 @@ jdk:
 # default install is mvn install --quiet -DskipTests=true
 install: mvn --show-version --quiet -P all,skipTests
 #invoker.streamLogs: we cannot access to log files through Travis web ui, so display everything in the console
-script: mvn --show-version --quiet clean install -Dinvoker.streamLogs=true
+#script: mvn --show-version --quiet clean install -Dinvoker.streamLogs=true
+script: mvn --show-version --quiet -PskipTests -Dinvoker.streamLogs=true
 notifications:
   webhooks: http://rovere.tirasa.net/cgi-bin/travis.cgi

http://git-wip-us.apache.org/repos/asf/syncope/blob/252b1510/client/lib/src/main/java/org/apache/syncope/client/lib/SyncopeClientFactoryBean.java
----------------------------------------------------------------------
diff --git a/client/lib/src/main/java/org/apache/syncope/client/lib/SyncopeClientFactoryBean.java b/client/lib/src/main/java/org/apache/syncope/client/lib/SyncopeClientFactoryBean.java
index 24923f1..a3a271c 100644
--- a/client/lib/src/main/java/org/apache/syncope/client/lib/SyncopeClientFactoryBean.java
+++ b/client/lib/src/main/java/org/apache/syncope/client/lib/SyncopeClientFactoryBean.java
@@ -20,6 +20,7 @@ package org.apache.syncope.client.lib;
 
 import com.fasterxml.jackson.jaxrs.json.JacksonJaxbJsonProvider;
 import java.util.ArrayList;
+import java.util.Collections;
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
@@ -31,6 +32,7 @@ import org.apache.cxf.feature.LoggingFeature;
 import org.apache.cxf.jaxrs.provider.JAXBElementProvider;
 import org.apache.cxf.staxutils.DocumentDepthProperties;
 import org.apache.syncope.common.lib.to.AbstractPolicyTO;
+import org.apache.syncope.common.rest.api.RESTHeaders;
 
 /**
  * Factory bean for creating instances of {@link SyncopeClient}.
@@ -62,8 +64,7 @@ public class SyncopeClientFactoryBean {
 
     private JacksonJaxbJsonProvider jsonProvider;
 
-    @SuppressWarnings("rawtypes")
-    private JAXBElementProvider jaxbProvider;
+    private JAXBElementProvider<?> jaxbProvider;
 
     private RestClientExceptionMapper exceptionMapper;
 
@@ -71,21 +72,23 @@ public class SyncopeClientFactoryBean {
 
     private ContentType contentType;
 
+    private String domain;
+
     private RestClientFactoryBean restClientFactoryBean;
 
     protected JacksonJaxbJsonProvider defaultJsonProvider() {
         return new JacksonJaxbJsonProvider();
     }
 
-    @SuppressWarnings({ "unchecked", "rawtypes" })
-    protected JAXBElementProvider defaultJAXBProvider() {
-        JAXBElementProvider defaultJAXBProvider = new JAXBElementProvider();
+    @SuppressWarnings({ "rawtypes" })
+    protected JAXBElementProvider<?> defaultJAXBProvider() {
+        JAXBElementProvider<?> defaultJAXBProvider = new JAXBElementProvider();
 
         DocumentDepthProperties depthProperties = new DocumentDepthProperties();
         depthProperties.setInnerElementCountThreshold(500);
         defaultJAXBProvider.setDepthProperties(depthProperties);
 
-        Map marshallerProperties = new HashMap();
+        Map<String, Object> marshallerProperties = new HashMap<>();
         marshallerProperties.put(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE);
         defaultJAXBProvider.setMarshallerProperties(marshallerProperties);
 
@@ -108,6 +111,10 @@ public class SyncopeClientFactoryBean {
         }
         defaultRestClientFactoryBean.setAddress(address);
 
+        if (StringUtils.isNotBlank(domain)) {
+            defaultRestClientFactoryBean.setHeaders(Collections.singletonMap(RESTHeaders.DOMAIN, domain));
+        }
+
         defaultRestClientFactoryBean.setThreadSafe(true);
         defaultRestClientFactoryBean.setInheritHeaders(true);
 
@@ -134,13 +141,13 @@ public class SyncopeClientFactoryBean {
         this.jsonProvider = jsonProvider;
     }
 
-    public JAXBElementProvider getJaxbProvider() {
+    public JAXBElementProvider<?> getJaxbProvider() {
         return jaxbProvider == null
                 ? defaultJAXBProvider()
                 : jaxbProvider;
     }
 
-    public SyncopeClientFactoryBean setJaxbProvider(final JAXBElementProvider jaxbProvider) {
+    public SyncopeClientFactoryBean setJaxbProvider(final JAXBElementProvider<?> jaxbProvider) {
         this.jaxbProvider = jaxbProvider;
         return this;
     }
@@ -181,6 +188,15 @@ public class SyncopeClientFactoryBean {
         return this;
     }
 
+    public String getDomain() {
+        return domain;
+    }
+
+    public SyncopeClientFactoryBean setDomain(final String domain) {
+        this.domain = domain;
+        return this;
+    }
+
     public RestClientFactoryBean getRestClientFactoryBean() {
         return restClientFactoryBean == null
                 ? defaultRestClientFactoryBean()

http://git-wip-us.apache.org/repos/asf/syncope/blob/252b1510/common/lib/src/main/java/org/apache/syncope/common/lib/SyncopeConstants.java
----------------------------------------------------------------------
diff --git a/common/lib/src/main/java/org/apache/syncope/common/lib/SyncopeConstants.java b/common/lib/src/main/java/org/apache/syncope/common/lib/SyncopeConstants.java
index 6538ec0..dbce5de 100644
--- a/common/lib/src/main/java/org/apache/syncope/common/lib/SyncopeConstants.java
+++ b/common/lib/src/main/java/org/apache/syncope/common/lib/SyncopeConstants.java
@@ -27,6 +27,8 @@ public final class SyncopeConstants {
 
     public static final String NAMESPACE = "http://syncope.apache.org/2.0";
 
+    public static final String MASTER_DOMAIN = "Master";
+
     public static final String ROOT_REALM = "/";
 
     public static final Set<String> FULL_ADMIN_REALMS = Collections.singleton("/");

http://git-wip-us.apache.org/repos/asf/syncope/blob/252b1510/common/lib/src/main/java/org/apache/syncope/common/lib/jaxb/package-info.java
----------------------------------------------------------------------
diff --git a/common/lib/src/main/java/org/apache/syncope/common/lib/jaxb/package-info.java b/common/lib/src/main/java/org/apache/syncope/common/lib/jaxb/package-info.java
new file mode 100644
index 0000000..a04b95d
--- /dev/null
+++ b/common/lib/src/main/java/org/apache/syncope/common/lib/jaxb/package-info.java
@@ -0,0 +1,23 @@
+/*
+ * 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.
+ */
+@XmlSchema(namespace = SyncopeConstants.NAMESPACE)
+package org.apache.syncope.common.lib.jaxb;
+
+import javax.xml.bind.annotation.XmlSchema;
+import org.apache.syncope.common.lib.SyncopeConstants;

http://git-wip-us.apache.org/repos/asf/syncope/blob/252b1510/common/lib/src/main/java/org/apache/syncope/common/lib/to/DomainTO.java
----------------------------------------------------------------------
diff --git a/common/lib/src/main/java/org/apache/syncope/common/lib/to/DomainTO.java b/common/lib/src/main/java/org/apache/syncope/common/lib/to/DomainTO.java
new file mode 100644
index 0000000..3f05e19
--- /dev/null
+++ b/common/lib/src/main/java/org/apache/syncope/common/lib/to/DomainTO.java
@@ -0,0 +1,62 @@
+/*
+ * 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.common.lib.to;
+
+import javax.xml.bind.annotation.XmlRootElement;
+import javax.xml.bind.annotation.XmlType;
+import org.apache.syncope.common.lib.AbstractBaseBean;
+import org.apache.syncope.common.lib.types.CipherAlgorithm;
+
+@XmlRootElement(name = "domain")
+@XmlType
+public class DomainTO extends AbstractBaseBean {
+
+    private static final long serialVersionUID = -7938075259986084934L;
+
+    private String key;
+
+    private String adminPwd;
+
+    private CipherAlgorithm adminCipherAlgorithm;
+
+    public String getKey() {
+        return key;
+    }
+
+    public void setKey(final String key) {
+        this.key = key;
+    }
+
+    public String getAdminPwd() {
+        return adminPwd;
+    }
+
+    public void setAdminPwd(final String adminPwd) {
+        this.adminPwd = adminPwd;
+    }
+
+    public CipherAlgorithm getAdminCipherAlgorithm() {
+        return adminCipherAlgorithm;
+    }
+
+    public void setAdminCipherAlgorithm(final CipherAlgorithm adminCipherAlgorithm) {
+        this.adminCipherAlgorithm = adminCipherAlgorithm;
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/252b1510/common/lib/src/main/java/org/apache/syncope/common/lib/types/Entitlement.java
----------------------------------------------------------------------
diff --git a/common/lib/src/main/java/org/apache/syncope/common/lib/types/Entitlement.java b/common/lib/src/main/java/org/apache/syncope/common/lib/types/Entitlement.java
index 806aaa4..85befc6 100644
--- a/common/lib/src/main/java/org/apache/syncope/common/lib/types/Entitlement.java
+++ b/common/lib/src/main/java/org/apache/syncope/common/lib/types/Entitlement.java
@@ -28,6 +28,16 @@ public final class Entitlement {
 
     public static final String ANONYMOUS = "ANONYMOUS";
 
+    public static final String DOMAIN_LIST = "DOMAIN_LIST";
+
+    public static final String DOMAIN_CREATE = "DOMAIN_CREATE";
+
+    public static final String DOMAIN_READ = "DOMAIN_READ";
+
+    public static final String DOMAIN_UPDATE = "DOMAIN_UPDATE";
+
+    public static final String DOMAIN_DELETE = "DOMAIN_DELETE";
+
     public static final String REALM_LIST = "REALM_LIST";
 
     public static final String REALM_CREATE = "REALM_CREATE";

http://git-wip-us.apache.org/repos/asf/syncope/blob/252b1510/common/rest-api/src/main/java/org/apache/syncope/common/rest/api/RESTHeaders.java
----------------------------------------------------------------------
diff --git a/common/rest-api/src/main/java/org/apache/syncope/common/rest/api/RESTHeaders.java b/common/rest-api/src/main/java/org/apache/syncope/common/rest/api/RESTHeaders.java
index 4d19e31..13b30df 100644
--- a/common/rest-api/src/main/java/org/apache/syncope/common/rest/api/RESTHeaders.java
+++ b/common/rest-api/src/main/java/org/apache/syncope/common/rest/api/RESTHeaders.java
@@ -23,6 +23,8 @@ package org.apache.syncope.common.rest.api;
  */
 public final class RESTHeaders {
 
+    public static final String DOMAIN = "X-Syncope-Domain";
+
     public static final String USER_KEY = "X-Syncope-User-Key";
 
     public static final String USERNAME = "X-Syncope-Username";

http://git-wip-us.apache.org/repos/asf/syncope/blob/252b1510/common/rest-api/src/main/java/org/apache/syncope/common/rest/api/service/DomainService.java
----------------------------------------------------------------------
diff --git a/common/rest-api/src/main/java/org/apache/syncope/common/rest/api/service/DomainService.java b/common/rest-api/src/main/java/org/apache/syncope/common/rest/api/service/DomainService.java
new file mode 100644
index 0000000..4076dc1
--- /dev/null
+++ b/common/rest-api/src/main/java/org/apache/syncope/common/rest/api/service/DomainService.java
@@ -0,0 +1,96 @@
+/*
+ * 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.common.rest.api.service;
+
+import java.util.List;
+import javax.validation.constraints.NotNull;
+import javax.ws.rs.Consumes;
+import javax.ws.rs.DELETE;
+import javax.ws.rs.GET;
+import javax.ws.rs.POST;
+import javax.ws.rs.PUT;
+import javax.ws.rs.Path;
+import javax.ws.rs.PathParam;
+import javax.ws.rs.Produces;
+import javax.ws.rs.core.MediaType;
+import javax.ws.rs.core.Response;
+import org.apache.cxf.jaxrs.model.wadl.Description;
+import org.apache.cxf.jaxrs.model.wadl.Descriptions;
+import org.apache.cxf.jaxrs.model.wadl.DocTarget;
+import org.apache.syncope.common.lib.to.DomainTO;
+
+/**
+ * REST operations for domains.
+ */
+@Path("domains")
+public interface DomainService extends JAXRSService {
+
+    /**
+     * Returns a list of all domains.
+     *
+     * @return list of all domains.
+     */
+    @GET
+    @Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
+    List<DomainTO> list();
+
+    /**
+     * Returns domain with matching key.
+     *
+     * @param key domain key to be read
+     * @return domain with matching key
+     */
+    @GET
+    @Path("{key}")
+    @Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
+    DomainTO read(@NotNull @PathParam("key") String key);
+
+    /**
+     * Creates a new domain.
+     *
+     * @param domainTO domain to be created
+     * @return <tt>Response</tt> object featuring <tt>Location</tt> header of created domain
+     */
+    @Descriptions({
+        @Description(target = DocTarget.RESPONSE,
+                value = "Featuring <tt>Location</tt> header of created domain")
+    })
+    @POST
+    @Consumes({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
+    Response create(@NotNull DomainTO domainTO);
+
+    /**
+     * Updates the domain matching the provided key.
+     *
+     * @param domainTO domain to be stored
+     */
+    @PUT
+    @Path("{key}")
+    @Consumes({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
+    void update(@NotNull DomainTO domainTO);
+
+    /**
+     * Deletes the domain matching the provided key.
+     *
+     * @param key domain key to be deleted
+     */
+    @DELETE
+    @Path("{key}")
+    void delete(@NotNull @PathParam("key") String key);
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/252b1510/core/logic/src/main/java/org/apache/syncope/core/logic/AbstractLogic.java
----------------------------------------------------------------------
diff --git a/core/logic/src/main/java/org/apache/syncope/core/logic/AbstractLogic.java b/core/logic/src/main/java/org/apache/syncope/core/logic/AbstractLogic.java
index 35e806a..6aa375c 100644
--- a/core/logic/src/main/java/org/apache/syncope/core/logic/AbstractLogic.java
+++ b/core/logic/src/main/java/org/apache/syncope/core/logic/AbstractLogic.java
@@ -31,9 +31,6 @@ import org.springframework.transaction.annotation.Transactional;
  */
 abstract class AbstractLogic<T extends AbstractBaseBean> {
 
-    /**
-     * Logger.
-     */
     protected static final Logger LOG = LoggerFactory.getLogger(AbstractLogic.class);
 
     /**

http://git-wip-us.apache.org/repos/asf/syncope/blob/252b1510/core/logic/src/main/java/org/apache/syncope/core/logic/AnyTypeClassLogic.java
----------------------------------------------------------------------
diff --git a/core/logic/src/main/java/org/apache/syncope/core/logic/AnyTypeClassLogic.java b/core/logic/src/main/java/org/apache/syncope/core/logic/AnyTypeClassLogic.java
index 8747631..1743370 100644
--- a/core/logic/src/main/java/org/apache/syncope/core/logic/AnyTypeClassLogic.java
+++ b/core/logic/src/main/java/org/apache/syncope/core/logic/AnyTypeClassLogic.java
@@ -42,11 +42,11 @@ public class AnyTypeClassLogic extends AbstractTransactionalLogic<AnyTypeClassTO
     private AnyTypeClassDataBinder binder;
 
     @Autowired
-    private AnyTypeClassDAO anyTypeDAO;
+    private AnyTypeClassDAO anyTypeClassDAO;
 
     @PreAuthorize("hasRole('" + Entitlement.ANYTYPECLASS_READ + "')")
     public AnyTypeClassTO read(final String key) {
-        AnyTypeClass anyType = anyTypeDAO.find(key);
+        AnyTypeClass anyType = anyTypeClassDAO.find(key);
         if (anyType == null) {
             LOG.error("Could not find anyType '" + key + "'");
 
@@ -58,7 +58,7 @@ public class AnyTypeClassLogic extends AbstractTransactionalLogic<AnyTypeClassTO
 
     @PreAuthorize("hasRole('" + Entitlement.ANYTYPECLASS_LIST + "')")
     public List<AnyTypeClassTO> list() {
-        return CollectionUtils.collect(anyTypeDAO.findAll(), new Transformer<AnyTypeClass, AnyTypeClassTO>() {
+        return CollectionUtils.collect(anyTypeClassDAO.findAll(), new Transformer<AnyTypeClass, AnyTypeClassTO>() {
 
             @Override
             public AnyTypeClassTO transform(final AnyTypeClass input) {
@@ -68,35 +68,35 @@ public class AnyTypeClassLogic extends AbstractTransactionalLogic<AnyTypeClassTO
     }
 
     @PreAuthorize("hasRole('" + Entitlement.ANYTYPECLASS_CREATE + "')")
-    public AnyTypeClassTO create(final AnyTypeClassTO anyTypeTO) {
-        return binder.getAnyTypeClassTO(anyTypeDAO.save(binder.create(anyTypeTO)));
+    public AnyTypeClassTO create(final AnyTypeClassTO anyTypeClassTO) {
+        return binder.getAnyTypeClassTO(anyTypeClassDAO.save(binder.create(anyTypeClassTO)));
     }
 
     @PreAuthorize("hasRole('" + Entitlement.ANYTYPECLASS_UPDATE + "')")
-    public AnyTypeClassTO update(final AnyTypeClassTO anyTypeTO) {
-        AnyTypeClass anyType = anyTypeDAO.find(anyTypeTO.getKey());
+    public AnyTypeClassTO update(final AnyTypeClassTO anyTypeClassTO) {
+        AnyTypeClass anyType = anyTypeClassDAO.find(anyTypeClassTO.getKey());
         if (anyType == null) {
-            LOG.error("Could not find anyType '" + anyTypeTO.getKey() + "'");
-            throw new NotFoundException(String.valueOf(anyTypeTO.getKey()));
+            LOG.error("Could not find anyTypeClass '" + anyTypeClassTO.getKey() + "'");
+            throw new NotFoundException(String.valueOf(anyTypeClassTO.getKey()));
         }
 
-        binder.update(anyType, anyTypeTO);
-        anyType = anyTypeDAO.save(anyType);
+        binder.update(anyType, anyTypeClassTO);
+        anyType = anyTypeClassDAO.save(anyType);
 
         return binder.getAnyTypeClassTO(anyType);
     }
 
     @PreAuthorize("hasRole('" + Entitlement.ANYTYPECLASS_DELETE + "')")
     public AnyTypeClassTO delete(final String key) {
-        AnyTypeClass anyType = anyTypeDAO.find(key);
-        if (anyType == null) {
-            LOG.error("Could not find anyType '" + key + "'");
+        AnyTypeClass anyTypeClass = anyTypeClassDAO.find(key);
+        if (anyTypeClass == null) {
+            LOG.error("Could not find anyTypeClass '" + key + "'");
 
             throw new NotFoundException(String.valueOf(key));
         }
 
-        AnyTypeClassTO deleted = binder.getAnyTypeClassTO(anyType);
-        anyTypeDAO.delete(key);
+        AnyTypeClassTO deleted = binder.getAnyTypeClassTO(anyTypeClass);
+        anyTypeClassDAO.delete(key);
         return deleted;
     }
 
@@ -108,7 +108,7 @@ public class AnyTypeClassLogic extends AbstractTransactionalLogic<AnyTypeClassTO
 
         if (ArrayUtils.isNotEmpty(args)) {
             for (int i = 0; key == null && i < args.length; i++) {
-                if (args[i] instanceof Long) {
+                if (args[i] instanceof String) {
                     key = (String) args[i];
                 } else if (args[i] instanceof AnyTypeClassTO) {
                     key = ((AnyTypeClassTO) args[i]).getKey();
@@ -118,7 +118,7 @@ public class AnyTypeClassLogic extends AbstractTransactionalLogic<AnyTypeClassTO
 
         if (StringUtils.isNotBlank(key)) {
             try {
-                return binder.getAnyTypeClassTO(anyTypeDAO.find(key));
+                return binder.getAnyTypeClassTO(anyTypeClassDAO.find(key));
             } catch (Throwable ignore) {
                 LOG.debug("Unresolved reference", ignore);
                 throw new UnresolvedReferenceException(ignore);

http://git-wip-us.apache.org/repos/asf/syncope/blob/252b1510/core/logic/src/main/java/org/apache/syncope/core/logic/AnyTypeLogic.java
----------------------------------------------------------------------
diff --git a/core/logic/src/main/java/org/apache/syncope/core/logic/AnyTypeLogic.java b/core/logic/src/main/java/org/apache/syncope/core/logic/AnyTypeLogic.java
index b0cfa03..1ff60c7 100644
--- a/core/logic/src/main/java/org/apache/syncope/core/logic/AnyTypeLogic.java
+++ b/core/logic/src/main/java/org/apache/syncope/core/logic/AnyTypeLogic.java
@@ -116,7 +116,7 @@ public class AnyTypeLogic extends AbstractTransactionalLogic<AnyTypeTO> {
 
         if (ArrayUtils.isNotEmpty(args)) {
             for (int i = 0; key == null && i < args.length; i++) {
-                if (args[i] instanceof Long) {
+                if (args[i] instanceof String) {
                     key = (String) args[i];
                 } else if (args[i] instanceof AnyTypeTO) {
                     key = ((AnyTypeTO) args[i]).getKey();

http://git-wip-us.apache.org/repos/asf/syncope/blob/252b1510/core/logic/src/main/java/org/apache/syncope/core/logic/DomainLogic.java
----------------------------------------------------------------------
diff --git a/core/logic/src/main/java/org/apache/syncope/core/logic/DomainLogic.java b/core/logic/src/main/java/org/apache/syncope/core/logic/DomainLogic.java
new file mode 100644
index 0000000..58f717d
--- /dev/null
+++ b/core/logic/src/main/java/org/apache/syncope/core/logic/DomainLogic.java
@@ -0,0 +1,136 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.syncope.core.logic;
+
+import java.lang.reflect.Method;
+import java.util.ArrayList;
+import java.util.List;
+import org.apache.commons.collections4.CollectionUtils;
+import org.apache.commons.collections4.Transformer;
+import org.apache.commons.lang3.ArrayUtils;
+import org.apache.commons.lang3.StringUtils;
+import org.apache.syncope.common.lib.to.DomainTO;
+import org.apache.syncope.common.lib.types.Entitlement;
+import org.apache.syncope.core.persistence.api.dao.NotFoundException;
+import org.apache.syncope.core.persistence.api.dao.DomainDAO;
+import org.apache.syncope.core.persistence.api.entity.Domain;
+import org.apache.syncope.core.provisioning.api.data.DomainDataBinder;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.security.access.prepost.PreAuthorize;
+import org.springframework.stereotype.Component;
+
+@Component
+public class DomainLogic extends AbstractTransactionalLogic<DomainTO> {
+
+    @Autowired
+    private DomainDataBinder binder;
+
+    @Autowired
+    private DomainDAO domainDAO;
+
+    @PreAuthorize("hasRole('" + Entitlement.DOMAIN_READ + "') and authentication.details.domain == "
+            + "T(org.apache.syncope.common.lib.SyncopeConstants).MASTER_DOMAIN")
+    public DomainTO read(final String key) {
+        Domain domain = domainDAO.find(key);
+        if (domain == null) {
+            LOG.error("Could not find domain '" + key + "'");
+
+            throw new NotFoundException(String.valueOf(key));
+        }
+
+        return binder.getDomainTO(domain);
+    }
+
+    @PreAuthorize("hasRole('" + Entitlement.DOMAIN_LIST + "') and authentication.details.domain == "
+            + "T(org.apache.syncope.common.lib.SyncopeConstants).MASTER_DOMAIN")
+    public List<DomainTO> list() {
+        return CollectionUtils.collect(domainDAO.findAll(), new Transformer<Domain, DomainTO>() {
+
+            @Override
+            public DomainTO transform(final Domain input) {
+                return binder.getDomainTO(input);
+            }
+        }, new ArrayList<DomainTO>());
+    }
+
+    @PreAuthorize("hasRole('" + Entitlement.DOMAIN_CREATE + "') and authentication.details.domain == "
+            + "T(org.apache.syncope.common.lib.SyncopeConstants).MASTER_DOMAIN")
+    public DomainTO create(final DomainTO domainTO) {
+        return binder.getDomainTO(domainDAO.save(binder.create(domainTO)));
+    }
+
+    @PreAuthorize("hasRole('" + Entitlement.DOMAIN_UPDATE + "') and authentication.details.domain == "
+            + "T(org.apache.syncope.common.lib.SyncopeConstants).MASTER_DOMAIN")
+    public DomainTO update(final DomainTO domainTO) {
+        Domain domain = domainDAO.find(domainTO.getKey());
+        if (domain == null) {
+            LOG.error("Could not find domain '" + domainTO.getKey() + "'");
+            throw new NotFoundException(String.valueOf(domainTO.getKey()));
+        }
+
+        binder.update(domain, domainTO);
+        domain = domainDAO.save(domain);
+
+        return binder.getDomainTO(domain);
+    }
+
+    @PreAuthorize("hasRole('" + Entitlement.DOMAIN_DELETE + "') and authentication.details.domain == "
+            + "T(org.apache.syncope.common.lib.SyncopeConstants).MASTER_DOMAIN")
+    public DomainTO delete(final String key) {
+        Domain domain = domainDAO.find(key);
+        if (domain == null) {
+            LOG.error("Could not find domain '" + key + "'");
+
+            throw new NotFoundException(String.valueOf(key));
+        }
+
+        DomainTO deleted = binder.getDomainTO(domain);
+        domainDAO.delete(key);
+        return deleted;
+    }
+
+    @Override
+    protected DomainTO resolveReference(final Method method, final Object... args)
+            throws UnresolvedReferenceException {
+
+        String key = null;
+
+        if (ArrayUtils.isNotEmpty(args)) {
+            for (int i = 0; key == null && i < args.length; i++) {
+                if (args[i] instanceof String) {
+                    key = (String) args[i];
+                } else if (args[i] instanceof DomainTO) {
+                    key = ((DomainTO) args[i]).getKey();
+                }
+            }
+        }
+
+        if (StringUtils.isNotBlank(key)) {
+            try {
+                return binder.getDomainTO(domainDAO.find(key));
+            } catch (Throwable ignore) {
+                LOG.debug("Unresolved reference", ignore);
+                throw new UnresolvedReferenceException(ignore);
+            }
+        }
+
+        throw new UnresolvedReferenceException();
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/252b1510/core/logic/src/main/java/org/apache/syncope/core/logic/GroupLogic.java
----------------------------------------------------------------------
diff --git a/core/logic/src/main/java/org/apache/syncope/core/logic/GroupLogic.java b/core/logic/src/main/java/org/apache/syncope/core/logic/GroupLogic.java
index ff5cd64..f476210 100644
--- a/core/logic/src/main/java/org/apache/syncope/core/logic/GroupLogic.java
+++ b/core/logic/src/main/java/org/apache/syncope/core/logic/GroupLogic.java
@@ -103,7 +103,7 @@ public class GroupLogic extends AbstractAnyLogic<GroupTO, GroupMod> {
     @Transactional(readOnly = true)
     public List<GroupTO> own() {
         return CollectionUtils.collect(
-                userDAO.findAllGroups(userDAO.find(AuthContextUtils.getAuthenticatedUsername())),
+                userDAO.findAllGroups(userDAO.find(AuthContextUtils.getUsername())),
                 new Transformer<Group, GroupTO>() {
 
                     @Override

http://git-wip-us.apache.org/repos/asf/syncope/blob/252b1510/core/misc/pom.xml
----------------------------------------------------------------------
diff --git a/core/misc/pom.xml b/core/misc/pom.xml
index d330ad6..d9c6049 100644
--- a/core/misc/pom.xml
+++ b/core/misc/pom.xml
@@ -100,11 +100,16 @@ under the License.
       <groupId>org.springframework.security</groupId>
       <artifactId>spring-security-web</artifactId>
     </dependency>
-        
+
     <dependency>
       <groupId>org.apache.syncope.core</groupId>
       <artifactId>syncope-core-provisioning-api</artifactId>
       <version>${project.version}</version>
+    </dependency>        
+    <dependency>
+      <groupId>org.apache.syncope.common</groupId>
+      <artifactId>syncope-common-rest-api</artifactId>
+      <version>${project.version}</version>
     </dependency>
     
     <!-- TEST -->

http://git-wip-us.apache.org/repos/asf/syncope/blob/252b1510/core/misc/src/main/java/org/apache/syncope/core/misc/security/AuthContextUtils.java
----------------------------------------------------------------------
diff --git a/core/misc/src/main/java/org/apache/syncope/core/misc/security/AuthContextUtils.java b/core/misc/src/main/java/org/apache/syncope/core/misc/security/AuthContextUtils.java
index 6eebf01..932627d 100644
--- a/core/misc/src/main/java/org/apache/syncope/core/misc/security/AuthContextUtils.java
+++ b/core/misc/src/main/java/org/apache/syncope/core/misc/security/AuthContextUtils.java
@@ -22,6 +22,7 @@ import java.util.HashMap;
 import java.util.Map;
 import java.util.Set;
 import org.apache.commons.collections4.MapUtils;
+import org.apache.commons.lang3.StringUtils;
 import org.apache.syncope.common.lib.SyncopeConstants;
 import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
 import org.springframework.security.core.Authentication;
@@ -32,24 +33,25 @@ import org.springframework.security.core.userdetails.User;
 
 public final class AuthContextUtils {
 
-    public static String getAuthenticatedUsername() {
+    public static String getUsername() {
         Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
         return authentication == null ? SyncopeConstants.UNAUTHENTICATED : authentication.getName();
     }
 
-    public static void updateAuthenticatedUsername(final String newUsername) {
+    public static void updateUsername(final String newUsername) {
         Authentication auth = SecurityContextHolder.getContext().getAuthentication();
 
-        Authentication newAuth = new UsernamePasswordAuthenticationToken(
+        UsernamePasswordAuthenticationToken newAuth = new UsernamePasswordAuthenticationToken(
                 new User(newUsername, "FAKE_PASSWORD", auth.getAuthorities()),
                 auth.getCredentials(), auth.getAuthorities());
+        newAuth.setDetails(auth.getDetails());
         SecurityContextHolder.getContext().setAuthentication(newAuth);
     }
 
     public static Map<String, Set<String>> getAuthorizations() {
         Map<String, Set<String>> result = null;
 
-        final SecurityContext ctx = SecurityContextHolder.getContext();
+        SecurityContext ctx = SecurityContextHolder.getContext();
         if (ctx != null && ctx.getAuthentication() != null && ctx.getAuthentication().getAuthorities() != null) {
             result = new HashMap<>();
             for (GrantedAuthority authority : ctx.getAuthentication().getAuthorities()) {
@@ -64,6 +66,19 @@ public final class AuthContextUtils {
         return MapUtils.emptyIfNull(result);
     }
 
+    public static String getDomain() {
+        Authentication auth = SecurityContextHolder.getContext().getAuthentication();
+
+        String domainKey = auth != null && auth.getDetails() instanceof SyncopeAuthenticationDetails
+                ? SyncopeAuthenticationDetails.class.cast(auth.getDetails()).getDomain()
+                : null;
+        if (StringUtils.isBlank(domainKey)) {
+            domainKey = SyncopeConstants.MASTER_DOMAIN;
+        }
+
+        return domainKey;
+    }
+
     /**
      * Private default constructor, for static-only classes.
      */

http://git-wip-us.apache.org/repos/asf/syncope/blob/252b1510/core/misc/src/main/java/org/apache/syncope/core/misc/security/SyncopeAuthenticationDetails.java
----------------------------------------------------------------------
diff --git a/core/misc/src/main/java/org/apache/syncope/core/misc/security/SyncopeAuthenticationDetails.java b/core/misc/src/main/java/org/apache/syncope/core/misc/security/SyncopeAuthenticationDetails.java
new file mode 100644
index 0000000..68b27f4
--- /dev/null
+++ b/core/misc/src/main/java/org/apache/syncope/core/misc/security/SyncopeAuthenticationDetails.java
@@ -0,0 +1,86 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.syncope.core.misc.security;
+
+import java.io.Serializable;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpSession;
+import org.apache.commons.lang3.builder.EqualsBuilder;
+import org.apache.commons.lang3.builder.HashCodeBuilder;
+import org.apache.commons.lang3.builder.ReflectionToStringBuilder;
+import org.apache.commons.lang3.builder.ToStringStyle;
+import org.apache.syncope.common.rest.api.RESTHeaders;
+
+public class SyncopeAuthenticationDetails implements Serializable {
+
+    private static final long serialVersionUID = -5899959397393502897L;
+
+    private final String remoteAddress;
+
+    private final String sessionId;
+
+    private String domain;
+
+    public SyncopeAuthenticationDetails(final HttpServletRequest request) {
+        this.remoteAddress = request.getRemoteAddr();
+
+        HttpSession session = request.getSession(false);
+        this.sessionId = session == null ? null : session.getId();
+
+        this.domain = request.getHeader(RESTHeaders.DOMAIN);
+    }
+
+    public SyncopeAuthenticationDetails(final String domain) {
+        this.remoteAddress = null;
+        this.sessionId = null;
+        this.domain = domain;
+    }
+
+    public String getRemoteAddress() {
+        return remoteAddress;
+    }
+
+    public String getSessionId() {
+        return sessionId;
+    }
+
+    public String getDomain() {
+        return domain;
+    }
+
+    public void setDomain(final String domain) {
+        this.domain = domain;
+    }
+
+    @Override
+    public boolean equals(final Object obj) {
+        return EqualsBuilder.reflectionEquals(this, obj);
+    }
+
+    @Override
+    public int hashCode() {
+        return HashCodeBuilder.reflectionHashCode(this);
+    }
+
+    @Override
+    public String toString() {
+        return ReflectionToStringBuilder.toString(this, ToStringStyle.MULTI_LINE_STYLE);
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/252b1510/core/misc/src/main/java/org/apache/syncope/core/misc/security/SyncopeAuthenticationDetailsSource.java
----------------------------------------------------------------------
diff --git a/core/misc/src/main/java/org/apache/syncope/core/misc/security/SyncopeAuthenticationDetailsSource.java b/core/misc/src/main/java/org/apache/syncope/core/misc/security/SyncopeAuthenticationDetailsSource.java
new file mode 100644
index 0000000..b943edf
--- /dev/null
+++ b/core/misc/src/main/java/org/apache/syncope/core/misc/security/SyncopeAuthenticationDetailsSource.java
@@ -0,0 +1,32 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.syncope.core.misc.security;
+
+import javax.servlet.http.HttpServletRequest;
+import org.springframework.security.authentication.AuthenticationDetailsSource;
+
+public class SyncopeAuthenticationDetailsSource
+        implements AuthenticationDetailsSource<HttpServletRequest, SyncopeAuthenticationDetails> {
+
+    @Override
+    public SyncopeAuthenticationDetails buildDetails(final HttpServletRequest context) {
+        return new SyncopeAuthenticationDetails(context);
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/252b1510/core/misc/src/main/java/org/apache/syncope/core/misc/security/SyncopeAuthenticationProvider.java
----------------------------------------------------------------------
diff --git a/core/misc/src/main/java/org/apache/syncope/core/misc/security/SyncopeAuthenticationProvider.java b/core/misc/src/main/java/org/apache/syncope/core/misc/security/SyncopeAuthenticationProvider.java
index 80d2b48..01abb93 100644
--- a/core/misc/src/main/java/org/apache/syncope/core/misc/security/SyncopeAuthenticationProvider.java
+++ b/core/misc/src/main/java/org/apache/syncope/core/misc/security/SyncopeAuthenticationProvider.java
@@ -23,14 +23,14 @@ import java.util.Iterator;
 import java.util.Set;
 import javax.annotation.Resource;
 import org.apache.commons.collections4.SetUtils;
-import org.apache.syncope.common.lib.types.AnyTypeKind;
+import org.apache.commons.lang3.StringUtils;
+import org.apache.syncope.common.lib.SyncopeConstants;
 import org.apache.syncope.common.lib.types.AuditElements;
 import org.apache.syncope.common.lib.types.AuditElements.Result;
 import org.apache.syncope.common.lib.types.CipherAlgorithm;
 import org.apache.syncope.core.persistence.api.dao.ConfDAO;
 import org.apache.syncope.core.persistence.api.dao.PolicyDAO;
 import org.apache.syncope.core.persistence.api.dao.UserDAO;
-import org.apache.syncope.core.persistence.api.entity.AnyUtils;
 import org.apache.syncope.core.persistence.api.entity.AnyUtilsFactory;
 import org.apache.syncope.core.persistence.api.entity.resource.ExternalResource;
 import org.apache.syncope.core.persistence.api.entity.conf.CPlainAttr;
@@ -39,7 +39,10 @@ import org.apache.syncope.core.provisioning.api.ConnectorFactory;
 import org.apache.syncope.core.misc.AuditManager;
 import org.apache.syncope.core.misc.MappingUtils;
 import org.apache.syncope.core.persistence.api.dao.AnyTypeDAO;
+import org.apache.syncope.core.persistence.api.dao.DomainDAO;
+import org.apache.syncope.core.persistence.api.dao.NotFoundException;
 import org.apache.syncope.core.persistence.api.dao.RealmDAO;
+import org.apache.syncope.core.persistence.api.entity.Domain;
 import org.apache.syncope.core.persistence.api.entity.Realm;
 import org.identityconnectors.framework.common.objects.Uid;
 import org.slf4j.Logger;
@@ -57,15 +60,15 @@ import org.springframework.transaction.annotation.Transactional;
 @Configurable
 public class SyncopeAuthenticationProvider implements AuthenticationProvider {
 
-    /**
-     * Logger.
-     */
     protected static final Logger LOG = LoggerFactory.getLogger(SyncopeAuthenticationProvider.class);
 
     @Autowired
     protected AuditManager auditManager;
 
     @Autowired
+    protected DomainDAO domainDAO;
+
+    @Autowired
     protected ConfDAO confDAO;
 
     @Autowired
@@ -131,18 +134,36 @@ public class SyncopeAuthenticationProvider implements AuthenticationProvider {
     @Transactional(noRollbackFor = { BadCredentialsException.class, DisabledException.class })
     public Authentication authenticate(final Authentication authentication) {
         boolean authenticated = false;
-        User user = null;
 
-        String username = authentication.getName();
-        if (anonymousUser.equals(username)) {
+        String domainKey = authentication.getDetails() instanceof SyncopeAuthenticationDetails
+                ? SyncopeAuthenticationDetails.class.cast(authentication.getDetails()).getDomain()
+                : null;
+        if (StringUtils.isBlank(domainKey)) {
+            domainKey = SyncopeConstants.MASTER_DOMAIN;
+        }
+        SyncopeAuthenticationDetails.class.cast(authentication.getDetails()).setDomain(domainKey);
+
+        if (anonymousUser.equals(authentication.getName())) {
             authenticated = authentication.getCredentials().toString().equals(anonymousKey);
-        } else if (adminUser.equals(username)) {
-            authenticated = encryptor.verify(
-                    authentication.getCredentials().toString(),
-                    CipherAlgorithm.valueOf(adminPasswordAlgorithm),
-                    adminPassword);
+        } else if (adminUser.equals(authentication.getName())) {
+            if (SyncopeConstants.MASTER_DOMAIN.equals(domainKey)) {
+                authenticated = encryptor.verify(
+                        authentication.getCredentials().toString(),
+                        CipherAlgorithm.valueOf(adminPasswordAlgorithm),
+                        adminPassword);
+            } else {
+                Domain domain = domainDAO.find(domainKey);
+                if (domain == null) {
+                    throw new NotFoundException("Could not find domain " + domainKey);
+                }
+
+                authenticated = encryptor.verify(
+                        authentication.getCredentials().toString(),
+                        domain.getAdminCipherAlgorithm(),
+                        domain.getAdminPwd());
+            }
         } else {
-            user = userDAO.find(username);
+            User user = userDAO.find(authentication.getName());
 
             if (user != null) {
                 if (user.isSuspended() != null && user.isSuspended()) {
@@ -166,7 +187,6 @@ public class SyncopeAuthenticationProvider implements AuthenticationProvider {
                     authentication.getPrincipal(),
                     null,
                     userDetailsService.loadUserByUsername(authentication.getPrincipal().toString()).getAuthorities());
-
             token.setDetails(authentication.getDetails());
 
             auditManager.audit(
@@ -257,7 +277,6 @@ public class SyncopeAuthenticationProvider implements AuthenticationProvider {
         boolean authenticated = encryptor.verify(password, user.getCipherAlgorithm(), user.getPassword());
         LOG.debug("{} authenticated on internal storage: {}", user.getUsername(), authenticated);
 
-        AnyUtils attrUtils = attrUtilsFactory.getInstance(AnyTypeKind.USER);
         for (Iterator<? extends ExternalResource> itor = getPassthroughResources(user).iterator();
                 itor.hasNext() && !authenticated;) {
 

http://git-wip-us.apache.org/repos/asf/syncope/blob/252b1510/core/misc/src/main/resources/securityContext.xml
----------------------------------------------------------------------
diff --git a/core/misc/src/main/resources/securityContext.xml b/core/misc/src/main/resources/securityContext.xml
index 00ced82..57b1980 100644
--- a/core/misc/src/main/resources/securityContext.xml
+++ b/core/misc/src/main/resources/securityContext.xml
@@ -49,9 +49,12 @@ under the License.
     <constructor-arg ref="securityContextRepository"/>
   </bean>
 
+  <bean id="syncopeAuthenticationDetailsSource"
+        class="org.apache.syncope.core.misc.security.SyncopeAuthenticationDetailsSource"/>
+
   <security:http security-context-repository-ref="securityContextRepository" realm="Apache Syncope authentication" 
                  use-expressions="false" disable-url-rewriting="false">
-    <security:http-basic/>
+    <security:http-basic authentication-details-source-ref="syncopeAuthenticationDetailsSource"/>
     <security:anonymous username="${anonymousUser}"/>
     <security:intercept-url pattern="/**"/>
     

http://git-wip-us.apache.org/repos/asf/syncope/blob/252b1510/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/DAO.java
----------------------------------------------------------------------
diff --git a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/DAO.java b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/DAO.java
index 4452890..eb00a0d 100644
--- a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/DAO.java
+++ b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/DAO.java
@@ -22,6 +22,8 @@ import org.apache.syncope.core.persistence.api.entity.Entity;
 
 public interface DAO<E extends Entity<KEY>, KEY> {
 
+    String getDomain(E entity);
+
     void refresh(E entity);
 
     void detach(E entity);

http://git-wip-us.apache.org/repos/asf/syncope/blob/252b1510/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/DomainDAO.java
----------------------------------------------------------------------
diff --git a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/DomainDAO.java b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/DomainDAO.java
new file mode 100644
index 0000000..ece1b16
--- /dev/null
+++ b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/DomainDAO.java
@@ -0,0 +1,33 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.syncope.core.persistence.api.dao;
+
+import java.util.List;
+import org.apache.syncope.core.persistence.api.entity.Domain;
+
+public interface DomainDAO extends DAO<Domain, String> {
+
+    Domain find(String key);
+
+    List<Domain> findAll();
+
+    Domain save(Domain domain);
+
+    void delete(String key);
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/252b1510/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/Domain.java
----------------------------------------------------------------------
diff --git a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/Domain.java b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/Domain.java
new file mode 100644
index 0000000..7c496f0
--- /dev/null
+++ b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/Domain.java
@@ -0,0 +1,32 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.syncope.core.persistence.api.entity;
+
+import org.apache.syncope.common.lib.types.CipherAlgorithm;
+
+public interface Domain extends Entity<String> {
+
+    void setKey(String name);
+
+    String getAdminPwd();
+
+    CipherAlgorithm getAdminCipherAlgorithm();
+
+    void setPassword(String password, CipherAlgorithm cipherAlgoritm);
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/252b1510/core/persistence-jpa/pom.xml
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/pom.xml b/core/persistence-jpa/pom.xml
index d48ef77..0ab9e82 100644
--- a/core/persistence-jpa/pom.xml
+++ b/core/persistence-jpa/pom.xml
@@ -55,7 +55,11 @@ under the License.
       <groupId>org.apache.openjpa</groupId>
       <artifactId>openjpa-persistence-jdbc</artifactId>
     </dependency>
-
+    <dependency>
+      <groupId>org.apache.openjpa</groupId>
+      <artifactId>openjpa-slice</artifactId>
+    </dependency>
+    
     <dependency>
       <groupId>org.apache.commons</groupId>
       <artifactId>commons-dbcp2</artifactId>
@@ -105,6 +109,11 @@ under the License.
     </dependency>
         
     <!-- TEST -->
+    <dependency> 
+      <groupId>javax.servlet</groupId> 
+      <artifactId>javax.servlet-api</artifactId> 
+      <scope>test</scope>
+    </dependency>
     <dependency>
       <groupId>org.slf4j</groupId>
       <artifactId>slf4j-simple</artifactId>

http://git-wip-us.apache.org/repos/asf/syncope/blob/252b1510/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/AbstractDAO.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/AbstractDAO.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/AbstractDAO.java
index a4ff529..c2d5ae6 100644
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/AbstractDAO.java
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/AbstractDAO.java
@@ -25,6 +25,8 @@ import javax.persistence.EntityManager;
 import javax.persistence.PersistenceContext;
 import javax.persistence.PersistenceContextType;
 import org.apache.commons.lang3.StringUtils;
+import org.apache.openjpa.slice.SlicePersistence;
+import org.apache.syncope.common.lib.SyncopeConstants;
 import org.apache.syncope.core.persistence.api.dao.DAO;
 import org.apache.syncope.core.persistence.api.dao.search.OrderByClause;
 import org.apache.syncope.core.persistence.api.entity.Entity;
@@ -93,6 +95,16 @@ public abstract class AbstractDAO<E extends Entity<KEY>, KEY> implements DAO<E,
     }
 
     @Override
+    public String getDomain(final E entity) {
+        try {
+            return SlicePersistence.getSlice(entity);
+        } catch (Exception e) {
+            LOG.debug("While fetching slice for {}", entity, e);
+            return SyncopeConstants.MASTER_DOMAIN;
+        }
+    }
+
+    @Override
     public void refresh(final E entity) {
         entityManager.refresh(entity);
     }

http://git-wip-us.apache.org/repos/asf/syncope/blob/252b1510/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAAnySearchDAO.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAAnySearchDAO.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAAnySearchDAO.java
index b8ab75d..e0eae6a 100644
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAAnySearchDAO.java
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAAnySearchDAO.java
@@ -387,12 +387,9 @@ public class JPAAnySearchDAO extends AbstractDAO<Any<?, ?, ?>, Long> implements
         List<T> result = new ArrayList<>();
 
         for (Object anyKey : query.getResultList()) {
-            long actualKey;
-            if (anyKey instanceof Object[]) {
-                actualKey = ((Number) ((Object[]) anyKey)[0]).longValue();
-            } else {
-                actualKey = ((Number) anyKey).longValue();
-            }
+            long actualKey = anyKey instanceof Object[]
+                    ? ((Number) ((Object[]) anyKey)[0]).longValue()
+                    : ((Number) anyKey).longValue();
 
             T any = typeKind == AnyTypeKind.USER
                     ? (T) userDAO.find(actualKey)

http://git-wip-us.apache.org/repos/asf/syncope/blob/252b1510/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPADomainDAO.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPADomainDAO.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPADomainDAO.java
new file mode 100644
index 0000000..37a4cd2
--- /dev/null
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPADomainDAO.java
@@ -0,0 +1,57 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.syncope.core.persistence.jpa.dao;
+
+import java.util.List;
+import javax.persistence.TypedQuery;
+import org.apache.syncope.core.persistence.api.dao.DomainDAO;
+import org.apache.syncope.core.persistence.api.entity.Domain;
+import org.apache.syncope.core.persistence.jpa.entity.JPADomain;
+import org.springframework.stereotype.Repository;
+
+@Repository
+public class JPADomainDAO extends AbstractDAO<Domain, String> implements DomainDAO {
+
+    @Override
+    public Domain find(final String key) {
+        return entityManager.find(JPADomain.class, key);
+    }
+
+    @Override
+    public List<Domain> findAll() {
+        TypedQuery<Domain> query = entityManager.createQuery(
+                "SELECT e FROM " + JPADomain.class.getSimpleName() + " e ", Domain.class);
+        return query.getResultList();
+    }
+
+    @Override
+    public Domain save(final Domain anyTypeClass) {
+        return entityManager.merge(anyTypeClass);
+    }
+
+    @Override
+    public void delete(final String key) {
+        Domain domain = find(key);
+        if (domain == null) {
+            return;
+        }
+
+        entityManager.remove(domain);
+    }
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/252b1510/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAUserDAO.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAUserDAO.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAUserDAO.java
index 7045ddc..3b413c0 100644
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAUserDAO.java
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAUserDAO.java
@@ -74,8 +74,8 @@ public class JPAUserDAO extends AbstractAnyDAO<User> implements UserDAO {
     protected void securityChecks(final User user) {
         // Allows anonymous (during self-registration) and self (during self-update) to read own user,
         // otherwise goes through security checks to see if required entitlements are owned
-        if (!AuthContextUtils.getAuthenticatedUsername().equals(anonymousUser)
-                && !AuthContextUtils.getAuthenticatedUsername().equals(user.getUsername())) {
+        if (!AuthContextUtils.getUsername().equals(anonymousUser)
+                && !AuthContextUtils.getUsername().equals(user.getUsername())) {
 
             Set<String> authRealms = AuthContextUtils.getAuthorizations().get(Entitlement.USER_READ);
             boolean authorized = CollectionUtils.exists(authRealms, new Predicate<String>() {

http://git-wip-us.apache.org/repos/asf/syncope/blob/252b1510/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/AnnotatedEntityListener.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/AnnotatedEntityListener.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/AnnotatedEntityListener.java
index 8a9547e..4e8044d 100644
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/AnnotatedEntityListener.java
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/AnnotatedEntityListener.java
@@ -33,7 +33,7 @@ public class AnnotatedEntityListener {
     @PrePersist
     @PreUpdate
     public void setSysInfo(final AnnotatedEntity<?> entity) {
-        final String username = AuthContextUtils.getAuthenticatedUsername();
+        final String username = AuthContextUtils.getUsername();
         LOG.debug("Set system properties for '{}'", entity);
 
         final Date now = new Date();

http://git-wip-us.apache.org/repos/asf/syncope/blob/252b1510/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/JPADomain.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/JPADomain.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/JPADomain.java
new file mode 100644
index 0000000..3e9169e
--- /dev/null
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/JPADomain.java
@@ -0,0 +1,79 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.syncope.core.persistence.jpa.entity;
+
+import javax.persistence.Entity;
+import javax.persistence.EnumType;
+import javax.persistence.Enumerated;
+import javax.persistence.Id;
+import javax.persistence.Table;
+import org.apache.syncope.common.lib.types.CipherAlgorithm;
+import org.apache.syncope.core.misc.security.Encryptor;
+import org.apache.syncope.core.persistence.api.entity.Domain;
+import org.apache.syncope.core.persistence.jpa.validation.entity.DomainCheck;
+
+@Entity
+@Table(name = JPADomain.TABLE)
+@DomainCheck
+public class JPADomain extends AbstractEntity<String> implements Domain {
+
+    private static final long serialVersionUID = -5891241943464285840L;
+
+    public static final String TABLE = "SyncopeDomain";
+
+    @Id
+    private String name;
+
+    private String adminPwd;
+
+    @Enumerated(EnumType.STRING)
+    private CipherAlgorithm adminCipherAlgorithm;
+
+    @Override
+    public String getKey() {
+        return name;
+    }
+
+    @Override
+    public void setKey(final String name) {
+        this.name = name;
+    }
+
+    @Override
+    public String getAdminPwd() {
+        return adminPwd;
+    }
+
+    @Override
+    public CipherAlgorithm getAdminCipherAlgorithm() {
+        return adminCipherAlgorithm;
+    }
+
+    @Override
+    public void setPassword(final String password, final CipherAlgorithm cipherAlgoritm) {
+        try {
+            this.adminPwd = Encryptor.getInstance().encode(password, cipherAlgoritm);
+            this.adminCipherAlgorithm = cipherAlgoritm;
+        } catch (Exception e) {
+            LOG.error("Could not encode password", e);
+            this.adminPwd = null;
+        }
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/252b1510/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/JPAEntityFactory.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/JPAEntityFactory.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/JPAEntityFactory.java
index ad6304e..41d3f74 100644
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/JPAEntityFactory.java
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/JPAEntityFactory.java
@@ -27,6 +27,7 @@ import org.apache.syncope.core.persistence.api.entity.AnyTypeClass;
 import org.apache.syncope.core.persistence.api.entity.ConnInstance;
 import org.apache.syncope.core.persistence.api.entity.ConnPoolConf;
 import org.apache.syncope.core.persistence.api.entity.DerSchema;
+import org.apache.syncope.core.persistence.api.entity.Domain;
 import org.apache.syncope.core.persistence.api.entity.user.DynRoleMembership;
 import org.apache.syncope.core.persistence.api.entity.Entity;
 import org.apache.syncope.core.persistence.api.entity.EntityFactory;
@@ -129,7 +130,9 @@ public class JPAEntityFactory implements EntityFactory {
     public <KEY, T extends Entity<KEY>> T newEntity(final Class<T> reference) {
         T result;
 
-        if (reference.equals(Realm.class)) {
+        if (reference.equals(Domain.class)) {
+            result = (T) new JPADomain();
+        } else if (reference.equals(Realm.class)) {
             result = (T) new JPARealm();
         } else if (reference.equals(AccountPolicy.class)) {
             result = (T) new JPAAccountPolicy();

http://git-wip-us.apache.org/repos/asf/syncope/blob/252b1510/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/slice/DomainDistributionPolicy.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/slice/DomainDistributionPolicy.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/slice/DomainDistributionPolicy.java
new file mode 100644
index 0000000..2e61b06
--- /dev/null
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/slice/DomainDistributionPolicy.java
@@ -0,0 +1,36 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.syncope.core.persistence.jpa.slice;
+
+import java.util.List;
+import org.apache.openjpa.slice.DistributionPolicy;
+import org.apache.syncope.common.lib.SyncopeConstants;
+import org.apache.syncope.core.misc.security.AuthContextUtils;
+import org.apache.syncope.core.persistence.api.entity.Domain;
+
+public class DomainDistributionPolicy implements DistributionPolicy {
+
+    @Override
+    public String distribute(final Object pc, final List<String> slices, final Object context) {
+        return (pc instanceof Domain)
+                ? SyncopeConstants.MASTER_DOMAIN
+                : AuthContextUtils.getDomain();
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/252b1510/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/slice/DomainFinderTargetPolicy.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/slice/DomainFinderTargetPolicy.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/slice/DomainFinderTargetPolicy.java
new file mode 100644
index 0000000..c6cad6e
--- /dev/null
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/slice/DomainFinderTargetPolicy.java
@@ -0,0 +1,38 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.syncope.core.persistence.jpa.slice;
+
+import java.util.List;
+import org.apache.openjpa.slice.FinderTargetPolicy;
+import org.apache.syncope.common.lib.SyncopeConstants;
+import org.apache.syncope.core.misc.security.AuthContextUtils;
+import org.apache.syncope.core.persistence.jpa.entity.JPADomain;
+
+public class DomainFinderTargetPolicy implements FinderTargetPolicy {
+
+    @Override
+    public String[] getTargets(final Class<?> cls, final Object oid, final List<String> slices, final Object context) {
+        return new String[] {
+            JPADomain.class.equals(cls)
+            ? SyncopeConstants.MASTER_DOMAIN
+            : AuthContextUtils.getDomain()
+        };
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/252b1510/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/slice/DomainQueryTargetPolicy.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/slice/DomainQueryTargetPolicy.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/slice/DomainQueryTargetPolicy.java
new file mode 100644
index 0000000..193ef2b
--- /dev/null
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/slice/DomainQueryTargetPolicy.java
@@ -0,0 +1,41 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.syncope.core.persistence.jpa.slice;
+
+import java.util.List;
+import java.util.Map;
+import org.apache.openjpa.slice.QueryTargetPolicy;
+import org.apache.syncope.common.lib.SyncopeConstants;
+import org.apache.syncope.core.misc.security.AuthContextUtils;
+import org.apache.syncope.core.persistence.jpa.entity.JPADomain;
+
+public class DomainQueryTargetPolicy implements QueryTargetPolicy {
+
+    @Override
+    public String[] getTargets(final String query, final Map<Object, Object> params, final String language,
+            final List<String> slices, final Object context) {
+
+        return new String[] {
+            query.contains(JPADomain.class.getSimpleName())
+            ? SyncopeConstants.MASTER_DOMAIN
+            : AuthContextUtils.getDomain()
+        };
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/252b1510/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/validation/entity/DomainCheck.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/validation/entity/DomainCheck.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/validation/entity/DomainCheck.java
new file mode 100644
index 0000000..f40c37e
--- /dev/null
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/validation/entity/DomainCheck.java
@@ -0,0 +1,41 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.syncope.core.persistence.jpa.validation.entity;
+
+import java.lang.annotation.Documented;
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+import javax.validation.Constraint;
+import javax.validation.Payload;
+
+@Target({ ElementType.TYPE })
+@Retention(RetentionPolicy.RUNTIME)
+@Constraint(validatedBy = DomainValidator.class)
+@Documented
+public @interface DomainCheck {
+
+    String message() default "{org.apache.syncope.core.persistence.validation.domain}";
+
+    Class<?>[] groups() default {};
+
+    Class<? extends Payload>[] payload() default {};
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/252b1510/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/validation/entity/DomainValidator.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/validation/entity/DomainValidator.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/validation/entity/DomainValidator.java
new file mode 100644
index 0000000..2e585e4
--- /dev/null
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/validation/entity/DomainValidator.java
@@ -0,0 +1,42 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.syncope.core.persistence.jpa.validation.entity;
+
+import javax.validation.ConstraintValidatorContext;
+import org.apache.syncope.common.lib.SyncopeConstants;
+import org.apache.syncope.common.lib.types.EntityViolationType;
+import org.apache.syncope.core.persistence.api.entity.Domain;
+
+public class DomainValidator extends AbstractValidator<DomainCheck, Domain> {
+
+    @Override
+    public boolean isValid(final Domain object, final ConstraintValidatorContext context) {
+        context.disableDefaultConstraintViolation();
+
+        boolean isValid = !SyncopeConstants.MASTER_DOMAIN.equals(object.getKey());
+
+        if (!isValid) {
+            context.buildConstraintViolationWithTemplate(
+                    getTemplate(EntityViolationType.InvalidName, "Reserved: " + SyncopeConstants.MASTER_DOMAIN)).
+                    addPropertyNode("name").addConstraintViolation();
+        }
+
+        return isValid;
+    }
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/252b1510/core/persistence-jpa/src/main/resources/persistence.properties
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/resources/persistence.properties b/core/persistence-jpa/src/main/resources/persistence.properties
index 5afa1a6..054808d 100644
--- a/core/persistence-jpa/src/main/resources/persistence.properties
+++ b/core/persistence-jpa/src/main/resources/persistence.properties
@@ -22,8 +22,8 @@ jpa.password=syncope
 jpa.dialect=org.apache.openjpa.jdbc.sql.PostgresDictionary
 jpa.pool.validationQuery=SELECT 1
 jpa.orm=META-INF/spring-orm.xml
-#note: other connection pool settings can also be configured here, see persistenceContext.xml
+# note: other connection pool settings can also be configured here, see persistenceContext.xml
 quartz.jobstore=org.quartz.impl.jdbcjobstore.PostgreSQLDelegate
 quartz.sql=tables_postgres.sql
 audit.sql=audit.sql
-database.schema=
+database.schema=
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/syncope/blob/252b1510/core/persistence-jpa/src/main/resources/persistenceContextEMFactory.xml
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/resources/persistenceContextEMFactory.xml b/core/persistence-jpa/src/main/resources/persistenceContextEMFactory.xml
index 3b3b86b..d3a7e45 100644
--- a/core/persistence-jpa/src/main/resources/persistenceContextEMFactory.xml
+++ b/core/persistence-jpa/src/main/resources/persistenceContextEMFactory.xml
@@ -21,7 +21,7 @@ under the License.
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:schemaLocation="http://www.springframework.org/schema/beans
                            http://www.springframework.org/schema/beans/spring-beans.xsd">
-
+  
   <bean id="entityManagerFactory"
         class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
     <property name="packagesToScan" value="org.apache.syncope.core.persistence.jpa.entity"/>
@@ -47,19 +47,41 @@ under the License.
     </property>
     <property name="jpaPropertyMap">
       <map>
+        <entry key="openjpa.Log" value="DefaultLevel=INFO, Runtime=TRACE, Tool=TRACE, SQL=TRACE"/>
+        
         <!--<entry key="openjpa.Log" value="SQL=TRACE"/>
         <entry key="openjpa.ConnectionFactoryProperties" 
         value="PrintParameters=true, PrettyPrint=true, PrettyPrintLineLength=80"/>-->
-                                
+        
         <entry key="openjpa.NontransactionalWrite" value="false"/>
         <entry key="openjpa.AutoDetach" value="close, commit, nontx-read, rollback"/>
 
         <entry key="openjpa.jdbc.SchemaFactory" value="native(ForeignKeys=true)"/>
-        <entry key="openjpa.jdbc.MappingDefaults" value="ForeignKeyDeleteAction=restrict, JoinForeignKeyDeleteAction=restrict"/>
-                
+        <entry key="openjpa.jdbc.MappingDefaults" 
+               value="ForeignKeyDeleteAction=restrict, JoinForeignKeyDeleteAction=restrict"/>
+                        
         <entry key="openjpa.DataCache" value="true"/>
-        <entry key="openjpa.QueryCache" value="true"/>
+        <entry key="openjpa.QueryCache" value="false"/>
+        <entry key="openjpa.QueryCompilationCache" value="false"/>
         <entry key="openjpa.RemoteCommitProvider" value="sjvm"/>
+        
+        <entry key="openjpa.BrokerFactory" value="slice"/>       
+        <entry key="openjpa.BrokerImpl" value="org.apache.openjpa.slice.DistributedBrokerImpl"/> 
+        <entry key="openjpa.slice.Lenient" value="false"/>
+        
+        <entry key="openjpa.slice.DistributionPolicy" 
+               value="org.apache.syncope.core.persistence.jpa.slice.DomainDistributionPolicy"/>
+        <entry key="openjpa.slice.QueryTargetPolicy" 
+               value="org.apache.syncope.core.persistence.jpa.slice.DomainQueryTargetPolicy"/>
+        <entry key="openjpa.slice.FinderTargetPolicy" 
+               value="org.apache.syncope.core.persistence.jpa.slice.DomainFinderTargetPolicy"/>
+
+        <entry key="openjpa.slice.Names" value="Master"/>        
+        <entry key="openjpa.slice.Master"  value="Master"/>
+        <entry key="openjpa.slice.Lenient" value="false"/>
+        
+        <entry key="openjpa.slice.Master.ConnectionFactory" value-ref="dataSource"/>
+        <entry key="openjpa.slice.Master.jdbc.DBDictionary" value="${jpa.dialect}"/>
       </map>
     </property>
   </bean>

http://git-wip-us.apache.org/repos/asf/syncope/blob/252b1510/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/inner/UserTest.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/inner/UserTest.java b/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/inner/UserTest.java
index 587f31d..a709638 100644
--- a/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/inner/UserTest.java
+++ b/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/inner/UserTest.java
@@ -54,7 +54,7 @@ public class UserTest extends AbstractTest {
     @Test
     public void findAll() {
         List<User> list = userDAO.findAll(SyncopeConstants.FULL_ADMIN_REALMS, 1, 100);
-        assertEquals("did not get expected number of users ", 5, list.size());
+        assertEquals("did not get expected number of users", 5, list.size());
     }
 
     @Test
@@ -68,25 +68,25 @@ public class UserTest extends AbstractTest {
     public void findAllByPageAndSize() {
         // get first page
         List<User> list = userDAO.findAll(SyncopeConstants.FULL_ADMIN_REALMS, 1, 2);
-        assertEquals("did not get expected number of users ", 2, list.size());
+        assertEquals("did not get expected number of users", 2, list.size());
 
         // get second page
         list = userDAO.findAll(SyncopeConstants.FULL_ADMIN_REALMS, 2, 2);
-        assertEquals("did not get expected number of users ", 2, list.size());
+        assertEquals("did not get expected number of users", 2, list.size());
 
         // get second page with uncomplete set
         list = userDAO.findAll(SyncopeConstants.FULL_ADMIN_REALMS, 2, 3);
-        assertEquals("did not get expected number of users ", 2, list.size());
+        assertEquals("did not get expected number of users", 2, list.size());
 
         // get unexistent page
         list = userDAO.findAll(SyncopeConstants.FULL_ADMIN_REALMS, 3, 2);
-        assertEquals("did not get expected number of users ", 1, list.size());
+        assertEquals("did not get expected number of users", 1, list.size());
     }
 
     @Test
     public void findByDerAttributeValue() {
         final List<User> list = userDAO.findByDerAttrValue("cn", "Vivaldi, Antonio");
-        assertEquals("did not get expected number of users ", 1, list.size());
+        assertEquals("did not get expected number of users", 1, list.size());
     }
 
     @Test(expected = IllegalArgumentException.class)
@@ -105,7 +105,7 @@ public class UserTest extends AbstractTest {
         fullnameValue.setStringValue("Gioacchino Rossini");
 
         final List<User> list = userDAO.findByAttrValue("fullname", fullnameValue);
-        assertEquals("did not get expected number of users ", 1, list.size());
+        assertEquals("did not get expected number of users", 1, list.size());
     }
 
     @Test
@@ -114,7 +114,7 @@ public class UserTest extends AbstractTest {
         coolValue.setBooleanValue(true);
 
         final List<User> list = userDAO.findByAttrValue("cool", coolValue);
-        assertEquals("did not get expected number of users ", 1, list.size());
+        assertEquals("did not get expected number of users", 1, list.size());
     }
 
     @Test

http://git-wip-us.apache.org/repos/asf/syncope/blob/252b1510/core/persistence-jpa/src/test/resources/persistence.properties
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/test/resources/persistence.properties b/core/persistence-jpa/src/test/resources/persistence.properties
index 92b0cbc..6993a0b 100644
--- a/core/persistence-jpa/src/test/resources/persistence.properties
+++ b/core/persistence-jpa/src/test/resources/persistence.properties
@@ -22,9 +22,9 @@ jpa.password=
 jpa.dialect=org.apache.openjpa.jdbc.sql.H2Dictionary
 jpa.pool.validationQuery=SELECT 1
 jpa.orm=META-INF/spring-orm.xml
-#note: other connection pool settings can also be configured here, see persistenceContext.xml
+# note: other connection pool settings can also be configured here, see persistenceContext.xml
 quartz.jobstore=org.quartz.impl.jdbcjobstore.StdJDBCDelegate
 quartz.scheduler.idleWaitTime=5000
 quartz.sql=tables_h2.sql
 audit.sql=audit.sql
-database.schema=
+database.schema=
\ No newline at end of file


[17/31] syncope git commit: [SYNCOPE-652] Still several things to refine, but it starts taking shape

Posted by md...@apache.org.
http://git-wip-us.apache.org/repos/asf/syncope/blob/6dfedd8f/core/persistence-jpa/src/main/resources/domains/MasterContent.xml
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/resources/domains/MasterContent.xml b/core/persistence-jpa/src/main/resources/domains/MasterContent.xml
new file mode 100644
index 0000000..d90518f
--- /dev/null
+++ b/core/persistence-jpa/src/main/resources/domains/MasterContent.xml
@@ -0,0 +1,124 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+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.
+-->
+<dataset>
+  <Realm id="1" name="/"/>
+
+  <SyncopeConf id="1" 
+               creator="admin" lastModifier="admin"
+               creationDate="2014-06-20 11:00:00" lastChangeDate="2014-06-20 11:00:00"/>
+
+  <PlainSchema name="password.cipher.algorithm" type="String"
+               mandatoryCondition="true" multivalue="0" uniqueConstraint="0" readonly="0"/>
+  <CPlainAttr id="1" owner_id="1" schema_name="password.cipher.algorithm"/>
+  <CPlainAttrValue id="1" attribute_id="1" stringValue="SHA1"/>
+
+  <!-- notificationjob.cronExpression:
+  + not existing: NotificationJob runs according to Notification.DEFAULT_CRON_EXP
+  + provided as empty string: NotificationJob disabled
+  + provided as non-empty string: NotificationJob runs according to the given value -->
+  <PlainSchema name="notificationjob.cronExpression" type="String"
+               mandatoryCondition="false" multivalue="0" uniqueConstraint="0" readonly="0"/>
+  <CPlainAttr id="2" owner_id="1" schema_name="notificationjob.cronExpression"/>
+  <CPlainAttrValue id="2" attribute_id="2" stringValue=""/>
+
+  <PlainSchema name="notification.maxRetries" type="Long"
+               mandatoryCondition="true" multivalue="0" uniqueConstraint="0" readonly="0"/>
+  <CPlainAttr id="3" owner_id="1" schema_name="notification.maxRetries"/>
+  <CPlainAttrValue id="3" attribute_id="3" longValue="3"/>
+
+  <PlainSchema name="token.length" type="Long"
+               mandatoryCondition="true" multivalue="0" uniqueConstraint="0" readonly="0"/>
+  <CPlainAttr id="4" owner_id="1" schema_name="token.length"/>
+  <CPlainAttrValue id="4" attribute_id="4" longValue="256"/>
+
+  <PlainSchema name="token.expireTime" type="Long"
+               mandatoryCondition="true" multivalue="0" uniqueConstraint="0" readonly="0"/>
+  <CPlainAttr id="5" owner_id="1" schema_name="token.expireTime"/>
+  <CPlainAttrValue id="5" attribute_id="5" longValue="60"/>
+
+  <PlainSchema name="selfRegistration.allowed" type="Boolean"
+               mandatoryCondition="true" multivalue="0" uniqueConstraint="0" readonly="0"/>
+  <CPlainAttr id="6" owner_id="1" schema_name="selfRegistration.allowed"/>
+  <CPlainAttrValue id="6" attribute_id="6" booleanValue="1"/>
+
+  <PlainSchema name="passwordReset.allowed" type="Boolean"
+               mandatoryCondition="true" multivalue="0" uniqueConstraint="0" readonly="0"/>
+  <CPlainAttr id="7" owner_id="1" schema_name="passwordReset.allowed"/>
+  <CPlainAttrValue id="7" attribute_id="7" booleanValue="1"/>
+
+  <PlainSchema name="passwordReset.securityQuestion" type="Boolean"
+               mandatoryCondition="true" multivalue="0" uniqueConstraint="0" readonly="0"/>
+  <CPlainAttr id="8" owner_id="1" schema_name="passwordReset.securityQuestion"/>
+  <CPlainAttrValue id="8" attribute_id="8" booleanValue="1"/>
+
+  <PlainSchema name="authentication.statuses" type="String"
+               mandatoryCondition="true" multivalue="1" uniqueConstraint="0" readonly="0"/>
+  <CPlainAttr id="9" owner_id="1" schema_name="authentication.statuses"/>
+  <CPlainAttrValue id="9" attribute_id="9" stringValue="created"/>
+  <CPlainAttrValue id="10" attribute_id="9" stringValue="active"/>
+
+  <!-- Save user login date upon successful authentication -->
+  <PlainSchema name="log.lastlogindate" type="Boolean"
+               mandatoryCondition="true" multivalue="0" uniqueConstraint="0" readonly="0"/>
+  <CPlainAttr id="11" owner_id="1" schema_name="log.lastlogindate"/>
+  <CPlainAttrValue id="11" attribute_id="11" booleanValue="1"/>
+
+  <PlainSchema name="tasks.interruptMaxRetries" type="Long"
+               mandatoryCondition="true" multivalue="0" uniqueConstraint="0" readonly="0"/>
+  <CPlainAttr id="12" owner_id="1" schema_name="tasks.interruptMaxRetries"/>
+  <CPlainAttrValue id="12" attribute_id="12" longValue="20"/>
+
+  <AnyType name="USER" kind="USER"/>
+  <AnyTypeClass name="BaseUser"/>
+  <AnyType_AnyTypeClass anyType_name="USER" anyTypeClass_name="baseUser"/>
+
+  <AnyType name="GROUP" kind="GROUP"/>
+  
+  <!-- For usage with admin console -->
+  <PlainSchema name="admin.user.layout" type="String"
+               mandatoryCondition="false" multivalue="1" uniqueConstraint="0" readonly="0"/>
+  <PlainSchema name="self.user.layout" type="String"
+               mandatoryCondition="false" multivalue="1" uniqueConstraint="0" readonly="0"/>
+  <PlainSchema name="admin.group.layout" type="String"
+               mandatoryCondition="false" multivalue="1" uniqueConstraint="0" readonly="0"/>
+  <PlainSchema name="self.group.layout" type="String"
+               mandatoryCondition="false" multivalue="1" uniqueConstraint="0" readonly="0"/>
+  <PlainSchema name="admin.membership.layout" type="String"
+               mandatoryCondition="false" multivalue="1" uniqueConstraint="0" readonly="0"/>
+  <PlainSchema name="self.membership.layout" type="String"
+               mandatoryCondition="false" multivalue="1" uniqueConstraint="0" readonly="0"/>
+        
+  <PlainSchema name="email" type="String" anyTypeClass_name="BaseUser"
+               mandatoryCondition="false" multivalue="0" uniqueConstraint="0" readonly="0"
+               validatorClass="org.apache.syncope.core.persistence.jpa.attrvalue.validation.EmailAddressValidator"/>
+  
+  <!-- Password reset notifications -->
+  <Notification id="1" active="1" recipientAttrName="email" recipientAttrType="UserPlainSchema" selfAsRecipient="1" 
+                sender="admin@syncope.apache.org" subject="Password Reset request" template="requestPasswordReset" 
+                traceLevel="FAILURES"/> 
+  <AnyAbout id="1" anyType_name="USER" notification_id="1" about="token!=$null"/>
+  <Notification_events Notification_id="1" event="[CUSTOM]:[]:[]:[requestPasswordReset]:[SUCCESS]"/>
+  
+  <Notification id="2" active="1" recipientAttrName="email" recipientAttrType="UserPlainSchema" selfAsRecipient="1" 
+                sender="admin@syncope.apache.org" subject="Password Reset successful" template="confirmPasswordReset" 
+                traceLevel="FAILURES"/> 
+  <Notification_events Notification_id="2" event="[CUSTOM]:[]:[]:[confirmPasswordReset]:[SUCCESS]"/>
+
+</dataset>

http://git-wip-us.apache.org/repos/asf/syncope/blob/6dfedd8f/core/persistence-jpa/src/main/resources/domains/MasterDomain.xml
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/resources/domains/MasterDomain.xml b/core/persistence-jpa/src/main/resources/domains/MasterDomain.xml
new file mode 100644
index 0000000..5cb38c2
--- /dev/null
+++ b/core/persistence-jpa/src/main/resources/domains/MasterDomain.xml
@@ -0,0 +1,125 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+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.
+-->
+<beans xmlns="http://www.springframework.org/schema/beans"
+       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+       xmlns:tx="http://www.springframework.org/schema/tx"
+       xmlns:util="http://www.springframework.org/schema/util"
+       xsi:schemaLocation="http://www.springframework.org/schema/beans
+                           http://www.springframework.org/schema/beans/spring-beans.xsd                           
+                           http://www.springframework.org/schema/tx
+                           http://www.springframework.org/schema/tx/spring-tx.xsd
+                           http://www.springframework.org/schema/util
+                           http://www.springframework.org/schema/util/spring-util.xsd">
+  
+  <bean id="MasterContentXML" class="org.apache.syncope.core.misc.spring.ResourceWithFallbackLoader">
+    <property name="primary" value="file:${content.directory}/domains/MasterContent.xml"/>
+    <property name="fallback" value="classpath:domains/MasterContent.xml"/>
+  </bean>
+  <bean id="MasterProperties" class="org.apache.syncope.core.misc.spring.ResourceWithFallbackLoader">
+    <property name="primary" value="file:${content.directory}/domains/Master.properties"/>
+    <property name="fallback" value="classpath:domains/Master.properties"/>
+  </bean>
+  <bean id="MasterDatabaseSchema" class="java.lang.String">
+    <constructor-arg value="${Master.schema}"/>
+  </bean>
+
+  <!-- Use JNDI datasource as default but, when not available, revert to
+  local datasource, with different properties for execution and testing. 
+  In any case, get all JDBC connections with a determined isolation level. -->
+  <bean id="MasterDataSource" class="org.springframework.jndi.JndiObjectFactoryBean">
+    <property name="jndiName" value="java:comp/env/jdbc/syncopeMasterDataSource"/>
+    <property name="defaultObject" ref="localMasterDataSource"/>
+  </bean>
+
+  <bean id="localMasterDataSource" class="org.apache.commons.dbcp2.BasicDataSource" destroy-method="close">
+    <property name="driverClassName" value="${Master.driverClassName}"/>
+    <property name="url" value="${Master.url}"/>
+    <property name="username" value="${Master.username}"/>
+    <property name="password" value="${Master.password}"/>
+    <!-- connection pool configuration - transaction isolation, default READ_COMMITTED (see SYNCOPE-202) -->
+    <property name="defaultTransactionIsolation">
+      <util:constant static-field="${Master.pool.defaultTransactionIsolation:java.sql.Connection.TRANSACTION_READ_COMMITTED}"/>
+    </property>
+    <!-- connection pool configuration - default values taken from BasicDataSource default values -->
+    <property name="initialSize" value="${Master.pool.initialSize:0}"/>
+    <property name="maxTotal" value="${Master.pool.maxActive:8}"/>
+    <property name="maxIdle" value="${Master.pool.maxIdle:8}"/>
+    <property name="minIdle" value="${Master.pool.minIdle:0}"/>
+    <property name="maxWaitMillis" value="${Master.pool.maxWait:-1}"/>
+    <property name="validationQuery" value="${Master.pool.validationQuery}"/>
+    <property name="validationQueryTimeout" value="${Master.pool.validationQueryTimeout:-1}"/>
+    <property name="testOnBorrow" value="${Master.pool.testOnBorrow:true}"/>
+    <property name="testOnReturn" value="${Master.pool.testOnReturn:false}"/>
+    <property name="testWhileIdle" value="${Master.pool.testWhileIdle:false}"/>
+    <property name="timeBetweenEvictionRunsMillis" value="${Master.pool.timeBetweenEvictionRunsMillis:-1}"/>
+    <property name="numTestsPerEvictionRun" value="${Master.pool.numTestsPerEvictionRun:3}"/>
+    <property name="minEvictableIdleTimeMillis" value="${Master.pool.minEvictableIdleTimeMillis:1800000}"/>
+    <property name="removeAbandonedOnBorrow" value="${Master.pool.removeAbandoned:false}"/>
+    <property name="removeAbandonedOnMaintenance" value="${Master.pool.removeAbandoned:false}"/>
+    <property name="removeAbandonedTimeout" value="${Master.pool.removeAbandonedTimeout:300}"/>
+    <property name="logAbandoned" value="${Master.pool.logAbandoned:false}"/>
+  </bean>
+  
+  <bean class="org.springframework.jdbc.datasource.init.DataSourceInitializer">
+    <property name="dataSource" ref="MasterDataSource"/>
+    <property name="enabled" value="true"/>
+    <property name="databasePopulator">
+      <bean class="org.springframework.jdbc.datasource.init.ResourceDatabasePopulator">
+        <property name="continueOnError" value="true"/>
+        <property name="ignoreFailedDrops" value="true"/>
+        <property name="sqlScriptEncoding" value="UTF-8"/>
+        <property name="scripts">
+          <array>
+            <value type="org.springframework.core.io.Resource">
+              classpath:/audit/${Master.audit.sql}
+            </value>
+          </array>
+        </property>
+      </bean>
+    </property>
+  </bean>
+  
+  <bean id="MasterEntityManagerFactory"
+        class="org.apache.syncope.core.persistence.jpa.spring.DomainEntityManagerFactoryBean">
+    <property name="mappingResources">
+      <list>
+        <value>${Master.orm}</value>
+      </list>
+    </property>
+    <property name="persistenceUnitName" value="Master"/>
+    <property name="dataSource" ref="MasterDataSource"/>
+    <property name="jpaVendorAdapter">
+      <bean class="org.springframework.orm.jpa.vendor.OpenJpaVendorAdapter">
+        <property name="showSql" value="false"/>
+        <property name="generateDdl" value="true"/>
+        <property name="databasePlatform" value="${Master.databasePlatform}"/>
+      </bean>
+    </property>
+    <property name="commonEntityManagerFactoryConf" ref="commonEMFConf"/>
+  </bean>  
+
+  <bean id="MasterTransactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
+    <property name="entityManagerFactory" ref="MasterEntityManagerFactory"/>
+    <qualifier value="Master"/>
+  </bean>
+  
+  <tx:annotation-driven transaction-manager="MasterTransactionManager"/>
+  
+</beans>
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/syncope/blob/6dfedd8f/core/persistence-jpa/src/main/resources/persistence.properties
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/resources/persistence.properties b/core/persistence-jpa/src/main/resources/persistence.properties
index 57f1af0..5aa696c 100644
--- a/core/persistence-jpa/src/main/resources/persistence.properties
+++ b/core/persistence-jpa/src/main/resources/persistence.properties
@@ -15,16 +15,3 @@
 # specific language governing permissions and limitations
 # under the License.
 content.directory=${conf.directory}
-jpa.driverClassName=org.postgresql.Driver
-jpa.url=jdbc:postgresql://localhost:5432/syncope
-jpa.username=syncope
-jpa.password=syncope
-jpa.dialect=org.apache.openjpa.jdbc.sql.PostgresDictionary
-jpa.pool.validationQuery=SELECT 1
-jpa.orm=META-INF/spring-orm.xml
-# note: other connection pool settings can also be configured here, see persistenceContext.xml
-quartz.jobstore=org.quartz.impl.jdbcjobstore.PostgreSQLDelegate
-quartz.sql=tables_postgres.sql
-audit.sql=audit.sql
-database.schema=
-

http://git-wip-us.apache.org/repos/asf/syncope/blob/6dfedd8f/core/persistence-jpa/src/main/resources/persistenceContext.xml
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/resources/persistenceContext.xml b/core/persistence-jpa/src/main/resources/persistenceContext.xml
index bea1729..ad2d837 100644
--- a/core/persistence-jpa/src/main/resources/persistenceContext.xml
+++ b/core/persistence-jpa/src/main/resources/persistenceContext.xml
@@ -20,53 +20,19 @@ under the License.
 <beans xmlns="http://www.springframework.org/schema/beans"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xmlns:context="http://www.springframework.org/schema/context"
-       xmlns:tx="http://www.springframework.org/schema/tx"
-       xmlns:util="http://www.springframework.org/schema/util"
        xsi:schemaLocation="http://www.springframework.org/schema/beans
                            http://www.springframework.org/schema/beans/spring-beans.xsd
                            http://www.springframework.org/schema/context
-                           http://www.springframework.org/schema/context/spring-context.xsd
-                           http://www.springframework.org/schema/tx
-                           http://www.springframework.org/schema/tx/spring-tx.xsd
-                           http://www.springframework.org/schema/util
-                           http://www.springframework.org/schema/util/spring-util.xsd">
-
+                           http://www.springframework.org/schema/context/spring-context.xsd">
   
-  <import resource="classpath:persistenceContextEMFactory.xml"/>
+  <import resource="domains.xml"/>
 
-  <bean id="nonJPAdbInitializer" class="org.springframework.jdbc.datasource.init.DataSourceInitializer">
-    <property name="dataSource" ref="dataSource"/>
-    <property name="enabled" value="true"/>
-    <property name="databasePopulator">
-      <bean class="org.springframework.jdbc.datasource.init.ResourceDatabasePopulator">
-        <property name="continueOnError" value="true"/>
-        <property name="ignoreFailedDrops" value="true"/>
-        <property name="sqlScriptEncoding" value="UTF-8"/>
-        <property name="scripts">
-          <array>
-            <value type="org.springframework.core.io.Resource">
-              classpath:/quartz/${quartz.sql}
-            </value>
-          </array>
-        </property>
-      </bean>
-    </property>
-  </bean>
-  
   <context:annotation-config/>
+  
   <context:component-scan base-package="org.apache.syncope.core.persistence.jpa"/>
 
-  <bean id="database.schema" class="java.lang.String">
-    <constructor-arg value="${database.schema}"/>
-  </bean>
-  <bean id="persistenceProperties" class="org.apache.syncope.core.misc.spring.ResourceWithFallbackLoader">
-    <property name="primary" value="file:${content.directory}/persistence.properties"/>
-    <property name="fallback" value="classpath:persistence.properties"/>
-  </bean>
-  <bean id="contentXML" class="org.apache.syncope.core.misc.spring.ResourceWithFallbackLoader">
-    <property name="primary" value="file:${content.directory}/content.xml"/>
-    <property name="fallback" value="classpath:content.xml"/>
-  </bean>
+  <bean class="org.springframework.validation.beanvalidation.LocalValidatorFactoryBean"/>
+
   <bean id="viewsXML" class="org.apache.syncope.core.misc.spring.ResourceWithFallbackLoader">
     <property name="primary" value="file:${content.directory}/views.xml"/>
     <property name="fallback" value="classpath:views.xml"/>
@@ -75,52 +41,5 @@ under the License.
     <property name="primary" value="file:${content.directory}/indexes.xml"/>
     <property name="fallback" value="classpath:indexes.xml"/>
   </bean>
-
-  <!-- Use JNDI datasource as default but, when not available, revert to
-  local datasource, with different properties for execution and testing. 
-  In any case, get all JDBC connections with a determined isolation level. -->
-  <bean id="dataSource" class="org.springframework.jndi.JndiObjectFactoryBean">
-    <property name="jndiName" value="java:comp/env/jdbc/syncopeDataSource"/>
-    <property name="defaultObject" ref="localDataSource"/>
-  </bean>
-
-  <bean id="localDataSource" class="org.apache.commons.dbcp2.BasicDataSource" destroy-method="close">
-    <property name="driverClassName" value="${jpa.driverClassName}"/>
-    <property name="url" value="${jpa.url}"/>
-    <property name="username" value="${jpa.username}"/>
-    <property name="password" value="${jpa.password}"/>
-    <!-- connection pool configuration - transaction isolation, default READ_COMMITTED (see SYNCOPE-202) -->
-    <property name="defaultTransactionIsolation">
-      <util:constant static-field="${jpa.pool.defaultTransactionIsolation:java.sql.Connection.TRANSACTION_READ_COMMITTED}"/>
-    </property>
-    <!-- connection pool configuration - default values taken from BasicDataSource default values -->
-    <property name="initialSize" value="${jpa.pool.initialSize:0}"/>
-    <property name="maxTotal" value="${jpa.pool.maxActive:8}"/>
-    <property name="maxIdle" value="${jpa.pool.maxIdle:8}"/>
-    <property name="minIdle" value="${jpa.pool.minIdle:0}"/>
-    <property name="maxWaitMillis" value="${jpa.pool.maxWait:-1}"/>
-    <property name="validationQuery" value="${jpa.pool.validationQuery}"/>
-    <property name="validationQueryTimeout" value="${jpa.pool.validationQueryTimeout:-1}"/>
-    <property name="testOnBorrow" value="${jpa.pool.testOnBorrow:true}"/>
-    <property name="testOnReturn" value="${jpa.pool.testOnReturn:false}"/>
-    <property name="testWhileIdle" value="${jpa.pool.testWhileIdle:false}"/>
-    <property name="timeBetweenEvictionRunsMillis" value="${jpa.pool.timeBetweenEvictionRunsMillis:-1}"/>
-    <property name="numTestsPerEvictionRun" value="${jpa.pool.numTestsPerEvictionRun:3}"/>
-    <property name="minEvictableIdleTimeMillis" value="${jpa.pool.minEvictableIdleTimeMillis:1800000}"/>
-    <property name="removeAbandonedOnBorrow" value="${jpa.pool.removeAbandoned:false}"/>
-    <property name="removeAbandonedOnMaintenance" value="${jpa.pool.removeAbandoned:false}"/>
-    <property name="removeAbandonedTimeout" value="${jpa.pool.removeAbandonedTimeout:300}"/>
-    <property name="logAbandoned" value="${jpa.pool.logAbandoned:false}"/>
-  </bean>
-
-  <bean id="entityManager" class="org.springframework.orm.jpa.support.SharedEntityManagerBean">
-    <property name="entityManagerFactory" ref="entityManagerFactory"/>
-  </bean>
-
-  <bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
-    <property name="entityManagerFactory" ref="entityManagerFactory"/>
-  </bean>
-  <tx:annotation-driven/>
-
-  <bean id="validator" class="org.springframework.validation.beanvalidation.LocalValidatorFactoryBean"/>
+  
 </beans>

http://git-wip-us.apache.org/repos/asf/syncope/blob/6dfedd8f/core/persistence-jpa/src/main/resources/persistenceContextEMFactory.xml
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/resources/persistenceContextEMFactory.xml b/core/persistence-jpa/src/main/resources/persistenceContextEMFactory.xml
deleted file mode 100644
index 5983ca6..0000000
--- a/core/persistence-jpa/src/main/resources/persistenceContextEMFactory.xml
+++ /dev/null
@@ -1,68 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
-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.
--->
-<beans xmlns="http://www.springframework.org/schema/beans"
-       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
-       xsi:schemaLocation="http://www.springframework.org/schema/beans
-                           http://www.springframework.org/schema/beans/spring-beans.xsd">
-
-  <bean id="entityManagerFactory"
-        class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
-    <property name="packagesToScan" value="org.apache.syncope.core.persistence.jpa.entity"/>
-    <property name="validationMode" value="NONE"/>
-    <property name="mappingResources">
-      <list>
-        <value>${jpa.orm}</value>
-      </list>
-    </property>
-    <property name="persistenceUnitName" value="syncopePersistenceUnit"/>
-    <property name="persistenceUnitPostProcessors">
-      <list>
-        <bean class="org.apache.syncope.core.persistence.jpa.spring.MultiJarAwarePersistenceUnitPostProcessor"/>
-      </list>
-    </property>
-    <property name="dataSource" ref="dataSource"/>
-    <property name="jpaVendorAdapter">
-      <bean class="org.springframework.orm.jpa.vendor.OpenJpaVendorAdapter">
-        <property name="showSql" value="false"/>
-        <property name="generateDdl" value="true"/>
-        <property name="databasePlatform" value="${jpa.dialect}"/>
-      </bean>
-    </property>
-    <property name="jpaPropertyMap">
-      <map>
-        <!--<entry key="openjpa.Log" value="SQL=TRACE"/>
-        <entry key="openjpa.ConnectionFactoryProperties" 
-        value="PrintParameters=true, PrettyPrint=true, PrettyPrintLineLength=80"/>-->
-                                
-        <entry key="openjpa.NontransactionalWrite" value="false"/>
-        <entry key="openjpa.AutoDetach" value="close, commit, nontx-read, rollback"/>
-
-        <entry key="openjpa.jdbc.SchemaFactory" value="native(ForeignKeys=true)"/>
-        <entry key="openjpa.jdbc.MappingDefaults" 
-               value="ForeignKeyDeleteAction=restrict, JoinForeignKeyDeleteAction=restrict"/>
-                
-        <entry key="openjpa.DataCache" value="true"/>
-        <entry key="openjpa.QueryCache" value="true"/>
-        <entry key="openjpa.RemoteCommitProvider" value="sjvm"/>
-      </map>
-    </property>
-  </bean>
-
-</beans>
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/syncope/blob/6dfedd8f/core/persistence-jpa/src/main/resources/quartz/tables_h2.sql
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/resources/quartz/tables_h2.sql b/core/persistence-jpa/src/main/resources/quartz/tables_h2.sql
deleted file mode 100644
index e798223..0000000
--- a/core/persistence-jpa/src/main/resources/quartz/tables_h2.sql
+++ /dev/null
@@ -1,266 +0,0 @@
--- Licensed to the Apache Software Foundation (ASF) under one
--- or more contributor license agreements.  See the NOTICE file
--- distributed with this work for additional information
--- regarding copyright ownership.  The ASF licenses this file
--- to you under the Apache License, Version 2.0 (the
--- "License"); you may not use this file except in compliance
--- with the License.  You may obtain a copy of the License at
---
---   http://www.apache.org/licenses/LICENSE-2.0
---
--- Unless required by applicable law or agreed to in writing,
--- software distributed under the License is distributed on an
--- "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
--- KIND, either express or implied.  See the License for the
--- specific language governing permissions and limitations
--- under the License.
-
--- Thanks to Amir Kibbar and Peter Rietzler for contributing the schema for H2 database, 
--- and verifying that it works with Quartz's StdJDBCDelegate
---
--- Note, Quartz depends on row-level locking which means you must use the MVCC=TRUE 
--- setting on your H2 database, or you will experience dead-locks
---
---
--- In your Quartz properties file, you'll need to set 
--- org.quartz.jobStore.driverDelegateClass = org.quartz.impl.jdbcjobstore.StdJDBCDelegate
-
-CREATE TABLE QRTZ_CALENDARS (
-  SCHED_NAME VARCHAR(120) NOT NULL,
-  CALENDAR_NAME VARCHAR (200)  NOT NULL ,
-  CALENDAR IMAGE NOT NULL
-);
-
-CREATE TABLE QRTZ_CRON_TRIGGERS (
-  SCHED_NAME VARCHAR(120) NOT NULL,
-  TRIGGER_NAME VARCHAR (200)  NOT NULL ,
-  TRIGGER_GROUP VARCHAR (200)  NOT NULL ,
-  CRON_EXPRESSION VARCHAR (120)  NOT NULL ,
-  TIME_ZONE_ID VARCHAR (80) 
-);
-
-CREATE TABLE QRTZ_FIRED_TRIGGERS (
-  SCHED_NAME VARCHAR(120) NOT NULL,
-  ENTRY_ID VARCHAR (95)  NOT NULL ,
-  TRIGGER_NAME VARCHAR (200)  NOT NULL ,
-  TRIGGER_GROUP VARCHAR (200)  NOT NULL ,
-  INSTANCE_NAME VARCHAR (200)  NOT NULL ,
-  FIRED_TIME BIGINT NOT NULL ,
-  SCHED_TIME BIGINT NOT NULL ,
-  PRIORITY INTEGER NOT NULL ,
-  STATE VARCHAR (16)  NOT NULL,
-  JOB_NAME VARCHAR (200)  NULL ,
-  JOB_GROUP VARCHAR (200)  NULL ,
-  IS_NONCONCURRENT BOOLEAN  NULL ,
-  REQUESTS_RECOVERY BOOLEAN  NULL 
-);
-
-CREATE TABLE QRTZ_PAUSED_TRIGGER_GRPS (
-  SCHED_NAME VARCHAR(120) NOT NULL,
-  TRIGGER_GROUP VARCHAR (200)  NOT NULL 
-);
-
-CREATE TABLE QRTZ_SCHEDULER_STATE (
-  SCHED_NAME VARCHAR(120) NOT NULL,
-  INSTANCE_NAME VARCHAR (200)  NOT NULL ,
-  LAST_CHECKIN_TIME BIGINT NOT NULL ,
-  CHECKIN_INTERVAL BIGINT NOT NULL
-);
-
-CREATE TABLE QRTZ_LOCKS (
-  SCHED_NAME VARCHAR(120) NOT NULL,
-  LOCK_NAME VARCHAR (40)  NOT NULL 
-);
-
-CREATE TABLE QRTZ_JOB_DETAILS (
-  SCHED_NAME VARCHAR(120) NOT NULL,
-  JOB_NAME VARCHAR (200)  NOT NULL ,
-  JOB_GROUP VARCHAR (200)  NOT NULL ,
-  DESCRIPTION VARCHAR (250) NULL ,
-  JOB_CLASS_NAME VARCHAR (250)  NOT NULL ,
-  IS_DURABLE BOOLEAN  NOT NULL ,
-  IS_NONCONCURRENT BOOLEAN  NOT NULL ,
-  IS_UPDATE_DATA BOOLEAN  NOT NULL ,
-  REQUESTS_RECOVERY BOOLEAN  NOT NULL ,
-  JOB_DATA IMAGE NULL
-);
-
-CREATE TABLE QRTZ_SIMPLE_TRIGGERS (
-  SCHED_NAME VARCHAR(120) NOT NULL,
-  TRIGGER_NAME VARCHAR (200)  NOT NULL ,
-  TRIGGER_GROUP VARCHAR (200)  NOT NULL ,
-  REPEAT_COUNT BIGINT NOT NULL ,
-  REPEAT_INTERVAL BIGINT NOT NULL ,
-  TIMES_TRIGGERED BIGINT NOT NULL
-);
-
-CREATE TABLE qrtz_simprop_triggers
-  (          
-    SCHED_NAME VARCHAR(120) NOT NULL,
-    TRIGGER_NAME VARCHAR(200) NOT NULL,
-    TRIGGER_GROUP VARCHAR(200) NOT NULL,
-    STR_PROP_1 VARCHAR(512) NULL,
-    STR_PROP_2 VARCHAR(512) NULL,
-    STR_PROP_3 VARCHAR(512) NULL,
-    INT_PROP_1 INTEGER NULL,
-    INT_PROP_2 INTEGER NULL,
-    LONG_PROP_1 BIGINT NULL,
-    LONG_PROP_2 BIGINT NULL,
-    DEC_PROP_1 NUMERIC(13,4) NULL,
-    DEC_PROP_2 NUMERIC(13,4) NULL,
-    BOOL_PROP_1 BOOLEAN NULL,
-    BOOL_PROP_2 BOOLEAN NULL,
-);
-
-CREATE TABLE QRTZ_BLOB_TRIGGERS (
-  SCHED_NAME VARCHAR(120) NOT NULL,
-  TRIGGER_NAME VARCHAR (200)  NOT NULL ,
-  TRIGGER_GROUP VARCHAR (200)  NOT NULL ,
-  BLOB_DATA IMAGE NULL
-);
-
-CREATE TABLE QRTZ_TRIGGERS (
-  SCHED_NAME VARCHAR(120) NOT NULL,
-  TRIGGER_NAME VARCHAR (200)  NOT NULL ,
-  TRIGGER_GROUP VARCHAR (200)  NOT NULL ,
-  JOB_NAME VARCHAR (200)  NOT NULL ,
-  JOB_GROUP VARCHAR (200)  NOT NULL ,
-  DESCRIPTION VARCHAR (250) NULL ,
-  NEXT_FIRE_TIME BIGINT NULL ,
-  PREV_FIRE_TIME BIGINT NULL ,
-  PRIORITY INTEGER NULL ,
-  TRIGGER_STATE VARCHAR (16)  NOT NULL ,
-  TRIGGER_TYPE VARCHAR (8)  NOT NULL ,
-  START_TIME BIGINT NOT NULL ,
-  END_TIME BIGINT NULL ,
-  CALENDAR_NAME VARCHAR (200)  NULL ,
-  MISFIRE_INSTR SMALLINT NULL ,
-  JOB_DATA IMAGE NULL
-);
-
-ALTER TABLE QRTZ_CALENDARS  ADD
-  CONSTRAINT PK_QRTZ_CALENDARS PRIMARY KEY  
-  (
-    SCHED_NAME,
-    CALENDAR_NAME
-  );
-
-ALTER TABLE QRTZ_CRON_TRIGGERS  ADD
-  CONSTRAINT PK_QRTZ_CRON_TRIGGERS PRIMARY KEY  
-  (
-    SCHED_NAME,
-    TRIGGER_NAME,
-    TRIGGER_GROUP
-  );
-
-ALTER TABLE QRTZ_FIRED_TRIGGERS  ADD
-  CONSTRAINT PK_QRTZ_FIRED_TRIGGERS PRIMARY KEY  
-  (
-    SCHED_NAME,
-    ENTRY_ID
-  );
-
-ALTER TABLE QRTZ_PAUSED_TRIGGER_GRPS  ADD
-  CONSTRAINT PK_QRTZ_PAUSED_TRIGGER_GRPS PRIMARY KEY  
-  (
-    SCHED_NAME,
-    TRIGGER_GROUP
-  );
-
-ALTER TABLE QRTZ_SCHEDULER_STATE  ADD
-  CONSTRAINT PK_QRTZ_SCHEDULER_STATE PRIMARY KEY  
-  (
-    SCHED_NAME,
-    INSTANCE_NAME
-  );
-
-ALTER TABLE QRTZ_LOCKS  ADD
-  CONSTRAINT PK_QRTZ_LOCKS PRIMARY KEY  
-  (
-    SCHED_NAME,
-    LOCK_NAME
-  );
-
-ALTER TABLE QRTZ_JOB_DETAILS  ADD
-  CONSTRAINT PK_QRTZ_JOB_DETAILS PRIMARY KEY  
-  (
-    SCHED_NAME,
-    JOB_NAME,
-    JOB_GROUP
-  );
-
-ALTER TABLE QRTZ_SIMPLE_TRIGGERS  ADD
-  CONSTRAINT PK_QRTZ_SIMPLE_TRIGGERS PRIMARY KEY  
-  (
-    SCHED_NAME,
-    TRIGGER_NAME,
-    TRIGGER_GROUP
-  );
-
-ALTER TABLE QRTZ_SIMPROP_TRIGGERS  ADD
-  CONSTRAINT PK_QRTZ_SIMPROP_TRIGGERS PRIMARY KEY  
-  (
-    SCHED_NAME,
-    TRIGGER_NAME,
-    TRIGGER_GROUP
-  );
-
-ALTER TABLE QRTZ_TRIGGERS  ADD
-  CONSTRAINT PK_QRTZ_TRIGGERS PRIMARY KEY  
-  (
-    SCHED_NAME,
-    TRIGGER_NAME,
-    TRIGGER_GROUP
-  );
-
-ALTER TABLE QRTZ_CRON_TRIGGERS ADD
-  CONSTRAINT FK_QRTZ_CRON_TRIGGERS_QRTZ_TRIGGERS FOREIGN KEY
-  (
-    SCHED_NAME,
-    TRIGGER_NAME,
-    TRIGGER_GROUP
-  ) REFERENCES QRTZ_TRIGGERS (
-    SCHED_NAME,
-    TRIGGER_NAME,
-    TRIGGER_GROUP
-  ) ON DELETE CASCADE;
-
-
-ALTER TABLE QRTZ_SIMPLE_TRIGGERS ADD
-  CONSTRAINT FK_QRTZ_SIMPLE_TRIGGERS_QRTZ_TRIGGERS FOREIGN KEY
-  (
-    SCHED_NAME,
-    TRIGGER_NAME,
-    TRIGGER_GROUP
-  ) REFERENCES QRTZ_TRIGGERS (
-    SCHED_NAME,
-    TRIGGER_NAME,
-    TRIGGER_GROUP
-  ) ON DELETE CASCADE;
-
-ALTER TABLE QRTZ_SIMPROP_TRIGGERS ADD
-  CONSTRAINT FK_QRTZ_SIMPROP_TRIGGERS_QRTZ_TRIGGERS FOREIGN KEY
-  (
-    SCHED_NAME,
-    TRIGGER_NAME,
-    TRIGGER_GROUP
-  ) REFERENCES QRTZ_TRIGGERS (
-    SCHED_NAME,
-    TRIGGER_NAME,
-    TRIGGER_GROUP
-  ) ON DELETE CASCADE;
-
-
-ALTER TABLE QRTZ_TRIGGERS ADD
-  CONSTRAINT FK_QRTZ_TRIGGERS_QRTZ_JOB_DETAILS FOREIGN KEY
-  (
-    SCHED_NAME,
-    JOB_NAME,
-    JOB_GROUP
-  ) REFERENCES QRTZ_JOB_DETAILS (
-    SCHED_NAME,
-    JOB_NAME,
-    JOB_GROUP
-  );
-  
-COMMIT;

http://git-wip-us.apache.org/repos/asf/syncope/blob/6dfedd8f/core/persistence-jpa/src/main/resources/quartz/tables_mariadb.sql
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/resources/quartz/tables_mariadb.sql b/core/persistence-jpa/src/main/resources/quartz/tables_mariadb.sql
deleted file mode 100644
index ebb8e59..0000000
--- a/core/persistence-jpa/src/main/resources/quartz/tables_mariadb.sql
+++ /dev/null
@@ -1,206 +0,0 @@
--- Licensed to the Apache Software Foundation (ASF) under one
--- or more contributor license agreements.  See the NOTICE file
--- distributed with this work for additional information
--- regarding copyright ownership.  The ASF licenses this file
--- to you under the Apache License, Version 2.0 (the
--- "License"); you may not use this file except in compliance
--- with the License.  You may obtain a copy of the License at
---
---   http://www.apache.org/licenses/LICENSE-2.0
---
--- Unless required by applicable law or agreed to in writing,
--- software distributed under the License is distributed on an
--- "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
--- KIND, either express or implied.  See the License for the
--- specific language governing permissions and limitations
--- under the License.
-
---
--- Quartz seems to work best with the driver mm.mysql-2.0.7-bin.jar
---
--- PLEASE consider using mysql with innodb tables to avoid locking issues
---
--- In your Quartz properties file, you'll need to set 
--- org.quartz.jobStore.driverDelegateClass = org.quartz.impl.jdbcjobstore.StdJDBCDelegate
---
-
-BEGIN;
-DROP TABLE IF EXISTS QRTZ_FIRED_TRIGGERS;
-DROP TABLE IF EXISTS QRTZ_PAUSED_TRIGGER_GRPS;
-DROP TABLE IF EXISTS QRTZ_SCHEDULER_STATE;
-DROP TABLE IF EXISTS QRTZ_LOCKS;
-DROP TABLE IF EXISTS QRTZ_SIMPLE_TRIGGERS;
-DROP TABLE IF EXISTS QRTZ_SIMPROP_TRIGGERS;
-DROP TABLE IF EXISTS QRTZ_CRON_TRIGGERS;
-DROP TABLE IF EXISTS QRTZ_BLOB_TRIGGERS;
-DROP TABLE IF EXISTS QRTZ_TRIGGERS;
-DROP TABLE IF EXISTS QRTZ_JOB_DETAILS;
-DROP TABLE IF EXISTS QRTZ_CALENDARS;
-COMMIT;
-
-
-BEGIN;
-CREATE TABLE QRTZ_JOB_DETAILS
-  (
-    SCHED_NAME VARCHAR(120) NOT NULL,
-    JOB_NAME  VARCHAR(200) NOT NULL,
-    JOB_GROUP VARCHAR(200) NOT NULL,
-    DESCRIPTION VARCHAR(250) NULL,
-    JOB_CLASS_NAME   VARCHAR(250) NOT NULL,
-    IS_DURABLE VARCHAR(1) NOT NULL,
-    IS_NONCONCURRENT VARCHAR(1) NOT NULL,
-    IS_UPDATE_DATA VARCHAR(1) NOT NULL,
-    REQUESTS_RECOVERY VARCHAR(1) NOT NULL,
-    JOB_DATA BLOB NULL,
-    PRIMARY KEY (SCHED_NAME,JOB_NAME,JOB_GROUP)
-);
-COMMIT;
-
-BEGIN;
-CREATE TABLE QRTZ_TRIGGERS
-  (
-    SCHED_NAME VARCHAR(120) NOT NULL,
-    TRIGGER_NAME VARCHAR(200) NOT NULL,
-    TRIGGER_GROUP VARCHAR(200) NOT NULL,
-    JOB_NAME  VARCHAR(200) NOT NULL,
-    JOB_GROUP VARCHAR(200) NOT NULL,
-    DESCRIPTION VARCHAR(250) NULL,
-    NEXT_FIRE_TIME BIGINT(13) NULL,
-    PREV_FIRE_TIME BIGINT(13) NULL,
-    PRIORITY INTEGER NULL,
-    TRIGGER_STATE VARCHAR(16) NOT NULL,
-    TRIGGER_TYPE VARCHAR(8) NOT NULL,
-    START_TIME BIGINT(13) NOT NULL,
-    END_TIME BIGINT(13) NULL,
-    CALENDAR_NAME VARCHAR(200) NULL,
-    MISFIRE_INSTR SMALLINT(2) NULL,
-    JOB_DATA BLOB NULL,
-    PRIMARY KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP),
-    FOREIGN KEY (SCHED_NAME,JOB_NAME,JOB_GROUP)
-        REFERENCES QRTZ_JOB_DETAILS(SCHED_NAME,JOB_NAME,JOB_GROUP)
-);
-COMMIT;
-
-BEGIN;
-CREATE TABLE QRTZ_SIMPLE_TRIGGERS
-  (
-    SCHED_NAME VARCHAR(120) NOT NULL,
-    TRIGGER_NAME VARCHAR(200) NOT NULL,
-    TRIGGER_GROUP VARCHAR(200) NOT NULL,
-    REPEAT_COUNT BIGINT(7) NOT NULL,
-    REPEAT_INTERVAL BIGINT(12) NOT NULL,
-    TIMES_TRIGGERED BIGINT(10) NOT NULL,
-    PRIMARY KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP),
-    FOREIGN KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP)
-        REFERENCES QRTZ_TRIGGERS(SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP)
-);
-COMMIT;
-
-BEGIN;
-CREATE TABLE QRTZ_CRON_TRIGGERS
-  (
-    SCHED_NAME VARCHAR(120) NOT NULL,
-    TRIGGER_NAME VARCHAR(200) NOT NULL,
-    TRIGGER_GROUP VARCHAR(200) NOT NULL,
-    CRON_EXPRESSION VARCHAR(200) NOT NULL,
-    TIME_ZONE_ID VARCHAR(80),
-    PRIMARY KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP),
-    FOREIGN KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP)
-        REFERENCES QRTZ_TRIGGERS(SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP)
-);
-COMMIT;
-
-BEGIN;
-CREATE TABLE QRTZ_SIMPROP_TRIGGERS
-  (          
-    SCHED_NAME VARCHAR(120) NOT NULL,
-    TRIGGER_NAME VARCHAR(200) NOT NULL,
-    TRIGGER_GROUP VARCHAR(200) NOT NULL,
-    STR_PROP_1 VARCHAR(512) NULL,
-    STR_PROP_2 VARCHAR(512) NULL,
-    STR_PROP_3 VARCHAR(512) NULL,
-    INT_PROP_1 INT NULL,
-    INT_PROP_2 INT NULL,
-    LONG_PROP_1 BIGINT NULL,
-    LONG_PROP_2 BIGINT NULL,
-    DEC_PROP_1 NUMERIC(13,4) NULL,
-    DEC_PROP_2 NUMERIC(13,4) NULL,
-    BOOL_PROP_1 VARCHAR(1) NULL,
-    BOOL_PROP_2 VARCHAR(1) NULL,
-    PRIMARY KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP),
-    FOREIGN KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP) 
-    REFERENCES QRTZ_TRIGGERS(SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP)
-);
-COMMIT;
-
-BEGIN;
-CREATE TABLE QRTZ_BLOB_TRIGGERS
-  (
-    SCHED_NAME VARCHAR(120) NOT NULL,
-    TRIGGER_NAME VARCHAR(200) NOT NULL,
-    TRIGGER_GROUP VARCHAR(200) NOT NULL,
-    BLOB_DATA BLOB NULL,
-    PRIMARY KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP),
-    FOREIGN KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP)
-        REFERENCES QRTZ_TRIGGERS(SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP)
-);
-COMMIT;
-
-BEGIN;
-CREATE TABLE QRTZ_CALENDARS
-  (
-    SCHED_NAME VARCHAR(120) NOT NULL,
-    CALENDAR_NAME  VARCHAR(200) NOT NULL,
-    CALENDAR BLOB NOT NULL,
-    PRIMARY KEY (SCHED_NAME,CALENDAR_NAME)
-);
-COMMIT;
-
-BEGIN;
-CREATE TABLE QRTZ_PAUSED_TRIGGER_GRPS
-  (
-    SCHED_NAME VARCHAR(120) NOT NULL,
-    TRIGGER_GROUP  VARCHAR(200) NOT NULL, 
-    PRIMARY KEY (SCHED_NAME,TRIGGER_GROUP)
-);
-COMMIT;
-
-BEGIN;
-CREATE TABLE QRTZ_FIRED_TRIGGERS
-  (
-    SCHED_NAME VARCHAR(120) NOT NULL,
-    ENTRY_ID VARCHAR(95) NOT NULL,
-    TRIGGER_NAME VARCHAR(200) NOT NULL,
-    TRIGGER_GROUP VARCHAR(200) NOT NULL,
-    INSTANCE_NAME VARCHAR(200) NOT NULL,
-    FIRED_TIME BIGINT(13) NOT NULL,
-    SCHED_TIME BIGINT(13) NOT NULL,
-    PRIORITY INTEGER NOT NULL,
-    STATE VARCHAR(16) NOT NULL,
-    JOB_NAME VARCHAR(200) NULL,
-    JOB_GROUP VARCHAR(200) NULL,
-    IS_NONCONCURRENT VARCHAR(1) NULL,
-    REQUESTS_RECOVERY VARCHAR(1) NULL,
-    PRIMARY KEY (SCHED_NAME,ENTRY_ID)
-);
-COMMIT;
-
-BEGIN;
-CREATE TABLE QRTZ_SCHEDULER_STATE
-  (
-    SCHED_NAME VARCHAR(120) NOT NULL,
-    INSTANCE_NAME VARCHAR(200) NOT NULL,
-    LAST_CHECKIN_TIME BIGINT(13) NOT NULL,
-    CHECKIN_INTERVAL BIGINT(13) NOT NULL,
-    PRIMARY KEY (SCHED_NAME,INSTANCE_NAME)
-);
-COMMIT;
-
-BEGIN;
-CREATE TABLE QRTZ_LOCKS
-  (
-    SCHED_NAME VARCHAR(120) NOT NULL,
-    LOCK_NAME  VARCHAR(40) NOT NULL, 
-    PRIMARY KEY (SCHED_NAME,LOCK_NAME)
-);
-COMMIT;

http://git-wip-us.apache.org/repos/asf/syncope/blob/6dfedd8f/core/persistence-jpa/src/main/resources/quartz/tables_mysql.sql
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/resources/quartz/tables_mysql.sql b/core/persistence-jpa/src/main/resources/quartz/tables_mysql.sql
deleted file mode 100644
index ebb8e59..0000000
--- a/core/persistence-jpa/src/main/resources/quartz/tables_mysql.sql
+++ /dev/null
@@ -1,206 +0,0 @@
--- Licensed to the Apache Software Foundation (ASF) under one
--- or more contributor license agreements.  See the NOTICE file
--- distributed with this work for additional information
--- regarding copyright ownership.  The ASF licenses this file
--- to you under the Apache License, Version 2.0 (the
--- "License"); you may not use this file except in compliance
--- with the License.  You may obtain a copy of the License at
---
---   http://www.apache.org/licenses/LICENSE-2.0
---
--- Unless required by applicable law or agreed to in writing,
--- software distributed under the License is distributed on an
--- "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
--- KIND, either express or implied.  See the License for the
--- specific language governing permissions and limitations
--- under the License.
-
---
--- Quartz seems to work best with the driver mm.mysql-2.0.7-bin.jar
---
--- PLEASE consider using mysql with innodb tables to avoid locking issues
---
--- In your Quartz properties file, you'll need to set 
--- org.quartz.jobStore.driverDelegateClass = org.quartz.impl.jdbcjobstore.StdJDBCDelegate
---
-
-BEGIN;
-DROP TABLE IF EXISTS QRTZ_FIRED_TRIGGERS;
-DROP TABLE IF EXISTS QRTZ_PAUSED_TRIGGER_GRPS;
-DROP TABLE IF EXISTS QRTZ_SCHEDULER_STATE;
-DROP TABLE IF EXISTS QRTZ_LOCKS;
-DROP TABLE IF EXISTS QRTZ_SIMPLE_TRIGGERS;
-DROP TABLE IF EXISTS QRTZ_SIMPROP_TRIGGERS;
-DROP TABLE IF EXISTS QRTZ_CRON_TRIGGERS;
-DROP TABLE IF EXISTS QRTZ_BLOB_TRIGGERS;
-DROP TABLE IF EXISTS QRTZ_TRIGGERS;
-DROP TABLE IF EXISTS QRTZ_JOB_DETAILS;
-DROP TABLE IF EXISTS QRTZ_CALENDARS;
-COMMIT;
-
-
-BEGIN;
-CREATE TABLE QRTZ_JOB_DETAILS
-  (
-    SCHED_NAME VARCHAR(120) NOT NULL,
-    JOB_NAME  VARCHAR(200) NOT NULL,
-    JOB_GROUP VARCHAR(200) NOT NULL,
-    DESCRIPTION VARCHAR(250) NULL,
-    JOB_CLASS_NAME   VARCHAR(250) NOT NULL,
-    IS_DURABLE VARCHAR(1) NOT NULL,
-    IS_NONCONCURRENT VARCHAR(1) NOT NULL,
-    IS_UPDATE_DATA VARCHAR(1) NOT NULL,
-    REQUESTS_RECOVERY VARCHAR(1) NOT NULL,
-    JOB_DATA BLOB NULL,
-    PRIMARY KEY (SCHED_NAME,JOB_NAME,JOB_GROUP)
-);
-COMMIT;
-
-BEGIN;
-CREATE TABLE QRTZ_TRIGGERS
-  (
-    SCHED_NAME VARCHAR(120) NOT NULL,
-    TRIGGER_NAME VARCHAR(200) NOT NULL,
-    TRIGGER_GROUP VARCHAR(200) NOT NULL,
-    JOB_NAME  VARCHAR(200) NOT NULL,
-    JOB_GROUP VARCHAR(200) NOT NULL,
-    DESCRIPTION VARCHAR(250) NULL,
-    NEXT_FIRE_TIME BIGINT(13) NULL,
-    PREV_FIRE_TIME BIGINT(13) NULL,
-    PRIORITY INTEGER NULL,
-    TRIGGER_STATE VARCHAR(16) NOT NULL,
-    TRIGGER_TYPE VARCHAR(8) NOT NULL,
-    START_TIME BIGINT(13) NOT NULL,
-    END_TIME BIGINT(13) NULL,
-    CALENDAR_NAME VARCHAR(200) NULL,
-    MISFIRE_INSTR SMALLINT(2) NULL,
-    JOB_DATA BLOB NULL,
-    PRIMARY KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP),
-    FOREIGN KEY (SCHED_NAME,JOB_NAME,JOB_GROUP)
-        REFERENCES QRTZ_JOB_DETAILS(SCHED_NAME,JOB_NAME,JOB_GROUP)
-);
-COMMIT;
-
-BEGIN;
-CREATE TABLE QRTZ_SIMPLE_TRIGGERS
-  (
-    SCHED_NAME VARCHAR(120) NOT NULL,
-    TRIGGER_NAME VARCHAR(200) NOT NULL,
-    TRIGGER_GROUP VARCHAR(200) NOT NULL,
-    REPEAT_COUNT BIGINT(7) NOT NULL,
-    REPEAT_INTERVAL BIGINT(12) NOT NULL,
-    TIMES_TRIGGERED BIGINT(10) NOT NULL,
-    PRIMARY KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP),
-    FOREIGN KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP)
-        REFERENCES QRTZ_TRIGGERS(SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP)
-);
-COMMIT;
-
-BEGIN;
-CREATE TABLE QRTZ_CRON_TRIGGERS
-  (
-    SCHED_NAME VARCHAR(120) NOT NULL,
-    TRIGGER_NAME VARCHAR(200) NOT NULL,
-    TRIGGER_GROUP VARCHAR(200) NOT NULL,
-    CRON_EXPRESSION VARCHAR(200) NOT NULL,
-    TIME_ZONE_ID VARCHAR(80),
-    PRIMARY KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP),
-    FOREIGN KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP)
-        REFERENCES QRTZ_TRIGGERS(SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP)
-);
-COMMIT;
-
-BEGIN;
-CREATE TABLE QRTZ_SIMPROP_TRIGGERS
-  (          
-    SCHED_NAME VARCHAR(120) NOT NULL,
-    TRIGGER_NAME VARCHAR(200) NOT NULL,
-    TRIGGER_GROUP VARCHAR(200) NOT NULL,
-    STR_PROP_1 VARCHAR(512) NULL,
-    STR_PROP_2 VARCHAR(512) NULL,
-    STR_PROP_3 VARCHAR(512) NULL,
-    INT_PROP_1 INT NULL,
-    INT_PROP_2 INT NULL,
-    LONG_PROP_1 BIGINT NULL,
-    LONG_PROP_2 BIGINT NULL,
-    DEC_PROP_1 NUMERIC(13,4) NULL,
-    DEC_PROP_2 NUMERIC(13,4) NULL,
-    BOOL_PROP_1 VARCHAR(1) NULL,
-    BOOL_PROP_2 VARCHAR(1) NULL,
-    PRIMARY KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP),
-    FOREIGN KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP) 
-    REFERENCES QRTZ_TRIGGERS(SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP)
-);
-COMMIT;
-
-BEGIN;
-CREATE TABLE QRTZ_BLOB_TRIGGERS
-  (
-    SCHED_NAME VARCHAR(120) NOT NULL,
-    TRIGGER_NAME VARCHAR(200) NOT NULL,
-    TRIGGER_GROUP VARCHAR(200) NOT NULL,
-    BLOB_DATA BLOB NULL,
-    PRIMARY KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP),
-    FOREIGN KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP)
-        REFERENCES QRTZ_TRIGGERS(SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP)
-);
-COMMIT;
-
-BEGIN;
-CREATE TABLE QRTZ_CALENDARS
-  (
-    SCHED_NAME VARCHAR(120) NOT NULL,
-    CALENDAR_NAME  VARCHAR(200) NOT NULL,
-    CALENDAR BLOB NOT NULL,
-    PRIMARY KEY (SCHED_NAME,CALENDAR_NAME)
-);
-COMMIT;
-
-BEGIN;
-CREATE TABLE QRTZ_PAUSED_TRIGGER_GRPS
-  (
-    SCHED_NAME VARCHAR(120) NOT NULL,
-    TRIGGER_GROUP  VARCHAR(200) NOT NULL, 
-    PRIMARY KEY (SCHED_NAME,TRIGGER_GROUP)
-);
-COMMIT;
-
-BEGIN;
-CREATE TABLE QRTZ_FIRED_TRIGGERS
-  (
-    SCHED_NAME VARCHAR(120) NOT NULL,
-    ENTRY_ID VARCHAR(95) NOT NULL,
-    TRIGGER_NAME VARCHAR(200) NOT NULL,
-    TRIGGER_GROUP VARCHAR(200) NOT NULL,
-    INSTANCE_NAME VARCHAR(200) NOT NULL,
-    FIRED_TIME BIGINT(13) NOT NULL,
-    SCHED_TIME BIGINT(13) NOT NULL,
-    PRIORITY INTEGER NOT NULL,
-    STATE VARCHAR(16) NOT NULL,
-    JOB_NAME VARCHAR(200) NULL,
-    JOB_GROUP VARCHAR(200) NULL,
-    IS_NONCONCURRENT VARCHAR(1) NULL,
-    REQUESTS_RECOVERY VARCHAR(1) NULL,
-    PRIMARY KEY (SCHED_NAME,ENTRY_ID)
-);
-COMMIT;
-
-BEGIN;
-CREATE TABLE QRTZ_SCHEDULER_STATE
-  (
-    SCHED_NAME VARCHAR(120) NOT NULL,
-    INSTANCE_NAME VARCHAR(200) NOT NULL,
-    LAST_CHECKIN_TIME BIGINT(13) NOT NULL,
-    CHECKIN_INTERVAL BIGINT(13) NOT NULL,
-    PRIMARY KEY (SCHED_NAME,INSTANCE_NAME)
-);
-COMMIT;
-
-BEGIN;
-CREATE TABLE QRTZ_LOCKS
-  (
-    SCHED_NAME VARCHAR(120) NOT NULL,
-    LOCK_NAME  VARCHAR(40) NOT NULL, 
-    PRIMARY KEY (SCHED_NAME,LOCK_NAME)
-);
-COMMIT;

http://git-wip-us.apache.org/repos/asf/syncope/blob/6dfedd8f/core/persistence-jpa/src/main/resources/quartz/tables_mysql_innodb.sql
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/resources/quartz/tables_mysql_innodb.sql b/core/persistence-jpa/src/main/resources/quartz/tables_mysql_innodb.sql
deleted file mode 100644
index c54493e..0000000
--- a/core/persistence-jpa/src/main/resources/quartz/tables_mysql_innodb.sql
+++ /dev/null
@@ -1,221 +0,0 @@
--- Licensed to the Apache Software Foundation (ASF) under one
--- or more contributor license agreements.  See the NOTICE file
--- distributed with this work for additional information
--- regarding copyright ownership.  The ASF licenses this file
--- to you under the Apache License, Version 2.0 (the
--- "License"); you may not use this file except in compliance
--- with the License.  You may obtain a copy of the License at
---
---   http://www.apache.org/licenses/LICENSE-2.0
---
--- Unless required by applicable law or agreed to in writing,
--- software distributed under the License is distributed on an
--- "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
--- KIND, either express or implied.  See the License for the
--- specific language governing permissions and limitations
--- under the License.
-
---
--- In your Quartz properties file, you'll need to set 
--- org.quartz.jobStore.driverDelegateClass = org.quartz.impl.jdbcjobstore.StdJDBCDelegate
---
---
--- By: Ron Cordell - roncordell
--- I didn't see this anywhere, so I thought I'd post it here. This is the script from Quartz to create the tables in a MySQL database, modified to use INNODB instead of MYISAM.
---
-
-BEGIN;
-DROP TABLE IF EXISTS QRTZ_FIRED_TRIGGERS;
-DROP TABLE IF EXISTS QRTZ_PAUSED_TRIGGER_GRPS;
-DROP TABLE IF EXISTS QRTZ_SCHEDULER_STATE;
-DROP TABLE IF EXISTS QRTZ_LOCKS;
-DROP TABLE IF EXISTS QRTZ_SIMPLE_TRIGGERS;
-DROP TABLE IF EXISTS QRTZ_SIMPROP_TRIGGERS;
-DROP TABLE IF EXISTS QRTZ_CRON_TRIGGERS;
-DROP TABLE IF EXISTS QRTZ_BLOB_TRIGGERS;
-DROP TABLE IF EXISTS QRTZ_TRIGGERS;
-DROP TABLE IF EXISTS QRTZ_JOB_DETAILS;
-DROP TABLE IF EXISTS QRTZ_CALENDARS;
-COMMIT;
-
-BEGIN;
-CREATE TABLE QRTZ_JOB_DETAILS(
-SCHED_NAME VARCHAR(120) NOT NULL,
-JOB_NAME VARCHAR(200) NOT NULL,
-JOB_GROUP VARCHAR(200) NOT NULL,
-DESCRIPTION VARCHAR(250) NULL,
-JOB_CLASS_NAME VARCHAR(250) NOT NULL,
-IS_DURABLE VARCHAR(1) NOT NULL,
-IS_NONCONCURRENT VARCHAR(1) NOT NULL,
-IS_UPDATE_DATA VARCHAR(1) NOT NULL,
-REQUESTS_RECOVERY VARCHAR(1) NOT NULL,
-JOB_DATA BLOB NULL,
-PRIMARY KEY (SCHED_NAME,JOB_NAME,JOB_GROUP))
-ENGINE=InnoDB;
-COMMIT;
-
-BEGIN;
-CREATE TABLE QRTZ_TRIGGERS (
-SCHED_NAME VARCHAR(120) NOT NULL,
-TRIGGER_NAME VARCHAR(200) NOT NULL,
-TRIGGER_GROUP VARCHAR(200) NOT NULL,
-JOB_NAME VARCHAR(200) NOT NULL,
-JOB_GROUP VARCHAR(200) NOT NULL,
-DESCRIPTION VARCHAR(250) NULL,
-NEXT_FIRE_TIME BIGINT(13) NULL,
-PREV_FIRE_TIME BIGINT(13) NULL,
-PRIORITY INTEGER NULL,
-TRIGGER_STATE VARCHAR(16) NOT NULL,
-TRIGGER_TYPE VARCHAR(8) NOT NULL,
-START_TIME BIGINT(13) NOT NULL,
-END_TIME BIGINT(13) NULL,
-CALENDAR_NAME VARCHAR(200) NULL,
-MISFIRE_INSTR SMALLINT(2) NULL,
-JOB_DATA BLOB NULL,
-PRIMARY KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP),
-FOREIGN KEY (SCHED_NAME,JOB_NAME,JOB_GROUP)
-REFERENCES QRTZ_JOB_DETAILS(SCHED_NAME,JOB_NAME,JOB_GROUP))
-ENGINE=InnoDB;
-COMMIT;
-
-BEGIN;
-CREATE TABLE QRTZ_SIMPLE_TRIGGERS (
-SCHED_NAME VARCHAR(120) NOT NULL,
-TRIGGER_NAME VARCHAR(200) NOT NULL,
-TRIGGER_GROUP VARCHAR(200) NOT NULL,
-REPEAT_COUNT BIGINT(7) NOT NULL,
-REPEAT_INTERVAL BIGINT(12) NOT NULL,
-TIMES_TRIGGERED BIGINT(10) NOT NULL,
-PRIMARY KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP),
-FOREIGN KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP)
-REFERENCES QRTZ_TRIGGERS(SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP))
-ENGINE=InnoDB;
-COMMIT;
-
-BEGIN;
-CREATE TABLE QRTZ_CRON_TRIGGERS (
-SCHED_NAME VARCHAR(120) NOT NULL,
-TRIGGER_NAME VARCHAR(200) NOT NULL,
-TRIGGER_GROUP VARCHAR(200) NOT NULL,
-CRON_EXPRESSION VARCHAR(120) NOT NULL,
-TIME_ZONE_ID VARCHAR(80),
-PRIMARY KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP),
-FOREIGN KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP)
-REFERENCES QRTZ_TRIGGERS(SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP))
-ENGINE=InnoDB;
-COMMIT;
-
-BEGIN;
-CREATE TABLE QRTZ_SIMPROP_TRIGGERS
-  (          
-    SCHED_NAME VARCHAR(120) NOT NULL,
-    TRIGGER_NAME VARCHAR(200) NOT NULL,
-    TRIGGER_GROUP VARCHAR(200) NOT NULL,
-    STR_PROP_1 VARCHAR(512) NULL,
-    STR_PROP_2 VARCHAR(512) NULL,
-    STR_PROP_3 VARCHAR(512) NULL,
-    INT_PROP_1 INT NULL,
-    INT_PROP_2 INT NULL,
-    LONG_PROP_1 BIGINT NULL,
-    LONG_PROP_2 BIGINT NULL,
-    DEC_PROP_1 NUMERIC(13,4) NULL,
-    DEC_PROP_2 NUMERIC(13,4) NULL,
-    BOOL_PROP_1 VARCHAR(1) NULL,
-    BOOL_PROP_2 VARCHAR(1) NULL,
-    PRIMARY KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP),
-    FOREIGN KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP) 
-    REFERENCES QRTZ_TRIGGERS(SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP))
-ENGINE=InnoDB;
-COMMIT;
-
-BEGIN;
-CREATE TABLE QRTZ_BLOB_TRIGGERS (
-SCHED_NAME VARCHAR(120) NOT NULL,
-TRIGGER_NAME VARCHAR(200) NOT NULL,
-TRIGGER_GROUP VARCHAR(200) NOT NULL,
-BLOB_DATA BLOB NULL,
-PRIMARY KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP),
-INDEX (SCHED_NAME,TRIGGER_NAME, TRIGGER_GROUP),
-FOREIGN KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP)
-REFERENCES QRTZ_TRIGGERS(SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP))
-ENGINE=InnoDB;
-COMMIT;
-
-BEGIN;
-CREATE TABLE QRTZ_CALENDARS (
-SCHED_NAME VARCHAR(120) NOT NULL,
-CALENDAR_NAME VARCHAR(200) NOT NULL,
-CALENDAR BLOB NOT NULL,
-PRIMARY KEY (SCHED_NAME,CALENDAR_NAME))
-ENGINE=InnoDB;
-COMMIT;
-
-BEGIN;
-CREATE TABLE QRTZ_PAUSED_TRIGGER_GRPS (
-SCHED_NAME VARCHAR(120) NOT NULL,
-TRIGGER_GROUP VARCHAR(200) NOT NULL,
-PRIMARY KEY (SCHED_NAME,TRIGGER_GROUP))
-ENGINE=InnoDB;
-COMMIT;
-
-BEGIN;
-CREATE TABLE QRTZ_FIRED_TRIGGERS (
-SCHED_NAME VARCHAR(120) NOT NULL,
-ENTRY_ID VARCHAR(95) NOT NULL,
-TRIGGER_NAME VARCHAR(200) NOT NULL,
-TRIGGER_GROUP VARCHAR(200) NOT NULL,
-INSTANCE_NAME VARCHAR(200) NOT NULL,
-FIRED_TIME BIGINT(13) NOT NULL,
-SCHED_TIME BIGINT(13) NOT NULL,
-PRIORITY INTEGER NOT NULL,
-STATE VARCHAR(16) NOT NULL,
-JOB_NAME VARCHAR(200) NULL,
-JOB_GROUP VARCHAR(200) NULL,
-IS_NONCONCURRENT VARCHAR(1) NULL,
-REQUESTS_RECOVERY VARCHAR(1) NULL,
-PRIMARY KEY (SCHED_NAME,ENTRY_ID))
-ENGINE=InnoDB;
-COMMIT;
-
-BEGIN;
-CREATE TABLE QRTZ_SCHEDULER_STATE (
-SCHED_NAME VARCHAR(120) NOT NULL,
-INSTANCE_NAME VARCHAR(200) NOT NULL,
-LAST_CHECKIN_TIME BIGINT(13) NOT NULL,
-CHECKIN_INTERVAL BIGINT(13) NOT NULL,
-PRIMARY KEY (SCHED_NAME,INSTANCE_NAME))
-ENGINE=InnoDB;
-COMMIT;
-
-BEGIN;
-CREATE TABLE QRTZ_LOCKS (
-SCHED_NAME VARCHAR(120) NOT NULL,
-LOCK_NAME VARCHAR(40) NOT NULL,
-PRIMARY KEY (SCHED_NAME,LOCK_NAME))
-ENGINE=InnoDB;
-COMMIT;
-
-BEGIN;
-CREATE INDEX IDX_QRTZ_J_REQ_RECOVERY ON QRTZ_JOB_DETAILS(SCHED_NAME,REQUESTS_RECOVERY);
-CREATE INDEX IDX_QRTZ_J_GRP ON QRTZ_JOB_DETAILS(SCHED_NAME,JOB_GROUP);
-
-CREATE INDEX IDX_QRTZ_T_J ON QRTZ_TRIGGERS(SCHED_NAME,JOB_NAME,JOB_GROUP);
-CREATE INDEX IDX_QRTZ_T_JG ON QRTZ_TRIGGERS(SCHED_NAME,JOB_GROUP);
-CREATE INDEX IDX_QRTZ_T_C ON QRTZ_TRIGGERS(SCHED_NAME,CALENDAR_NAME);
-CREATE INDEX IDX_QRTZ_T_G ON QRTZ_TRIGGERS(SCHED_NAME,TRIGGER_GROUP);
-CREATE INDEX IDX_QRTZ_T_STATE ON QRTZ_TRIGGERS(SCHED_NAME,TRIGGER_STATE);
-CREATE INDEX IDX_QRTZ_T_N_STATE ON QRTZ_TRIGGERS(SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP,TRIGGER_STATE);
-CREATE INDEX IDX_QRTZ_T_N_G_STATE ON QRTZ_TRIGGERS(SCHED_NAME,TRIGGER_GROUP,TRIGGER_STATE);
-CREATE INDEX IDX_QRTZ_T_NEXT_FIRE_TIME ON QRTZ_TRIGGERS(SCHED_NAME,NEXT_FIRE_TIME);
-CREATE INDEX IDX_QRTZ_T_NFT_ST ON QRTZ_TRIGGERS(SCHED_NAME,TRIGGER_STATE,NEXT_FIRE_TIME);
-CREATE INDEX IDX_QRTZ_T_NFT_MISFIRE ON QRTZ_TRIGGERS(SCHED_NAME,MISFIRE_INSTR,NEXT_FIRE_TIME);
-CREATE INDEX IDX_QRTZ_T_NFT_ST_MISFIRE ON QRTZ_TRIGGERS(SCHED_NAME,MISFIRE_INSTR,NEXT_FIRE_TIME,TRIGGER_STATE);
-CREATE INDEX IDX_QRTZ_T_NFT_ST_MISFIRE_GRP ON QRTZ_TRIGGERS(SCHED_NAME,MISFIRE_INSTR,NEXT_FIRE_TIME,TRIGGER_GROUP,TRIGGER_STATE);
-
-CREATE INDEX IDX_QRTZ_FT_TRIG_INST_NAME ON QRTZ_FIRED_TRIGGERS(SCHED_NAME,INSTANCE_NAME);
-CREATE INDEX IDX_QRTZ_FT_INST_JOB_REQ_RCVRY ON QRTZ_FIRED_TRIGGERS(SCHED_NAME,INSTANCE_NAME,REQUESTS_RECOVERY);
-CREATE INDEX IDX_QRTZ_FT_J_G ON QRTZ_FIRED_TRIGGERS(SCHED_NAME,JOB_NAME,JOB_GROUP);
-CREATE INDEX IDX_QRTZ_FT_JG ON QRTZ_FIRED_TRIGGERS(SCHED_NAME,JOB_GROUP);
-CREATE INDEX IDX_QRTZ_FT_T_G ON QRTZ_FIRED_TRIGGERS(SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP);
-CREATE INDEX IDX_QRTZ_FT_TG ON QRTZ_FIRED_TRIGGERS(SCHED_NAME,TRIGGER_GROUP);
-COMMIT;

http://git-wip-us.apache.org/repos/asf/syncope/blob/6dfedd8f/core/persistence-jpa/src/main/resources/quartz/tables_oracle.sql
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/resources/quartz/tables_oracle.sql b/core/persistence-jpa/src/main/resources/quartz/tables_oracle.sql
deleted file mode 100644
index 4384ac5..0000000
--- a/core/persistence-jpa/src/main/resources/quartz/tables_oracle.sql
+++ /dev/null
@@ -1,208 +0,0 @@
--- Licensed to the Apache Software Foundation (ASF) under one
--- or more contributor license agreements.  See the NOTICE file
--- distributed with this work for additional information
--- regarding copyright ownership.  The ASF licenses this file
--- to you under the Apache License, Version 2.0 (the
--- "License"); you may not use this file except in compliance
--- with the License.  You may obtain a copy of the License at
---
---   http://www.apache.org/licenses/LICENSE-2.0
---
--- Unless required by applicable law or agreed to in writing,
--- software distributed under the License is distributed on an
--- "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
--- KIND, either express or implied.  See the License for the
--- specific language governing permissions and limitations
--- under the License.
-
---
--- A hint submitted by a user: Oracle DB MUST be created as "shared" and the 
--- job_queue_processes parameter  must be greater than 2
--- However, these settings are pretty much standard after any
--- Oracle install, so most users need not worry about this.
---
--- Many other users (including the primary author of Quartz) have had success
--- runing in dedicated mode, so only consider the above as a hint ;-)
---
-
-delete from qrtz_fired_triggers;
-delete from qrtz_simple_triggers;
-delete from qrtz_simprop_triggers;
-delete from qrtz_cron_triggers;
-delete from qrtz_blob_triggers;
-delete from qrtz_triggers;
-delete from qrtz_job_details;
-delete from qrtz_calendars;
-delete from qrtz_paused_trigger_grps;
-delete from qrtz_locks;
-delete from qrtz_scheduler_state;
-
-drop table qrtz_calendars;
-drop table qrtz_fired_triggers;
-drop table qrtz_blob_triggers;
-drop table qrtz_cron_triggers;
-drop table qrtz_simple_triggers;
-drop table qrtz_simprop_triggers;
-drop table qrtz_triggers;
-drop table qrtz_job_details;
-drop table qrtz_paused_trigger_grps;
-drop table qrtz_locks;
-drop table qrtz_scheduler_state;
-
-
-CREATE TABLE qrtz_job_details
-  (
-    SCHED_NAME VARCHAR2(120) NOT NULL,
-    JOB_NAME  VARCHAR2(200) NOT NULL,
-    JOB_GROUP VARCHAR2(200) NOT NULL,
-    DESCRIPTION VARCHAR2(250) NULL,
-    JOB_CLASS_NAME   VARCHAR2(250) NOT NULL, 
-    IS_DURABLE VARCHAR2(1) NOT NULL,
-    IS_NONCONCURRENT VARCHAR2(1) NOT NULL,
-    IS_UPDATE_DATA VARCHAR2(1) NOT NULL,
-    REQUESTS_RECOVERY VARCHAR2(1) NOT NULL,
-    JOB_DATA BLOB NULL,
-    CONSTRAINT QRTZ_JOB_DETAILS_PK PRIMARY KEY (SCHED_NAME,JOB_NAME,JOB_GROUP)
-);
-CREATE TABLE qrtz_triggers
-  (
-    SCHED_NAME VARCHAR2(120) NOT NULL,
-    TRIGGER_NAME VARCHAR2(200) NOT NULL,
-    TRIGGER_GROUP VARCHAR2(200) NOT NULL,
-    JOB_NAME  VARCHAR2(200) NOT NULL, 
-    JOB_GROUP VARCHAR2(200) NOT NULL,
-    DESCRIPTION VARCHAR2(250) NULL,
-    NEXT_FIRE_TIME NUMBER(13) NULL,
-    PREV_FIRE_TIME NUMBER(13) NULL,
-    PRIORITY NUMBER(13) NULL,
-    TRIGGER_STATE VARCHAR2(16) NOT NULL,
-    TRIGGER_TYPE VARCHAR2(8) NOT NULL,
-    START_TIME NUMBER(13) NOT NULL,
-    END_TIME NUMBER(13) NULL,
-    CALENDAR_NAME VARCHAR2(200) NULL,
-    MISFIRE_INSTR NUMBER(2) NULL,
-    JOB_DATA BLOB NULL,
-    CONSTRAINT QRTZ_TRIGGERS_PK PRIMARY KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP),
-    CONSTRAINT QRTZ_TRIGGER_TO_JOBS_FK FOREIGN KEY (SCHED_NAME,JOB_NAME,JOB_GROUP) 
-      REFERENCES QRTZ_JOB_DETAILS(SCHED_NAME,JOB_NAME,JOB_GROUP) 
-);
-CREATE TABLE qrtz_simple_triggers
-  (
-    SCHED_NAME VARCHAR2(120) NOT NULL,
-    TRIGGER_NAME VARCHAR2(200) NOT NULL,
-    TRIGGER_GROUP VARCHAR2(200) NOT NULL,
-    REPEAT_COUNT NUMBER(7) NOT NULL,
-    REPEAT_INTERVAL NUMBER(12) NOT NULL,
-    TIMES_TRIGGERED NUMBER(10) NOT NULL,
-    CONSTRAINT QRTZ_SIMPLE_TRIG_PK PRIMARY KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP),
-    CONSTRAINT QRTZ_SIMPLE_TRIG_TO_TRIG_FK FOREIGN KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP) 
-	REFERENCES QRTZ_TRIGGERS(SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP)
-);
-CREATE TABLE qrtz_cron_triggers
-  (
-    SCHED_NAME VARCHAR2(120) NOT NULL,
-    TRIGGER_NAME VARCHAR2(200) NOT NULL,
-    TRIGGER_GROUP VARCHAR2(200) NOT NULL,
-    CRON_EXPRESSION VARCHAR2(120) NOT NULL,
-    TIME_ZONE_ID VARCHAR2(80),
-    CONSTRAINT QRTZ_CRON_TRIG_PK PRIMARY KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP),
-    CONSTRAINT QRTZ_CRON_TRIG_TO_TRIG_FK FOREIGN KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP) 
-      REFERENCES QRTZ_TRIGGERS(SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP)
-);
-CREATE TABLE qrtz_simprop_triggers
-  (          
-    SCHED_NAME VARCHAR2(120) NOT NULL,
-    TRIGGER_NAME VARCHAR2(200) NOT NULL,
-    TRIGGER_GROUP VARCHAR2(200) NOT NULL,
-    STR_PROP_1 VARCHAR2(512) NULL,
-    STR_PROP_2 VARCHAR2(512) NULL,
-    STR_PROP_3 VARCHAR2(512) NULL,
-    INT_PROP_1 NUMBER(10) NULL,
-    INT_PROP_2 NUMBER(10) NULL,
-    LONG_PROP_1 NUMBER(13) NULL,
-    LONG_PROP_2 NUMBER(13) NULL,
-    DEC_PROP_1 NUMERIC(13,4) NULL,
-    DEC_PROP_2 NUMERIC(13,4) NULL,
-    BOOL_PROP_1 VARCHAR2(1) NULL,
-    BOOL_PROP_2 VARCHAR2(1) NULL,
-    CONSTRAINT QRTZ_SIMPROP_TRIG_PK PRIMARY KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP),
-    CONSTRAINT QRTZ_SIMPROP_TRIG_TO_TRIG_FK FOREIGN KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP) 
-      REFERENCES QRTZ_TRIGGERS(SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP)
-);
-CREATE TABLE qrtz_blob_triggers
-  (
-    SCHED_NAME VARCHAR2(120) NOT NULL,
-    TRIGGER_NAME VARCHAR2(200) NOT NULL,
-    TRIGGER_GROUP VARCHAR2(200) NOT NULL,
-    BLOB_DATA BLOB NULL,
-    CONSTRAINT QRTZ_BLOB_TRIG_PK PRIMARY KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP),
-    CONSTRAINT QRTZ_BLOB_TRIG_TO_TRIG_FK FOREIGN KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP) 
-        REFERENCES QRTZ_TRIGGERS(SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP)
-);
-CREATE TABLE qrtz_calendars
-  (
-    SCHED_NAME VARCHAR2(120) NOT NULL,
-    CALENDAR_NAME  VARCHAR2(200) NOT NULL, 
-    CALENDAR BLOB NOT NULL,
-    CONSTRAINT QRTZ_CALENDARS_PK PRIMARY KEY (SCHED_NAME,CALENDAR_NAME)
-);
-CREATE TABLE qrtz_paused_trigger_grps
-  (
-    SCHED_NAME VARCHAR2(120) NOT NULL,
-    TRIGGER_GROUP  VARCHAR2(200) NOT NULL, 
-    CONSTRAINT QRTZ_PAUSED_TRIG_GRPS_PK PRIMARY KEY (SCHED_NAME,TRIGGER_GROUP)
-);
-CREATE TABLE qrtz_fired_triggers 
-  (
-    SCHED_NAME VARCHAR2(120) NOT NULL,
-    ENTRY_ID VARCHAR2(95) NOT NULL,
-    TRIGGER_NAME VARCHAR2(200) NOT NULL,
-    TRIGGER_GROUP VARCHAR2(200) NOT NULL,
-    INSTANCE_NAME VARCHAR2(200) NOT NULL,
-    FIRED_TIME NUMBER(13) NOT NULL,
-    SCHED_TIME NUMBER(13) NOT NULL,
-    PRIORITY NUMBER(13) NOT NULL,
-    STATE VARCHAR2(16) NOT NULL,
-    JOB_NAME VARCHAR2(200) NULL,
-    JOB_GROUP VARCHAR2(200) NULL,
-    IS_NONCONCURRENT VARCHAR2(1) NULL,
-    REQUESTS_RECOVERY VARCHAR2(1) NULL,
-    CONSTRAINT QRTZ_FIRED_TRIGGER_PK PRIMARY KEY (SCHED_NAME,ENTRY_ID)
-);
-CREATE TABLE qrtz_scheduler_state 
-  (
-    SCHED_NAME VARCHAR2(120) NOT NULL,
-    INSTANCE_NAME VARCHAR2(200) NOT NULL,
-    LAST_CHECKIN_TIME NUMBER(13) NOT NULL,
-    CHECKIN_INTERVAL NUMBER(13) NOT NULL,
-    CONSTRAINT QRTZ_SCHEDULER_STATE_PK PRIMARY KEY (SCHED_NAME,INSTANCE_NAME)
-);
-CREATE TABLE qrtz_locks
-  (
-    SCHED_NAME VARCHAR2(120) NOT NULL,
-    LOCK_NAME  VARCHAR2(40) NOT NULL, 
-    CONSTRAINT QRTZ_LOCKS_PK PRIMARY KEY (SCHED_NAME,LOCK_NAME)
-);
-
-create index idx_qrtz_j_req_recovery on qrtz_job_details(SCHED_NAME,REQUESTS_RECOVERY);
-create index idx_qrtz_j_grp on qrtz_job_details(SCHED_NAME,JOB_GROUP);
-
-create index idx_qrtz_t_j on qrtz_triggers(SCHED_NAME,JOB_NAME,JOB_GROUP);
-create index idx_qrtz_t_jg on qrtz_triggers(SCHED_NAME,JOB_GROUP);
-create index idx_qrtz_t_c on qrtz_triggers(SCHED_NAME,CALENDAR_NAME);
-create index idx_qrtz_t_g on qrtz_triggers(SCHED_NAME,TRIGGER_GROUP);
-create index idx_qrtz_t_state on qrtz_triggers(SCHED_NAME,TRIGGER_STATE);
-create index idx_qrtz_t_n_state on qrtz_triggers(SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP,TRIGGER_STATE);
-create index idx_qrtz_t_n_g_state on qrtz_triggers(SCHED_NAME,TRIGGER_GROUP,TRIGGER_STATE);
-create index idx_qrtz_t_next_fire_time on qrtz_triggers(SCHED_NAME,NEXT_FIRE_TIME);
-create index idx_qrtz_t_nft_st on qrtz_triggers(SCHED_NAME,TRIGGER_STATE,NEXT_FIRE_TIME);
-create index idx_qrtz_t_nft_misfire on qrtz_triggers(SCHED_NAME,MISFIRE_INSTR,NEXT_FIRE_TIME);
-create index idx_qrtz_t_nft_st_misfire on qrtz_triggers(SCHED_NAME,MISFIRE_INSTR,NEXT_FIRE_TIME,TRIGGER_STATE);
-create index idx_qrtz_t_nft_st_misfire_grp on qrtz_triggers(SCHED_NAME,MISFIRE_INSTR,NEXT_FIRE_TIME,TRIGGER_GROUP,TRIGGER_STATE);
-
-create index idx_qrtz_ft_trig_inst_name on qrtz_fired_triggers(SCHED_NAME,INSTANCE_NAME);
-create index idx_qrtz_ft_inst_job_req_rcvry on qrtz_fired_triggers(SCHED_NAME,INSTANCE_NAME,REQUESTS_RECOVERY);
-create index idx_qrtz_ft_j_g on qrtz_fired_triggers(SCHED_NAME,JOB_NAME,JOB_GROUP);
-create index idx_qrtz_ft_jg on qrtz_fired_triggers(SCHED_NAME,JOB_GROUP);
-create index idx_qrtz_ft_t_g on qrtz_fired_triggers(SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP);
-create index idx_qrtz_ft_tg on qrtz_fired_triggers(SCHED_NAME,TRIGGER_GROUP);

http://git-wip-us.apache.org/repos/asf/syncope/blob/6dfedd8f/core/persistence-jpa/src/main/resources/quartz/tables_postgres.sql
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/resources/quartz/tables_postgres.sql b/core/persistence-jpa/src/main/resources/quartz/tables_postgres.sql
deleted file mode 100644
index 9b7800f..0000000
--- a/core/persistence-jpa/src/main/resources/quartz/tables_postgres.sql
+++ /dev/null
@@ -1,204 +0,0 @@
--- Licensed to the Apache Software Foundation (ASF) under one
--- or more contributor license agreements.  See the NOTICE file
--- distributed with this work for additional information
--- regarding copyright ownership.  The ASF licenses this file
--- to you under the Apache License, Version 2.0 (the
--- "License"); you may not use this file except in compliance
--- with the License.  You may obtain a copy of the License at
---
---   http://www.apache.org/licenses/LICENSE-2.0
---
--- Unless required by applicable law or agreed to in writing,
--- software distributed under the License is distributed on an
--- "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
--- KIND, either express or implied.  See the License for the
--- specific language governing permissions and limitations
--- under the License.
-
--- Thanks to Patrick Lightbody for submitting this...
---
--- In your Quartz properties file, you'll need to set 
--- org.quartz.jobStore.driverDelegateClass = org.quartz.impl.jdbcjobstore.PostgreSQLDelegate
-
-drop table qrtz_fired_triggers;
-DROP TABLE QRTZ_PAUSED_TRIGGER_GRPS;
-DROP TABLE QRTZ_SCHEDULER_STATE;
-DROP TABLE QRTZ_LOCKS;
-drop table qrtz_simple_triggers;
-drop table qrtz_cron_triggers;
-drop table qrtz_simprop_triggers;
-DROP TABLE QRTZ_BLOB_TRIGGERS;
-drop table qrtz_triggers;
-drop table qrtz_job_details;
-drop table qrtz_calendars;
-
-CREATE TABLE qrtz_job_details
-  (
-    SCHED_NAME VARCHAR(120) NOT NULL,
-    JOB_NAME  VARCHAR(200) NOT NULL,
-    JOB_GROUP VARCHAR(200) NOT NULL,
-    DESCRIPTION VARCHAR(250) NULL,
-    JOB_CLASS_NAME   VARCHAR(250) NOT NULL, 
-    IS_DURABLE BOOL NOT NULL,
-    IS_NONCONCURRENT BOOL NOT NULL,
-    IS_UPDATE_DATA BOOL NOT NULL,
-    REQUESTS_RECOVERY BOOL NOT NULL,
-    JOB_DATA BYTEA NULL,
-    PRIMARY KEY (SCHED_NAME,JOB_NAME,JOB_GROUP)
-);
-
-CREATE TABLE qrtz_triggers
-  (
-    SCHED_NAME VARCHAR(120) NOT NULL,
-    TRIGGER_NAME VARCHAR(200) NOT NULL,
-    TRIGGER_GROUP VARCHAR(200) NOT NULL,
-    JOB_NAME  VARCHAR(200) NOT NULL, 
-    JOB_GROUP VARCHAR(200) NOT NULL,
-    DESCRIPTION VARCHAR(250) NULL,
-    NEXT_FIRE_TIME BIGINT NULL,
-    PREV_FIRE_TIME BIGINT NULL,
-    PRIORITY INTEGER NULL,
-    TRIGGER_STATE VARCHAR(16) NOT NULL,
-    TRIGGER_TYPE VARCHAR(8) NOT NULL,
-    START_TIME BIGINT NOT NULL,
-    END_TIME BIGINT NULL,
-    CALENDAR_NAME VARCHAR(200) NULL,
-    MISFIRE_INSTR SMALLINT NULL,
-    JOB_DATA BYTEA NULL,
-    PRIMARY KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP),
-    FOREIGN KEY (SCHED_NAME,JOB_NAME,JOB_GROUP) 
-	REFERENCES QRTZ_JOB_DETAILS(SCHED_NAME,JOB_NAME,JOB_GROUP) 
-);
-
-CREATE TABLE qrtz_simple_triggers
-  (
-    SCHED_NAME VARCHAR(120) NOT NULL,
-    TRIGGER_NAME VARCHAR(200) NOT NULL,
-    TRIGGER_GROUP VARCHAR(200) NOT NULL,
-    REPEAT_COUNT BIGINT NOT NULL,
-    REPEAT_INTERVAL BIGINT NOT NULL,
-    TIMES_TRIGGERED BIGINT NOT NULL,
-    PRIMARY KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP),
-    FOREIGN KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP) 
-	REFERENCES QRTZ_TRIGGERS(SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP)
-);
-
-CREATE TABLE qrtz_cron_triggers
-  (
-    SCHED_NAME VARCHAR(120) NOT NULL,
-    TRIGGER_NAME VARCHAR(200) NOT NULL,
-    TRIGGER_GROUP VARCHAR(200) NOT NULL,
-    CRON_EXPRESSION VARCHAR(120) NOT NULL,
-    TIME_ZONE_ID VARCHAR(80),
-    PRIMARY KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP),
-    FOREIGN KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP) 
-	REFERENCES QRTZ_TRIGGERS(SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP)
-);
-
-CREATE TABLE qrtz_simprop_triggers
-  (          
-    SCHED_NAME VARCHAR(120) NOT NULL,
-    TRIGGER_NAME VARCHAR(200) NOT NULL,
-    TRIGGER_GROUP VARCHAR(200) NOT NULL,
-    STR_PROP_1 VARCHAR(512) NULL,
-    STR_PROP_2 VARCHAR(512) NULL,
-    STR_PROP_3 VARCHAR(512) NULL,
-    INT_PROP_1 INT NULL,
-    INT_PROP_2 INT NULL,
-    LONG_PROP_1 BIGINT NULL,
-    LONG_PROP_2 BIGINT NULL,
-    DEC_PROP_1 NUMERIC(13,4) NULL,
-    DEC_PROP_2 NUMERIC(13,4) NULL,
-    BOOL_PROP_1 BOOL NULL,
-    BOOL_PROP_2 BOOL NULL,
-    PRIMARY KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP),
-    FOREIGN KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP) 
-    REFERENCES QRTZ_TRIGGERS(SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP)
-);
-
-CREATE TABLE qrtz_blob_triggers
-  (
-    SCHED_NAME VARCHAR(120) NOT NULL,
-    TRIGGER_NAME VARCHAR(200) NOT NULL,
-    TRIGGER_GROUP VARCHAR(200) NOT NULL,
-    BLOB_DATA BYTEA NULL,
-    PRIMARY KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP),
-    FOREIGN KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP) 
-        REFERENCES QRTZ_TRIGGERS(SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP)
-);
-
-CREATE TABLE qrtz_calendars
-  (
-    SCHED_NAME VARCHAR(120) NOT NULL,
-    CALENDAR_NAME  VARCHAR(200) NOT NULL, 
-    CALENDAR BYTEA NOT NULL,
-    PRIMARY KEY (SCHED_NAME,CALENDAR_NAME)
-);
-
-
-CREATE TABLE qrtz_paused_trigger_grps
-  (
-    SCHED_NAME VARCHAR(120) NOT NULL,
-    TRIGGER_GROUP  VARCHAR(200) NOT NULL, 
-    PRIMARY KEY (SCHED_NAME,TRIGGER_GROUP)
-);
-
-CREATE TABLE qrtz_fired_triggers 
-  (
-    SCHED_NAME VARCHAR(120) NOT NULL,
-    ENTRY_ID VARCHAR(95) NOT NULL,
-    TRIGGER_NAME VARCHAR(200) NOT NULL,
-    TRIGGER_GROUP VARCHAR(200) NOT NULL,
-    INSTANCE_NAME VARCHAR(200) NOT NULL,
-    FIRED_TIME BIGINT NOT NULL,
-    SCHED_TIME BIGINT NOT NULL,
-    PRIORITY INTEGER NOT NULL,
-    STATE VARCHAR(16) NOT NULL,
-    JOB_NAME VARCHAR(200) NULL,
-    JOB_GROUP VARCHAR(200) NULL,
-    IS_NONCONCURRENT BOOL NULL,
-    REQUESTS_RECOVERY BOOL NULL,
-    PRIMARY KEY (SCHED_NAME,ENTRY_ID)
-);
-
-CREATE TABLE qrtz_scheduler_state 
-  (
-    SCHED_NAME VARCHAR(120) NOT NULL,
-    INSTANCE_NAME VARCHAR(200) NOT NULL,
-    LAST_CHECKIN_TIME BIGINT NOT NULL,
-    CHECKIN_INTERVAL BIGINT NOT NULL,
-    PRIMARY KEY (SCHED_NAME,INSTANCE_NAME)
-);
-
-CREATE TABLE qrtz_locks
-  (
-    SCHED_NAME VARCHAR(120) NOT NULL,
-    LOCK_NAME  VARCHAR(40) NOT NULL, 
-    PRIMARY KEY (SCHED_NAME,LOCK_NAME)
-);
-
-create index idx_qrtz_j_req_recovery on qrtz_job_details(SCHED_NAME,REQUESTS_RECOVERY);
-create index idx_qrtz_j_grp on qrtz_job_details(SCHED_NAME,JOB_GROUP);
-
-create index idx_qrtz_t_j on qrtz_triggers(SCHED_NAME,JOB_NAME,JOB_GROUP);
-create index idx_qrtz_t_jg on qrtz_triggers(SCHED_NAME,JOB_GROUP);
-create index idx_qrtz_t_c on qrtz_triggers(SCHED_NAME,CALENDAR_NAME);
-create index idx_qrtz_t_g on qrtz_triggers(SCHED_NAME,TRIGGER_GROUP);
-create index idx_qrtz_t_state on qrtz_triggers(SCHED_NAME,TRIGGER_STATE);
-create index idx_qrtz_t_n_state on qrtz_triggers(SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP,TRIGGER_STATE);
-create index idx_qrtz_t_n_g_state on qrtz_triggers(SCHED_NAME,TRIGGER_GROUP,TRIGGER_STATE);
-create index idx_qrtz_t_next_fire_time on qrtz_triggers(SCHED_NAME,NEXT_FIRE_TIME);
-create index idx_qrtz_t_nft_st on qrtz_triggers(SCHED_NAME,TRIGGER_STATE,NEXT_FIRE_TIME);
-create index idx_qrtz_t_nft_misfire on qrtz_triggers(SCHED_NAME,MISFIRE_INSTR,NEXT_FIRE_TIME);
-create index idx_qrtz_t_nft_st_misfire on qrtz_triggers(SCHED_NAME,MISFIRE_INSTR,NEXT_FIRE_TIME,TRIGGER_STATE);
-create index idx_qrtz_t_nft_st_misfire_grp on qrtz_triggers(SCHED_NAME,MISFIRE_INSTR,NEXT_FIRE_TIME,TRIGGER_GROUP,TRIGGER_STATE);
-
-create index idx_qrtz_ft_trig_inst_name on qrtz_fired_triggers(SCHED_NAME,INSTANCE_NAME);
-create index idx_qrtz_ft_inst_job_req_rcvry on qrtz_fired_triggers(SCHED_NAME,INSTANCE_NAME,REQUESTS_RECOVERY);
-create index idx_qrtz_ft_j_g on qrtz_fired_triggers(SCHED_NAME,JOB_NAME,JOB_GROUP);
-create index idx_qrtz_ft_jg on qrtz_fired_triggers(SCHED_NAME,JOB_GROUP);
-create index idx_qrtz_ft_t_g on qrtz_fired_triggers(SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP);
-create index idx_qrtz_ft_tg on qrtz_fired_triggers(SCHED_NAME,TRIGGER_GROUP);
-
-
-commit;

http://git-wip-us.apache.org/repos/asf/syncope/blob/6dfedd8f/core/persistence-jpa/src/main/resources/quartz/tables_sqlServer.sql
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/resources/quartz/tables_sqlServer.sql b/core/persistence-jpa/src/main/resources/quartz/tables_sqlServer.sql
deleted file mode 100644
index 288b990..0000000
--- a/core/persistence-jpa/src/main/resources/quartz/tables_sqlServer.sql
+++ /dev/null
@@ -1,296 +0,0 @@
--- Licensed to the Apache Software Foundation (ASF) under one
--- or more contributor license agreements.  See the NOTICE file
--- distributed with this work for additional information
--- regarding copyright ownership.  The ASF licenses this file
--- to you under the Apache License, Version 2.0 (the
--- "License"); you may not use this file except in compliance
--- with the License.  You may obtain a copy of the License at
---
---   http://www.apache.org/licenses/LICENSE-2.0
---
--- Unless required by applicable law or agreed to in writing,
--- software distributed under the License is distributed on an
--- "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
--- KIND, either express or implied.  See the License for the
--- specific language governing permissions and limitations
--- under the License.
-
-IF EXISTS (SELECT * FROM dbo.sysobjects WHERE id = OBJECT_ID(N'[dbo].[FK_QRTZ_TRIGGERS_QRTZ_JOB_DETAILS]') AND OBJECTPROPERTY(id, N'ISFOREIGNKEY') = 1)
-ALTER TABLE [dbo].[QRTZ_TRIGGERS] DROP CONSTRAINT FK_QRTZ_TRIGGERS_QRTZ_JOB_DETAILS;
-
-IF EXISTS (SELECT * FROM dbo.sysobjects WHERE id = OBJECT_ID(N'[dbo].[FK_QRTZ_CRON_TRIGGERS_QRTZ_TRIGGERS]') AND OBJECTPROPERTY(id, N'ISFOREIGNKEY') = 1)
-ALTER TABLE [dbo].[QRTZ_CRON_TRIGGERS] DROP CONSTRAINT FK_QRTZ_CRON_TRIGGERS_QRTZ_TRIGGERS;
-
-IF EXISTS (SELECT * FROM dbo.sysobjects WHERE id = OBJECT_ID(N'[dbo].[FK_QRTZ_SIMPLE_TRIGGERS_QRTZ_TRIGGERS]') AND OBJECTPROPERTY(id, N'ISFOREIGNKEY') = 1)
-ALTER TABLE [dbo].[QRTZ_SIMPLE_TRIGGERS] DROP CONSTRAINT FK_QRTZ_SIMPLE_TRIGGERS_QRTZ_TRIGGERS;
-
-IF EXISTS (SELECT * FROM dbo.sysobjects WHERE id = OBJECT_ID(N'[dbo].[FK_QRTZ_SIMPROP_TRIGGERS_QRTZ_TRIGGERS]') AND OBJECTPROPERTY(id, N'ISFOREIGNKEY') = 1)
-ALTER TABLE [dbo].[QRTZ_SIMPROP_TRIGGERS] DROP CONSTRAINT FK_QRTZ_SIMPROP_TRIGGERS_QRTZ_TRIGGERS;
-
-IF EXISTS (SELECT * FROM dbo.sysobjects WHERE id = OBJECT_ID(N'[dbo].[QRTZ_CALENDARS]') AND OBJECTPROPERTY(id, N'ISUSERTABLE') = 1)
-DROP TABLE [dbo].[QRTZ_CALENDARS];
-
-IF EXISTS (SELECT * FROM dbo.sysobjects WHERE id = OBJECT_ID(N'[dbo].[QRTZ_CRON_TRIGGERS]') AND OBJECTPROPERTY(id, N'ISUSERTABLE') = 1)
-DROP TABLE [dbo].[QRTZ_CRON_TRIGGERS];
-
-IF EXISTS (SELECT * FROM dbo.sysobjects WHERE id = OBJECT_ID(N'[dbo].[QRTZ_BLOB_TRIGGERS]') AND OBJECTPROPERTY(id, N'ISUSERTABLE') = 1)
-DROP TABLE [dbo].[QRTZ_BLOB_TRIGGERS];
-
-IF EXISTS (SELECT * FROM dbo.sysobjects WHERE id = OBJECT_ID(N'[dbo].[QRTZ_FIRED_TRIGGERS]') AND OBJECTPROPERTY(id, N'ISUSERTABLE') = 1)
-DROP TABLE [dbo].[QRTZ_FIRED_TRIGGERS];
-
-IF EXISTS (SELECT * FROM dbo.sysobjects WHERE id = OBJECT_ID(N'[dbo].[QRTZ_PAUSED_TRIGGER_GRPS]') AND OBJECTPROPERTY(id, N'ISUSERTABLE') = 1)
-DROP TABLE [dbo].[QRTZ_PAUSED_TRIGGER_GRPS];
-
-IF EXISTS (SELECT * FROM dbo.sysobjects WHERE id = OBJECT_ID(N'[dbo].[QRTZ_SCHEDULER_STATE]') AND OBJECTPROPERTY(id, N'ISUSERTABLE') = 1)
-DROP TABLE [dbo].[QRTZ_SCHEDULER_STATE];
-
-IF EXISTS (SELECT * FROM dbo.sysobjects WHERE id = OBJECT_ID(N'[dbo].[QRTZ_LOCKS]') AND OBJECTPROPERTY(id, N'ISUSERTABLE') = 1)
-DROP TABLE [dbo].[QRTZ_LOCKS];
-
-IF EXISTS (SELECT * FROM dbo.sysobjects WHERE id = OBJECT_ID(N'[dbo].[QRTZ_JOB_DETAILS]') AND OBJECTPROPERTY(id, N'ISUSERTABLE') = 1)
-DROP TABLE [dbo].[QRTZ_JOB_DETAILS];
-
-IF EXISTS (SELECT * FROM dbo.sysobjects WHERE id = OBJECT_ID(N'[dbo].[QRTZ_SIMPLE_TRIGGERS]') AND OBJECTPROPERTY(id, N'ISUSERTABLE') = 1)
-DROP TABLE [dbo].[QRTZ_SIMPLE_TRIGGERS];
-
-IF EXISTS (SELECT * FROM dbo.sysobjects WHERE id = OBJECT_ID(N'[dbo].[QRTZ_SIMPROP_TRIGGERS]') AND OBJECTPROPERTY(id, N'ISUSERTABLE') = 1)
-DROP TABLE [dbo].[QRTZ_SIMPROP_TRIGGERS];
-
-IF EXISTS (SELECT * FROM dbo.sysobjects WHERE id = OBJECT_ID(N'[dbo].[QRTZ_TRIGGERS]') AND OBJECTPROPERTY(id, N'ISUSERTABLE') = 1)
-DROP TABLE [dbo].[QRTZ_TRIGGERS];
-
-CREATE TABLE [dbo].[QRTZ_CALENDARS] (
-  [SCHED_NAME] [VARCHAR] (120)  NOT NULL ,
-  [CALENDAR_NAME] [VARCHAR] (200)  NOT NULL ,
-  [CALENDAR] [IMAGE] NOT NULL
-) ON [PRIMARY];
-
-CREATE TABLE [dbo].[QRTZ_CRON_TRIGGERS] (
-  [SCHED_NAME] [VARCHAR] (120)  NOT NULL ,
-  [TRIGGER_NAME] [VARCHAR] (200)  NOT NULL ,
-  [TRIGGER_GROUP] [VARCHAR] (200)  NOT NULL ,
-  [CRON_EXPRESSION] [VARCHAR] (120)  NOT NULL ,
-  [TIME_ZONE_ID] [VARCHAR] (80) 
-) ON [PRIMARY];
-
-CREATE TABLE [dbo].[QRTZ_FIRED_TRIGGERS] (
-  [SCHED_NAME] [VARCHAR] (120)  NOT NULL ,
-  [ENTRY_ID] [VARCHAR] (95)  NOT NULL ,
-  [TRIGGER_NAME] [VARCHAR] (200)  NOT NULL ,
-  [TRIGGER_GROUP] [VARCHAR] (200)  NOT NULL ,
-  [INSTANCE_NAME] [VARCHAR] (200)  NOT NULL ,
-  [FIRED_TIME] [BIGINT] NOT NULL ,
-  [SCHED_TIME] [BIGINT] NOT NULL ,
-  [PRIORITY] [INTEGER] NOT NULL ,
-  [STATE] [VARCHAR] (16)  NOT NULL,
-  [JOB_NAME] [VARCHAR] (200)  NULL ,
-  [JOB_GROUP] [VARCHAR] (200)  NULL ,
-  [IS_NONCONCURRENT] [VARCHAR] (1)  NULL ,
-  [REQUESTS_RECOVERY] [VARCHAR] (1)  NULL 
-) ON [PRIMARY];
-
-CREATE TABLE [dbo].[QRTZ_PAUSED_TRIGGER_GRPS] (
-  [SCHED_NAME] [VARCHAR] (120)  NOT NULL ,
-  [TRIGGER_GROUP] [VARCHAR] (200)  NOT NULL 
-) ON [PRIMARY];
-
-CREATE TABLE [dbo].[QRTZ_SCHEDULER_STATE] (
-  [SCHED_NAME] [VARCHAR] (120)  NOT NULL ,
-  [INSTANCE_NAME] [VARCHAR] (200)  NOT NULL ,
-  [LAST_CHECKIN_TIME] [BIGINT] NOT NULL ,
-  [CHECKIN_INTERVAL] [BIGINT] NOT NULL
-) ON [PRIMARY];
-
-CREATE TABLE [dbo].[QRTZ_LOCKS] (
-  [SCHED_NAME] [VARCHAR] (120)  NOT NULL ,
-  [LOCK_NAME] [VARCHAR] (40)  NOT NULL 
-) ON [PRIMARY];
-
-CREATE TABLE [dbo].[QRTZ_JOB_DETAILS] (
-  [SCHED_NAME] [VARCHAR] (120)  NOT NULL ,
-  [JOB_NAME] [VARCHAR] (200)  NOT NULL ,
-  [JOB_GROUP] [VARCHAR] (200)  NOT NULL ,
-  [DESCRIPTION] [VARCHAR] (250) NULL ,
-  [JOB_CLASS_NAME] [VARCHAR] (250)  NOT NULL ,
-  [IS_DURABLE] [VARCHAR] (1)  NOT NULL ,
-  [IS_NONCONCURRENT] [VARCHAR] (1)  NOT NULL ,
-  [IS_UPDATE_DATA] [VARCHAR] (1)  NOT NULL ,
-  [REQUESTS_RECOVERY] [VARCHAR] (1)  NOT NULL ,
-  [JOB_DATA] [IMAGE] NULL
-) ON [PRIMARY];
-
-CREATE TABLE [dbo].[QRTZ_SIMPLE_TRIGGERS] (
-  [SCHED_NAME] [VARCHAR] (120)  NOT NULL ,
-  [TRIGGER_NAME] [VARCHAR] (200)  NOT NULL ,
-  [TRIGGER_GROUP] [VARCHAR] (200)  NOT NULL ,
-  [REPEAT_COUNT] [BIGINT] NOT NULL ,
-  [REPEAT_INTERVAL] [BIGINT] NOT NULL ,
-  [TIMES_TRIGGERED] [BIGINT] NOT NULL
-) ON [PRIMARY];
-
-CREATE TABLE [dbo].[QRTZ_SIMPROP_TRIGGERS] (
-  [SCHED_NAME] [VARCHAR] (120)  NOT NULL ,
-  [TRIGGER_NAME] [VARCHAR] (200)  NOT NULL ,
-  [TRIGGER_GROUP] [VARCHAR] (200)  NOT NULL ,
-  [STR_PROP_1] [VARCHAR] (512) NULL,
-  [STR_PROP_2] [VARCHAR] (512) NULL,
-  [STR_PROP_3] [VARCHAR] (512) NULL,
-  [INT_PROP_1] [INT] NULL,
-  [INT_PROP_2] [INT] NULL,
-  [LONG_PROP_1] [BIGINT] NULL,
-  [LONG_PROP_2] [BIGINT] NULL,
-  [DEC_PROP_1] [NUMERIC] (13,4) NULL,
-  [DEC_PROP_2] [NUMERIC] (13,4) NULL,
-  [BOOL_PROP_1] [VARCHAR] (1) NULL,
-  [BOOL_PROP_2] [VARCHAR] (1) NULL,
-) ON [PRIMARY];
-
-CREATE TABLE [dbo].[QRTZ_BLOB_TRIGGERS] (
-  [SCHED_NAME] [VARCHAR] (120)  NOT NULL ,
-  [TRIGGER_NAME] [VARCHAR] (200)  NOT NULL ,
-  [TRIGGER_GROUP] [VARCHAR] (200)  NOT NULL ,
-  [BLOB_DATA] [IMAGE] NULL
-) ON [PRIMARY];
-
-CREATE TABLE [dbo].[QRTZ_TRIGGERS] (
-  [SCHED_NAME] [VARCHAR] (120)  NOT NULL ,
-  [TRIGGER_NAME] [VARCHAR] (200)  NOT NULL ,
-  [TRIGGER_GROUP] [VARCHAR] (200)  NOT NULL ,
-  [JOB_NAME] [VARCHAR] (200)  NOT NULL ,
-  [JOB_GROUP] [VARCHAR] (200)  NOT NULL ,
-  [DESCRIPTION] [VARCHAR] (250) NULL ,
-  [NEXT_FIRE_TIME] [BIGINT] NULL ,
-  [PREV_FIRE_TIME] [BIGINT] NULL ,
-  [PRIORITY] [INTEGER] NULL ,
-  [TRIGGER_STATE] [VARCHAR] (16)  NOT NULL ,
-  [TRIGGER_TYPE] [VARCHAR] (8)  NOT NULL ,
-  [START_TIME] [BIGINT] NOT NULL ,
-  [END_TIME] [BIGINT] NULL ,
-  [CALENDAR_NAME] [VARCHAR] (200)  NULL ,
-  [MISFIRE_INSTR] [SMALLINT] NULL ,
-  [JOB_DATA] [IMAGE] NULL
-) ON [PRIMARY];
-
-ALTER TABLE [dbo].[QRTZ_CALENDARS] WITH NOCHECK ADD
-  CONSTRAINT [PK_QRTZ_CALENDARS] PRIMARY KEY  CLUSTERED
-  (
-    [SCHED_NAME],
-    [CALENDAR_NAME]
-  )  ON [PRIMARY];
-
-ALTER TABLE [dbo].[QRTZ_CRON_TRIGGERS] WITH NOCHECK ADD
-  CONSTRAINT [PK_QRTZ_CRON_TRIGGERS] PRIMARY KEY  CLUSTERED
-  (
-    [SCHED_NAME],
-    [TRIGGER_NAME],
-    [TRIGGER_GROUP]
-  )  ON [PRIMARY];
-
-ALTER TABLE [dbo].[QRTZ_FIRED_TRIGGERS] WITH NOCHECK ADD
-  CONSTRAINT [PK_QRTZ_FIRED_TRIGGERS] PRIMARY KEY  CLUSTERED
-  (
-    [SCHED_NAME],
-    [ENTRY_ID]
-  )  ON [PRIMARY];
-
-ALTER TABLE [dbo].[QRTZ_PAUSED_TRIGGER_GRPS] WITH NOCHECK ADD
-  CONSTRAINT [PK_QRTZ_PAUSED_TRIGGER_GRPS] PRIMARY KEY  CLUSTERED
-  (
-    [SCHED_NAME],
-    [TRIGGER_GROUP]
-  )  ON [PRIMARY];
-
-ALTER TABLE [dbo].[QRTZ_SCHEDULER_STATE] WITH NOCHECK ADD
-  CONSTRAINT [PK_QRTZ_SCHEDULER_STATE] PRIMARY KEY  CLUSTERED
-  (
-    [SCHED_NAME],
-    [INSTANCE_NAME]
-  )  ON [PRIMARY];
-
-ALTER TABLE [dbo].[QRTZ_LOCKS] WITH NOCHECK ADD
-  CONSTRAINT [PK_QRTZ_LOCKS] PRIMARY KEY  CLUSTERED
-  (
-    [SCHED_NAME],
-    [LOCK_NAME]
-  )  ON [PRIMARY];
-
-ALTER TABLE [dbo].[QRTZ_JOB_DETAILS] WITH NOCHECK ADD
-  CONSTRAINT [PK_QRTZ_JOB_DETAILS] PRIMARY KEY  CLUSTERED
-  (
-    [SCHED_NAME],
-    [JOB_NAME],
-    [JOB_GROUP]
-  )  ON [PRIMARY];
-
-ALTER TABLE [dbo].[QRTZ_SIMPLE_TRIGGERS] WITH NOCHECK ADD
-  CONSTRAINT [PK_QRTZ_SIMPLE_TRIGGERS] PRIMARY KEY  CLUSTERED
-  (
-    [SCHED_NAME],
-    [TRIGGER_NAME],
-    [TRIGGER_GROUP]
-  )  ON [PRIMARY];
-
-ALTER TABLE [dbo].[QRTZ_SIMPROP_TRIGGERS] WITH NOCHECK ADD
-  CONSTRAINT [PK_QRTZ_SIMPROP_TRIGGERS] PRIMARY KEY  CLUSTERED
-  (
-    [SCHED_NAME],
-    [TRIGGER_NAME],
-    [TRIGGER_GROUP]
-  )  ON [PRIMARY];
-
-ALTER TABLE [dbo].[QRTZ_TRIGGERS] WITH NOCHECK ADD
-  CONSTRAINT [PK_QRTZ_TRIGGERS] PRIMARY KEY  CLUSTERED
-  (
-    [SCHED_NAME],
-    [TRIGGER_NAME],
-    [TRIGGER_GROUP]
-  )  ON [PRIMARY];
-
-ALTER TABLE [dbo].[QRTZ_CRON_TRIGGERS] ADD
-  CONSTRAINT [FK_QRTZ_CRON_TRIGGERS_QRTZ_TRIGGERS] FOREIGN KEY
-  (
-    [SCHED_NAME],
-    [TRIGGER_NAME],
-    [TRIGGER_GROUP]
-  ) REFERENCES [dbo].[QRTZ_TRIGGERS] (
-    [SCHED_NAME],
-    [TRIGGER_NAME],
-    [TRIGGER_GROUP]
-  ) ON DELETE CASCADE;
-
-ALTER TABLE [dbo].[QRTZ_SIMPLE_TRIGGERS] ADD
-  CONSTRAINT [FK_QRTZ_SIMPLE_TRIGGERS_QRTZ_TRIGGERS] FOREIGN KEY
-  (
-    [SCHED_NAME],
-    [TRIGGER_NAME],
-    [TRIGGER_GROUP]
-  ) REFERENCES [dbo].[QRTZ_TRIGGERS] (
-    [SCHED_NAME],
-    [TRIGGER_NAME],
-    [TRIGGER_GROUP]
-  ) ON DELETE CASCADE;
-
-ALTER TABLE [dbo].[QRTZ_SIMPROP_TRIGGERS] ADD
-  CONSTRAINT [FK_QRTZ_SIMPROP_TRIGGERS_QRTZ_TRIGGERS] FOREIGN KEY
-  (
-    [SCHED_NAME],
-    [TRIGGER_NAME],
-    [TRIGGER_GROUP]
-  ) REFERENCES [dbo].[QRTZ_TRIGGERS] (
-    [SCHED_NAME],
-    [TRIGGER_NAME],
-    [TRIGGER_GROUP]
-  ) ON DELETE CASCADE;
-
-ALTER TABLE [dbo].[QRTZ_TRIGGERS] ADD
-  CONSTRAINT [FK_QRTZ_TRIGGERS_QRTZ_JOB_DETAILS] FOREIGN KEY
-  (
-    [SCHED_NAME],
-    [JOB_NAME],
-    [JOB_GROUP]
-  ) REFERENCES [dbo].[QRTZ_JOB_DETAILS] (
-    [SCHED_NAME],
-    [JOB_NAME],
-    [JOB_GROUP]
-  );

http://git-wip-us.apache.org/repos/asf/syncope/blob/6dfedd8f/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/AbstractTest.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/AbstractTest.java b/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/AbstractTest.java
index a3b6701..201708f 100644
--- a/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/AbstractTest.java
+++ b/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/AbstractTest.java
@@ -18,15 +18,21 @@
  */
 package org.apache.syncope.core.persistence.jpa;
 
+import javax.persistence.EntityManager;
+import org.apache.syncope.core.misc.security.AuthContextUtils;
+import org.apache.syncope.core.misc.spring.ApplicationContextProvider;
 import org.apache.syncope.core.persistence.api.entity.AnyUtilsFactory;
 import org.apache.syncope.core.persistence.api.entity.EntityFactory;
 import org.junit.runner.RunWith;
 import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.orm.jpa.EntityManagerFactoryUtils;
 import org.springframework.test.context.ContextConfiguration;
 import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
+import org.springframework.test.context.transaction.TransactionConfiguration;
 
 @RunWith(SpringJUnit4ClassRunner.class)
 @ContextConfiguration(locations = { "classpath:persistenceTest.xml" })
+@TransactionConfiguration(transactionManager = "MasterTransactionManager")
 public abstract class AbstractTest {
 
     @Autowired
@@ -35,4 +41,14 @@ public abstract class AbstractTest {
     @Autowired
     protected AnyUtilsFactory anyUtilsFactory;
 
+    protected EntityManager entityManager() {
+        EntityManager entityManager = EntityManagerFactoryUtils.getTransactionalEntityManager(
+                EntityManagerFactoryUtils.findEntityManagerFactory(
+                        ApplicationContextProvider.getBeanFactory(), AuthContextUtils.getDomain()));
+        if (entityManager == null) {
+            throw new IllegalStateException("Could not find EntityManager for domain " + AuthContextUtils.getDomain());
+        }
+
+        return entityManager;
+    }
 }


[31/31] syncope git commit: Merge from master

Posted by md...@apache.org.
Merge from master


Project: http://git-wip-us.apache.org/repos/asf/syncope/repo
Commit: http://git-wip-us.apache.org/repos/asf/syncope/commit/f0883ca5
Tree: http://git-wip-us.apache.org/repos/asf/syncope/tree/f0883ca5
Diff: http://git-wip-us.apache.org/repos/asf/syncope/diff/f0883ca5

Branch: refs/heads/SYNCOPE-156
Commit: f0883ca5f10e5b282f91da98916b9b3486c15a27
Parents: d011626
Author: Marco Di Sabatino Di Diodoro <md...@apache.org>
Authored: Fri Aug 14 10:30:08 2015 +0200
Committer: Marco Di Sabatino Di Diodoro <md...@apache.org>
Committed: Fri Aug 14 10:30:08 2015 +0200

----------------------------------------------------------------------
 .../apache/syncope/client/console/pages/StatusModalPage.java | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/syncope/blob/f0883ca5/client/console/src/main/java/org/apache/syncope/client/console/pages/StatusModalPage.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/pages/StatusModalPage.java b/client/console/src/main/java/org/apache/syncope/client/console/pages/StatusModalPage.java
index c97e44c..57e5a0c 100644
--- a/client/console/src/main/java/org/apache/syncope/client/console/pages/StatusModalPage.java
+++ b/client/console/src/main/java/org/apache/syncope/client/console/pages/StatusModalPage.java
@@ -39,7 +39,7 @@ import org.apache.syncope.common.lib.to.BulkActionResult;
 import org.apache.syncope.common.lib.to.ResourceTO;
 import org.apache.syncope.common.lib.to.GroupTO;
 import org.apache.syncope.common.lib.to.UserTO;
-import org.apache.syncope.common.lib.types.ResourceAssociationActionType;
+import org.apache.syncope.common.lib.types.ResourceAssociationAction;
 import org.apache.wicket.PageReference;
 import org.apache.wicket.ajax.AjaxRequestTarget;
 import org.apache.wicket.ajax.form.AjaxFormComponentUpdatingBehavior;
@@ -401,7 +401,7 @@ public class StatusModalPage<T extends AnyTO> extends AbstractStatusModalPage {
 
                     if (anyTO instanceof UserTO) {
                         StatusModalPage.this.passwordManagement(
-                                target, ResourceAssociationActionType.PROVISION, table.getModelObject());
+                                target, ResourceAssociationAction.PROVISION, table.getModelObject());
                     } else {
                         try {
                             final BulkActionResult bulkActionResult = groupRestClient.provision(
@@ -458,7 +458,7 @@ public class StatusModalPage<T extends AnyTO> extends AbstractStatusModalPage {
                 public void onClick(final AjaxRequestTarget target, final Serializable ignore) {
                     if (anyTO instanceof UserTO) {
                         StatusModalPage.this.passwordManagement(
-                                target, ResourceAssociationActionType.ASSIGN, table.getModelObject());
+                                target, ResourceAssociationAction.ASSIGN, table.getModelObject());
                     } else {
                         try {
                             final BulkActionResult bulkActionResult = groupRestClient.assign(
@@ -546,7 +546,7 @@ public class StatusModalPage<T extends AnyTO> extends AbstractStatusModalPage {
 
     private void passwordManagement(
             final AjaxRequestTarget target,
-            final ResourceAssociationActionType type,
+            final ResourceAssociationAction type,
             final Collection<StatusBean> selection) {
 
         final ClearIndicatingAjaxButton goon =


[29/31] syncope git commit: Fixing build with Oracle JDK 8

Posted by md...@apache.org.
Fixing build with Oracle JDK 8


Project: http://git-wip-us.apache.org/repos/asf/syncope/repo
Commit: http://git-wip-us.apache.org/repos/asf/syncope/commit/4b2dc4d8
Tree: http://git-wip-us.apache.org/repos/asf/syncope/tree/4b2dc4d8
Diff: http://git-wip-us.apache.org/repos/asf/syncope/diff/4b2dc4d8

Branch: refs/heads/SYNCOPE-156
Commit: 4b2dc4d896b894bcd5728740a52601e40e8f17b3
Parents: ce015d1
Author: Francesco Chicchiriccò <il...@apache.org>
Authored: Fri Aug 14 09:57:21 2015 +0200
Committer: Francesco Chicchiriccò <il...@apache.org>
Committed: Fri Aug 14 09:57:21 2015 +0200

----------------------------------------------------------------------
 .../org/apache/syncope/common/rest/api/service/ReportService.java | 2 +-
 .../org/apache/syncope/common/rest/api/service/TaskService.java   | 2 +-
 .../org/apache/syncope/common/rest/api/service/UserService.java   | 3 +--
 3 files changed, 3 insertions(+), 4 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/syncope/blob/4b2dc4d8/common/rest-api/src/main/java/org/apache/syncope/common/rest/api/service/ReportService.java
----------------------------------------------------------------------
diff --git a/common/rest-api/src/main/java/org/apache/syncope/common/rest/api/service/ReportService.java b/common/rest-api/src/main/java/org/apache/syncope/common/rest/api/service/ReportService.java
index b5ce7ec..17c091d 100644
--- a/common/rest-api/src/main/java/org/apache/syncope/common/rest/api/service/ReportService.java
+++ b/common/rest-api/src/main/java/org/apache/syncope/common/rest/api/service/ReportService.java
@@ -173,7 +173,7 @@ public interface ReportService extends JAXRSService {
      * Executes an action on an existing report's job.
      *
      * @param key report key
-     * @param action
+     * @param action action to execute
      */
     @POST
     @Path("{key}")

http://git-wip-us.apache.org/repos/asf/syncope/blob/4b2dc4d8/common/rest-api/src/main/java/org/apache/syncope/common/rest/api/service/TaskService.java
----------------------------------------------------------------------
diff --git a/common/rest-api/src/main/java/org/apache/syncope/common/rest/api/service/TaskService.java b/common/rest-api/src/main/java/org/apache/syncope/common/rest/api/service/TaskService.java
index 5e39b2a..31b76f4 100644
--- a/common/rest-api/src/main/java/org/apache/syncope/common/rest/api/service/TaskService.java
+++ b/common/rest-api/src/main/java/org/apache/syncope/common/rest/api/service/TaskService.java
@@ -185,7 +185,7 @@ public interface TaskService extends JAXRSService {
      * Executes an action on an existing task's job.
      *
      * @param key task key
-     * @param action
+     * @param action action to execute
      */
     @POST
     @Path("{key}")

http://git-wip-us.apache.org/repos/asf/syncope/blob/4b2dc4d8/common/rest-api/src/main/java/org/apache/syncope/common/rest/api/service/UserService.java
----------------------------------------------------------------------
diff --git a/common/rest-api/src/main/java/org/apache/syncope/common/rest/api/service/UserService.java b/common/rest-api/src/main/java/org/apache/syncope/common/rest/api/service/UserService.java
index 6dbb56c..418e233 100644
--- a/common/rest-api/src/main/java/org/apache/syncope/common/rest/api/service/UserService.java
+++ b/common/rest-api/src/main/java/org/apache/syncope/common/rest/api/service/UserService.java
@@ -91,9 +91,8 @@ public interface UserService extends AnyService<UserTO, UserMod> {
             @DefaultValue("true") @QueryParam("storePassword") boolean storePassword);
 
     /**
-     * Performs a status update on user matching provided key.
+     * Performs a status update on given.
      *
-     * @param key id of user to be subjected to status update
      * @param statusMod status update details
      * @return <tt>Response</tt> object featuring the updated user enriched with propagation status information
      * - {@link UserTO} as <tt>Entity</tt>


[13/31] syncope git commit: [SYNCOPE-652] Still several things to refine, but it starts taking shape

Posted by md...@apache.org.
http://git-wip-us.apache.org/repos/asf/syncope/blob/6dfedd8f/core/persistence-jpa/src/test/resources/domains/MasterContent.xml
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/test/resources/domains/MasterContent.xml b/core/persistence-jpa/src/test/resources/domains/MasterContent.xml
new file mode 100644
index 0000000..2542a1a
--- /dev/null
+++ b/core/persistence-jpa/src/test/resources/domains/MasterContent.xml
@@ -0,0 +1,1131 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+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.
+-->
+<dataset>
+  <SyncopeDomain name="Two" adminCipherAlgorithm="SHA" adminPwd="2AA60A8FF7FCD473D321E0146AFD9E26DF395147"/>  
+  
+  <SyncopeConf id="1" 
+               creator="admin" lastModifier="admin"
+               creationDate="2014-06-20 11:00:00" lastChangeDate="2014-06-20 11:00:00"/>
+
+  <PlainSchema name="password.cipher.algorithm" type="String"
+               mandatoryCondition="true" multivalue="0" uniqueConstraint="0" readonly="0"/>
+  <CPlainAttr id="1" owner_id="1" schema_name="password.cipher.algorithm"/>
+  <CPlainAttrValue id="1" attribute_id="1" stringValue="SHA1"/>
+
+  <!-- notificationjob.cronExpression:
+  + not existing: NotificationJob runs according to Notification.DEFAULT_CRON_EXP
+  + provided as empty string: NotificationJob disabled
+  + provided as non-empty string: NotificationJob runs according to the given value -->
+  <PlainSchema name="notificationjob.cronExpression" type="String"
+               mandatoryCondition="false" multivalue="0" uniqueConstraint="0" readonly="0"/>
+  <CPlainAttr id="2" owner_id="1" schema_name="notificationjob.cronExpression"/>
+  <CPlainAttrValue id="2" attribute_id="2" stringValue=""/>
+  
+  <PlainSchema name="notification.maxRetries" type="Long"
+               mandatoryCondition="true" multivalue="0" uniqueConstraint="0" readonly="0"/>
+  <CPlainAttr id="3" owner_id="1" schema_name="notification.maxRetries"/>
+  <CPlainAttrValue id="3" attribute_id="3" longValue="3"/>
+
+  <PlainSchema name="token.length" type="Long"
+               mandatoryCondition="true" multivalue="0" uniqueConstraint="0" readonly="0"/>
+  <CPlainAttr id="4" owner_id="1" schema_name="token.length"/>
+  <CPlainAttrValue id="4" attribute_id="4" longValue="256"/>
+
+  <PlainSchema name="token.expireTime" type="Long"
+               mandatoryCondition="true" multivalue="0" uniqueConstraint="0" readonly="0"/>
+  <CPlainAttr id="5" owner_id="1" schema_name="token.expireTime"/>
+  <CPlainAttrValue id="5" attribute_id="5" longValue="60"/>
+
+  <PlainSchema name="selfRegistration.allowed" type="Boolean"
+               mandatoryCondition="true" multivalue="0" uniqueConstraint="0" readonly="0"/>
+  <CPlainAttr id="6" owner_id="1" schema_name="selfRegistration.allowed"/>
+  <CPlainAttrValue id="6" attribute_id="6" booleanValue="1"/>
+
+  <PlainSchema name="passwordReset.allowed" type="Boolean"
+               mandatoryCondition="true" multivalue="0" uniqueConstraint="0" readonly="0"/>
+  <CPlainAttr id="7" owner_id="1" schema_name="passwordReset.allowed"/>
+  <CPlainAttrValue id="7" attribute_id="7" booleanValue="1"/>
+
+  <PlainSchema name="passwordReset.securityQuestion" type="Boolean"
+               mandatoryCondition="true" multivalue="0" uniqueConstraint="0" readonly="0"/>
+  <CPlainAttr id="8" owner_id="1" schema_name="passwordReset.securityQuestion"/>
+  <CPlainAttrValue id="8" attribute_id="8" booleanValue="1"/>
+
+  <PlainSchema name="authentication.statuses" type="String"
+               mandatoryCondition="true" multivalue="1" uniqueConstraint="0" readonly="0"/>
+  <CPlainAttr id="9" owner_id="1" schema_name="authentication.statuses"/>
+  <CPlainAttrValue id="9" attribute_id="9" stringValue="created"/>
+  <CPlainAttrValue id="10" attribute_id="9" stringValue="active"/>
+
+  <!-- Save user login date upon successful authentication -->
+  <PlainSchema name="log.lastlogindate" type="Boolean"
+               mandatoryCondition="true" multivalue="0" uniqueConstraint="0" readonly="0"/>
+  <CPlainAttr id="11" owner_id="1" schema_name="log.lastlogindate"/>
+  <CPlainAttrValue id="11" attribute_id="11" booleanValue="1"/>
+
+  <PlainSchema name="tasks.interruptMaxRetries" type="Long"
+               mandatoryCondition="true" multivalue="0" uniqueConstraint="0" readonly="0"/>
+  <CPlainAttr id="12" owner_id="1" schema_name="tasks.interruptMaxRetries"/>
+  <CPlainAttrValue id="12" attribute_id="12" longValue="20"/>
+
+  <!-- For usage with admin console -->
+  <PlainSchema name="admin.user.layout" type="String"
+               mandatoryCondition="false" multivalue="1" uniqueConstraint="0" readonly="0"/>
+  <PlainSchema name="self.user.layout" type="String"
+               mandatoryCondition="false" multivalue="1" uniqueConstraint="0" readonly="0"/>
+  <PlainSchema name="admin.group.layout" type="String"
+               mandatoryCondition="false" multivalue="1" uniqueConstraint="0" readonly="0"/>
+  <PlainSchema name="self.group.layout" type="String"
+               mandatoryCondition="false" multivalue="1" uniqueConstraint="0" readonly="0"/>
+  <PlainSchema name="admin.membership.layout" type="String"
+               mandatoryCondition="false" multivalue="1" uniqueConstraint="0" readonly="0"/>
+  <PlainSchema name="self.membership.layout" type="String"
+               mandatoryCondition="false" multivalue="1" uniqueConstraint="0" readonly="0"/>
+  
+  <!-- sample policies -->
+  <Policy DTYPE="SyncPolicy" id="1" description="a sync policy" type="SYNC" 
+          specification='{"conflictResolutionAction":"IGNORE","items":[]}'/>
+  <Policy DTYPE="PasswordPolicy" id="2" description="a password policy" type="PASSWORD" 
+          specification='{"historyLength":1,"maxLength":0,"minLength":8,"nonAlphanumericRequired":false,"alphanumericRequired":false,"digitRequired":false,"lowercaseRequired":false,"uppercaseRequired":false,"mustStartWithDigit":false,"mustntStartWithDigit":false,"mustEndWithDigit":false,"mustntEndWithDigit":false,"mustStartWithNonAlpha":false,"mustStartWithAlpha":false,"mustntStartWithNonAlpha":false,"mustntStartWithAlpha":false,"mustEndWithNonAlpha":false,"mustEndWithAlpha":false,"mustntEndWithNonAlpha":false,"mustntEndWithAlpha":false,"wordsNotPermitted":[],"schemasNotPermitted":[],"prefixesNotPermitted":["notpermitted1","notpermitted2"],"suffixesNotPermitted":[],"allowNullPassword":true}'/>
+  <Policy DTYPE="SyncPolicy" id="3" description="sync policy 2" type="SYNC" 
+          specification='{"conflictResolutionAction":"ALL","items":[{"anyTypeKey":"USER","javaRule":null,"altSearchSchemas":["username","firstname"]}]}'/>
+  <Policy DTYPE="PasswordPolicy" id="4" description="sample password policy" type="PASSWORD" 
+          specification='{"historyLength":0,"maxLength":0,"minLength":10,"nonAlphanumericRequired":false,"alphanumericRequired":false,"digitRequired":true,"lowercaseRequired":false,"uppercaseRequired":false,"mustStartWithDigit":false,"mustntStartWithDigit":false,"mustEndWithDigit":false,"mustntEndWithDigit":false,"mustStartWithNonAlpha":false,"mustStartWithAlpha":false,"mustntStartWithNonAlpha":false,"mustntStartWithAlpha":false,"mustEndWithNonAlpha":false,"mustEndWithAlpha":false,"mustntEndWithNonAlpha":false,"mustntEndWithAlpha":false,"wordsNotPermitted":[],"schemasNotPermitted":[],"prefixesNotPermitted":["notpermitted1","notpermitted2"],"suffixesNotPermitted":[], "allowNullPassword":true}'/>
+  <Policy DTYPE="AccountPolicy" id="5" description="an account policy" type="ACCOUNT" 
+          specification='{"maxLength":0,"minLength":0,"pattern":null,"allUpperCase":false,"allLowerCase":false,"propagateSuspension":false,"maxAuthenticationAttempts":0,"wordsNotPermitted":[],"schemasNotPermitted":[],"prefixesNotPermitted":[],"suffixesNotPermitted":[]}'/>
+  <Policy DTYPE="AccountPolicy" id="6" description="sample account policy" type="ACCOUNT" 
+          specification='{"maxLength":0,"minLength":4,"pattern":null,"allUpperCase":false,"allLowerCase":false,"propagateSuspension":false,"maxAuthenticationAttempts":3,"wordsNotPermitted":[],"schemasNotPermitted":[],"prefixesNotPermitted":["notpermitted1","notpermitted2"],"suffixesNotPermitted":[]}'/>
+  <Policy DTYPE="SyncPolicy" id="7" description="sync policy 1" type="SYNC" 
+          specification='{"conflictResolutionAction":"IGNORE","items":[]}'/>
+  <Policy DTYPE="PasswordPolicy" id="8" description="sample password policy" type="PASSWORD" 
+          specification='{"historyLength":0,"maxLength":0,"minLength":10,"nonAlphanumericRequired":true,"alphanumericRequired":false,"digitRequired":true,"lowercaseRequired":true,"uppercaseRequired":true,"mustStartWithDigit":true,"mustntStartWithDigit":false,"mustEndWithDigit":true,"mustntEndWithDigit":false,"mustStartWithNonAlpha":false,"mustStartWithAlpha":false,"mustntStartWithNonAlpha":false,"mustntStartWithAlpha":false,"mustEndWithNonAlpha":false,"mustEndWithAlpha":false,"mustntEndWithNonAlpha":false,"mustntEndWithAlpha":false,"wordsNotPermitted":[],"schemasNotPermitted":[],"prefixesNotPermitted":["notpermitted1","notpermitted2"],"suffixesNotPermitted":[],"allowNullPassword":false}'/>
+  <Policy DTYPE="SyncPolicy" id="9" description="sync policy for java rule" type="SYNC" 
+          specification='{"conflictResolutionAction":"IGNORE","items":[]}'/>
+
+  <RelationshipType name="inclusion" description="Models the act that an object is included in another"/>
+  <RelationshipType name="neighborhood"/>
+  
+  <AnyTypeClass name="generic membership"/>
+
+  <AnyType name="USER" kind="USER"/>
+  <AnyTypeClass name="minimal user"/>
+  <AnyType_AnyTypeClass anyType_name="USER" anyTypeClass_name="minimal user"/>
+  <AnyTypeClass name="other"/>
+  <AnyType_AnyTypeClass anyType_name="USER" anyTypeClass_name="other"/>
+
+  <AnyType name="GROUP" kind="GROUP"/>
+  <AnyTypeClass name="minimal group"/>
+  <AnyType_AnyTypeClass anyType_name="GROUP" anyTypeClass_name="minimal group"/>
+  
+  <AnyType name="PRINTER" kind="ANY_OBJECT"/>
+  <AnyTypeClass name="minimal printer"/>
+  <AnyType_AnyTypeClass anyType_name="PRINTER" anyTypeClass_name="minimal printer"/>
+      
+  <AnyTypeClass name="csv"/>
+
+  <Realm id="1" name="/" passwordPolicy_id="4"/>
+  <Realm id="2" name="odd" parent_id="1" accountPolicy_id="6"/>
+  <Realm id="3" name="even" parent_id="1"/>
+  <Realm id="4" name="two" parent_id="3" accountPolicy_id="5" passwordPolicy_id="2"/>
+  
+  <AnyObject id="1" realm_id="1" type_name="PRINTER"
+             creator="admin" lastModifier="admin" 
+             creationDate="2010-10-20 11:00:00" lastChangeDate="2010-10-20 11:00:00"/>
+  <AnyObject id="2" realm_id="1" type_name="PRINTER"
+             creator="admin" lastModifier="admin" 
+             creationDate="2010-10-20 11:00:00" lastChangeDate="2010-10-20 11:00:00"/>
+  
+  <ARelationship id="1" left_anyObject_id="1" right_anyObject_id="2" type_name="neighborhood"/>
+  
+  <SyncopeRole id="1" name="User reviewer"/>
+  <SyncopeRole_entitlements entitlement="USER_READ" role_id="1"/>
+  <SyncopeRole_entitlements entitlement="USER_LIST" role_id="1"/>
+  <SyncopeRole_entitlements entitlement="USER_SEARCH" role_id="1"/>
+  <SyncopeRole_Realm role_id="1" realm_id="2"/>
+  <SyncopeRole_Realm role_id="1" realm_id="3"/>
+  
+  <SyncopeRole id="2" name="User manager"/>
+  <SyncopeRole_entitlements entitlement="USER_READ" role_id="2"/>
+  <SyncopeRole_entitlements entitlement="USER_LIST" role_id="2"/>
+  <SyncopeRole_entitlements entitlement="USER_SEARCH" role_id="2"/>
+  <SyncopeRole_entitlements entitlement="WORKFLOW_FORM_CLAIM" role_id="2"/>
+  <SyncopeRole_entitlements entitlement="WORKFLOW_FORM_SUBMIT" role_id="2"/>
+  <SyncopeRole_Realm role_id="2" realm_id="1"/>
+
+  <SyncopeRole id="3" name="Other"/>
+  <SyncopeRole_entitlements entitlement="SCHEMA_READ" role_id="3"/>
+  <SyncopeRole_entitlements entitlement="GROUP_READ" role_id="3"/>
+  <SyncopeRole_entitlements entitlement="WORKFLOW_FORM_CLAIM" role_id="3"/>
+  <SyncopeRole_Realm role_id="3" realm_id="2"/>
+  
+  <SyncopeRole id="4" name="Search for /even/two"/>
+  <SyncopeRole_entitlements entitlement="USER_READ" role_id="4"/>
+  <SyncopeRole_entitlements entitlement="USER_SEARCH" role_id="4"/>
+  <SyncopeRole_Realm role_id="4" realm_id="4"/>
+
+  <SyncopeUser id="1" workflowId="4" status="active" password="5baa61e4c9b93f3f0682250b6cf8331b7ee68fd8" cipherAlgorithm="SHA1"
+               realm_id="3"
+               username="rossini" creator="admin" lastModifier="admin"
+               creationDate="2010-10-20 11:00:00" lastChangeDate="2010-10-20 11:00:00" suspended="0"/>
+  <SyncopeUser_SyncopeRole user_id="1" role_id="3"/>
+  <SyncopeUser id="2" workflowId="6" status="active" password="5baa61e4c9b93f3f0682250b6cf8331b7ee68fd8" cipherAlgorithm="SHA1"
+               realm_id="1"
+               username="verdi" creator="admin" lastModifier="admin"
+               creationDate="2010-10-20 11:00:00" lastChangeDate="2010-10-20 11:00:00" suspended="0"/>
+  <SyncopeUser id="3" workflowId="8" status="active" password="5baa61e4c9b93f3f0682250b6cf8331b7ee68fd8" cipherAlgorithm="SHA1"
+               realm_id="1"
+               username="vivaldi" creator="admin" lastModifier="admin"
+               creationDate="2010-10-20 11:00:00" lastChangeDate="2010-10-20 11:00:00" suspended="0"/>
+  <SyncopeUser id="4" workflowId="10" status="active" password="5baa61e4c9b93f3f0682250b6cf8331b7ee68fd8" cipherAlgorithm="SHA1"
+               realm_id="1"
+               username="bellini" creator="admin" lastModifier="admin"
+               creationDate="2010-10-20 11:00:00" lastChangeDate="2010-10-20 11:00:00" suspended="0"/>
+  <SyncopeUser_SyncopeRole user_id="4" role_id="1"/>
+  <SyncopeUser_SyncopeRole user_id="4" role_id="2"/>
+  <SyncopeUser id="5" workflowId="12" status="active" password="5baa61e4c9b93f3f0682250b6cf8331b7ee68fd8" cipherAlgorithm="SHA1"
+               realm_id="1"
+               username="puccini" creator="admin" lastModifier="admin" 
+               creationDate="2010-10-20 11:00:00" lastChangeDate="2010-10-20 11:00:00" suspended="0"/>
+  <SyncopeUser_SyncopeRole user_id="5" role_id="4"/>
+  
+  <SyncopeGroup id="1" name="root"
+                realm_id="1"
+                creator="admin" lastModifier="admin" 
+                creationDate="2010-10-20 11:00:00" lastChangeDate="2010-10-20 11:00:00"/>
+  <SyncopeGroup id="2" name="child"
+                realm_id="1"
+                creator="admin" lastModifier="admin" 
+                creationDate="2010-10-20 11:00:00" lastChangeDate="2010-10-20 11:00:00"/>
+  <SyncopeGroup id="3" name="citizen"
+                realm_id="1"
+                creator="admin" lastModifier="admin" 
+                creationDate="2010-10-20 11:00:00" lastChangeDate="2010-10-20 11:00:00"/>
+  <SyncopeGroup id="4" name="employee"
+                realm_id="1"
+                creator="admin" lastModifier="admin" 
+                creationDate="2010-10-20 11:00:00" lastChangeDate="2010-10-20 11:00:00"/>
+  <SyncopeGroup id="5" name="secretary"
+                realm_id="1"
+                creator="admin" lastModifier="admin" 
+                creationDate="2010-10-20 11:00:00" lastChangeDate="2010-10-20 11:00:00"/>
+  <SyncopeGroup id="6" name="director" userOwner_id="5"
+                realm_id="1"
+                creator="admin" lastModifier="admin" 
+                creationDate="2010-10-20 11:00:00" lastChangeDate="2010-10-20 11:00:00"/>
+  <SyncopeGroup id="7" name="managingDirector"
+                realm_id="1"
+                creator="admin" lastModifier="admin" 
+                creationDate="2010-10-20 11:00:00" lastChangeDate="2010-10-20 11:00:00"/>
+  <SyncopeGroup id="8" name="otherchild"
+                realm_id="1"
+                creator="admin" lastModifier="admin" 
+                creationDate="2010-10-20 11:00:00" lastChangeDate="2010-10-20 11:00:00"/>
+  <SyncopeGroup id="9" name="groupForWorkflowApproval"
+                realm_id="1"
+                creator="admin" lastModifier="admin" 
+                creationDate="2010-10-20 11:00:00" lastChangeDate="2010-10-20 11:00:00"/>
+  <SyncopeGroup id="10" name="managingConsultant"
+                realm_id="1"
+                creator="admin" lastModifier="admin" 
+                creationDate="2010-10-20 11:00:00" lastChangeDate="2010-10-20 11:00:00"/>
+  <SyncopeGroup id="11" name="groupForWorkflowOptIn"
+                realm_id="1"
+                creator="admin" lastModifier="admin" 
+                creationDate="2010-10-20 11:00:00" lastChangeDate="2010-10-20 11:00:00"/>
+  <SyncopeGroup id="12" name="aGroupForPropagation"
+                realm_id="1"
+                creator="admin" lastModifier="admin" 
+                creationDate="2010-10-20 11:00:00" lastChangeDate="2010-10-20 11:00:00"/>
+  <SyncopeGroup_AnyTypeClass group_id="12" anyTypeClass_name="csv"/>  
+  <SyncopeGroup id="13" name="bGroupForPropagation"
+                realm_id="1"
+                creator="admin" lastModifier="admin" 
+                creationDate="2010-10-20 11:00:00" lastChangeDate="2010-10-20 11:00:00"/>
+  <SyncopeGroup_AnyTypeClass group_id="13" anyTypeClass_name="csv"/>  
+  <SyncopeGroup id="14" name="artDirector"
+                realm_id="1"
+                creator="admin" lastModifier="admin" 
+                creationDate="2010-10-20 11:00:00" lastChangeDate="2010-10-20 11:00:00"/>
+  
+  <URelationship id="1" user_id="4" anyObject_id="1" type_name="neighborhood"/>
+
+  <UMembership id="1" user_id="1" group_id="1"/>
+  <UMembership id="2" user_id="2" group_id="1"/>
+  <UMembership id="3" user_id="2" group_id="2"/>
+  <UMembership id="4" user_id="4" group_id="7"/>
+  <UMembership id="5" user_id="1" group_id="8"/>
+  <UMembership id="6" user_id="2" group_id="3"/>
+  <UMembership id="7" user_id="5" group_id="14"/>
+
+  <PlainSchema name="fullname" type="String" anyTypeClass_name="minimal user"
+               mandatoryCondition="true" multivalue="0" uniqueConstraint="1" readonly="0"/>
+  <PlainSchema name="userId" type="String" anyTypeClass_name="minimal user"
+               mandatoryCondition="true" multivalue="0" uniqueConstraint="1" readonly="0"
+               validatorClass="org.apache.syncope.core.persistence.jpa.attrvalue.validation.EmailAddressValidator"/>
+  <PlainSchema name="loginDate" type="Date" anyTypeClass_name="other"
+               mandatoryCondition="false" multivalue="1" uniqueConstraint="0" readonly="0"
+               conversionPattern="yyyy-MM-dd"/>
+  <PlainSchema name="firstname" type="String" anyTypeClass_name="minimal user"
+               mandatoryCondition="false" multivalue="0" uniqueConstraint="0" readonly="0"/>
+  <PlainSchema name="surname" type="String" anyTypeClass_name="minimal user"
+               mandatoryCondition="true" multivalue="0" uniqueConstraint="0" readonly="0"/>
+  <PlainSchema name="type" type="String" anyTypeClass_name="other"
+               mandatoryCondition="false" multivalue="0" uniqueConstraint="0" readonly="0"/>
+  <PlainSchema name="email" type="String" anyTypeClass_name="minimal user"
+               mandatoryCondition="false" multivalue="0" uniqueConstraint="0" readonly="0"
+               validatorClass="org.apache.syncope.core.persistence.jpa.attrvalue.validation.EmailAddressValidator"/>
+  <PlainSchema name="activationDate" type="Date" anyTypeClass_name="other"
+               mandatoryCondition="false" multivalue="0" uniqueConstraint="0" readonly="0"
+               conversionPattern="yyyy-MM-dd'T'HH:mm:ss.SSSZ"/>
+  <PlainSchema name="uselessReadonly" type="String" anyTypeClass_name="other"
+               mandatoryCondition="false" multivalue="0" uniqueConstraint="0" readonly="1"/>
+  <PlainSchema name="cool" type="Boolean" anyTypeClass_name="other" 
+               mandatoryCondition="false" multivalue="0" uniqueConstraint="0" readonly="0"/>
+  <PlainSchema name="gender" type="Enum" anyTypeClass_name="other"
+               mandatoryCondition="false" multivalue="0" uniqueConstraint="0" readonly="0"
+               enumerationValues="M;F"/>
+  <PlainSchema name="aLong" type="Long" anyTypeClass_name="other"
+               mandatoryCondition="false" multivalue="0" uniqueConstraint="0" readonly="0"/>
+  <PlainSchema name="makeItDouble" type="Long" anyTypeClass_name="other"
+               mandatoryCondition="false" multivalue="0" uniqueConstraint="0" readonly="0"/>
+  <PlainSchema name="obscure" type="Encrypted" anyTypeClass_name="other"
+               mandatoryCondition="false" multivalue="0" uniqueConstraint="0" readonly="0"
+               secretKey="7abcdefghilmnopqrstuvz9#" cipherAlgorithm="SHA"/>
+  <PlainSchema name="photo" type="Binary" anyTypeClass_name="other"
+               mandatoryCondition="false" multivalue="0" uniqueConstraint="0" readonly="0"
+               mimeType="image/jpeg"/>
+
+  <DerSchema name="csvuserid" expression="firstname + ',' + surname" anyTypeClass_name="csv"/>
+  <DerSchema name="cn" expression="surname + ', ' + firstname" anyTypeClass_name="minimal user"/>
+  <DerSchema name="noschema" expression="surname + ', ' + notfound" anyTypeClass_name="other"/>
+
+  <VirSchema name="virtualdata" anyTypeClass_name="minimal user"/>
+  <VirSchema name="virtualReadOnly" READONLY="1"  anyTypeClass_name="minimal user"/>
+
+  <PlainSchema name="icon" type="String" anyTypeClass_name="minimal group"
+               mandatoryCondition="false" multivalue="0" uniqueConstraint="0" readonly="0"/>                
+  <PlainSchema name="show" type="Boolean" anyTypeClass_name="minimal group"
+               mandatoryCondition="false" multivalue="0" uniqueConstraint="0" readonly="0"/>
+  <PlainSchema name="rderived_sx" type="String" anyTypeClass_name="minimal group"
+               mandatoryCondition="false" multivalue="0" uniqueConstraint="0" readonly="0"/>
+  <PlainSchema name="rderived_dx" type="String" anyTypeClass_name="minimal group"
+               mandatoryCondition="false" multivalue="0" uniqueConstraint="0" readonly="0"/>           
+  <PlainSchema name="title" type="String" anyTypeClass_name="minimal group"
+               mandatoryCondition="false" multivalue="1" uniqueConstraint="0" readonly="0"/>
+
+  <DerSchema name="rderiveddata" expression="rderived_sx + '-' + rderived_dx"
+             anyTypeClass_name="minimal group"/>
+  <DerSchema name="displayProperty" expression="icon + ': ' + show"
+             anyTypeClass_name="minimal group"/>
+  <DerSchema name="rderToBePropagated" expression="rderived_sx + '-' + rderived_dx"
+             anyTypeClass_name="minimal group"/>
+
+  <VirSchema name="rvirtualdata" anyTypeClass_name="minimal group"/>
+
+  <DerSchema name="rderivedschema" expression="rderived_sx + '-' + rderived_dx"  anyTypeClass_name="minimal group"/>
+
+  <PlainSchema name="subscriptionDate" type="Date" anyTypeClass_name="generic membership"
+               mandatoryCondition="false" multivalue="0" uniqueConstraint="0" readonly="0"
+               conversionPattern="yyyy-MM-dd'T'HH:mm:ss.SSSZ"/>
+  <PlainSchema name="mderived_sx" type="String" anyTypeClass_name="generic membership"
+               mandatoryCondition="false" multivalue="0" uniqueConstraint="0" readonly="0"/>
+  <PlainSchema name="mderived_dx" type="String" anyTypeClass_name="generic membership"
+               mandatoryCondition="false" multivalue="0" uniqueConstraint="0" readonly="0"/>          
+  <PlainSchema name="postalAddress" type="String" anyTypeClass_name="generic membership"
+               mandatoryCondition="false" multivalue="0" uniqueConstraint="0" readonly="0"/>
+
+  <DerSchema name="mderiveddata" expression="mderived_sx + '-' + mderived_dx"/>
+  <DerSchema name="mderToBePropagated" expression="mderived_sx + '-' + mderived_dx" 
+             anyTypeClass_name="generic membership"/>
+
+  <VirSchema name="mvirtualdata"/>
+        
+  <PlainSchema name="model" type="String" anyTypeClass_name="minimal printer"
+               mandatoryCondition="false" multivalue="0" uniqueConstraint="0" readonly="0"/>
+  <PlainSchema name="location" type="String" anyTypeClass_name="minimal printer"
+               mandatoryCondition="false" multivalue="0" uniqueConstraint="0" readonly="0"/>
+    
+  <APlainAttr id="1" owner_id="1" schema_name="model"/>
+  <APlainAttrValue id="1" attribute_id="1" stringValue="Canon MFC8030"/>
+  <APlainAttr id="2" owner_id="1" schema_name="location"/>
+  <APlainAttrValue id="2" attribute_id="2" stringValue="1st floor"/>
+    
+  <APlainAttr id="3" owner_id="2" schema_name="model"/>
+  <APlainAttrValue id="3" attribute_id="3" stringValue="HP Laserjet 1300n"/>
+  <APlainAttr id="4" owner_id="2" schema_name="location"/>
+  <APlainAttrValue id="4" attribute_id="4" stringValue="2nd floor"/>
+
+  <UPlainAttr id="99" owner_id="1" schema_name="type"/>
+  <UPlainAttrValue id="9" attribute_id="99" stringValue="G"/>
+  <UPlainAttr id="100" owner_id="1" schema_name="fullname"/>
+  <UPlainAttrUniqueValue id="10" attribute_id="100" schema_name="fullname" stringValue="Gioacchino Rossini"/>
+  <UPlainAttr id="101" owner_id="1" schema_name="firstname"/>
+  <UPlainAttrValue id="11" attribute_id="101" stringValue="Gioacchino"/>
+  <UPlainAttr id="102" owner_id="1" schema_name="surname"/>
+  <UPlainAttrValue id="12" attribute_id="102" stringValue="Rossini"/>
+  <UPlainAttr id="103" owner_id="1" schema_name="userId"/>
+  <UPlainAttrUniqueValue id="13" attribute_id="103" schema_name="userId" stringValue="rossini@apache.org"/>
+  <UPlainAttr id="104" owner_id="1" schema_name="loginDate"/>
+  <UPlainAttrValue id="14" attribute_id="104" dateValue="2009-05-26"/>
+  <UPlainAttrValue id="15" attribute_id="104" dateValue="2010-05-26 15:40:04"/>
+
+  <UPlainAttr id="105" owner_id="2" schema_name="fullname"/>
+  <UPlainAttrUniqueValue id="16" attribute_id="105" schema_name="fullname" stringValue="Giuseppe Verdi"/>
+  <UPlainAttr id="106" owner_id="2" schema_name="firstname"/>
+  <UPlainAttrValue id="17" attribute_id="106" stringValue="Giuseppe"/>
+  <UPlainAttr id="107" owner_id="2" schema_name="surname"/>
+  <UPlainAttrValue id="18" attribute_id="107" stringValue="Verdi"/>
+  <UPlainAttr id="108" owner_id="2" schema_name="userId"/>
+  <UPlainAttrUniqueValue id="19" attribute_id="108" schema_name="userId" stringValue="verdi@apache.org"/>
+
+  <UPlainAttr id="109" owner_id="3" schema_name="firstname"/>
+  <UPlainAttrValue id="20" attribute_id="109" stringValue="Antonio"/>
+  <UPlainAttr id="110" owner_id="3" schema_name="surname"/>
+  <UPlainAttrValue id="21" attribute_id="110" stringValue="Vivaldi"/>
+  <UPlainAttr id="111" owner_id="3" schema_name="fullname"/>
+  <UPlainAttrUniqueValue id="22" attribute_id="111" schema_name="fullname" stringValue="Antonio Vivaldi"/>
+  <UPlainAttr id="112" owner_id="3" schema_name="userId"/>
+  <UPlainAttrUniqueValue id="23" attribute_id="112" schema_name="userId" stringValue="vivaldi@apache.org"/>
+
+  <UPlainAttr id="113" owner_id="4" schema_name="firstname"/>
+  <UPlainAttrValue id="24" attribute_id="113" stringValue="Vincenzo"/>
+  <UPlainAttr id="114" owner_id="4" schema_name="surname"/>
+  <UPlainAttrValue id="25" attribute_id="114" stringValue="Bellini"/>
+  <UPlainAttr id="115" owner_id="4" schema_name="fullname"/>
+  <UPlainAttrUniqueValue id="26" attribute_id="115" schema_name="fullname" stringValue="Vincenzo Bellini"/>
+  <UPlainAttr id="116" owner_id="4" schema_name="userId"/>
+  <UPlainAttrUniqueValue id="27" attribute_id="116" schema_name="userId" stringValue="bellini@apache.org"/>
+  <UPlainAttr id="117" owner_id="4" schema_name="loginDate"/>
+  <UPlainAttrValue id="28" attribute_id="117" dateValue="2009-06-24"/>
+  <UPlainAttr id="118" owner_id="4" schema_name="cool"/>
+  <UPlainAttrValue id="29" attribute_id="118" booleanValue="1"/>
+  <UPlainAttr id="119" owner_id="4" schema_name="gender"/>
+  <UPlainAttrValue id="30" attribute_id="119" stringValue="M"/>
+  
+  <UPlainAttr id="120" owner_id="5" schema_name="firstname"/>
+  <UPlainAttrValue id="31" attribute_id="120" stringValue="Giacomo"/>
+  <UPlainAttr id="121" owner_id="5" schema_name="surname"/>
+  <UPlainAttrValue id="32" attribute_id="121" stringValue="Puccini"/>
+  <UPlainAttr id="122" owner_id="5" schema_name="fullname"/>
+  <UPlainAttrUniqueValue id="33" attribute_id="122" schema_name="fullname" stringValue="Giacomo Puccini"/>
+  <UPlainAttr id="123" owner_id="5" schema_name="userId"/>
+  <UPlainAttrUniqueValue id="34" attribute_id="123" schema_name="userId" stringValue="puccini@apache.org"/>
+  
+  <UPlainAttr id="124" owner_id="2" schema_name="email"/>
+  <UPlainAttrValue id="35" attribute_id="124" stringValue="verdi@syncope.org"/>
+  <UPlainAttr id="125" owner_id="3" schema_name="email"/>
+  <UPlainAttrValue id="36" attribute_id="125" stringValue="vivaldi@syncope.org"/>
+  <UPlainAttr id="126" owner_id="3" schema_name="type"/>
+  <UPlainAttrValue id="37" attribute_id="126" stringValue="F"/>
+    
+  <UVirAttr id="100" schema_name="virtualdata" owner_id="3"/>
+  
+  <UDerAttr id="100" schema_name="cn" owner_id="3"/>
+  <UDerAttr id="101" schema_name="cn" owner_id="1"/>
+
+  <GPlainAttr id="600" owner_id="1" schema_name="icon"/>
+  <GPlainAttrValue attribute_id="600" id="40" stringValue="niceIcon"/>
+
+  <GPlainAttr id="700" owner_id="2" schema_name="icon"/>
+  <GPlainAttrValue attribute_id="700" id="41" stringValue="badIcon"/>
+
+  <GPlainAttr id="800" owner_id="1"  schema_name="show"/>
+  <GPlainAttrValue attribute_id="800" id="42" booleanValue="1"/>
+
+  <GPlainAttr id="900" owner_id="6" schema_name="icon"/>
+  <GPlainAttrValue attribute_id="900" id="43" stringValue="icon6"/>
+
+  <GPlainAttr id="950" owner_id="4" schema_name="icon"/>
+  <GPlainAttrValue attribute_id="950" id="44" stringValue="icon4"/>
+
+  <GPlainAttr id="992" owner_id="1" schema_name="rderived_sx"/>
+  <GPlainAttrValue attribute_id="992" id="92" stringValue="sx"/>
+
+  <GPlainAttr id="993" owner_id="1" schema_name="rderived_dx"/>
+  <GPlainAttrValue attribute_id="993" id="93" stringValue="dx"/>
+
+  <GPlainAttr id="994" owner_id="12" schema_name="title"/>
+  <GPlainAttrValue attribute_id="994" id="94" stringValue="r12"/>
+  
+  <GPlainAttr id="995" owner_id="13" schema_name="title"/>
+  <GPlainAttrValue attribute_id="995" id="95" stringValue="r13"/>
+
+  <GDerAttr id="100" owner_id="1" schema_name="rderiveddata"/>
+    
+  <GDerAttr id="101" owner_id="1" schema_name="displayProperty"/>
+  
+  <GDerAttr id="102" owner_id="4" schema_name="displayProperty"/>
+
+  <GDerAttr id="103" owner_id="1" schema_name="rderToBePropagated"/>    
+
+  <GVirAttr id="98" owner_id="4" schema_name="rvirtualdata"/>
+
+  <ConnInstance id="100" displayName="ConnInstance100"
+                location="${connid.location}"
+                bundleName="net.tirasa.connid.bundles.soap"
+                connectorName="net.tirasa.connid.bundles.soap.WebServiceConnector"
+                version="${connid.soap.version}"
+                jsonConf='[{"schema":{"name":"endpoint","displayName":null,"helpMessage":null,"type":"java.lang.String","required":true,"order":0,"confidential":false,"defaultValues":null},"overridable":false,"values":["http://localhost:${cargo.servlet.port}/wssample/services/provisioning"]},{"schema":{"name":"servicename","displayName":null,"helpMessage":null,"type":"java.lang.String","required":true,"order":0,"confidential":false,"defaultValues":null},"overridable":false,"values":["net.tirasa.connid.bundles.soap.provisioning.interfaces.Provisioning"]}]'/>
+  <ConnInstance_capabilities ConnInstance_id="100" capability="ONE_PHASE_CREATE"/>
+  <ConnInstance_capabilities ConnInstance_id="100" capability="ONE_PHASE_UPDATE"/>
+  <ConnInstance_capabilities ConnInstance_id="100" capability="ONE_PHASE_DELETE"/>
+  <ConnInstance_capabilities ConnInstance_id="100" capability="TWO_PHASES_CREATE"/>
+  <ConnInstance_capabilities ConnInstance_id="100" capability="TWO_PHASES_UPDATE"/>
+  <ConnInstance_capabilities ConnInstance_id="100" capability="TWO_PHASES_DELETE"/>
+  <ConnInstance_capabilities ConnInstance_id="100" capability="SEARCH"/>
+
+  <ConnInstance id="101" displayName="H2"
+                location="connid://${testconnectorserver.key}@localhost:${testconnectorserver.port}"
+                bundleName="net.tirasa.connid.bundles.db.table"
+                connectorName="net.tirasa.connid.bundles.db.table.DatabaseTableConnector"
+                version="${connid.database.version}"
+                jsonConf='[{"schema":{"name":"disabledStatusValue","displayName":null,"helpMessage":null,"type":"java.lang.String","required":false,"order":0,"confidential":false,"defaultValues":null},"overridable":false,"values":["false"]},{"schema":{"name":"user","displayName":null,"helpMessage":null,"type":"java.lang.String","required":false,"order":0,"confidential":false,"defaultValues":null},"overridable":false,"values":["sa"]},{"schema":{"name":"keyColumn","displayName":null,"helpMessage":null,"type":"java.lang.String","required":true,"order":0,"confidential":false,"defaultValues":null},"overridable":false,"values":["id"]},{"schema":{"name":"retrievePassword","displayName":null,"helpMessage":null,"type":"boolean","required":false,"order":0,"confidential":false,"defaultValues":null},"overridable":false,"values":["true"]},{"schema":{"name":"cipherAlgorithm","displayName":null,"helpMessage":null,"type":"java.lang.String","required":true,"order":0,"confidential":false,"defaultValu
 es":null},"overridable":false,"values":["SHA1"]},{"schema":{"name":"enabledStatusValue","displayName":null,"helpMessage":null,"type":"java.lang.String","required":false,"order":0,"confidential":false,"defaultValues":null},"overridable":false,"values":["true"]},{"schema":{"name":"passwordColumn","displayName":null,"helpMessage":null,"type":"java.lang.String","required":false,"order":0,"confidential":false,"defaultValues":null},"overridable":false,"values":["password"]},{"schema":{"name":"jdbcDriver","displayName":null,"helpMessage":null,"type":"java.lang.String","required":false,"order":0,"confidential":false,"defaultValues":null},"overridable":false,"values":["org.h2.Driver"]},{"schema":{"name":"defaultStatusValue","displayName":null,"helpMessage":null,"type":"java.lang.String","required":false,"order":0,"confidential":false,"defaultValues":null},"overridable":false,"values":["true"]},{"schema":{"name":"table","displayName":null,"helpMessage":null,"type":"java.lang.String","required
 ":true,"order":0,"confidential":false,"defaultValues":null},"overridable":false,"values":["test"]},{"schema":{"name":"password","displayName":null,"helpMessage":null,"type":"org.identityconnectors.common.security.GuardedString","required":false,"order":0,"confidential":false,"defaultValues":null},"overridable":false,"values":["sa"]},{"schema":{"name":"statusColumn","displayName":null,"helpMessage":null,"type":"java.lang.String","required":false,"order":0,"confidential":false,"defaultValues":null},"overridable":false,"values":["status"]},{"schema":{"name":"jdbcUrlTemplate","displayName":null,"helpMessage":null,"type":"java.lang.String","required":false,"order":0,"confidential":false,"defaultValues":null},"overridable":false,"values":["${testdb.url}"]}]'/>
+  <ConnInstance_capabilities ConnInstance_id="101" capability="AUTHENTICATE"/>
+  <ConnInstance_capabilities ConnInstance_id="101" capability="ONE_PHASE_CREATE"/>
+  <ConnInstance_capabilities ConnInstance_id="101" capability="ONE_PHASE_UPDATE"/>
+  <ConnInstance_capabilities ConnInstance_id="101" capability="ONE_PHASE_DELETE"/>
+  <ConnInstance_capabilities ConnInstance_id="101" capability="TWO_PHASES_CREATE"/>
+  <ConnInstance_capabilities ConnInstance_id="101" capability="TWO_PHASES_UPDATE"/>
+  <ConnInstance_capabilities ConnInstance_id="101" capability="TWO_PHASES_DELETE"/>
+  <ConnInstance_capabilities ConnInstance_id="101" capability="SEARCH"/>
+  <ConnInstance_capabilities ConnInstance_id="101" capability="SYNC"/>
+
+  <ConnInstance id="102" displayName="ConnInstance102"
+                location="${connid.location}"
+                bundleName="net.tirasa.connid.bundles.soap"
+                connectorName="net.tirasa.connid.bundles.soap.WebServiceConnector"
+                version="${connid.soap.version}"
+                connRequestTimeout="10"
+                jsonConf='[{"schema":{"name":"servicename","displayName":null,"helpMessage":null,"type":"java.lang.String","required":true,"order":0,"confidential":false,"defaultValues":null},"overridable":false,"values":["net.tirasa.connid.bundles.soap.provisioning.interfaces.Provisioning"]},{"schema":{"name":"endpoint","displayName":null,"helpMessage":null,"type":"java.lang.String","required":true,"order":0,"confidential":false,"defaultValues":null},"overridable":true,"values":["http://localhost:${cargo.servlet.port}/wssample/services/provisioning"]}]'/>
+  <ConnInstance_capabilities ConnInstance_id="102" capability="ONE_PHASE_CREATE"/>
+  <ConnInstance_capabilities ConnInstance_id="102" capability="ONE_PHASE_UPDATE"/>
+  <ConnInstance_capabilities ConnInstance_id="102" capability="ONE_PHASE_DELETE"/>
+  <ConnInstance_capabilities ConnInstance_id="102" capability="TWO_PHASES_CREATE"/>
+  <ConnInstance_capabilities ConnInstance_id="102" capability="TWO_PHASES_UPDATE"/>
+  <ConnInstance_capabilities ConnInstance_id="102" capability="TWO_PHASES_DELETE"/>
+  <ConnInstance_capabilities ConnInstance_id="102" capability="SEARCH"/>
+
+  <ConnInstance id="103" displayName="ConnInstance103"
+                location="${connid.location}"
+                bundleName="net.tirasa.connid.bundles.soap"
+                connectorName="net.tirasa.connid.bundles.soap.WebServiceConnector"
+                version="${connid.soap.version}"
+                jsonConf='[{"schema":{"name":"endpoint","displayName":null,"helpMessage":null,"type":"java.lang.String","required":true,"order":0,"confidential":false,"defaultValues":null},"overridable":false,"values":["http://localhost:${cargo.servlet.port}/wssample/services/provisioning"]},{"schema":{"name":"servicename","displayName":null,"helpMessage":null,"type":"java.lang.String","required":true,"order":0,"confidential":false,"defaultValues":null},"overridable":false,"values":["net.tirasa.connid.bundles.soap.provisioning.interfaces.Provisioning"]}]'/>
+
+  <ConnInstance id="104" displayName="CSVDir"
+                location="${connid.location}"
+                bundleName="net.tirasa.connid.bundles.csvdir"
+                connectorName="net.tirasa.connid.bundles.csvdir.CSVDirConnector"
+                version="${connid.csvdir.version}"
+                jsonConf='[{"schema":{"name":"fields","displayName":"fields","helpMessage":"Column names separated by comma","type":"[Ljava.lang.String;","required":true,"order":0,"confidential":false,"defaultValues":null},"overridable":false,"values":["id","name","surname","email","password","theirgroup","membership","status","deleted"]},{"schema":{"name":"keyColumnNames","displayName":"Key column name","helpMessage":"Name of the column used to identify user uniquely","type":"[Ljava.lang.String;","required":true,"order":0,"confidential":false,"defaultValues":null},"overridable":false,"values":["name","surname"]},{"schema":{"name":"deleteColumnName","displayName":"Delete column name","helpMessage":"Name of the column used to specify users to be deleted","type":"java.lang.String","required":false,"order":0,"confidential":false,"defaultValues":null},"overridable":false,"values":["deleted"]},{"schema":{"name":"passwordColumnName","displayName":"Password column name","helpMessage":"Name
  of the column used to specify user password","type":"java.lang.String","required":false,"order":0,"confidential":false,"defaultValues":null},"overridable":false,"values":["password"]},{"schema":{"name":"keyseparator","displayName":"Key separator","helpMessage":"Character used to separate keys in a multi-key scenario","type":"java.lang.String","required":true,"order":0,"confidential":false,"defaultValues":null},"overridable":false,"values":[","]},{"schema":{"name":"ignoreHeader","displayName":"Ignore header","helpMessage":"Specify it first line file must be ignored","type":"java.lang.Boolean","required":true,"order":0,"confidential":false,"defaultValues":null},"overridable":false,"values":[false]},{"schema":{"name":"fieldDelimiter","displayName":"fieldDelimiter","helpMessage":"fieldDelimiter","type":"char","required":true,"order":0,"confidential":false,"defaultValues":null},"overridable":false,"values":[","]},{"schema":{"name":"quotationRequired","displayName":"Value quotation requi
 red","helpMessage":"Specify if value quotation is required","type":"java.lang.Boolean","required":true,"order":0,"confidential":false,"defaultValues":null},"overridable":false,"values":[false]},{"schema":{"name":"statusColumn","displayName":"statusColumn","helpMessage":"Status column","type":"java.lang.String","required":false,"order":0,"confidential":false,"defaultValues":null},"overridable":false,"values":["status"]},{"schema":{"name":"sourcePath","displayName":"Source path","helpMessage":"Absolute path of a directory where are located CSV files to be processed","type":"java.lang.String","required":true,"order":0,"confidential":false,"defaultValues":null},"overridable":false,"values":["${test.csvdir.path}"]},{"schema":{"name":"fileMask","displayName":"File mask","helpMessage":"Regular expression describing files to be processed","type":"java.lang.String","required":true,"order":0,"confidential":false,"defaultValues":null},"overridable":false,"values":["test.csv"]}]'/>
+  <ConnInstance_capabilities ConnInstance_id="104" capability="ONE_PHASE_CREATE"/>
+  <ConnInstance_capabilities ConnInstance_id="104" capability="ONE_PHASE_UPDATE"/>
+  <ConnInstance_capabilities ConnInstance_id="104" capability="ONE_PHASE_DELETE"/>
+  <ConnInstance_capabilities ConnInstance_id="104" capability="TWO_PHASES_CREATE"/>
+  <ConnInstance_capabilities ConnInstance_id="104" capability="TWO_PHASES_UPDATE"/>
+  <ConnInstance_capabilities ConnInstance_id="104" capability="TWO_PHASES_DELETE"/>
+  <ConnInstance_capabilities ConnInstance_id="104" capability="SEARCH"/>
+  <ConnInstance_capabilities ConnInstance_id="104" capability="SYNC"/>
+    
+  <ConnInstance id="105" bundleName="net.tirasa.connid.bundles.ldap" displayName="ApacheDS"
+                location="${connid.location}"
+                connectorName="net.tirasa.connid.bundles.ldap.LdapConnector"
+                version="${connid.ldap.version}" 
+                jsonConf='[{"schema":{"name":"synchronizePasswords","displayName":"Enable Password Synchronization","helpMessage":"If true, the connector will synchronize passwords. The Password Capture Plugin needs to be installed for password synchronization to work.","type":"boolean","required":false,"order":0,"confidential":false,"defaultValues":null},"overridable":false,"values":["false"]},{"schema":{"name":"maintainLdapGroupMembership","displayName":"Maintain LDAP Group Membership","helpMessage":"When enabled and a user is renamed or deleted, update any LDAP groups to which the user belongs to reflect the new name. Otherwise, the LDAP resource must maintain referential integrity with respect to group membership.","type":"boolean","required":false,"order":0,"confidential":false,"defaultValues":null},"overridable":false,"values":["true"]},{"schema":{"name":"host","displayName":"Host","helpMessage":"The name or IP address of the host where the LDAP server is running.","type":"jav
 a.lang.String","required":false,"order":0,"confidential":false,"defaultValues":null},"overridable":false,"values":["localhost"]},{"schema":{"name":"passwordHashAlgorithm","displayName":"Password Hash Algorithm","helpMessage":"Indicates the algorithm that the Identity system should use to hash the password. Currently supported values are SSHA, SHA, SSHA1, and SHA1. A blank value indicates that the system will not hash passwords. This will cause cleartext passwords to be stored in LDAP unless the LDAP server performs the hash (Netscape Directory Server and iPlanet Directory Server do).","type":"java.lang.String","required":false,"order":0,"confidential":false,"defaultValues":null},"overridable":false,"values":["SHA"]},{"schema":{"name":"blockSize","displayName":"Block Size","helpMessage":"The maximum number of accounts that can be in a block when retrieving accounts in blocks.","type":"int","required":false,"order":0,"confidential":false,"defaultValues":null},"overridable":false,"valu
 es":[]},{"schema":{"name":"useBlocks","displayName":"Use Blocks","helpMessage":"When performing operations on large numbers of accounts, the accounts are processed in blocks to reduce the amount of memory used by the operation. Select this option to process accounts in blocks.","type":"boolean","required":false,"order":0,"confidential":false,"defaultValues":null},"overridable":false,"values":[false]},{"schema":{"name":"usePagedResultControl","displayName":"Use Paged Result Control","helpMessage":"When enabled, the LDAP Paged Results control is preferred over the VLV control when retrieving accounts.","type":"boolean","required":false,"order":0,"confidential":false,"defaultValues":null},"overridable":false,"values":["false"]},{"schema":{"name":"port","displayName":"TCP Port","helpMessage":"TCP/IP port number used to communicate with the LDAP server.","type":"int","required":false,"order":0,"confidential":false,"defaultValues":null},"overridable":false,"values":[1389]},{"schema":{"nam
 e":"vlvSortAttribute","displayName":"VLV Sort Attribute","helpMessage":"Specify the sort attribute to use for VLV indexes on the resource.","type":"java.lang.String","required":false,"order":0,"confidential":false,"defaultValues":null},"overridable":false,"values":[]},{"schema":{"name":"statusManagementClass","displayName":"Status management class ","helpMessage":"Class to be used to manage enabled/disabled status. If no class is specified then identity status management wont be possible.","type":"java.lang.String","required":false,"order":0,"confidential":false,"defaultValues":null},"overridable":false,"values":["net.tirasa.connid.bundles.ldap.commons.AttributeStatusManagement"]},{"schema":{"name":"accountObjectClasses","displayName":"Account Object Classes","helpMessage":"The object class or classes that will be used when creating new user objects in the LDAP tree. When entering more than one object class, each entry should be on its own line; do not use commas or semi-colons to s
 eparate multiple object classes. Some object classes may require that you specify all object classes in the class hierarchy.","type":"[Ljava.lang.String;","required":false,"order":0,"confidential":false,"defaultValues":null},"overridable":false,"values":["inetOrgPerson"]},{"schema":{"name":"accountUserNameAttributes","displayName":"Account User Name Attributes","helpMessage":"Attribute or attributes which holds the account user name. They will be used when authenticating to find the LDAP entry for the user name to authenticate.","type":"[Ljava.lang.String;","required":false,"order":0,"confidential":false,"defaultValues":null},"overridable":false,"values":["uid"]},{"schema":{"name":"baseContextsToSynchronize","displayName":"Base Contexts to Synchronize","helpMessage":"One or more starting points in the LDAP tree that will be used to determine if a change should be synchronized. The base contexts attribute will be used to synchronize a change if this property is not set.","type":"[Lja
 va.lang.String;","required":false,"order":0,"confidential":false,"defaultValues":null},"overridable":false,"values":["ou=people,o=isp","ou=groups,o=isp"]},{"schema":{"name":"accountSynchronizationFilter","displayName":"LDAP Filter for Accounts to Synchronize","helpMessage":"An optional LDAP filter for the objects to synchronize. Because the change log is for all objects, this filter updates only objects that match the specified filter. If you specify a filter, an object will be synchronized only if it matches the filter and includes a synchronized object class.","type":"java.lang.String","required":false,"order":0,"confidential":false,"defaultValues":null},"overridable":false,"values":[]},{"schema":{"name":"removeLogEntryObjectClassFromFilter","displayName":"Remove Log Entry Object Class from Filter","helpMessage":"If this property is set (the default), the filter used to fetch change log entries does not contain the \"changeLogEntry\" object class, expecting that there are no entri
 es of other object types in the change log.","type":"boolean","required":false,"order":0,"confidential":false,"defaultValues":null},"overridable":false,"values":["false"]},{"schema":{"name":"passwordDecryptionKey","displayName":"Password Decryption Key","helpMessage":"The key to decrypt passwords with when performing password synchronization.","type":"org.identityconnectors.common.security.GuardedByteArray","required":false,"order":0,"confidential":false,"defaultValues":null},"overridable":false,"values":[]},{"schema":{"name":"readSchema","displayName":"Read Schema","helpMessage":"If true, the connector will read the schema from the server. If false, the connector will provide a default schema based on the object classes in the configuration. This property must be true in order to use extended object classes.","type":"boolean","required":false,"order":0,"confidential":false,"defaultValues":null},"overridable":false,"values":["false"]},{"schema":{"name":"ssl","displayName":"SSL","hel
 pMessage":"Select the check box to connect to the LDAP server using SSL.","type":"boolean","required":false,"order":0,"confidential":false,"defaultValues":null},"overridable":false,"values":["false"]},{"schema":{"name":"passwordAttributeToSynchronize","displayName":"Password Attribute to Synchronize","helpMessage":"The name of the password attribute to synchronize when performing password synchronization.","type":"java.lang.String","required":false,"order":0,"confidential":false,"defaultValues":null},"overridable":false,"values":[]},{"schema":{"name":"accountSearchFilter","displayName":"LDAP Filter for Retrieving Accounts","helpMessage":"An optional LDAP filter to control which accounts are returned from the LDAP resource. If no filter is specified, only accounts that include all specified object classes are returned.","type":"java.lang.String","required":false,"order":0,"confidential":false,"defaultValues":null},"overridable":false,"values":["uid=*"]},{"schema":{"name":"passwordDec
 ryptionInitializationVector","displayName":"Password Decryption Initialization Vector","helpMessage":"The initialization vector to decrypt passwords with when performing password synchronization.","type":"org.identityconnectors.common.security.GuardedByteArray","required":false,"order":0,"confidential":false,"defaultValues":null},"overridable":false,"values":[]},{"schema":{"name":"groupMemberAttribute","displayName":"Group Member Attribute","helpMessage":"The name of the group attribute that will be updated with the distinguished name of the user when the user is added to the group.","type":"java.lang.String","required":false,"order":0,"confidential":false,"defaultValues":null},"overridable":false,"values":[]},{"schema":{"name":"failover","displayName":"Failover Servers","helpMessage":"List all servers that should be used for failover in case the preferred server fails. If the preferred server fails, JNDI will connect to the next available server in the list. List all servers in the
  form of \"ldap://ldap.example.com:389/\", which follows the standard LDAP v3 URLs described in RFC 2255. Only the host and port parts of the URL are relevant in this setting.","type":"[Ljava.lang.String;","required":false,"order":0,"confidential":false,"defaultValues":null},"overridable":false,"values":[]},{"schema":{"name":"modifiersNamesToFilterOut","displayName":"Filter Out Changes By","helpMessage":"The names (DNs) of directory administrators to filter from the changes. Changes with the attribute \"modifiersName\" that match entries in this list will be filtered out. The standard value is the administrator name used by this adapter, to prevent loops. Entries should be of the format \"cn=Directory Manager\".","type":"[Ljava.lang.String;","required":false,"order":0,"confidential":false,"defaultValues":null},"overridable":false,"values":[]},{"schema":{"name":"groupNameAttributes","displayName":"Group Name Attributes","helpMessage":"Attribute or attributes which holds the group nam
 e.","type":"[Ljava.lang.String;","required":false,"order":0,"confidential":false,"defaultValues":null},"overridable":false,"values":["cn"]},{"schema":{"name":"uidAttribute","displayName":"Uid Attribute","helpMessage":"The name of the LDAP attribute which is mapped to the Uid attribute.","type":"java.lang.String","required":false,"order":0,"confidential":false,"defaultValues":null},"overridable":false,"values":["cn"]},{"schema":{"name":"respectResourcePasswordPolicyChangeAfterReset","displayName":"Respect Resource Password Policy Change-After-Reset","helpMessage":"When this resource is specified in a Login Module (i.e., this resource is a pass-through authentication target) and the resource password policy is configured for change-after-reset, a user whose resource account password has been administratively reset will be required to change that password after successfully authenticating.","type":"boolean","required":false,"order":0,"confidential":false,"defaultValues":null},"overrida
 ble":false,"values":["false"]},{"schema":{"name":"filterWithOrInsteadOfAnd","displayName":"Filter with Or Instead of And","helpMessage":"Normally the the filter used to fetch change log entries is an and-based filter retrieving an interval of change entries. If this property is set, the filter will or together the required change numbers instead.","type":"boolean","required":false,"order":0,"confidential":false,"defaultValues":null},"overridable":false,"values":["false"]},{"schema":{"name":"principal","displayName":"Principal","helpMessage":"The distinguished name with which to authenticate to the LDAP server.","type":"java.lang.String","required":false,"order":0,"confidential":false,"defaultValues":null},"overridable":false,"values":["uid=admin,ou=system"]},{"schema":{"name":"changeLogBlockSize","displayName":"Change Log Block Size","helpMessage":"The number of change log entries to fetch per query.","type":"int","required":true,"order":0,"confidential":false,"defaultValues":null},
 "overridable":false,"values":[100]},{"schema":{"name":"baseContexts","displayName":"Base Contexts","helpMessage":"One or more starting points in the LDAP tree that will be used when searching the tree. Searches are performed when discovering users from the LDAP server or when looking for the groups of which a user is a member.","type":"[Ljava.lang.String;","required":false,"order":0,"confidential":false,"defaultValues":null},"overridable":false,"values":["ou=people,o=isp","ou=groups,o=isp"]},{"schema":{"name":"passwordAttribute","displayName":"Password Attribute","helpMessage":"The name of the LDAP attribute which holds the password. When changing an user password, the new password is set to this attribute.","type":"java.lang.String","required":false,"order":0,"confidential":false,"defaultValues":null},"overridable":false,"values":["userpassword"]},{"schema":{"name":"changeNumberAttribute","displayName":"Change Number Attribute","helpMessage":"The name of the change number attribute
  in the change log entry.","type":"java.lang.String","required":true,"order":0,"confidential":false,"defaultValues":null},"overridable":false,"values":["changeNumber"]},{"schema":{"name":"objectClassesToSynchronize","displayName":"Object Classes to Synchronize","helpMessage":"The object classes to synchronize. The change log is for all objects; this filters updates to just the listed object classes. You should not list the superclasses of an object class unless you intend to synchronize objects with any of the superclass values. For example, if only \"inetOrgPerson\" objects should be synchronized, but the superclasses of \"inetOrgPerson\" (\"person\", \"organizationalperson\" and \"top\") should be filtered out, then list only \"inetOrgPerson\" here. All objects in LDAP are subclassed from \"top\". For this reason, you should never list \"top\", otherwise no object would be filtered.","type":"[Ljava.lang.String;","required":true,"order":0,"confidential":false,"defaultValues":null},
 "overridable":false,"values":["inetOrgPerson","groupOfUniqueNames"]},{"schema":{"name":"credentials","displayName":"Password","helpMessage":"Password for the principal.","type":"org.identityconnectors.common.security.GuardedString","required":false,"order":0,"confidential":false,"defaultValues":null},"overridable":false,"values":["secret"]},{"schema":{"name":"attributesToSynchronize","displayName":"Attributes to Synchronize","helpMessage":"The names of the attributes to synchronize. This ignores updates from the change log if they do not update any of the named attributes. For example, if only \"department\" is listed, then only changes that affect \"department\" will be processed. All other updates are ignored. If blank (the default), then all changes are processed.","type":"[Ljava.lang.String;","required":false,"order":0,"confidential":false,"defaultValues":null},"overridable":false,"values":[]},{"schema":{"name":"maintainPosixGroupMembership","displayName":"Maintain POSIX Group M
 embership","helpMessage":"When enabled and a user is renamed or deleted, update any POSIX groups to which the user belongs to reflect the new name. Otherwise, the LDAP resource must maintain referential integrity with respect to group membership.","type":"boolean","required":false,"order":0,"confidential":false,"defaultValues":null},"overridable":false,"values":["truemaintainLdapGroupMembership"]}]'/>
+  <ConnInstance_capabilities ConnInstance_id="105" capability="ONE_PHASE_CREATE"/>
+  <ConnInstance_capabilities ConnInstance_id="105" capability="ONE_PHASE_UPDATE"/>
+  <ConnInstance_capabilities ConnInstance_id="105" capability="ONE_PHASE_DELETE"/>
+  <ConnInstance_capabilities ConnInstance_id="105" capability="SEARCH"/>
+  
+  <ConnInstance id="106" displayName="H2-test2"
+                location="connid://${testconnectorserver.key}@localhost:${testconnectorserver.port}"
+                bundleName="net.tirasa.connid.bundles.db.table"
+                connectorName="net.tirasa.connid.bundles.db.table.DatabaseTableConnector"
+                version="${connid.database.version}"
+                jsonConf='[{"schema":{"name":"disabledStatusValue","displayName":null,"helpMessage":null,"type":"java.lang.String","required":false,"order":0,"confidential":false,"defaultValues":null},"overridable":false,"values":["false"]},{"schema":{"name":"user","displayName":null,"helpMessage":null,"type":"java.lang.String","required":false,"order":0,"confidential":false,"defaultValues":null},"overridable":false,"values":["sa"]},{"schema":{"name":"keyColumn","displayName":null,"helpMessage":null,"type":"java.lang.String","required":true,"order":0,"confidential":false,"defaultValues":null},"overridable":false,"values":["id"]},{"schema":{"name":"cipherAlgorithm","displayName":null,"helpMessage":null,"type":"java.lang.String","required":true,"order":0,"confidential":false,"defaultValues":null},"overridable":false,"values":["SHA1"]},{"schema":{"name":"enabledStatusValue","displayName":null,"helpMessage":null,"type":"java.lang.String","required":false,"order":0,"confidential":false,"
 defaultValues":null},"overridable":false,"values":["true"]},{"schema":{"name":"passwordColumn","displayName":null,"helpMessage":null,"type":"java.lang.String","required":false,"order":0,"confidential":false,"defaultValues":null},"overridable":false,"values":["password"]},{"schema":{"name":"jdbcDriver","displayName":null,"helpMessage":null,"type":"java.lang.String","required":false,"order":0,"confidential":false,"defaultValues":null},"overridable":false,"values":["org.h2.Driver"]},{"schema":{"name":"retrievePassword","displayName":null,"helpMessage":null,"type":"java.lang.Boolean","required":false,"order":0,"confidential":false,"defaultValues":null},"overridable":false,"values":["true"]},{"schema":{"name":"defaultStatusValue","displayName":null,"helpMessage":null,"type":"java.lang.String","required":false,"order":0,"confidential":false,"defaultValues":null},"overridable":false,"values":["true"]},{"schema":{"name":"password","displayName":null,"helpMessage":null,"type":"org.identityco
 nnectors.common.security.GuardedString","required":false,"order":0,"confidential":false,"defaultValues":null},"overridable":false,"values":["sa"]},{"schema":{"name":"statusColumn","displayName":null,"helpMessage":null,"type":"java.lang.String","required":false,"order":0,"confidential":false,"defaultValues":null},"overridable":false,"values":["status"]},{"schema":{"name":"jdbcUrlTemplate","displayName":null,"helpMessage":null,"type":"java.lang.String","required":false,"order":0,"confidential":false,"defaultValues":null},"overridable":false,"values":["${testdb.url}"]},{"schema":{"name":"table","displayName":null,"helpMessage":null,"type":"java.lang.String","required":true,"order":0,"confidential":false,"defaultValues":null},"overridable":false,"values":["test2"]}]'/>
+  <ConnInstance_capabilities ConnInstance_id="106" capability="ONE_PHASE_CREATE"/>
+  <ConnInstance_capabilities ConnInstance_id="106" capability="ONE_PHASE_UPDATE"/>
+  <ConnInstance_capabilities ConnInstance_id="106" capability="SEARCH"/>
+  <ConnInstance_capabilities ConnInstance_id="106" capability="SYNC"/>
+  
+  <ConnInstance id="107" bundleName="net.tirasa.connid.bundles.db.table" 
+                location="connid://${testconnectorserver.key}@localhost:${testconnectorserver.port}"
+                connectorName="net.tirasa.connid.bundles.db.table.DatabaseTableConnector" 
+                displayName="H2-testsync" version="${connid.database.version}"
+                jsonConf='[{"schema":{"name":"changeLogColumn","displayName":"Change Log Column (Sync)","helpMessage":"=&lt;b&gt;Change Log Column&lt;/b&gt;&lt;br&gt;The change log column store the latest change time. Providing this value the Sync capabilities are activated.","type":"java.lang.String","required":false,"order":21,"confidential":false,"defaultValues":null},"overridable":false,"values":[]},{"schema":{"name":"nativeTimestamps","displayName":"Native Timestamps ","helpMessage":"&lt;b&gt;Native Timestamps&lt;/b&gt;&lt;br&gt;Select to retrieve Timestamp data type of the columns in java.sql.Timestamp format from the database table.","type":"boolean","required":false,"order":18,"confidential":false,"defaultValues":null},"overridable":false,"values":["false"]},{"schema":{"name":"cipherAlgorithm","displayName":"Password cipher algorithm (defaults to CLEARTEXT)","helpMessage":"Cipher algorithm used to encode password before to store it onto the database table.\nSpecify one of th
 e values among CLEARTEXT,AES, MD5, SHA1, SHA256 or a custom implementation identified by its class name.","type":"java.lang.String","required":false,"order":24,"confidential":false,"defaultValues":null},"overridable":false,"values":[]},{"schema":{"name":"enabledStatusValue","displayName":"Enabled Status Value","helpMessage":"&lt;b&gt;Enabled Status Value&lt;/b&gt;&lt;br&gt;Enter the value for enabled status.","type":"java.lang.String","required":false,"order":12,"confidential":false,"defaultValues":null},"overridable":false,"values":[]},{"schema":{"name":"retrievePassword","displayName":"Retrieve password","helpMessage":"Specify if password must be retrieved by default.","type":"boolean","required":true,"order":27,"confidential":false,"defaultValues":null},"overridable":false,"values":["false"]},{"schema":{"name":"datasource","displayName":"Datasource Path","helpMessage":"&lt;b&gt;JDBC Data Source Name/Path&lt;/b&gt;&lt;br&gt;Enter the JDBC Data Source Name/Path to connect to the Or
 acle server. If specified, connector will only try to connect using Datasource and ignore other resource parameters specified.&lt;br&gt;the example value is: &lt;CODE&gt;jdbc/SampleDataSourceName&lt;/CODE&gt;","type":"java.lang.String","required":false,"order":22,"confidential":false,"defaultValues":null},"overridable":false,"values":[]},{"schema":{"name":"allNative","displayName":"All native","helpMessage":"&lt;b&gt;All native&lt;/b&gt;&lt;br&gt;Select to retrieve all data type of the columns in a native format from the database table.","type":"boolean","required":false,"order":19,"confidential":false,"defaultValues":null},"overridable":false,"values":["false"]},{"schema":{"name":"user","displayName":"User","helpMessage":"&lt;b&gt;User&lt;/b&gt;&lt;br&gt;Enter the name of the mandatory Database user with permission to account table.","type":"java.lang.String","required":false,"order":4,"confidential":false,"defaultValues":null},"overridable":false,"values":["sa"]},{"schema":{"name"
 :"pwdEncodeToLowerCase","displayName":"Force password encoding to lower case","helpMessage":"Force password encoding to lower case.","type":"boolean","required":false,"order":26,"confidential":false,"defaultValues":null},"overridable":false,"values":["false"]},{"schema":{"name":"jdbcUrlTemplate","displayName":"JDBC Connection URL","helpMessage":"&lt;b&gt;JDBC Connection URL&lt;/b&gt;&lt;br&gt;Specify the JDBC Driver Connection URL.&lt;br&gt; Oracle template is jdbc:oracle:thin:@[host]:[port(1521)]:[DB].&lt;br&gt;  MySQL template is jdbc:mysql://[host]:[port(3306)]/[db], for more info, read the JDBC driver documentation.&lt;br&gt;Could be empty if datasource is provided.","type":"java.lang.String","required":false,"order":15,"confidential":false,"defaultValues":null},"overridable":false,"values":["${testdb.url}"]},{"schema":{"name":"keyColumn","displayName":"Key Column","helpMessage":"&lt;b&gt;Key Column&lt;/b&gt;&lt;br&gt;This mandatory column value will be used as the unique identi
 fier for rows in the table.&lt;br&gt;","type":"java.lang.String","required":true,"order":8,"confidential":false,"defaultValues":null},"overridable":false,"values":["id"]},{"schema":{"name":"validConnectionQuery","displayName":"Validate Connection Query","helpMessage":"&lt;b&gt;Validate Connection Query&lt;/b&gt;&lt;br&gt;There can be specified the check connection alive query. If empty, default implementation will test it using the switch on/off the autocommit. Some select 1 from dummy table could be more efficient.","type":"java.lang.String","required":false,"order":20,"confidential":false,"defaultValues":null},"overridable":false,"values":[]},{"schema":{"name":"rethrowAllSQLExceptions","displayName":"Rethrow all SQLExceptions","helpMessage":"If this is not checked, SQL statements which throw SQLExceptions with a 0 ErrorCode will be have the exception caught and suppressed. Check it to have exceptions with 0 ErrorCodes rethrown.","type":"boolean","required":false,"order":17,"confid
 ential":false,"defaultValues":null},"overridable":false,"values":["false"]},{"schema":{"name":"passwordColumn","displayName":"Password Column","helpMessage":"&lt;b&gt;Password Column&lt;/b&gt;&lt;br&gt;Enter the name of the column in the table that will hold the password values. If empty, no validation on resource and passwords are activated.","type":"java.lang.String","required":false,"order":9,"confidential":false,"defaultValues":null},"overridable":false,"values":[]},{"schema":{"name":"jndiProperties","displayName":"Initial JNDI Properties","helpMessage":"&lt;b&gt;Initial JNDI Properties&lt;/b&gt;&lt;br&gt;Could be empty or enter the JDBC JNDI Initial context factory, context provider in a format: key = value.","type":"[Ljava.lang.String;","required":false,"order":23,"confidential":false,"defaultValues":null},"overridable":false,"values":[]},{"schema":{"name":"password","displayName":"User Password","helpMessage":"&lt;b&gt;User Password&lt;/b&gt;&lt;br&gt;Enter a user account tha
 t has permission to access accounts table.","type":"org.identityconnectors.common.security.GuardedString","required":false,"order":5,"confidential":true,"defaultValues":null},"overridable":false,"values":["sa"]},{"schema":{"name":"host","displayName":"Host","helpMessage":"&lt;b&gt;Host&lt;/b&gt;&lt;br&gt;Enter the name of the host where the database is running.","type":"java.lang.String","required":false,"order":2,"confidential":false,"defaultValues":null},"overridable":false,"values":[]},{"schema":{"name":"port","displayName":"Port","helpMessage":"&lt;b&gt;TCP Port&lt;/b&gt;&lt;br&gt;Enter the port number the database server is listening on.","type":"java.lang.String","required":false,"order":3,"confidential":false,"defaultValues":null},"overridable":false,"values":[]},{"schema":{"name":"statusColumn","displayName":"Status Column","helpMessage":"&lt;b&gt;Status Column&lt;/b&gt;&lt;br&gt;Enter the name of the column in the table that will hold the status values. If empty enabled and
  disabled operation wont be performed.","type":"java.lang.String","required":false,"order":10,"confidential":false,"defaultValues":null},"overridable":false,"values":[]},{"schema":{"name":"pwdEncodeToUpperCase","displayName":"Force password encoding to upper case","helpMessage":"Force password encoding to upper case.","type":"boolean","required":false,"order":25,"confidential":false,"defaultValues":null},"overridable":false,"values":["false"]},{"schema":{"name":"enableEmptyString","displayName":"Enable writing empty string","helpMessage":"&lt;b&gt;Enable writing empty string&lt;/b&gt;&lt;br&gt;Select to enable support for writing an empty strings, instead of a NULL value, in character based columns defined as not-null in the table schema. This option does not influence the way strings are written for Oracle based tables. By default empty strings are written as a NULL value.","type":"boolean","required":false,"order":16,"confidential":false,"defaultValues":null},"overridable":false,"
 values":["false"]},{"schema":{"name":"database","displayName":"Database","helpMessage":"&lt;b&gt;Database&lt;/b&gt;&lt;br&gt;Enter the name of the database on the database server that contains the table.","type":"java.lang.String","required":false,"order":6,"confidential":false,"defaultValues":null},"overridable":false,"values":[]},{"schema":{"name":"defaultStatusValue","displayName":"Default Status Value","helpMessage":"&lt;b&gt;Default Status Value&lt;/b&gt;&lt;br&gt;Enter the value for status in case of status not specified.","type":"java.lang.String","required":false,"order":13,"confidential":false,"defaultValues":null},"overridable":false,"values":[]},{"schema":{"name":"table","displayName":"Table","helpMessage":"&lt;b&gt;Table&lt;/b&gt;&lt;br&gt;Enter the name of the table in the database that contains the accounts.","type":"java.lang.String","required":true,"order":7,"confidential":false,"defaultValues":null},"overridable":false,"values":["testsync"]},{"schema":{"name":"disab
 ledStatusValue","displayName":"Disabled Status Value","helpMessage":"&lt;b&gt;Disabled Status Value&lt;/b&gt;&lt;br&gt;Enter the value for disabled status.","type":"java.lang.String","required":false,"order":11,"confidential":false,"defaultValues":null},"overridable":false,"values":[]},{"schema":{"name":"jdbcDriver","displayName":"JDBC Driver","helpMessage":"&lt;b&gt;JDBC Driver&lt;/b&gt;&lt;br&gt;Specify the JDBC Driver class name. Oracle is oracle.jdbc.driver.OracleDriver. MySQL is org.gjt.mm.mysql.Driver.&lt;br&gt;Could be empty if datasource is provided.","type":"java.lang.String","required":false,"order":14,"confidential":false,"defaultValues":null},"overridable":false,"values":["org.h2.Driver"]},{"schema":{"name":"quoting","displayName":"Name Quoting","helpMessage":"&lt;b&gt;Name Quoting&lt;/b&gt;&lt;br&gt;Select whether database column names for this resource should be quoted, and the quoting characters. By default, database column names are not quoted (None). For other selec
 tions (Single, Double, Back, or Brackets), column names will appear between single quotes, double quotes, back quotes, or brackets in the SQL generated to access the database.","type":"java.lang.String","required":false,"order":1,"confidential":false,"defaultValues":null},"overridable":false,"values":[]},{"schema":{"name":"cipherKey","displayName":"Password cipher key","helpMessage":"Specify key in case of reversible algorithm.","type":"java.lang.String","required":false,"order":25,"confidential":false,"defaultValues":null},"overridable":false,"values":[]}]'/>
+  <ConnInstance_capabilities ConnInstance_id="107" capability="ONE_PHASE_CREATE"/>
+  <ConnInstance_capabilities ConnInstance_id="107" capability="TWO_PHASES_CREATE"/>
+  <ConnInstance_capabilities ConnInstance_id="107" capability="ONE_PHASE_UPDATE"/>
+  <ConnInstance_capabilities ConnInstance_id="107" capability="TWO_PHASES_UPDATE"/>
+  <ConnInstance_capabilities ConnInstance_id="107" capability="ONE_PHASE_DELETE"/>
+  <ConnInstance_capabilities ConnInstance_id="107" capability="TWO_PHASES_DELETE"/>
+  <ConnInstance_capabilities ConnInstance_id="107" capability="SEARCH"/>
+  
+  <ConnInstance id="108" bundleName="net.tirasa.connid.bundles.db.scriptedsql" 
+                location="connid://${testconnectorserver.key}@localhost:${testconnectorserver.port}"
+                connectorName="net.tirasa.connid.bundles.db.scriptedsql.ScriptedSQLConnector"
+                displayName="Scripted SQL" version="${connid.database.version}"
+                jsonConf='[{&quot;schema&quot;:{&quot;name&quot;:&quot;updateScriptFileName&quot;,&quot;displayName&quot;:&quot;updateScriptFileName&quot;,&quot;helpMessage&quot;:&quot;updateScriptFileName&quot;,&quot;type&quot;:&quot;java.lang.String&quot;,&quot;required&quot;:false,&quot;order&quot;:0,&quot;confidential&quot;:false,&quot;defaultValues&quot;:[]},&quot;overridable&quot;:false,&quot;values&quot;:[&quot;${basedir}/src/main/resources/scriptedsql/UpdateScript.groovy&quot;]},{&quot;schema&quot;:{&quot;name&quot;:&quot;testScript&quot;,&quot;displayName&quot;:&quot;testScript&quot;,&quot;helpMessage&quot;:&quot;testScript&quot;,&quot;type&quot;:&quot;java.lang.String&quot;,&quot;required&quot;:false,&quot;order&quot;:0,&quot;confidential&quot;:false,&quot;defaultValues&quot;:[&quot;&quot;]},&quot;overridable&quot;:false,&quot;values&quot;:[]},{&quot;schema&quot;:{&quot;name&quot;:&quot;host&quot;,&quot;displayName&quot;:&quot;Host&quot;,&quot;helpMessage&quot;:&quot;&lt;b
 &gt;Host&lt;/b&gt;&lt;br/&gt;Enter the name of the host where the database is running.&quot;,&quot;type&quot;:&quot;java.lang.String&quot;,&quot;required&quot;:false,&quot;order&quot;:2,&quot;confidential&quot;:false,&quot;defaultValues&quot;:[&quot;localhost&quot;]},&quot;overridable&quot;:false},{&quot;schema&quot;:{&quot;name&quot;:&quot;port&quot;,&quot;displayName&quot;:&quot;Port&quot;,&quot;helpMessage&quot;:&quot;&lt;b&gt;TCP Port&lt;/b&gt;&lt;br/&gt;Enter the port number the database server is listening on.&quot;,&quot;type&quot;:&quot;java.lang.String&quot;,&quot;required&quot;:false,&quot;order&quot;:3,&quot;confidential&quot;:false,&quot;defaultValues&quot;:[&quot;3306&quot;]},&quot;overridable&quot;:false},{&quot;schema&quot;:{&quot;name&quot;:&quot;database&quot;,&quot;displayName&quot;:&quot;Database&quot;,&quot;helpMessage&quot;:&quot;&lt;b&gt;Database&lt;/b&gt;&lt;br/&gt;Enter the name of the database on the database server that contains the table.&quot;,&quot;type&
 quot;:&quot;java.lang.String&quot;,&quot;required&quot;:false,&quot;order&quot;:6,&quot;confidential&quot;:false,&quot;defaultValues&quot;:[&quot;&quot;]},&quot;overridable&quot;:false},{&quot;schema&quot;:{&quot;name&quot;:&quot;createScript&quot;,&quot;displayName&quot;:&quot;createScript&quot;,&quot;helpMessage&quot;:&quot;createScript&quot;,&quot;type&quot;:&quot;java.lang.String&quot;,&quot;required&quot;:false,&quot;order&quot;:0,&quot;confidential&quot;:false,&quot;defaultValues&quot;:[&quot;&quot;]},&quot;overridable&quot;:false,&quot;values&quot;:[]},{&quot;schema&quot;:{&quot;name&quot;:&quot;jdbcUrlTemplate&quot;,&quot;displayName&quot;:&quot;JDBC Connection URL&quot;,&quot;helpMessage&quot;:&quot;&lt;b&gt;JDBC Connection URL&lt;/b&gt;&lt;br/&gt;Specify the JDBC Driver Connection URL.&lt;br/&gt; Oracle template is jdbc:oracle:thin:@[host]:[port(1521)]:[DB].&lt;br/&gt;  MySQL template is jdbc:mysql://[host]:[port(3306)]/[db], for more info, read the JDBC driver documentati
 on.&lt;br/&gt;Could be empty if datasource is provided.&quot;,&quot;type&quot;:&quot;java.lang.String&quot;,&quot;required&quot;:false,&quot;order&quot;:11,&quot;confidential&quot;:false,&quot;defaultValues&quot;:[&quot;jdbc:mysql://%h:%p/%d&quot;]},&quot;overridable&quot;:false,&quot;values&quot;:[&quot;${testdb.url}&quot;]},{&quot;schema&quot;:{&quot;name&quot;:&quot;jndiProperties&quot;,&quot;displayName&quot;:&quot;Initial JNDI Properties&quot;,&quot;helpMessage&quot;:&quot;&lt;b&gt;Initial JNDI Properties&lt;/b&gt;&lt;br/&gt;Could be empty or enter the JDBC JNDI Initial context factory, context provider in a format: key = value.&quot;,&quot;type&quot;:&quot;[Ljava.lang.String;&quot;,&quot;required&quot;:false,&quot;order&quot;:21,&quot;confidential&quot;:false,&quot;defaultValues&quot;:[]},&quot;overridable&quot;:false,&quot;values&quot;:[]},{&quot;schema&quot;:{&quot;name&quot;:&quot;enableEmptyString&quot;,&quot;displayName&quot;:&quot;Enable writing empty string&quot;,&quot;
 helpMessage&quot;:&quot;&lt;b&gt;Enable writing empty string&lt;/b&gt;&lt;br/&gt;Select to enable support for writing an empty strings, instead of a NULL value, in character based columns defined as not-null in the table schema. This option does not influence the way strings are written for Oracle based tables. By default empty strings are written as a NULL value.&quot;,&quot;type&quot;:&quot;boolean&quot;,&quot;required&quot;:false,&quot;order&quot;:12,&quot;confidential&quot;:false,&quot;defaultValues&quot;:[false]},&quot;overridable&quot;:false,&quot;values&quot;:[&quot;false&quot;]},{&quot;schema&quot;:{&quot;name&quot;:&quot;allNative&quot;,&quot;displayName&quot;:&quot;All native&quot;,&quot;helpMessage&quot;:&quot;&lt;b&gt;All native&lt;/b&gt;&lt;br/&gt;Select to retrieve all data type of the columns in a native format from the database table.&quot;,&quot;type&quot;:&quot;boolean&quot;,&quot;required&quot;:false,&quot;order&quot;:16,&quot;confidential&quot;:false,&quot;defaul
 tValues&quot;:[false]},&quot;overridable&quot;:false,&quot;values&quot;:[false]},{&quot;schema&quot;:{&quot;name&quot;:&quot;password&quot;,&quot;displayName&quot;:&quot;User Password&quot;,&quot;helpMessage&quot;:&quot;&lt;b&gt;User Password&lt;/b&gt;&lt;br/&gt;Enter a user account that has permission to access accounts table.&quot;,&quot;type&quot;:&quot;org.identityconnectors.common.security.GuardedString&quot;,&quot;required&quot;:false,&quot;order&quot;:5,&quot;confidential&quot;:true,&quot;defaultValues&quot;:[]},&quot;overridable&quot;:false,&quot;values&quot;:[&quot;${testdb.password}&quot;]},{&quot;schema&quot;:{&quot;name&quot;:&quot;validConnectionQuery&quot;,&quot;displayName&quot;:&quot;Validate Connection Query&quot;,&quot;helpMessage&quot;:&quot;&lt;b&gt;Validate Connection Query&lt;/b&gt;&lt;br/&gt;There can be specified the check connection alive query. If empty, default implementation will test it using the switch on/off the autocommit. Some select 1 from dummy tab
 le could be more efficient.&quot;,&quot;type&quot;:&quot;java.lang.String&quot;,&quot;required&quot;:false,&quot;order&quot;:17,&quot;confidential&quot;:false,&quot;defaultValues&quot;:[]},&quot;overridable&quot;:false,&quot;values&quot;:[]},{&quot;schema&quot;:{&quot;name&quot;:&quot;reloadScriptOnExecution&quot;,&quot;displayName&quot;:&quot;reloadScriptOnExecution&quot;,&quot;helpMessage&quot;:&quot;reloadScriptOnExecution&quot;,&quot;type&quot;:&quot;boolean&quot;,&quot;required&quot;:false,&quot;order&quot;:0,&quot;confidential&quot;:false,&quot;defaultValues&quot;:[false]},&quot;overridable&quot;:false,&quot;values&quot;:[&quot;true&quot;]},{&quot;schema&quot;:{&quot;name&quot;:&quot;schemaScriptFileName&quot;,&quot;displayName&quot;:&quot;schemaScriptFileName&quot;,&quot;helpMessage&quot;:&quot;schemaScriptFileName&quot;,&quot;type&quot;:&quot;java.lang.String&quot;,&quot;required&quot;:false,&quot;order&quot;:0,&quot;confidential&quot;:false,&quot;defaultValues&quot;:[]},&qu
 ot;overridable&quot;:true,&quot;values&quot;:[&quot;${basedir}/src/main/resources/scriptedsql/SchemaScript.groovy&quot;]},{&quot;schema&quot;:{&quot;name&quot;:&quot;jdbcDriver&quot;,&quot;displayName&quot;:&quot;JDBC Driver&quot;,&quot;helpMessage&quot;:&quot;&lt;b&gt;JDBC Driver&lt;/b&gt;&lt;br/&gt;Specify the JDBC Driver class name. Oracle is oracle.jdbc.driver.OracleDriver. MySQL is org.gjt.mm.mysql.Driver.&lt;br/&gt;Could be empty if datasource is provided.&quot;,&quot;type&quot;:&quot;java.lang.String&quot;,&quot;required&quot;:false,&quot;order&quot;:10,&quot;confidential&quot;:false,&quot;defaultValues&quot;:[&quot;com.mysql.jdbc.Driver&quot;]},&quot;overridable&quot;:false,&quot;values&quot;:[&quot;${testdb.driver}&quot;]},{&quot;schema&quot;:{&quot;name&quot;:&quot;testScriptFileName&quot;,&quot;displayName&quot;:&quot;testScriptFileName&quot;,&quot;helpMessage&quot;:&quot;testScriptFileName&quot;,&quot;type&quot;:&quot;java.lang.String&quot;,&quot;required&quot;:false,&qu
 ot;order&quot;:0,&quot;confidential&quot;:false,&quot;defaultValues&quot;:[]},&quot;overridable&quot;:true,&quot;values&quot;:[&quot;${basedir}/src/main/resources/scriptedsql/TestScript.groovy&quot;]},{&quot;schema&quot;:{&quot;name&quot;:&quot;quoting&quot;,&quot;displayName&quot;:&quot;Name Quoting&quot;,&quot;helpMessage&quot;:&quot;&lt;b&gt;Name Quoting&lt;/b&gt;&lt;br/&gt;Select whether database column names for this resource should be quoted, and the quoting characters. By default, database column names are not quoted (None). For other selections (Single, Double, Back, or Brackets), column names will appear between single quotes, double quotes, back quotes, or brackets in the SQL generated to access the database.&quot;,&quot;type&quot;:&quot;java.lang.String&quot;,&quot;required&quot;:false,&quot;order&quot;:-1,&quot;confidential&quot;:false,&quot;defaultValues&quot;:[&quot;&quot;]},&quot;overridable&quot;:false,&quot;values&quot;:[]},{&quot;schema&quot;:{&quot;name&quot;:&quo
 t;createScriptFileName&quot;,&quot;displayName&quot;:&quot;createScriptFileName&quot;,&quot;helpMessage&quot;:&quot;createScriptFileName&quot;,&quot;type&quot;:&quot;java.lang.String&quot;,&quot;required&quot;:false,&quot;order&quot;:0,&quot;confidential&quot;:false,&quot;defaultValues&quot;:[]},&quot;overridable&quot;:false,&quot;values&quot;:[&quot;${basedir}/src/main/resources/scriptedsql/CreateScript.groovy&quot;]},{&quot;schema&quot;:{&quot;name&quot;:&quot;clearTextPasswordToScript&quot;,&quot;displayName&quot;:&quot;clearTextPasswordToScript&quot;,&quot;helpMessage&quot;:&quot;clearTextPasswordToScript&quot;,&quot;type&quot;:&quot;boolean&quot;,&quot;required&quot;:false,&quot;order&quot;:0,&quot;confidential&quot;:false,&quot;defaultValues&quot;:[true]},&quot;overridable&quot;:false,&quot;values&quot;:[&quot;false&quot;]},{&quot;schema&quot;:{&quot;name&quot;:&quot;nativeTimestamps&quot;,&quot;displayName&quot;:&quot;Native Timestamps&quot;,&quot;helpMessage&quot;:&quot;&lt;
 b&gt;Native Timestamps&lt;/b&gt;&lt;br/&gt;Select to retrieve Timestamp data type of the columns in java.sql.Timestamp format from the database table.&quot;,&quot;type&quot;:&quot;boolean&quot;,&quot;required&quot;:false,&quot;order&quot;:15,&quot;confidential&quot;:false,&quot;defaultValues&quot;:[false]},&quot;overridable&quot;:false,&quot;values&quot;:[false]},{&quot;schema&quot;:{&quot;name&quot;:&quot;syncScript&quot;,&quot;displayName&quot;:&quot;syncScript&quot;,&quot;helpMessage&quot;:&quot;syncScript&quot;,&quot;type&quot;:&quot;java.lang.String&quot;,&quot;required&quot;:false,&quot;order&quot;:0,&quot;confidential&quot;:false,&quot;defaultValues&quot;:[&quot;&quot;]},&quot;overridable&quot;:false,&quot;values&quot;:[]},{&quot;schema&quot;:{&quot;name&quot;:&quot;autoCommit&quot;,&quot;displayName&quot;:&quot;autoCommit&quot;,&quot;helpMessage&quot;:&quot;autoCommit&quot;,&quot;type&quot;:&quot;boolean&quot;,&quot;required&quot;:false,&quot;order&quot;:0,&quot;confidential
 &quot;:false,&quot;defaultValues&quot;:[true]},&quot;overridable&quot;:false,&quot;values&quot;:[true]},{&quot;schema&quot;:{&quot;name&quot;:&quot;scriptingLanguage&quot;,&quot;displayName&quot;:&quot;scriptingLanguage&quot;,&quot;helpMessage&quot;:&quot;scriptingLanguage&quot;,&quot;type&quot;:&quot;java.lang.String&quot;,&quot;required&quot;:false,&quot;order&quot;:0,&quot;confidential&quot;:false,&quot;defaultValues&quot;:[&quot;GROOVY&quot;]},&quot;overridable&quot;:false,&quot;values&quot;:[&quot;GROOVY&quot;]},{&quot;schema&quot;:{&quot;name&quot;:&quot;datasource&quot;,&quot;displayName&quot;:&quot;Datasource Path&quot;,&quot;helpMessage&quot;:&quot;&lt;b&gt;JDBC Data Source Name/Path&lt;/b&gt;&lt;br/&gt;Enter the JDBC Data Source Name/Path to connect to the Oracle server. If specified, connector will only try to connect using Datasource and ignore other resource parameters specified.&lt;br/&gt;the example value is: &lt;CODE&gt;jdbc/SampleDataSourceName&lt;/CODE&gt;&quot;,&q
 uot;type&quot;:&quot;java.lang.String&quot;,&quot;required&quot;:false,&quot;order&quot;:20,&quot;confidential&quot;:false,&quot;defaultValues&quot;:[&quot;&quot;]},&quot;overridable&quot;:false,&quot;values&quot;:[]},{&quot;schema&quot;:{&quot;name&quot;:&quot;deleteScript&quot;,&quot;displayName&quot;:&quot;deleteScript&quot;,&quot;helpMessage&quot;:&quot;deleteScript&quot;,&quot;type&quot;:&quot;java.lang.String&quot;,&quot;required&quot;:false,&quot;order&quot;:0,&quot;confidential&quot;:false,&quot;defaultValues&quot;:[&quot;&quot;]},&quot;overridable&quot;:false,&quot;values&quot;:[]},{&quot;schema&quot;:{&quot;name&quot;:&quot;rethrowAllSQLExceptions&quot;,&quot;displayName&quot;:&quot;Rethrow all SQLExceptions&quot;,&quot;helpMessage&quot;:&quot;If this is not checked, SQL statements which throw SQLExceptions with a 0 ErrorCode will be have the exception caught and suppressed. Check it to have exceptions with 0 ErrorCodes rethrown.&quot;,&quot;type&quot;:&quot;boolean&quot;,
 &quot;required&quot;:false,&quot;order&quot;:14,&quot;confidential&quot;:false,&quot;defaultValues&quot;:[true]},&quot;overridable&quot;:false,&quot;values&quot;:[true]},{&quot;schema&quot;:{&quot;name&quot;:&quot;syncScriptFileName&quot;,&quot;displayName&quot;:&quot;syncScriptFileName&quot;,&quot;helpMessage&quot;:&quot;syncScriptFileName&quot;,&quot;type&quot;:&quot;java.lang.String&quot;,&quot;required&quot;:false,&quot;order&quot;:0,&quot;confidential&quot;:false,&quot;defaultValues&quot;:[]},&quot;overridable&quot;:true,&quot;values&quot;:[&quot;${basedir}/src/main/resources/scriptedsql/SyncScript.groovy&quot;]},{&quot;schema&quot;:{&quot;name&quot;:&quot;updateScript&quot;,&quot;displayName&quot;:&quot;updateScript&quot;,&quot;helpMessage&quot;:&quot;updateScript&quot;,&quot;type&quot;:&quot;java.lang.String&quot;,&quot;required&quot;:false,&quot;order&quot;:0,&quot;confidential&quot;:false,&quot;defaultValues&quot;:[&quot;&quot;]},&quot;overridable&quot;:false,&quot;values&q
 uot;:[]},{&quot;schema&quot;:{&quot;name&quot;:&quot;user&quot;,&quot;displayName&quot;:&quot;User&quot;,&quot;helpMessage&quot;:&quot;&lt;b&gt;User&lt;/b&gt;&lt;br/&gt;Enter the name of the mandatory Database user with permission to account table.&quot;,&quot;type&quot;:&quot;java.lang.String&quot;,&quot;required&quot;:false,&quot;order&quot;:4,&quot;confidential&quot;:false,&quot;defaultValues&quot;:[&quot;&quot;]},&quot;overridable&quot;:false,&quot;values&quot;:[&quot;${testdb.username}&quot;]},{&quot;schema&quot;:{&quot;name&quot;:&quot;deleteScriptFileName&quot;,&quot;displayName&quot;:&quot;deleteScriptFileName&quot;,&quot;helpMessage&quot;:&quot;deleteScriptFileName&quot;,&quot;type&quot;:&quot;java.lang.String&quot;,&quot;required&quot;:false,&quot;order&quot;:0,&quot;confidential&quot;:false,&quot;defaultValues&quot;:[]},&quot;overridable&quot;:false,&quot;values&quot;:[&quot;${basedir}/src/main/resources/scriptedsql/DeleteScript.groovy&quot;]},{&quot;schema&quot;:{&quot;n
 ame&quot;:&quot;searchScriptFileName&quot;,&quot;displayName&quot;:&quot;searchScriptFileName&quot;,&quot;helpMessage&quot;:&quot;searchScriptFileName&quot;,&quot;type&quot;:&quot;java.lang.String&quot;,&quot;required&quot;:false,&quot;order&quot;:0,&quot;confidential&quot;:false,&quot;defaultValues&quot;:[]},&quot;overridable&quot

<TRUNCATED>

[07/31] syncope git commit: [SYNCOPE-652] Still several things to refine, but it starts taking shape

Posted by md...@apache.org.
http://git-wip-us.apache.org/repos/asf/syncope/blob/6dfedd8f/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/SyncTaskITCase.java
----------------------------------------------------------------------
diff --git a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/SyncTaskITCase.java b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/SyncTaskITCase.java
index f6d2e57..9f277fa 100644
--- a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/SyncTaskITCase.java
+++ b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/SyncTaskITCase.java
@@ -126,7 +126,7 @@ public class SyncTaskITCase extends AbstractTaskITCase {
         task = taskService.read(actual.getKey());
         assertNotNull(task);
         assertEquals(actual.getKey(), task.getKey());
-        assertEquals(actual.getJobClassName(), task.getJobClassName());
+        assertEquals(actual.getJobDelegateClassName(), task.getJobDelegateClassName());
         assertEquals(userTemplate, task.getTemplates().get(AnyTypeKind.USER.name()));
         assertEquals(groupTemplate, task.getTemplates().get(AnyTypeKind.GROUP.name()));
     }
@@ -231,14 +231,11 @@ public class SyncTaskITCase extends AbstractTaskITCase {
             assertNotNull(userTO);
             assertEquals("active", userTO.getStatus());
 
-            // SYNCOPE-317
-            execProvisioningTask(SYNC_TASK_ID, 50, false);
-
-            final Set<Long> pushTaskIds = new HashSet<>();
-            pushTaskIds.add(25L);
-            pushTaskIds.add(26L);
+            Set<Long> otherSyncTaskKeys = new HashSet<>();
+            otherSyncTaskKeys.add(25L);
+            otherSyncTaskKeys.add(26L);
+            execProvisioningTasks(otherSyncTaskKeys, 50, false);
 
-            execProvisioningTasks(pushTaskIds, 50, false);
             // Matching --> UNLINK
             assertFalse(readUser("test9").getResources().contains(RESOURCE_NAME_CSV));
             assertFalse(readUser("test7").getResources().contains(RESOURCE_NAME_CSV));
@@ -290,7 +287,7 @@ public class SyncTaskITCase extends AbstractTaskITCase {
                 build());
         if (matchingGroups.getSize() > 0) {
             for (GroupTO group : matchingGroups.getResult()) {
-                groupService.bulkDeassociation(group.getKey(),
+                groupService.deassociate(group.getKey(),
                         ResourceDeassociationActionType.UNLINK,
                         CollectionWrapper.wrap(RESOURCE_NAME_LDAP, ResourceKey.class));
                 groupService.delete(group.getKey());
@@ -302,7 +299,7 @@ public class SyncTaskITCase extends AbstractTaskITCase {
                 build());
         if (matchingUsers.getSize() > 0) {
             for (UserTO user : matchingUsers.getResult()) {
-                userService.bulkDeassociation(user.getKey(),
+                userService.deassociate(user.getKey(),
                         ResourceDeassociationActionType.UNLINK,
                         CollectionWrapper.wrap(RESOURCE_NAME_LDAP, ResourceKey.class));
                 userService.delete(user.getKey());
@@ -352,6 +349,9 @@ public class SyncTaskITCase extends AbstractTaskITCase {
         assertEquals("true", groupTO.getPlainAttrMap().get("show").getValues().get(0));
         assertEquals(matchingUsers.getResult().iterator().next().getKey(), groupTO.getUserOwner(), 0);
         assertNull(groupTO.getGroupOwner());
+
+        // SYNCOPE-317
+        execProvisioningTask(11L, 50, false);
     }
 
     @Test
@@ -376,7 +376,7 @@ public class SyncTaskITCase extends AbstractTaskITCase {
                         is("location").equalTo("sync*").query()).build());
         assertTrue(matchingPrinters.getSize() > 0);
         for (AnyObjectTO printer : matchingPrinters.getResult()) {
-            anyObjectService.bulkDeassociation(printer.getKey(),
+            anyObjectService.deassociate(printer.getKey(),
                     ResourceDeassociationActionType.UNLINK,
                     CollectionWrapper.wrap(RESOURCE_NAME_DBSCRIPTED, ResourceKey.class));
             anyObjectService.delete(printer.getKey());
@@ -678,7 +678,7 @@ public class SyncTaskITCase extends AbstractTaskITCase {
         syncTask = taskService.read(actual.getKey());
         assertNotNull(syncTask);
         assertEquals(actual.getKey(), syncTask.getKey());
-        assertEquals(actual.getJobClassName(), syncTask.getJobClassName());
+        assertEquals(actual.getJobDelegateClassName(), syncTask.getJobDelegateClassName());
 
         TaskExecTO execution = execProvisioningTask(syncTask.getKey(), 50, false);
         final String status = execution.getStatus();
@@ -755,7 +755,7 @@ public class SyncTaskITCase extends AbstractTaskITCase {
         syncTask = taskService.read(actual.getKey());
         assertNotNull(syncTask);
         assertEquals(actual.getKey(), syncTask.getKey());
-        assertEquals(actual.getJobClassName(), syncTask.getJobClassName());
+        assertEquals(actual.getJobDelegateClassName(), syncTask.getJobDelegateClassName());
 
         TaskExecTO execution = execProvisioningTask(syncTask.getKey(), 50, false);
         String status = execution.getStatus();

http://git-wip-us.apache.org/repos/asf/syncope/blob/6dfedd8f/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/UserITCase.java
----------------------------------------------------------------------
diff --git a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/UserITCase.java b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/UserITCase.java
index 10b07bf..4cecdf7 100644
--- a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/UserITCase.java
+++ b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/UserITCase.java
@@ -47,7 +47,6 @@ import org.apache.syncope.client.lib.SyncopeClient;
 import org.apache.syncope.common.lib.AnyOperations;
 import org.apache.syncope.common.lib.SyncopeClientException;
 import org.apache.syncope.common.lib.SyncopeConstants;
-import org.apache.syncope.common.lib.mod.AttrMod;
 import org.apache.syncope.common.lib.mod.ResourceAssociationMod;
 import org.apache.syncope.common.lib.mod.StatusMod;
 import org.apache.syncope.common.lib.mod.UserMod;
@@ -70,7 +69,7 @@ import org.apache.syncope.common.lib.types.CipherAlgorithm;
 import org.apache.syncope.common.lib.types.ClientExceptionType;
 import org.apache.syncope.common.lib.types.MappingPurpose;
 import org.apache.syncope.common.lib.types.PropagationTaskExecStatus;
-import org.apache.syncope.common.lib.types.ResourceAssociationActionType;
+import org.apache.syncope.common.lib.types.ResourceAssociationAction;
 import org.apache.syncope.common.lib.types.ResourceDeassociationActionType;
 import org.apache.syncope.common.lib.types.TaskType;
 import org.apache.syncope.common.lib.wrap.ResourceKey;
@@ -436,7 +435,7 @@ public class UserITCase extends AbstractITCase {
             createUser(userTO);
             fail();
         } catch (SyncopeClientException e) {
-            assertEquals(ClientExceptionType.DataIntegrityViolation, e.getType());
+            assertEquals(ClientExceptionType.GenericPersistence, e.getType());
         }
     }
 
@@ -923,8 +922,9 @@ public class UserITCase extends AbstractITCase {
         assertTrue(getBooleanAttribute(connObjectTO, OperationalAttributes.ENABLE_NAME));
     }
 
+    @Test
     public void updateMultivalueAttribute() {
-        UserTO userTO = getSampleTO("multivalue@syncope.apache.org");
+        UserTO userTO = getUniqueSampleTO("multivalue@syncope.apache.org");
         userTO.getResources().clear();
         userTO.getDerAttrs().clear();
         userTO.getVirAttrs().clear();
@@ -938,11 +938,8 @@ public class UserITCase extends AbstractITCase {
 
         UserMod userMod = new UserMod();
 
-        AttrMod loginDateMod = new AttrMod();
-        loginDateMod.getValuesToBeAdded().add("2000-01-01");
-
         userMod.setKey(userTO.getKey());
-        userMod.getPlainAttrsToUpdate().add(loginDateMod);
+        userMod.getPlainAttrsToUpdate().add(attrMod("loginDate", "2000-01-01"));
 
         userTO = updateUser(userMod);
         assertNotNull(userTO);
@@ -1519,18 +1516,15 @@ public class UserITCase extends AbstractITCase {
 
     @Test
     public void issueSYNCOPE265() {
-        for (long i = 1; i <= 5; i++) {
+        for (long key = 1; key <= 5; key++) {
             UserMod userMod = new UserMod();
-            userMod.setKey(i);
-
-            AttrMod attributeMod = new AttrMod();
-            attributeMod.setSchema("type");
-            attributeMod.getValuesToBeAdded().add("a type");
+            userMod.setKey(key);
 
             userMod.getPlainAttrsToRemove().add("type");
-            userMod.getPlainAttrsToUpdate().add(attributeMod);
+            userMod.getPlainAttrsToUpdate().add(attrMod("type", "a type"));
 
             UserTO userTO = updateUser(userMod);
+
             assertEquals("a type", userTO.getPlainAttrMap().get("type").getValues().get(0));
         }
     }
@@ -1549,21 +1543,21 @@ public class UserITCase extends AbstractITCase {
 
         assertEquals(11, bulkAction.getTargets().size());
 
-        bulkAction.setOperation(BulkAction.Type.SUSPEND);
+        bulkAction.setType(BulkAction.Type.SUSPEND);
         BulkActionResult res = userService.bulk(bulkAction);
         assertEquals(10, res.getResultByStatus(Status.SUCCESS).size());
         assertEquals(1, res.getResultByStatus(Status.FAILURE).size());
         assertEquals("suspended", userService.read(
                 Long.parseLong(res.getResultByStatus(Status.SUCCESS).get(3))).getStatus());
 
-        bulkAction.setOperation(BulkAction.Type.REACTIVATE);
+        bulkAction.setType(BulkAction.Type.REACTIVATE);
         res = userService.bulk(bulkAction);
         assertEquals(10, res.getResultByStatus(Status.SUCCESS).size());
         assertEquals(1, res.getResultByStatus(Status.FAILURE).size());
         assertEquals("active", userService.read(
                 Long.parseLong(res.getResultByStatus(Status.SUCCESS).get(3))).getStatus());
 
-        bulkAction.setOperation(BulkAction.Type.DELETE);
+        bulkAction.setType(BulkAction.Type.DELETE);
         res = userService.bulk(bulkAction);
         assertEquals(10, res.getResultByStatus(Status.SUCCESS).size());
         assertEquals(1, res.getResultByStatus(Status.FAILURE).size());
@@ -1765,7 +1759,7 @@ public class UserITCase extends AbstractITCase {
         assertNotNull(actual);
         assertNotNull(resourceService.readConnObject(RESOURCE_NAME_CSV, AnyTypeKind.USER.name(), actual.getKey()));
 
-        assertNotNull(userService.bulkDeassociation(actual.getKey(),
+        assertNotNull(userService.deassociate(actual.getKey(),
                 ResourceDeassociationActionType.UNLINK,
                 CollectionWrapper.wrap(RESOURCE_NAME_CSV, ResourceKey.class)).
                 readEntity(BulkActionResult.class));
@@ -1801,8 +1795,7 @@ public class UserITCase extends AbstractITCase {
         final ResourceAssociationMod associationMod = new ResourceAssociationMod();
         associationMod.getTargetResources().addAll(CollectionWrapper.wrap(RESOURCE_NAME_CSV, ResourceKey.class));
 
-        assertNotNull(userService.bulkAssociation(
-                actual.getKey(), ResourceAssociationActionType.LINK, associationMod).readEntity(BulkActionResult.class));
+        assertNotNull(userService.associate(actual.getKey(), ResourceAssociationAction.LINK, associationMod).readEntity(BulkActionResult.class));
 
         actual = userService.read(actual.getKey());
         assertNotNull(actual);
@@ -1831,7 +1824,7 @@ public class UserITCase extends AbstractITCase {
         assertNotNull(actual);
         assertNotNull(resourceService.readConnObject(RESOURCE_NAME_CSV, AnyTypeKind.USER.name(), actual.getKey()));
 
-        assertNotNull(userService.bulkDeassociation(actual.getKey(),
+        assertNotNull(userService.deassociate(actual.getKey(),
                 ResourceDeassociationActionType.UNASSIGN,
                 CollectionWrapper.wrap(RESOURCE_NAME_CSV, ResourceKey.class)).
                 readEntity(BulkActionResult.class));
@@ -1869,12 +1862,12 @@ public class UserITCase extends AbstractITCase {
             assertNotNull(e);
         }
 
-        final ResourceAssociationMod associationMod = new ResourceAssociationMod();
+        ResourceAssociationMod associationMod = new ResourceAssociationMod();
         associationMod.getTargetResources().addAll(CollectionWrapper.wrap(RESOURCE_NAME_CSV, ResourceKey.class));
         associationMod.setChangePwd(true);
         associationMod.setPassword("password");
 
-        assertNotNull(userService.bulkAssociation(actual.getKey(), ResourceAssociationActionType.ASSIGN, associationMod)
+        assertNotNull(userService.associate(actual.getKey(), ResourceAssociationAction.ASSIGN, associationMod)
                 .readEntity(BulkActionResult.class));
 
         actual = userService.read(actual.getKey());
@@ -1898,7 +1891,7 @@ public class UserITCase extends AbstractITCase {
         assertNotNull(actual);
         assertNotNull(resourceService.readConnObject(RESOURCE_NAME_CSV, AnyTypeKind.USER.name(), actual.getKey()));
 
-        assertNotNull(userService.bulkDeassociation(actual.getKey(),
+        assertNotNull(userService.deassociate(actual.getKey(),
                 ResourceDeassociationActionType.DEPROVISION,
                 CollectionWrapper.wrap(RESOURCE_NAME_CSV, ResourceKey.class)).
                 readEntity(BulkActionResult.class));
@@ -1936,14 +1929,13 @@ public class UserITCase extends AbstractITCase {
             assertNotNull(e);
         }
 
-        final ResourceAssociationMod associationMod = new ResourceAssociationMod();
+        ResourceAssociationMod associationMod = new ResourceAssociationMod();
         associationMod.getTargetResources().addAll(CollectionWrapper.wrap(RESOURCE_NAME_CSV, ResourceKey.class));
         associationMod.setChangePwd(true);
         associationMod.setPassword("password");
 
-        assertNotNull(userService.bulkAssociation(actual.getKey(), ResourceAssociationActionType.PROVISION,
-                associationMod)
-                .readEntity(BulkActionResult.class));
+        assertNotNull(userService.associate(actual.getKey(), ResourceAssociationAction.PROVISION, associationMod).
+                readEntity(BulkActionResult.class));
 
         actual = userService.read(actual.getKey());
         assertNotNull(actual);
@@ -1977,7 +1969,7 @@ public class UserITCase extends AbstractITCase {
         associationMod.setChangePwd(true);
         associationMod.setPassword("password");
 
-        assertNotNull(userService.bulkAssociation(actual.getKey(), ResourceAssociationActionType.PROVISION,
+        assertNotNull(userService.associate(actual.getKey(), ResourceAssociationAction.PROVISION,
                 associationMod)
                 .readEntity(BulkActionResult.class));
 
@@ -1986,7 +1978,7 @@ public class UserITCase extends AbstractITCase {
         assertTrue(actual.getResources().isEmpty());
         assertNotNull(resourceService.readConnObject(RESOURCE_NAME_CSV, AnyTypeKind.USER.name(), actual.getKey()));
 
-        assertNotNull(userService.bulkDeassociation(actual.getKey(),
+        assertNotNull(userService.deassociate(actual.getKey(),
                 ResourceDeassociationActionType.DEPROVISION,
                 CollectionWrapper.wrap(RESOURCE_NAME_CSV, ResourceKey.class)).
                 readEntity(BulkActionResult.class));


[18/31] syncope git commit: [SYNCOPE-652] Still several things to refine, but it starts taking shape

Posted by md...@apache.org.
http://git-wip-us.apache.org/repos/asf/syncope/blob/6dfedd8f/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAReportDAO.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAReportDAO.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAReportDAO.java
index 793411d..6de5ffb 100644
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAReportDAO.java
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAReportDAO.java
@@ -32,12 +32,13 @@ import org.springframework.transaction.annotation.Transactional;
 @Repository
 public class JPAReportDAO extends AbstractDAO<Report, Long> implements ReportDAO {
 
-    @Override
     @Transactional(readOnly = true)
+    @Override
     public Report find(final Long key) {
-        return entityManager.find(JPAReport.class, key);
+        return entityManager().find(JPAReport.class, key);
     }
 
+    @Transactional(readOnly = true)
     @Override
     public List<Report> findAll() {
         return findAll(-1, -1, Collections.<OrderByClause>emptyList());
@@ -45,7 +46,7 @@ public class JPAReportDAO extends AbstractDAO<Report, Long> implements ReportDAO
 
     @Override
     public List<Report> findAll(final int page, final int itemsPerPage, final List<OrderByClause> orderByClauses) {
-        final TypedQuery<Report> query = entityManager.createQuery(
+        final TypedQuery<Report> query = entityManager().createQuery(
                 "SELECT e FROM " + JPAReport.class.getSimpleName() + " e "
                 + toOrderByStatement(Report.class, "e", orderByClauses), Report.class);
 
@@ -62,14 +63,14 @@ public class JPAReportDAO extends AbstractDAO<Report, Long> implements ReportDAO
 
     @Override
     public int count() {
-        Query countQuery = entityManager.createNativeQuery("SELECT COUNT(id) FROM " + JPAReport.TABLE);
+        Query countQuery = entityManager().createNativeQuery("SELECT COUNT(id) FROM " + JPAReport.TABLE);
         return ((Number) countQuery.getSingleResult()).intValue();
     }
 
     @Override
     @Transactional(rollbackFor = Throwable.class)
     public Report save(final Report report) {
-        return entityManager.merge(report);
+        return entityManager().merge(report);
     }
 
     @Override
@@ -84,6 +85,6 @@ public class JPAReportDAO extends AbstractDAO<Report, Long> implements ReportDAO
 
     @Override
     public void delete(final Report report) {
-        entityManager.remove(report);
+        entityManager().remove(report);
     }
 }

http://git-wip-us.apache.org/repos/asf/syncope/blob/6dfedd8f/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAReportExecDAO.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAReportExecDAO.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAReportExecDAO.java
index 95f57df..cf9e781 100644
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAReportExecDAO.java
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAReportExecDAO.java
@@ -32,11 +32,11 @@ public class JPAReportExecDAO extends AbstractDAO<ReportExec, Long> implements R
 
     @Override
     public ReportExec find(final Long key) {
-        return entityManager.find(JPAReportExec.class, key);
+        return entityManager().find(JPAReportExec.class, key);
     }
 
     private ReportExec findLatest(final Report report, final String field) {
-        TypedQuery<ReportExec> query = entityManager.createQuery(
+        TypedQuery<ReportExec> query = entityManager().createQuery(
                 "SELECT e FROM " + JPAReportExec.class.getSimpleName() + " e "
                 + "WHERE e.report=:report ORDER BY e." + field + " DESC", ReportExec.class);
         query.setParameter("report", report);
@@ -60,7 +60,7 @@ public class JPAReportExecDAO extends AbstractDAO<ReportExec, Long> implements R
 
     @Override
     public List<ReportExec> findAll() {
-        TypedQuery<ReportExec> query = entityManager.createQuery(
+        TypedQuery<ReportExec> query = entityManager().createQuery(
                 "SELECT e FROM " + JPAReportExec.class.getSimpleName() + " e", ReportExec.class);
         return query.getResultList();
     }
@@ -75,7 +75,7 @@ public class JPAReportExecDAO extends AbstractDAO<ReportExec, Long> implements R
     @Override
     @Transactional(rollbackFor = Throwable.class)
     public ReportExec save(final ReportExec execution) {
-        return entityManager.merge(execution);
+        return entityManager().merge(execution);
     }
 
     @Override
@@ -94,6 +94,6 @@ public class JPAReportExecDAO extends AbstractDAO<ReportExec, Long> implements R
             execution.getReport().removeExec(execution);
         }
 
-        entityManager.remove(execution);
+        entityManager().remove(execution);
     }
 }

http://git-wip-us.apache.org/repos/asf/syncope/blob/6dfedd8f/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPARoleDAO.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPARoleDAO.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPARoleDAO.java
index 5f600b6..6fb5ec3 100644
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPARoleDAO.java
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPARoleDAO.java
@@ -43,12 +43,12 @@ public class JPARoleDAO extends AbstractDAO<Role, Long> implements RoleDAO {
 
     @Override
     public Role find(final Long key) {
-        return entityManager.find(JPARole.class, key);
+        return entityManager().find(JPARole.class, key);
     }
 
     @Override
     public Role find(final String name) {
-        TypedQuery<Role> query = entityManager.createQuery(
+        TypedQuery<Role> query = entityManager().createQuery(
                 "SELECT e FROM " + JPARole.class.getSimpleName() + " e WHERE e.name=:name", Role.class);
         query.setParameter("name", name);
 
@@ -64,7 +64,7 @@ public class JPARoleDAO extends AbstractDAO<Role, Long> implements RoleDAO {
 
     @Override
     public List<Role> findByRealm(final Realm realm) {
-        TypedQuery<Role> query = entityManager.createQuery(
+        TypedQuery<Role> query = entityManager().createQuery(
                 "SELECT e FROM " + JPARole.class.getSimpleName() + " e WHERE :realm MEMBER OF e.realms", Role.class);
         query.setParameter("realm", realm);
         return query.getResultList();
@@ -72,7 +72,7 @@ public class JPARoleDAO extends AbstractDAO<Role, Long> implements RoleDAO {
 
     @Override
     public List<Role> findAll() {
-        TypedQuery<Role> query = entityManager.createQuery(
+        TypedQuery<Role> query = entityManager().createQuery(
                 "SELECT e FROM " + JPARole.class.getSimpleName() + " e ", Role.class);
         return query.getResultList();
     }
@@ -90,12 +90,12 @@ public class JPARoleDAO extends AbstractDAO<Role, Long> implements RoleDAO {
             }
         }
 
-        return entityManager.merge(role);
+        return entityManager().merge(role);
     }
 
     @Override
     public void delete(final Role role) {
-        entityManager.remove(role);
+        entityManager().remove(role);
     }
 
     @Override

http://git-wip-us.apache.org/repos/asf/syncope/blob/6dfedd8f/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPASecurityQuestionDAO.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPASecurityQuestionDAO.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPASecurityQuestionDAO.java
index 5c242d6..7028080 100644
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPASecurityQuestionDAO.java
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPASecurityQuestionDAO.java
@@ -36,19 +36,19 @@ public class JPASecurityQuestionDAO extends AbstractDAO<SecurityQuestion, Long>
 
     @Override
     public SecurityQuestion find(final Long key) {
-        return entityManager.find(JPASecurityQuestion.class, key);
+        return entityManager().find(JPASecurityQuestion.class, key);
     }
 
     @Override
     public List<SecurityQuestion> findAll() {
-        final TypedQuery<SecurityQuestion> query = entityManager.createQuery(
+        final TypedQuery<SecurityQuestion> query = entityManager().createQuery(
                 "SELECT e FROM " + JPASecurityQuestion.class.getSimpleName() + " e ", SecurityQuestion.class);
         return query.getResultList();
     }
 
     @Override
     public SecurityQuestion save(final SecurityQuestion securityQuestion) {
-        return entityManager.merge(securityQuestion);
+        return entityManager().merge(securityQuestion);
     }
 
     @Override
@@ -64,7 +64,7 @@ public class JPASecurityQuestionDAO extends AbstractDAO<SecurityQuestion, Long>
             userDAO.save(user);
         }
 
-        entityManager.remove(securityQuestion);
+        entityManager().remove(securityQuestion);
     }
 
 }

http://git-wip-us.apache.org/repos/asf/syncope/blob/6dfedd8f/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPATaskDAO.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPATaskDAO.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPATaskDAO.java
index ff93071..a70f65e 100644
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPATaskDAO.java
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPATaskDAO.java
@@ -75,7 +75,7 @@ public class JPATaskDAO extends AbstractDAO<Task, Long> implements TaskDAO {
     @SuppressWarnings("unchecked")
     @Override
     public <T extends Task> T find(final Long key) {
-        return (T) entityManager.find(JPATask.class, key);
+        return (T) entityManager().find(JPATask.class, key);
     }
 
     private <T extends Task> StringBuilder buildfindAllQuery(final TaskType type) {
@@ -96,7 +96,7 @@ public class JPATaskDAO extends AbstractDAO<Task, Long> implements TaskDAO {
         }
         queryString.append("ORDER BY e.id DESC");
 
-        Query query = entityManager.createQuery(queryString.toString());
+        Query query = entityManager().createQuery(queryString.toString());
         query.setParameter("type", type);
         return query.getResultList();
     }
@@ -106,13 +106,14 @@ public class JPATaskDAO extends AbstractDAO<Task, Long> implements TaskDAO {
     public <T extends Task> List<T> findAll(final ExternalResource resource, final TaskType type) {
         StringBuilder queryString = buildfindAllQuery(type).append("AND e.resource=:resource ORDER BY e.id DESC");
 
-        final Query query = entityManager.createQuery(queryString.toString());
+        final Query query = entityManager().createQuery(queryString.toString());
         query.setParameter("type", type);
         query.setParameter("resource", resource);
 
         return query.getResultList();
     }
 
+    @Transactional(readOnly = true)
     @Override
     public <T extends Task> List<T> findAll(final TaskType type) {
         return findAll(-1, -1, Collections.<OrderByClause>emptyList(), type);
@@ -128,7 +129,7 @@ public class JPATaskDAO extends AbstractDAO<Task, Long> implements TaskDAO {
                 ? "ORDER BY e.id DESC"
                 : toOrderByStatement(getEntityReference(type), "e", orderByClauses));
 
-        Query query = entityManager.createQuery(queryString.toString());
+        Query query = entityManager().createQuery(queryString.toString());
         query.setParameter("type", type);
 
         query.setFirstResult(itemsPerPage * (page <= 0
@@ -144,7 +145,7 @@ public class JPATaskDAO extends AbstractDAO<Task, Long> implements TaskDAO {
 
     @Override
     public int count(final TaskType type) {
-        Query countQuery = entityManager.createNativeQuery("SELECT COUNT(id) FROM Task WHERE TYPE=?1");
+        Query countQuery = entityManager().createNativeQuery("SELECT COUNT(id) FROM Task WHERE TYPE=?1");
         countQuery.setParameter(1, type.name());
         return ((Number) countQuery.getSingleResult()).intValue();
     }
@@ -152,7 +153,7 @@ public class JPATaskDAO extends AbstractDAO<Task, Long> implements TaskDAO {
     @Transactional(rollbackFor = { Throwable.class })
     @Override
     public <T extends Task> T save(final T task) {
-        return entityManager.merge(task);
+        return entityManager().merge(task);
     }
 
     @Override
@@ -167,7 +168,7 @@ public class JPATaskDAO extends AbstractDAO<Task, Long> implements TaskDAO {
 
     @Override
     public void delete(final Task task) {
-        entityManager.remove(task);
+        entityManager().remove(task);
     }
 
     @Override

http://git-wip-us.apache.org/repos/asf/syncope/blob/6dfedd8f/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPATaskExecDAO.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPATaskExecDAO.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPATaskExecDAO.java
index 5d840da..38155ff 100644
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPATaskExecDAO.java
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPATaskExecDAO.java
@@ -38,11 +38,11 @@ public class JPATaskExecDAO extends AbstractDAO<TaskExec, Long> implements TaskE
 
     @Override
     public TaskExec find(final Long key) {
-        return entityManager.find(JPATaskExec.class, key);
+        return entityManager().find(JPATaskExec.class, key);
     }
 
     private <T extends Task> TaskExec findLatest(final T task, final String field) {
-        TypedQuery<TaskExec> query = entityManager.createQuery(
+        TypedQuery<TaskExec> query = entityManager().createQuery(
                 "SELECT e FROM " + JPATaskExec.class.getSimpleName() + " e "
                 + "WHERE e.task=:task "
                 + "ORDER BY e." + field + " DESC", TaskExec.class);
@@ -71,13 +71,13 @@ public class JPATaskExecDAO extends AbstractDAO<TaskExec, Long> implements TaskE
                 append(" e WHERE e.task IN (").append("SELECT t FROM ").
                 append(taskDAO.getEntityReference(type).getSimpleName()).append(" t)");
 
-        TypedQuery<TaskExec> query = entityManager.createQuery(queryString.toString(), TaskExec.class);
+        TypedQuery<TaskExec> query = entityManager().createQuery(queryString.toString(), TaskExec.class);
         return query.getResultList();
     }
 
     @Override
     public TaskExec save(final TaskExec execution) {
-        return entityManager.merge(execution);
+        return entityManager().merge(execution);
     }
 
     /**
@@ -111,6 +111,6 @@ public class JPATaskExecDAO extends AbstractDAO<TaskExec, Long> implements TaskE
             execution.getTask().removeExec(execution);
         }
 
-        entityManager.remove(execution);
+        entityManager().remove(execution);
     }
 }

http://git-wip-us.apache.org/repos/asf/syncope/blob/6dfedd8f/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAUserDAO.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAUserDAO.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAUserDAO.java
index 3b413c0..50564f2 100644
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAUserDAO.java
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAUserDAO.java
@@ -29,8 +29,17 @@ import javax.persistence.TypedQuery;
 import org.apache.commons.collections4.CollectionUtils;
 import org.apache.commons.collections4.Predicate;
 import org.apache.commons.collections4.Transformer;
+import org.apache.commons.lang3.tuple.ImmutablePair;
+import org.apache.commons.lang3.tuple.Pair;
+import org.apache.syncope.common.lib.types.AccountPolicySpec;
 import org.apache.syncope.common.lib.types.AnyTypeKind;
 import org.apache.syncope.common.lib.types.Entitlement;
+import org.apache.syncope.common.lib.types.EntityViolationType;
+import org.apache.syncope.common.lib.types.PasswordPolicySpec;
+import org.apache.syncope.core.misc.policy.AccountPolicyEnforcer;
+import org.apache.syncope.core.misc.policy.AccountPolicyException;
+import org.apache.syncope.core.misc.policy.PasswordPolicyEnforcer;
+import org.apache.syncope.core.misc.policy.PolicyEvaluator;
 import org.apache.syncope.core.persistence.api.dao.NotFoundException;
 import org.apache.syncope.core.persistence.api.dao.GroupDAO;
 import org.apache.syncope.core.persistence.api.dao.UserDAO;
@@ -40,14 +49,21 @@ import org.apache.syncope.core.persistence.api.entity.user.User;
 import org.apache.syncope.core.persistence.jpa.entity.user.JPAUser;
 import org.apache.syncope.core.misc.security.AuthContextUtils;
 import org.apache.syncope.core.misc.security.UnauthorizedException;
+import org.apache.syncope.core.persistence.api.attrvalue.validation.InvalidEntityException;
+import org.apache.syncope.core.persistence.api.dao.RealmDAO;
 import org.apache.syncope.core.persistence.api.dao.RoleDAO;
+import org.apache.syncope.core.persistence.api.entity.AccountPolicy;
 import org.apache.syncope.core.persistence.api.entity.AnyUtils;
+import org.apache.syncope.core.persistence.api.entity.PasswordPolicy;
+import org.apache.syncope.core.persistence.api.entity.Policy;
+import org.apache.syncope.core.persistence.api.entity.Realm;
 import org.apache.syncope.core.persistence.api.entity.Role;
 import org.apache.syncope.core.persistence.api.entity.group.Group;
 import org.apache.syncope.core.persistence.api.entity.user.UMembership;
 import org.apache.syncope.core.persistence.jpa.entity.JPAAnyUtilsFactory;
 import org.apache.syncope.core.persistence.jpa.entity.user.JPADynRoleMembership;
 import org.apache.syncope.core.persistence.jpa.entity.user.JPAUDynGroupMembership;
+import org.apache.syncope.core.provisioning.api.UserSuspender;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Repository;
 import org.springframework.transaction.annotation.Propagation;
@@ -57,14 +73,32 @@ import org.springframework.transaction.annotation.Transactional;
 public class JPAUserDAO extends AbstractAnyDAO<User> implements UserDAO {
 
     @Autowired
+    private RealmDAO realmDAO;
+
+    @Autowired
     private GroupDAO groupDAO;
 
     @Autowired
     private RoleDAO roleDAO;
 
+    @Resource(name = "adminUser")
+    private String adminUser;
+
     @Resource(name = "anonymousUser")
     private String anonymousUser;
 
+    @Autowired
+    private PolicyEvaluator evaluator;
+
+    @Autowired
+    private PasswordPolicyEnforcer ppEnforcer;
+
+    @Autowired
+    private AccountPolicyEnforcer apEnforcer;
+
+    @Autowired(required = false)
+    private UserSuspender suspender;
+
     @Override
     protected AnyUtils init() {
         return new JPAAnyUtilsFactory().getInstance(AnyTypeKind.USER);
@@ -110,7 +144,7 @@ public class JPAUserDAO extends AbstractAnyDAO<User> implements UserDAO {
 
     @Override
     public User find(final String username) {
-        TypedQuery<User> query = entityManager.createQuery("SELECT e FROM " + JPAUser.class.getSimpleName()
+        TypedQuery<User> query = entityManager().createQuery("SELECT e FROM " + JPAUser.class.getSimpleName()
                 + " e WHERE e.username = :username", User.class);
         query.setParameter("username", username);
 
@@ -126,7 +160,7 @@ public class JPAUserDAO extends AbstractAnyDAO<User> implements UserDAO {
 
     @Override
     public User findByToken(final String token) {
-        TypedQuery<User> query = entityManager.createQuery("SELECT e FROM " + JPAUser.class.getSimpleName()
+        TypedQuery<User> query = entityManager().createQuery("SELECT e FROM " + JPAUser.class.getSimpleName()
                 + " e WHERE e.token LIKE :token", User.class);
         query.setParameter("token", token);
 
@@ -142,16 +176,151 @@ public class JPAUserDAO extends AbstractAnyDAO<User> implements UserDAO {
 
     @Override
     public List<User> findBySecurityQuestion(final SecurityQuestion securityQuestion) {
-        TypedQuery<User> query = entityManager.createQuery("SELECT e FROM " + JPAUser.class.getSimpleName()
+        TypedQuery<User> query = entityManager().createQuery("SELECT e FROM " + JPAUser.class.getSimpleName()
                 + " e WHERE e.securityQuestion = :securityQuestion", User.class);
         query.setParameter("securityQuestion", securityQuestion);
 
         return query.getResultList();
     }
 
+    private List<PasswordPolicy> getPasswordPolicies(final User user) {
+        List<PasswordPolicy> policies = new ArrayList<>();
+
+        PasswordPolicy policy;
+
+        // add resource policies
+        for (ExternalResource resource : findAllResources(user)) {
+            policy = resource.getPasswordPolicy();
+            if (policy != null) {
+                policies.add(policy);
+            }
+        }
+
+        // add realm policies
+        for (Realm realm : realmDAO.findAncestors(user.getRealm())) {
+            policy = realm.getPasswordPolicy();
+            if (policy != null) {
+                policies.add(policy);
+            }
+        }
+
+        return policies;
+    }
+
+    private List<AccountPolicy> getAccountPolicies(final User user) {
+        List<AccountPolicy> policies = new ArrayList<>();
+
+        AccountPolicy policy;
+
+        // add resource policies        
+        for (ExternalResource resource : findAllResources(user)) {
+            policy = resource.getAccountPolicy();
+            if (policy != null) {
+                policies.add(policy);
+            }
+        }
+
+        // add realm policies
+        for (Realm realm : realmDAO.findAncestors(user.getRealm())) {
+            policy = realm.getAccountPolicy();
+            if (policy != null) {
+                policies.add(policy);
+            }
+        }
+
+        return policies;
+    }
+
+    private Pair<Boolean, Boolean> enforcePolicies(final User user) {
+        // ------------------------------
+        // Verify password policies
+        // ------------------------------
+        LOG.debug("Password Policy enforcement");
+
+        try {
+            int maxPPSpecHistory = 0;
+            for (Policy policy : getPasswordPolicies(user)) {
+                // evaluate policy
+                PasswordPolicySpec ppSpec = evaluator.evaluate(policy, user);
+                // enforce policy
+                ppEnforcer.enforce(ppSpec, policy.getType(), user);
+
+                if (ppSpec.getHistoryLength() > maxPPSpecHistory) {
+                    maxPPSpecHistory = ppSpec.getHistoryLength();
+                }
+            }
+
+            // update user's password history with encrypted password
+            if (maxPPSpecHistory > 0 && user.getPassword() != null) {
+                user.getPasswordHistory().add(user.getPassword());
+            }
+            // keep only the last maxPPSpecHistory items in user's password history
+            if (maxPPSpecHistory < user.getPasswordHistory().size()) {
+                for (int i = 0; i < user.getPasswordHistory().size() - maxPPSpecHistory; i++) {
+                    user.getPasswordHistory().remove(i);
+                }
+            }
+        } catch (Exception e) {
+            LOG.error("Invalid password for {}", user, e);
+            throw new InvalidEntityException(User.class, EntityViolationType.InvalidPassword, e.getMessage());
+        } finally {
+            // password has been validated, let's remove its clear version
+            user.removeClearPassword();
+        }
+
+        // ------------------------------
+        // Verify account policies
+        // ------------------------------
+        LOG.debug("Account Policy enforcement");
+
+        boolean suspend = false;
+        boolean propagateSuspension = false;
+        try {
+            if (adminUser.equals(user.getUsername()) || anonymousUser.equals(user.getUsername())) {
+                throw new AccountPolicyException("Not allowed: " + user.getUsername());
+            }
+
+            // invalid username
+            for (Policy policy : getAccountPolicies(user)) {
+                // evaluate policy
+                AccountPolicySpec apSpec = evaluator.evaluate(policy, user);
+
+                // enforce policy
+                suspend |= apEnforcer.enforce(apSpec, policy.getType(), user);
+                propagateSuspension |= apSpec.isPropagateSuspension();
+            }
+        } catch (Exception e) {
+            LOG.error("Invalid username for {}", user, e);
+            throw new InvalidEntityException(User.class, EntityViolationType.InvalidUsername, e.getMessage());
+        }
+
+        return ImmutablePair.of(suspend, propagateSuspension);
+    }
+
     @Override
     public User save(final User user) {
+        // 1. save clear password value before save
+        String clearPwd = user.getClearPassword();
+
+        // 2. save and flush to trigger entity validation        
         User merged = super.save(user);
+        entityManager().flush();
+
+        // 3. set back the sole clear password value
+        JPAUser.class.cast(merged).setClearPassword(clearPwd);
+
+        // 4. enforce password and account policies
+        Pair<Boolean, Boolean> enforceSuspend = null;
+        try {
+            enforceSuspend = enforcePolicies(merged);
+        } catch (InvalidEntityException e) {
+            entityManager().remove(merged);
+            throw e;
+        }
+
+        if (suspender != null && enforceSuspend.getKey()) {
+            suspender.suspend(user, enforceSuspend.getValue());
+        }
 
         roleDAO.refreshDynMemberships(merged);
         groupDAO.refreshDynMemberships(merged);
@@ -168,13 +337,13 @@ public class JPAUserDAO extends AbstractAnyDAO<User> implements UserDAO {
             group.getUDynMembership().remove(user);
         }
 
-        entityManager.remove(user);
+        entityManager().remove(user);
     }
 
     @Transactional(propagation = Propagation.REQUIRES_NEW, readOnly = true)
     @Override
     public List<Role> findDynRoleMemberships(final User user) {
-        TypedQuery<Role> query = entityManager.createQuery(
+        TypedQuery<Role> query = entityManager().createQuery(
                 "SELECT e.role FROM " + JPADynRoleMembership.class.getSimpleName()
                 + " e WHERE :user MEMBER OF e.users", Role.class);
         query.setParameter("user", user);
@@ -185,7 +354,7 @@ public class JPAUserDAO extends AbstractAnyDAO<User> implements UserDAO {
     @Transactional(propagation = Propagation.REQUIRES_NEW, readOnly = true)
     @Override
     public List<Group> findDynGroupMemberships(final User user) {
-        TypedQuery<Group> query = entityManager.createQuery(
+        TypedQuery<Group> query = entityManager().createQuery(
                 "SELECT e.group FROM " + JPAUDynGroupMembership.class.getSimpleName()
                 + " e WHERE :user MEMBER OF e.users", Group.class);
         query.setParameter("user", user);

http://git-wip-us.apache.org/repos/asf/syncope/blob/6dfedd8f/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAVirAttrDAO.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAVirAttrDAO.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAVirAttrDAO.java
index 3ef6791..2c8b99f 100644
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAVirAttrDAO.java
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAVirAttrDAO.java
@@ -49,19 +49,19 @@ public class JPAVirAttrDAO extends AbstractDAO<VirAttr<?>, Long> implements VirA
 
     @Override
     public <T extends VirAttr<?>> T find(final Long key, final Class<T> reference) {
-        return reference.cast(entityManager.find(getJPAEntityReference(reference), key));
+        return reference.cast(entityManager().find(getJPAEntityReference(reference), key));
     }
 
     @Override
     public <T extends VirAttr<?>> List<T> findAll(final Class<T> reference) {
-        TypedQuery<T> query = entityManager.createQuery(
+        TypedQuery<T> query = entityManager().createQuery(
                 "SELECT e FROM " + getJPAEntityReference(reference).getSimpleName() + " e", reference);
         return query.getResultList();
     }
 
     @Override
     public <T extends VirAttr<?>> T save(final T virAttr) {
-        return entityManager.merge(virAttr);
+        return entityManager().merge(virAttr);
     }
 
     @Override
@@ -81,6 +81,6 @@ public class JPAVirAttrDAO extends AbstractDAO<VirAttr<?>, Long> implements VirA
             ((Any<?, ?, T>) virAttr.getOwner()).remove(virAttr);
         }
 
-        entityManager.remove(virAttr);
+        entityManager().remove(virAttr);
     }
 }

http://git-wip-us.apache.org/repos/asf/syncope/blob/6dfedd8f/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAVirSchemaDAO.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAVirSchemaDAO.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAVirSchemaDAO.java
index dae6afc..46a06f6 100644
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAVirSchemaDAO.java
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAVirSchemaDAO.java
@@ -45,7 +45,7 @@ public class JPAVirSchemaDAO extends AbstractDAO<VirSchema, String> implements V
 
     @Override
     public VirSchema find(final String key) {
-        return entityManager.find(JPAVirSchema.class, key);
+        return entityManager().find(JPAVirSchema.class, key);
     }
 
     @Override
@@ -54,7 +54,7 @@ public class JPAVirSchemaDAO extends AbstractDAO<VirSchema, String> implements V
                 append(JPAVirSchema.class.getSimpleName()).
                 append(" e WHERE e.anyTypeClass=:anyTypeClass");
 
-        TypedQuery<VirSchema> query = entityManager.createQuery(queryString.toString(), VirSchema.class);
+        TypedQuery<VirSchema> query = entityManager().createQuery(queryString.toString(), VirSchema.class);
         query.setParameter("anyTypeClass", anyTypeClass);
 
         return query.getResultList();
@@ -62,7 +62,7 @@ public class JPAVirSchemaDAO extends AbstractDAO<VirSchema, String> implements V
 
     @Override
     public List<VirSchema> findAll() {
-        TypedQuery<VirSchema> query = entityManager.createQuery(
+        TypedQuery<VirSchema> query = entityManager().createQuery(
                 "SELECT e FROM " + JPAVirSchema.class.getSimpleName() + " e", VirSchema.class);
         return query.getResultList();
     }
@@ -73,7 +73,7 @@ public class JPAVirSchemaDAO extends AbstractDAO<VirSchema, String> implements V
                 append(((JPAVirAttrDAO) virAttrDAO).getJPAEntityReference(reference).getSimpleName()).
                 append(" e WHERE e.schema=:schema");
 
-        TypedQuery<T> query = entityManager.createQuery(queryString.toString(), reference);
+        TypedQuery<T> query = entityManager().createQuery(queryString.toString(), reference);
         query.setParameter("schema", schema);
 
         return query.getResultList();
@@ -81,7 +81,7 @@ public class JPAVirSchemaDAO extends AbstractDAO<VirSchema, String> implements V
 
     @Override
     public VirSchema save(final VirSchema virSchema) {
-        return entityManager.merge(virSchema);
+        return entityManager().merge(virSchema);
     }
 
     @Override
@@ -106,6 +106,6 @@ public class JPAVirSchemaDAO extends AbstractDAO<VirSchema, String> implements V
             schema.getAnyTypeClass().remove(schema);
         }
 
-        entityManager.remove(schema);
+        entityManager().remove(schema);
     }
 }

http://git-wip-us.apache.org/repos/asf/syncope/blob/6dfedd8f/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/group/JPAGroup.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/group/JPAGroup.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/group/JPAGroup.java
index 06bebdb..2913dc6 100644
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/group/JPAGroup.java
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/group/JPAGroup.java
@@ -125,7 +125,7 @@ public class JPAGroup extends AbstractAny<GPlainAttr, GDerAttr, GVirAttr> implem
 
     @Override
     public AnyType getType() {
-        return ApplicationContextProvider.getApplicationContext().getBean(AnyTypeDAO.class).findGroup();
+        return ApplicationContextProvider.getBeanFactory().getBean(AnyTypeDAO.class).findGroup();
     }
 
     @Override

http://git-wip-us.apache.org/repos/asf/syncope/blob/6dfedd8f/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/task/AbstractProvisioningTask.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/task/AbstractProvisioningTask.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/task/AbstractProvisioningTask.java
index 9723f1d..463408e 100644
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/task/AbstractProvisioningTask.java
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/task/AbstractProvisioningTask.java
@@ -80,15 +80,15 @@ public abstract class AbstractProvisioningTask extends JPASchedTask implements P
     @Enumerated(EnumType.STRING)
     protected MatchingRule matchingRule;
 
-    public AbstractProvisioningTask(final TaskType type, final String jobClassName) {
+    public AbstractProvisioningTask(final TaskType type, final String jobDelegateClassName) {
         super();
 
         this.type = type;
-        super.setJobClassName(jobClassName);
+        super.setJobDelegateClassName(jobDelegateClassName);
     }
 
     @Override
-    public void setJobClassName(final String jobClassName) {
+    public void setJobDelegateClassName(final String jobClassName) {
         // fixed to SyncJob, cannot be changed
     }
 

http://git-wip-us.apache.org/repos/asf/syncope/blob/6dfedd8f/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/task/JPAPushTask.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/task/JPAPushTask.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/task/JPAPushTask.java
index 0592a9d..190cc0f 100644
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/task/JPAPushTask.java
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/task/JPAPushTask.java
@@ -37,7 +37,6 @@ import org.apache.syncope.common.lib.types.TaskType;
 import org.apache.syncope.core.persistence.api.entity.AnyType;
 import org.apache.syncope.core.persistence.api.entity.task.AnyFilter;
 import org.apache.syncope.core.persistence.api.entity.task.PushTask;
-import org.apache.syncope.core.provisioning.api.job.PushJob;
 
 @Entity
 @DiscriminatorValue("PushTask")
@@ -59,7 +58,7 @@ public class JPAPushTask extends AbstractProvisioningTask implements PushTask {
      * Default constructor.
      */
     public JPAPushTask() {
-        super(TaskType.PUSH, PushJob.class.getName());
+        super(TaskType.PUSH, null);
     }
 
     @Override

http://git-wip-us.apache.org/repos/asf/syncope/blob/6dfedd8f/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/task/JPASchedTask.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/task/JPASchedTask.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/task/JPASchedTask.java
index 5703380..4f650ba 100644
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/task/JPASchedTask.java
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/task/JPASchedTask.java
@@ -34,8 +34,7 @@ public class JPASchedTask extends JPATask implements SchedTask {
 
     protected String cronExpression;
 
-    @NotNull
-    protected String jobClassName;
+    protected String jobDelegateClassName;
 
     @NotNull
     protected String name;
@@ -58,13 +57,13 @@ public class JPASchedTask extends JPATask implements SchedTask {
     }
 
     @Override
-    public String getJobClassName() {
-        return jobClassName;
+    public String getJobDelegateClassName() {
+        return jobDelegateClassName;
     }
 
     @Override
-    public void setJobClassName(final String jobClassName) {
-        this.jobClassName = jobClassName;
+    public void setJobDelegateClassName(final String jobDelegateClassName) {
+        this.jobDelegateClassName = jobDelegateClassName;
     }
 
     @Override

http://git-wip-us.apache.org/repos/asf/syncope/blob/6dfedd8f/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/task/JPASyncTask.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/task/JPASyncTask.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/task/JPASyncTask.java
index 41eb4ea..f2da581 100644
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/task/JPASyncTask.java
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/task/JPASyncTask.java
@@ -40,7 +40,6 @@ import org.apache.commons.collections4.Predicate;
 import org.apache.syncope.common.lib.types.TaskType;
 import org.apache.syncope.core.persistence.api.entity.AnyType;
 import org.apache.syncope.core.persistence.api.entity.task.SyncTask;
-import org.apache.syncope.core.provisioning.api.job.SyncJob;
 import org.apache.syncope.core.persistence.api.entity.Realm;
 import org.apache.syncope.core.persistence.api.entity.task.AnyTemplate;
 import org.apache.syncope.core.persistence.jpa.entity.JPARealm;
@@ -73,7 +72,7 @@ public class JPASyncTask extends AbstractProvisioningTask implements SyncTask {
      * Default constructor.
      */
     public JPASyncTask() {
-        super(TaskType.SYNCHRONIZATION, SyncJob.class.getName());
+        super(TaskType.SYNCHRONIZATION, null);
     }
 
     @Override

http://git-wip-us.apache.org/repos/asf/syncope/blob/6dfedd8f/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/user/JPAUser.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/user/JPAUser.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/user/JPAUser.java
index 88c86fb..1f153da 100644
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/user/JPAUser.java
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/user/JPAUser.java
@@ -55,7 +55,6 @@ import org.apache.syncope.core.persistence.api.entity.user.UDerAttr;
 import org.apache.syncope.core.persistence.api.entity.user.UPlainAttr;
 import org.apache.syncope.core.persistence.api.entity.user.UVirAttr;
 import org.apache.syncope.core.persistence.api.entity.user.User;
-import org.apache.syncope.core.persistence.jpa.validation.entity.UserCheck;
 import org.apache.syncope.core.persistence.jpa.entity.resource.JPAExternalResource;
 import org.apache.syncope.core.persistence.jpa.entity.JPASecurityQuestion;
 import org.apache.syncope.core.misc.security.Encryptor;
@@ -75,7 +74,6 @@ import org.apache.syncope.core.persistence.jpa.entity.JPARole;
 @Entity
 @Table(name = JPAUser.TABLE)
 @Cacheable
-@UserCheck
 public class JPAUser extends AbstractAny<UPlainAttr, UDerAttr, UVirAttr> implements User {
 
     private static final long serialVersionUID = -3905046855521446823L;
@@ -212,7 +210,7 @@ public class JPAUser extends AbstractAny<UPlainAttr, UDerAttr, UVirAttr> impleme
 
     @Override
     public AnyType getType() {
-        return ApplicationContextProvider.getApplicationContext().getBean(AnyTypeDAO.class).findUser();
+        return ApplicationContextProvider.getBeanFactory().getBean(AnyTypeDAO.class).findUser();
     }
 
     @Override
@@ -252,9 +250,13 @@ public class JPAUser extends AbstractAny<UPlainAttr, UDerAttr, UVirAttr> impleme
         return clearPassword;
     }
 
+    public void setClearPassword(final String clearPassword) {
+        this.clearPassword = clearPassword;
+    }
+
     @Override
     public void removeClearPassword() {
-        clearPassword = null;
+        setClearPassword(null);
     }
 
     @Override

http://git-wip-us.apache.org/repos/asf/syncope/blob/6dfedd8f/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/spring/CommonEntityManagerFactoryConf.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/spring/CommonEntityManagerFactoryConf.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/spring/CommonEntityManagerFactoryConf.java
new file mode 100644
index 0000000..3e44864
--- /dev/null
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/spring/CommonEntityManagerFactoryConf.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.core.persistence.jpa.spring;
+
+import java.util.HashMap;
+import java.util.Map;
+import javax.persistence.ValidationMode;
+import javax.sql.DataSource;
+import org.apache.commons.lang3.StringUtils;
+import org.apache.syncope.core.persistence.api.DomainsHolder;
+import org.springframework.beans.BeansException;
+import org.springframework.beans.factory.InitializingBean;
+import org.springframework.context.ApplicationContext;
+import org.springframework.context.ApplicationContextAware;
+import org.springframework.orm.jpa.persistenceunit.PersistenceUnitPostProcessor;
+
+/**
+ * Container for common configuration options among all EntityManagerFactory entities (one for each domain).
+ * <br/>
+ * Acts as a commodity place for fetching each domain's {@link DataSource}..
+ */
+public class CommonEntityManagerFactoryConf implements DomainsHolder, InitializingBean, ApplicationContextAware {
+
+    private ApplicationContext ctx;
+
+    private final Map<String, DataSource> domains = new HashMap<>();
+
+    private String[] packagesToScan;
+
+    private ValidationMode validationMode;
+
+    private PersistenceUnitPostProcessor[] postProcessors;
+
+    private final Map<String, Object> jpaPropertyMap = new HashMap<>();
+
+    @Override
+    public void setApplicationContext(final ApplicationContext ctx) throws BeansException {
+        this.ctx = ctx;
+    }
+
+    @Override
+    public void afterPropertiesSet() {
+        for (Map.Entry<String, DataSource> entry : ctx.getBeansOfType(DataSource.class).entrySet()) {
+            if (!entry.getKey().startsWith("local")) {
+                this.domains.put(
+                        StringUtils.substringBefore(entry.getKey(), DataSource.class.getSimpleName()),
+                        entry.getValue());
+            }
+        }
+    }
+
+    @Override
+    public Map<String, DataSource> getDomains() {
+        return domains;
+    }
+
+    public String[] getPackagesToScan() {
+        return packagesToScan;
+    }
+
+    public void setPackagesToScan(final String... packagesToScan) {
+        this.packagesToScan = packagesToScan;
+    }
+
+    public ValidationMode getValidationMode() {
+        return validationMode;
+    }
+
+    public void setValidationMode(final ValidationMode validationMode) {
+        this.validationMode = validationMode;
+    }
+
+    public PersistenceUnitPostProcessor[] getPersistenceUnitPostProcessors() {
+        return postProcessors;
+    }
+
+    public void setPersistenceUnitPostProcessors(final PersistenceUnitPostProcessor... postProcessors) {
+        this.postProcessors = postProcessors;
+    }
+
+    public Map<String, ?> getJpaPropertyMap() {
+        return jpaPropertyMap;
+    }
+
+    public void setJpaPropertyMap(final Map<String, ?> jpaProperties) {
+        if (jpaProperties != null) {
+            this.jpaPropertyMap.putAll(jpaProperties);
+        }
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/6dfedd8f/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/spring/DomainEntityManagerFactoryBean.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/spring/DomainEntityManagerFactoryBean.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/spring/DomainEntityManagerFactoryBean.java
new file mode 100644
index 0000000..a959f96
--- /dev/null
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/spring/DomainEntityManagerFactoryBean.java
@@ -0,0 +1,45 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.syncope.core.persistence.jpa.spring;
+
+import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean;
+
+/**
+ * Extension of {@link LocalContainerEntityManagerFactoryBean} relying on {@link CommonEntityManagerFactoryConf} for
+ * common configuration options.
+ */
+public class DomainEntityManagerFactoryBean extends LocalContainerEntityManagerFactoryBean {
+
+    private static final long serialVersionUID = 49152547930966545L;
+
+    public void setCommonEntityManagerFactoryConf(final CommonEntityManagerFactoryConf commonEMFConf) {
+        super.setJpaPropertyMap(commonEMFConf.getJpaPropertyMap());
+
+        if (commonEMFConf.getPackagesToScan() != null) {
+            super.setPackagesToScan(commonEMFConf.getPackagesToScan());
+        }
+
+        super.setValidationMode(commonEMFConf.getValidationMode());
+
+        if (commonEMFConf.getPersistenceUnitPostProcessors() != null) {
+            super.setPersistenceUnitPostProcessors(commonEMFConf.getPersistenceUnitPostProcessors());
+        }
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/6dfedd8f/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/spring/DomainTransactionInterceptor.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/spring/DomainTransactionInterceptor.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/spring/DomainTransactionInterceptor.java
new file mode 100644
index 0000000..42779ed
--- /dev/null
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/spring/DomainTransactionInterceptor.java
@@ -0,0 +1,70 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.syncope.core.persistence.jpa.spring;
+
+import java.lang.reflect.Method;
+import org.aopalliance.intercept.MethodInvocation;
+import org.apache.syncope.core.misc.security.AuthContextUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.transaction.interceptor.DefaultTransactionAttribute;
+import org.springframework.transaction.interceptor.TransactionAttribute;
+import org.springframework.transaction.interceptor.TransactionAttributeSource;
+import org.springframework.transaction.interceptor.TransactionInterceptor;
+
+/**
+ * Extends the standard {@link TransactionInterceptor} by dynamically setting the appropriate
+ * {@link TransactionAttribute} qualifier according to the authentication domain of the caller - retrieved via
+ * {@link AuthContextUtils#getDomain()}.
+ */
+public class DomainTransactionInterceptor extends TransactionInterceptor {
+
+    private static final long serialVersionUID = 5113728988680448551L;
+
+    private static final Logger LOG = LoggerFactory.getLogger(DomainTransactionInterceptor.class);
+
+    @Override
+    public TransactionAttributeSource getTransactionAttributeSource() {
+        final TransactionAttributeSource origTxAttrSource = super.getTransactionAttributeSource();
+
+        return new TransactionAttributeSource() {
+
+            @Override
+            public TransactionAttribute getTransactionAttribute(final Method method, final Class<?> targetClass) {
+                TransactionAttribute txAttr = origTxAttrSource.getTransactionAttribute(method, targetClass);
+
+                if (txAttr instanceof DefaultTransactionAttribute) {
+                    ((DefaultTransactionAttribute) txAttr).setQualifier(AuthContextUtils.getDomain());
+                }
+
+                return txAttr;
+            }
+        };
+    }
+
+    @Override
+    public Object invoke(final MethodInvocation invocation) throws Throwable {
+        try {
+            return super.invoke(invocation);
+        } catch (Throwable e) {
+            LOG.debug("Error during {} invocation", invocation.getMethod(), e);
+            throw e;
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/6dfedd8f/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/spring/SpringComponentReplacer.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/spring/SpringComponentReplacer.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/spring/SpringComponentReplacer.java
new file mode 100644
index 0000000..e983426
--- /dev/null
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/spring/SpringComponentReplacer.java
@@ -0,0 +1,42 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.syncope.core.persistence.jpa.spring;
+
+import org.springframework.beans.BeansException;
+import org.springframework.beans.factory.config.BeanDefinition;
+import org.springframework.beans.factory.config.BeanFactoryPostProcessor;
+import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
+import org.springframework.stereotype.Component;
+import org.springframework.transaction.interceptor.TransactionInterceptor;
+
+/**
+ * Hack for dynamically replacing standard {@link TransactionInterceptor} with
+ * {@link DomainTransactionInterceptor} in Spring context.
+ */
+@Component
+public class SpringComponentReplacer implements BeanFactoryPostProcessor {
+
+    @Override
+    public void postProcessBeanFactory(final ConfigurableListableBeanFactory factory) throws BeansException {
+        for (String name : factory.getBeanNamesForType(TransactionInterceptor.class)) {
+            BeanDefinition bd = factory.getBeanDefinition(name);
+            bd.setBeanClassName(DomainTransactionInterceptor.class.getName());
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/6dfedd8f/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/validation/entity/EntityValidationListener.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/validation/entity/EntityValidationListener.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/validation/entity/EntityValidationListener.java
index b7616c7..f1df70c 100644
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/validation/entity/EntityValidationListener.java
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/validation/entity/EntityValidationListener.java
@@ -49,7 +49,7 @@ public class EntityValidationListener {
     @PrePersist
     @PreUpdate
     public void validate(final Object object) {
-        final Validator validator = ApplicationContextProvider.getApplicationContext().getBean(Validator.class);
+        final Validator validator = ApplicationContextProvider.getBeanFactory().getBean(Validator.class);
         Set<ConstraintViolation<Object>> violations = validator.validate(object);
         if (!violations.isEmpty()) {
             LOG.warn("Bean validation errors found: {}", violations);

http://git-wip-us.apache.org/repos/asf/syncope/blob/6dfedd8f/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/validation/entity/ProvisioningTaskValidator.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/validation/entity/ProvisioningTaskValidator.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/validation/entity/ProvisioningTaskValidator.java
index 2b6e4e0..3c64499 100644
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/validation/entity/ProvisioningTaskValidator.java
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/validation/entity/ProvisioningTaskValidator.java
@@ -37,11 +37,11 @@ public class ProvisioningTaskValidator extends AbstractValidator<ProvisioningTas
     }
 
     @Override
-    public boolean isValid(final ProvisioningTask object, final ConstraintValidatorContext context) {
-        boolean isValid = schedV.isValid(object, context);
+    public boolean isValid(final ProvisioningTask task, final ConstraintValidatorContext context) {
+        boolean isValid = schedV.isValid(task, context);
 
         if (isValid) {
-            isValid = object.getResource() != null;
+            isValid = task.getResource() != null;
             if (!isValid) {
                 LOG.error("Resource is null");
 
@@ -51,15 +51,15 @@ public class ProvisioningTaskValidator extends AbstractValidator<ProvisioningTas
                         addPropertyNode("resource").addConstraintViolation();
             }
 
-            if (!object.getActionsClassNames().isEmpty()) {
-                for (String className : object.getActionsClassNames()) {
+            if (!task.getActionsClassNames().isEmpty()) {
+                for (String className : task.getActionsClassNames()) {
                     Class<?> actionsClass = null;
                     boolean isAssignable = false;
                     try {
                         actionsClass = Class.forName(className);
-                        isAssignable = object instanceof JPASyncTask
+                        isAssignable = task instanceof JPASyncTask
                                 ? SyncActions.class.isAssignableFrom(actionsClass)
-                                : object instanceof JPAPushTask
+                                : task instanceof JPAPushTask
                                         ? PushActions.class.isAssignableFrom(actionsClass)
                                         : false;
                     } catch (Exception e) {

http://git-wip-us.apache.org/repos/asf/syncope/blob/6dfedd8f/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/validation/entity/SchedTaskValidator.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/validation/entity/SchedTaskValidator.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/validation/entity/SchedTaskValidator.java
index 50a6d5d..5c159c2 100644
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/validation/entity/SchedTaskValidator.java
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/validation/entity/SchedTaskValidator.java
@@ -21,39 +21,43 @@ package org.apache.syncope.core.persistence.jpa.validation.entity;
 import java.text.ParseException;
 
 import javax.validation.ConstraintValidatorContext;
+import org.apache.commons.lang3.ClassUtils;
 import org.apache.syncope.common.lib.types.EntityViolationType;
+import org.apache.syncope.core.persistence.api.entity.task.ProvisioningTask;
 import org.apache.syncope.core.persistence.api.entity.task.SchedTask;
+import org.apache.syncope.core.provisioning.api.job.SchedTaskJobDelegate;
 import org.quartz.CronExpression;
-import org.quartz.Job;
 
 public class SchedTaskValidator extends AbstractValidator<SchedTaskCheck, SchedTask> {
 
     @Override
-    public boolean isValid(final SchedTask object, final ConstraintValidatorContext context) {
-        boolean isValid;
+    public boolean isValid(final SchedTask task, final ConstraintValidatorContext context) {
+        boolean isValid = true;
 
-        Class<?> jobClass = null;
-        try {
-            jobClass = Class.forName(object.getJobClassName());
-            isValid = Job.class.isAssignableFrom(jobClass);
-        } catch (Exception e) {
-            LOG.error("Invalid Job class specified", e);
-            isValid = false;
-        }
-        if (jobClass == null || !isValid) {
-            isValid = false;
+        if (!(task instanceof ProvisioningTask)) {
+            Class<?> jobDelegateClass = null;
+            try {
+                jobDelegateClass = ClassUtils.getClass(task.getJobDelegateClassName());
+                isValid = SchedTaskJobDelegate.class.isAssignableFrom(jobDelegateClass);
+            } catch (Exception e) {
+                LOG.error("Invalid JobDelegate class specified", e);
+                isValid = false;
+            }
+            if (jobDelegateClass == null || !isValid) {
+                isValid = false;
 
-            context.disableDefaultConstraintViolation();
-            context.buildConstraintViolationWithTemplate(
-                    getTemplate(EntityViolationType.InvalidSchedTask, "Invalid job class name")).
-                    addPropertyNode("jobClassName").addConstraintViolation();
+                context.disableDefaultConstraintViolation();
+                context.buildConstraintViolationWithTemplate(
+                        getTemplate(EntityViolationType.InvalidSchedTask, "Invalid job delegate class name")).
+                        addPropertyNode("jobDelegateClassName").addConstraintViolation();
+            }
         }
 
-        if (isValid && object.getCronExpression() != null) {
+        if (isValid && task.getCronExpression() != null) {
             try {
-                new CronExpression(object.getCronExpression());
+                new CronExpression(task.getCronExpression());
             } catch (ParseException e) {
-                LOG.error("Invalid cron expression '" + object.getCronExpression() + "'", e);
+                LOG.error("Invalid cron expression '" + task.getCronExpression() + "'", e);
                 isValid = false;
 
                 context.disableDefaultConstraintViolation();

http://git-wip-us.apache.org/repos/asf/syncope/blob/6dfedd8f/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/validation/entity/UserCheck.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/validation/entity/UserCheck.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/validation/entity/UserCheck.java
deleted file mode 100644
index 2d9fec6..0000000
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/validation/entity/UserCheck.java
+++ /dev/null
@@ -1,41 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.syncope.core.persistence.jpa.validation.entity;
-
-import java.lang.annotation.Documented;
-import java.lang.annotation.ElementType;
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-import java.lang.annotation.Target;
-
-import javax.validation.Constraint;
-import javax.validation.Payload;
-
-@Target({ ElementType.TYPE })
-@Retention(RetentionPolicy.RUNTIME)
-@Constraint(validatedBy = UserValidator.class)
-@Documented
-public @interface UserCheck {
-
-    String message() default "{org.apache.syncope.core.persistence.validation.user}";
-
-    Class<?>[] groups() default {};
-
-    Class<? extends Payload>[] payload() default {};
-}

http://git-wip-us.apache.org/repos/asf/syncope/blob/6dfedd8f/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/validation/entity/UserValidator.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/validation/entity/UserValidator.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/validation/entity/UserValidator.java
deleted file mode 100644
index e142de3..0000000
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/validation/entity/UserValidator.java
+++ /dev/null
@@ -1,199 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.syncope.core.persistence.jpa.validation.entity;
-
-import java.util.ArrayList;
-import java.util.List;
-import javax.annotation.Resource;
-import javax.validation.ConstraintValidatorContext;
-import org.apache.syncope.common.lib.types.AccountPolicySpec;
-import org.apache.syncope.common.lib.types.EntityViolationType;
-import org.apache.syncope.common.lib.types.PasswordPolicySpec;
-import org.apache.syncope.core.persistence.api.entity.AccountPolicy;
-import org.apache.syncope.core.persistence.api.entity.resource.ExternalResource;
-import org.apache.syncope.core.persistence.api.entity.PasswordPolicy;
-import org.apache.syncope.core.persistence.api.entity.Policy;
-import org.apache.syncope.core.persistence.api.entity.user.User;
-import org.apache.syncope.core.misc.policy.AccountPolicyEnforcer;
-import org.apache.syncope.core.misc.policy.AccountPolicyException;
-import org.apache.syncope.core.misc.policy.PasswordPolicyEnforcer;
-import org.apache.syncope.core.misc.policy.PolicyEvaluator;
-import org.apache.syncope.core.persistence.api.dao.RealmDAO;
-import org.apache.syncope.core.persistence.api.dao.UserDAO;
-import org.apache.syncope.core.persistence.api.entity.Realm;
-import org.springframework.beans.factory.annotation.Autowired;
-
-public class UserValidator extends AbstractValidator<UserCheck, User> {
-
-    @Resource(name = "adminUser")
-    private String adminUser;
-
-    @Resource(name = "anonymousUser")
-    private String anonymousUser;
-
-    @Autowired
-    private UserDAO userDAO;
-
-    @Autowired
-    private RealmDAO realmDAO;
-
-    @Autowired
-    private PolicyEvaluator evaluator;
-
-    @Autowired
-    private PasswordPolicyEnforcer ppEnforcer;
-
-    @Autowired
-    private AccountPolicyEnforcer apEnforcer;
-
-    @Override
-    public boolean isValid(final User user, final ConstraintValidatorContext context) {
-        context.disableDefaultConstraintViolation();
-
-        // need to treat it explicitly, otherwise policy evaluation will silently fail
-        if (user.getRealm() == null) {
-            context.buildConstraintViolationWithTemplate(
-                    getTemplate(EntityViolationType.InvalidRealm, "realm not specified")).
-                    addPropertyNode("realm").addConstraintViolation();
-
-            return false;
-        }
-
-        // ------------------------------
-        // Verify password policies
-        // ------------------------------
-        LOG.debug("Password Policy enforcement");
-
-        try {
-            int maxPPSpecHistory = 0;
-            for (Policy policy : getPasswordPolicies(user)) {
-                // evaluate policy
-                PasswordPolicySpec ppSpec = evaluator.evaluate(policy, user);
-                // enforce policy
-                ppEnforcer.enforce(ppSpec, policy.getType(), user);
-
-                if (ppSpec.getHistoryLength() > maxPPSpecHistory) {
-                    maxPPSpecHistory = ppSpec.getHistoryLength();
-                }
-            }
-
-            // update user's password history with encrypted password
-            if (maxPPSpecHistory > 0 && user.getPassword() != null) {
-                user.getPasswordHistory().add(user.getPassword());
-            }
-            // keep only the last maxPPSpecHistory items in user's password history
-            if (maxPPSpecHistory < user.getPasswordHistory().size()) {
-                for (int i = 0; i < user.getPasswordHistory().size() - maxPPSpecHistory; i++) {
-                    user.getPasswordHistory().remove(i);
-                }
-            }
-        } catch (Exception e) {
-            LOG.debug("Invalid password");
-
-            context.buildConstraintViolationWithTemplate(
-                    getTemplate(EntityViolationType.InvalidPassword, e.getMessage())).
-                    addPropertyNode("password").addConstraintViolation();
-
-            return false;
-        } finally {
-            // password has been validated, let's remove its clear version
-            user.removeClearPassword();
-        }
-        // ------------------------------
-
-        // ------------------------------
-        // Verify account policies
-        // ------------------------------
-        LOG.debug("Account Policy enforcement");
-
-        try {
-            if (adminUser.equals(user.getUsername()) || anonymousUser.equals(user.getUsername())) {
-                throw new AccountPolicyException("Not allowed: " + user.getUsername());
-            }
-
-            // invalid username
-            for (Policy policy : getAccountPolicies(user)) {
-                // evaluate policy
-                AccountPolicySpec accountPolicy = evaluator.evaluate(policy, user);
-
-                // enforce policy
-                apEnforcer.enforce(accountPolicy, policy.getType(), user);
-            }
-        } catch (Exception e) {
-            LOG.debug("Invalid username");
-
-            context.buildConstraintViolationWithTemplate(
-                    getTemplate(EntityViolationType.InvalidUsername, e.getMessage())).
-                    addPropertyNode("username").addConstraintViolation();
-
-            return false;
-        }
-        // ------------------------------
-
-        return true;
-    }
-
-    private List<PasswordPolicy> getPasswordPolicies(final User user) {
-        List<PasswordPolicy> policies = new ArrayList<>();
-
-        PasswordPolicy policy;
-
-        // add resource policies
-        for (ExternalResource resource : userDAO.findAllResources(user)) {
-            policy = resource.getPasswordPolicy();
-            if (policy != null) {
-                policies.add(policy);
-            }
-        }
-
-        // add realm policies
-        for (Realm realm : realmDAO.findAncestors(user.getRealm())) {
-            policy = realm.getPasswordPolicy();
-            if (policy != null) {
-                policies.add(policy);
-            }
-        }
-
-        return policies;
-    }
-
-    private List<AccountPolicy> getAccountPolicies(final User user) {
-        List<AccountPolicy> policies = new ArrayList<>();
-
-        AccountPolicy policy;
-
-        // add resource policies
-        for (ExternalResource resource : userDAO.findAllResources(user)) {
-            policy = resource.getAccountPolicy();
-            if (policy != null) {
-                policies.add(policy);
-            }
-        }
-
-        // add realm policies
-        for (Realm realm : realmDAO.findAncestors(user.getRealm())) {
-            policy = realm.getAccountPolicy();
-            if (policy != null) {
-                policies.add(policy);
-            }
-        }
-
-        return policies;
-    }
-}

http://git-wip-us.apache.org/repos/asf/syncope/blob/6dfedd8f/core/persistence-jpa/src/main/resources/audit/audit.sql
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/resources/audit/audit.sql b/core/persistence-jpa/src/main/resources/audit/audit.sql
index faf8c5b..44ffb17 100644
--- a/core/persistence-jpa/src/main/resources/audit/audit.sql
+++ b/core/persistence-jpa/src/main/resources/audit/audit.sql
@@ -21,4 +21,6 @@ CREATE TABLE IF NOT EXISTS SYNCOPEAUDIT (
   LOGGER VARCHAR(255) NOT NULL,
   MESSAGE TEXT NOT NULL,
   THROWABLE TEXT
-)
+);
+
+COMMIT;

http://git-wip-us.apache.org/repos/asf/syncope/blob/6dfedd8f/core/persistence-jpa/src/main/resources/content.xml
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/resources/content.xml b/core/persistence-jpa/src/main/resources/content.xml
deleted file mode 100644
index caba10e..0000000
--- a/core/persistence-jpa/src/main/resources/content.xml
+++ /dev/null
@@ -1,117 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
-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.
--->
-<dataset>
-  <Realm id="1" name="/"/>
-
-  <SyncopeConf id="1" 
-               creator="admin" lastModifier="admin"
-               creationDate="2014-06-20 11:00:00" lastChangeDate="2014-06-20 11:00:00"/>
-
-  <PlainSchema name="password.cipher.algorithm" type="String"
-               mandatoryCondition="true" multivalue="0" uniqueConstraint="0" readonly="0"/>
-  <CPlainAttr id="1" owner_id="1" schema_name="password.cipher.algorithm"/>
-  <CPlainAttrValue id="1" attribute_id="1" stringValue="SHA1"/>
-
-  <!-- notificationjob.cronExpression:
-  + not existing: NotificationJob runs according to Notification.DEFAULT_CRON_EXP
-  + provided as empty string: NotificationJob disabled
-  + provided as non-empty string: NotificationJob runs according to the given value -->
-  <PlainSchema name="notificationjob.cronExpression" type="String"
-               mandatoryCondition="false" multivalue="0" uniqueConstraint="0" readonly="0"/>
-  <CPlainAttr id="2" owner_id="1" schema_name="notificationjob.cronExpression"/>
-  <CPlainAttrValue id="2" attribute_id="2" stringValue=""/>
-
-  <PlainSchema name="notification.maxRetries" type="Long"
-               mandatoryCondition="true" multivalue="0" uniqueConstraint="0" readonly="0"/>
-  <CPlainAttr id="3" owner_id="1" schema_name="notification.maxRetries"/>
-  <CPlainAttrValue id="3" attribute_id="3" longValue="3"/>
-
-  <PlainSchema name="token.length" type="Long"
-               mandatoryCondition="true" multivalue="0" uniqueConstraint="0" readonly="0"/>
-  <CPlainAttr id="4" owner_id="1" schema_name="token.length"/>
-  <CPlainAttrValue id="4" attribute_id="4" longValue="256"/>
-
-  <PlainSchema name="token.expireTime" type="Long"
-               mandatoryCondition="true" multivalue="0" uniqueConstraint="0" readonly="0"/>
-  <CPlainAttr id="5" owner_id="1" schema_name="token.expireTime"/>
-  <CPlainAttrValue id="5" attribute_id="5" longValue="60"/>
-
-  <PlainSchema name="selfRegistration.allowed" type="Boolean"
-               mandatoryCondition="true" multivalue="0" uniqueConstraint="0" readonly="0"/>
-  <CPlainAttr id="6" owner_id="1" schema_name="selfRegistration.allowed"/>
-  <CPlainAttrValue id="6" attribute_id="6" booleanValue="1"/>
-
-  <PlainSchema name="passwordReset.allowed" type="Boolean"
-               mandatoryCondition="true" multivalue="0" uniqueConstraint="0" readonly="0"/>
-  <CPlainAttr id="7" owner_id="1" schema_name="passwordReset.allowed"/>
-  <CPlainAttrValue id="7" attribute_id="7" booleanValue="1"/>
-
-  <PlainSchema name="passwordReset.securityQuestion" type="Boolean"
-               mandatoryCondition="true" multivalue="0" uniqueConstraint="0" readonly="0"/>
-  <CPlainAttr id="8" owner_id="1" schema_name="passwordReset.securityQuestion"/>
-  <CPlainAttrValue id="8" attribute_id="8" booleanValue="1"/>
-
-  <PlainSchema name="authentication.statuses" type="String"
-               mandatoryCondition="true" multivalue="1" uniqueConstraint="0" readonly="0"/>
-  <CPlainAttr id="9" owner_id="1" schema_name="authentication.statuses"/>
-  <CPlainAttrValue id="9" attribute_id="9" stringValue="created"/>
-  <CPlainAttrValue id="10" attribute_id="9" stringValue="active"/>
-
-  <!-- Save user login date upon successful authentication -->
-  <PlainSchema name="log.lastlogindate" type="Boolean"
-               mandatoryCondition="true" multivalue="0" uniqueConstraint="0" readonly="0"/>
-  <CPlainAttr id="11" owner_id="1" schema_name="log.lastlogindate"/>
-  <CPlainAttrValue id="11" attribute_id="11" booleanValue="1"/>
-
-  <PlainSchema name="tasks.interruptMaxRetries" type="Long"
-               mandatoryCondition="true" multivalue="0" uniqueConstraint="0" readonly="0"/>
-  <CPlainAttr id="12" owner_id="1" schema_name="tasks.interruptMaxRetries"/>
-  <CPlainAttrValue id="12" attribute_id="12" longValue="20"/>
-
-  <!-- For usage with admin console -->
-  <PlainSchema name="admin.user.layout" type="String"
-               mandatoryCondition="false" multivalue="1" uniqueConstraint="0" readonly="0"/>
-  <PlainSchema name="self.user.layout" type="String"
-               mandatoryCondition="false" multivalue="1" uniqueConstraint="0" readonly="0"/>
-  <PlainSchema name="admin.group.layout" type="String"
-               mandatoryCondition="false" multivalue="1" uniqueConstraint="0" readonly="0"/>
-  <PlainSchema name="self.group.layout" type="String"
-               mandatoryCondition="false" multivalue="1" uniqueConstraint="0" readonly="0"/>
-  <PlainSchema name="admin.membership.layout" type="String"
-               mandatoryCondition="false" multivalue="1" uniqueConstraint="0" readonly="0"/>
-  <PlainSchema name="self.membership.layout" type="String"
-               mandatoryCondition="false" multivalue="1" uniqueConstraint="0" readonly="0"/>
-        
-  <PlainSchema name="email" type="String"
-               mandatoryCondition="false" multivalue="0" uniqueConstraint="0" readonly="0"
-               validatorClass="org.apache.syncope.core.persistence.jpa.attrvalue.validation.EmailAddressValidator"/>
-  
-  <!-- Password reset notifications -->
-  <Notification id="1" active="1" recipientAttrName="email" recipientAttrType="UserPlainSchema" selfAsRecipient="1" 
-                sender="admin@syncope.apache.org" subject="Password Reset request" template="requestPasswordReset" 
-                traceLevel="FAILURES" userAbout="token!=$null"/> 
-  <Notification_events Notification_id="1" event="[CUSTOM]:[]:[]:[requestPasswordReset]:[SUCCESS]"/>
-  
-  <Notification id="2" active="1" recipientAttrName="email" recipientAttrType="UserPlainSchema" selfAsRecipient="1" 
-                sender="admin@syncope.apache.org" subject="Password Reset successful" template="confirmPasswordReset" 
-                traceLevel="FAILURES" userAbout="token!=$null"/> 
-  <Notification_events Notification_id="2" event="[CUSTOM]:[]:[]:[confirmPasswordReset]:[SUCCESS]"/>
-
-</dataset>

http://git-wip-us.apache.org/repos/asf/syncope/blob/6dfedd8f/core/persistence-jpa/src/main/resources/domains.xml
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/resources/domains.xml b/core/persistence-jpa/src/main/resources/domains.xml
new file mode 100644
index 0000000..43fce14
--- /dev/null
+++ b/core/persistence-jpa/src/main/resources/domains.xml
@@ -0,0 +1,56 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+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.
+-->
+<beans xmlns="http://www.springframework.org/schema/beans"
+       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+       xsi:schemaLocation="http://www.springframework.org/schema/beans
+                           http://www.springframework.org/schema/beans/spring-beans.xsd">
+  
+  <import resource="classpath*:domains/*Domain.xml"/>
+    
+  <bean id="commonEMFConf" class="org.apache.syncope.core.persistence.jpa.spring.CommonEntityManagerFactoryConf">
+    <property name="packagesToScan" value="org.apache.syncope.core.persistence.jpa.entity"/>
+    <property name="validationMode" value="NONE"/>
+    <property name="persistenceUnitPostProcessors">
+      <list>
+        <bean class="org.apache.syncope.core.persistence.jpa.spring.MultiJarAwarePersistenceUnitPostProcessor"/>
+      </list>
+    </property>
+    <property name="jpaPropertyMap">
+      <map>
+        <entry key="openjpa.Log" value="slf4j"/>
+        <!--<entry key="openjpa.Log" value="SQL=TRACE"/>
+        <entry key="openjpa.ConnectionFactoryProperties" 
+        value="PrintParameters=true, PrettyPrint=true, PrettyPrintLineLength=80"/>-->
+                                
+        <entry key="openjpa.NontransactionalWrite" value="false"/>
+        <entry key="openjpa.AutoDetach" value="close, commit, nontx-read, rollback"/>
+
+        <entry key="openjpa.jdbc.SchemaFactory" value="native(ForeignKeys=true)"/>
+        <entry key="openjpa.jdbc.MappingDefaults" 
+               value="ForeignKeyDeleteAction=restrict, JoinForeignKeyDeleteAction=restrict"/>
+                
+        <entry key="openjpa.DataCache" value="true"/>
+        <entry key="openjpa.QueryCache" value="true"/>
+        <entry key="openjpa.RemoteCommitProvider" value="sjvm"/>
+      </map>
+    </property>    
+  </bean>
+  
+</beans>

http://git-wip-us.apache.org/repos/asf/syncope/blob/6dfedd8f/core/persistence-jpa/src/main/resources/domains/Master.properties
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/resources/domains/Master.properties b/core/persistence-jpa/src/main/resources/domains/Master.properties
new file mode 100644
index 0000000..177e988
--- /dev/null
+++ b/core/persistence-jpa/src/main/resources/domains/Master.properties
@@ -0,0 +1,28 @@
+# 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.
+Master.driverClassName=org.postgresql.Driver
+Master.url=jdbc:postgresql://localhost:5432/syncope
+Master.schema=
+Master.username=syncope
+Master.password=syncope
+Master.databasePlatform=org.apache.openjpa.jdbc.sql.PostgresDictionary
+Master.orm=META-INF/spring-orm.xml
+
+# note: other connection pool settings can also be configured here, see DataSource definition
+Master.pool.validationQuery=SELECT 1
+
+Master.audit.sql=audit.sql


[22/31] syncope git commit: [SYNCOPE-652] Now account lockout is working properly again

Posted by md...@apache.org.
http://git-wip-us.apache.org/repos/asf/syncope/blob/5cf6aae8/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/VirAttrITCase.java
----------------------------------------------------------------------
diff --git a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/VirAttrITCase.java b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/VirAttrITCase.java
index 3fc1b98..92bca46 100644
--- a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/VirAttrITCase.java
+++ b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/VirAttrITCase.java
@@ -134,8 +134,9 @@ public class VirAttrITCase extends AbstractITCase {
         // suspend/reactivate user and check virtual attribute value (unchanged)
         // ----------------------------------
         StatusMod statusMod = new StatusMod();
+        statusMod.setKey(userTO.getKey());
         statusMod.setType(StatusMod.ModType.SUSPEND);
-        userTO = userService.status(userTO.getKey(), statusMod).readEntity(UserTO.class);
+        userTO = userService.status(statusMod).readEntity(UserTO.class);
         assertEquals("suspended", userTO.getStatus());
 
         connObjectTO = resourceService.readConnObject(RESOURCE_NAME_WS2, AnyTypeKind.USER.name(), userTO.getKey());
@@ -144,8 +145,9 @@ public class VirAttrITCase extends AbstractITCase {
         assertEquals("virtualvalue2", connObjectTO.getPlainAttrMap().get("NAME").getValues().get(0));
 
         statusMod = new StatusMod();
+        statusMod.setKey(userTO.getKey());
         statusMod.setType(StatusMod.ModType.REACTIVATE);
-        userTO = userService.status(userTO.getKey(), statusMod).readEntity(UserTO.class);
+        userTO = userService.status(statusMod).readEntity(UserTO.class);
         assertEquals("active", userTO.getStatus());
 
         connObjectTO = resourceService.readConnObject(RESOURCE_NAME_WS2, AnyTypeKind.USER.name(), userTO.getKey());

http://git-wip-us.apache.org/repos/asf/syncope/blob/5cf6aae8/pom.xml
----------------------------------------------------------------------
diff --git a/pom.xml b/pom.xml
index bc1e2f4..e5d21f4 100644
--- a/pom.xml
+++ b/pom.xml
@@ -336,7 +336,7 @@ under the License.
     <spring-security.version>4.0.2.RELEASE</spring-security.version>
 
     <openjpa.version>2.4.0</openjpa.version>
-    <commons-dbcp.version>2.1</commons-dbcp.version>
+    <commons-dbcp.version>2.1.1</commons-dbcp.version>
     <hibernate-validator.version>5.2.1.Final</hibernate-validator.version>
 
     <jasypt.version>1.9.2</jasypt.version>


[27/31] syncope git commit: Upgrading H2

Posted by md...@apache.org.
Upgrading H2


Project: http://git-wip-us.apache.org/repos/asf/syncope/repo
Commit: http://git-wip-us.apache.org/repos/asf/syncope/commit/dff48fd3
Tree: http://git-wip-us.apache.org/repos/asf/syncope/tree/dff48fd3
Diff: http://git-wip-us.apache.org/repos/asf/syncope/diff/dff48fd3

Branch: refs/heads/SYNCOPE-156
Commit: dff48fd30cbcf14f5404d1c9812d6095b5f4e82e
Parents: 61a371f
Author: Francesco Chicchiriccò <il...@apache.org>
Authored: Thu Aug 13 17:49:12 2015 +0200
Committer: Francesco Chicchiriccò <il...@apache.org>
Committed: Thu Aug 13 17:49:12 2015 +0200

----------------------------------------------------------------------
 pom.xml | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/syncope/blob/dff48fd3/pom.xml
----------------------------------------------------------------------
diff --git a/pom.xml b/pom.xml
index 994d09f..a952b3c 100644
--- a/pom.xml
+++ b/pom.xml
@@ -362,7 +362,7 @@ under the License.
 
     <groovy.version>2.3.10</groovy.version>
 
-    <h2.version>1.4.187</h2.version>
+    <h2.version>1.4.188</h2.version>
 
     <log4j.version>2.3</log4j.version>
     <slf4j.version>1.7.12</slf4j.version>


[09/31] syncope git commit: [SYNCOPE-652] Still several things to refine, but it starts taking shape

Posted by md...@apache.org.
http://git-wip-us.apache.org/repos/asf/syncope/blob/6dfedd8f/core/provisioning-java/src/test/resources/provisioningTest.xml
----------------------------------------------------------------------
diff --git a/core/provisioning-java/src/test/resources/provisioningTest.xml b/core/provisioning-java/src/test/resources/provisioningTest.xml
index b6621c3..54797a5 100644
--- a/core/provisioning-java/src/test/resources/provisioningTest.xml
+++ b/core/provisioning-java/src/test/resources/provisioningTest.xml
@@ -26,6 +26,7 @@ under the License.
     <property name="locations">
       <list>
         <value>classpath:persistence.properties</value>
+        <value>classpath:domains/*.properties</value>
         <value>classpath:security.properties</value>
         <value>classpath:connid.properties</value>
         <value>classpath:mail.properties</value>
@@ -37,10 +38,4 @@ under the License.
     <property name="ignoreUnresolvablePlaceholders" value="true"/>
   </bean>
   
-  <bean id="contentXML" class="org.apache.syncope.core.misc.spring.ResourceWithFallbackLoader">
-    <property name="primary" value="file:${conf.directory}/content.xml"/>
-    <property name="fallback" value="classpath:content.xml"/>
-  </bean>
-  <bean class="org.apache.syncope.core.persistence.jpa.content.XMLContentLoader" init-method="load"/>
-  
 </beans>

http://git-wip-us.apache.org/repos/asf/syncope/blob/6dfedd8f/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/AbstractAnyService.java
----------------------------------------------------------------------
diff --git a/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/AbstractAnyService.java b/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/AbstractAnyService.java
index 600b6d0..d54dbca 100644
--- a/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/AbstractAnyService.java
+++ b/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/AbstractAnyService.java
@@ -18,8 +18,6 @@
  */
 package org.apache.syncope.core.rest.cxf.service;
 
-import static org.apache.syncope.core.rest.cxf.service.AbstractServiceImpl.LOG;
-
 import java.util.List;
 import javax.ws.rs.core.Response;
 import org.apache.commons.collections4.CollectionUtils;
@@ -34,7 +32,7 @@ import org.apache.syncope.common.lib.to.BulkAction;
 import org.apache.syncope.common.lib.to.BulkActionResult;
 import org.apache.syncope.common.lib.to.PagedResult;
 import org.apache.syncope.common.lib.to.PropagationStatus;
-import org.apache.syncope.common.lib.types.ResourceAssociationActionType;
+import org.apache.syncope.common.lib.types.ResourceAssociationAction;
 import org.apache.syncope.common.lib.types.ResourceDeassociationActionType;
 import org.apache.syncope.common.lib.wrap.ResourceKey;
 import org.apache.syncope.common.rest.api.CollectionWrapper;
@@ -129,7 +127,7 @@ public abstract class AbstractAnyService<TO extends AnyTO, MOD extends AnyMod>
     }
 
     @Override
-    public Response bulkDeassociation(
+    public Response deassociate(
             final Long key, final ResourceDeassociationActionType type, final List<ResourceKey> resourceNames) {
 
         TO any = getAnyLogic().read(key);
@@ -174,8 +172,8 @@ public abstract class AbstractAnyService<TO extends AnyTO, MOD extends AnyMod>
     }
 
     @Override
-    public Response bulkAssociation(
-            final Long key, final ResourceAssociationActionType type, final ResourceAssociationMod associationMod) {
+    public Response associate(
+            final Long key, final ResourceAssociationAction type, final ResourceAssociationMod associationMod) {
 
         TO any = getAnyLogic().read(key);
 
@@ -211,7 +209,7 @@ public abstract class AbstractAnyService<TO extends AnyTO, MOD extends AnyMod>
 
         BulkActionResult result = new BulkActionResult();
 
-        if (type == ResourceAssociationActionType.LINK) {
+        if (type == ResourceAssociationAction.LINK) {
             for (ResourceKey resourceName : associationMod.getTargetResources()) {
                 result.getResults().put(resourceName.getElement(),
                         updated.getResources().contains(resourceName.getElement())
@@ -234,7 +232,7 @@ public abstract class AbstractAnyService<TO extends AnyTO, MOD extends AnyMod>
 
         BulkActionResult result = new BulkActionResult();
 
-        switch (bulkAction.getOperation()) {
+        switch (bulkAction.getType()) {
             case DELETE:
                 for (String key : bulkAction.getTargets()) {
                     try {

http://git-wip-us.apache.org/repos/asf/syncope/blob/6dfedd8f/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/ConnectorServiceImpl.java
----------------------------------------------------------------------
diff --git a/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/ConnectorServiceImpl.java b/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/ConnectorServiceImpl.java
index 6725bf9..bc43165 100644
--- a/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/ConnectorServiceImpl.java
+++ b/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/ConnectorServiceImpl.java
@@ -132,7 +132,7 @@ public class ConnectorServiceImpl extends AbstractServiceImpl implements Connect
     public BulkActionResult bulk(final BulkAction bulkAction) {
         BulkActionResult result = new BulkActionResult();
 
-        if (bulkAction.getOperation() == BulkAction.Type.DELETE) {
+        if (bulkAction.getType() == BulkAction.Type.DELETE) {
             for (String key : bulkAction.getTargets()) {
                 try {
                     result.getResults().put(

http://git-wip-us.apache.org/repos/asf/syncope/blob/6dfedd8f/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/ResourceServiceImpl.java
----------------------------------------------------------------------
diff --git a/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/ResourceServiceImpl.java b/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/ResourceServiceImpl.java
index ae7c426..179e021 100644
--- a/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/ResourceServiceImpl.java
+++ b/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/ResourceServiceImpl.java
@@ -144,7 +144,7 @@ public class ResourceServiceImpl extends AbstractServiceImpl implements Resource
     public BulkActionResult bulk(final BulkAction bulkAction) {
         BulkActionResult result = new BulkActionResult();
 
-        if (bulkAction.getOperation() == BulkAction.Type.DELETE) {
+        if (bulkAction.getType() == BulkAction.Type.DELETE) {
             for (String name : bulkAction.getTargets()) {
                 try {
                     result.getResults().put(logic.delete(name).getKey(), BulkActionResult.Status.SUCCESS);

http://git-wip-us.apache.org/repos/asf/syncope/blob/6dfedd8f/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/TaskServiceImpl.java
----------------------------------------------------------------------
diff --git a/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/TaskServiceImpl.java b/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/TaskServiceImpl.java
index 5fb19e2..3acf5c8 100644
--- a/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/TaskServiceImpl.java
+++ b/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/TaskServiceImpl.java
@@ -124,7 +124,7 @@ public class TaskServiceImpl extends AbstractServiceImpl implements TaskService
     public BulkActionResult bulk(final BulkAction bulkAction) {
         BulkActionResult result = new BulkActionResult();
 
-        switch (bulkAction.getOperation()) {
+        switch (bulkAction.getType()) {
             case DELETE:
                 for (String key : bulkAction.getTargets()) {
                     try {

http://git-wip-us.apache.org/repos/asf/syncope/blob/6dfedd8f/core/workflow-activiti/src/main/java/org/apache/syncope/core/workflow/activiti/ActivitiDefinitionLoader.java
----------------------------------------------------------------------
diff --git a/core/workflow-activiti/src/main/java/org/apache/syncope/core/workflow/activiti/ActivitiDefinitionLoader.java b/core/workflow-activiti/src/main/java/org/apache/syncope/core/workflow/activiti/ActivitiDefinitionLoader.java
index 6108b2b..494a03e 100644
--- a/core/workflow-activiti/src/main/java/org/apache/syncope/core/workflow/activiti/ActivitiDefinitionLoader.java
+++ b/core/workflow-activiti/src/main/java/org/apache/syncope/core/workflow/activiti/ActivitiDefinitionLoader.java
@@ -24,15 +24,17 @@ import java.io.ByteArrayInputStream;
 import java.io.IOException;
 import java.io.InputStream;
 import java.util.List;
+import java.util.Map;
 import javax.annotation.Resource;
 import org.activiti.editor.constants.ModelDataJsonConstants;
-import org.activiti.engine.RepositoryService;
+import org.activiti.engine.ProcessEngine;
 import org.activiti.engine.repository.Model;
 import org.activiti.engine.repository.ProcessDefinition;
 import org.activiti.spring.SpringProcessEngineConfiguration;
 import org.apache.commons.io.IOUtils;
 import org.apache.syncope.core.misc.spring.ResourceWithFallbackLoader;
 import org.apache.syncope.core.persistence.api.SyncopeLoader;
+import org.apache.syncope.core.workflow.activiti.spring.DomainProcessEngine;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.springframework.beans.factory.annotation.Autowired;
@@ -47,13 +49,7 @@ public class ActivitiDefinitionLoader implements SyncopeLoader {
     private ResourceWithFallbackLoader userWorkflowDef;
 
     @Autowired
-    private RepositoryService repositoryService;
-
-    @Autowired
-    private SpringProcessEngineConfiguration conf;
-
-    @Autowired
-    private ActivitiImportUtils importUtils;
+    private DomainProcessEngine dpEngine;
 
     @Override
     public Integer getPriority() {
@@ -62,22 +58,34 @@ public class ActivitiDefinitionLoader implements SyncopeLoader {
 
     @Override
     public void load() {
-        List<ProcessDefinition> processes = repositoryService.createProcessDefinitionQuery().processDefinitionKey(
-                ActivitiUserWorkflowAdapter.WF_PROCESS_ID).list();
-        LOG.debug(ActivitiUserWorkflowAdapter.WF_PROCESS_ID + " Activiti processes in repository: {}", processes);
+        byte[] wfDef = new byte[0];
 
-        // Only loads process definition from file if not found in repository
-        if (processes.isEmpty()) {
-            InputStream wfIn = null;
-            try {
-                wfIn = userWorkflowDef.getResource().getInputStream();
-                repositoryService.createDeployment().addInputStream(ActivitiUserWorkflowAdapter.WF_PROCESS_RESOURCE,
-                        new ByteArrayInputStream(IOUtils.toByteArray(wfIn))).deploy();
+        InputStream wfIn = null;
+        try {
+            wfIn = userWorkflowDef.getResource().getInputStream();
+            wfDef = IOUtils.toByteArray(wfIn);
+        } catch (IOException e) {
+            LOG.error("While loading " + ActivitiUserWorkflowAdapter.WF_PROCESS_RESOURCE, e);
+        } finally {
+            IOUtils.closeQuietly(wfIn);
+        }
 
-                ProcessDefinition procDef = repositoryService.createProcessDefinitionQuery().processDefinitionKey(
-                        ActivitiUserWorkflowAdapter.WF_PROCESS_ID).latestVersion().singleResult();
+        for (Map.Entry<String, ProcessEngine> entry : dpEngine.getEngines().entrySet()) {
+            List<ProcessDefinition> processes = entry.getValue().getRepositoryService().
+                    createProcessDefinitionQuery().processDefinitionKey(ActivitiUserWorkflowAdapter.WF_PROCESS_ID).
+                    list();
+            LOG.debug(ActivitiUserWorkflowAdapter.WF_PROCESS_ID + " Activiti processes in repository: {}", processes);
 
-                Model model = repositoryService.newModel();
+            // Only loads process definition from file if not found in repository
+            if (processes.isEmpty()) {
+                entry.getValue().getRepositoryService().createDeployment().addInputStream(
+                        ActivitiUserWorkflowAdapter.WF_PROCESS_RESOURCE, new ByteArrayInputStream(wfDef)).deploy();
+
+                ProcessDefinition procDef = entry.getValue().getRepositoryService().createProcessDefinitionQuery().
+                        processDefinitionKey(ActivitiUserWorkflowAdapter.WF_PROCESS_ID).latestVersion().
+                        singleResult();
+
+                Model model = entry.getValue().getRepositoryService().newModel();
                 ObjectNode modelObjectNode = new ObjectMapper().createObjectNode();
                 modelObjectNode.put(ModelDataJsonConstants.MODEL_NAME, procDef.getName());
                 modelObjectNode.put(ModelDataJsonConstants.MODEL_REVISION, 1);
@@ -85,19 +93,16 @@ public class ActivitiDefinitionLoader implements SyncopeLoader {
                 model.setMetaInfo(modelObjectNode.toString());
                 model.setName(procDef.getName());
                 model.setDeploymentId(procDef.getDeploymentId());
-                importUtils.fromJSON(procDef, model);
+                ActivitiImportUtils.fromJSON(entry.getValue(), procDef, model);
 
-                LOG.debug("Activiti Workflow definition loaded");
-            } catch (IOException e) {
-                LOG.error("While loading " + ActivitiUserWorkflowAdapter.WF_PROCESS_RESOURCE, e);
-            } finally {
-                IOUtils.closeQuietly(wfIn);
+                LOG.debug("Activiti Workflow definition loaded for domain {}", entry.getKey());
             }
-        }
 
-        // jump to the next ID block
-        for (int i = 0; i < conf.getIdBlockSize(); i++) {
-            conf.getIdGenerator().getNextId();
+            // jump to the next ID block
+            for (int i = 0; i < entry.getValue().getProcessEngineConfiguration().getIdBlockSize(); i++) {
+                SpringProcessEngineConfiguration.class.cast(entry.getValue().getProcessEngineConfiguration()).
+                        getIdGenerator().getNextId();
+            }
         }
     }
 }

http://git-wip-us.apache.org/repos/asf/syncope/blob/6dfedd8f/core/workflow-activiti/src/main/java/org/apache/syncope/core/workflow/activiti/ActivitiImportUtils.java
----------------------------------------------------------------------
diff --git a/core/workflow-activiti/src/main/java/org/apache/syncope/core/workflow/activiti/ActivitiImportUtils.java b/core/workflow-activiti/src/main/java/org/apache/syncope/core/workflow/activiti/ActivitiImportUtils.java
index 973584d..5df8ac4 100644
--- a/core/workflow-activiti/src/main/java/org/apache/syncope/core/workflow/activiti/ActivitiImportUtils.java
+++ b/core/workflow-activiti/src/main/java/org/apache/syncope/core/workflow/activiti/ActivitiImportUtils.java
@@ -28,53 +28,50 @@ import org.activiti.bpmn.converter.BpmnXMLConverter;
 import org.activiti.bpmn.model.BpmnModel;
 import org.activiti.editor.language.json.converter.BpmnJsonConverter;
 import org.activiti.engine.ActivitiException;
-import org.activiti.engine.RepositoryService;
+import org.activiti.engine.ProcessEngine;
 import org.activiti.engine.repository.Model;
 import org.activiti.engine.repository.ProcessDefinition;
 import org.apache.commons.io.IOUtils;
 import org.apache.syncope.core.workflow.api.WorkflowException;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.stereotype.Component;
 
-@Component
-public class ActivitiImportUtils {
+public final class ActivitiImportUtils {
 
-    @Autowired
-    private RepositoryService repositoryService;
-
-    public void fromXML(final byte[] definition) {
+    public static void fromXML(final ProcessEngine engine, final byte[] definition) {
         try {
-            repositoryService.createDeployment().addInputStream(ActivitiUserWorkflowAdapter.WF_PROCESS_RESOURCE,
-                    new ByteArrayInputStream(definition)).deploy();
+            engine.getRepositoryService().createDeployment().
+                    addInputStream(ActivitiUserWorkflowAdapter.WF_PROCESS_RESOURCE,
+                            new ByteArrayInputStream(definition)).deploy();
         } catch (ActivitiException e) {
             throw new WorkflowException("While updating process " + ActivitiUserWorkflowAdapter.WF_PROCESS_RESOURCE, e);
         }
     }
 
-    public void fromJSON(final byte[] definition, final ProcessDefinition procDef, final Model model) {
+    public static void fromJSON(
+            final ProcessEngine engine, final byte[] definition, final ProcessDefinition procDef, final Model model) {
+
         try {
             model.setVersion(procDef.getVersion());
             model.setDeploymentId(procDef.getDeploymentId());
-            repositoryService.saveModel(model);
+            engine.getRepositoryService().saveModel(model);
 
-            repositoryService.addModelEditorSource(model.getId(), definition);
+            engine.getRepositoryService().addModelEditorSource(model.getId(), definition);
         } catch (Exception e) {
             throw new WorkflowException("While updating process " + ActivitiUserWorkflowAdapter.WF_PROCESS_RESOURCE, e);
         }
     }
 
-    public void fromJSON(final ProcessDefinition procDef, final Model model) {
+    public static void fromJSON(final ProcessEngine engine, final ProcessDefinition procDef, final Model model) {
         InputStream bpmnStream = null;
         InputStreamReader isr = null;
         XMLStreamReader xtr = null;
         try {
-            bpmnStream = repositoryService.getResourceAsStream(
+            bpmnStream = engine.getRepositoryService().getResourceAsStream(
                     procDef.getDeploymentId(), procDef.getResourceName());
             isr = new InputStreamReader(bpmnStream);
             xtr = XMLInputFactory.newInstance().createXMLStreamReader(isr);
             BpmnModel bpmnModel = new BpmnXMLConverter().convertToBpmnModel(xtr);
 
-            fromJSON(new BpmnJsonConverter().convertToJson(bpmnModel).toString().getBytes(), procDef, model);
+            fromJSON(engine, new BpmnJsonConverter().convertToJson(bpmnModel).toString().getBytes(), procDef, model);
         } catch (Exception e) {
             throw new WorkflowException("While updating process " + ActivitiUserWorkflowAdapter.WF_PROCESS_RESOURCE, e);
         } finally {
@@ -89,4 +86,8 @@ public class ActivitiImportUtils {
             IOUtils.closeQuietly(bpmnStream);
         }
     }
+
+    private ActivitiImportUtils() {
+        // private constructor for static utility class
+    }
 }

http://git-wip-us.apache.org/repos/asf/syncope/blob/6dfedd8f/core/workflow-activiti/src/main/java/org/apache/syncope/core/workflow/activiti/ActivitiUserWorkflowAdapter.java
----------------------------------------------------------------------
diff --git a/core/workflow-activiti/src/main/java/org/apache/syncope/core/workflow/activiti/ActivitiUserWorkflowAdapter.java b/core/workflow-activiti/src/main/java/org/apache/syncope/core/workflow/activiti/ActivitiUserWorkflowAdapter.java
index c124c05..1ce0d97 100644
--- a/core/workflow-activiti/src/main/java/org/apache/syncope/core/workflow/activiti/ActivitiUserWorkflowAdapter.java
+++ b/core/workflow-activiti/src/main/java/org/apache/syncope/core/workflow/activiti/ActivitiUserWorkflowAdapter.java
@@ -38,11 +38,7 @@ import org.activiti.bpmn.model.BpmnModel;
 import org.activiti.editor.constants.ModelDataJsonConstants;
 import org.activiti.editor.language.json.converter.BpmnJsonConverter;
 import org.activiti.engine.ActivitiException;
-import org.activiti.engine.FormService;
-import org.activiti.engine.HistoryService;
-import org.activiti.engine.RepositoryService;
-import org.activiti.engine.RuntimeService;
-import org.activiti.engine.TaskService;
+import org.activiti.engine.ProcessEngine;
 import org.activiti.engine.form.FormProperty;
 import org.activiti.engine.form.FormType;
 import org.activiti.engine.form.TaskFormData;
@@ -136,22 +132,7 @@ public class ActivitiUserWorkflowAdapter extends AbstractUserWorkflowAdapter {
     protected String adminUser;
 
     @Autowired
-    protected RuntimeService runtimeService;
-
-    @Autowired
-    protected TaskService taskService;
-
-    @Autowired
-    protected FormService formService;
-
-    @Autowired
-    protected HistoryService historyService;
-
-    @Autowired
-    protected RepositoryService repositoryService;
-
-    @Autowired
-    protected ActivitiImportUtils importUtils;
+    protected ProcessEngine engine;
 
     @Autowired
     protected UserDataBinder userDataBinder;
@@ -176,7 +157,7 @@ public class ActivitiUserWorkflowAdapter extends AbstractUserWorkflowAdapter {
     }
 
     protected void updateStatus(final User user) {
-        List<Task> tasks = taskService.createTaskQuery().processInstanceId(user.getWorkflowId()).list();
+        List<Task> tasks = engine.getTaskService().createTaskQuery().processInstanceId(user.getWorkflowId()).list();
         if (tasks.isEmpty() || tasks.size() > 1) {
             LOG.warn("While setting user status: unexpected task number ({})", tasks.size());
         } else {
@@ -187,12 +168,12 @@ public class ActivitiUserWorkflowAdapter extends AbstractUserWorkflowAdapter {
     protected String getFormTask(final User user) {
         String result = null;
 
-        List<Task> tasks = taskService.createTaskQuery().processInstanceId(user.getWorkflowId()).list();
+        List<Task> tasks = engine.getTaskService().createTaskQuery().processInstanceId(user.getWorkflowId()).list();
         if (tasks.isEmpty() || tasks.size() > 1) {
             LOG.warn("While checking if form task: unexpected task number ({})", tasks.size());
         } else {
             try {
-                TaskFormData formData = formService.getTaskFormData(tasks.get(0).getId());
+                TaskFormData formData = engine.getFormService().getTaskFormData(tasks.get(0).getId());
                 if (formData != null && !formData.getFormProperties().isEmpty()) {
                     result = tasks.get(0).getId();
                 }
@@ -207,8 +188,8 @@ public class ActivitiUserWorkflowAdapter extends AbstractUserWorkflowAdapter {
     protected Set<String> getPerformedTasks(final User user) {
         final Set<String> result = new HashSet<>();
 
-        for (HistoricActivityInstance task
-                : historyService.createHistoricActivityInstanceQuery().executionId(user.getWorkflowId()).list()) {
+        for (HistoricActivityInstance task : engine.getHistoryService().createHistoricActivityInstanceQuery().
+                executionId(user.getWorkflowId()).list()) {
 
             result.add(task.getActivityId());
         }
@@ -223,14 +204,14 @@ public class ActivitiUserWorkflowAdapter extends AbstractUserWorkflowAdapter {
         String formTaskId = getFormTask(user);
         if (formTaskId != null) {
             // SYNCOPE-238: This is needed to simplify the task query in this.getForms()
-            taskService.setVariableLocal(formTaskId, TASK_IS_FORM, Boolean.TRUE);
-            runtimeService.setVariable(user.getWorkflowId(), PROP_BY_RESOURCE, propByRes);
+            engine.getTaskService().setVariableLocal(formTaskId, TASK_IS_FORM, Boolean.TRUE);
+            engine.getRuntimeService().setVariable(user.getWorkflowId(), PROP_BY_RESOURCE, propByRes);
             if (propByRes != null) {
                 propByRes.clear();
             }
 
             if (StringUtils.isNotBlank(password)) {
-                runtimeService.setVariable(user.getWorkflowId(), ENCRYPTED_PWD, encrypt(password));
+                engine.getRuntimeService().setVariable(user.getWorkflowId(), ENCRYPTED_PWD, encrypt(password));
             }
         }
     }
@@ -259,15 +240,15 @@ public class ActivitiUserWorkflowAdapter extends AbstractUserWorkflowAdapter {
 
         ProcessInstance processInstance = null;
         try {
-            processInstance = runtimeService.startProcessInstanceByKey(WF_PROCESS_ID, variables);
+            processInstance = engine.getRuntimeService().startProcessInstanceByKey(WF_PROCESS_ID, variables);
         } catch (ActivitiException e) {
             throwException(e, "While starting " + WF_PROCESS_ID + " instance");
         }
 
-        User user = runtimeService.getVariable(processInstance.getProcessInstanceId(), USER, User.class);
+        User user = engine.getRuntimeService().getVariable(processInstance.getProcessInstanceId(), USER, User.class);
 
         Boolean updatedEnabled =
-                runtimeService.getVariable(processInstance.getProcessInstanceId(), ENABLED, Boolean.class);
+                engine.getRuntimeService().getVariable(processInstance.getProcessInstanceId(), ENABLED, Boolean.class);
         if (updatedEnabled != null) {
             user.setSuspended(!updatedEnabled);
         }
@@ -280,8 +261,8 @@ public class ActivitiUserWorkflowAdapter extends AbstractUserWorkflowAdapter {
         updateStatus(user);
         user = userDAO.save(user);
 
-        Boolean propagateEnable =
-                runtimeService.getVariable(processInstance.getProcessInstanceId(), PROPAGATE_ENABLE, Boolean.class);
+        Boolean propagateEnable = engine.getRuntimeService().getVariable(
+                processInstance.getProcessInstanceId(), PROPAGATE_ENABLE, Boolean.class);
         if (propagateEnable == null) {
             propagateEnable = enabled;
         }
@@ -315,10 +296,10 @@ public class ActivitiUserWorkflowAdapter extends AbstractUserWorkflowAdapter {
             throw new WorkflowException(new NotFoundException("Empty workflow id for " + user));
         }
 
-        List<Task> tasks = taskService.createTaskQuery().processInstanceId(user.getWorkflowId()).list();
+        List<Task> tasks = engine.getTaskService().createTaskQuery().processInstanceId(user.getWorkflowId()).list();
         if (tasks.size() == 1) {
             try {
-                taskService.complete(tasks.get(0).getId(), variables);
+                engine.getTaskService().complete(tasks.get(0).getId(), variables);
             } catch (ActivitiException e) {
                 throwException(e, "While completing task '" + tasks.get(0).getName() + "' for " + user);
             }
@@ -349,14 +330,15 @@ public class ActivitiUserWorkflowAdapter extends AbstractUserWorkflowAdapter {
         updateStatus(user);
         User updated = userDAO.save(user);
 
-        PropagationByResource propByRes =
-                runtimeService.getVariable(user.getWorkflowId(), PROP_BY_RESOURCE, PropagationByResource.class);
-        UserMod updatedMod =
-                runtimeService.getVariable(user.getWorkflowId(), USER_MOD, UserMod.class);
+        PropagationByResource propByRes = engine.getRuntimeService().getVariable(
+                user.getWorkflowId(), PROP_BY_RESOURCE, PropagationByResource.class);
+        UserMod updatedMod = engine.getRuntimeService().getVariable(
+                user.getWorkflowId(), USER_MOD, UserMod.class);
 
         saveForFormSubmit(updated, updatedMod.getPassword(), propByRes);
 
-        Boolean propagateEnable = runtimeService.getVariable(user.getWorkflowId(), PROPAGATE_ENABLE, Boolean.class);
+        Boolean propagateEnable = engine.getRuntimeService().getVariable(
+                user.getWorkflowId(), PROPAGATE_ENABLE, Boolean.class);
 
         return new WorkflowResult<Pair<UserMod, Boolean>>(
                 new ImmutablePair<>(updatedMod, propagateEnable), propByRes, tasks);
@@ -413,15 +395,15 @@ public class ActivitiUserWorkflowAdapter extends AbstractUserWorkflowAdapter {
 
         saveForFormSubmit(user, null, propByRes);
 
-        if (runtimeService.createProcessInstanceQuery().
+        if (engine.getRuntimeService().createProcessInstanceQuery().
                 processInstanceId(user.getWorkflowId()).active().list().isEmpty()) {
 
             userDAO.delete(user.getKey());
 
-            if (!historyService.createHistoricProcessInstanceQuery().
+            if (!engine.getHistoryService().createHistoricProcessInstanceQuery().
                     processInstanceId(user.getWorkflowId()).list().isEmpty()) {
 
-                historyService.deleteHistoricProcessInstance(user.getWorkflowId());
+                engine.getHistoryService().deleteHistoricProcessInstance(user.getWorkflowId());
             }
         } else {
             updateStatus(user);
@@ -445,7 +427,7 @@ public class ActivitiUserWorkflowAdapter extends AbstractUserWorkflowAdapter {
 
     protected ProcessDefinition getProcessDefinition() {
         try {
-            return repositoryService.createProcessDefinitionQuery().processDefinitionKey(
+            return engine.getRepositoryService().createProcessDefinitionQuery().processDefinitionKey(
                     ActivitiUserWorkflowAdapter.WF_PROCESS_ID).latestVersion().singleResult();
         } catch (ActivitiException e) {
             throw new WorkflowException("While accessing process " + ActivitiUserWorkflowAdapter.WF_PROCESS_ID, e);
@@ -455,7 +437,8 @@ public class ActivitiUserWorkflowAdapter extends AbstractUserWorkflowAdapter {
 
     protected Model getModel(final ProcessDefinition procDef) {
         try {
-            Model model = repositoryService.createModelQuery().deploymentId(procDef.getDeploymentId()).singleResult();
+            Model model = engine.getRepositoryService().createModelQuery().
+                    deploymentId(procDef.getDeploymentId()).singleResult();
             if (model == null) {
                 throw new NotFoundException("Could not find Model for deployment " + procDef.getDeploymentId());
             }
@@ -468,7 +451,8 @@ public class ActivitiUserWorkflowAdapter extends AbstractUserWorkflowAdapter {
     protected void exportProcessResource(final String resourceName, final OutputStream os) {
         ProcessDefinition procDef = getProcessDefinition();
 
-        InputStream procDefIS = repositoryService.getResourceAsStream(procDef.getDeploymentId(), resourceName);
+        InputStream procDefIS = engine.getRepositoryService().getResourceAsStream(procDef.getDeploymentId(),
+                resourceName);
         try {
             IOUtils.copy(procDefIS, os);
         } catch (IOException e) {
@@ -486,7 +470,7 @@ public class ActivitiUserWorkflowAdapter extends AbstractUserWorkflowAdapter {
             ObjectNode modelNode = (ObjectNode) objectMapper.readTree(model.getMetaInfo());
             modelNode.put(ModelDataJsonConstants.MODEL_ID, model.getId());
             modelNode.replace(MODEL_DATA_JSON_MODEL,
-                    objectMapper.readTree(repositoryService.getModelEditorSource(model.getId())));
+                    objectMapper.readTree(engine.getRepositoryService().getModelEditorSource(model.getId())));
 
             os.write(modelNode.toString().getBytes());
         } catch (IOException e) {
@@ -529,20 +513,21 @@ public class ActivitiUserWorkflowAdapter extends AbstractUserWorkflowAdapter {
                     }
 
                     BpmnModel bpmnModel = new BpmnJsonConverter().convertToBpmnModel(definitionNode);
-                    importUtils.fromXML(new BpmnXMLConverter().convertToXML(bpmnModel));
+                    ActivitiImportUtils.fromXML(engine, new BpmnXMLConverter().convertToXML(bpmnModel));
                 } catch (Exception e) {
                     throw new WorkflowException("While updating process "
                             + ActivitiUserWorkflowAdapter.WF_PROCESS_RESOURCE, e);
                 }
 
-                importUtils.fromJSON(definitionNode.toString().getBytes(), getProcessDefinition(), model);
+                ActivitiImportUtils.fromJSON(
+                        engine, definitionNode.toString().getBytes(), getProcessDefinition(), model);
                 break;
 
             case XML:
             default:
-                importUtils.fromXML(definition.getBytes());
+                ActivitiImportUtils.fromXML(engine, definition.getBytes());
 
-                importUtils.fromJSON(getProcessDefinition(), model);
+                ActivitiImportUtils.fromJSON(engine, getProcessDefinition(), model);
         }
     }
 
@@ -569,7 +554,7 @@ public class ActivitiUserWorkflowAdapter extends AbstractUserWorkflowAdapter {
     }
 
     protected WorkflowFormTO getFormTO(final Task task) {
-        return getFormTO(task, formService.getTaskFormData(task.getId()));
+        return getFormTO(task, engine.getFormService().getTaskFormData(task.getId()));
     }
 
     protected WorkflowFormTO getFormTO(final Task task, final TaskFormData fd) {
@@ -583,7 +568,8 @@ public class ActivitiUserWorkflowAdapter extends AbstractUserWorkflowAdapter {
     protected WorkflowFormTO getFormTO(final HistoricTaskInstance task) {
         final List<HistoricFormPropertyEntity> props = new ArrayList<>();
 
-        for (HistoricDetail historicDetail : historyService.createHistoricDetailQuery().taskId(task.getId()).list()) {
+        for (HistoricDetail historicDetail
+                : engine.getHistoryService().createHistoricDetailQuery().taskId(task.getId()).list()) {
 
             if (historicDetail instanceof HistoricFormPropertyEntity) {
                 props.add((HistoricFormPropertyEntity) historicDetail);
@@ -594,7 +580,8 @@ public class ActivitiUserWorkflowAdapter extends AbstractUserWorkflowAdapter {
                 task.getProcessInstanceId(), task.getId(), task.getFormKey(), props);
         BeanUtils.copyProperties(task, formTO);
 
-        final HistoricActivityInstance historicActivityInstance = historyService.createHistoricActivityInstanceQuery().
+        final HistoricActivityInstance historicActivityInstance = engine.getHistoryService().
+                createHistoricActivityInstanceQuery().
                 executionId(task.getExecutionId()).activityType("userTask").activityName(task.getName()).singleResult();
 
         if (historicActivityInstance != null) {
@@ -676,7 +663,7 @@ public class ActivitiUserWorkflowAdapter extends AbstractUserWorkflowAdapter {
 
         final String authUser = AuthContextUtils.getUsername();
         if (adminUser.equals(authUser)) {
-            forms.addAll(getForms(taskService.createTaskQuery().
+            forms.addAll(getForms(engine.getTaskService().createTaskQuery().
                     taskVariableValueEquals(TASK_IS_FORM, Boolean.TRUE)));
         } else {
             User user = userDAO.find(authUser);
@@ -684,7 +671,7 @@ public class ActivitiUserWorkflowAdapter extends AbstractUserWorkflowAdapter {
                 throw new NotFoundException("Syncope User " + authUser);
             }
 
-            forms.addAll(getForms(taskService.createTaskQuery().
+            forms.addAll(getForms(engine.getTaskService().createTaskQuery().
                     taskVariableValueEquals(TASK_IS_FORM, Boolean.TRUE).
                     taskCandidateOrAssigned(user.getKey().toString())));
 
@@ -693,7 +680,7 @@ public class ActivitiUserWorkflowAdapter extends AbstractUserWorkflowAdapter {
                 candidateGroups.add(groupId.toString());
             }
             if (!candidateGroups.isEmpty()) {
-                forms.addAll(getForms(taskService.createTaskQuery().
+                forms.addAll(getForms(engine.getTaskService().createTaskQuery().
                         taskVariableValueEquals(TASK_IS_FORM, Boolean.TRUE).
                         taskCandidateGroupIn(candidateGroups)));
             }
@@ -705,10 +692,10 @@ public class ActivitiUserWorkflowAdapter extends AbstractUserWorkflowAdapter {
     @Override
     public List<WorkflowFormTO> getForms(final String workflowId, final String name) {
         List<WorkflowFormTO> forms = getForms(
-                taskService.createTaskQuery().processInstanceId(workflowId).taskName(name).
+                engine.getTaskService().createTaskQuery().processInstanceId(workflowId).taskName(name).
                 taskVariableValueEquals(TASK_IS_FORM, Boolean.TRUE));
 
-        forms.addAll(getForms(historyService.createHistoricTaskInstanceQuery().taskName(name).
+        forms.addAll(getForms(engine.getHistoryService().createHistoricTaskInstanceQuery().taskName(name).
                 taskVariableValueEquals(TASK_IS_FORM, Boolean.TRUE)));
 
         return forms;
@@ -739,14 +726,14 @@ public class ActivitiUserWorkflowAdapter extends AbstractUserWorkflowAdapter {
     public WorkflowFormTO getForm(final String workflowId) {
         Task task;
         try {
-            task = taskService.createTaskQuery().processInstanceId(workflowId).singleResult();
+            task = engine.getTaskService().createTaskQuery().processInstanceId(workflowId).singleResult();
         } catch (ActivitiException e) {
             throw new WorkflowException("While reading form for workflow instance " + workflowId, e);
         }
 
         TaskFormData formData;
         try {
-            formData = formService.getTaskFormData(task.getId());
+            formData = engine.getFormService().getTaskFormData(task.getId());
         } catch (ActivitiException e) {
             LOG.debug("No form found for task {}", task.getId(), e);
             formData = null;
@@ -763,14 +750,14 @@ public class ActivitiUserWorkflowAdapter extends AbstractUserWorkflowAdapter {
     protected Pair<Task, TaskFormData> checkTask(final String taskId, final String authUser) {
         Task task;
         try {
-            task = taskService.createTaskQuery().taskId(taskId).singleResult();
+            task = engine.getTaskService().createTaskQuery().taskId(taskId).singleResult();
         } catch (ActivitiException e) {
             throw new NotFoundException("Activiti Task " + taskId, e);
         }
 
         TaskFormData formData;
         try {
-            formData = formService.getTaskFormData(task.getId());
+            formData = engine.getFormService().getTaskFormData(task.getId());
         } catch (ActivitiException e) {
             throw new NotFoundException("Form for Activiti Task " + taskId, e);
         }
@@ -792,7 +779,8 @@ public class ActivitiUserWorkflowAdapter extends AbstractUserWorkflowAdapter {
         Pair<Task, TaskFormData> checked = checkTask(taskId, authUser);
 
         if (!adminUser.equals(authUser)) {
-            List<Task> tasksForUser = taskService.createTaskQuery().taskId(taskId).taskCandidateUser(authUser).list();
+            List<Task> tasksForUser = engine.getTaskService().createTaskQuery().taskId(taskId).taskCandidateUser(
+                    authUser).list();
             if (tasksForUser.isEmpty()) {
                 throw new WorkflowException(
                         new IllegalArgumentException(authUser + " is not candidate for task " + taskId));
@@ -801,8 +789,8 @@ public class ActivitiUserWorkflowAdapter extends AbstractUserWorkflowAdapter {
 
         Task task;
         try {
-            taskService.setOwner(taskId, authUser);
-            task = taskService.createTaskQuery().taskId(taskId).singleResult();
+            engine.getTaskService().setOwner(taskId, authUser);
+            task = engine.getTaskService().createTaskQuery().taskId(taskId).singleResult();
         } catch (ActivitiException e) {
             throw new WorkflowException("While reading task " + taskId, e);
         }
@@ -828,8 +816,8 @@ public class ActivitiUserWorkflowAdapter extends AbstractUserWorkflowAdapter {
 
         Set<String> preTasks = getPerformedTasks(user);
         try {
-            formService.submitTaskFormData(form.getTaskId(), form.getPropertiesForSubmit());
-            runtimeService.setVariable(user.getWorkflowId(), FORM_SUBMITTER, authUser);
+            engine.getFormService().submitTaskFormData(form.getTaskId(), form.getPropertiesForSubmit());
+            engine.getRuntimeService().setVariable(user.getWorkflowId(), FORM_SUBMITTER, authUser);
         } catch (ActivitiException e) {
             throwException(e, "While submitting form for task " + form.getTaskId());
         }
@@ -842,12 +830,12 @@ public class ActivitiUserWorkflowAdapter extends AbstractUserWorkflowAdapter {
         User updated = userDAO.save(user);
 
         // see if there is any propagation to be done
-        PropagationByResource propByRes =
-                runtimeService.getVariable(user.getWorkflowId(), PROP_BY_RESOURCE, PropagationByResource.class);
+        PropagationByResource propByRes = engine.getRuntimeService().getVariable(
+                user.getWorkflowId(), PROP_BY_RESOURCE, PropagationByResource.class);
 
         // fetch - if available - the encrypted password
         String clearPassword = null;
-        String encryptedPwd = runtimeService.getVariable(user.getWorkflowId(), ENCRYPTED_PWD, String.class);
+        String encryptedPwd = engine.getRuntimeService().getVariable(user.getWorkflowId(), ENCRYPTED_PWD, String.class);
         if (StringUtils.isNotBlank(encryptedPwd)) {
             clearPassword = decrypt(encryptedPwd);
         }
@@ -855,7 +843,7 @@ public class ActivitiUserWorkflowAdapter extends AbstractUserWorkflowAdapter {
         // supports approval chains
         saveForFormSubmit(user, clearPassword, propByRes);
 
-        UserMod userMod = runtimeService.getVariable(user.getWorkflowId(), USER_MOD, UserMod.class);
+        UserMod userMod = engine.getRuntimeService().getVariable(user.getWorkflowId(), USER_MOD, UserMod.class);
         if (userMod == null) {
             userMod = new UserMod();
             userMod.setKey(updated.getKey());

http://git-wip-us.apache.org/repos/asf/syncope/blob/6dfedd8f/core/workflow-activiti/src/main/java/org/apache/syncope/core/workflow/activiti/spring/DomainProcessEngine.java
----------------------------------------------------------------------
diff --git a/core/workflow-activiti/src/main/java/org/apache/syncope/core/workflow/activiti/spring/DomainProcessEngine.java b/core/workflow-activiti/src/main/java/org/apache/syncope/core/workflow/activiti/spring/DomainProcessEngine.java
new file mode 100644
index 0000000..83619c7
--- /dev/null
+++ b/core/workflow-activiti/src/main/java/org/apache/syncope/core/workflow/activiti/spring/DomainProcessEngine.java
@@ -0,0 +1,102 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.syncope.core.workflow.activiti.spring;
+
+import java.util.Collections;
+import java.util.Map;
+import org.activiti.engine.FormService;
+import org.activiti.engine.HistoryService;
+import org.activiti.engine.IdentityService;
+import org.activiti.engine.ManagementService;
+import org.activiti.engine.ProcessEngine;
+import org.activiti.engine.ProcessEngineConfiguration;
+import org.activiti.engine.RepositoryService;
+import org.activiti.engine.RuntimeService;
+import org.activiti.engine.TaskService;
+import org.apache.syncope.core.misc.security.AuthContextUtils;
+
+/**
+ * {@link ProcessEngine} delegating actual method invocation to the inner map of {@link ProcessEngine} instances,
+ * one for each Syncope domain.
+ */
+public class DomainProcessEngine implements ProcessEngine {
+
+    private final Map<String, ProcessEngine> engines;
+
+    public DomainProcessEngine(final Map<String, ProcessEngine> engines) {
+        this.engines = Collections.synchronizedMap(engines);
+    }
+
+    public Map<String, ProcessEngine> getEngines() {
+        return engines;
+    }
+
+    @Override
+    public String getName() {
+        return engines.get(AuthContextUtils.getDomain()).getName();
+    }
+
+    @Override
+    public void close() {
+        for (ProcessEngine engine : engines.values()) {
+            engine.close();
+        }
+    }
+
+    @Override
+    public RepositoryService getRepositoryService() {
+        return engines.get(AuthContextUtils.getDomain()).getRepositoryService();
+    }
+
+    @Override
+    public RuntimeService getRuntimeService() {
+        return engines.get(AuthContextUtils.getDomain()).getRuntimeService();
+    }
+
+    @Override
+    public FormService getFormService() {
+        return engines.get(AuthContextUtils.getDomain()).getFormService();
+    }
+
+    @Override
+    public TaskService getTaskService() {
+        return engines.get(AuthContextUtils.getDomain()).getTaskService();
+    }
+
+    @Override
+    public HistoryService getHistoryService() {
+        return engines.get(AuthContextUtils.getDomain()).getHistoryService();
+    }
+
+    @Override
+    public IdentityService getIdentityService() {
+        return engines.get(AuthContextUtils.getDomain()).getIdentityService();
+    }
+
+    @Override
+    public ManagementService getManagementService() {
+        return engines.get(AuthContextUtils.getDomain()).getManagementService();
+    }
+
+    @Override
+    public ProcessEngineConfiguration getProcessEngineConfiguration() {
+        return engines.get(AuthContextUtils.getDomain()).getProcessEngineConfiguration();
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/6dfedd8f/core/workflow-activiti/src/main/java/org/apache/syncope/core/workflow/activiti/spring/DomainProcessEngineFactoryBean.java
----------------------------------------------------------------------
diff --git a/core/workflow-activiti/src/main/java/org/apache/syncope/core/workflow/activiti/spring/DomainProcessEngineFactoryBean.java b/core/workflow-activiti/src/main/java/org/apache/syncope/core/workflow/activiti/spring/DomainProcessEngineFactoryBean.java
new file mode 100644
index 0000000..cf112bd
--- /dev/null
+++ b/core/workflow-activiti/src/main/java/org/apache/syncope/core/workflow/activiti/spring/DomainProcessEngineFactoryBean.java
@@ -0,0 +1,104 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.syncope.core.workflow.activiti.spring;
+
+import java.util.HashMap;
+import java.util.Map;
+import javax.sql.DataSource;
+import org.activiti.engine.ProcessEngine;
+import org.activiti.engine.impl.cfg.SpringBeanFactoryProxyMap;
+import org.activiti.spring.SpringExpressionManager;
+import org.activiti.spring.SpringProcessEngineConfiguration;
+import org.apache.commons.lang3.StringUtils;
+import org.springframework.beans.BeansException;
+import org.springframework.beans.factory.DisposableBean;
+import org.springframework.beans.factory.FactoryBean;
+import org.springframework.context.ApplicationContext;
+import org.springframework.context.ApplicationContextAware;
+import org.springframework.transaction.PlatformTransactionManager;
+
+/**
+ * Spring factory for {@link DomainProcessEngine} which takes the provided {@link SpringProcessEngineConfiguration} as
+ * template for each of the configured Syncope domains.
+ */
+public class DomainProcessEngineFactoryBean
+        implements FactoryBean<DomainProcessEngine>, DisposableBean, ApplicationContextAware {
+
+    private ApplicationContext ctx;
+
+    private DomainProcessEngine engine;
+
+    @Override
+    public void setApplicationContext(final ApplicationContext ctx) throws BeansException {
+        this.ctx = ctx;
+    }
+
+    @Override
+    public DomainProcessEngine getObject() throws Exception {
+        if (engine == null) {
+            Map<String, ProcessEngine> engines = new HashMap<>();
+
+            for (Map.Entry<String, DataSource> entry : ctx.getBeansOfType(DataSource.class).entrySet()) {
+                if (!entry.getKey().startsWith("local")) {
+                    String domain = StringUtils.substringBefore(entry.getKey(), DataSource.class.getSimpleName());
+                    DataSource dataSource = entry.getValue();
+                    PlatformTransactionManager transactionManager = ctx.getBean(
+                            domain + "TransactionManager", PlatformTransactionManager.class);
+                    Object entityManagerFactory = ctx.getBean(domain + "EntityManagerFactory");
+
+                    SpringProcessEngineConfiguration conf = ctx.getBean(SpringProcessEngineConfiguration.class);
+                    conf.setDataSource(dataSource);
+                    conf.setTransactionManager(transactionManager);
+                    conf.setTransactionsExternallyManaged(true);
+                    conf.setJpaEntityManagerFactory(entityManagerFactory);
+                    if (conf.getBeans() == null) {
+                        conf.setBeans(new SpringBeanFactoryProxyMap(ctx));
+                    }
+                    if (conf.getExpressionManager() == null) {
+                        conf.setExpressionManager(new SpringExpressionManager(ctx, conf.getBeans()));
+                    }
+
+                    engines.put(domain, conf.buildProcessEngine());
+                }
+            }
+
+            engine = new DomainProcessEngine(engines);
+        }
+
+        return engine;
+    }
+
+    @Override
+    public Class<DomainProcessEngine> getObjectType() {
+        return DomainProcessEngine.class;
+    }
+
+    @Override
+    public boolean isSingleton() {
+        return true;
+    }
+
+    @Override
+    public void destroy() throws Exception {
+        if (engine != null) {
+            engine.close();
+        }
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/6dfedd8f/core/workflow-activiti/src/main/java/org/apache/syncope/core/workflow/activiti/task/AbstractActivitiServiceTask.java
----------------------------------------------------------------------
diff --git a/core/workflow-activiti/src/main/java/org/apache/syncope/core/workflow/activiti/task/AbstractActivitiServiceTask.java b/core/workflow-activiti/src/main/java/org/apache/syncope/core/workflow/activiti/task/AbstractActivitiServiceTask.java
index 85a0ac0..ff898ad 100644
--- a/core/workflow-activiti/src/main/java/org/apache/syncope/core/workflow/activiti/task/AbstractActivitiServiceTask.java
+++ b/core/workflow-activiti/src/main/java/org/apache/syncope/core/workflow/activiti/task/AbstractActivitiServiceTask.java
@@ -18,7 +18,7 @@
  */
 package org.apache.syncope.core.workflow.activiti.task;
 
-import org.activiti.engine.RuntimeService;
+import org.activiti.engine.ProcessEngine;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.springframework.beans.factory.annotation.Autowired;
@@ -31,13 +31,10 @@ import org.springframework.transaction.annotation.Transactional;
 @Component
 public abstract class AbstractActivitiServiceTask {
 
-    /**
-     * Logger.
-     */
     protected static final Logger LOG = LoggerFactory.getLogger(AbstractActivitiServiceTask.class);
 
     @Autowired
-    protected RuntimeService runtimeService;
+    protected ProcessEngine engine;
 
     @Transactional(rollbackFor = { Throwable.class })
     public void execute(final String executionId) {

http://git-wip-us.apache.org/repos/asf/syncope/blob/6dfedd8f/core/workflow-activiti/src/main/java/org/apache/syncope/core/workflow/activiti/task/AutoActivate.java
----------------------------------------------------------------------
diff --git a/core/workflow-activiti/src/main/java/org/apache/syncope/core/workflow/activiti/task/AutoActivate.java b/core/workflow-activiti/src/main/java/org/apache/syncope/core/workflow/activiti/task/AutoActivate.java
index 370e6e3..51dfb50 100644
--- a/core/workflow-activiti/src/main/java/org/apache/syncope/core/workflow/activiti/task/AutoActivate.java
+++ b/core/workflow-activiti/src/main/java/org/apache/syncope/core/workflow/activiti/task/AutoActivate.java
@@ -26,6 +26,6 @@ public class AutoActivate extends AbstractActivitiServiceTask {
 
     @Override
     protected void doExecute(final String executionId) {
-        runtimeService.setVariable(executionId, ActivitiUserWorkflowAdapter.PROPAGATE_ENABLE, Boolean.TRUE);
+        engine.getRuntimeService().setVariable(executionId, ActivitiUserWorkflowAdapter.PROPAGATE_ENABLE, Boolean.TRUE);
     }
 }

http://git-wip-us.apache.org/repos/asf/syncope/blob/6dfedd8f/core/workflow-activiti/src/main/java/org/apache/syncope/core/workflow/activiti/task/Create.java
----------------------------------------------------------------------
diff --git a/core/workflow-activiti/src/main/java/org/apache/syncope/core/workflow/activiti/task/Create.java b/core/workflow-activiti/src/main/java/org/apache/syncope/core/workflow/activiti/task/Create.java
index adf36ad..e911f98 100644
--- a/core/workflow-activiti/src/main/java/org/apache/syncope/core/workflow/activiti/task/Create.java
+++ b/core/workflow-activiti/src/main/java/org/apache/syncope/core/workflow/activiti/task/Create.java
@@ -37,15 +37,17 @@ public class Create extends AbstractActivitiServiceTask {
 
     @Override
     protected void doExecute(final String executionId) {
-        UserTO userTO = runtimeService.getVariable(executionId, ActivitiUserWorkflowAdapter.USER_TO, UserTO.class);
+        UserTO userTO = engine.getRuntimeService().
+                getVariable(executionId, ActivitiUserWorkflowAdapter.USER_TO, UserTO.class);
         Boolean storePassword =
-                runtimeService.getVariable(executionId, ActivitiUserWorkflowAdapter.STORE_PASSWORD, Boolean.class);
+                engine.getRuntimeService().
+                getVariable(executionId, ActivitiUserWorkflowAdapter.STORE_PASSWORD, Boolean.class);
         // create and set workflow id
         User user = entityFactory.newEntity(User.class);
         dataBinder.create(user, userTO, storePassword == null ? true : storePassword);
         user.setWorkflowId(executionId);
 
         // report user as result
-        runtimeService.setVariable(executionId, ActivitiUserWorkflowAdapter.USER, user);
+        engine.getRuntimeService().setVariable(executionId, ActivitiUserWorkflowAdapter.USER, user);
     }
 }

http://git-wip-us.apache.org/repos/asf/syncope/blob/6dfedd8f/core/workflow-activiti/src/main/java/org/apache/syncope/core/workflow/activiti/task/Delete.java
----------------------------------------------------------------------
diff --git a/core/workflow-activiti/src/main/java/org/apache/syncope/core/workflow/activiti/task/Delete.java b/core/workflow-activiti/src/main/java/org/apache/syncope/core/workflow/activiti/task/Delete.java
index d386388..7933751 100644
--- a/core/workflow-activiti/src/main/java/org/apache/syncope/core/workflow/activiti/task/Delete.java
+++ b/core/workflow-activiti/src/main/java/org/apache/syncope/core/workflow/activiti/task/Delete.java
@@ -27,7 +27,8 @@ public class Delete extends AbstractActivitiServiceTask {
 
     @Override
     protected void doExecute(final String executionId) {
-        User user = runtimeService.getVariable(executionId, ActivitiUserWorkflowAdapter.USER, User.class);
+        User user = engine.getRuntimeService().
+                getVariable(executionId, ActivitiUserWorkflowAdapter.USER, User.class);
 
         // Do something with user...
         if (user != null) {
@@ -35,6 +36,6 @@ public class Delete extends AbstractActivitiServiceTask {
         }
 
         // remove user variable
-        runtimeService.removeVariable(executionId, ActivitiUserWorkflowAdapter.USER);
+        engine.getRuntimeService().removeVariable(executionId, ActivitiUserWorkflowAdapter.USER);
     }
 }

http://git-wip-us.apache.org/repos/asf/syncope/blob/6dfedd8f/core/workflow-activiti/src/main/java/org/apache/syncope/core/workflow/activiti/task/GenerateToken.java
----------------------------------------------------------------------
diff --git a/core/workflow-activiti/src/main/java/org/apache/syncope/core/workflow/activiti/task/GenerateToken.java b/core/workflow-activiti/src/main/java/org/apache/syncope/core/workflow/activiti/task/GenerateToken.java
index dcbcfd0..9ce6941 100644
--- a/core/workflow-activiti/src/main/java/org/apache/syncope/core/workflow/activiti/task/GenerateToken.java
+++ b/core/workflow-activiti/src/main/java/org/apache/syncope/core/workflow/activiti/task/GenerateToken.java
@@ -32,12 +32,13 @@ public class GenerateToken extends AbstractActivitiServiceTask {
 
     @Override
     protected void doExecute(final String executionId) {
-        User user = runtimeService.getVariable(executionId, ActivitiUserWorkflowAdapter.USER, User.class);
+        User user = engine.getRuntimeService().
+                getVariable(executionId, ActivitiUserWorkflowAdapter.USER, User.class);
 
         user.generateToken(
                 confDAO.find("token.length", "256").getValues().get(0).getLongValue().intValue(),
                 confDAO.find("token.expireTime", "60").getValues().get(0).getLongValue().intValue());
 
-        runtimeService.setVariable(executionId, ActivitiUserWorkflowAdapter.USER, user);
+        engine.getRuntimeService().setVariable(executionId, ActivitiUserWorkflowAdapter.USER, user);
     }
 }

http://git-wip-us.apache.org/repos/asf/syncope/blob/6dfedd8f/core/workflow-activiti/src/main/java/org/apache/syncope/core/workflow/activiti/task/Notify.java
----------------------------------------------------------------------
diff --git a/core/workflow-activiti/src/main/java/org/apache/syncope/core/workflow/activiti/task/Notify.java b/core/workflow-activiti/src/main/java/org/apache/syncope/core/workflow/activiti/task/Notify.java
index 3c886fe..54e7852 100644
--- a/core/workflow-activiti/src/main/java/org/apache/syncope/core/workflow/activiti/task/Notify.java
+++ b/core/workflow-activiti/src/main/java/org/apache/syncope/core/workflow/activiti/task/Notify.java
@@ -40,9 +40,12 @@ public class Notify extends AbstractActivitiServiceTask {
 
     @Override
     protected void doExecute(final String executionId) {
-        User user = runtimeService.getVariable(executionId, ActivitiUserWorkflowAdapter.USER, User.class);
-        UserTO userTO = runtimeService.getVariable(executionId, ActivitiUserWorkflowAdapter.USER_TO, UserTO.class);
-        String event = runtimeService.getVariable(executionId, ActivitiUserWorkflowAdapter.EVENT, String.class);
+        User user = engine.getRuntimeService().
+                getVariable(executionId, ActivitiUserWorkflowAdapter.USER, User.class);
+        UserTO userTO = engine.getRuntimeService().
+                getVariable(executionId, ActivitiUserWorkflowAdapter.USER_TO, UserTO.class);
+        String event = engine.getRuntimeService().
+                getVariable(executionId, ActivitiUserWorkflowAdapter.EVENT, String.class);
 
         if (StringUtils.isNotBlank(event)) {
             notificationManager.createTasks(

http://git-wip-us.apache.org/repos/asf/syncope/blob/6dfedd8f/core/workflow-activiti/src/main/java/org/apache/syncope/core/workflow/activiti/task/PasswordReset.java
----------------------------------------------------------------------
diff --git a/core/workflow-activiti/src/main/java/org/apache/syncope/core/workflow/activiti/task/PasswordReset.java b/core/workflow-activiti/src/main/java/org/apache/syncope/core/workflow/activiti/task/PasswordReset.java
index 2fc8097..10e9afe 100644
--- a/core/workflow-activiti/src/main/java/org/apache/syncope/core/workflow/activiti/task/PasswordReset.java
+++ b/core/workflow-activiti/src/main/java/org/apache/syncope/core/workflow/activiti/task/PasswordReset.java
@@ -28,9 +28,12 @@ public class PasswordReset extends AbstractActivitiServiceTask {
 
     @Override
     protected void doExecute(final String executionId) {
-        User user = runtimeService.getVariable(executionId, ActivitiUserWorkflowAdapter.USER, User.class);
-        String token = runtimeService.getVariable(executionId, ActivitiUserWorkflowAdapter.TOKEN, String.class);
-        String password = runtimeService.getVariable(executionId, ActivitiUserWorkflowAdapter.PASSWORD, String.class);
+        User user = engine.getRuntimeService().
+                getVariable(executionId, ActivitiUserWorkflowAdapter.USER, User.class);
+        String token = engine.getRuntimeService().
+                getVariable(executionId, ActivitiUserWorkflowAdapter.TOKEN, String.class);
+        String password = engine.getRuntimeService().
+                getVariable(executionId, ActivitiUserWorkflowAdapter.PASSWORD, String.class);
 
         if (!user.checkToken(token)) {
             throw new WorkflowException(new IllegalArgumentException("Wrong token: " + token + " for " + user));
@@ -38,7 +41,7 @@ public class PasswordReset extends AbstractActivitiServiceTask {
 
         user.removeToken();
         user.setPassword(password, user.getCipherAlgorithm());
-        runtimeService.setVariable(executionId, ActivitiUserWorkflowAdapter.USER, user);
+        engine.getRuntimeService().setVariable(executionId, ActivitiUserWorkflowAdapter.USER, user);
     }
 
 }

http://git-wip-us.apache.org/repos/asf/syncope/blob/6dfedd8f/core/workflow-activiti/src/main/java/org/apache/syncope/core/workflow/activiti/task/Update.java
----------------------------------------------------------------------
diff --git a/core/workflow-activiti/src/main/java/org/apache/syncope/core/workflow/activiti/task/Update.java b/core/workflow-activiti/src/main/java/org/apache/syncope/core/workflow/activiti/task/Update.java
index 4da56c6..e4ee649 100644
--- a/core/workflow-activiti/src/main/java/org/apache/syncope/core/workflow/activiti/task/Update.java
+++ b/core/workflow-activiti/src/main/java/org/apache/syncope/core/workflow/activiti/task/Update.java
@@ -35,9 +35,11 @@ public class Update extends AbstractActivitiServiceTask {
 
     @Override
     protected void doExecute(final String executionId) {
-        User user = runtimeService.getVariable(executionId, ActivitiUserWorkflowAdapter.USER, User.class);
+        User user = engine.getRuntimeService().
+                getVariable(executionId, ActivitiUserWorkflowAdapter.USER, User.class);
         UserMod userMod =
-                runtimeService.getVariable(executionId, ActivitiUserWorkflowAdapter.USER_MOD, UserMod.class);
+                engine.getRuntimeService().
+                getVariable(executionId, ActivitiUserWorkflowAdapter.USER_MOD, UserMod.class);
 
         // update password internally only if required
         UserMod updatedMod = SerializationUtils.clone(userMod);
@@ -50,8 +52,8 @@ public class Update extends AbstractActivitiServiceTask {
         updatedMod.setPassword(updatedPwd);
 
         // report updated user and propagation by resource as result
-        runtimeService.setVariable(executionId, ActivitiUserWorkflowAdapter.USER, user);
-        runtimeService.setVariable(executionId, ActivitiUserWorkflowAdapter.USER_MOD, updatedMod);
-        runtimeService.setVariable(executionId, ActivitiUserWorkflowAdapter.PROP_BY_RESOURCE, propByRes);
+        engine.getRuntimeService().setVariable(executionId, ActivitiUserWorkflowAdapter.USER, user);
+        engine.getRuntimeService().setVariable(executionId, ActivitiUserWorkflowAdapter.USER_MOD, updatedMod);
+        engine.getRuntimeService().setVariable(executionId, ActivitiUserWorkflowAdapter.PROP_BY_RESOURCE, propByRes);
     }
 }

http://git-wip-us.apache.org/repos/asf/syncope/blob/6dfedd8f/core/workflow-activiti/src/main/resources/workflowActivitiContext.xml
----------------------------------------------------------------------
diff --git a/core/workflow-activiti/src/main/resources/workflowActivitiContext.xml b/core/workflow-activiti/src/main/resources/workflowActivitiContext.xml
index 75f0c38..81058e1 100644
--- a/core/workflow-activiti/src/main/resources/workflowActivitiContext.xml
+++ b/core/workflow-activiti/src/main/resources/workflowActivitiContext.xml
@@ -35,13 +35,10 @@ under the License.
   <bean id="syncopeActivitiUserManager" class="org.apache.syncope.core.workflow.activiti.SyncopeUserManager"/>
   <bean id="syncopeActivitiGroupManager" class="org.apache.syncope.core.workflow.activiti.SyncopeGroupManager"/>
 
-  <bean id="processEngineConfiguration" class="org.activiti.spring.SpringProcessEngineConfiguration">
-    <property name="dataSource" ref="dataSource"/>
-    <property name="transactionManager" ref="transactionManager"/>
+  <bean class="org.activiti.spring.SpringProcessEngineConfiguration" scope="prototype">
     <property name="transactionsExternallyManaged" value="true"/>
     <property name="databaseSchemaUpdate" value="true"/>
 
-    <property name="jpaEntityManagerFactory" ref="entityManagerFactory"/>
     <property name="jpaHandleTransaction" value="true"/>
     <property name="jpaCloseEntityManager" value="false"/>
 
@@ -64,17 +61,7 @@ under the License.
     </property>
   </bean>
 
-  <bean id="processEngine" class="org.activiti.spring.ProcessEngineFactoryBean">
-    <property name="processEngineConfiguration" ref="processEngineConfiguration"/>
-  </bean>
-
-  <bean id="repositoryService" factory-bean="processEngine" factory-method="getRepositoryService"/>
-  <bean id="runtimeService" factory-bean="processEngine" factory-method="getRuntimeService"/>
-  <bean id="taskService" factory-bean="processEngine" factory-method="getTaskService"/>
-  <bean id="historyService" factory-bean="processEngine" factory-method="getHistoryService"/>
-  <bean id="managementService" factory-bean="processEngine" factory-method="getManagementService"/>
-  <bean id="identityService" factory-bean="processEngine" factory-method="getIdentityService"/>
-  <bean id="formService" factory-bean="processEngine" factory-method="getFormService"/>
+  <bean class="org.apache.syncope.core.workflow.activiti.spring.DomainProcessEngineFactoryBean"/>
 
   <context:component-scan base-package="org.apache.syncope.core.workflow.activiti"/>
     

http://git-wip-us.apache.org/repos/asf/syncope/blob/6dfedd8f/core/workflow-api/src/main/java/org/apache/syncope/core/workflow/api/UserWorkflowAdapter.java
----------------------------------------------------------------------
diff --git a/core/workflow-api/src/main/java/org/apache/syncope/core/workflow/api/UserWorkflowAdapter.java b/core/workflow-api/src/main/java/org/apache/syncope/core/workflow/api/UserWorkflowAdapter.java
index 0d7c86a..fbf29c3 100644
--- a/core/workflow-api/src/main/java/org/apache/syncope/core/workflow/api/UserWorkflowAdapter.java
+++ b/core/workflow-api/src/main/java/org/apache/syncope/core/workflow/api/UserWorkflowAdapter.java
@@ -90,15 +90,15 @@ public interface UserWorkflowAdapter extends WorkflowAdapter {
     /**
      * Suspend an user.
      *
-     * @param userKey user to be suspended
+     * @param key to be suspended
      * @return user just suspended
      */
-    WorkflowResult<Long> suspend(Long userKey);
+    WorkflowResult<Long> suspend(Long key);
 
     /**
      * Suspend an user.
      *
-     * @param user to be suspended
+     * @param user user to be suspended
      * @return user just suspended
      */
     WorkflowResult<Long> suspend(User user);

http://git-wip-us.apache.org/repos/asf/syncope/blob/6dfedd8f/core/workflow-java/src/main/java/org/apache/syncope/core/workflow/java/AbstractAnyObjectWorkflowAdapter.java
----------------------------------------------------------------------
diff --git a/core/workflow-java/src/main/java/org/apache/syncope/core/workflow/java/AbstractAnyObjectWorkflowAdapter.java b/core/workflow-java/src/main/java/org/apache/syncope/core/workflow/java/AbstractAnyObjectWorkflowAdapter.java
index ef15ab0..3f0d61a 100644
--- a/core/workflow-java/src/main/java/org/apache/syncope/core/workflow/java/AbstractAnyObjectWorkflowAdapter.java
+++ b/core/workflow-java/src/main/java/org/apache/syncope/core/workflow/java/AbstractAnyObjectWorkflowAdapter.java
@@ -26,9 +26,10 @@ import org.apache.syncope.core.provisioning.api.WorkflowResult;
 import org.apache.syncope.core.provisioning.api.data.AnyObjectDataBinder;
 import org.apache.syncope.core.workflow.api.AnyObjectWorkflowAdapter;
 import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.transaction.annotation.Propagation;
 import org.springframework.transaction.annotation.Transactional;
 
-@Transactional(rollbackFor = { Throwable.class })
+@Transactional(propagation = Propagation.REQUIRES_NEW, rollbackFor = { Throwable.class })
 public abstract class AbstractAnyObjectWorkflowAdapter implements AnyObjectWorkflowAdapter {
 
     @Autowired

http://git-wip-us.apache.org/repos/asf/syncope/blob/6dfedd8f/core/workflow-java/src/main/java/org/apache/syncope/core/workflow/java/AbstractGroupWorkflowAdapter.java
----------------------------------------------------------------------
diff --git a/core/workflow-java/src/main/java/org/apache/syncope/core/workflow/java/AbstractGroupWorkflowAdapter.java b/core/workflow-java/src/main/java/org/apache/syncope/core/workflow/java/AbstractGroupWorkflowAdapter.java
index 97a8b1f..2b921ce 100644
--- a/core/workflow-java/src/main/java/org/apache/syncope/core/workflow/java/AbstractGroupWorkflowAdapter.java
+++ b/core/workflow-java/src/main/java/org/apache/syncope/core/workflow/java/AbstractGroupWorkflowAdapter.java
@@ -26,9 +26,10 @@ import org.apache.syncope.core.provisioning.api.WorkflowResult;
 import org.apache.syncope.core.provisioning.api.data.GroupDataBinder;
 import org.apache.syncope.core.workflow.api.GroupWorkflowAdapter;
 import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.transaction.annotation.Propagation;
 import org.springframework.transaction.annotation.Transactional;
 
-@Transactional(rollbackFor = { Throwable.class })
+@Transactional(propagation = Propagation.REQUIRES_NEW, rollbackFor = { Throwable.class })
 public abstract class AbstractGroupWorkflowAdapter implements GroupWorkflowAdapter {
 
     @Autowired

http://git-wip-us.apache.org/repos/asf/syncope/blob/6dfedd8f/core/workflow-java/src/main/java/org/apache/syncope/core/workflow/java/AbstractUserWorkflowAdapter.java
----------------------------------------------------------------------
diff --git a/core/workflow-java/src/main/java/org/apache/syncope/core/workflow/java/AbstractUserWorkflowAdapter.java b/core/workflow-java/src/main/java/org/apache/syncope/core/workflow/java/AbstractUserWorkflowAdapter.java
index fc75987..ecc1c01 100644
--- a/core/workflow-java/src/main/java/org/apache/syncope/core/workflow/java/AbstractUserWorkflowAdapter.java
+++ b/core/workflow-java/src/main/java/org/apache/syncope/core/workflow/java/AbstractUserWorkflowAdapter.java
@@ -29,9 +29,10 @@ import org.apache.syncope.core.workflow.api.UserWorkflowAdapter;
 import org.identityconnectors.common.Base64;
 import org.identityconnectors.common.security.EncryptorFactory;
 import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.transaction.annotation.Propagation;
 import org.springframework.transaction.annotation.Transactional;
 
-@Transactional(rollbackFor = { Throwable.class })
+@Transactional(propagation = Propagation.REQUIRES_NEW, rollbackFor = { Throwable.class })
 public abstract class AbstractUserWorkflowAdapter implements UserWorkflowAdapter {
 
     @Autowired

http://git-wip-us.apache.org/repos/asf/syncope/blob/6dfedd8f/core/workflow-java/src/main/java/org/apache/syncope/core/workflow/java/DefaultUserWorkflowAdapter.java
----------------------------------------------------------------------
diff --git a/core/workflow-java/src/main/java/org/apache/syncope/core/workflow/java/DefaultUserWorkflowAdapter.java b/core/workflow-java/src/main/java/org/apache/syncope/core/workflow/java/DefaultUserWorkflowAdapter.java
index 78360a9..3d56daf 100644
--- a/core/workflow-java/src/main/java/org/apache/syncope/core/workflow/java/DefaultUserWorkflowAdapter.java
+++ b/core/workflow-java/src/main/java/org/apache/syncope/core/workflow/java/DefaultUserWorkflowAdapter.java
@@ -35,12 +35,10 @@ import org.apache.syncope.core.provisioning.api.WorkflowResult;
 import org.apache.syncope.core.workflow.api.WorkflowDefinitionFormat;
 import org.apache.syncope.core.workflow.api.WorkflowException;
 import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.transaction.annotation.Transactional;
 
 /**
  * Simple implementation basically not involving any workflow engine.
  */
-@Transactional(rollbackFor = { Throwable.class })
 public class DefaultUserWorkflowAdapter extends AbstractUserWorkflowAdapter {
 
     @Autowired

http://git-wip-us.apache.org/repos/asf/syncope/blob/6dfedd8f/ext/camel/logic/src/main/java/org/apache/syncope/core/logic/init/CamelRouteLoader.java
----------------------------------------------------------------------
diff --git a/ext/camel/logic/src/main/java/org/apache/syncope/core/logic/init/CamelRouteLoader.java b/ext/camel/logic/src/main/java/org/apache/syncope/core/logic/init/CamelRouteLoader.java
index 4359e7b..97bb299 100644
--- a/ext/camel/logic/src/main/java/org/apache/syncope/core/logic/init/CamelRouteLoader.java
+++ b/ext/camel/logic/src/main/java/org/apache/syncope/core/logic/init/CamelRouteLoader.java
@@ -24,6 +24,7 @@ import java.util.Map;
 import javax.sql.DataSource;
 import org.apache.syncope.common.lib.types.AnyTypeKind;
 import org.apache.syncope.core.misc.spring.ResourceWithFallbackLoader;
+import org.apache.syncope.core.persistence.api.DomainsHolder;
 import org.apache.syncope.core.persistence.api.SyncopeLoader;
 import org.apache.syncope.core.persistence.api.entity.CamelEntityFactory;
 import org.apache.syncope.core.persistence.api.entity.CamelRoute;
@@ -60,7 +61,7 @@ public class CamelRouteLoader implements SyncopeLoader {
     private ResourceWithFallbackLoader anyObjectRoutesLoader;
 
     @Autowired
-    private DataSource dataSource;
+    private DomainsHolder domainsHolder;
 
     @Autowired
     private CamelEntityFactory entityFactory;
@@ -77,15 +78,20 @@ public class CamelRouteLoader implements SyncopeLoader {
     public void load() {
         synchronized (this) {
             if (!loaded) {
-                loadRoutes(userRoutesLoader.getResource(), AnyTypeKind.USER);
-                loadRoutes(groupRoutesLoader.getResource(), AnyTypeKind.GROUP);
-                loadRoutes(anyObjectRoutesLoader.getResource(), AnyTypeKind.ANY_OBJECT);
+                for (Map.Entry<String, DataSource> entry : domainsHolder.getDomains().entrySet()) {
+                    loadRoutes(entry.getKey(), entry.getValue(),
+                            userRoutesLoader.getResource(), AnyTypeKind.USER);
+                    loadRoutes(entry.getKey(), entry.getValue(),
+                            groupRoutesLoader.getResource(), AnyTypeKind.GROUP);
+                    loadRoutes(entry.getKey(), entry.getValue(),
+                            anyObjectRoutesLoader.getResource(), AnyTypeKind.ANY_OBJECT);
+                }
                 loaded = true;
             }
         }
     }
 
-    private boolean loadRoutesFor(final AnyTypeKind anyTypeKind) {
+    private boolean loadRoutesFor(final DataSource dataSource, final AnyTypeKind anyTypeKind) {
         final String sql = String.format("SELECT * FROM %s WHERE ANYTYPEKIND = ?", CamelRoute.class.getSimpleName());
         final JdbcTemplate jdbcTemplate = new JdbcTemplate(dataSource);
         final List<Map<String, Object>> rows = jdbcTemplate.queryForList(sql, new Object[] { anyTypeKind.name() });
@@ -106,8 +112,10 @@ public class CamelRouteLoader implements SyncopeLoader {
         return writer.toString();
     }
 
-    private void loadRoutes(final Resource resource, final AnyTypeKind anyTypeKind) {
-        if (loadRoutesFor(anyTypeKind)) {
+    private void loadRoutes(
+            final String domain, final DataSource dataSource, final Resource resource, final AnyTypeKind anyTypeKind) {
+
+        if (loadRoutesFor(dataSource, anyTypeKind)) {
             String query = String.format("INSERT INTO %s(NAME, ANYTYPEKIND, CONTENT) VALUES (?, ?, ?)",
                     CamelRoute.class.getSimpleName());
             JdbcTemplate jdbcTemplate = new JdbcTemplate(dataSource);
@@ -132,12 +140,12 @@ public class CamelRouteLoader implements SyncopeLoader {
                     route.setContent(routeContent);
 
                     jdbcTemplate.update(query, new Object[] { routeId, anyTypeKind.name(), routeContent });
-                    LOG.info("Route successfully loaded: {}", routeId);
+                    LOG.info("[{}] Route successfully loaded: {}", domain, routeId);
                 }
             } catch (DataAccessException e) {
-                LOG.error("While trying to store queries {}", e);
+                LOG.error("[{}] While trying to store queries", domain, e);
             } catch (Exception e) {
-                LOG.error("Route load failed {}", e.getMessage());
+                LOG.error("[{}] Route load failed {}", domain, e.getMessage());
             }
         }
     }

http://git-wip-us.apache.org/repos/asf/syncope/blob/6dfedd8f/ext/camel/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPACamelRouteDAO.java
----------------------------------------------------------------------
diff --git a/ext/camel/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPACamelRouteDAO.java b/ext/camel/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPACamelRouteDAO.java
index e9f2c72..8894992 100644
--- a/ext/camel/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPACamelRouteDAO.java
+++ b/ext/camel/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPACamelRouteDAO.java
@@ -32,13 +32,13 @@ public class JPACamelRouteDAO extends AbstractDAO<CamelRoute, String> implements
 
     @Override
     public CamelRoute find(final String key) {
-        return entityManager.find(JPACamelRoute.class, key);
+        return entityManager().find(JPACamelRoute.class, key);
     }
 
     @Transactional(readOnly = true)
     @Override
     public List<CamelRoute> find(final AnyTypeKind anyTypeKind) {
-        TypedQuery<CamelRoute> query = entityManager.createQuery(
+        TypedQuery<CamelRoute> query = entityManager().createQuery(
                 "SELECT e FROM " + JPACamelRoute.class.getSimpleName()
                 + " e WHERE e.anyTypeKind = :anyTypeKind", CamelRoute.class);
         query.setParameter("anyTypeKind", anyTypeKind);
@@ -49,21 +49,21 @@ public class JPACamelRouteDAO extends AbstractDAO<CamelRoute, String> implements
     @Transactional(readOnly = true)
     @Override
     public List<CamelRoute> findAll() {
-        TypedQuery<CamelRoute> query = entityManager.createQuery(
+        TypedQuery<CamelRoute> query = entityManager().createQuery(
                 "SELECT e FROM " + JPACamelRoute.class.getSimpleName() + " e ", CamelRoute.class);
         return query.getResultList();
     }
 
     @Override
     public CamelRoute save(final CamelRoute route) {
-        return entityManager.merge(route);
+        return entityManager().merge(route);
     }
 
     @Override
     public void delete(final String key) {
         CamelRoute route = find(key);
         if (route != null) {
-            entityManager.remove(route);
+            entityManager().remove(route);
         }
     }
 

http://git-wip-us.apache.org/repos/asf/syncope/blob/6dfedd8f/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/CamelAnyObjectProvisioningManager.java
----------------------------------------------------------------------
diff --git a/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/CamelAnyObjectProvisioningManager.java b/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/CamelAnyObjectProvisioningManager.java
index ae29501..bb01cd3 100644
--- a/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/CamelAnyObjectProvisioningManager.java
+++ b/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/CamelAnyObjectProvisioningManager.java
@@ -143,6 +143,25 @@ public class CamelAnyObjectProvisioningManager
 
     @Override
     @SuppressWarnings("unchecked")
+    public List<PropagationStatus> provision(final Long key, final Collection<String> resources) {
+        PollingConsumer pollingConsumer = getConsumer("direct:provisionAnyObjectPort");
+
+        Map<String, Object> props = new HashMap<>();
+        props.put("resources", resources);
+
+        sendMessage("direct:provisionAnyObject", key, props);
+
+        Exchange exchange = pollingConsumer.receive();
+
+        if (exchange.getProperty(Exchange.EXCEPTION_CAUGHT) != null) {
+            throw (RuntimeException) exchange.getProperty(Exchange.EXCEPTION_CAUGHT);
+        }
+
+        return exchange.getIn().getBody(List.class);
+    }
+
+    @Override
+    @SuppressWarnings("unchecked")
     public List<PropagationStatus> deprovision(final Long anyObjectKey, final Collection<String> resources) {
         PollingConsumer pollingConsumer = getConsumer("direct:deprovisionAnyObjectPort");
 

http://git-wip-us.apache.org/repos/asf/syncope/blob/6dfedd8f/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/CamelGroupProvisioningManager.java
----------------------------------------------------------------------
diff --git a/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/CamelGroupProvisioningManager.java b/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/CamelGroupProvisioningManager.java
index f97203a..bc0c854 100644
--- a/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/CamelGroupProvisioningManager.java
+++ b/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/CamelGroupProvisioningManager.java
@@ -163,13 +163,32 @@ public class CamelGroupProvisioningManager
 
     @Override
     @SuppressWarnings("unchecked")
-    public List<PropagationStatus> deprovision(final Long groupKey, final Collection<String> resources) {
+    public List<PropagationStatus> provision(final Long key, final Collection<String> resources) {
+        PollingConsumer pollingConsumer = getConsumer("direct:provisionGroupPort");
+
+        Map<String, Object> props = new HashMap<>();
+        props.put("resources", resources);
+
+        sendMessage("direct:provisionGroup", key, props);
+
+        Exchange exchange = pollingConsumer.receive();
+
+        if (exchange.getProperty(Exchange.EXCEPTION_CAUGHT) != null) {
+            throw (RuntimeException) exchange.getProperty(Exchange.EXCEPTION_CAUGHT);
+        }
+
+        return exchange.getIn().getBody(List.class);
+    }
+    
+    @Override
+    @SuppressWarnings("unchecked")
+    public List<PropagationStatus> deprovision(final Long key, final Collection<String> resources) {
         PollingConsumer pollingConsumer = getConsumer("direct:deprovisionGroupPort");
 
         Map<String, Object> props = new HashMap<>();
         props.put("resources", resources);
 
-        sendMessage("direct:deprovisionGroup", groupKey, props);
+        sendMessage("direct:deprovisionGroup", key, props);
 
         Exchange exchange = pollingConsumer.receive();
 


[02/31] syncope git commit: Fix as per CXF-6499

Posted by md...@apache.org.
Fix as per CXF-6499


Project: http://git-wip-us.apache.org/repos/asf/syncope/repo
Commit: http://git-wip-us.apache.org/repos/asf/syncope/commit/0d6187d1
Tree: http://git-wip-us.apache.org/repos/asf/syncope/tree/0d6187d1
Diff: http://git-wip-us.apache.org/repos/asf/syncope/diff/0d6187d1

Branch: refs/heads/SYNCOPE-156
Commit: 0d6187d1ff992e563bda761a91e69649f4e950f7
Parents: 252b151
Author: Francesco Chicchiriccò <il...@apache.org>
Authored: Fri Jul 17 15:27:14 2015 +0200
Committer: Francesco Chicchiriccò <il...@apache.org>
Committed: Thu Aug 13 17:16:50 2015 +0200

----------------------------------------------------------------------
 core/rest-cxf/src/main/resources/restCXFContext.xml | 1 +
 1 file changed, 1 insertion(+)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/syncope/blob/0d6187d1/core/rest-cxf/src/main/resources/restCXFContext.xml
----------------------------------------------------------------------
diff --git a/core/rest-cxf/src/main/resources/restCXFContext.xml b/core/rest-cxf/src/main/resources/restCXFContext.xml
index 5818422..b26ed2e 100644
--- a/core/rest-cxf/src/main/resources/restCXFContext.xml
+++ b/core/rest-cxf/src/main/resources/restCXFContext.xml
@@ -85,6 +85,7 @@ under the License.
     <property name="useJaxbContextForQnames" value="true"/>
     <property name="ignoreMessageWriters" value="true"/>
     <property name="addResourceAndMethodIds" value="true"/>
+    <property name="usePathParamsToCompareOperations" value="false"/>
     <property name="javaDocPath" value="/WEB-INF/lib/syncope-common-rest-api-${syncope.version}-javadoc.jar"/>
   </bean>
   


[05/31] syncope git commit: [SYNCOPE-652] More test improvements

Posted by md...@apache.org.
[SYNCOPE-652] More test improvements


Project: http://git-wip-us.apache.org/repos/asf/syncope/repo
Commit: http://git-wip-us.apache.org/repos/asf/syncope/commit/e199fbae
Tree: http://git-wip-us.apache.org/repos/asf/syncope/tree/e199fbae
Diff: http://git-wip-us.apache.org/repos/asf/syncope/diff/e199fbae

Branch: refs/heads/SYNCOPE-156
Commit: e199fbaeca4e30bd9b288b6c54b0a466c486eb47
Parents: 554b725
Author: Francesco Chicchiriccò <il...@apache.org>
Authored: Thu Aug 13 16:59:12 2015 +0200
Committer: Francesco Chicchiriccò <il...@apache.org>
Committed: Thu Aug 13 17:16:51 2015 +0200

----------------------------------------------------------------------
 .../fit/core/reference/AbstractTaskITCase.java      | 16 +++++++++-------
 1 file changed, 9 insertions(+), 7 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/syncope/blob/e199fbae/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/AbstractTaskITCase.java
----------------------------------------------------------------------
diff --git a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/AbstractTaskITCase.java b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/AbstractTaskITCase.java
index 2d9dae1..7bdd7c5 100644
--- a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/AbstractTaskITCase.java
+++ b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/AbstractTaskITCase.java
@@ -50,8 +50,6 @@ public abstract class AbstractTaskITCase extends AbstractITCase {
 
     protected static class ThreadExec implements Callable<TaskExecTO> {
 
-        private final AbstractTaskITCase test;
-
         private final TaskService taskService;
 
         private final Long taskKey;
@@ -60,10 +58,9 @@ public abstract class AbstractTaskITCase extends AbstractITCase {
 
         private final boolean dryRun;
 
-        public ThreadExec(final AbstractTaskITCase test, final TaskService taskService, final Long taskKey,
-                final int maxWaitSeconds, final boolean dryRun) {
+        public ThreadExec(
+                final TaskService taskService, final Long taskKey, final int maxWaitSeconds, final boolean dryRun) {
 
-            this.test = test;
             this.taskService = taskService;
             this.taskKey = taskKey;
             this.maxWaitSeconds = maxWaitSeconds;
@@ -72,7 +69,7 @@ public abstract class AbstractTaskITCase extends AbstractITCase {
 
         @Override
         public TaskExecTO call() throws Exception {
-            return test.execProvisioningTask(taskService, taskKey, maxWaitSeconds, dryRun);
+            return execProvisioningTask(taskService, taskKey, maxWaitSeconds, dryRun);
         }
     }
 
@@ -132,7 +129,12 @@ public abstract class AbstractTaskITCase extends AbstractITCase {
         List<Future<TaskExecTO>> futures = new ArrayList<>();
 
         for (Long key : taskKeys) {
-            futures.add(service.submit(new ThreadExec(this, taskService, key, maxWaitSeconds, dryRun)));
+            futures.add(service.submit(new ThreadExec(taskService, key, maxWaitSeconds, dryRun)));
+            // avoid flooding the test server
+            try {
+                Thread.sleep(2000);
+            } catch (InterruptedException e) {
+            }
         }
 
         Map<Long, TaskExecTO> res = new HashMap<>();


[11/31] syncope git commit: [SYNCOPE-652] Still several things to refine, but it starts taking shape

Posted by md...@apache.org.
http://git-wip-us.apache.org/repos/asf/syncope/blob/6dfedd8f/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/job/AbstractTaskJob.java
----------------------------------------------------------------------
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/job/AbstractTaskJob.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/job/AbstractTaskJob.java
deleted file mode 100644
index 728ab41..0000000
--- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/job/AbstractTaskJob.java
+++ /dev/null
@@ -1,216 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.syncope.core.provisioning.java.job;
-
-import java.util.Date;
-import java.util.concurrent.atomic.AtomicReference;
-import org.apache.syncope.common.lib.types.AuditElements;
-import org.apache.syncope.common.lib.types.AuditElements.Result;
-import org.apache.syncope.core.persistence.api.dao.TaskDAO;
-import org.apache.syncope.core.persistence.api.dao.TaskExecDAO;
-import org.apache.syncope.core.persistence.api.entity.EntityFactory;
-import org.apache.syncope.core.persistence.api.entity.task.Task;
-import org.apache.syncope.core.persistence.api.entity.task.TaskExec;
-import org.apache.syncope.core.provisioning.api.job.TaskJob;
-import org.apache.syncope.core.misc.AuditManager;
-import org.apache.syncope.core.misc.DataFormat;
-import org.apache.syncope.core.misc.ExceptionUtils2;
-import org.apache.syncope.core.persistence.api.dao.ConfDAO;
-import org.apache.syncope.core.provisioning.api.notification.NotificationManager;
-import org.quartz.DisallowConcurrentExecution;
-import org.quartz.JobExecutionContext;
-import org.quartz.JobExecutionException;
-import org.quartz.UnableToInterruptJobException;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.springframework.beans.factory.annotation.Autowired;
-
-/**
- * Abstract job implementation that delegates to concrete implementation the actual job execution and provides some
- * base features.
- * <strong>Extending this class will not provide support transaction management.</strong><br/>
- * Extend <tt>AbstractTransactionalTaskJob</tt> for this purpose.
- *
- * @see AbstractTransactionalTaskJob
- */
-@DisallowConcurrentExecution
-public abstract class AbstractTaskJob implements TaskJob {
-
-    /**
-     * Task execution status.
-     */
-    public enum Status {
-
-        SUCCESS,
-        FAILURE
-
-    }
-
-    /**
-     * Logger.
-     */
-    protected static final Logger LOG = LoggerFactory.getLogger(AbstractTaskJob.class);
-
-    /**
-     * Task DAO.
-     */
-    @Autowired
-    protected TaskDAO taskDAO;
-
-    /**
-     * Task execution DAO.
-     */
-    @Autowired
-    private TaskExecDAO taskExecDAO;
-
-    /**
-     * Configuration DAO.
-     */
-    @Autowired
-    private ConfDAO confDAO;
-
-    /**
-     * Notification manager.
-     */
-    @Autowired
-    private NotificationManager notificationManager;
-
-    /**
-     * Audit manager.
-     */
-    @Autowired
-    private AuditManager auditManager;
-
-    @Autowired
-    private EntityFactory entityFactory;
-
-    /**
-     * Id, set by the caller, for identifying the task to be executed.
-     */
-    protected Long taskId;
-
-    /**
-     * The actual task to be executed.
-     */
-    protected Task task;
-
-    /**
-     * The current running thread containing the task to be executed.
-     */
-    protected AtomicReference<Thread> runningThread = new AtomicReference<Thread>();
-
-    /**
-     * Task id setter.
-     *
-     * @param taskId to be set
-     */
-    @Override
-    public void setTaskId(final Long taskId) {
-        this.taskId = taskId;
-    }
-
-    @Override
-    public void execute(final JobExecutionContext context) throws JobExecutionException {
-        this.runningThread.set(Thread.currentThread());
-        task = taskDAO.find(taskId);
-        if (task == null) {
-            throw new JobExecutionException("Task " + taskId + " not found");
-        }
-
-        TaskExec execution = entityFactory.newEntity(TaskExec.class);
-        execution.setStartDate(new Date());
-        execution.setTask(task);
-
-        Result result;
-
-        try {
-            execution.setMessage(doExecute(context.getMergedJobDataMap().getBoolean(DRY_RUN_JOBDETAIL_KEY)));
-            execution.setStatus(Status.SUCCESS.name());
-            result = Result.SUCCESS;
-        } catch (JobExecutionException e) {
-            LOG.error("While executing task " + taskId, e);
-            result = Result.FAILURE;
-
-            execution.setMessage(ExceptionUtils2.getFullStackTrace(e));
-            execution.setStatus(Status.FAILURE.name());
-        }
-        execution.setEndDate(new Date());
-
-        if (hasToBeRegistered(execution)) {
-            taskExecDAO.saveAndAdd(taskId, execution);
-        }
-        task = taskDAO.save(task);
-
-        notificationManager.createTasks(
-                AuditElements.EventCategoryType.TASK,
-                this.getClass().getSimpleName(),
-                null,
-                this.getClass().getSimpleName(), // searching for before object is too much expensive ...
-                result,
-                task,
-                execution);
-
-        auditManager.audit(
-                AuditElements.EventCategoryType.TASK,
-                task.getClass().getSimpleName(),
-                null,
-                null, // searching for before object is too much expensive ...
-                result,
-                task,
-                (Object[]) null);
-    }
-
-    /**
-     * The actual execution, delegated to child classes.
-     *
-     * @param dryRun whether to actually touch the data
-     * @return the task execution status to be set
-     * @throws JobExecutionException if anything goes wrong
-     */
-    protected abstract String doExecute(boolean dryRun) throws JobExecutionException;
-
-    /**
-     * Template method to determine whether this job's task execution has to be persisted or not.
-     *
-     * @param execution task execution
-     * @return wether to persist or not
-     */
-    protected boolean hasToBeRegistered(final TaskExec execution) {
-        return false;
-    }
-
-    @Override
-    public void interrupt() throws UnableToInterruptJobException {
-        Thread thread = this.runningThread.getAndSet(null);
-        if (thread == null) {
-            LOG.warn("Unable to retrieve the thread of the current job execution");
-        } else {
-            LOG.info("Interrupting job from thread {} at {} ", thread.getId(), DataFormat.format(new Date()));
-
-            long maxRetry = confDAO.find("tasks.interruptMaxRetries", "1").getValues().get(0).getLongValue();
-            for (int i = 0; i < maxRetry && thread.isAlive(); i++) {
-                thread.interrupt();
-            }
-            // if the thread is still alive, it should be available in the next stop
-            if (thread.isAlive()) {
-                this.runningThread.set(thread);
-            }
-        }
-    }
-}

http://git-wip-us.apache.org/repos/asf/syncope/blob/6dfedd8f/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/job/AbstractTransactionalTaskJob.java
----------------------------------------------------------------------
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/job/AbstractTransactionalTaskJob.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/job/AbstractTransactionalTaskJob.java
deleted file mode 100644
index b90c142..0000000
--- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/job/AbstractTransactionalTaskJob.java
+++ /dev/null
@@ -1,35 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.syncope.core.provisioning.java.job;
-
-import org.quartz.JobExecutionContext;
-import org.quartz.JobExecutionException;
-import org.springframework.transaction.annotation.Transactional;
-
-/**
- * Abstract job implementation for transactional execution.
- */
-public abstract class AbstractTransactionalTaskJob extends AbstractTaskJob {
-
-    @Transactional
-    @Override
-    public void execute(final JobExecutionContext context) throws JobExecutionException {
-        super.execute(context);
-    }
-}

http://git-wip-us.apache.org/repos/asf/syncope/blob/6dfedd8f/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/job/SampleJob.java
----------------------------------------------------------------------
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/job/SampleJob.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/job/SampleJob.java
deleted file mode 100644
index e031905..0000000
--- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/job/SampleJob.java
+++ /dev/null
@@ -1,52 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.syncope.core.provisioning.java.job;
-
-import org.apache.syncope.core.persistence.api.entity.task.SchedTask;
-import org.apache.syncope.core.persistence.api.entity.task.TaskExec;
-import org.quartz.JobExecutionException;
-
-/**
- * Sample implementation for execution a scheduled task.
- *
- * @see SchedTask
- */
-public class SampleJob extends AbstractTaskJob {
-
-    @Override
-    protected String doExecute(final boolean dryRun) throws JobExecutionException {
-        if (!(task instanceof SchedTask)) {
-            throw new JobExecutionException("Task " + taskId + " isn't a SchedTask");
-        }
-        final SchedTask schedTask = (SchedTask) this.task;
-
-        LOG.info("SampleJob {}running [SchedTask {}]", (dryRun
-                ? "dry "
-                : ""), schedTask.getKey());
-
-        return (dryRun
-                ? "DRY "
-                : "") + "RUNNING";
-    }
-
-    @Override
-    protected boolean hasToBeRegistered(final TaskExec execution) {
-        return true;
-    }
-}

http://git-wip-us.apache.org/repos/asf/syncope/blob/6dfedd8f/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/job/SpringBeanJobFactory.java
----------------------------------------------------------------------
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/job/SpringBeanJobFactory.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/job/SpringBeanJobFactory.java
index fc3938e..925c6e6 100644
--- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/job/SpringBeanJobFactory.java
+++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/job/SpringBeanJobFactory.java
@@ -26,6 +26,10 @@ import org.springframework.beans.PropertyAccessorFactory;
 import org.springframework.context.ApplicationContext;
 import org.springframework.context.ConfigurableApplicationContext;
 
+/**
+ * An implementation of SpringBeanJobFactory that retrieves the bean from the Spring context so that autowiring and
+ * transactions work.
+ */
 public class SpringBeanJobFactory extends org.springframework.scheduling.quartz.SpringBeanJobFactory {
 
     private String[] ignoredUnknownProperties;
@@ -33,7 +37,7 @@ public class SpringBeanJobFactory extends org.springframework.scheduling.quartz.
     private SchedulerContext schedulerContext;
 
     @Override
-    public void setIgnoredUnknownProperties(final String[] ignoredUnknownProperties) {
+    public void setIgnoredUnknownProperties(final String... ignoredUnknownProperties) {
         String[] defensiveCopy = ignoredUnknownProperties.clone();
         super.setIgnoredUnknownProperties(defensiveCopy);
         this.ignoredUnknownProperties = defensiveCopy;
@@ -45,12 +49,6 @@ public class SpringBeanJobFactory extends org.springframework.scheduling.quartz.
         this.schedulerContext = schedulerContext;
     }
 
-    /**
-     * An implementation of SpringBeanJobFactory that retrieves the bean from the Spring context so that autowiring and
-     * transactions work.
-     *
-     * {@inheritDoc}
-     */
     @Override
     protected Object createJobInstance(final TriggerFiredBundle bundle) throws Exception {
         final ApplicationContext ctx = ((ConfigurableApplicationContext) schedulerContext.get("applicationContext"));

http://git-wip-us.apache.org/repos/asf/syncope/blob/6dfedd8f/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/job/TaskJob.java
----------------------------------------------------------------------
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/job/TaskJob.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/job/TaskJob.java
new file mode 100644
index 0000000..2001e22
--- /dev/null
+++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/job/TaskJob.java
@@ -0,0 +1,119 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.syncope.core.provisioning.java.job;
+
+import java.util.Date;
+import java.util.concurrent.atomic.AtomicReference;
+import org.apache.commons.lang3.ClassUtils;
+import org.apache.syncope.core.misc.DataFormat;
+import org.apache.syncope.core.misc.security.AuthContextUtils;
+import org.apache.syncope.core.misc.spring.ApplicationContextProvider;
+import org.apache.syncope.core.provisioning.api.job.JobInstanceLoader;
+import org.apache.syncope.core.provisioning.api.job.SchedTaskJobDelegate;
+import org.quartz.DisallowConcurrentExecution;
+import org.quartz.InterruptableJob;
+import org.quartz.JobExecutionContext;
+import org.quartz.JobExecutionException;
+import org.quartz.UnableToInterruptJobException;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.support.AbstractBeanDefinition;
+
+@DisallowConcurrentExecution
+public class TaskJob implements InterruptableJob {
+
+    private static final Logger LOG = LoggerFactory.getLogger(TaskJob.class);
+
+    public static final String DRY_RUN_JOBDETAIL_KEY = "dryRun";
+
+    public static final String DELEGATE_CLASS_KEY = "delegateClass";
+
+    public static final String INTERRUPT_MAX_RETRIES_KEY = "interruptMaxRetries";
+
+    /**
+     * Task execution status.
+     */
+    public enum Status {
+
+        SUCCESS,
+        FAILURE
+
+    }
+
+    /**
+     * The current running thread containing the task to be executed.
+     */
+    private final AtomicReference<Thread> runningThread = new AtomicReference<>();
+
+    /**
+     * Key, set by the caller, for identifying the task to be executed.
+     */
+    private Long taskKey;
+
+    private long interruptMaxRetries = 1;
+
+    /**
+     * Task key setter.
+     *
+     * @param taskKey to be set
+     */
+    public void setTaskKey(final Long taskKey) {
+        this.taskKey = taskKey;
+    }
+
+    @Override
+    public void execute(final JobExecutionContext context) throws JobExecutionException {
+        this.runningThread.set(Thread.currentThread());
+        this.interruptMaxRetries = context.getMergedJobDataMap().getLong(INTERRUPT_MAX_RETRIES_KEY);
+
+        AuthContextUtils.setFakeAuth(context.getMergedJobDataMap().getString(JobInstanceLoader.DOMAIN));
+        try {
+            Class<?> delegateClass = ClassUtils.getClass(context.getMergedJobDataMap().getString(DELEGATE_CLASS_KEY));
+
+            ((SchedTaskJobDelegate) ApplicationContextProvider.getBeanFactory().
+                    createBean(delegateClass, AbstractBeanDefinition.AUTOWIRE_BY_NAME, false)).
+                    execute(taskKey, context.getMergedJobDataMap().getBoolean(DRY_RUN_JOBDETAIL_KEY));
+        } catch (Exception e) {
+            throw new JobExecutionException(e);
+        } finally {
+            AuthContextUtils.clearFakeAuth();
+        }
+    }
+
+    @Override
+    public void interrupt() throws UnableToInterruptJobException {
+        Thread thread = this.runningThread.getAndSet(null);
+        if (thread == null) {
+            LOG.warn("Unable to retrieve the thread of the current job execution");
+        } else {
+            LOG.info("Interrupting job from thread {} at {} ", thread.getId(), DataFormat.format(new Date()));
+
+            if (interruptMaxRetries < 1) {
+                interruptMaxRetries = 1;
+            }
+            for (int i = 0; i < interruptMaxRetries && thread.isAlive(); i++) {
+                thread.interrupt();
+            }
+            // if the thread is still alive, it should be available in the next stop
+            if (thread.isAlive()) {
+                this.runningThread.set(thread);
+            }
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/6dfedd8f/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/propagation/PropagationManagerImpl.java
----------------------------------------------------------------------
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/propagation/PropagationManagerImpl.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/propagation/PropagationManagerImpl.java
index a73f5b9..1c704df 100644
--- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/propagation/PropagationManagerImpl.java
+++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/propagation/PropagationManagerImpl.java
@@ -195,11 +195,11 @@ public class PropagationManagerImpl implements PropagationManager {
     }
 
     @Override
-    public List<PropagationTask> getUserUpdateTasks(final User user, final Boolean enable,
+    public List<PropagationTask> getUserUpdateTasks(final Long key, final Boolean enable,
             final Collection<String> noPropResourceNames) {
 
         return getUpdateTasks(
-                user, // user to be updated on external resources
+                userDAO.find(key), // user to be updated on external resources
                 null, // no password
                 false,
                 enable, // status to be propagated
@@ -236,7 +236,7 @@ public class PropagationManagerImpl implements PropagationManager {
         } else {
             // b. generate the propagation task list in two phases: first the ones containing password,
             // the the rest (with no password)
-            final PropagationByResource origPropByRes = new PropagationByResource();
+            PropagationByResource origPropByRes = new PropagationByResource();
             origPropByRes.merge(wfResult.getPropByRes());
 
             Set<String> pwdResourceNames = new HashSet<>(userMod.getPwdPropRequest().getResourceNames());

http://git-wip-us.apache.org/repos/asf/syncope/blob/6dfedd8f/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/sync/AbstractProvisioningJob.java
----------------------------------------------------------------------
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/sync/AbstractProvisioningJob.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/sync/AbstractProvisioningJob.java
deleted file mode 100644
index 34ca299..0000000
--- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/sync/AbstractProvisioningJob.java
+++ /dev/null
@@ -1,480 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.syncope.core.provisioning.java.sync;
-
-import static org.apache.syncope.common.lib.types.AnyTypeKind.USER;
-
-import java.lang.reflect.ParameterizedType;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.List;
-import javax.annotation.Resource;
-import org.apache.commons.collections4.CollectionUtils;
-import org.apache.commons.collections4.Transformer;
-import org.apache.syncope.common.lib.SyncopeConstants;
-import org.apache.syncope.common.lib.types.Entitlement;
-import org.apache.syncope.common.lib.types.TraceLevel;
-import org.apache.syncope.core.misc.security.SyncopeAuthenticationDetails;
-import org.apache.syncope.core.misc.security.SyncopeGrantedAuthority;
-import org.apache.syncope.core.persistence.api.dao.AnyTypeDAO;
-import org.apache.syncope.core.persistence.api.dao.ExternalResourceDAO;
-import org.apache.syncope.core.persistence.api.dao.PolicyDAO;
-import org.apache.syncope.core.persistence.api.entity.AnyType;
-import org.apache.syncope.core.persistence.api.entity.resource.Mapping;
-import org.apache.syncope.core.persistence.api.entity.resource.Provision;
-import org.apache.syncope.core.persistence.api.entity.task.ProvisioningTask;
-import org.apache.syncope.core.persistence.api.entity.task.TaskExec;
-import org.apache.syncope.core.provisioning.api.Connector;
-import org.apache.syncope.core.provisioning.api.ConnectorFactory;
-import org.apache.syncope.core.provisioning.api.sync.ProvisioningActions;
-import org.apache.syncope.core.provisioning.api.sync.ProvisioningResult;
-import org.apache.syncope.core.provisioning.java.job.AbstractTaskJob;
-import org.quartz.JobExecutionException;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
-import org.springframework.security.core.GrantedAuthority;
-import org.springframework.security.core.context.SecurityContextHolder;
-import org.springframework.security.core.userdetails.User;
-
-/**
- * Job for executing synchronization tasks.
- *
- * @see AbstractTaskJob
- * @see org.apache.syncope.core.persistence.api.entity.task.SyncTask
- * @see org.apache.syncope.core.persistence.api.entity.task.PushTask
- */
-public abstract class AbstractProvisioningJob<T extends ProvisioningTask, A extends ProvisioningActions>
-        extends AbstractTaskJob {
-
-    @Resource(name = "adminUser")
-    protected String adminUser;
-
-    /**
-     * ConnInstance loader.
-     */
-    @Autowired
-    protected ConnectorFactory connFactory;
-
-    @Autowired
-    protected AnyTypeDAO anyTypeDAO;
-
-    /**
-     * Resource DAO.
-     */
-    @Autowired
-    protected ExternalResourceDAO resourceDAO;
-
-    /**
-     * Policy DAO.
-     */
-    @Autowired
-    protected PolicyDAO policyDAO;
-
-    /**
-     * SyncJob actions.
-     */
-    protected List<A> actions;
-
-    public void setActions(final List<A> actions) {
-        this.actions = actions;
-    }
-
-    /**
-     * Create a textual report of the synchronization, based on the trace level.
-     *
-     * @param provResults Sync results
-     * @param syncTraceLevel Sync trace level
-     * @param dryRun dry run?
-     * @return report as string
-     */
-    protected String createReport(final Collection<ProvisioningResult> provResults, final TraceLevel syncTraceLevel,
-            final boolean dryRun) {
-
-        if (syncTraceLevel == TraceLevel.NONE) {
-            return null;
-        }
-
-        StringBuilder report = new StringBuilder();
-
-        if (dryRun) {
-            report.append("==>Dry run only, no modifications were made<==\n\n");
-        }
-
-        List<ProvisioningResult> uSuccCreate = new ArrayList<>();
-        List<ProvisioningResult> uFailCreate = new ArrayList<>();
-        List<ProvisioningResult> uSuccUpdate = new ArrayList<>();
-        List<ProvisioningResult> uFailUpdate = new ArrayList<>();
-        List<ProvisioningResult> uSuccDelete = new ArrayList<>();
-        List<ProvisioningResult> uFailDelete = new ArrayList<>();
-        List<ProvisioningResult> uSuccNone = new ArrayList<>();
-        List<ProvisioningResult> uIgnore = new ArrayList<>();
-        List<ProvisioningResult> gSuccCreate = new ArrayList<>();
-        List<ProvisioningResult> gFailCreate = new ArrayList<>();
-        List<ProvisioningResult> gSuccUpdate = new ArrayList<>();
-        List<ProvisioningResult> gFailUpdate = new ArrayList<>();
-        List<ProvisioningResult> gSuccDelete = new ArrayList<>();
-        List<ProvisioningResult> gFailDelete = new ArrayList<>();
-        List<ProvisioningResult> gSuccNone = new ArrayList<>();
-        List<ProvisioningResult> gIgnore = new ArrayList<>();
-        List<ProvisioningResult> aSuccCreate = new ArrayList<>();
-        List<ProvisioningResult> aFailCreate = new ArrayList<>();
-        List<ProvisioningResult> aSuccUpdate = new ArrayList<>();
-        List<ProvisioningResult> aFailUpdate = new ArrayList<>();
-        List<ProvisioningResult> aSuccDelete = new ArrayList<>();
-        List<ProvisioningResult> aFailDelete = new ArrayList<>();
-        List<ProvisioningResult> aSuccNone = new ArrayList<>();
-        List<ProvisioningResult> aIgnore = new ArrayList<>();
-
-        for (ProvisioningResult provResult : provResults) {
-            AnyType anyType = anyTypeDAO.find(provResult.getAnyType());
-
-            switch (provResult.getStatus()) {
-                case SUCCESS:
-                    switch (provResult.getOperation()) {
-                        case CREATE:
-                            switch (anyType.getKind()) {
-                                case USER:
-                                    uSuccCreate.add(provResult);
-                                    break;
-
-                                case GROUP:
-                                    gSuccCreate.add(provResult);
-                                    break;
-
-                                case ANY_OBJECT:
-                                default:
-                                    aSuccCreate.add(provResult);
-                            }
-                            break;
-
-                        case UPDATE:
-                            switch (anyType.getKind()) {
-                                case USER:
-                                    uSuccUpdate.add(provResult);
-                                    break;
-
-                                case GROUP:
-                                    gSuccUpdate.add(provResult);
-                                    break;
-
-                                case ANY_OBJECT:
-                                default:
-                                    aSuccUpdate.add(provResult);
-                            }
-                            break;
-
-                        case DELETE:
-                            switch (anyType.getKind()) {
-                                case USER:
-                                    uSuccDelete.add(provResult);
-                                    break;
-
-                                case GROUP:
-                                    gSuccDelete.add(provResult);
-                                    break;
-
-                                case ANY_OBJECT:
-                                default:
-                                    aSuccDelete.add(provResult);
-                            }
-                            break;
-
-                        case NONE:
-                            switch (anyType.getKind()) {
-                                case USER:
-                                    uSuccNone.add(provResult);
-                                    break;
-
-                                case GROUP:
-                                    gSuccNone.add(provResult);
-                                    break;
-
-                                case ANY_OBJECT:
-                                default:
-                                    aSuccNone.add(provResult);
-                            }
-                            break;
-
-                        default:
-                    }
-                    break;
-
-                case FAILURE:
-                    switch (provResult.getOperation()) {
-                        case CREATE:
-                            switch (anyType.getKind()) {
-                                case USER:
-                                    uFailCreate.add(provResult);
-                                    break;
-
-                                case GROUP:
-                                    gFailCreate.add(provResult);
-                                    break;
-
-                                case ANY_OBJECT:
-                                default:
-                                    aFailCreate.add(provResult);
-                            }
-                            break;
-
-                        case UPDATE:
-                            switch (anyType.getKind()) {
-                                case USER:
-                                    uFailUpdate.add(provResult);
-                                    break;
-
-                                case GROUP:
-                                    gFailUpdate.add(provResult);
-                                    break;
-
-                                case ANY_OBJECT:
-                                default:
-                                    aFailUpdate.add(provResult);
-                            }
-                            break;
-
-                        case DELETE:
-                            switch (anyType.getKind()) {
-                                case USER:
-                                    uFailDelete.add(provResult);
-                                    break;
-
-                                case GROUP:
-                                    gFailDelete.add(provResult);
-                                    break;
-
-                                case ANY_OBJECT:
-                                default:
-                                    aFailDelete.add(provResult);
-                            }
-                            break;
-
-                        default:
-                    }
-                    break;
-
-                case IGNORE:
-                    switch (anyType.getKind()) {
-                        case USER:
-                            uIgnore.add(provResult);
-                            break;
-
-                        case GROUP:
-                            gIgnore.add(provResult);
-                            break;
-
-                        case ANY_OBJECT:
-                        default:
-                            aIgnore.add(provResult);
-                    }
-                    break;
-
-                default:
-            }
-        }
-
-        // Summary, also to be included for FAILURE and ALL, so create it anyway.
-        report.append("Users ").
-                append("[created/failures]: ").append(uSuccCreate.size()).append('/').append(uFailCreate.size()).
-                append(' ').
-                append("[updated/failures]: ").append(uSuccUpdate.size()).append('/').append(uFailUpdate.size()).
-                append(' ').
-                append("[deleted/failures]: ").append(uSuccDelete.size()).append('/').append(uFailDelete.size()).
-                append(' ').
-                append("[no operation/ignored]: ").append(uSuccNone.size()).append('/').append(uIgnore.size()).
-                append('\n');
-        report.append("Groups ").
-                append("[created/failures]: ").append(gSuccCreate.size()).append('/').append(gFailCreate.size()).
-                append(' ').
-                append("[updated/failures]: ").append(gSuccUpdate.size()).append('/').append(gFailUpdate.size()).
-                append(' ').
-                append("[deleted/failures]: ").append(gSuccDelete.size()).append('/').append(gFailDelete.size()).
-                append(' ').
-                append("[no operation/ignored]: ").append(gSuccNone.size()).append('/').append(gIgnore.size()).
-                append('\n');
-        report.append("Any objects ").
-                append("[created/failures]: ").append(aSuccCreate.size()).append('/').append(aFailCreate.size()).
-                append(' ').
-                append("[updated/failures]: ").append(aSuccUpdate.size()).append('/').append(aFailUpdate.size()).
-                append(' ').
-                append("[deleted/failures]: ").append(aSuccDelete.size()).append('/').append(aFailDelete.size()).
-                append(' ').
-                append("[no operation/ignored]: ").append(aSuccNone.size()).append('/').append(aIgnore.size());
-
-        // Failures
-        if (syncTraceLevel == TraceLevel.FAILURES || syncTraceLevel == TraceLevel.ALL) {
-            if (!uFailCreate.isEmpty()) {
-                report.append("\n\nUsers failed to create: ");
-                report.append(ProvisioningResult.produceReport(uFailCreate, syncTraceLevel));
-            }
-            if (!uFailUpdate.isEmpty()) {
-                report.append("\nUsers failed to update: ");
-                report.append(ProvisioningResult.produceReport(uFailUpdate, syncTraceLevel));
-            }
-            if (!uFailDelete.isEmpty()) {
-                report.append("\nUsers failed to delete: ");
-                report.append(ProvisioningResult.produceReport(uFailDelete, syncTraceLevel));
-            }
-
-            if (!gFailCreate.isEmpty()) {
-                report.append("\n\nGroups failed to create: ");
-                report.append(ProvisioningResult.produceReport(gFailCreate, syncTraceLevel));
-            }
-            if (!gFailUpdate.isEmpty()) {
-                report.append("\nGroups failed to update: ");
-                report.append(ProvisioningResult.produceReport(gFailUpdate, syncTraceLevel));
-            }
-            if (!gFailDelete.isEmpty()) {
-                report.append("\nGroups failed to delete: ");
-                report.append(ProvisioningResult.produceReport(gFailDelete, syncTraceLevel));
-            }
-
-            if (!aFailCreate.isEmpty()) {
-                report.append("\nAny objects failed to create: ");
-                report.append(ProvisioningResult.produceReport(aFailCreate, syncTraceLevel));
-            }
-            if (!aFailUpdate.isEmpty()) {
-                report.append("\nAny objects failed to update: ");
-                report.append(ProvisioningResult.produceReport(aFailUpdate, syncTraceLevel));
-            }
-            if (!aFailDelete.isEmpty()) {
-                report.append("\nAny objects failed to delete: ");
-                report.append(ProvisioningResult.produceReport(aFailDelete, syncTraceLevel));
-            }
-        }
-
-        // Succeeded, only if on 'ALL' level
-        if (syncTraceLevel == TraceLevel.ALL) {
-            report.append("\n\nUsers created:\n").
-                    append(ProvisioningResult.produceReport(uSuccCreate, syncTraceLevel)).
-                    append("\nUsers updated:\n").
-                    append(ProvisioningResult.produceReport(uSuccUpdate, syncTraceLevel)).
-                    append("\nUsers deleted:\n").
-                    append(ProvisioningResult.produceReport(uSuccDelete, syncTraceLevel)).
-                    append("\nUsers no operation:\n").
-                    append(ProvisioningResult.produceReport(uSuccNone, syncTraceLevel)).
-                    append("\nUsers ignored:\n").
-                    append(ProvisioningResult.produceReport(uIgnore, syncTraceLevel));
-            report.append("\n\nGroups created:\n").
-                    append(ProvisioningResult.produceReport(gSuccCreate, syncTraceLevel)).
-                    append("\nGroups updated:\n").
-                    append(ProvisioningResult.produceReport(gSuccUpdate, syncTraceLevel)).
-                    append("\nGroups deleted:\n").
-                    append(ProvisioningResult.produceReport(gSuccDelete, syncTraceLevel)).
-                    append("\nGroups no operation:\n").
-                    append(ProvisioningResult.produceReport(gSuccNone, syncTraceLevel)).
-                    append("\nGroups ignored:\n").
-                    append(ProvisioningResult.produceReport(gSuccNone, syncTraceLevel));
-            report.append("\n\nAny objects created:\n").
-                    append(ProvisioningResult.produceReport(aSuccCreate, syncTraceLevel)).
-                    append("\nAny objects updated:\n").
-                    append(ProvisioningResult.produceReport(aSuccUpdate, syncTraceLevel)).
-                    append("\nAny objects deleted:\n").
-                    append(ProvisioningResult.produceReport(aSuccDelete, syncTraceLevel)).
-                    append("\nAny objects no operation:\n").
-                    append(ProvisioningResult.produceReport(aSuccNone, syncTraceLevel)).
-                    append("\nAny objects ignored:\n").
-                    append(ProvisioningResult.produceReport(aSuccNone, syncTraceLevel));
-        }
-
-        return report.toString();
-    }
-
-    @Override
-    protected String doExecute(final boolean dryRun) throws JobExecutionException {
-        // PRE: grant all authorities (i.e. setup the SecurityContextHolder)
-        List<GrantedAuthority> authorities = CollectionUtils.collect(Entitlement.values(),
-                new Transformer<String, GrantedAuthority>() {
-
-                    @Override
-                    public GrantedAuthority transform(final String entitlement) {
-                        return new SyncopeGrantedAuthority(entitlement, SyncopeConstants.ROOT_REALM);
-                    }
-                }, new ArrayList<GrantedAuthority>());
-
-        UsernamePasswordAuthenticationToken auth = new UsernamePasswordAuthenticationToken(
-                new User(adminUser, "FAKE_PASSWORD", authorities), "FAKE_PASSWORD", authorities);
-        auth.setDetails(new SyncopeAuthenticationDetails(taskDAO.getDomain(task)));
-        SecurityContextHolder.getContext().setAuthentication(auth);
-
-        try {
-            Class<T> clazz = getTaskClassReference();
-            if (!clazz.isAssignableFrom(task.getClass())) {
-                throw new JobExecutionException("Task " + taskId + " isn't a SyncTask");
-            }
-
-            T provisioningTask = clazz.cast(task);
-
-            Connector connector;
-            try {
-                connector = connFactory.getConnector(provisioningTask.getResource());
-            } catch (Exception e) {
-                String msg = String.format("Connector instance bean for resource %s and connInstance %s not found",
-                        provisioningTask.getResource(), provisioningTask.getResource().getConnector());
-                throw new JobExecutionException(msg, e);
-            }
-
-            boolean noMapping = true;
-            for (Provision provision : provisioningTask.getResource().getProvisions()) {
-                Mapping mapping = provision.getMapping();
-                if (mapping != null) {
-                    noMapping = false;
-                    if (mapping.getConnObjectKeyItem() == null) {
-                        throw new JobExecutionException(
-                                "Invalid ConnObjectKey mapping for provision " + provision);
-                    }
-                }
-            }
-            if (noMapping) {
-                return "No mapping configured for both users and groups: aborting...";
-            }
-
-            return executeWithSecurityContext(
-                    provisioningTask,
-                    connector,
-                    dryRun);
-        } catch (Throwable t) {
-            LOG.error("While executing provisioning job {}", getClass().getName(), t);
-            throw t;
-        } finally {
-            // POST: clean up the SecurityContextHolder
-            SecurityContextHolder.clearContext();
-        }
-    }
-
-    protected abstract String executeWithSecurityContext(
-            final T task,
-            final Connector connector,
-            final boolean dryRun) throws JobExecutionException;
-
-    @Override
-    protected boolean hasToBeRegistered(final TaskExec execution) {
-        final ProvisioningTask provTask = (ProvisioningTask) task;
-
-        // True if either failed and failures have to be registered, or if ALL has to be registered.
-        return (Status.valueOf(execution.getStatus()) == Status.FAILURE
-                && provTask.getResource().getSyncTraceLevel().ordinal() >= TraceLevel.FAILURES.ordinal())
-                || provTask.getResource().getSyncTraceLevel().ordinal() >= TraceLevel.SUMMARY.ordinal();
-    }
-
-    @SuppressWarnings("unchecked")
-    private Class<T> getTaskClassReference() {
-        return (Class<T>) ((ParameterizedType) this.getClass().getGenericSuperclass()).getActualTypeArguments()[0];
-    }
-}

http://git-wip-us.apache.org/repos/asf/syncope/blob/6dfedd8f/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/sync/AbstractProvisioningJobDelegate.java
----------------------------------------------------------------------
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/sync/AbstractProvisioningJobDelegate.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/sync/AbstractProvisioningJobDelegate.java
new file mode 100644
index 0000000..0c8deb2
--- /dev/null
+++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/sync/AbstractProvisioningJobDelegate.java
@@ -0,0 +1,434 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.syncope.core.provisioning.java.sync;
+
+import java.lang.reflect.ParameterizedType;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+import javax.annotation.Resource;
+import org.apache.syncope.common.lib.types.TraceLevel;
+import org.apache.syncope.core.persistence.api.dao.AnyTypeDAO;
+import org.apache.syncope.core.persistence.api.dao.ExternalResourceDAO;
+import org.apache.syncope.core.persistence.api.dao.PolicyDAO;
+import org.apache.syncope.core.persistence.api.entity.AnyType;
+import org.apache.syncope.core.persistence.api.entity.resource.Mapping;
+import org.apache.syncope.core.persistence.api.entity.resource.Provision;
+import org.apache.syncope.core.persistence.api.entity.task.ProvisioningTask;
+import org.apache.syncope.core.persistence.api.entity.task.TaskExec;
+import org.apache.syncope.core.provisioning.api.Connector;
+import org.apache.syncope.core.provisioning.api.ConnectorFactory;
+import org.apache.syncope.core.provisioning.api.sync.ProvisioningResult;
+import org.apache.syncope.core.provisioning.java.job.AbstractSchedTaskJobDelegate;
+import org.apache.syncope.core.provisioning.java.job.TaskJob;
+import org.quartz.JobExecutionException;
+import org.springframework.beans.factory.annotation.Autowired;
+
+public abstract class AbstractProvisioningJobDelegate<T extends ProvisioningTask>
+        extends AbstractSchedTaskJobDelegate {
+
+    @Resource(name = "adminUser")
+    protected String adminUser;
+
+    /**
+     * ConnInstance loader.
+     */
+    @Autowired
+    protected ConnectorFactory connFactory;
+
+    @Autowired
+    protected AnyTypeDAO anyTypeDAO;
+
+    /**
+     * Resource DAO.
+     */
+    @Autowired
+    protected ExternalResourceDAO resourceDAO;
+
+    /**
+     * Policy DAO.
+     */
+    @Autowired
+    protected PolicyDAO policyDAO;
+
+    /**
+     * Create a textual report of the synchronization, based on the trace level.
+     *
+     * @param provResults Sync results
+     * @param syncTraceLevel Sync trace level
+     * @param dryRun dry run?
+     * @return report as string
+     */
+    protected String createReport(final Collection<ProvisioningResult> provResults, final TraceLevel syncTraceLevel,
+            final boolean dryRun) {
+
+        if (syncTraceLevel == TraceLevel.NONE) {
+            return null;
+        }
+
+        StringBuilder report = new StringBuilder();
+
+        if (dryRun) {
+            report.append("==>Dry run only, no modifications were made<==\n\n");
+        }
+
+        List<ProvisioningResult> uSuccCreate = new ArrayList<>();
+        List<ProvisioningResult> uFailCreate = new ArrayList<>();
+        List<ProvisioningResult> uSuccUpdate = new ArrayList<>();
+        List<ProvisioningResult> uFailUpdate = new ArrayList<>();
+        List<ProvisioningResult> uSuccDelete = new ArrayList<>();
+        List<ProvisioningResult> uFailDelete = new ArrayList<>();
+        List<ProvisioningResult> uSuccNone = new ArrayList<>();
+        List<ProvisioningResult> uIgnore = new ArrayList<>();
+        List<ProvisioningResult> gSuccCreate = new ArrayList<>();
+        List<ProvisioningResult> gFailCreate = new ArrayList<>();
+        List<ProvisioningResult> gSuccUpdate = new ArrayList<>();
+        List<ProvisioningResult> gFailUpdate = new ArrayList<>();
+        List<ProvisioningResult> gSuccDelete = new ArrayList<>();
+        List<ProvisioningResult> gFailDelete = new ArrayList<>();
+        List<ProvisioningResult> gSuccNone = new ArrayList<>();
+        List<ProvisioningResult> gIgnore = new ArrayList<>();
+        List<ProvisioningResult> aSuccCreate = new ArrayList<>();
+        List<ProvisioningResult> aFailCreate = new ArrayList<>();
+        List<ProvisioningResult> aSuccUpdate = new ArrayList<>();
+        List<ProvisioningResult> aFailUpdate = new ArrayList<>();
+        List<ProvisioningResult> aSuccDelete = new ArrayList<>();
+        List<ProvisioningResult> aFailDelete = new ArrayList<>();
+        List<ProvisioningResult> aSuccNone = new ArrayList<>();
+        List<ProvisioningResult> aIgnore = new ArrayList<>();
+
+        for (ProvisioningResult provResult : provResults) {
+            AnyType anyType = anyTypeDAO.find(provResult.getAnyType());
+
+            switch (provResult.getStatus()) {
+                case SUCCESS:
+                    switch (provResult.getOperation()) {
+                        case CREATE:
+                            switch (anyType.getKind()) {
+                                case USER:
+                                    uSuccCreate.add(provResult);
+                                    break;
+
+                                case GROUP:
+                                    gSuccCreate.add(provResult);
+                                    break;
+
+                                case ANY_OBJECT:
+                                default:
+                                    aSuccCreate.add(provResult);
+                            }
+                            break;
+
+                        case UPDATE:
+                            switch (anyType.getKind()) {
+                                case USER:
+                                    uSuccUpdate.add(provResult);
+                                    break;
+
+                                case GROUP:
+                                    gSuccUpdate.add(provResult);
+                                    break;
+
+                                case ANY_OBJECT:
+                                default:
+                                    aSuccUpdate.add(provResult);
+                            }
+                            break;
+
+                        case DELETE:
+                            switch (anyType.getKind()) {
+                                case USER:
+                                    uSuccDelete.add(provResult);
+                                    break;
+
+                                case GROUP:
+                                    gSuccDelete.add(provResult);
+                                    break;
+
+                                case ANY_OBJECT:
+                                default:
+                                    aSuccDelete.add(provResult);
+                            }
+                            break;
+
+                        case NONE:
+                            switch (anyType.getKind()) {
+                                case USER:
+                                    uSuccNone.add(provResult);
+                                    break;
+
+                                case GROUP:
+                                    gSuccNone.add(provResult);
+                                    break;
+
+                                case ANY_OBJECT:
+                                default:
+                                    aSuccNone.add(provResult);
+                            }
+                            break;
+
+                        default:
+                    }
+                    break;
+
+                case FAILURE:
+                    switch (provResult.getOperation()) {
+                        case CREATE:
+                            switch (anyType.getKind()) {
+                                case USER:
+                                    uFailCreate.add(provResult);
+                                    break;
+
+                                case GROUP:
+                                    gFailCreate.add(provResult);
+                                    break;
+
+                                case ANY_OBJECT:
+                                default:
+                                    aFailCreate.add(provResult);
+                            }
+                            break;
+
+                        case UPDATE:
+                            switch (anyType.getKind()) {
+                                case USER:
+                                    uFailUpdate.add(provResult);
+                                    break;
+
+                                case GROUP:
+                                    gFailUpdate.add(provResult);
+                                    break;
+
+                                case ANY_OBJECT:
+                                default:
+                                    aFailUpdate.add(provResult);
+                            }
+                            break;
+
+                        case DELETE:
+                            switch (anyType.getKind()) {
+                                case USER:
+                                    uFailDelete.add(provResult);
+                                    break;
+
+                                case GROUP:
+                                    gFailDelete.add(provResult);
+                                    break;
+
+                                case ANY_OBJECT:
+                                default:
+                                    aFailDelete.add(provResult);
+                            }
+                            break;
+
+                        default:
+                    }
+                    break;
+
+                case IGNORE:
+                    switch (anyType.getKind()) {
+                        case USER:
+                            uIgnore.add(provResult);
+                            break;
+
+                        case GROUP:
+                            gIgnore.add(provResult);
+                            break;
+
+                        case ANY_OBJECT:
+                        default:
+                            aIgnore.add(provResult);
+                    }
+                    break;
+
+                default:
+            }
+        }
+
+        // Summary, also to be included for FAILURE and ALL, so create it anyway.
+        report.append("Users ").
+                append("[created/failures]: ").append(uSuccCreate.size()).append('/').append(uFailCreate.size()).
+                append(' ').
+                append("[updated/failures]: ").append(uSuccUpdate.size()).append('/').append(uFailUpdate.size()).
+                append(' ').
+                append("[deleted/failures]: ").append(uSuccDelete.size()).append('/').append(uFailDelete.size()).
+                append(' ').
+                append("[no operation/ignored]: ").append(uSuccNone.size()).append('/').append(uIgnore.size()).
+                append('\n');
+        report.append("Groups ").
+                append("[created/failures]: ").append(gSuccCreate.size()).append('/').append(gFailCreate.size()).
+                append(' ').
+                append("[updated/failures]: ").append(gSuccUpdate.size()).append('/').append(gFailUpdate.size()).
+                append(' ').
+                append("[deleted/failures]: ").append(gSuccDelete.size()).append('/').append(gFailDelete.size()).
+                append(' ').
+                append("[no operation/ignored]: ").append(gSuccNone.size()).append('/').append(gIgnore.size()).
+                append('\n');
+        report.append("Any objects ").
+                append("[created/failures]: ").append(aSuccCreate.size()).append('/').append(aFailCreate.size()).
+                append(' ').
+                append("[updated/failures]: ").append(aSuccUpdate.size()).append('/').append(aFailUpdate.size()).
+                append(' ').
+                append("[deleted/failures]: ").append(aSuccDelete.size()).append('/').append(aFailDelete.size()).
+                append(' ').
+                append("[no operation/ignored]: ").append(aSuccNone.size()).append('/').append(aIgnore.size());
+
+        // Failures
+        if (syncTraceLevel == TraceLevel.FAILURES || syncTraceLevel == TraceLevel.ALL) {
+            if (!uFailCreate.isEmpty()) {
+                report.append("\n\nUsers failed to create: ");
+                report.append(ProvisioningResult.produceReport(uFailCreate, syncTraceLevel));
+            }
+            if (!uFailUpdate.isEmpty()) {
+                report.append("\nUsers failed to update: ");
+                report.append(ProvisioningResult.produceReport(uFailUpdate, syncTraceLevel));
+            }
+            if (!uFailDelete.isEmpty()) {
+                report.append("\nUsers failed to delete: ");
+                report.append(ProvisioningResult.produceReport(uFailDelete, syncTraceLevel));
+            }
+
+            if (!gFailCreate.isEmpty()) {
+                report.append("\n\nGroups failed to create: ");
+                report.append(ProvisioningResult.produceReport(gFailCreate, syncTraceLevel));
+            }
+            if (!gFailUpdate.isEmpty()) {
+                report.append("\nGroups failed to update: ");
+                report.append(ProvisioningResult.produceReport(gFailUpdate, syncTraceLevel));
+            }
+            if (!gFailDelete.isEmpty()) {
+                report.append("\nGroups failed to delete: ");
+                report.append(ProvisioningResult.produceReport(gFailDelete, syncTraceLevel));
+            }
+
+            if (!aFailCreate.isEmpty()) {
+                report.append("\nAny objects failed to create: ");
+                report.append(ProvisioningResult.produceReport(aFailCreate, syncTraceLevel));
+            }
+            if (!aFailUpdate.isEmpty()) {
+                report.append("\nAny objects failed to update: ");
+                report.append(ProvisioningResult.produceReport(aFailUpdate, syncTraceLevel));
+            }
+            if (!aFailDelete.isEmpty()) {
+                report.append("\nAny objects failed to delete: ");
+                report.append(ProvisioningResult.produceReport(aFailDelete, syncTraceLevel));
+            }
+        }
+
+        // Succeeded, only if on 'ALL' level
+        if (syncTraceLevel == TraceLevel.ALL) {
+            report.append("\n\nUsers created:\n").
+                    append(ProvisioningResult.produceReport(uSuccCreate, syncTraceLevel)).
+                    append("\nUsers updated:\n").
+                    append(ProvisioningResult.produceReport(uSuccUpdate, syncTraceLevel)).
+                    append("\nUsers deleted:\n").
+                    append(ProvisioningResult.produceReport(uSuccDelete, syncTraceLevel)).
+                    append("\nUsers no operation:\n").
+                    append(ProvisioningResult.produceReport(uSuccNone, syncTraceLevel)).
+                    append("\nUsers ignored:\n").
+                    append(ProvisioningResult.produceReport(uIgnore, syncTraceLevel));
+            report.append("\n\nGroups created:\n").
+                    append(ProvisioningResult.produceReport(gSuccCreate, syncTraceLevel)).
+                    append("\nGroups updated:\n").
+                    append(ProvisioningResult.produceReport(gSuccUpdate, syncTraceLevel)).
+                    append("\nGroups deleted:\n").
+                    append(ProvisioningResult.produceReport(gSuccDelete, syncTraceLevel)).
+                    append("\nGroups no operation:\n").
+                    append(ProvisioningResult.produceReport(gSuccNone, syncTraceLevel)).
+                    append("\nGroups ignored:\n").
+                    append(ProvisioningResult.produceReport(gSuccNone, syncTraceLevel));
+            report.append("\n\nAny objects created:\n").
+                    append(ProvisioningResult.produceReport(aSuccCreate, syncTraceLevel)).
+                    append("\nAny objects updated:\n").
+                    append(ProvisioningResult.produceReport(aSuccUpdate, syncTraceLevel)).
+                    append("\nAny objects deleted:\n").
+                    append(ProvisioningResult.produceReport(aSuccDelete, syncTraceLevel)).
+                    append("\nAny objects no operation:\n").
+                    append(ProvisioningResult.produceReport(aSuccNone, syncTraceLevel)).
+                    append("\nAny objects ignored:\n").
+                    append(ProvisioningResult.produceReport(aSuccNone, syncTraceLevel));
+        }
+
+        return report.toString();
+    }
+
+    @Override
+    protected String doExecute(final boolean dryRun) throws JobExecutionException {
+        try {
+            Class<T> clazz = getTaskClassReference();
+            if (!clazz.isAssignableFrom(task.getClass())) {
+                throw new JobExecutionException("Task " + task.getKey() + " isn't a ProvisioningTask");
+            }
+
+            T provisioningTask = clazz.cast(task);
+
+            Connector connector;
+            try {
+                connector = connFactory.getConnector(provisioningTask.getResource());
+            } catch (Exception e) {
+                String msg = String.format("Connector instance bean for resource %s and connInstance %s not found",
+                        provisioningTask.getResource(), provisioningTask.getResource().getConnector());
+                throw new JobExecutionException(msg, e);
+            }
+
+            boolean noMapping = true;
+            for (Provision provision : provisioningTask.getResource().getProvisions()) {
+                Mapping mapping = provision.getMapping();
+                if (mapping != null) {
+                    noMapping = false;
+                    if (mapping.getConnObjectKeyItem() == null) {
+                        throw new JobExecutionException(
+                                "Invalid ConnObjectKey mapping for provision " + provision);
+                    }
+                }
+            }
+            if (noMapping) {
+                return "No mapping configured for both users and groups: aborting...";
+            }
+
+            return doExecuteProvisioning(
+                    provisioningTask,
+                    connector,
+                    dryRun);
+        } catch (Throwable t) {
+            LOG.error("While executing provisioning job {}", getClass().getName(), t);
+            throw t;
+        }
+    }
+
+    protected abstract String doExecuteProvisioning(
+            final T task,
+            final Connector connector,
+            final boolean dryRun) throws JobExecutionException;
+
+    @Override
+    protected boolean hasToBeRegistered(final TaskExec execution) {
+        final ProvisioningTask provTask = (ProvisioningTask) task;
+
+        // True if either failed and failures have to be registered, or if ALL has to be registered.
+        return (TaskJob.Status.valueOf(execution.getStatus()) == TaskJob.Status.FAILURE
+                && provTask.getResource().getSyncTraceLevel().ordinal() >= TraceLevel.FAILURES.ordinal())
+                || provTask.getResource().getSyncTraceLevel().ordinal() >= TraceLevel.SUMMARY.ordinal();
+    }
+
+    @SuppressWarnings("unchecked")
+    private Class<T> getTaskClassReference() {
+        return (Class<T>) ((ParameterizedType) this.getClass().getGenericSuperclass()).getActualTypeArguments()[0];
+    }
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/6dfedd8f/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/sync/AbstractPushResultHandler.java
----------------------------------------------------------------------
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/sync/AbstractPushResultHandler.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/sync/AbstractPushResultHandler.java
index fd5a482..6be2167 100644
--- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/sync/AbstractPushResultHandler.java
+++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/sync/AbstractPushResultHandler.java
@@ -50,6 +50,7 @@ import org.apache.syncope.core.provisioning.api.sync.SyncopePushResultHandler;
 import org.identityconnectors.framework.common.objects.ConnectorObject;
 import org.identityconnectors.framework.common.objects.ObjectClass;
 import org.quartz.JobExecutionException;
+import org.springframework.transaction.annotation.Propagation;
 import org.springframework.transaction.annotation.Transactional;
 
 public abstract class AbstractPushResultHandler extends AbstractSyncopeResultHandler<PushTask, PushActions>
@@ -71,7 +72,7 @@ public abstract class AbstractPushResultHandler extends AbstractSyncopeResultHan
 
     protected abstract ConnectorObject getRemoteObject(String connObjectKey, ObjectClass objectClass);
 
-    @Transactional
+    @Transactional(propagation = Propagation.REQUIRES_NEW)
     @Override
     public boolean handle(final long anyKey) {
         Any<?, ?, ?> any = null;

http://git-wip-us.apache.org/repos/asf/syncope/blob/6dfedd8f/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/sync/AbstractSyncResultHandler.java
----------------------------------------------------------------------
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/sync/AbstractSyncResultHandler.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/sync/AbstractSyncResultHandler.java
index 6d8986a..b0b5a58 100644
--- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/sync/AbstractSyncResultHandler.java
+++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/sync/AbstractSyncResultHandler.java
@@ -44,7 +44,9 @@ import org.identityconnectors.framework.common.objects.SyncDelta;
 import org.identityconnectors.framework.common.objects.SyncDeltaType;
 import org.quartz.JobExecutionException;
 import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.transaction.annotation.Transactional;
 
+@Transactional(rollbackFor = Throwable.class)
 public abstract class AbstractSyncResultHandler extends AbstractSyncopeResultHandler<SyncTask, SyncActions>
         implements SyncopeSyncResultHandler {
 
@@ -614,9 +616,7 @@ public abstract class AbstractSyncResultHandler extends AbstractSyncopeResultHan
      * @param provision provisioning info
      * @throws JobExecutionException in case of synchronization failure.
      */
-    protected void doHandle(final SyncDelta delta, final Provision provision)
-            throws JobExecutionException {
-
+    protected void doHandle(final SyncDelta delta, final Provision provision) throws JobExecutionException {
         AnyUtils anyUtils = getAnyUtils();
 
         LOG.debug("Process {} for {} as {}",

http://git-wip-us.apache.org/repos/asf/syncope/blob/6dfedd8f/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/sync/AbstractSyncopeResultHandler.java
----------------------------------------------------------------------
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/sync/AbstractSyncopeResultHandler.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/sync/AbstractSyncopeResultHandler.java
index cf08d8d..49a38d3 100644
--- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/sync/AbstractSyncopeResultHandler.java
+++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/sync/AbstractSyncopeResultHandler.java
@@ -28,7 +28,6 @@ import org.apache.syncope.core.provisioning.api.UserProvisioningManager;
 import org.apache.syncope.core.provisioning.api.data.UserDataBinder;
 import org.apache.syncope.core.provisioning.api.propagation.PropagationManager;
 import org.apache.syncope.core.provisioning.api.propagation.PropagationTaskExecutor;
-import org.apache.syncope.core.provisioning.api.sync.ProvisioningActions;
 import org.apache.syncope.core.provisioning.api.sync.ProvisioningProfile;
 import org.apache.syncope.core.provisioning.api.sync.SyncopeResultHandler;
 import org.apache.syncope.core.misc.AuditManager;
@@ -39,6 +38,7 @@ import org.apache.syncope.core.persistence.api.entity.AnyUtilsFactory;
 import org.apache.syncope.core.provisioning.api.AnyObjectProvisioningManager;
 import org.apache.syncope.core.provisioning.api.data.AnyObjectDataBinder;
 import org.apache.syncope.core.provisioning.api.notification.NotificationManager;
+import org.apache.syncope.core.provisioning.api.sync.ProvisioningActions;
 import org.apache.syncope.core.workflow.api.AnyObjectWorkflowAdapter;
 import org.apache.syncope.core.workflow.api.GroupWorkflowAdapter;
 import org.apache.syncope.core.workflow.api.UserWorkflowAdapter;

http://git-wip-us.apache.org/repos/asf/syncope/blob/6dfedd8f/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/sync/PushJobDelegate.java
----------------------------------------------------------------------
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/sync/PushJobDelegate.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/sync/PushJobDelegate.java
new file mode 100644
index 0000000..ff6ff21
--- /dev/null
+++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/sync/PushJobDelegate.java
@@ -0,0 +1,192 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.syncope.core.provisioning.java.sync;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+import org.apache.commons.lang3.StringUtils;
+import org.apache.syncope.common.lib.SyncopeConstants;
+import org.apache.syncope.common.lib.types.AnyTypeKind;
+import org.apache.syncope.core.misc.search.SearchCondConverter;
+import org.apache.syncope.core.misc.spring.ApplicationContextProvider;
+import org.apache.syncope.core.persistence.api.dao.AnyDAO;
+import org.apache.syncope.core.persistence.api.dao.AnyObjectDAO;
+import org.apache.syncope.core.persistence.api.dao.AnySearchDAO;
+import org.apache.syncope.core.persistence.api.dao.GroupDAO;
+import org.apache.syncope.core.persistence.api.dao.UserDAO;
+import org.apache.syncope.core.persistence.api.dao.search.OrderByClause;
+import org.apache.syncope.core.persistence.api.entity.Any;
+import org.apache.syncope.core.persistence.api.entity.resource.Provision;
+import org.apache.syncope.core.persistence.api.entity.task.PushTask;
+import org.apache.syncope.core.provisioning.api.Connector;
+import org.apache.syncope.core.provisioning.api.sync.AnyObjectPushResultHandler;
+import org.apache.syncope.core.provisioning.api.sync.GroupPushResultHandler;
+import org.apache.syncope.core.provisioning.api.sync.ProvisioningProfile;
+import org.apache.syncope.core.provisioning.api.sync.PushActions;
+import org.apache.syncope.core.provisioning.api.sync.SyncopePushResultHandler;
+import org.apache.syncope.core.provisioning.api.sync.UserPushResultHandler;
+import org.quartz.JobExecutionException;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.support.AbstractBeanDefinition;
+
+public class PushJobDelegate extends AbstractProvisioningJobDelegate<PushTask> {
+
+    private static final int PAGE_SIZE = 1000;
+
+    /**
+     * User DAO.
+     */
+    @Autowired
+    private UserDAO userDAO;
+
+    /**
+     * Search DAO.
+     */
+    @Autowired
+    private AnySearchDAO searchDAO;
+
+    /**
+     * Group DAO.
+     */
+    @Autowired
+    private GroupDAO groupDAO;
+
+    @Autowired
+    private AnyObjectDAO anyObjectDAO;
+
+    private AnyDAO<?> getAnyDAO(final AnyTypeKind anyTypeKind) {
+        AnyDAO<?> result;
+        switch (anyTypeKind) {
+            case USER:
+                result = userDAO;
+                break;
+
+            case GROUP:
+                result = groupDAO;
+                break;
+
+            case ANY_OBJECT:
+            default:
+                result = anyObjectDAO;
+        }
+
+        return result;
+    }
+
+    @Override
+    protected String doExecuteProvisioning(
+            final PushTask pushTask,
+            final Connector connector,
+            final boolean dryRun) throws JobExecutionException {
+
+        LOG.debug("Executing push on {}", pushTask.getResource());
+
+        List<PushActions> actions = new ArrayList<>();
+        for (String className : pushTask.getActionsClassNames()) {
+            try {
+                Class<?> actionsClass = Class.forName(className);
+
+                PushActions syncActions = (PushActions) ApplicationContextProvider.getBeanFactory().
+                        createBean(actionsClass, AbstractBeanDefinition.AUTOWIRE_BY_TYPE, true);
+                actions.add(syncActions);
+            } catch (Exception e) {
+                LOG.info("Class '{}' not found", className, e);
+            }
+        }
+
+        ProvisioningProfile<PushTask, PushActions> profile = new ProvisioningProfile<>(connector, pushTask);
+        profile.setDryRun(dryRun);
+        profile.setResAct(null);
+
+        AnyObjectPushResultHandler ahandler =
+                (AnyObjectPushResultHandler) ApplicationContextProvider.getBeanFactory().
+                createBean(AnyObjectPushResultHandlerImpl.class, AbstractBeanDefinition.AUTOWIRE_BY_NAME, false);
+        ahandler.setProfile(profile);
+
+        UserPushResultHandler uhandler =
+                (UserPushResultHandler) ApplicationContextProvider.getBeanFactory().
+                createBean(UserPushResultHandlerImpl.class, AbstractBeanDefinition.AUTOWIRE_BY_NAME, false);
+        uhandler.setProfile(profile);
+
+        GroupPushResultHandler ghandler =
+                (GroupPushResultHandler) ApplicationContextProvider.getBeanFactory().
+                createBean(GroupPushResultHandlerImpl.class, AbstractBeanDefinition.AUTOWIRE_BY_NAME, false);
+        ghandler.setProfile(profile);
+
+        if (!profile.isDryRun()) {
+            for (PushActions action : actions) {
+                action.beforeAll(profile);
+            }
+        }
+
+        for (Provision provision : pushTask.getResource().getProvisions()) {
+            if (provision.getMapping() != null) {
+                AnyDAO<?> anyDAO = getAnyDAO(provision.getAnyType().getKind());
+                String filter = pushTask.getFilter(provision.getAnyType()) == null
+                        ? null
+                        : pushTask.getFilter(provision.getAnyType()).get();
+
+                int count = anyDAO.count(SyncopeConstants.FULL_ADMIN_REALMS);
+                for (int page = 1; page <= (count / PAGE_SIZE) + 1; page++) {
+                    List<? extends Any<?, ?, ?>> localAnys = StringUtils.isBlank(filter)
+                            ? anyDAO.findAll(SyncopeConstants.FULL_ADMIN_REALMS, page, PAGE_SIZE)
+                            : searchDAO.search(SyncopeConstants.FULL_ADMIN_REALMS,
+                                    SearchCondConverter.convert(filter),
+                                    Collections.<OrderByClause>emptyList(), provision.getAnyType().getKind());
+
+                    for (Any<?, ?, ?> any : localAnys) {
+                        SyncopePushResultHandler handler;
+                        switch (provision.getAnyType().getKind()) {
+                            case USER:
+                                handler = uhandler;
+                                break;
+
+                            case GROUP:
+                                handler = ghandler;
+                                break;
+
+                            case ANY_OBJECT:
+                            default:
+                                handler = ahandler;
+                        }
+
+                        try {
+                            handler.handle(any.getKey());
+                        } catch (Exception e) {
+                            LOG.warn("Failure pushing '{}' on '{}'", any, pushTask.getResource(), e);
+                            throw new JobExecutionException(
+                                    "While pushing " + any + " on " + pushTask.getResource(), e);
+                        }
+                    }
+                }
+            }
+        }
+
+        if (!profile.isDryRun()) {
+            for (PushActions action : actions) {
+                action.afterAll(profile);
+            }
+        }
+
+        String result = createReport(profile.getResults(), pushTask.getResource().getSyncTraceLevel(), dryRun);
+        LOG.debug("Sync result: {}", result);
+        return result;
+    }
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/6dfedd8f/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/sync/PushJobImpl.java
----------------------------------------------------------------------
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/sync/PushJobImpl.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/sync/PushJobImpl.java
deleted file mode 100644
index b658bc4..0000000
--- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/sync/PushJobImpl.java
+++ /dev/null
@@ -1,189 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.syncope.core.provisioning.java.sync;
-
-import java.util.Collections;
-import java.util.List;
-import org.apache.commons.lang3.StringUtils;
-import org.apache.syncope.common.lib.SyncopeConstants;
-import org.apache.syncope.common.lib.types.AnyTypeKind;
-import org.apache.syncope.core.persistence.api.dao.GroupDAO;
-import org.apache.syncope.core.persistence.api.dao.UserDAO;
-import org.apache.syncope.core.persistence.api.dao.search.OrderByClause;
-import org.apache.syncope.core.persistence.api.entity.task.PushTask;
-import org.apache.syncope.core.provisioning.api.Connector;
-import org.apache.syncope.core.provisioning.api.sync.ProvisioningProfile;
-import org.apache.syncope.core.provisioning.api.sync.PushActions;
-import org.apache.syncope.core.misc.spring.ApplicationContextProvider;
-import org.apache.syncope.core.misc.search.SearchCondConverter;
-import org.apache.syncope.core.persistence.api.dao.AnyDAO;
-import org.apache.syncope.core.persistence.api.dao.AnyObjectDAO;
-import org.apache.syncope.core.persistence.api.dao.AnySearchDAO;
-import org.apache.syncope.core.persistence.api.entity.Any;
-import org.apache.syncope.core.persistence.api.entity.resource.Provision;
-import org.apache.syncope.core.provisioning.api.job.PushJob;
-import org.apache.syncope.core.provisioning.api.sync.AnyObjectPushResultHandler;
-import org.apache.syncope.core.provisioning.api.sync.GroupPushResultHandler;
-import org.apache.syncope.core.provisioning.api.sync.SyncopePushResultHandler;
-import org.apache.syncope.core.provisioning.api.sync.UserPushResultHandler;
-import org.quartz.JobExecutionException;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.beans.factory.support.AbstractBeanDefinition;
-
-/**
- * Job for executing synchronization (towards external resource) tasks.
- *
- * @see AbstractProvisioningJob
- * @see PushTask
- * @see PushActions
- */
-public class PushJobImpl extends AbstractProvisioningJob<PushTask, PushActions> implements PushJob {
-
-    private static final int PAGE_SIZE = 1000;
-
-    /**
-     * User DAO.
-     */
-    @Autowired
-    private UserDAO userDAO;
-
-    /**
-     * Search DAO.
-     */
-    @Autowired
-    private AnySearchDAO searchDAO;
-
-    /**
-     * Group DAO.
-     */
-    @Autowired
-    private GroupDAO groupDAO;
-
-    @Autowired
-    private AnyObjectDAO anyObjectDAO;
-
-    private AnyDAO<?> getAnyDAO(final AnyTypeKind anyTypeKind) {
-        AnyDAO<?> result;
-        switch (anyTypeKind) {
-            case USER:
-                result = userDAO;
-                break;
-
-            case GROUP:
-                result = groupDAO;
-                break;
-
-            case ANY_OBJECT:
-            default:
-                result = anyObjectDAO;
-        }
-
-        return result;
-    }
-
-    @Override
-    protected String executeWithSecurityContext(
-            final PushTask pushTask,
-            final Connector connector,
-            final boolean dryRun) throws JobExecutionException {
-
-        LOG.debug("Executing push on {}", pushTask.getResource());
-
-        ProvisioningProfile<PushTask, PushActions> profile = new ProvisioningProfile<>(connector, pushTask);
-        if (actions != null) {
-            profile.getActions().addAll(actions);
-        }
-        profile.setDryRun(dryRun);
-        profile.setResAct(null);
-
-        AnyObjectPushResultHandler ahandler =
-                (AnyObjectPushResultHandler) ApplicationContextProvider.getApplicationContext().getBeanFactory().
-                createBean(AnyObjectPushResultHandlerImpl.class, AbstractBeanDefinition.AUTOWIRE_BY_NAME, false);
-        ahandler.setProfile(profile);
-
-        UserPushResultHandler uhandler =
-                (UserPushResultHandler) ApplicationContextProvider.getApplicationContext().getBeanFactory().
-                createBean(UserPushResultHandlerImpl.class, AbstractBeanDefinition.AUTOWIRE_BY_NAME, false);
-        uhandler.setProfile(profile);
-
-        GroupPushResultHandler ghandler =
-                (GroupPushResultHandler) ApplicationContextProvider.getApplicationContext().getBeanFactory().
-                createBean(GroupPushResultHandlerImpl.class, AbstractBeanDefinition.AUTOWIRE_BY_NAME, false);
-        ghandler.setProfile(profile);
-
-        if (actions != null && !profile.isDryRun()) {
-            for (PushActions action : actions) {
-                action.beforeAll(profile);
-            }
-        }
-
-        for (Provision provision : pushTask.getResource().getProvisions()) {
-            if (provision.getMapping() != null) {
-                AnyDAO<?> anyDAO = getAnyDAO(provision.getAnyType().getKind());
-                String filter = pushTask.getFilter(provision.getAnyType()) == null
-                        ? null
-                        : pushTask.getFilter(provision.getAnyType()).get();
-
-                int count = anyDAO.count(SyncopeConstants.FULL_ADMIN_REALMS);
-                for (int page = 1; page <= (count / PAGE_SIZE) + 1; page++) {
-                    List<? extends Any<?, ?, ?>> localAnys = StringUtils.isBlank(filter)
-                            ? anyDAO.findAll(SyncopeConstants.FULL_ADMIN_REALMS, page, PAGE_SIZE)
-                            : searchDAO.search(SyncopeConstants.FULL_ADMIN_REALMS,
-                                    SearchCondConverter.convert(filter),
-                                    Collections.<OrderByClause>emptyList(), provision.getAnyType().getKind());
-
-                    for (Any<?, ?, ?> any : localAnys) {
-                        SyncopePushResultHandler handler;
-                        switch (provision.getAnyType().getKind()) {
-                            case USER:
-                                handler = uhandler;
-                                break;
-
-                            case GROUP:
-                                handler = ghandler;
-                                break;
-
-                            case ANY_OBJECT:
-                            default:
-                                handler = ahandler;
-                        }
-
-                        try {
-                            handler.handle(any.getKey());
-                        } catch (Exception e) {
-                            LOG.warn("Failure pushing '{}' on '{}'", any, pushTask.getResource(), e);
-                            throw new JobExecutionException(
-                                    "While pushing " + any + " on " + pushTask.getResource(), e);
-                        }
-                    }
-                }
-            }
-        }
-
-        if (actions != null && !profile.isDryRun()) {
-            for (PushActions action : actions) {
-                action.afterAll(profile);
-            }
-        }
-
-        String result = createReport(profile.getResults(), pushTask.getResource().getSyncTraceLevel(), dryRun);
-        LOG.debug("Sync result: {}", result);
-        return result;
-    }
-}


[30/31] syncope git commit: Merge branch 'master' into SYNCOPE-156

Posted by md...@apache.org.
Merge branch 'master' into SYNCOPE-156


Project: http://git-wip-us.apache.org/repos/asf/syncope/repo
Commit: http://git-wip-us.apache.org/repos/asf/syncope/commit/d0116264
Tree: http://git-wip-us.apache.org/repos/asf/syncope/tree/d0116264
Diff: http://git-wip-us.apache.org/repos/asf/syncope/diff/d0116264

Branch: refs/heads/SYNCOPE-156
Commit: d0116264b576e125d1e70e4f7adbaf6de4be0e29
Parents: 62f5e4e 4b2dc4d
Author: Marco Di Sabatino Di Diodoro <md...@apache.org>
Authored: Fri Aug 14 10:11:06 2015 +0200
Committer: Marco Di Sabatino Di Diodoro <md...@apache.org>
Committed: Fri Aug 14 10:11:06 2015 +0200

----------------------------------------------------------------------
 .travis.yml                                     |    8 +-
 .../client/cli/commands/LoggerCommand.java      |    6 +-
 .../client/console/SyncopeConsoleSession.java   |   43 +-
 .../syncope/client/console/pages/BasePage.java  |    5 +-
 .../console/pages/BulkActionModalPage.java      |   12 +-
 .../syncope/client/console/pages/Login.java     |   49 +
 .../syncope/client/console/pages/Realms.java    |    4 -
 .../client/console/rest/BaseRestClient.java     |    3 -
 .../client/console/rest/GroupRestClient.java    |   14 +-
 .../client/console/rest/LoggerRestClient.java   |   11 +-
 .../client/console/rest/RealmRestClient.java    |    2 +-
 .../client/console/rest/UserRestClient.java     |   20 +-
 .../syncope/client/console/pages/BasePage.html  |    7 +
 .../syncope/client/console/pages/Login.html     |    1 +
 .../client/lib/SyncopeClientFactoryBean.java    |   32 +-
 .../client/console/pages/Configuration.java     |    2 -
 .../syncope/common/lib/SyncopeConstants.java    |    2 +
 .../syncope/common/lib/jaxb/package-info.java   |   23 +
 .../syncope/common/lib/mod/StatusMod.java       |    2 +
 .../syncope/common/lib/to/AbstractSchemaTO.java |   11 +
 .../syncope/common/lib/to/BulkAction.java       |   10 +-
 .../apache/syncope/common/lib/to/DomainTO.java  |   62 +
 .../apache/syncope/common/lib/to/LoggerTO.java  |    2 +
 .../syncope/common/lib/to/SchedTaskTO.java      |   10 +-
 .../common/lib/types/AbstractPolicySpec.java    |   19 +
 .../syncope/common/lib/types/AuditElements.java |    8 +
 .../syncope/common/lib/types/Entitlement.java   |   10 +-
 .../syncope/common/lib/types/LoggerType.java    |    5 +-
 .../lib/types/ResourceAssociationAction.java    |   39 +
 .../types/ResourceAssociationActionType.java    |   39 -
 .../common/rest/api/CollectionWrapper.java      |    8 +-
 .../syncope/common/rest/api/RESTHeaders.java    |    2 +
 .../common/rest/api/service/AnyService.java     |    8 +-
 .../rest/api/service/AnyTypeClassService.java   |    2 +-
 .../common/rest/api/service/DomainService.java  |   96 ++
 .../common/rest/api/service/LoggerService.java  |    6 +-
 .../common/rest/api/service/ReportService.java  |    2 +-
 .../common/rest/api/service/TaskService.java    |    2 +-
 .../common/rest/api/service/UserService.java    |    5 +-
 core/logic/pom.xml                              |   29 +
 .../syncope/core/logic/AbstractAnyLogic.java    |   25 +-
 .../syncope/core/logic/AbstractLogic.java       |    3 -
 .../syncope/core/logic/AnyObjectLogic.java      |  167 +--
 .../syncope/core/logic/AnyTypeClassLogic.java   |   36 +-
 .../apache/syncope/core/logic/AnyTypeLogic.java |    2 +-
 .../syncope/core/logic/ConfigurationLogic.java  |    3 +-
 .../apache/syncope/core/logic/DomainLogic.java  |  143 +++
 .../apache/syncope/core/logic/GroupLogic.java   |  188 +--
 .../apache/syncope/core/logic/LoggerLogic.java  |   33 +-
 .../syncope/core/logic/ResourceLogic.java       |    4 -
 .../apache/syncope/core/logic/SchemaLogic.java  |   33 +-
 .../apache/syncope/core/logic/SyncopeLogic.java |    2 +-
 .../apache/syncope/core/logic/TaskLogic.java    |   76 +-
 .../apache/syncope/core/logic/UserLogic.java    |  167 ++-
 .../logic/audit/AuditConnectionFactory.java     |  159 ---
 .../init/ImplementationClassNamesLoader.java    |   18 +-
 .../core/logic/init/JobInstanceLoaderImpl.java  |  181 ++-
 .../syncope/core/logic/init/LoggerAccessor.java |   95 ++
 .../syncope/core/logic/init/LoggerLoader.java   |  107 +-
 .../core/logic/init/LogicInitializer.java       |    3 +
 .../logic/notification/NotificationJob.java     |  237 +---
 .../notification/NotificationJobDelegate.java   |  258 ++++
 .../syncope/core/logic/report/ReportJob.java    |  158 +--
 .../core/logic/report/ReportJobDelegate.java    |  181 +++
 .../apache/syncope/core/logic/AbstractTest.java |    5 +-
 .../apache/syncope/core/logic/MappingTest.java  |   67 --
 .../syncope/core/logic/NotificationTest.java    |    6 +-
 core/logic/src/test/resources/logicTest.xml     |   23 +-
 core/misc/pom.xml                               |    7 +-
 .../apache/syncope/core/misc/AuditManager.java  |   23 +-
 .../apache/syncope/core/misc/MappingUtils.java  |   26 +-
 .../apache/syncope/core/misc/RealmUtils.java    |    4 +-
 .../core/misc/policy/AccountPolicyEnforcer.java |   18 +-
 .../misc/policy/PasswordPolicyEnforcer.java     |    7 +-
 .../core/misc/policy/PolicyEnforcer.java        |   27 -
 .../core/misc/policy/PolicyEvaluator.java       |    5 +-
 .../core/misc/security/AuthContextUtils.java    |   66 +-
 .../core/misc/security/AuthDataAccessor.java    |  288 +++++
 .../core/misc/security/PasswordGenerator.java   |   15 +-
 .../security/SyncopeAuthenticationDetails.java  |   86 ++
 .../SyncopeAuthenticationDetailsSource.java     |   32 +
 .../security/SyncopeAuthenticationProvider.java |  278 ++---
 .../misc/security/SyncopeGrantedAuthority.java  |    7 +
 .../security/SyncopeUserDetailsService.java     |   88 +-
 .../misc/security/UnauthorizedException.java    |    5 +-
 .../misc/spring/ApplicationContextProvider.java |   12 +-
 .../misc/src/main/resources/securityContext.xml |    7 +-
 .../core/persistence/api/DomainsHolder.java     |   27 +
 .../api/content/ContentExporter.java            |    2 +-
 .../core/persistence/api/dao/DomainDAO.java     |   33 +
 .../core/persistence/api/dao/UserDAO.java       |    3 +
 .../core/persistence/api/entity/Domain.java     |   32 +
 .../persistence/api/entity/task/SchedTask.java  |    4 +-
 core/persistence-jpa/pom.xml                    |   12 +-
 .../jpa/content/AbstractContentDealer.java      |   57 +-
 .../jpa/content/XMLContentExporter.java         |   36 +-
 .../jpa/content/XMLContentLoader.java           |  113 +-
 .../persistence/jpa/dao/AbstractAnyDAO.java     |   17 +-
 .../core/persistence/jpa/dao/AbstractDAO.java   |   51 +-
 .../persistence/jpa/dao/JPAAnyObjectDAO.java    |    8 +-
 .../persistence/jpa/dao/JPAAnySearchDAO.java    |   15 +-
 .../persistence/jpa/dao/JPAAnyTypeClassDAO.java |   20 +-
 .../core/persistence/jpa/dao/JPAAnyTypeDAO.java |   10 +-
 .../core/persistence/jpa/dao/JPAConfDAO.java    |    8 +-
 .../persistence/jpa/dao/JPAConnInstanceDAO.java |    8 +-
 .../core/persistence/jpa/dao/JPADerAttrDAO.java |    8 +-
 .../persistence/jpa/dao/JPADerSchemaDAO.java    |   12 +-
 .../core/persistence/jpa/dao/JPADomainDAO.java  |   59 +
 .../jpa/dao/JPAExternalResourceDAO.java         |   28 +-
 .../core/persistence/jpa/dao/JPAGroupDAO.java   |   16 +-
 .../core/persistence/jpa/dao/JPALoggerDAO.java  |    8 +-
 .../persistence/jpa/dao/JPANotificationDAO.java |    8 +-
 .../persistence/jpa/dao/JPAPlainAttrDAO.java    |    4 +-
 .../jpa/dao/JPAPlainAttrValueDAO.java           |    8 +-
 .../persistence/jpa/dao/JPAPlainSchemaDAO.java  |   12 +-
 .../core/persistence/jpa/dao/JPAPolicyDAO.java  |   12 +-
 .../core/persistence/jpa/dao/JPARealmDAO.java   |   14 +-
 .../jpa/dao/JPARelationshipTypeDAO.java         |   14 +-
 .../core/persistence/jpa/dao/JPAReportDAO.java  |   13 +-
 .../persistence/jpa/dao/JPAReportExecDAO.java   |   10 +-
 .../core/persistence/jpa/dao/JPARoleDAO.java    |   21 +-
 .../jpa/dao/JPASecurityQuestionDAO.java         |    8 +-
 .../core/persistence/jpa/dao/JPATaskDAO.java    |   15 +-
 .../persistence/jpa/dao/JPATaskExecDAO.java     |   10 +-
 .../core/persistence/jpa/dao/JPAUserDAO.java    |  176 ++-
 .../core/persistence/jpa/dao/JPAVirAttrDAO.java |    8 +-
 .../persistence/jpa/dao/JPAVirSchemaDAO.java    |   12 +-
 .../jpa/entity/AnnotatedEntityListener.java     |    2 +-
 .../persistence/jpa/entity/JPADerSchema.java    |    3 +-
 .../core/persistence/jpa/entity/JPADomain.java  |   79 ++
 .../jpa/entity/JPAEntityFactory.java            |    5 +-
 .../persistence/jpa/entity/JPAPlainSchema.java  |    3 +-
 .../persistence/jpa/entity/JPAVirSchema.java    |    3 +-
 .../persistence/jpa/entity/group/JPAGroup.java  |    2 +-
 .../entity/task/AbstractProvisioningTask.java   |    6 +-
 .../jpa/entity/task/JPAPushTask.java            |    3 +-
 .../jpa/entity/task/JPASchedTask.java           |   11 +-
 .../jpa/entity/task/JPASyncTask.java            |    3 +-
 .../persistence/jpa/entity/user/JPAUser.java    |   10 +-
 .../spring/CommonEntityManagerFactoryConf.java  |  107 ++
 .../spring/DomainEntityManagerFactoryBean.java  |   45 +
 .../spring/DomainTransactionInterceptor.java    |   70 ++
 .../jpa/spring/SpringComponentReplacer.java     |   42 +
 .../jpa/validation/entity/DomainCheck.java      |   41 +
 .../jpa/validation/entity/DomainValidator.java  |   42 +
 .../entity/EntityValidationListener.java        |    2 +-
 .../entity/ProvisioningTaskValidator.java       |   14 +-
 .../validation/entity/SchedTaskValidator.java   |   44 +-
 .../jpa/validation/entity/UserCheck.java        |   41 -
 .../jpa/validation/entity/UserValidator.java    |  199 ---
 .../src/main/resources/audit/audit.sql          |    4 +-
 .../src/main/resources/content.xml              |  117 --
 .../src/main/resources/domains.xml              |   56 +
 .../main/resources/domains/Master.properties    |   28 +
 .../main/resources/domains/MasterContent.xml    |  124 ++
 .../src/main/resources/domains/MasterDomain.xml |  125 ++
 .../src/main/resources/persistence.properties   |   12 -
 .../src/main/resources/persistenceContext.xml   |   93 +-
 .../resources/persistenceContextEMFactory.xml   |   67 --
 .../src/main/resources/quartz/tables_h2.sql     |  266 ----
 .../main/resources/quartz/tables_mariadb.sql    |  206 ----
 .../src/main/resources/quartz/tables_mysql.sql  |  206 ----
 .../resources/quartz/tables_mysql_innodb.sql    |  221 ----
 .../src/main/resources/quartz/tables_oracle.sql |  208 ----
 .../main/resources/quartz/tables_postgres.sql   |  204 ----
 .../main/resources/quartz/tables_sqlServer.sql  |  296 -----
 .../core/persistence/jpa/AbstractTest.java      |   16 +
 .../core/persistence/jpa/inner/DomainTest.java  |   88 ++
 .../persistence/jpa/inner/MultitenancyTest.java |  111 ++
 .../core/persistence/jpa/inner/TaskTest.java    |   27 +
 .../core/persistence/jpa/inner/UserTest.java    |   20 +-
 .../persistence/jpa/outer/AnyTypeClassTest.java |   32 +
 .../core/persistence/jpa/outer/GroupTest.java   |   11 +-
 .../persistence/jpa/outer/ResourceTest.java     |    5 +-
 .../core/persistence/jpa/outer/RoleTest.java    |   41 +-
 .../resources/META-INF/persistence-enhance.xml  |    2 +-
 .../src/test/resources/content.xml              | 1138 ------------------
 .../test/resources/domains/Master.properties    |   28 +
 .../test/resources/domains/MasterContent.xml    | 1131 +++++++++++++++++
 .../src/test/resources/domains/Two.properties   |   28 +
 .../src/test/resources/domains/TwoContent.xml   |  134 +++
 .../src/test/resources/domains/TwoDomain.xml    |  125 ++
 .../src/test/resources/persistence.properties   |   30 -
 .../src/test/resources/persistenceTest.xml      |    1 +
 .../api/AnyObjectProvisioningManager.java       |    5 +
 .../api/GroupProvisioningManager.java           |    3 +
 .../api/UserProvisioningManager.java            |   14 +-
 .../core/provisioning/api/UserSuspender.java    |   26 -
 .../provisioning/api/data/DomainDataBinder.java |   31 +
 .../provisioning/api/data/SchemaDataBinder.java |   18 +-
 .../provisioning/api/job/JobInstanceLoader.java |   12 +-
 .../core/provisioning/api/job/JobNamer.java     |   10 +-
 .../provisioning/api/job/ProvisioningJob.java   |   28 -
 .../core/provisioning/api/job/PushJob.java      |   26 -
 .../api/job/SchedTaskJobDelegate.java           |   26 +
 .../core/provisioning/api/job/SyncJob.java      |   26 -
 .../core/provisioning/api/job/TaskJob.java      |   43 -
 .../api/propagation/PropagationManager.java     |    5 +-
 core/provisioning-java/pom.xml                  |   13 +
 .../provisioning/java/ConnectorFacadeProxy.java |    2 +-
 .../provisioning/java/ConnectorManager.java     |    2 +-
 .../DefaultAnyObjectProvisioningManager.java    |   46 +-
 .../java/DefaultGroupProvisioningManager.java   |   62 +-
 .../java/DefaultUserProvisioningManager.java    |  133 +-
 .../provisioning/java/UserSuspenderImpl.java    |   51 -
 .../java/data/AbstractAnyDataBinder.java        |   18 +-
 .../java/data/AnyObjectDataBinderImpl.java      |    2 -
 .../java/data/AnyTypeClassDataBinderImpl.java   |   27 +-
 .../java/data/ConfigurationDataBinderImpl.java  |    2 -
 .../java/data/DomainDataBinderImpl.java         |   70 ++
 .../java/data/SchemaDataBinderImpl.java         |  155 ++-
 .../java/data/TaskDataBinderImpl.java           |    8 +-
 .../java/data/UserDataBinderImpl.java           |    8 +-
 .../java/job/AbstractSchedTaskJobDelegate.java  |  144 +++
 .../provisioning/java/job/AbstractTaskJob.java  |  216 ----
 .../java/job/AbstractTransactionalTaskJob.java  |   35 -
 .../core/provisioning/java/job/SampleJob.java   |   52 -
 .../java/job/SpringBeanJobFactory.java          |   12 +-
 .../core/provisioning/java/job/TaskJob.java     |  119 ++
 .../propagation/PropagationManagerImpl.java     |    6 +-
 .../java/sync/AbstractProvisioningJob.java      |  478 --------
 .../sync/AbstractProvisioningJobDelegate.java   |  434 +++++++
 .../java/sync/AbstractPushResultHandler.java    |    3 +-
 .../java/sync/AbstractSyncResultHandler.java    |    6 +-
 .../java/sync/AbstractSyncopeResultHandler.java |    2 +-
 .../provisioning/java/sync/PushJobDelegate.java |  192 +++
 .../provisioning/java/sync/PushJobImpl.java     |  189 ---
 .../provisioning/java/sync/SyncJobDelegate.java |  221 ++++
 .../provisioning/java/sync/SyncJobImpl.java     |  212 ----
 .../core/provisioning/java/sync/SyncUtils.java  |    2 +
 .../java/sync/UserSyncResultHandlerImpl.java    |    7 +-
 .../src/main/resources/provisioning.properties  |    3 +
 .../src/main/resources/provisioningContext.xml  |   27 +-
 .../src/main/resources/quartz/tables_h2.sql     |  266 ++++
 .../main/resources/quartz/tables_mariadb.sql    |  206 ++++
 .../src/main/resources/quartz/tables_mysql.sql  |  206 ++++
 .../resources/quartz/tables_mysql_innodb.sql    |  221 ++++
 .../src/main/resources/quartz/tables_oracle.sql |  208 ++++
 .../main/resources/quartz/tables_postgres.sql   |  204 ++++
 .../main/resources/quartz/tables_sqlServer.sql  |  296 +++++
 .../core/provisioning/java/AbstractTest.java    |    2 +
 .../provisioning/java/ConnectorManagerTest.java |    2 +-
 .../core/provisioning/java/MappingTest.java     |   69 ++
 .../java/ResourceDataBinderTest.java            |  130 ++
 .../core/provisioning/java/TestInitializer.java |   37 +
 .../java/data/ResourceDataBinderTest.java       |  132 --
 .../src/test/resources/provisioningTest.xml     |    7 +-
 .../syncope/core/rest/cxf/AddDomainFilter.java  |   39 +
 .../syncope/core/rest/cxf/AddETagFilter.java    |   48 +
 .../rest/cxf/service/AbstractAnyService.java    |   14 +-
 .../core/rest/cxf/service/AddETagFilter.java    |   50 -
 .../rest/cxf/service/ConnectorServiceImpl.java  |    2 +-
 .../rest/cxf/service/DomainServiceImpl.java     |   66 +
 .../rest/cxf/service/LoggerServiceImpl.java     |   10 +-
 .../rest/cxf/service/ResourceServiceImpl.java   |    2 +-
 .../core/rest/cxf/service/TaskServiceImpl.java  |    2 +-
 .../rest/cxf/service/UserSelfServiceImpl.java   |    6 +-
 .../core/rest/cxf/service/UserServiceImpl.java  |    5 +-
 .../src/main/resources/restCXFContext.xml       |    7 +-
 .../activiti/ActivitiDefinitionLoader.java      |   67 +-
 .../workflow/activiti/ActivitiImportUtils.java  |   35 +-
 .../activiti/ActivitiUserWorkflowAdapter.java   |  153 ++-
 .../activiti/spring/DomainProcessEngine.java    |  102 ++
 .../spring/DomainProcessEngineFactoryBean.java  |  104 ++
 .../task/AbstractActivitiServiceTask.java       |    7 +-
 .../workflow/activiti/task/AutoActivate.java    |    2 +-
 .../core/workflow/activiti/task/Create.java     |    8 +-
 .../core/workflow/activiti/task/Delete.java     |    5 +-
 .../workflow/activiti/task/GenerateToken.java   |    5 +-
 .../core/workflow/activiti/task/Notify.java     |    9 +-
 .../workflow/activiti/task/PasswordReset.java   |   11 +-
 .../core/workflow/activiti/task/Update.java     |   12 +-
 .../main/resources/workflowActivitiContext.xml  |   17 +-
 .../core/workflow/api/UserWorkflowAdapter.java  |   13 +-
 .../java/AbstractAnyObjectWorkflowAdapter.java  |    3 +-
 .../java/AbstractGroupWorkflowAdapter.java      |    3 +-
 .../java/AbstractUserWorkflowAdapter.java       |   57 +-
 .../java/DefaultUserWorkflowAdapter.java        |    2 -
 .../core/logic/init/CamelRouteLoader.java       |   28 +-
 .../persistence/jpa/dao/JPACamelRouteDAO.java   |   10 +-
 .../camel/AbstractCamelProvisioningManager.java |    4 +-
 .../CamelAnyObjectProvisioningManager.java      |   19 +
 .../camel/CamelGroupProvisioningManager.java    |   23 +-
 .../camel/CamelUserProvisioningManager.java     |   67 +-
 .../processor/AnyObjectCreateProcessor.java     |    2 +-
 .../processor/AnyObjectDeleteProcessor.java     |    2 +-
 .../AnyObjectDeprovisionProcessor.java          |    2 +-
 .../processor/AnyObjectProvisionProcessor.java  |   77 ++
 .../processor/AnyObjectUpdateProcessor.java     |    2 +-
 .../camel/processor/GroupCreateProcessor.java   |    2 +-
 .../camel/processor/GroupDeleteProcessor.java   |    2 +-
 .../processor/GroupDeprovisionProcessor.java    |    4 +-
 .../processor/GroupProvisionProcessor.java      |   77 ++
 .../camel/processor/GroupUpdateProcessor.java   |    2 +-
 .../processor/UserConfirmPwdResetProcessor.java |    7 +-
 .../camel/processor/UserCreateProcessor.java    |    2 +-
 .../camel/processor/UserDeleteProcessor.java    |    2 +-
 .../processor/UserDeprovisionProcessor.java     |    2 +-
 .../processor/UserInnerSuspendProcessor.java    |   61 -
 .../processor/UserInternalSuspendProcessor.java |   61 +
 .../camel/processor/UserProvisionProcessor.java |   98 ++
 .../processor/UserSetStatusInSyncProcessor.java |    2 +-
 .../UserStatusPropagationProcessor.java         |   13 +-
 .../processor/UserUpdateInSyncProcessor.java    |    2 +-
 .../camel/processor/UserUpdateProcessor.java    |    2 +-
 .../src/main/resources/anyObjectRoutes.xml      |    6 +
 .../src/main/resources/groupRoutes.xml          |    6 +
 .../src/main/resources/userRoutes.xml           |   20 +-
 fit/core-reference/pom.xml                      |   10 +-
 .../fit/core/reference/TestSampleJob.java       |   64 -
 .../core/reference/TestSampleJobDelegate.java   |   64 +
 .../main/resources/all/provisioning.properties  |    6 +-
 .../src/main/resources/coreContext.xml          |    2 +
 .../src/main/resources/log4j2.xml               |   41 +-
 .../src/main/resources/provisioning.properties  |    4 +
 .../src/main/webapp/cacheStats.jsp              |    5 +-
 fit/core-reference/src/main/webapp/db.jsp       |    3 +-
 .../fit/core/reference/AbstractITCase.java      |   19 +-
 .../fit/core/reference/AbstractTaskITCase.java  |   22 +-
 .../fit/core/reference/AnyTypeClassITCase.java  |   24 +-
 .../fit/core/reference/AnyTypeITCase.java       |    1 -
 .../core/reference/AuthenticationITCase.java    |  102 +-
 .../fit/core/reference/CamelRouteITCase.java    |    5 +-
 .../fit/core/reference/ConnectorITCase.java     |    9 +-
 .../fit/core/reference/DomainITCase.java        |  118 ++
 .../core/reference/ExceptionMapperITCase.java   |    3 +-
 .../syncope/fit/core/reference/GroupITCase.java |   24 +-
 .../fit/core/reference/LoggerITCase.java        |   11 +-
 .../fit/core/reference/MultitenancyITCase.java  |  214 ++++
 .../core/reference/PropagationTaskITCase.java   |    2 +-
 .../fit/core/reference/PushTaskITCase.java      |   25 +-
 .../fit/core/reference/ResourceITCase.java      |    2 +-
 .../fit/core/reference/SchedTaskITCase.java     |    5 +-
 .../fit/core/reference/SyncTaskITCase.java      |   57 +-
 .../syncope/fit/core/reference/UserITCase.java  |   85 +-
 .../fit/core/reference/VirAttrITCase.java       |    6 +-
 pom.xml                                         |   12 +-
 337 files changed, 10976 insertions(+), 7572 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/syncope/blob/d0116264/client/console/src/main/java/org/apache/syncope/client/console/pages/Realms.java
----------------------------------------------------------------------

http://git-wip-us.apache.org/repos/asf/syncope/blob/d0116264/client/console/src/main/java/org/apache/syncope/client/console/rest/GroupRestClient.java
----------------------------------------------------------------------

http://git-wip-us.apache.org/repos/asf/syncope/blob/d0116264/client/console/src/main/java/org/apache/syncope/client/console/rest/RealmRestClient.java
----------------------------------------------------------------------

http://git-wip-us.apache.org/repos/asf/syncope/blob/d0116264/client/console/src/main/java/org/apache/syncope/client/console/rest/UserRestClient.java
----------------------------------------------------------------------


[12/31] syncope git commit: [SYNCOPE-652] Still several things to refine, but it starts taking shape

Posted by md...@apache.org.
http://git-wip-us.apache.org/repos/asf/syncope/blob/6dfedd8f/core/persistence-jpa/src/test/resources/domains/Two.properties
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/test/resources/domains/Two.properties b/core/persistence-jpa/src/test/resources/domains/Two.properties
new file mode 100644
index 0000000..b37a969
--- /dev/null
+++ b/core/persistence-jpa/src/test/resources/domains/Two.properties
@@ -0,0 +1,28 @@
+# 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.
+Two.driverClassName=org.h2.Driver
+Two.url=jdbc:h2:file:${project.build.directory}/test-classes/syncopetwo.db;DB_CLOSE_DELAY=-1
+Two.schema=
+Two.username=sa
+Two.password=
+Two.databasePlatform=org.apache.openjpa.jdbc.sql.H2Dictionary
+Two.orm=META-INF/spring-orm.xml
+
+# note: other connection pool settings can also be configured here, see DataSource definition
+Two.pool.validationQuery=SELECT 1
+
+Two.audit.sql=audit.sql

http://git-wip-us.apache.org/repos/asf/syncope/blob/6dfedd8f/core/persistence-jpa/src/test/resources/domains/TwoContent.xml
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/test/resources/domains/TwoContent.xml b/core/persistence-jpa/src/test/resources/domains/TwoContent.xml
new file mode 100644
index 0000000..92216fd
--- /dev/null
+++ b/core/persistence-jpa/src/test/resources/domains/TwoContent.xml
@@ -0,0 +1,124 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+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.
+-->
+<dataset>
+  <Realm id="1" name="/"/>
+
+  <SyncopeConf id="1" 
+               creator="admin" lastModifier="admin"
+               creationDate="2014-06-20 11:00:00" lastChangeDate="2014-06-20 11:00:00"/>
+
+  <PlainSchema name="password.cipher.algorithm" type="String"
+               mandatoryCondition="true" multivalue="0" uniqueConstraint="0" readonly="0"/>
+  <CPlainAttr id="1" owner_id="1" schema_name="password.cipher.algorithm"/>
+  <CPlainAttrValue id="1" attribute_id="1" stringValue="SHA1"/>
+
+  <!-- notificationjob.cronExpression:
+  + not existing: NotificationJob runs according to Notification.DEFAULT_CRON_EXP
+  + provided as empty string: NotificationJob disabled
+  + provided as non-empty string: NotificationJob runs according to the given value -->
+  <PlainSchema name="notificationjob.cronExpression" type="String"
+               mandatoryCondition="false" multivalue="0" uniqueConstraint="0" readonly="0"/>
+  <CPlainAttr id="2" owner_id="1" schema_name="notificationjob.cronExpression"/>
+  <CPlainAttrValue id="2" attribute_id="2" stringValue=""/>
+
+  <PlainSchema name="notification.maxRetries" type="Long"
+               mandatoryCondition="true" multivalue="0" uniqueConstraint="0" readonly="0"/>
+  <CPlainAttr id="3" owner_id="1" schema_name="notification.maxRetries"/>
+  <CPlainAttrValue id="3" attribute_id="3" longValue="3"/>
+
+  <PlainSchema name="token.length" type="Long"
+               mandatoryCondition="true" multivalue="0" uniqueConstraint="0" readonly="0"/>
+  <CPlainAttr id="4" owner_id="1" schema_name="token.length"/>
+  <CPlainAttrValue id="4" attribute_id="4" longValue="256"/>
+
+  <PlainSchema name="token.expireTime" type="Long"
+               mandatoryCondition="true" multivalue="0" uniqueConstraint="0" readonly="0"/>
+  <CPlainAttr id="5" owner_id="1" schema_name="token.expireTime"/>
+  <CPlainAttrValue id="5" attribute_id="5" longValue="60"/>
+
+  <PlainSchema name="selfRegistration.allowed" type="Boolean"
+               mandatoryCondition="true" multivalue="0" uniqueConstraint="0" readonly="0"/>
+  <CPlainAttr id="6" owner_id="1" schema_name="selfRegistration.allowed"/>
+  <CPlainAttrValue id="6" attribute_id="6" booleanValue="1"/>
+
+  <PlainSchema name="passwordReset.allowed" type="Boolean"
+               mandatoryCondition="true" multivalue="0" uniqueConstraint="0" readonly="0"/>
+  <CPlainAttr id="7" owner_id="1" schema_name="passwordReset.allowed"/>
+  <CPlainAttrValue id="7" attribute_id="7" booleanValue="1"/>
+
+  <PlainSchema name="passwordReset.securityQuestion" type="Boolean"
+               mandatoryCondition="true" multivalue="0" uniqueConstraint="0" readonly="0"/>
+  <CPlainAttr id="8" owner_id="1" schema_name="passwordReset.securityQuestion"/>
+  <CPlainAttrValue id="8" attribute_id="8" booleanValue="1"/>
+
+  <PlainSchema name="authentication.statuses" type="String"
+               mandatoryCondition="true" multivalue="1" uniqueConstraint="0" readonly="0"/>
+  <CPlainAttr id="9" owner_id="1" schema_name="authentication.statuses"/>
+  <CPlainAttrValue id="9" attribute_id="9" stringValue="created"/>
+  <CPlainAttrValue id="10" attribute_id="9" stringValue="active"/>
+
+  <!-- Save user login date upon successful authentication -->
+  <PlainSchema name="log.lastlogindate" type="Boolean"
+               mandatoryCondition="true" multivalue="0" uniqueConstraint="0" readonly="0"/>
+  <CPlainAttr id="11" owner_id="1" schema_name="log.lastlogindate"/>
+  <CPlainAttrValue id="11" attribute_id="11" booleanValue="1"/>
+
+  <PlainSchema name="tasks.interruptMaxRetries" type="Long"
+               mandatoryCondition="true" multivalue="0" uniqueConstraint="0" readonly="0"/>
+  <CPlainAttr id="12" owner_id="1" schema_name="tasks.interruptMaxRetries"/>
+  <CPlainAttrValue id="12" attribute_id="12" longValue="20"/>
+
+  <AnyType name="USER" kind="USER"/>
+  <AnyTypeClass name="BaseUser"/>
+  <AnyType_AnyTypeClass anyType_name="USER" anyTypeClass_name="BaseUser"/>
+
+  <AnyType name="GROUP" kind="GROUP"/>
+  
+  <!-- For usage with admin console -->
+  <PlainSchema name="admin.user.layout" type="String"
+               mandatoryCondition="false" multivalue="1" uniqueConstraint="0" readonly="0"/>
+  <PlainSchema name="self.user.layout" type="String"
+               mandatoryCondition="false" multivalue="1" uniqueConstraint="0" readonly="0"/>
+  <PlainSchema name="admin.group.layout" type="String"
+               mandatoryCondition="false" multivalue="1" uniqueConstraint="0" readonly="0"/>
+  <PlainSchema name="self.group.layout" type="String"
+               mandatoryCondition="false" multivalue="1" uniqueConstraint="0" readonly="0"/>
+  <PlainSchema name="admin.membership.layout" type="String"
+               mandatoryCondition="false" multivalue="1" uniqueConstraint="0" readonly="0"/>
+  <PlainSchema name="self.membership.layout" type="String"
+               mandatoryCondition="false" multivalue="1" uniqueConstraint="0" readonly="0"/>
+        
+  <PlainSchema name="email" type="String" anyTypeClass_name="BaseUser"
+               mandatoryCondition="false" multivalue="0" uniqueConstraint="0" readonly="0"
+               validatorClass="org.apache.syncope.core.persistence.jpa.attrvalue.validation.EmailAddressValidator"/>
+  
+  <!-- Password reset notifications -->
+  <Notification id="1" active="1" recipientAttrName="email" recipientAttrType="UserPlainSchema" selfAsRecipient="1" 
+                sender="admin@syncope.apache.org" subject="Password Reset request" template="requestPasswordReset" 
+                traceLevel="FAILURES"/> 
+  <AnyAbout id="1" anyType_name="USER" notification_id="1" about="token!=$null"/>
+  <Notification_events Notification_id="1" event="[CUSTOM]:[]:[]:[requestPasswordReset]:[SUCCESS]"/>
+  
+  <Notification id="2" active="1" recipientAttrName="email" recipientAttrType="UserPlainSchema" selfAsRecipient="1" 
+                sender="admin@syncope.apache.org" subject="Password Reset successful" template="confirmPasswordReset" 
+                traceLevel="FAILURES"/> 
+  <Notification_events Notification_id="2" event="[CUSTOM]:[]:[]:[confirmPasswordReset]:[SUCCESS]"/>
+
+</dataset>

http://git-wip-us.apache.org/repos/asf/syncope/blob/6dfedd8f/core/persistence-jpa/src/test/resources/domains/TwoDomain.xml
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/test/resources/domains/TwoDomain.xml b/core/persistence-jpa/src/test/resources/domains/TwoDomain.xml
new file mode 100644
index 0000000..c7e7a9b
--- /dev/null
+++ b/core/persistence-jpa/src/test/resources/domains/TwoDomain.xml
@@ -0,0 +1,125 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+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.
+-->
+<beans xmlns="http://www.springframework.org/schema/beans"
+       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+       xmlns:tx="http://www.springframework.org/schema/tx"
+       xmlns:util="http://www.springframework.org/schema/util"
+       xsi:schemaLocation="http://www.springframework.org/schema/beans
+                           http://www.springframework.org/schema/beans/spring-beans.xsd                           
+                           http://www.springframework.org/schema/tx
+                           http://www.springframework.org/schema/tx/spring-tx.xsd
+                           http://www.springframework.org/schema/util
+                           http://www.springframework.org/schema/util/spring-util.xsd">
+  
+  <bean id="TwoContentXML" class="org.apache.syncope.core.misc.spring.ResourceWithFallbackLoader">
+    <property name="primary" value="file:${content.directory}/domains/TwoContent.xml"/>
+    <property name="fallback" value="classpath:domains/TwoContent.xml"/>
+  </bean>
+  <bean id="TwoProperties" class="org.apache.syncope.core.misc.spring.ResourceWithFallbackLoader">
+    <property name="primary" value="file:${content.directory}/domains/Two.properties"/>
+    <property name="fallback" value="classpath:domains/Two.properties"/>
+  </bean>
+  <bean id="TwoDatabaseSchema" class="java.lang.String">
+    <constructor-arg value="${Two.schema}"/>
+  </bean>
+
+  <!-- Use JNDI datasource as default but, when not available, revert to
+  local datasource, with different properties for execution and testing. 
+  In any case, get all JDBC connections with a determined isolation level. -->
+  <bean id="TwoDataSource" class="org.springframework.jndi.JndiObjectFactoryBean">
+    <property name="jndiName" value="java:comp/env/jdbc/syncopeTwoDataSource"/>
+    <property name="defaultObject" ref="localTwoDataSource"/>
+  </bean>
+
+  <bean id="localTwoDataSource" class="org.apache.commons.dbcp2.BasicDataSource" destroy-method="close">
+    <property name="driverClassName" value="${Two.driverClassName}"/>
+    <property name="url" value="${Two.url}"/>
+    <property name="username" value="${Two.username}"/>
+    <property name="password" value="${Two.password}"/>
+    <!-- connection pool configuration - transaction isolation, default READ_COMMITTED (see SYNCOPE-202) -->
+    <property name="defaultTransactionIsolation">
+      <util:constant static-field="${Two.pool.defaultTransactionIsolation:java.sql.Connection.TRANSACTION_READ_COMMITTED}"/>
+    </property>
+    <!-- connection pool configuration - default values taken from BasicDataSource default values -->
+    <property name="initialSize" value="${Two.pool.initialSize:0}"/>
+    <property name="maxTotal" value="${Two.pool.maxActive:8}"/>
+    <property name="maxIdle" value="${Two.pool.maxIdle:8}"/>
+    <property name="minIdle" value="${Two.pool.minIdle:0}"/>
+    <property name="maxWaitMillis" value="${Two.pool.maxWait:-1}"/>
+    <!--<property name="validationQuery" value="${Two.pool.validationQuery}"/>-->
+    <property name="validationQueryTimeout" value="${Two.pool.validationQueryTimeout:-1}"/>
+    <property name="testOnBorrow" value="${Two.pool.testOnBorrow:true}"/>
+    <property name="testOnReturn" value="${Two.pool.testOnReturn:false}"/>
+    <property name="testWhileIdle" value="${Two.pool.testWhileIdle:false}"/>
+    <property name="timeBetweenEvictionRunsMillis" value="${Two.pool.timeBetweenEvictionRunsMillis:-1}"/>
+    <property name="numTestsPerEvictionRun" value="${Two.pool.numTestsPerEvictionRun:3}"/>
+    <property name="minEvictableIdleTimeMillis" value="${Two.pool.minEvictableIdleTimeMillis:1800000}"/>
+    <property name="removeAbandonedOnBorrow" value="${Two.pool.removeAbandoned:false}"/>
+    <property name="removeAbandonedOnMaintenance" value="${Two.pool.removeAbandoned:false}"/>
+    <property name="removeAbandonedTimeout" value="${Two.pool.removeAbandonedTimeout:300}"/>
+    <property name="logAbandoned" value="${Two.pool.logAbandoned:false}"/>
+  </bean>
+  
+  <bean class="org.springframework.jdbc.datasource.init.DataSourceInitializer">
+    <property name="dataSource" ref="TwoDataSource"/>
+    <property name="enabled" value="true"/>
+    <property name="databasePopulator">
+      <bean class="org.springframework.jdbc.datasource.init.ResourceDatabasePopulator">
+        <property name="continueOnError" value="true"/>
+        <property name="ignoreFailedDrops" value="true"/>
+        <property name="sqlScriptEncoding" value="UTF-8"/>
+        <property name="scripts">
+          <array>
+            <value type="org.springframework.core.io.Resource">
+              classpath:/audit/${Two.audit.sql}
+            </value>
+          </array>
+        </property>
+      </bean>
+    </property>
+  </bean>
+  
+  <bean id="TwoEntityManagerFactory"
+        class="org.apache.syncope.core.persistence.jpa.spring.DomainEntityManagerFactoryBean">
+    <property name="mappingResources">
+      <list>
+        <value>${Two.orm}</value>
+      </list>
+    </property>
+    <property name="persistenceUnitName" value="Two"/>
+    <property name="dataSource" ref="TwoDataSource"/>
+    <property name="jpaVendorAdapter">
+      <bean class="org.springframework.orm.jpa.vendor.OpenJpaVendorAdapter">
+        <property name="showSql" value="false"/>
+        <property name="generateDdl" value="true"/>
+        <property name="databasePlatform" value="${Two.databasePlatform}"/>
+      </bean>
+    </property>
+    <property name="commonEntityManagerFactoryConf" ref="commonEMFConf"/>
+  </bean>  
+
+  <bean id="TwoTransactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
+    <property name="entityManagerFactory" ref="TwoEntityManagerFactory"/>
+    <qualifier value="Two"/>
+  </bean>
+  
+  <tx:annotation-driven transaction-manager="TwoTransactionManager"/>
+
+</beans>
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/syncope/blob/6dfedd8f/core/persistence-jpa/src/test/resources/persistence.properties
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/test/resources/persistence.properties b/core/persistence-jpa/src/test/resources/persistence.properties
deleted file mode 100644
index 31ea1b0..0000000
--- a/core/persistence-jpa/src/test/resources/persistence.properties
+++ /dev/null
@@ -1,31 +0,0 @@
-# Licensed to the Apache Software Foundation (ASF) under one
-# or more contributor license agreements.  See the NOTICE file
-# distributed with this work for additional information
-# regarding copyright ownership.  The ASF licenses this file
-# to you under the Apache License, Version 2.0 (the
-# "License"); you may not use this file except in compliance
-# with the License.  You may obtain a copy of the License at
-#
-#   http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing,
-# software distributed under the License is distributed on an
-# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-# KIND, either express or implied.  See the License for the
-# specific language governing permissions and limitations
-# under the License.
-content.directory=${conf.directory}
-jpa.driverClassName=org.h2.Driver
-jpa.url=jdbc:h2:mem:syncopedb;DB_CLOSE_DELAY=-1
-jpa.username=sa
-jpa.password=
-jpa.dialect=org.apache.openjpa.jdbc.sql.H2Dictionary
-jpa.pool.validationQuery=SELECT 1
-jpa.orm=META-INF/spring-orm.xml
-# note: other connection pool settings can also be configured here, see persistenceContext.xml
-quartz.jobstore=org.quartz.impl.jdbcjobstore.StdJDBCDelegate
-quartz.scheduler.idleWaitTime=5000
-quartz.sql=tables_h2.sql
-audit.sql=audit.sql
-database.schema=
-

http://git-wip-us.apache.org/repos/asf/syncope/blob/6dfedd8f/core/persistence-jpa/src/test/resources/persistenceTest.xml
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/test/resources/persistenceTest.xml b/core/persistence-jpa/src/test/resources/persistenceTest.xml
index a87172b..da8f321 100644
--- a/core/persistence-jpa/src/test/resources/persistenceTest.xml
+++ b/core/persistence-jpa/src/test/resources/persistenceTest.xml
@@ -29,6 +29,7 @@ under the License.
     <property name="locations">
       <list>
         <value>classpath:persistence.properties</value>
+        <value>classpath:domains/*.properties</value>
         <value>classpath:security.properties</value>
       </list>
     </property>

http://git-wip-us.apache.org/repos/asf/syncope/blob/6dfedd8f/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/AnyObjectProvisioningManager.java
----------------------------------------------------------------------
diff --git a/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/AnyObjectProvisioningManager.java b/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/AnyObjectProvisioningManager.java
index 6928ffd..5645979 100644
--- a/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/AnyObjectProvisioningManager.java
+++ b/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/AnyObjectProvisioningManager.java
@@ -18,8 +18,13 @@
  */
 package org.apache.syncope.core.provisioning.api;
 
+import java.util.Collection;
+import java.util.List;
 import org.apache.syncope.common.lib.mod.AnyObjectMod;
 import org.apache.syncope.common.lib.to.AnyObjectTO;
+import org.apache.syncope.common.lib.to.PropagationStatus;
 
 public interface AnyObjectProvisioningManager extends ProvisioningManager<AnyObjectTO, AnyObjectMod> {
+
+    List<PropagationStatus> provision(Long key, Collection<String> resources);
 }

http://git-wip-us.apache.org/repos/asf/syncope/blob/6dfedd8f/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/GroupProvisioningManager.java
----------------------------------------------------------------------
diff --git a/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/GroupProvisioningManager.java b/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/GroupProvisioningManager.java
index 1dce013..c74b5df 100644
--- a/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/GroupProvisioningManager.java
+++ b/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/GroupProvisioningManager.java
@@ -18,6 +18,7 @@
  */
 package org.apache.syncope.core.provisioning.api;
 
+import java.util.Collection;
 import java.util.List;
 import java.util.Map;
 import java.util.Set;
@@ -31,4 +32,6 @@ public interface GroupProvisioningManager extends ProvisioningManager<GroupTO, G
     Pair<Long, List<PropagationStatus>> create(
             GroupTO groupTO, Map<Long, String> groupOwnerMap, Set<String> excludedResources);
 
+    List<PropagationStatus> provision(Long key, Collection<String> resources);
+
 }

http://git-wip-us.apache.org/repos/asf/syncope/blob/6dfedd8f/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/UserProvisioningManager.java
----------------------------------------------------------------------
diff --git a/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/UserProvisioningManager.java b/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/UserProvisioningManager.java
index 810a788..3378707 100644
--- a/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/UserProvisioningManager.java
+++ b/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/UserProvisioningManager.java
@@ -18,6 +18,7 @@
  */
 package org.apache.syncope.core.provisioning.api;
 
+import java.util.Collection;
 import java.util.List;
 import java.util.Set;
 import org.apache.commons.lang3.tuple.Pair;
@@ -30,11 +31,11 @@ import org.apache.syncope.core.provisioning.api.sync.ProvisioningResult;
 
 public interface UserProvisioningManager extends ProvisioningManager<UserTO, UserMod> {
 
-    Pair<Long, List<PropagationStatus>> activate(User user, StatusMod statusMod);
+    Pair<Long, List<PropagationStatus>> activate(StatusMod statusMod);
 
-    Pair<Long, List<PropagationStatus>> reactivate(User user, StatusMod statusMod);
+    Pair<Long, List<PropagationStatus>> reactivate(StatusMod statusMod);
 
-    Pair<Long, List<PropagationStatus>> suspend(User user, StatusMod statusMod);
+    Pair<Long, List<PropagationStatus>> suspend(StatusMod statusMod);
 
     void innerSuspend(User user, boolean propagate);
 
@@ -48,6 +49,8 @@ public interface UserProvisioningManager extends ProvisioningManager<UserTO, Use
 
     void requestPasswordReset(Long key);
 
-    void confirmPasswordReset(User user, String token, String password);
+    void confirmPasswordReset(Long key, String token, String password);
+
+    List<PropagationStatus> provision(Long key, boolean changePwd, String password, Collection<String> resources);
 
 }

http://git-wip-us.apache.org/repos/asf/syncope/blob/6dfedd8f/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/job/JobInstanceLoader.java
----------------------------------------------------------------------
diff --git a/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/job/JobInstanceLoader.java b/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/job/JobInstanceLoader.java
index 7434976..14f0c83 100644
--- a/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/job/JobInstanceLoader.java
+++ b/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/job/JobInstanceLoader.java
@@ -19,20 +19,20 @@
 package org.apache.syncope.core.provisioning.api.job;
 
 import java.text.ParseException;
+import java.util.Map;
 import org.apache.syncope.core.persistence.api.entity.Report;
+import org.apache.syncope.core.persistence.api.entity.task.SchedTask;
 import org.apache.syncope.core.persistence.api.entity.task.Task;
 import org.quartz.SchedulerException;
 
 public interface JobInstanceLoader {
 
-    void registerJob(Task task, String jobClassName, String cronExpression)
-            throws ClassNotFoundException, SchedulerException, ParseException;
+    String DOMAIN = "domain";
 
-    void registerJob(Report report) throws SchedulerException, ParseException;
+    Map<String, Object> registerJob(final SchedTask task, final long interruptMaxRetries)
+            throws SchedulerException, ParseException;
 
-    void registerReportJob(Long reportKey) throws SchedulerException, ParseException;
-
-    void registerTaskJob(Long taskKey) throws ClassNotFoundException, SchedulerException, ParseException;
+    void registerJob(final Report report) throws SchedulerException, ParseException;
 
     void unregisterJob(Task task);
 

http://git-wip-us.apache.org/repos/asf/syncope/blob/6dfedd8f/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/job/JobNamer.java
----------------------------------------------------------------------
diff --git a/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/job/JobNamer.java b/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/job/JobNamer.java
index 9ddf563..22d7b54 100644
--- a/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/job/JobNamer.java
+++ b/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/job/JobNamer.java
@@ -29,7 +29,7 @@ public final class JobNamer {
 
     private static final Logger LOG = LoggerFactory.getLogger(JobNamer.class);
 
-    private static Long getIdFromJobName(final String name, final String pattern, final int prefixLength) {
+    private static Long getKeyFromJobName(final String name, final String pattern, final int prefixLength) {
         Long result = null;
 
         Matcher jobMatcher = Pattern.compile(pattern).matcher(name);
@@ -45,17 +45,15 @@ public final class JobNamer {
     }
 
     public static Long getTaskKeyFromJobName(final String name) {
-        return getIdFromJobName(name, "taskJob[0-9]+", 7);
+        return getKeyFromJobName(name, "taskJob[0-9]+", 7);
     }
 
     public static Long getReportKeyFromJobName(final String name) {
-        return getIdFromJobName(name, "reportJob[0-9]+", 9);
+        return getKeyFromJobName(name, "reportJob[0-9]+", 9);
     }
 
     public static String getJobName(final Task task) {
-        return task == null
-                ? "taskNotificationJob"
-                : "taskJob" + task.getKey();
+        return "taskJob" + task.getKey();
     }
 
     public static String getJobName(final Report report) {

http://git-wip-us.apache.org/repos/asf/syncope/blob/6dfedd8f/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/job/ProvisioningJob.java
----------------------------------------------------------------------
diff --git a/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/job/ProvisioningJob.java b/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/job/ProvisioningJob.java
deleted file mode 100644
index 9a6386f..0000000
--- a/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/job/ProvisioningJob.java
+++ /dev/null
@@ -1,28 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.syncope.core.provisioning.api.job;
-
-import java.util.List;
-import org.apache.syncope.core.persistence.api.entity.task.ProvisioningTask;
-import org.apache.syncope.core.provisioning.api.sync.ProvisioningActions;
-
-public interface ProvisioningJob<T extends ProvisioningTask, A extends ProvisioningActions> extends TaskJob {
-
-    void setActions(List<A> actions);
-}

http://git-wip-us.apache.org/repos/asf/syncope/blob/6dfedd8f/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/job/PushJob.java
----------------------------------------------------------------------
diff --git a/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/job/PushJob.java b/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/job/PushJob.java
deleted file mode 100644
index 388d780..0000000
--- a/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/job/PushJob.java
+++ /dev/null
@@ -1,26 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.syncope.core.provisioning.api.job;
-
-import org.apache.syncope.core.persistence.api.entity.task.PushTask;
-import org.apache.syncope.core.provisioning.api.sync.PushActions;
-
-public interface PushJob extends ProvisioningJob<PushTask, PushActions> {
-
-}

http://git-wip-us.apache.org/repos/asf/syncope/blob/6dfedd8f/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/job/SchedTaskJobDelegate.java
----------------------------------------------------------------------
diff --git a/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/job/SchedTaskJobDelegate.java b/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/job/SchedTaskJobDelegate.java
new file mode 100644
index 0000000..74e9247
--- /dev/null
+++ b/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/job/SchedTaskJobDelegate.java
@@ -0,0 +1,26 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.syncope.core.provisioning.api.job;
+
+import org.quartz.JobExecutionException;
+
+public interface SchedTaskJobDelegate {
+
+    void execute(Long taskKey, boolean dryRun) throws JobExecutionException;
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/6dfedd8f/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/job/SyncJob.java
----------------------------------------------------------------------
diff --git a/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/job/SyncJob.java b/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/job/SyncJob.java
deleted file mode 100644
index 147daa5..0000000
--- a/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/job/SyncJob.java
+++ /dev/null
@@ -1,26 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.syncope.core.provisioning.api.job;
-
-import org.apache.syncope.core.persistence.api.entity.task.SyncTask;
-import org.apache.syncope.core.provisioning.api.sync.SyncActions;
-
-public interface SyncJob extends ProvisioningJob<SyncTask, SyncActions> {
-
-}

http://git-wip-us.apache.org/repos/asf/syncope/blob/6dfedd8f/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/job/TaskJob.java
----------------------------------------------------------------------
diff --git a/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/job/TaskJob.java b/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/job/TaskJob.java
deleted file mode 100644
index 3df89bc..0000000
--- a/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/job/TaskJob.java
+++ /dev/null
@@ -1,43 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.syncope.core.provisioning.api.job;
-
-import org.quartz.DisallowConcurrentExecution;
-import org.quartz.InterruptableJob;
-
-/**
- * Interface for Quartz jobs bound to a given Task.
- */
-@DisallowConcurrentExecution
-public interface TaskJob extends InterruptableJob {
-
-    String DRY_RUN_JOBDETAIL_KEY = "dryRun";
-
-    /**
-     * Task execution status.
-     */
-    public enum Status {
-
-        SUCCESS,
-        FAILURE
-
-    }
-
-    void setTaskId(Long taskId);
-}

http://git-wip-us.apache.org/repos/asf/syncope/blob/6dfedd8f/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/propagation/PropagationManager.java
----------------------------------------------------------------------
diff --git a/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/propagation/PropagationManager.java b/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/propagation/PropagationManager.java
index cf8cde4..3155223 100644
--- a/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/propagation/PropagationManager.java
+++ b/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/propagation/PropagationManager.java
@@ -27,7 +27,6 @@ import org.apache.syncope.common.lib.mod.UserMod;
 import org.apache.syncope.common.lib.to.AttrTO;
 import org.apache.syncope.common.lib.types.PropagationByResource;
 import org.apache.syncope.core.persistence.api.entity.Any;
-import org.apache.syncope.core.persistence.api.entity.user.User;
 import org.apache.syncope.core.persistence.api.entity.task.PropagationTask;
 import org.apache.syncope.core.provisioning.api.WorkflowResult;
 
@@ -149,12 +148,12 @@ public interface PropagationManager {
     /**
      * Performs update on each resource associated to the user excluding the specified into 'resourceNames' parameter.
      *
-     * @param user to be propagated
+     * @param key to be propagated
      * @param enable whether user must be enabled or not
      * @param noPropResourceNames external resource names not to be considered for propagation
      * @return list of propagation tasks
      */
-    List<PropagationTask> getUserUpdateTasks(User user, Boolean enable, Collection<String> noPropResourceNames);
+    List<PropagationTask> getUserUpdateTasks(Long key, Boolean enable, Collection<String> noPropResourceNames);
 
     /**
      * Performs update on each resource associated to the user.

http://git-wip-us.apache.org/repos/asf/syncope/blob/6dfedd8f/core/provisioning-java/pom.xml
----------------------------------------------------------------------
diff --git a/core/provisioning-java/pom.xml b/core/provisioning-java/pom.xml
index a1dc161..85ea59f 100644
--- a/core/provisioning-java/pom.xml
+++ b/core/provisioning-java/pom.xml
@@ -150,6 +150,13 @@ under the License.
         <filtering>true</filtering>
       </testResource>
       <testResource>
+        <directory>${basedir}/../persistence-jpa/src/main/resources</directory>
+        <includes>
+          <include>persistence.properties</include>
+        </includes>
+        <filtering>true</filtering>
+      </testResource>
+      <testResource>
         <directory>${basedir}/../persistence-jpa/src/test/resources</directory>
         <filtering>true</filtering>
       </testResource>

http://git-wip-us.apache.org/repos/asf/syncope/blob/6dfedd8f/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/ConnectorFacadeProxy.java
----------------------------------------------------------------------
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/ConnectorFacadeProxy.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/ConnectorFacadeProxy.java
index e23143a..bcea03d 100644
--- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/ConnectorFacadeProxy.java
+++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/ConnectorFacadeProxy.java
@@ -95,7 +95,7 @@ public class ConnectorFacadeProxy implements Connector {
         this.activeConnInstance = connInstance;
 
         ConnIdBundleManager connIdBundleManager =
-                ApplicationContextProvider.getApplicationContext().getBean(ConnIdBundleManager.class);
+                ApplicationContextProvider.getBeanFactory().getBean(ConnIdBundleManager.class);
         ConnectorInfo info = connIdBundleManager.getConnectorInfo(connInstance);
 
         // create default configuration

http://git-wip-us.apache.org/repos/asf/syncope/blob/6dfedd8f/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/ConnectorManager.java
----------------------------------------------------------------------
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/ConnectorManager.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/ConnectorManager.java
index 7d0cf2f..38b3f2a 100644
--- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/ConnectorManager.java
+++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/ConnectorManager.java
@@ -25,13 +25,13 @@ import java.util.Map;
 import java.util.Set;
 import org.apache.commons.lang3.SerializationUtils;
 import org.apache.syncope.common.lib.types.ConnConfProperty;
+import org.apache.syncope.core.misc.spring.ApplicationContextProvider;
 import org.apache.syncope.core.persistence.api.dao.ExternalResourceDAO;
 import org.apache.syncope.core.persistence.api.entity.ConnInstance;
 import org.apache.syncope.core.provisioning.api.ConnIdBundleManager;
 import org.apache.syncope.core.provisioning.api.Connector;
 import org.apache.syncope.core.provisioning.api.ConnectorFactory;
 import org.apache.syncope.core.provisioning.api.ConnectorRegistry;
-import org.apache.syncope.core.misc.spring.ApplicationContextProvider;
 import org.apache.syncope.core.persistence.api.entity.resource.ExternalResource;
 import org.identityconnectors.common.l10n.CurrentLocale;
 import org.identityconnectors.framework.api.ConnectorFacadeFactory;

http://git-wip-us.apache.org/repos/asf/syncope/blob/6dfedd8f/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/DefaultAnyObjectProvisioningManager.java
----------------------------------------------------------------------
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/DefaultAnyObjectProvisioningManager.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/DefaultAnyObjectProvisioningManager.java
index fd6bcf1..9722adb 100644
--- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/DefaultAnyObjectProvisioningManager.java
+++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/DefaultAnyObjectProvisioningManager.java
@@ -32,6 +32,7 @@ import org.apache.syncope.common.lib.to.PropagationStatus;
 import org.apache.syncope.common.lib.to.AnyObjectTO;
 import org.apache.syncope.common.lib.types.AnyTypeKind;
 import org.apache.syncope.common.lib.types.PropagationByResource;
+import org.apache.syncope.common.lib.types.ResourceOperation;
 import org.apache.syncope.core.persistence.api.dao.AnyObjectDAO;
 import org.apache.syncope.core.persistence.api.entity.task.PropagationTask;
 import org.apache.syncope.core.provisioning.api.AnyObjectProvisioningManager;
@@ -81,7 +82,7 @@ public class DefaultAnyObjectProvisioningManager implements AnyObjectProvisionin
         List<PropagationTask> tasks = propagationManager.getAnyObjectCreateTasks(
                 created, anyObjectTO.getVirAttrs(), excludedResources);
         PropagationReporter propagationReporter =
-                ApplicationContextProvider.getApplicationContext().getBean(PropagationReporter.class);
+                ApplicationContextProvider.getBeanFactory().getBean(PropagationReporter.class);
         try {
             taskExecutor.execute(tasks, propagationReporter);
         } catch (PropagationException e) {
@@ -118,7 +119,7 @@ public class DefaultAnyObjectProvisioningManager implements AnyObjectProvisionin
         }
 
         PropagationReporter propagationReporter =
-                ApplicationContextProvider.getApplicationContext().getBean(PropagationReporter.class);
+                ApplicationContextProvider.getBeanFactory().getBean(PropagationReporter.class);
         try {
             taskExecutor.execute(tasks, propagationReporter);
         } catch (PropagationException e) {
@@ -130,20 +131,20 @@ public class DefaultAnyObjectProvisioningManager implements AnyObjectProvisionin
     }
 
     @Override
-    public List<PropagationStatus> delete(final Long anyObjectKey) {
-        return delete(anyObjectKey, Collections.<String>emptySet());
+    public List<PropagationStatus> delete(final Long key) {
+        return delete(key, Collections.<String>emptySet());
     }
 
     @Override
-    public List<PropagationStatus> delete(final Long anyObjectKey, final Set<String> excludedResources) {
+    public List<PropagationStatus> delete(final Long key, final Set<String> excludedResources) {
         List<PropagationTask> tasks = new ArrayList<>();
 
-        AnyObject anyObject = anyObjectDAO.authFind(anyObjectKey);
+        AnyObject anyObject = anyObjectDAO.authFind(key);
         if (anyObject != null) {
             tasks.addAll(propagationManager.getAnyObjectDeleteTasks(anyObject.getKey()));
         }
 
-        PropagationReporter propagationReporter = ApplicationContextProvider.getApplicationContext().
+        PropagationReporter propagationReporter = ApplicationContextProvider.getBeanFactory().
                 getBean(PropagationReporter.class);
         try {
             taskExecutor.execute(tasks, propagationReporter);
@@ -152,7 +153,7 @@ public class DefaultAnyObjectProvisioningManager implements AnyObjectProvisionin
             propagationReporter.onPrimaryResourceFailure(tasks);
         }
 
-        awfAdapter.delete(anyObjectKey);
+        awfAdapter.delete(key);
 
         return propagationReporter.getStatuses();
     }
@@ -168,15 +169,36 @@ public class DefaultAnyObjectProvisioningManager implements AnyObjectProvisionin
     }
 
     @Override
-    public List<PropagationStatus> deprovision(final Long anyObjectKey, final Collection<String> resources) {
-        AnyObject anyObject = anyObjectDAO.authFind(anyObjectKey);
+    public List<PropagationStatus> provision(final Long key, final Collection<String> resources) {
+        PropagationByResource propByRes = new PropagationByResource();
+        for (String resource : resources) {
+            propByRes.add(ResourceOperation.UPDATE, resource);
+        }
+
+        WorkflowResult<Long> wfResult = new WorkflowResult<>(key, propByRes, "update");
+
+        List<PropagationTask> tasks = propagationManager.getAnyObjectUpdateTasks(wfResult, null, null, null);
+        PropagationReporter propagationReporter =
+                ApplicationContextProvider.getBeanFactory().getBean(PropagationReporter.class);
+        try {
+            taskExecutor.execute(tasks, propagationReporter);
+        } catch (PropagationException e) {
+            LOG.error("Error propagation primary resource", e);
+            propagationReporter.onPrimaryResourceFailure(tasks);
+        }
+        return propagationReporter.getStatuses();
+    }
+
+    @Override
+    public List<PropagationStatus> deprovision(final Long key, final Collection<String> resources) {
+        AnyObject anyObject = anyObjectDAO.authFind(key);
 
         Collection<String> noPropResourceName = CollectionUtils.removeAll(anyObject.getResourceNames(), resources);
 
         List<PropagationTask> tasks = propagationManager.getAnyObjectDeleteTasks(
-                anyObjectKey, new HashSet<>(resources), noPropResourceName);
+                key, new HashSet<>(resources), noPropResourceName);
         PropagationReporter propagationReporter =
-                ApplicationContextProvider.getApplicationContext().getBean(PropagationReporter.class);
+                ApplicationContextProvider.getBeanFactory().getBean(PropagationReporter.class);
         try {
             taskExecutor.execute(tasks, propagationReporter);
         } catch (PropagationException e) {

http://git-wip-us.apache.org/repos/asf/syncope/blob/6dfedd8f/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/DefaultGroupProvisioningManager.java
----------------------------------------------------------------------
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/DefaultGroupProvisioningManager.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/DefaultGroupProvisioningManager.java
index 5661df4..457f74d 100644
--- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/DefaultGroupProvisioningManager.java
+++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/DefaultGroupProvisioningManager.java
@@ -38,6 +38,7 @@ import org.apache.syncope.common.lib.to.PropagationStatus;
 import org.apache.syncope.common.lib.to.GroupTO;
 import org.apache.syncope.common.lib.types.AnyTypeKind;
 import org.apache.syncope.common.lib.types.PropagationByResource;
+import org.apache.syncope.common.lib.types.ResourceOperation;
 import org.apache.syncope.core.persistence.api.dao.GroupDAO;
 import org.apache.syncope.core.persistence.api.entity.group.Group;
 import org.apache.syncope.core.persistence.api.entity.task.PropagationTask;
@@ -81,8 +82,8 @@ public class DefaultGroupProvisioningManager implements GroupProvisioningManager
 
         List<PropagationTask> tasks = propagationManager.getGroupCreateTasks(
                 created, groupTO.getVirAttrs(), excludedResources);
-        PropagationReporter propagationReporter = ApplicationContextProvider.getApplicationContext().getBean(
-                PropagationReporter.class);
+        PropagationReporter propagationReporter =
+                ApplicationContextProvider.getBeanFactory().getBean(PropagationReporter.class);
         try {
             taskExecutor.execute(tasks, propagationReporter);
         } catch (PropagationException e) {
@@ -98,6 +99,8 @@ public class DefaultGroupProvisioningManager implements GroupProvisioningManager
             final GroupTO groupTO, final Map<Long, String> groupOwnerMap, final Set<String> excludedResources) {
 
         WorkflowResult<Long> created = gwfAdapter.create(groupTO);
+
+        // see ConnObjectUtils#getAnyTOFromConnObject for GroupOwnerSchema
         AttrTO groupOwner = groupTO.getPlainAttrMap().get(StringUtils.EMPTY);
         if (groupOwner != null) {
             groupOwnerMap.put(created.getResult(), groupOwner.getValues().iterator().next());
@@ -105,15 +108,21 @@ public class DefaultGroupProvisioningManager implements GroupProvisioningManager
 
         List<PropagationTask> tasks = propagationManager.getGroupCreateTasks(
                 created, groupTO.getVirAttrs(), excludedResources);
-
-        taskExecutor.execute(tasks);
+        PropagationReporter propagationReporter =
+                ApplicationContextProvider.getBeanFactory().getBean(PropagationReporter.class);
+        try {
+            taskExecutor.execute(tasks, propagationReporter);
+        } catch (PropagationException e) {
+            LOG.error("Error propagation primary resource", e);
+            propagationReporter.onPrimaryResourceFailure(tasks);
+        }
 
         return new ImmutablePair<>(created.getResult(), null);
     }
 
     @Override
-    public Pair<Long, List<PropagationStatus>> update(final GroupMod groupObjectMod) {
-        return update(groupObjectMod, Collections.<String>emptySet());
+    public Pair<Long, List<PropagationStatus>> update(final GroupMod groupMod) {
+        return update(groupMod, Collections.<String>emptySet());
     }
 
     @Override
@@ -137,7 +146,7 @@ public class DefaultGroupProvisioningManager implements GroupProvisioningManager
         }
 
         PropagationReporter propagationReporter =
-                ApplicationContextProvider.getApplicationContext().getBean(PropagationReporter.class);
+                ApplicationContextProvider.getBeanFactory().getBean(PropagationReporter.class);
         try {
             taskExecutor.execute(tasks, propagationReporter);
         } catch (PropagationException e) {
@@ -149,15 +158,15 @@ public class DefaultGroupProvisioningManager implements GroupProvisioningManager
     }
 
     @Override
-    public List<PropagationStatus> delete(final Long groupObjectKey) {
-        return delete(groupObjectKey, Collections.<String>emptySet());
+    public List<PropagationStatus> delete(final Long key) {
+        return delete(key, Collections.<String>emptySet());
     }
 
     @Override
-    public List<PropagationStatus> delete(final Long groupKey, final Set<String> excludedResources) {
+    public List<PropagationStatus> delete(final Long key, final Set<String> excludedResources) {
         List<PropagationTask> tasks = new ArrayList<>();
 
-        Group group = groupDAO.authFind(groupKey);
+        Group group = groupDAO.authFind(key);
         if (group != null) {
             // Generate propagation tasks for deleting users from group resources, if they are on those resources only
             // because of the reason being deleted (see SYNCOPE-357)
@@ -180,7 +189,7 @@ public class DefaultGroupProvisioningManager implements GroupProvisioningManager
             tasks.addAll(propagationManager.getGroupDeleteTasks(group.getKey()));
         }
 
-        PropagationReporter propagationReporter = ApplicationContextProvider.getApplicationContext().
+        PropagationReporter propagationReporter = ApplicationContextProvider.getBeanFactory().
                 getBean(PropagationReporter.class);
         try {
             taskExecutor.execute(tasks, propagationReporter);
@@ -189,7 +198,7 @@ public class DefaultGroupProvisioningManager implements GroupProvisioningManager
             propagationReporter.onPrimaryResourceFailure(tasks);
         }
 
-        gwfAdapter.delete(groupKey);
+        gwfAdapter.delete(key);
 
         return propagationReporter.getStatuses();
     }
@@ -201,15 +210,34 @@ public class DefaultGroupProvisioningManager implements GroupProvisioningManager
     }
 
     @Override
-    public List<PropagationStatus> deprovision(final Long groupKey, final Collection<String> resources) {
-        Group group = groupDAO.authFind(groupKey);
+    public List<PropagationStatus> provision(final Long key, final Collection<String> resources) {
+        PropagationByResource propByRes = new PropagationByResource();
+        propByRes.addAll(ResourceOperation.UPDATE, resources);
+
+        WorkflowResult<Long> wfResult = new WorkflowResult<>(key, propByRes, "update");
+
+        List<PropagationTask> tasks = propagationManager.getGroupUpdateTasks(wfResult, null, null, null);
+        PropagationReporter propagationReporter =
+                ApplicationContextProvider.getBeanFactory().getBean(PropagationReporter.class);
+        try {
+            taskExecutor.execute(tasks, propagationReporter);
+        } catch (PropagationException e) {
+            LOG.error("Error propagation primary resource", e);
+            propagationReporter.onPrimaryResourceFailure(tasks);
+        }
+        return propagationReporter.getStatuses();
+    }
+
+    @Override
+    public List<PropagationStatus> deprovision(final Long key, final Collection<String> resources) {
+        Group group = groupDAO.authFind(key);
 
         Collection<String> noPropResourceName = CollectionUtils.removeAll(group.getResourceNames(), resources);
 
         List<PropagationTask> tasks = propagationManager.getGroupDeleteTasks(
-                groupKey, new HashSet<>(resources), noPropResourceName);
+                key, new HashSet<>(resources), noPropResourceName);
         PropagationReporter propagationReporter =
-                ApplicationContextProvider.getApplicationContext().getBean(PropagationReporter.class);
+                ApplicationContextProvider.getBeanFactory().getBean(PropagationReporter.class);
         try {
             taskExecutor.execute(tasks, propagationReporter);
         } catch (PropagationException e) {

http://git-wip-us.apache.org/repos/asf/syncope/blob/6dfedd8f/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/DefaultUserProvisioningManager.java
----------------------------------------------------------------------
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/DefaultUserProvisioningManager.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/DefaultUserProvisioningManager.java
index 656bc75..0809607 100644
--- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/DefaultUserProvisioningManager.java
+++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/DefaultUserProvisioningManager.java
@@ -37,6 +37,7 @@ import org.apache.syncope.core.persistence.api.entity.user.User;
 import org.apache.syncope.core.provisioning.api.UserProvisioningManager;
 import org.apache.syncope.core.provisioning.api.WorkflowResult;
 import org.apache.syncope.common.lib.types.PropagationByResource;
+import org.apache.syncope.common.lib.types.ResourceOperation;
 import org.apache.syncope.core.provisioning.api.propagation.PropagationException;
 import org.apache.syncope.core.provisioning.api.propagation.PropagationManager;
 import org.apache.syncope.core.provisioning.api.propagation.PropagationReporter;
@@ -87,12 +88,8 @@ public class DefaultUserProvisioningManager implements UserProvisioningManager {
     public Pair<Long, List<PropagationStatus>> create(final UserTO userTO, final boolean storePassword,
             final boolean disablePwdPolicyCheck, final Boolean enabled, final Set<String> excludedResources) {
 
-        WorkflowResult<Pair<Long, Boolean>> created;
-        try {
-            created = uwfAdapter.create(userTO, disablePwdPolicyCheck, enabled, storePassword);
-        } catch (PropagationException e) {
-            throw e;
-        }
+        WorkflowResult<Pair<Long, Boolean>> created =
+                uwfAdapter.create(userTO, disablePwdPolicyCheck, enabled, storePassword);
 
         List<PropagationTask> tasks = propagationManager.getUserCreateTasks(
                 created.getResult().getKey(),
@@ -102,7 +99,7 @@ public class DefaultUserProvisioningManager implements UserProvisioningManager {
                 userTO.getVirAttrs(),
                 excludedResources);
         PropagationReporter propagationReporter =
-                ApplicationContextProvider.getApplicationContext().getBean(PropagationReporter.class);
+                ApplicationContextProvider.getBeanFactory().getBean(PropagationReporter.class);
         try {
             taskExecutor.execute(tasks, propagationReporter);
         } catch (PropagationException e) {
@@ -129,7 +126,7 @@ public class DefaultUserProvisioningManager implements UserProvisioningManager {
                     ? propagationManager.getUserUpdateTasks(updated, false, null)
                     : Collections.<PropagationTask>emptyList());
         }
-        PropagationReporter propagationReporter = ApplicationContextProvider.getApplicationContext().
+        PropagationReporter propagationReporter = ApplicationContextProvider.getBeanFactory().
                 getBean(PropagationReporter.class);
         if (!tasks.isEmpty()) {
             try {
@@ -140,9 +137,7 @@ public class DefaultUserProvisioningManager implements UserProvisioningManager {
             }
         }
 
-        Pair<Long, List<PropagationStatus>> result = new ImmutablePair<>(
-                updated.getResult().getKey().getKey(), propagationReporter.getStatuses());
-        return result;
+        return new ImmutablePair<>(updated.getResult().getKey().getKey(), propagationReporter.getStatuses());
     }
 
     @Override
@@ -191,7 +186,7 @@ public class DefaultUserProvisioningManager implements UserProvisioningManager {
 
         List<PropagationTask> tasks = propagationManager.getUserUpdateTasks(
                 updated, updated.getResult().getKey().getPassword() != null, excludedResources);
-        PropagationReporter propagationReporter = ApplicationContextProvider.getApplicationContext().
+        PropagationReporter propagationReporter = ApplicationContextProvider.getBeanFactory().
                 getBean(PropagationReporter.class);
         try {
             taskExecutor.execute(tasks, propagationReporter);
@@ -204,21 +199,21 @@ public class DefaultUserProvisioningManager implements UserProvisioningManager {
     }
 
     @Override
-    public List<PropagationStatus> delete(final Long userKey) {
-        return delete(userKey, Collections.<String>emptySet());
+    public List<PropagationStatus> delete(final Long key) {
+        return delete(key, Collections.<String>emptySet());
     }
 
     @Override
-    public List<PropagationStatus> delete(final Long anyId, final Set<String> excludedResources) {
+    public List<PropagationStatus> delete(final Long key, final Set<String> excludedResources) {
         // Note here that we can only notify about "delete", not any other
         // task defined in workflow process definition: this because this
         // information could only be available after uwfAdapter.delete(), which
         // will also effectively remove user from db, thus making virtually
         // impossible by NotificationManager to fetch required user information
-        List<PropagationTask> tasks = propagationManager.getUserDeleteTasks(anyId, excludedResources);
+        List<PropagationTask> tasks = propagationManager.getUserDeleteTasks(key, excludedResources);
 
         PropagationReporter propagationReporter =
-                ApplicationContextProvider.getApplicationContext().getBean(PropagationReporter.class);
+                ApplicationContextProvider.getBeanFactory().getBean(PropagationReporter.class);
         try {
             taskExecutor.execute(tasks, propagationReporter);
         } catch (PropagationException e) {
@@ -227,7 +222,7 @@ public class DefaultUserProvisioningManager implements UserProvisioningManager {
         }
 
         try {
-            uwfAdapter.delete(anyId);
+            uwfAdapter.delete(key);
         } catch (PropagationException e) {
             throw e;
         }
@@ -247,40 +242,40 @@ public class DefaultUserProvisioningManager implements UserProvisioningManager {
     }
 
     @Override
-    public Pair<Long, List<PropagationStatus>> activate(final User user, final StatusMod statusMod) {
+    public Pair<Long, List<PropagationStatus>> activate(final StatusMod statusMod) {
         WorkflowResult<Long> updated = statusMod.isOnSyncope()
-                ? uwfAdapter.activate(user.getKey(), statusMod.getToken())
-                : new WorkflowResult<>(user.getKey(), null, statusMod.getType().name().toLowerCase());
+                ? uwfAdapter.activate(statusMod.getKey(), statusMod.getToken())
+                : new WorkflowResult<>(statusMod.getKey(), null, statusMod.getType().name().toLowerCase());
 
-        return new ImmutablePair<>(updated.getResult(), propagateStatus(user, statusMod));
+        return new ImmutablePair<>(updated.getResult(), propagateStatus(statusMod));
     }
 
     @Override
-    public Pair<Long, List<PropagationStatus>> reactivate(final User user, final StatusMod statusMod) {
+    public Pair<Long, List<PropagationStatus>> reactivate(final StatusMod statusMod) {
         WorkflowResult<Long> updated = statusMod.isOnSyncope()
-                ? uwfAdapter.reactivate(user.getKey())
-                : new WorkflowResult<>(user.getKey(), null, statusMod.getType().name().toLowerCase());
+                ? uwfAdapter.reactivate(statusMod.getKey())
+                : new WorkflowResult<>(statusMod.getKey(), null, statusMod.getType().name().toLowerCase());
 
-        return new ImmutablePair<>(updated.getResult(), propagateStatus(user, statusMod));
+        return new ImmutablePair<>(updated.getResult(), propagateStatus(statusMod));
     }
 
     @Override
-    public Pair<Long, List<PropagationStatus>> suspend(final User user, final StatusMod statusMod) {
+    public Pair<Long, List<PropagationStatus>> suspend(final StatusMod statusMod) {
         WorkflowResult<Long> updated = statusMod.isOnSyncope()
-                ? uwfAdapter.suspend(user.getKey())
-                : new WorkflowResult<>(user.getKey(), null, statusMod.getType().name().toLowerCase());
+                ? uwfAdapter.suspend(statusMod.getKey())
+                : new WorkflowResult<>(statusMod.getKey(), null, statusMod.getType().name().toLowerCase());
 
-        return new ImmutablePair<>(updated.getResult(), propagateStatus(user, statusMod));
+        return new ImmutablePair<>(updated.getResult(), propagateStatus(statusMod));
     }
 
-    protected List<PropagationStatus> propagateStatus(final User user, final StatusMod statusMod) {
-        Collection<String> noPropResourceNames =
-                CollectionUtils.removeAll(userDAO.findAllResourceNames(user), statusMod.getResourceNames());
+    protected List<PropagationStatus> propagateStatus(final StatusMod statusMod) {
+        Collection<String> noPropResourceNames = CollectionUtils.removeAll(
+                userDAO.findAllResourceNames(userDAO.find(statusMod.getKey())), statusMod.getResourceNames());
 
         List<PropagationTask> tasks = propagationManager.getUserUpdateTasks(
-                user, statusMod.getType() != StatusMod.ModType.SUSPEND, noPropResourceNames);
+                statusMod.getKey(), statusMod.getType() != StatusMod.ModType.SUSPEND, noPropResourceNames);
         PropagationReporter propReporter =
-                ApplicationContextProvider.getApplicationContext().getBean(PropagationReporter.class);
+                ApplicationContextProvider.getBeanFactory().getBean(PropagationReporter.class);
         try {
             taskExecutor.execute(tasks, propReporter);
         } catch (PropagationException e) {
@@ -311,15 +306,50 @@ public class DefaultUserProvisioningManager implements UserProvisioningManager {
     }
 
     @Override
-    public List<PropagationStatus> deprovision(final Long userKey, final Collection<String> resources) {
-        final User user = userDAO.authFind(userKey);
+    public List<PropagationStatus> provision(
+            final Long key, final boolean changePwd, final String password, final Collection<String> resources) {
+
+        UserMod userMod = new UserMod();
+        userMod.setKey(key);
+        userMod.getResourcesToAdd().addAll(resources);
+
+        if (changePwd) {
+            StatusMod statusMod = new StatusMod();
+            statusMod.setOnSyncope(false);
+            statusMod.getResourceNames().addAll(resources);
+            userMod.setPwdPropRequest(statusMod);
+            userMod.setPassword(password);
+        }
+
+        PropagationByResource propByRes = new PropagationByResource();
+        propByRes.addAll(ResourceOperation.UPDATE, resources);
+
+        WorkflowResult<Pair<UserMod, Boolean>> wfResult = new WorkflowResult<Pair<UserMod, Boolean>>(
+                ImmutablePair.of(userMod, (Boolean) null), propByRes, "update");
+
+        List<PropagationTask> tasks = propagationManager.getUserUpdateTasks(wfResult, changePwd, null);
+        PropagationReporter propagationReporter =
+                ApplicationContextProvider.getBeanFactory().getBean(PropagationReporter.class);
+        try {
+            taskExecutor.execute(tasks, propagationReporter);
+        } catch (PropagationException e) {
+            LOG.error("Error propagation primary resource", e);
+            propagationReporter.onPrimaryResourceFailure(tasks);
+        }
+
+        return propagationReporter.getStatuses();
+    }
+
+    @Override
+    public List<PropagationStatus> deprovision(final Long key, final Collection<String> resources) {
+        User user = userDAO.authFind(key);
 
         List<PropagationTask> tasks = propagationManager.getUserDeleteTasks(
-                userKey,
+                key,
                 new HashSet<>(resources),
                 CollectionUtils.removeAll(userDAO.findAllResourceNames(user), resources));
         PropagationReporter propagationReporter =
-                ApplicationContextProvider.getApplicationContext().getBean(PropagationReporter.class);
+                ApplicationContextProvider.getBeanFactory().getBean(PropagationReporter.class);
         try {
             taskExecutor.execute(tasks, propagationReporter);
         } catch (PropagationException e) {
@@ -331,16 +361,16 @@ public class DefaultUserProvisioningManager implements UserProvisioningManager {
     }
 
     @Override
-    public void requestPasswordReset(final Long id) {
-        uwfAdapter.requestPasswordReset(id);
+    public void requestPasswordReset(final Long key) {
+        uwfAdapter.requestPasswordReset(key);
     }
 
     @Override
-    public void confirmPasswordReset(final User user, final String token, final String password) {
-        uwfAdapter.confirmPasswordReset(user.getKey(), token, password);
+    public void confirmPasswordReset(final Long key, final String token, final String password) {
+        uwfAdapter.confirmPasswordReset(key, token, password);
 
         UserMod userMod = new UserMod();
-        userMod.setKey(user.getKey());
+        userMod.setKey(key);
         userMod.setPassword(password);
 
         List<PropagationTask> tasks = propagationManager.getUserUpdateTasks(
@@ -348,7 +378,7 @@ public class DefaultUserProvisioningManager implements UserProvisioningManager {
                         new ImmutablePair<UserMod, Boolean>(userMod, null), null, "confirmPasswordReset"),
                 true, null);
         PropagationReporter propReporter =
-                ApplicationContextProvider.getApplicationContext().getBean(PropagationReporter.class);
+                ApplicationContextProvider.getBeanFactory().getBean(PropagationReporter.class);
         try {
             taskExecutor.execute(tasks, propReporter);
         } catch (PropagationException e) {

http://git-wip-us.apache.org/repos/asf/syncope/blob/6dfedd8f/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/UserSuspenderImpl.java
----------------------------------------------------------------------
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/UserSuspenderImpl.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/UserSuspenderImpl.java
index bec5e28..7ff9e84 100644
--- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/UserSuspenderImpl.java
+++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/UserSuspenderImpl.java
@@ -18,8 +18,8 @@
  */
 package org.apache.syncope.core.provisioning.java;
 
-import org.apache.syncope.core.provisioning.api.UserSuspender;
 import org.apache.syncope.core.persistence.api.entity.user.User;
+import org.apache.syncope.core.provisioning.api.UserSuspender;
 import org.apache.syncope.core.provisioning.api.UserProvisioningManager;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;

http://git-wip-us.apache.org/repos/asf/syncope/blob/6dfedd8f/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/AbstractAnyDataBinder.java
----------------------------------------------------------------------
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/AbstractAnyDataBinder.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/AbstractAnyDataBinder.java
index 92a9bd3..689037b 100644
--- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/AbstractAnyDataBinder.java
+++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/AbstractAnyDataBinder.java
@@ -345,8 +345,8 @@ abstract class AbstractAnyDataBinder {
         Set<ExternalResource> resources = getAllResources(any);
 
         // 5. attributes to be removed
-        for (String attributeToBeRemoved : anyMod.getPlainAttrsToRemove()) {
-            PlainSchema schema = getPlainSchema(attributeToBeRemoved);
+        for (String attrToRemove : anyMod.getPlainAttrsToRemove()) {
+            PlainSchema schema = getPlainSchema(attrToRemove);
             if (schema != null) {
                 PlainAttr<?> attr = any.getPlainAttr(schema.getKey());
                 if (attr == null) {
@@ -388,8 +388,8 @@ abstract class AbstractAnyDataBinder {
         LOG.debug("Attributes to be removed:\n{}", propByRes);
 
         // 6. attributes to be updated
-        for (AttrMod attributeMod : anyMod.getPlainAttrsToUpdate()) {
-            PlainSchema schema = getPlainSchema(attributeMod.getSchema());
+        for (AttrMod attrMod : anyMod.getPlainAttrsToUpdate()) {
+            PlainSchema schema = getPlainSchema(attrMod.getSchema());
             PlainAttr attr = null;
             if (schema != null) {
                 attr = any.getPlainAttr(schema.getKey());
@@ -407,7 +407,7 @@ abstract class AbstractAnyDataBinder {
 
                 // 1.1 remove values
                 Set<Long> valuesToBeRemoved = new HashSet<>();
-                for (String valueToBeRemoved : attributeMod.getValuesToBeRemoved()) {
+                for (String valueToBeRemoved : attrMod.getValuesToBeRemoved()) {
                     if (attr.getSchema().isUniqueConstraint()) {
                         if (attr.getUniqueValue() != null
                                 && valueToBeRemoved.equals(attr.getUniqueValue().getValueAsString())) {
@@ -422,17 +422,17 @@ abstract class AbstractAnyDataBinder {
                         }
                     }
                 }
-                for (Long attributeValueId : valuesToBeRemoved) {
-                    plainAttrValueDAO.delete(attributeValueId, anyUtils.plainAttrValueClass());
+                for (Long attrValueKey : valuesToBeRemoved) {
+                    plainAttrValueDAO.delete(attrValueKey, anyUtils.plainAttrValueClass());
                 }
 
                 // 1.2 add values
-                List<String> valuesToBeAdded = attributeMod.getValuesToBeAdded();
+                List<String> valuesToBeAdded = attrMod.getValuesToBeAdded();
                 if (valuesToBeAdded != null && !valuesToBeAdded.isEmpty()
                         && (!schema.isUniqueConstraint() || attr.getUniqueValue() == null
                         || !valuesToBeAdded.iterator().next().equals(attr.getUniqueValue().getValueAsString()))) {
 
-                    fillAttribute(attributeMod.getValuesToBeAdded(), anyUtils, schema, attr, invalidValues);
+                    fillAttribute(attrMod.getValuesToBeAdded(), anyUtils, schema, attr, invalidValues);
                 }
 
                 // if no values are in, the attribute can be safely removed

http://git-wip-us.apache.org/repos/asf/syncope/blob/6dfedd8f/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/AnyObjectDataBinderImpl.java
----------------------------------------------------------------------
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/AnyObjectDataBinderImpl.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/AnyObjectDataBinderImpl.java
index 258e713..08c7e1d 100644
--- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/AnyObjectDataBinderImpl.java
+++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/AnyObjectDataBinderImpl.java
@@ -18,8 +18,6 @@
  */
 package org.apache.syncope.core.provisioning.java.data;
 
-import static org.apache.syncope.core.provisioning.java.data.AbstractAnyDataBinder.LOG;
-
 import java.util.Collection;
 import java.util.HashSet;
 import java.util.Map;

http://git-wip-us.apache.org/repos/asf/syncope/blob/6dfedd8f/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/ConfigurationDataBinderImpl.java
----------------------------------------------------------------------
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/ConfigurationDataBinderImpl.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/ConfigurationDataBinderImpl.java
index 3cf65fd..fe135b2 100644
--- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/ConfigurationDataBinderImpl.java
+++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/ConfigurationDataBinderImpl.java
@@ -18,8 +18,6 @@
  */
 package org.apache.syncope.core.provisioning.java.data;
 
-import static org.apache.syncope.core.provisioning.java.data.AbstractAnyDataBinder.LOG;
-
 import org.apache.syncope.core.provisioning.api.data.ConfigurationDataBinder;
 import java.util.Collections;
 import java.util.List;

http://git-wip-us.apache.org/repos/asf/syncope/blob/6dfedd8f/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/TaskDataBinderImpl.java
----------------------------------------------------------------------
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/TaskDataBinderImpl.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/TaskDataBinderImpl.java
index 762cca5..2295753 100644
--- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/TaskDataBinderImpl.java
+++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/TaskDataBinderImpl.java
@@ -61,6 +61,8 @@ import org.apache.syncope.core.persistence.api.entity.EntityFactory;
 import org.apache.syncope.core.persistence.api.entity.resource.ExternalResource;
 import org.apache.syncope.core.persistence.api.entity.task.AnyFilter;
 import org.apache.syncope.core.persistence.api.entity.task.AnyTemplate;
+import org.apache.syncope.core.provisioning.java.sync.PushJobDelegate;
+import org.apache.syncope.core.provisioning.java.sync.SyncJobDelegate;
 import org.quartz.Scheduler;
 import org.quartz.SchedulerException;
 import org.quartz.Trigger;
@@ -147,6 +149,8 @@ public class TaskDataBinderImpl implements TaskDataBinder {
             final PushTask pushTask = (PushTask) task;
             final PushTaskTO pushTaskTO = (PushTaskTO) taskTO;
 
+            pushTask.setJobDelegateClassName(PushJobDelegate.class.getName());
+
             pushTask.setMatchingRule(pushTaskTO.getMatchingRule() == null
                     ? MatchingRule.LINK : pushTaskTO.getMatchingRule());
             pushTask.setUnmatchingRule(pushTaskTO.getUnmatchingRule() == null
@@ -181,6 +185,8 @@ public class TaskDataBinderImpl implements TaskDataBinder {
 
             syncTask.setDestinationRealm(realmDAO.find(syncTaskTO.getDestinationRealm()));
 
+            syncTask.setJobDelegateClassName(SyncJobDelegate.class.getName());
+
             syncTask.setMatchingRule(syncTaskTO.getMatchingRule() == null
                     ? MatchingRule.UPDATE : syncTaskTO.getMatchingRule());
             syncTask.setUnmatchingRule(syncTaskTO.getUnmatchingRule() == null
@@ -239,7 +245,7 @@ public class TaskDataBinderImpl implements TaskDataBinder {
         task.setDescription(taskTO.getDescription());
 
         if (taskUtils.getType() == TaskType.SCHEDULED) {
-            task.setJobClassName(taskTO.getJobClassName());
+            task.setJobDelegateClassName(taskTO.getJobDelegateClassName());
         } else if (taskTO instanceof AbstractProvisioningTaskTO) {
             AbstractProvisioningTaskTO provisioningTaskTO = (AbstractProvisioningTaskTO) taskTO;
 

http://git-wip-us.apache.org/repos/asf/syncope/blob/6dfedd8f/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/job/AbstractSchedTaskJobDelegate.java
----------------------------------------------------------------------
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/job/AbstractSchedTaskJobDelegate.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/job/AbstractSchedTaskJobDelegate.java
new file mode 100644
index 0000000..3042239
--- /dev/null
+++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/job/AbstractSchedTaskJobDelegate.java
@@ -0,0 +1,144 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.syncope.core.provisioning.java.job;
+
+import java.util.Date;
+import org.apache.syncope.common.lib.types.AuditElements;
+import org.apache.syncope.core.misc.AuditManager;
+import org.apache.syncope.core.misc.ExceptionUtils2;
+import org.apache.syncope.core.persistence.api.dao.TaskDAO;
+import org.apache.syncope.core.persistence.api.dao.TaskExecDAO;
+import org.apache.syncope.core.persistence.api.entity.EntityFactory;
+import org.apache.syncope.core.persistence.api.entity.task.Task;
+import org.apache.syncope.core.persistence.api.entity.task.TaskExec;
+import org.apache.syncope.core.provisioning.api.job.SchedTaskJobDelegate;
+import org.apache.syncope.core.provisioning.api.notification.NotificationManager;
+import org.quartz.JobExecutionException;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.transaction.annotation.Transactional;
+
+public abstract class AbstractSchedTaskJobDelegate implements SchedTaskJobDelegate {
+
+    protected static final Logger LOG = LoggerFactory.getLogger(SchedTaskJobDelegate.class);
+
+    /**
+     * The actual task to be executed.
+     */
+    protected Task task;
+
+    /**
+     * Task execution DAO.
+     */
+    @Autowired
+    protected TaskExecDAO taskExecDAO;
+
+    /**
+     * Task DAO.
+     */
+    @Autowired
+    protected TaskDAO taskDAO;
+
+    @Autowired
+    protected EntityFactory entityFactory;
+
+    /**
+     * Notification manager.
+     */
+    @Autowired
+    protected NotificationManager notificationManager;
+
+    /**
+     * Audit manager.
+     */
+    @Autowired
+    protected AuditManager auditManager;
+
+    @Transactional
+    @Override
+    public void execute(final Long taskKey, final boolean dryRun) throws JobExecutionException {
+        task = taskDAO.find(taskKey);
+        if (task == null) {
+            throw new JobExecutionException("Task " + taskKey + " not found");
+        }
+
+        TaskExec execution = entityFactory.newEntity(TaskExec.class);
+        execution.setStartDate(new Date());
+        execution.setTask(task);
+
+        AuditElements.Result result;
+
+        try {
+            execution.setMessage(doExecute(dryRun));
+            execution.setStatus(TaskJob.Status.SUCCESS.name());
+            result = AuditElements.Result.SUCCESS;
+        } catch (JobExecutionException e) {
+            LOG.error("While executing task " + taskKey, e);
+            result = AuditElements.Result.FAILURE;
+
+            execution.setMessage(ExceptionUtils2.getFullStackTrace(e));
+            execution.setStatus(TaskJob.Status.FAILURE.name());
+        }
+        execution.setEndDate(new Date());
+
+        if (hasToBeRegistered(execution)) {
+            taskExecDAO.saveAndAdd(taskKey, execution);
+        }
+        task = taskDAO.save(task);
+
+        notificationManager.createTasks(
+                AuditElements.EventCategoryType.TASK,
+                this.getClass().getSimpleName(),
+                null,
+                this.getClass().getSimpleName(), // searching for before object is too much expensive ...
+                result,
+                task,
+                execution);
+
+        auditManager.audit(
+                AuditElements.EventCategoryType.TASK,
+                task.getClass().getSimpleName(),
+                null,
+                null, // searching for before object is too much expensive ...
+                result,
+                task,
+                (Object[]) null);
+    }
+
+    /**
+     * The actual execution, delegated to child classes.
+     *
+     * @param dryRun whether to actually touch the data
+     * @return the task execution status to be set
+     * @throws JobExecutionException if anything goes wrong
+     */
+    protected abstract String doExecute(boolean dryRun) throws JobExecutionException;
+
+    /**
+     * Template method to determine whether this job's task execution has to be persisted or not.
+     *
+     * @param execution task execution
+     * @return wether to persist or not
+     */
+    protected boolean hasToBeRegistered(final TaskExec execution) {
+        return false;
+    }
+
+}


[23/31] syncope git commit: [SYNCOPE-652] Now account lockout is working properly again

Posted by md...@apache.org.
[SYNCOPE-652] Now account lockout is working properly again


Project: http://git-wip-us.apache.org/repos/asf/syncope/repo
Commit: http://git-wip-us.apache.org/repos/asf/syncope/commit/5cf6aae8
Tree: http://git-wip-us.apache.org/repos/asf/syncope/tree/5cf6aae8
Diff: http://git-wip-us.apache.org/repos/asf/syncope/diff/5cf6aae8

Branch: refs/heads/SYNCOPE-156
Commit: 5cf6aae8274d8e10b884ec9faeca54f623234836
Parents: 6dfedd8
Author: Francesco Chicchiriccò <il...@apache.org>
Authored: Tue Aug 11 08:18:54 2015 +0200
Committer: Francesco Chicchiriccò <il...@apache.org>
Committed: Thu Aug 13 17:16:51 2015 +0200

----------------------------------------------------------------------
 .../client/console/rest/UserRestClient.java     |   6 +-
 .../syncope/common/lib/mod/StatusMod.java       |   2 +
 .../common/rest/api/service/UserService.java    |   2 +-
 .../core/misc/security/AuthDataAccessor.java    | 282 +++++++++++++++++++
 .../security/SyncopeAuthenticationProvider.java | 276 +++++++-----------
 .../security/SyncopeUserDetailsService.java     |  88 +-----
 .../misc/src/main/resources/securityContext.xml |   2 +
 .../core/persistence/api/dao/UserDAO.java       |   3 +
 .../core/persistence/jpa/dao/JPADomainDAO.java  |   2 +
 .../core/persistence/jpa/dao/JPAUserDAO.java    |  21 +-
 .../api/UserProvisioningManager.java            |   3 +-
 .../core/provisioning/api/UserSuspender.java    |  26 --
 .../java/DefaultUserProvisioningManager.java    |  13 +-
 .../provisioning/java/UserSuspenderImpl.java    |  51 ----
 .../java/data/UserDataBinderImpl.java           |   2 +-
 .../core/rest/cxf/service/UserServiceImpl.java  |   5 +-
 .../activiti/ActivitiUserWorkflowAdapter.java   |  15 +-
 .../core/workflow/api/UserWorkflowAdapter.java  |   9 +-
 .../java/AbstractUserWorkflowAdapter.java       |  54 +++-
 .../camel/AbstractCamelProvisioningManager.java |   4 +-
 .../camel/CamelUserProvisioningManager.java     |  10 +-
 .../processor/UserInnerSuspendProcessor.java    |  61 ----
 .../processor/UserInternalSuspendProcessor.java |  61 ++++
 .../src/main/resources/userRoutes.xml           |  12 +-
 .../core/reference/AuthenticationITCase.java    |   5 +-
 .../syncope/fit/core/reference/UserITCase.java  |  33 ++-
 .../fit/core/reference/VirAttrITCase.java       |   6 +-
 pom.xml                                         |   2 +-
 28 files changed, 559 insertions(+), 497 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/syncope/blob/5cf6aae8/client/console/src/main/java/org/apache/syncope/client/console/rest/UserRestClient.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/rest/UserRestClient.java b/client/console/src/main/java/org/apache/syncope/client/console/rest/UserRestClient.java
index 5c5c062..d161658 100644
--- a/client/console/src/main/java/org/apache/syncope/client/console/rest/UserRestClient.java
+++ b/client/console/src/main/java/org/apache/syncope/client/console/rest/UserRestClient.java
@@ -124,20 +124,22 @@ public class UserRestClient extends AbstractAnyRestClient {
 
     public void suspend(final String etag, final long userKey, final List<StatusBean> statuses) {
         StatusMod statusMod = StatusUtils.buildStatusMod(statuses, false);
+        statusMod.setKey(userKey);
         statusMod.setType(StatusMod.ModType.SUSPEND);
         synchronized (this) {
             UserService service = getService(etag, UserService.class);
-            service.status(userKey, statusMod);
+            service.status(statusMod);
             resetClient(UserService.class);
         }
     }
 
     public void reactivate(final String etag, final long userKey, final List<StatusBean> statuses) {
         StatusMod statusMod = StatusUtils.buildStatusMod(statuses, true);
+        statusMod.setKey(userKey);
         statusMod.setType(StatusMod.ModType.REACTIVATE);
         synchronized (this) {
             UserService service = getService(etag, UserService.class);
-            service.status(userKey, statusMod);
+            service.status(statusMod);
             resetClient(UserService.class);
         }
     }

http://git-wip-us.apache.org/repos/asf/syncope/blob/5cf6aae8/common/lib/src/main/java/org/apache/syncope/common/lib/mod/StatusMod.java
----------------------------------------------------------------------
diff --git a/common/lib/src/main/java/org/apache/syncope/common/lib/mod/StatusMod.java b/common/lib/src/main/java/org/apache/syncope/common/lib/mod/StatusMod.java
index 082b6f8..f989ecf 100644
--- a/common/lib/src/main/java/org/apache/syncope/common/lib/mod/StatusMod.java
+++ b/common/lib/src/main/java/org/apache/syncope/common/lib/mod/StatusMod.java
@@ -21,6 +21,7 @@ package org.apache.syncope.common.lib.mod;
 import com.fasterxml.jackson.annotation.JsonProperty;
 import java.util.ArrayList;
 import java.util.List;
+import javax.ws.rs.PathParam;
 import javax.xml.bind.annotation.XmlElement;
 import javax.xml.bind.annotation.XmlElementWrapper;
 import javax.xml.bind.annotation.XmlEnum;
@@ -66,6 +67,7 @@ public class StatusMod extends AbstractBaseBean {
      */
     private final List<String> resourceNames = new ArrayList<>();
 
+    @PathParam("key")
     public long getKey() {
         return key;
     }

http://git-wip-us.apache.org/repos/asf/syncope/blob/5cf6aae8/common/rest-api/src/main/java/org/apache/syncope/common/rest/api/service/UserService.java
----------------------------------------------------------------------
diff --git a/common/rest-api/src/main/java/org/apache/syncope/common/rest/api/service/UserService.java b/common/rest-api/src/main/java/org/apache/syncope/common/rest/api/service/UserService.java
index bf1e6b7..6dbb56c 100644
--- a/common/rest-api/src/main/java/org/apache/syncope/common/rest/api/service/UserService.java
+++ b/common/rest-api/src/main/java/org/apache/syncope/common/rest/api/service/UserService.java
@@ -107,5 +107,5 @@ public interface UserService extends AnyService<UserTO, UserMod> {
     @Path("{key}/status")
     @Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
     @Consumes({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
-    Response status(@NotNull @PathParam("key") Long key, @NotNull StatusMod statusMod);
+    Response status(@NotNull StatusMod statusMod);
 }

http://git-wip-us.apache.org/repos/asf/syncope/blob/5cf6aae8/core/misc/src/main/java/org/apache/syncope/core/misc/security/AuthDataAccessor.java
----------------------------------------------------------------------
diff --git a/core/misc/src/main/java/org/apache/syncope/core/misc/security/AuthDataAccessor.java b/core/misc/src/main/java/org/apache/syncope/core/misc/security/AuthDataAccessor.java
new file mode 100644
index 0000000..7643f9d
--- /dev/null
+++ b/core/misc/src/main/java/org/apache/syncope/core/misc/security/AuthDataAccessor.java
@@ -0,0 +1,282 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.syncope.core.misc.security;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Date;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Set;
+import javax.annotation.Resource;
+import org.apache.commons.collections4.Closure;
+import org.apache.commons.collections4.CollectionUtils;
+import org.apache.commons.collections4.IteratorUtils;
+import org.apache.commons.collections4.PredicateUtils;
+import org.apache.commons.collections4.SetUtils;
+import org.apache.commons.collections4.Transformer;
+import org.apache.commons.lang3.tuple.ImmutablePair;
+import org.apache.commons.lang3.tuple.Pair;
+import org.apache.syncope.common.lib.SyncopeConstants;
+import org.apache.syncope.common.lib.types.AuditElements;
+import org.apache.syncope.common.lib.types.Entitlement;
+import org.apache.syncope.core.misc.AuditManager;
+import org.apache.syncope.core.misc.MappingUtils;
+import org.apache.syncope.core.misc.RealmUtils;
+import org.apache.syncope.core.persistence.api.dao.AnyTypeDAO;
+import org.apache.syncope.core.persistence.api.dao.ConfDAO;
+import org.apache.syncope.core.persistence.api.dao.DomainDAO;
+import org.apache.syncope.core.persistence.api.dao.GroupDAO;
+import org.apache.syncope.core.persistence.api.dao.NotFoundException;
+import org.apache.syncope.core.persistence.api.dao.RealmDAO;
+import org.apache.syncope.core.persistence.api.dao.UserDAO;
+import org.apache.syncope.core.persistence.api.entity.Domain;
+import org.apache.syncope.core.persistence.api.entity.Realm;
+import org.apache.syncope.core.persistence.api.entity.Role;
+import org.apache.syncope.core.persistence.api.entity.conf.CPlainAttr;
+import org.apache.syncope.core.persistence.api.entity.group.Group;
+import org.apache.syncope.core.persistence.api.entity.resource.ExternalResource;
+import org.apache.syncope.core.persistence.api.entity.user.User;
+import org.apache.syncope.core.provisioning.api.ConnectorFactory;
+import org.identityconnectors.framework.common.objects.Uid;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.security.authentication.DisabledException;
+import org.springframework.security.core.Authentication;
+import org.springframework.security.core.userdetails.UsernameNotFoundException;
+import org.springframework.transaction.annotation.Transactional;
+
+public class AuthDataAccessor {
+
+    protected static final Logger LOG = LoggerFactory.getLogger(AuthDataAccessor.class);
+
+    @Resource(name = "adminUser")
+    protected String adminUser;
+
+    @Resource(name = "anonymousUser")
+    protected String anonymousUser;
+
+    @Autowired
+    protected DomainDAO domainDAO;
+
+    @Autowired
+    protected ConfDAO confDAO;
+
+    @Autowired
+    protected RealmDAO realmDAO;
+
+    @Autowired
+    protected UserDAO userDAO;
+
+    @Autowired
+    protected GroupDAO groupDAO;
+
+    @Autowired
+    protected AnyTypeDAO anyTypeDAO;
+
+    @Autowired
+    protected ConnectorFactory connFactory;
+
+    @Autowired
+    protected AuditManager auditManager;
+
+    protected final Encryptor encryptor = Encryptor.getInstance();
+
+    @Transactional(readOnly = true)
+    public Domain findDomain(final String key) {
+        Domain domain = domainDAO.find(key);
+        if (domain == null) {
+            throw new NotFoundException("Could not find domain " + key);
+        }
+        return domain;
+    }
+
+    @Transactional(noRollbackFor = DisabledException.class)
+    public Pair<Long, Boolean> authenticate(final Authentication authentication) {
+        Long key = null;
+        Boolean authenticated = false;
+
+        User user = userDAO.find(authentication.getName());
+        if (user != null) {
+            key = user.getKey();
+
+            if (user.isSuspended() != null && user.isSuspended()) {
+                throw new DisabledException("User " + user.getUsername() + " is suspended");
+            }
+
+            CPlainAttr authStatuses = confDAO.find("authentication.statuses");
+            if (authStatuses != null && !authStatuses.getValuesAsStrings().contains(user.getStatus())) {
+                throw new DisabledException("User " + user.getUsername() + " not allowed to authenticate");
+            }
+
+            boolean userModified = false;
+            authenticated = authenticate(user, authentication.getCredentials().toString());
+            if (authenticated) {
+                if (confDAO.find("log.lastlogindate", Boolean.toString(true)).getValues().get(0).getBooleanValue()) {
+                    user.setLastLoginDate(new Date());
+                    userModified = true;
+                }
+
+                if (user.getFailedLogins() != 0) {
+                    user.setFailedLogins(0);
+                    userModified = true;
+                }
+
+            } else {
+                user.setFailedLogins(user.getFailedLogins() + 1);
+                userModified = true;
+            }
+
+            if (userModified) {
+                userDAO.save(user);
+            }
+        }
+
+        return ImmutablePair.of(key, authenticated);
+    }
+
+    protected boolean authenticate(final User user, final String password) {
+        boolean authenticated = encryptor.verify(password, user.getCipherAlgorithm(), user.getPassword());
+        LOG.debug("{} authenticated on internal storage: {}", user.getUsername(), authenticated);
+
+        for (Iterator<? extends ExternalResource> itor = getPassthroughResources(user).iterator();
+                itor.hasNext() && !authenticated;) {
+
+            ExternalResource resource = itor.next();
+            String connObjectKey = null;
+            try {
+                connObjectKey = MappingUtils.getConnObjectKeyValue(user, resource.getProvision(anyTypeDAO.findUser()));
+                Uid uid = connFactory.getConnector(resource).authenticate(connObjectKey, password, null);
+                if (uid != null) {
+                    authenticated = true;
+                }
+            } catch (Exception e) {
+                LOG.debug("Could not authenticate {} on {}", user.getUsername(), resource.getKey(), e);
+            }
+            LOG.debug("{} authenticated on {} as {}: {}",
+                    user.getUsername(), resource.getKey(), connObjectKey, authenticated);
+        }
+
+        return authenticated;
+    }
+
+    protected Set<? extends ExternalResource> getPassthroughResources(final User user) {
+        Set<? extends ExternalResource> result = null;
+
+        // 1. look for assigned resources, pick the ones whose account policy has authentication resources
+        for (ExternalResource resource : userDAO.findAllResources(user)) {
+            if (resource.getAccountPolicy() != null && !resource.getAccountPolicy().getResources().isEmpty()) {
+                if (result == null) {
+                    result = resource.getAccountPolicy().getResources();
+                } else {
+                    result.retainAll(resource.getAccountPolicy().getResources());
+                }
+            }
+        }
+
+        // 2. look for realms, pick the ones whose account policy has authentication resources
+        for (Realm realm : realmDAO.findAncestors(user.getRealm())) {
+            if (realm.getAccountPolicy() != null && !realm.getAccountPolicy().getResources().isEmpty()) {
+                if (result == null) {
+                    result = realm.getAccountPolicy().getResources();
+                } else {
+                    result.retainAll(realm.getAccountPolicy().getResources());
+                }
+            }
+        }
+
+        return SetUtils.emptyIfNull(result);
+    }
+
+    @Transactional(readOnly = true)
+    public void audit(
+            final AuditElements.EventCategoryType type,
+            final String category,
+            final String subcategory,
+            final String event,
+            final AuditElements.Result result,
+            final Object before,
+            final Object output,
+            final Object... input) {
+
+        auditManager.audit(type, category, subcategory, event, result, before, output, input);
+    }
+
+    @Transactional
+    public Set<SyncopeGrantedAuthority> load(final String username) {
+        final Set<SyncopeGrantedAuthority> authorities = new HashSet<>();
+        if (anonymousUser.equals(username)) {
+            authorities.add(new SyncopeGrantedAuthority(Entitlement.ANONYMOUS));
+        } else if (adminUser.equals(username)) {
+            CollectionUtils.collect(IteratorUtils.filteredIterator(Entitlement.values().iterator(),
+                    PredicateUtils.notPredicate(PredicateUtils.equalPredicate(Entitlement.ANONYMOUS))),
+                    new Transformer<String, SyncopeGrantedAuthority>() {
+
+                        @Override
+                        public SyncopeGrantedAuthority transform(final String entitlement) {
+                            return new SyncopeGrantedAuthority(entitlement, SyncopeConstants.ROOT_REALM);
+                        }
+                    },
+                    authorities);
+        } else {
+            User user = userDAO.find(username);
+            if (user == null) {
+                throw new UsernameNotFoundException("Could not find any user with id " + username);
+            }
+
+            // Give entitlements as assigned by roles (with realms, where applicable) - assigned either
+            // statically and dynamically
+            for (final Role role : userDAO.findAllRoles(user)) {
+                CollectionUtils.forAllDo(role.getEntitlements(), new Closure<String>() {
+
+                    @Override
+                    public void execute(final String entitlement) {
+                        SyncopeGrantedAuthority authority = new SyncopeGrantedAuthority(entitlement);
+                        authorities.add(authority);
+
+                        List<String> realmFullPahs = new ArrayList<>();
+                        CollectionUtils.collect(role.getRealms(), new Transformer<Realm, String>() {
+
+                            @Override
+                            public String transform(final Realm realm) {
+                                return realm.getFullPath();
+                            }
+                        }, realmFullPahs);
+                        authority.addRealms(realmFullPahs);
+                    }
+                });
+            }
+
+            // Give group entitlements for owned groups
+            for (Group group : groupDAO.findOwnedByUser(user.getKey())) {
+                for (String entitlement : Arrays.asList(
+                        Entitlement.GROUP_READ, Entitlement.GROUP_UPDATE, Entitlement.GROUP_DELETE)) {
+
+                    SyncopeGrantedAuthority authority = new SyncopeGrantedAuthority(entitlement);
+                    authority.addRealm(RealmUtils.getGroupOwnerRealm(group.getRealm().getFullPath(), group.getKey()));
+                    authorities.add(authority);
+                }
+            }
+        }
+
+        return authorities;
+    }
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/5cf6aae8/core/misc/src/main/java/org/apache/syncope/core/misc/security/SyncopeAuthenticationProvider.java
----------------------------------------------------------------------
diff --git a/core/misc/src/main/java/org/apache/syncope/core/misc/security/SyncopeAuthenticationProvider.java b/core/misc/src/main/java/org/apache/syncope/core/misc/security/SyncopeAuthenticationProvider.java
index f452128..c8fa53d 100644
--- a/core/misc/src/main/java/org/apache/syncope/core/misc/security/SyncopeAuthenticationProvider.java
+++ b/core/misc/src/main/java/org/apache/syncope/core/misc/security/SyncopeAuthenticationProvider.java
@@ -18,44 +18,26 @@
  */
 package org.apache.syncope.core.misc.security;
 
-import java.util.Date;
-import java.util.Iterator;
-import java.util.Set;
 import javax.annotation.Resource;
-import org.apache.commons.collections4.SetUtils;
 import org.apache.commons.lang3.StringUtils;
+import org.apache.commons.lang3.tuple.Pair;
 import org.apache.syncope.common.lib.SyncopeConstants;
 import org.apache.syncope.common.lib.types.AuditElements;
 import org.apache.syncope.common.lib.types.AuditElements.Result;
 import org.apache.syncope.common.lib.types.CipherAlgorithm;
-import org.apache.syncope.core.persistence.api.dao.ConfDAO;
-import org.apache.syncope.core.persistence.api.dao.PolicyDAO;
-import org.apache.syncope.core.persistence.api.dao.UserDAO;
-import org.apache.syncope.core.persistence.api.entity.AnyUtilsFactory;
-import org.apache.syncope.core.persistence.api.entity.resource.ExternalResource;
-import org.apache.syncope.core.persistence.api.entity.conf.CPlainAttr;
-import org.apache.syncope.core.persistence.api.entity.user.User;
-import org.apache.syncope.core.provisioning.api.ConnectorFactory;
-import org.apache.syncope.core.misc.AuditManager;
-import org.apache.syncope.core.misc.MappingUtils;
-import org.apache.syncope.core.persistence.api.dao.AnyTypeDAO;
-import org.apache.syncope.core.persistence.api.dao.DomainDAO;
-import org.apache.syncope.core.persistence.api.dao.NotFoundException;
-import org.apache.syncope.core.persistence.api.dao.RealmDAO;
 import org.apache.syncope.core.persistence.api.entity.Domain;
-import org.apache.syncope.core.persistence.api.entity.Realm;
-import org.identityconnectors.framework.common.objects.Uid;
+import org.apache.syncope.core.provisioning.api.UserProvisioningManager;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.beans.factory.annotation.Configurable;
 import org.springframework.security.authentication.AuthenticationProvider;
 import org.springframework.security.authentication.BadCredentialsException;
-import org.springframework.security.authentication.DisabledException;
 import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
 import org.springframework.security.core.Authentication;
+import org.springframework.security.core.context.SecurityContext;
+import org.springframework.security.core.context.SecurityContextHolder;
 import org.springframework.security.core.userdetails.UserDetailsService;
-import org.springframework.transaction.annotation.Transactional;
 
 @Configurable
 public class SyncopeAuthenticationProvider implements AuthenticationProvider {
@@ -63,31 +45,10 @@ public class SyncopeAuthenticationProvider implements AuthenticationProvider {
     protected static final Logger LOG = LoggerFactory.getLogger(SyncopeAuthenticationProvider.class);
 
     @Autowired
-    protected AuditManager auditManager;
+    protected AuthDataAccessor dataAccessor;
 
     @Autowired
-    protected DomainDAO domainDAO;
-
-    @Autowired
-    protected ConfDAO confDAO;
-
-    @Autowired
-    protected RealmDAO realmDAO;
-
-    @Autowired
-    protected UserDAO userDAO;
-
-    @Autowired
-    protected PolicyDAO policyDAO;
-
-    @Autowired
-    protected AnyTypeDAO anyTypeDAO;
-
-    @Autowired
-    protected ConnectorFactory connFactory;
-
-    @Autowired
-    protected AnyUtilsFactory attrUtilsFactory;
+    protected UserProvisioningManager provisioningManager;
 
     @Resource(name = "adminUser")
     protected String adminUser;
@@ -130,19 +91,26 @@ public class SyncopeAuthenticationProvider implements AuthenticationProvider {
         this.userDetailsService = syncopeUserDetailsService;
     }
 
+    protected <T> T execWithAuthContext(final String domainKey, final Executable<T> executable) {
+        SecurityContext ctx = SecurityContextHolder.getContext();
+        AuthContextUtils.setFakeAuth(domainKey);
+        try {
+            return executable.exec();
+        } finally {
+            AuthContextUtils.clearFakeAuth();
+            SecurityContextHolder.setContext(ctx);
+        }
+    }
+
     @Override
-    @Transactional(noRollbackFor = { BadCredentialsException.class, DisabledException.class })
     public Authentication authenticate(final Authentication authentication) {
-        boolean authenticated = false;
-
-        String domainKey = authentication.getDetails() instanceof SyncopeAuthenticationDetails
-                ? SyncopeAuthenticationDetails.class.cast(authentication.getDetails()).getDomain()
-                : null;
+        String domainKey = SyncopeAuthenticationDetails.class.cast(authentication.getDetails()).getDomain();
         if (StringUtils.isBlank(domainKey)) {
             domainKey = SyncopeConstants.MASTER_DOMAIN;
         }
         SyncopeAuthenticationDetails.class.cast(authentication.getDetails()).setDomain(domainKey);
 
+        boolean authenticated;
         if (anonymousUser.equals(authentication.getName())) {
             authenticated = authentication.getCredentials().toString().equals(anonymousKey);
         } else if (adminUser.equals(authentication.getName())) {
@@ -152,67 +120,90 @@ public class SyncopeAuthenticationProvider implements AuthenticationProvider {
                         CipherAlgorithm.valueOf(adminPasswordAlgorithm),
                         adminPassword);
             } else {
-                Domain domain = domainDAO.find(domainKey);
-                if (domain == null) {
-                    throw new NotFoundException("Could not find domain " + domainKey);
-                }
-
-                authenticated = encryptor.verify(
-                        authentication.getCredentials().toString(),
-                        domain.getAdminCipherAlgorithm(),
-                        domain.getAdminPwd());
+                final String domainToFind = domainKey;
+                authenticated = execWithAuthContext(SyncopeConstants.MASTER_DOMAIN, new Executable<Boolean>() {
+
+                    @Override
+                    public Boolean exec() {
+                        Domain domain = dataAccessor.findDomain(domainToFind);
+
+                        return encryptor.verify(
+                                authentication.getCredentials().toString(),
+                                domain.getAdminCipherAlgorithm(),
+                                domain.getAdminPwd());
+                    }
+                });
             }
         } else {
-            User user = userDAO.find(authentication.getName());
-
-            if (user != null) {
-                if (user.isSuspended() != null && user.isSuspended()) {
-                    throw new DisabledException("User " + user.getUsername() + " is suspended");
-                }
-
-                CPlainAttr authStatuses = confDAO.find("authentication.statuses");
-                if (authStatuses != null && !authStatuses.getValuesAsStrings().contains(user.getStatus())) {
-                    throw new DisabledException("User " + user.getUsername() + " not allowed to authenticate");
-                }
-
-                authenticated = authenticate(user, authentication.getCredentials().toString());
-
-                updateLoginAttributes(user, authenticated);
+            final Pair<Long, Boolean> authResult =
+                    execWithAuthContext(domainKey, new Executable<Pair<Long, Boolean>>() {
+
+                        @Override
+                        public Pair<Long, Boolean> exec() {
+                            return dataAccessor.authenticate(authentication);
+                        }
+                    });
+            authenticated = authResult.getValue();
+            if (!authenticated) {
+                execWithAuthContext(domainKey, new Executable<Void>() {
+
+                    @Override
+                    public Void exec() {
+                        provisioningManager.internalSuspend(authResult.getKey());
+                        return null;
+                    }
+                });
             }
         }
 
+        final boolean isAuthenticated = authenticated;
         UsernamePasswordAuthenticationToken token;
-        if (authenticated) {
-            token = new UsernamePasswordAuthenticationToken(
-                    authentication.getPrincipal(),
-                    null,
-                    userDetailsService.loadUserByUsername(authentication.getPrincipal().toString()).getAuthorities());
-            token.setDetails(authentication.getDetails());
-
-            auditManager.audit(
-                    AuditElements.EventCategoryType.REST,
-                    AuditElements.AUTHENTICATION_CATEGORY,
-                    null,
-                    AuditElements.LOGIN_EVENT,
-                    Result.SUCCESS,
-                    null,
-                    authenticated,
-                    authentication,
-                    "Successfully authenticated, with entitlements: " + token.getAuthorities());
+        if (isAuthenticated) {
+            token = execWithAuthContext(domainKey, new Executable<UsernamePasswordAuthenticationToken>() {
+
+                @Override
+                public UsernamePasswordAuthenticationToken exec() {
+                    UsernamePasswordAuthenticationToken token = new UsernamePasswordAuthenticationToken(
+                            authentication.getPrincipal(),
+                            null,
+                            userDetailsService.loadUserByUsername(authentication.getPrincipal().toString()).
+                            getAuthorities());
+                    token.setDetails(authentication.getDetails());
+
+                    dataAccessor.audit(
+                            AuditElements.EventCategoryType.REST,
+                            AuditElements.AUTHENTICATION_CATEGORY,
+                            null,
+                            AuditElements.LOGIN_EVENT,
+                            Result.SUCCESS,
+                            null,
+                            isAuthenticated,
+                            authentication,
+                            "Successfully authenticated, with entitlements: " + token.getAuthorities());
+                    return token;
+                }
+            });
 
             LOG.debug("User {} successfully authenticated, with groups {}",
                     authentication.getPrincipal(), token.getAuthorities());
         } else {
-            auditManager.audit(
-                    AuditElements.EventCategoryType.REST,
-                    AuditElements.AUTHENTICATION_CATEGORY,
-                    null,
-                    AuditElements.LOGIN_EVENT,
-                    Result.FAILURE,
-                    null,
-                    authenticated,
-                    authentication,
-                    "User " + authentication.getPrincipal() + " not authenticated");
+            execWithAuthContext(domainKey, new Executable<Void>() {
+
+                @Override
+                public Void exec() {
+                    dataAccessor.audit(
+                            AuditElements.EventCategoryType.REST,
+                            AuditElements.AUTHENTICATION_CATEGORY,
+                            null,
+                            AuditElements.LOGIN_EVENT,
+                            Result.FAILURE,
+                            null,
+                            isAuthenticated,
+                            authentication,
+                            "User " + authentication.getPrincipal() + " not authenticated");
+                    return null;
+                }
+            });
 
             LOG.debug("User {} not authenticated", authentication.getPrincipal());
 
@@ -222,84 +213,13 @@ public class SyncopeAuthenticationProvider implements AuthenticationProvider {
         return token;
     }
 
-    protected void updateLoginAttributes(final User user, final boolean authenticated) {
-        boolean userModified = false;
-
-        if (authenticated) {
-            if (confDAO.find("log.lastlogindate", Boolean.toString(true)).getValues().get(0).getBooleanValue()) {
-                user.setLastLoginDate(new Date());
-                userModified = true;
-            }
-
-            if (user.getFailedLogins() != 0) {
-                user.setFailedLogins(0);
-                userModified = true;
-            }
-        } else {
-            user.setFailedLogins(user.getFailedLogins() + 1);
-            userModified = true;
-        }
-
-        if (userModified) {
-            userDAO.save(user);
-        }
-    }
-
-    protected Set<? extends ExternalResource> getPassthroughResources(final User user) {
-        Set<? extends ExternalResource> result = null;
-
-        // 1. look for assigned resources, pick the ones whose account policy has authentication resources
-        for (ExternalResource resource : userDAO.findAllResources(user)) {
-            if (resource.getAccountPolicy() != null && !resource.getAccountPolicy().getResources().isEmpty()) {
-                if (result == null) {
-                    result = resource.getAccountPolicy().getResources();
-                } else {
-                    result.retainAll(resource.getAccountPolicy().getResources());
-                }
-            }
-        }
-
-        // 2. look for realms, pick the ones whose account policy has authentication resources
-        for (Realm realm : realmDAO.findAncestors(user.getRealm())) {
-            if (realm.getAccountPolicy() != null && !realm.getAccountPolicy().getResources().isEmpty()) {
-                if (result == null) {
-                    result = realm.getAccountPolicy().getResources();
-                } else {
-                    result.retainAll(realm.getAccountPolicy().getResources());
-                }
-            }
-        }
-
-        return SetUtils.emptyIfNull(result);
-    }
-
-    protected boolean authenticate(final User user, final String password) {
-        boolean authenticated = encryptor.verify(password, user.getCipherAlgorithm(), user.getPassword());
-        LOG.debug("{} authenticated on internal storage: {}", user.getUsername(), authenticated);
-
-        for (Iterator<? extends ExternalResource> itor = getPassthroughResources(user).iterator();
-                itor.hasNext() && !authenticated;) {
-
-            ExternalResource resource = itor.next();
-            String connObjectKey = null;
-            try {
-                connObjectKey = MappingUtils.getConnObjectKeyValue(user, resource.getProvision(anyTypeDAO.findUser()));
-                Uid uid = connFactory.getConnector(resource).authenticate(connObjectKey, password, null);
-                if (uid != null) {
-                    authenticated = true;
-                }
-            } catch (Exception e) {
-                LOG.debug("Could not authenticate {} on {}", user.getUsername(), resource.getKey(), e);
-            }
-            LOG.debug("{} authenticated on {} as {}: {}",
-                    user.getUsername(), resource.getKey(), connObjectKey, authenticated);
-        }
-
-        return authenticated;
-    }
-
     @Override
     public boolean supports(final Class<? extends Object> type) {
         return type.equals(UsernamePasswordAuthenticationToken.class);
     }
+
+    protected interface Executable<T> {
+
+        T exec();
+    }
 }

http://git-wip-us.apache.org/repos/asf/syncope/blob/5cf6aae8/core/misc/src/main/java/org/apache/syncope/core/misc/security/SyncopeUserDetailsService.java
----------------------------------------------------------------------
diff --git a/core/misc/src/main/java/org/apache/syncope/core/misc/security/SyncopeUserDetailsService.java b/core/misc/src/main/java/org/apache/syncope/core/misc/security/SyncopeUserDetailsService.java
index a179e75..70ec6ac 100644
--- a/core/misc/src/main/java/org/apache/syncope/core/misc/security/SyncopeUserDetailsService.java
+++ b/core/misc/src/main/java/org/apache/syncope/core/misc/security/SyncopeUserDetailsService.java
@@ -18,104 +18,20 @@
  */
 package org.apache.syncope.core.misc.security;
 
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Set;
-import javax.annotation.Resource;
-import org.apache.commons.collections4.Closure;
-import org.apache.commons.collections4.CollectionUtils;
-import org.apache.commons.collections4.IteratorUtils;
-import org.apache.commons.collections4.PredicateUtils;
-import org.apache.commons.collections4.Transformer;
-import org.apache.syncope.common.lib.SyncopeConstants;
-import org.apache.syncope.common.lib.types.Entitlement;
-import org.apache.syncope.core.misc.RealmUtils;
-import org.apache.syncope.core.persistence.api.dao.GroupDAO;
-import org.apache.syncope.core.persistence.api.dao.UserDAO;
-import org.apache.syncope.core.persistence.api.entity.Realm;
-import org.apache.syncope.core.persistence.api.entity.Role;
-import org.apache.syncope.core.persistence.api.entity.group.Group;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.beans.factory.annotation.Configurable;
 import org.springframework.security.core.userdetails.User;
 import org.springframework.security.core.userdetails.UserDetails;
 import org.springframework.security.core.userdetails.UserDetailsService;
-import org.springframework.security.core.userdetails.UsernameNotFoundException;
 
 @Configurable
 public class SyncopeUserDetailsService implements UserDetailsService {
 
     @Autowired
-    protected UserDAO userDAO;
-
-    @Autowired
-    protected GroupDAO groupDAO;
-
-    @Resource(name = "adminUser")
-    protected String adminUser;
-
-    @Resource(name = "anonymousUser")
-    protected String anonymousUser;
+    protected AuthDataAccessor dataAccessor;
 
     @Override
     public UserDetails loadUserByUsername(final String username) {
-        final Set<SyncopeGrantedAuthority> authorities = new HashSet<>();
-        if (anonymousUser.equals(username)) {
-            authorities.add(new SyncopeGrantedAuthority(Entitlement.ANONYMOUS));
-        } else if (adminUser.equals(username)) {
-            CollectionUtils.collect(IteratorUtils.filteredIterator(Entitlement.values().iterator(),
-                    PredicateUtils.notPredicate(PredicateUtils.equalPredicate(Entitlement.ANONYMOUS))),
-                    new Transformer<String, SyncopeGrantedAuthority>() {
-
-                        @Override
-                        public SyncopeGrantedAuthority transform(final String entitlement) {
-                            return new SyncopeGrantedAuthority(entitlement, SyncopeConstants.ROOT_REALM);
-                        }
-                    },
-                    authorities);
-        } else {
-            org.apache.syncope.core.persistence.api.entity.user.User user = userDAO.find(username);
-            if (user == null) {
-                throw new UsernameNotFoundException("Could not find any user with id " + username);
-            }
-
-            // Give entitlements as assigned by roles (with realms, where applicable) - assigned either
-            // statically and dynamically
-            for (final Role role : userDAO.findAllRoles(user)) {
-                CollectionUtils.forAllDo(role.getEntitlements(), new Closure<String>() {
-
-                    @Override
-                    public void execute(final String entitlement) {
-                        SyncopeGrantedAuthority authority = new SyncopeGrantedAuthority(entitlement);
-                        authorities.add(authority);
-
-                        List<String> realmFullPahs = new ArrayList<>();
-                        CollectionUtils.collect(role.getRealms(), new Transformer<Realm, String>() {
-
-                            @Override
-                            public String transform(final Realm realm) {
-                                return realm.getFullPath();
-                            }
-                        }, realmFullPahs);
-                        authority.addRealms(realmFullPahs);
-                    }
-                });
-            }
-
-            // Give group entitlements for owned groups
-            for (Group group : groupDAO.findOwnedByUser(user.getKey())) {
-                for (String entitlement : Arrays.asList(
-                        Entitlement.GROUP_READ, Entitlement.GROUP_UPDATE, Entitlement.GROUP_DELETE)) {
-
-                    SyncopeGrantedAuthority authority = new SyncopeGrantedAuthority(entitlement);
-                    authority.addRealm(RealmUtils.getGroupOwnerRealm(group.getRealm().getFullPath(), group.getKey()));
-                    authorities.add(authority);
-                }
-            }
-        }
-
-        return new User(username, "<PASSWORD_PLACEHOLDER>", authorities);
+        return new User(username, "<PASSWORD_PLACEHOLDER>", dataAccessor.load(username));
     }
 }

http://git-wip-us.apache.org/repos/asf/syncope/blob/5cf6aae8/core/misc/src/main/resources/securityContext.xml
----------------------------------------------------------------------
diff --git a/core/misc/src/main/resources/securityContext.xml b/core/misc/src/main/resources/securityContext.xml
index 57b1980..1022815 100644
--- a/core/misc/src/main/resources/securityContext.xml
+++ b/core/misc/src/main/resources/securityContext.xml
@@ -62,6 +62,8 @@ under the License.
     <security:csrf disabled="true"/>
   </security:http>
 
+  <bean class="org.apache.syncope.core.misc.security.AuthDataAccessor"/>
+
   <bean id="syncopeUserDetailsService" class="org.apache.syncope.core.misc.security.SyncopeUserDetailsService"/>
 
   <bean id="syncopeAuthenticationProvider" class="org.apache.syncope.core.misc.security.SyncopeAuthenticationProvider">

http://git-wip-us.apache.org/repos/asf/syncope/blob/5cf6aae8/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/UserDAO.java
----------------------------------------------------------------------
diff --git a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/UserDAO.java b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/UserDAO.java
index a1e4d09..3fc9b99 100644
--- a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/UserDAO.java
+++ b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/UserDAO.java
@@ -20,6 +20,7 @@ package org.apache.syncope.core.persistence.api.dao;
 
 import java.util.Collection;
 import java.util.List;
+import org.apache.commons.lang3.tuple.Pair;
 import org.apache.syncope.core.persistence.api.entity.Role;
 import org.apache.syncope.core.persistence.api.entity.group.Group;
 import org.apache.syncope.core.persistence.api.entity.resource.ExternalResource;
@@ -49,4 +50,6 @@ public interface UserDAO extends AnyDAO<User> {
     Collection<ExternalResource> findAllResources(User user);
 
     Collection<String> findAllResourceNames(User user);
+
+    Pair<Boolean, Boolean> enforcePolicies(User user);
 }

http://git-wip-us.apache.org/repos/asf/syncope/blob/5cf6aae8/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPADomainDAO.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPADomainDAO.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPADomainDAO.java
index b3bb188..eeee97c 100644
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPADomainDAO.java
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPADomainDAO.java
@@ -24,10 +24,12 @@ import org.apache.syncope.core.persistence.api.dao.DomainDAO;
 import org.apache.syncope.core.persistence.api.entity.Domain;
 import org.apache.syncope.core.persistence.jpa.entity.JPADomain;
 import org.springframework.stereotype.Repository;
+import org.springframework.transaction.annotation.Transactional;
 
 @Repository
 public class JPADomainDAO extends AbstractDAO<Domain, String> implements DomainDAO {
 
+    @Transactional(readOnly = true)
     @Override
     public Domain find(final String key) {
         return entityManager().find(JPADomain.class, key);

http://git-wip-us.apache.org/repos/asf/syncope/blob/5cf6aae8/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAUserDAO.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAUserDAO.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAUserDAO.java
index 50564f2..4e9afe1 100644
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAUserDAO.java
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAUserDAO.java
@@ -63,7 +63,6 @@ import org.apache.syncope.core.persistence.api.entity.user.UMembership;
 import org.apache.syncope.core.persistence.jpa.entity.JPAAnyUtilsFactory;
 import org.apache.syncope.core.persistence.jpa.entity.user.JPADynRoleMembership;
 import org.apache.syncope.core.persistence.jpa.entity.user.JPAUDynGroupMembership;
-import org.apache.syncope.core.provisioning.api.UserSuspender;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Repository;
 import org.springframework.transaction.annotation.Propagation;
@@ -96,9 +95,6 @@ public class JPAUserDAO extends AbstractAnyDAO<User> implements UserDAO {
     @Autowired
     private AccountPolicyEnforcer apEnforcer;
 
-    @Autowired(required = false)
-    private UserSuspender suspender;
-
     @Override
     protected AnyUtils init() {
         return new JPAAnyUtilsFactory().getInstance(AnyTypeKind.USER);
@@ -210,11 +206,9 @@ public class JPAUserDAO extends AbstractAnyDAO<User> implements UserDAO {
     private List<AccountPolicy> getAccountPolicies(final User user) {
         List<AccountPolicy> policies = new ArrayList<>();
 
-        AccountPolicy policy;
-
         // add resource policies        
         for (ExternalResource resource : findAllResources(user)) {
-            policy = resource.getAccountPolicy();
+            AccountPolicy policy = resource.getAccountPolicy();
             if (policy != null) {
                 policies.add(policy);
             }
@@ -222,7 +216,7 @@ public class JPAUserDAO extends AbstractAnyDAO<User> implements UserDAO {
 
         // add realm policies
         for (Realm realm : realmDAO.findAncestors(user.getRealm())) {
-            policy = realm.getAccountPolicy();
+            AccountPolicy policy = realm.getAccountPolicy();
             if (policy != null) {
                 policies.add(policy);
             }
@@ -231,7 +225,9 @@ public class JPAUserDAO extends AbstractAnyDAO<User> implements UserDAO {
         return policies;
     }
 
-    private Pair<Boolean, Boolean> enforcePolicies(final User user) {
+    @Transactional(readOnly = true)
+    @Override
+    public Pair<Boolean, Boolean> enforcePolicies(final User user) {
         // ------------------------------
         // Verify password policies
         // ------------------------------
@@ -310,18 +306,13 @@ public class JPAUserDAO extends AbstractAnyDAO<User> implements UserDAO {
         JPAUser.class.cast(merged).setClearPassword(clearPwd);
 
         // 4. enforce password and account policies
-        Pair<Boolean, Boolean> enforceSuspend = null;
         try {
-            enforceSuspend = enforcePolicies(merged);
+            enforcePolicies(merged);
         } catch (InvalidEntityException e) {
             entityManager().remove(merged);
             throw e;
         }
 
-        if (suspender != null && enforceSuspend.getKey()) {
-            suspender.suspend(user, enforceSuspend.getValue());
-        }
-
         roleDAO.refreshDynMemberships(merged);
         groupDAO.refreshDynMemberships(merged);
 

http://git-wip-us.apache.org/repos/asf/syncope/blob/5cf6aae8/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/UserProvisioningManager.java
----------------------------------------------------------------------
diff --git a/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/UserProvisioningManager.java b/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/UserProvisioningManager.java
index 3378707..21acad2 100644
--- a/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/UserProvisioningManager.java
+++ b/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/UserProvisioningManager.java
@@ -26,7 +26,6 @@ import org.apache.syncope.common.lib.mod.StatusMod;
 import org.apache.syncope.common.lib.mod.UserMod;
 import org.apache.syncope.common.lib.to.PropagationStatus;
 import org.apache.syncope.common.lib.to.UserTO;
-import org.apache.syncope.core.persistence.api.entity.user.User;
 import org.apache.syncope.core.provisioning.api.sync.ProvisioningResult;
 
 public interface UserProvisioningManager extends ProvisioningManager<UserTO, UserMod> {
@@ -37,7 +36,7 @@ public interface UserProvisioningManager extends ProvisioningManager<UserTO, Use
 
     Pair<Long, List<PropagationStatus>> suspend(StatusMod statusMod);
 
-    void innerSuspend(User user, boolean propagate);
+    void internalSuspend(Long key);
 
     Pair<Long, List<PropagationStatus>> create(UserTO userTO, boolean storePassword);
 

http://git-wip-us.apache.org/repos/asf/syncope/blob/5cf6aae8/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/UserSuspender.java
----------------------------------------------------------------------
diff --git a/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/UserSuspender.java b/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/UserSuspender.java
deleted file mode 100644
index 610513c..0000000
--- a/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/UserSuspender.java
+++ /dev/null
@@ -1,26 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.syncope.core.provisioning.api;
-
-import org.apache.syncope.core.persistence.api.entity.user.User;
-
-public interface UserSuspender {
-
-    void suspend(User user, boolean propagateSuspension);
-}

http://git-wip-us.apache.org/repos/asf/syncope/blob/5cf6aae8/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/DefaultUserProvisioningManager.java
----------------------------------------------------------------------
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/DefaultUserProvisioningManager.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/DefaultUserProvisioningManager.java
index 0809607..38264de 100644
--- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/DefaultUserProvisioningManager.java
+++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/DefaultUserProvisioningManager.java
@@ -288,19 +288,18 @@ public class DefaultUserProvisioningManager implements UserProvisioningManager {
     }
 
     @Override
-    public void innerSuspend(final User user, final boolean propagate) {
-        final WorkflowResult<Long> updated = uwfAdapter.suspend(user);
+    public void internalSuspend(final Long key) {
+        Pair<WorkflowResult<Long>, Boolean> updated = uwfAdapter.internalSuspend(key);
 
         // propagate suspension if and only if it is required by policy
-        if (propagate) {
+        if (updated != null && updated.getValue()) {
             UserMod userMod = new UserMod();
-            userMod.setKey(updated.getResult());
+            userMod.setKey(updated.getKey().getResult());
 
-            final List<PropagationTask> tasks = propagationManager.getUserUpdateTasks(
+            List<PropagationTask> tasks = propagationManager.getUserUpdateTasks(
                     new WorkflowResult<Pair<UserMod, Boolean>>(
                             new ImmutablePair<>(userMod, Boolean.FALSE),
-                            updated.getPropByRes(), updated.getPerformedTasks()));
-
+                            updated.getKey().getPropByRes(), updated.getKey().getPerformedTasks()));
             taskExecutor.execute(tasks);
         }
     }

http://git-wip-us.apache.org/repos/asf/syncope/blob/5cf6aae8/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/UserSuspenderImpl.java
----------------------------------------------------------------------
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/UserSuspenderImpl.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/UserSuspenderImpl.java
deleted file mode 100644
index 7ff9e84..0000000
--- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/UserSuspenderImpl.java
+++ /dev/null
@@ -1,51 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.syncope.core.provisioning.java;
-
-import org.apache.syncope.core.persistence.api.entity.user.User;
-import org.apache.syncope.core.provisioning.api.UserSuspender;
-import org.apache.syncope.core.provisioning.api.UserProvisioningManager;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.stereotype.Component;
-
-@Component
-public class UserSuspenderImpl implements UserSuspender {
-
-    private static final Logger LOG = LoggerFactory.getLogger(UserSuspenderImpl.class);
-
-    @Autowired
-    private UserProvisioningManager provisioningManager;
-
-    @Override
-    public void suspend(final User user, final boolean suspend) {
-        try {
-            LOG.debug("User {}:{} is over to max failed logins", user.getKey(), user.getUsername());
-
-            // reduce failed logins number to avoid multiple request
-            user.setFailedLogins(user.getFailedLogins() - 1);
-
-            // disable user and propagate suspension if and only if it is required by policy          
-            provisioningManager.innerSuspend(user, suspend);
-        } catch (Exception e) {
-            LOG.error("Error during user suspension", e);
-        }
-    }
-}

http://git-wip-us.apache.org/repos/asf/syncope/blob/5cf6aae8/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/UserDataBinderImpl.java
----------------------------------------------------------------------
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/UserDataBinderImpl.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/UserDataBinderImpl.java
index f52b941..459c052 100644
--- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/UserDataBinderImpl.java
+++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/UserDataBinderImpl.java
@@ -88,7 +88,7 @@ public class UserDataBinderImpl extends AbstractAnyDataBinder implements UserDat
     public UserTO getAuthenticatedUserTO() {
         final UserTO authUserTO;
 
-        final String authUsername = AuthContextUtils.getUsername();
+        String authUsername = AuthContextUtils.getUsername();
         if (anonymousUser.equals(authUsername)) {
             authUserTO = new UserTO();
             authUserTO.setKey(-2);

http://git-wip-us.apache.org/repos/asf/syncope/blob/5cf6aae8/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/UserServiceImpl.java
----------------------------------------------------------------------
diff --git a/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/UserServiceImpl.java b/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/UserServiceImpl.java
index 391aea8..2447697 100644
--- a/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/UserServiceImpl.java
+++ b/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/UserServiceImpl.java
@@ -62,12 +62,11 @@ public class UserServiceImpl extends AbstractAnyService<UserTO, UserMod> impleme
     }
 
     @Override
-    public Response status(final Long key, final StatusMod statusMod) {
-        UserTO user = logic.read(key);
+    public Response status(final StatusMod statusMod) {
+        UserTO user = logic.read(statusMod.getKey());
 
         checkETag(user.getETagValue());
 
-        statusMod.setKey(key);
         UserTO updated = logic.status(statusMod);
         return modificationResponse(updated);
     }

http://git-wip-us.apache.org/repos/asf/syncope/blob/5cf6aae8/core/workflow-activiti/src/main/java/org/apache/syncope/core/workflow/activiti/ActivitiUserWorkflowAdapter.java
----------------------------------------------------------------------
diff --git a/core/workflow-activiti/src/main/java/org/apache/syncope/core/workflow/activiti/ActivitiUserWorkflowAdapter.java b/core/workflow-activiti/src/main/java/org/apache/syncope/core/workflow/activiti/ActivitiUserWorkflowAdapter.java
index 1ce0d97..7a4ba38 100644
--- a/core/workflow-activiti/src/main/java/org/apache/syncope/core/workflow/activiti/ActivitiUserWorkflowAdapter.java
+++ b/core/workflow-activiti/src/main/java/org/apache/syncope/core/workflow/activiti/ActivitiUserWorkflowAdapter.java
@@ -74,8 +74,6 @@ import org.apache.syncope.core.provisioning.api.data.UserDataBinder;
 import org.apache.syncope.core.workflow.api.WorkflowDefinitionFormat;
 import org.apache.syncope.core.workflow.api.WorkflowException;
 import org.apache.syncope.core.workflow.java.AbstractUserWorkflowAdapter;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.transaction.annotation.Transactional;
 
@@ -84,8 +82,6 @@ import org.springframework.transaction.annotation.Transactional;
  */
 public class ActivitiUserWorkflowAdapter extends AbstractUserWorkflowAdapter {
 
-    protected static final Logger LOG = LoggerFactory.getLogger(ActivitiUserWorkflowAdapter.class);
-
     protected static final String[] PROPERTY_IGNORE_PROPS = { "type" };
 
     public static final String WF_PROCESS_ID = "userWorkflow";
@@ -279,7 +275,7 @@ public class ActivitiUserWorkflowAdapter extends AbstractUserWorkflowAdapter {
     protected Set<String> doExecuteTask(final User user, final String task, final Map<String, Object> moreVariables) {
         Set<String> preTasks = getPerformedTasks(user);
 
-        final Map<String, Object> variables = new HashMap<>();
+        Map<String, Object> variables = new HashMap<>();
         variables.put(WF_EXECUTOR, AuthContextUtils.getUsername());
         variables.put(TASK, task);
 
@@ -345,7 +341,6 @@ public class ActivitiUserWorkflowAdapter extends AbstractUserWorkflowAdapter {
     }
 
     @Override
-    @Transactional(rollbackFor = { Throwable.class })
     protected WorkflowResult<Long> doSuspend(final User user) {
         Set<String> performedTasks = doExecuteTask(user, "suspend", null);
         updateStatus(user);
@@ -661,7 +656,7 @@ public class ActivitiUserWorkflowAdapter extends AbstractUserWorkflowAdapter {
     public List<WorkflowFormTO> getForms() {
         List<WorkflowFormTO> forms = new ArrayList<>();
 
-        final String authUser = AuthContextUtils.getUsername();
+        String authUser = AuthContextUtils.getUsername();
         if (adminUser.equals(authUser)) {
             forms.addAll(getForms(engine.getTaskService().createTaskQuery().
                     taskVariableValueEquals(TASK_IS_FORM, Boolean.TRUE)));
@@ -772,10 +767,9 @@ public class ActivitiUserWorkflowAdapter extends AbstractUserWorkflowAdapter {
         return new ImmutablePair<>(task, formData);
     }
 
-    @Transactional
     @Override
     public WorkflowFormTO claimForm(final String taskId) {
-        final String authUser = AuthContextUtils.getUsername();
+        String authUser = AuthContextUtils.getUsername();
         Pair<Task, TaskFormData> checked = checkTask(taskId, authUser);
 
         if (!adminUser.equals(authUser)) {
@@ -798,10 +792,9 @@ public class ActivitiUserWorkflowAdapter extends AbstractUserWorkflowAdapter {
         return getFormTO(task, checked.getValue());
     }
 
-    @Transactional
     @Override
     public WorkflowResult<UserMod> submitForm(final WorkflowFormTO form) {
-        final String authUser = AuthContextUtils.getUsername();
+        String authUser = AuthContextUtils.getUsername();
         Pair<Task, TaskFormData> checked = checkTask(form.getTaskId(), authUser);
 
         if (!checked.getKey().getOwner().equals(authUser)) {

http://git-wip-us.apache.org/repos/asf/syncope/blob/5cf6aae8/core/workflow-api/src/main/java/org/apache/syncope/core/workflow/api/UserWorkflowAdapter.java
----------------------------------------------------------------------
diff --git a/core/workflow-api/src/main/java/org/apache/syncope/core/workflow/api/UserWorkflowAdapter.java b/core/workflow-api/src/main/java/org/apache/syncope/core/workflow/api/UserWorkflowAdapter.java
index fbf29c3..7122b84 100644
--- a/core/workflow-api/src/main/java/org/apache/syncope/core/workflow/api/UserWorkflowAdapter.java
+++ b/core/workflow-api/src/main/java/org/apache/syncope/core/workflow/api/UserWorkflowAdapter.java
@@ -22,7 +22,6 @@ import org.apache.commons.lang3.tuple.Pair;
 import org.apache.syncope.core.provisioning.api.WorkflowResult;
 import org.apache.syncope.common.lib.mod.UserMod;
 import org.apache.syncope.common.lib.to.UserTO;
-import org.apache.syncope.core.persistence.api.entity.user.User;
 
 /**
  * Interface for calling underlying workflow implementations.
@@ -96,12 +95,12 @@ public interface UserWorkflowAdapter extends WorkflowAdapter {
     WorkflowResult<Long> suspend(Long key);
 
     /**
-     * Suspend an user.
+     * Suspend an user (used by internal authentication process)
      *
-     * @param user user to be suspended
-     * @return user just suspended
+     * @param key to be suspended
+     * @return user just suspended and information whether to propagate suspension
      */
-    WorkflowResult<Long> suspend(User user);
+    Pair<WorkflowResult<Long>, Boolean> internalSuspend(Long key);
 
     /**
      * Reactivate an user.

http://git-wip-us.apache.org/repos/asf/syncope/blob/5cf6aae8/core/workflow-java/src/main/java/org/apache/syncope/core/workflow/java/AbstractUserWorkflowAdapter.java
----------------------------------------------------------------------
diff --git a/core/workflow-java/src/main/java/org/apache/syncope/core/workflow/java/AbstractUserWorkflowAdapter.java b/core/workflow-java/src/main/java/org/apache/syncope/core/workflow/java/AbstractUserWorkflowAdapter.java
index ecc1c01..b829137 100644
--- a/core/workflow-java/src/main/java/org/apache/syncope/core/workflow/java/AbstractUserWorkflowAdapter.java
+++ b/core/workflow-java/src/main/java/org/apache/syncope/core/workflow/java/AbstractUserWorkflowAdapter.java
@@ -18,6 +18,7 @@
  */
 package org.apache.syncope.core.workflow.java;
 
+import org.apache.commons.lang3.tuple.ImmutablePair;
 import org.apache.commons.lang3.tuple.Pair;
 import org.apache.syncope.common.lib.mod.UserMod;
 import org.apache.syncope.core.persistence.api.dao.UserDAO;
@@ -28,6 +29,8 @@ import org.apache.syncope.core.provisioning.api.data.UserDataBinder;
 import org.apache.syncope.core.workflow.api.UserWorkflowAdapter;
 import org.identityconnectors.common.Base64;
 import org.identityconnectors.common.security.EncryptorFactory;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.transaction.annotation.Propagation;
 import org.springframework.transaction.annotation.Transactional;
@@ -35,6 +38,8 @@ import org.springframework.transaction.annotation.Transactional;
 @Transactional(propagation = Propagation.REQUIRES_NEW, rollbackFor = { Throwable.class })
 public abstract class AbstractUserWorkflowAdapter implements UserWorkflowAdapter {
 
+    protected static final Logger LOG = LoggerFactory.getLogger(UserWorkflowAdapter.class);
+
     @Autowired
     protected UserDataBinder dataBinder;
 
@@ -62,8 +67,8 @@ public abstract class AbstractUserWorkflowAdapter implements UserWorkflowAdapter
     protected abstract WorkflowResult<Long> doActivate(User user, String token);
 
     @Override
-    public WorkflowResult<Long> activate(final Long userKey, final String token) {
-        return doActivate(userDAO.authFind(userKey), token);
+    public WorkflowResult<Long> activate(final Long key, final String token) {
+        return doActivate(userDAO.authFind(key), token);
     }
 
     protected abstract WorkflowResult<Pair<UserMod, Boolean>> doUpdate(User user, UserMod userMod);
@@ -76,23 +81,42 @@ public abstract class AbstractUserWorkflowAdapter implements UserWorkflowAdapter
     protected abstract WorkflowResult<Long> doSuspend(User user);
 
     @Override
-    public WorkflowResult<Long> suspend(final Long userKey) {
-        return suspend(userDAO.authFind(userKey));
-    }
+    public WorkflowResult<Long> suspend(final Long key) {
+        User user = userDAO.authFind(key);
 
-    @Override
-    public WorkflowResult<Long> suspend(final User user) {
         // set suspended flag
         user.setSuspended(Boolean.TRUE);
 
         return doSuspend(user);
     }
 
+    @Override
+    public Pair<WorkflowResult<Long>, Boolean> internalSuspend(final Long key) {
+        User user = userDAO.authFind(key);
+
+        Pair<WorkflowResult<Long>, Boolean> result = null;
+
+        Pair<Boolean, Boolean> enforce = userDAO.enforcePolicies(user);
+        if (enforce.getKey()) {
+            LOG.debug("User {} {} is over the max failed logins", user.getKey(), user.getUsername());
+
+            // reduce failed logins number to avoid multiple request       
+            user.setFailedLogins(user.getFailedLogins() - 1);
+
+            // set suspended flag
+            user.setSuspended(Boolean.TRUE);
+
+            result = ImmutablePair.of(doSuspend(user), enforce.getValue());
+        }
+
+        return result;
+    }
+
     protected abstract WorkflowResult<Long> doReactivate(User user);
 
     @Override
-    public WorkflowResult<Long> reactivate(final Long userKey) {
-        final User user = userDAO.authFind(userKey);
+    public WorkflowResult<Long> reactivate(final Long key) {
+        User user = userDAO.authFind(key);
 
         // reset failed logins
         user.setFailedLogins(0);
@@ -106,21 +130,21 @@ public abstract class AbstractUserWorkflowAdapter implements UserWorkflowAdapter
     protected abstract void doRequestPasswordReset(User user);
 
     @Override
-    public void requestPasswordReset(final Long userKey) {
-        doRequestPasswordReset(userDAO.authFind(userKey));
+    public void requestPasswordReset(final Long key) {
+        doRequestPasswordReset(userDAO.authFind(key));
     }
 
     protected abstract void doConfirmPasswordReset(User user, String token, String password);
 
     @Override
-    public void confirmPasswordReset(final Long userKey, final String token, final String password) {
-        doConfirmPasswordReset(userDAO.authFind(userKey), token, password);
+    public void confirmPasswordReset(final Long key, final String token, final String password) {
+        doConfirmPasswordReset(userDAO.authFind(key), token, password);
     }
 
     protected abstract void doDelete(User user);
 
     @Override
-    public void delete(final Long userKey) {
-        doDelete(userDAO.authFind(userKey));
+    public void delete(final Long key) {
+        doDelete(userDAO.authFind(key));
     }
 }

http://git-wip-us.apache.org/repos/asf/syncope/blob/5cf6aae8/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/AbstractCamelProvisioningManager.java
----------------------------------------------------------------------
diff --git a/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/AbstractCamelProvisioningManager.java b/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/AbstractCamelProvisioningManager.java
index 516e798..1a6d7df 100644
--- a/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/AbstractCamelProvisioningManager.java
+++ b/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/AbstractCamelProvisioningManager.java
@@ -68,7 +68,7 @@ abstract class AbstractCamelProvisioningManager {
         template.send(uri, exchange);
     }
 
-    protected void sendMessage(final String uri, final Object obj, final Map<String, Object> properties) {
+    protected void sendMessage(final String uri, final Object body, final Map<String, Object> properties) {
         Exchange exchange = new DefaultExchange(getContext());
 
         for (Map.Entry<String, Object> property : properties.entrySet()) {
@@ -77,7 +77,7 @@ abstract class AbstractCamelProvisioningManager {
         }
 
         DefaultMessage message = new DefaultMessage();
-        message.setBody(obj);
+        message.setBody(body);
         exchange.setIn(message);
         ProducerTemplate template = getContext().createProducerTemplate();
         template.send(uri, exchange);

http://git-wip-us.apache.org/repos/asf/syncope/blob/5cf6aae8/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/CamelUserProvisioningManager.java
----------------------------------------------------------------------
diff --git a/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/CamelUserProvisioningManager.java b/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/CamelUserProvisioningManager.java
index 8b5ad89..fa0b84b 100644
--- a/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/CamelUserProvisioningManager.java
+++ b/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/CamelUserProvisioningManager.java
@@ -34,7 +34,6 @@ import org.apache.syncope.common.lib.mod.UserMod;
 import org.apache.syncope.common.lib.to.PropagationStatus;
 import org.apache.syncope.common.lib.to.UserTO;
 import org.apache.syncope.common.lib.types.PropagationByResource;
-import org.apache.syncope.core.persistence.api.entity.user.User;
 import org.apache.syncope.core.provisioning.api.UserProvisioningManager;
 import org.apache.syncope.core.provisioning.api.WorkflowResult;
 import org.apache.syncope.core.provisioning.api.sync.ProvisioningResult;
@@ -319,13 +318,10 @@ public class CamelUserProvisioningManager extends AbstractCamelProvisioningManag
     }
 
     @Override
-    public void innerSuspend(final User user, final boolean propagate) {
-        PollingConsumer pollingConsumer = getConsumer("direct:innerSuspendUserPort");
+    public void internalSuspend(final Long key) {
+        PollingConsumer pollingConsumer = getConsumer("direct:internalSuspendUserPort");
 
-        Map<String, Object> props = new HashMap<>();
-        props.put("propagate", propagate);
-
-        sendMessage("direct:innerSuspendUser", user.getKey(), props);
+        sendMessage("direct:internalSuspendUser", key);
 
         Exchange exchange = pollingConsumer.receive();
 

http://git-wip-us.apache.org/repos/asf/syncope/blob/5cf6aae8/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/processor/UserInnerSuspendProcessor.java
----------------------------------------------------------------------
diff --git a/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/processor/UserInnerSuspendProcessor.java b/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/processor/UserInnerSuspendProcessor.java
deleted file mode 100644
index be3e6ac..0000000
--- a/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/processor/UserInnerSuspendProcessor.java
+++ /dev/null
@@ -1,61 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.syncope.core.provisioning.camel.processor;
-
-import java.util.List;
-import org.apache.camel.Exchange;
-import org.apache.camel.Processor;
-import org.apache.commons.lang3.tuple.ImmutablePair;
-import org.apache.commons.lang3.tuple.Pair;
-import org.apache.syncope.common.lib.mod.UserMod;
-import org.apache.syncope.core.persistence.api.entity.task.PropagationTask;
-import org.apache.syncope.core.provisioning.api.WorkflowResult;
-import org.apache.syncope.core.provisioning.api.propagation.PropagationManager;
-import org.apache.syncope.core.provisioning.api.propagation.PropagationTaskExecutor;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.stereotype.Component;
-
-@Component
-public class UserInnerSuspendProcessor implements Processor {
-
-    @Autowired
-    protected PropagationManager propagationManager;
-
-    @Autowired
-    protected PropagationTaskExecutor taskExecutor;
-
-    @Override
-    public void process(final Exchange exchange) {
-        @SuppressWarnings("unchecked")
-        WorkflowResult<Long> updated = (WorkflowResult) exchange.getIn().getBody();
-        Boolean propagate = exchange.getProperty("propagate", Boolean.class);
-
-        if (propagate) {
-            UserMod userMod = new UserMod();
-            userMod.setKey(updated.getResult());
-
-            List<PropagationTask> tasks = propagationManager.getUserUpdateTasks(
-                    new WorkflowResult<Pair<UserMod, Boolean>>(
-                            new ImmutablePair<>(userMod, Boolean.FALSE),
-                            updated.getPropByRes(), updated.getPerformedTasks()));
-            taskExecutor.execute(tasks);
-        }
-    }
-
-}

http://git-wip-us.apache.org/repos/asf/syncope/blob/5cf6aae8/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/processor/UserInternalSuspendProcessor.java
----------------------------------------------------------------------
diff --git a/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/processor/UserInternalSuspendProcessor.java b/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/processor/UserInternalSuspendProcessor.java
new file mode 100644
index 0000000..73e63ad
--- /dev/null
+++ b/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/processor/UserInternalSuspendProcessor.java
@@ -0,0 +1,61 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.syncope.core.provisioning.camel.processor;
+
+import java.util.List;
+import org.apache.camel.Exchange;
+import org.apache.camel.Processor;
+import org.apache.commons.lang3.tuple.ImmutablePair;
+import org.apache.commons.lang3.tuple.Pair;
+import org.apache.syncope.common.lib.mod.UserMod;
+import org.apache.syncope.core.persistence.api.entity.task.PropagationTask;
+import org.apache.syncope.core.provisioning.api.WorkflowResult;
+import org.apache.syncope.core.provisioning.api.propagation.PropagationManager;
+import org.apache.syncope.core.provisioning.api.propagation.PropagationTaskExecutor;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+
+@Component
+public class UserInternalSuspendProcessor implements Processor {
+
+    @Autowired
+    protected PropagationManager propagationManager;
+
+    @Autowired
+    protected PropagationTaskExecutor taskExecutor;
+
+    @Override
+    public void process(final Exchange exchange) {
+        @SuppressWarnings("unchecked")
+        Pair<WorkflowResult<Long>, Boolean> updated = (Pair) exchange.getIn().getBody();
+
+        // propagate suspension if and only if it is required by policy
+        if (updated != null && updated.getValue()) {
+            UserMod userMod = new UserMod();
+            userMod.setKey(updated.getKey().getResult());
+
+            List<PropagationTask> tasks = propagationManager.getUserUpdateTasks(
+                    new WorkflowResult<Pair<UserMod, Boolean>>(
+                            new ImmutablePair<>(userMod, Boolean.FALSE),
+                            updated.getKey().getPropByRes(), updated.getKey().getPerformedTasks()));
+            taskExecutor.execute(tasks);
+        }
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/5cf6aae8/ext/camel/provisioning-camel/src/main/resources/userRoutes.xml
----------------------------------------------------------------------
diff --git a/ext/camel/provisioning-camel/src/main/resources/userRoutes.xml b/ext/camel/provisioning-camel/src/main/resources/userRoutes.xml
index aca6a46..38e48f3 100644
--- a/ext/camel/provisioning-camel/src/main/resources/userRoutes.xml
+++ b/ext/camel/provisioning-camel/src/main/resources/userRoutes.xml
@@ -198,18 +198,18 @@ under the License.
     <to uri="direct:deprovisionPort"/>              
   </route>
     
-  <route id="innerSuspendUser">
-    <from uri="direct:innerSuspendUser"/>
+  <route id="internalSuspendUser">
+    <from uri="direct:internalSuspendUser"/>
     <doTry>
-      <bean ref="uwfAdapter" method="suspend(${body})"/>
-      <process ref="userInnerSuspendProcessor"/>
-      <to uri="direct:innerSuspendUserPort"/>
+      <bean ref="uwfAdapter" method="internalSuspend(${body})"/>
+      <process ref="userInternalSuspendProcessor"/>
+      <to uri="direct:internalSuspendUserPort"/>
       <doCatch>        
         <exception>java.lang.RuntimeException</exception>
         <handled>
           <constant>false</constant>
         </handled>
-        <to uri="direct:innerSuspendUserPort"/>
+        <to uri="direct:internalSuspendUserPort"/>
       </doCatch>
     </doTry>  
   </route>

http://git-wip-us.apache.org/repos/asf/syncope/blob/5cf6aae8/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/AuthenticationITCase.java
----------------------------------------------------------------------
diff --git a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/AuthenticationITCase.java b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/AuthenticationITCase.java
index 9d810b6..6378631 100644
--- a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/AuthenticationITCase.java
+++ b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/AuthenticationITCase.java
@@ -258,7 +258,7 @@ public class AuthenticationITCase extends AbstractITCase {
         assertEquals(0, getFailedLogins(userService4, userId));
     }
 
-    //@Test
+    @Test
     public void checkUserSuspension() {
         UserTO userTO = UserITCase.getUniqueSampleTO("checkSuspension@syncope.apache.org");
         userTO.setRealm("/odd");
@@ -292,8 +292,9 @@ public class AuthenticationITCase extends AbstractITCase {
         assertReadFails(goodPwdClient);
 
         StatusMod reactivate = new StatusMod();
+        reactivate.setKey(userTO.getKey());
         reactivate.setType(StatusMod.ModType.REACTIVATE);
-        userTO = userService.status(userTO.getKey(), reactivate).readEntity(UserTO.class);
+        userTO = userService.status(reactivate).readEntity(UserTO.class);
         assertNotNull(userTO);
         assertEquals("active", userTO.getStatus());
 

http://git-wip-us.apache.org/repos/asf/syncope/blob/5cf6aae8/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/UserITCase.java
----------------------------------------------------------------------
diff --git a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/UserITCase.java b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/UserITCase.java
index 4cecdf7..048259d 100644
--- a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/UserITCase.java
+++ b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/UserITCase.java
@@ -818,9 +818,10 @@ public class UserITCase extends AbstractITCase {
         assertEquals("created", userTO.getStatus());
 
         StatusMod statusMod = new StatusMod();
+        statusMod.setKey(userTO.getKey());
         statusMod.setType(StatusMod.ModType.ACTIVATE);
         statusMod.setToken(userTO.getToken());
-        userTO = userService.status(userTO.getKey(), statusMod).readEntity(UserTO.class);
+        userTO = userService.status(statusMod).readEntity(UserTO.class);
 
         assertNotNull(userTO);
         assertNull(userTO.getToken());
@@ -844,14 +845,16 @@ public class UserITCase extends AbstractITCase {
                 : "created", userTO.getStatus());
 
         StatusMod statusMod = new StatusMod();
+        statusMod.setKey(userTO.getKey());
         statusMod.setType(StatusMod.ModType.SUSPEND);
-        userTO = userService.status(userTO.getKey(), statusMod).readEntity(UserTO.class);
+        userTO = userService.status(statusMod).readEntity(UserTO.class);
         assertNotNull(userTO);
         assertEquals("suspended", userTO.getStatus());
 
         statusMod = new StatusMod();
+        statusMod.setKey(userTO.getKey());
         statusMod.setType(StatusMod.ModType.REACTIVATE);
-        userTO = userService.status(userTO.getKey(), statusMod).readEntity(UserTO.class);
+        userTO = userService.status(statusMod).readEntity(UserTO.class);
         assertNotNull(userTO);
         assertEquals("active", userTO.getStatus());
     }
@@ -875,50 +878,53 @@ public class UserITCase extends AbstractITCase {
         assertEquals(ActivitiDetector.isActivitiEnabledForUsers(syncopeService)
                 ? "active"
                 : "created", userTO.getStatus());
-        long userId = userTO.getKey();
+        long userKey = userTO.getKey();
 
         // Suspend with effect on syncope, ldap and db => user should be suspended in syncope and all resources
         StatusMod statusMod = new StatusMod();
+        statusMod.setKey(userKey);
         statusMod.setType(StatusMod.ModType.SUSPEND);
         statusMod.setOnSyncope(true);
         statusMod.getResourceNames().add(RESOURCE_NAME_TESTDB);
         statusMod.getResourceNames().add(RESOURCE_NAME_LDAP);
-        userTO = userService.status(userId, statusMod).readEntity(UserTO.class);
+        userTO = userService.status(statusMod).readEntity(UserTO.class);
         assertNotNull(userTO);
         assertEquals("suspended", userTO.getStatus());
 
         ConnObjectTO connObjectTO =
-                resourceService.readConnObject(RESOURCE_NAME_TESTDB, AnyTypeKind.USER.name(), userId);
+                resourceService.readConnObject(RESOURCE_NAME_TESTDB, AnyTypeKind.USER.name(), userKey);
         assertFalse(getBooleanAttribute(connObjectTO, OperationalAttributes.ENABLE_NAME));
 
-        connObjectTO = resourceService.readConnObject(RESOURCE_NAME_LDAP, AnyTypeKind.USER.name(), userId);
+        connObjectTO = resourceService.readConnObject(RESOURCE_NAME_LDAP, AnyTypeKind.USER.name(), userKey);
         assertNotNull(connObjectTO);
 
         // Suspend and reactivate only on ldap => db and syncope should still show suspended
         statusMod = new StatusMod();
+        statusMod.setKey(userKey);
         statusMod.setType(StatusMod.ModType.SUSPEND);
         statusMod.setOnSyncope(false);
         statusMod.getResourceNames().add(RESOURCE_NAME_LDAP);
-        userService.status(userId, statusMod);
+        userService.status(statusMod);
         statusMod.setType(StatusMod.ModType.REACTIVATE);
-        userTO = userService.status(userId, statusMod).readEntity(UserTO.class);
+        userTO = userService.status(statusMod).readEntity(UserTO.class);
         assertNotNull(userTO);
         assertEquals("suspended", userTO.getStatus());
 
-        connObjectTO = resourceService.readConnObject(RESOURCE_NAME_TESTDB, AnyTypeKind.USER.name(), userId);
+        connObjectTO = resourceService.readConnObject(RESOURCE_NAME_TESTDB, AnyTypeKind.USER.name(), userKey);
         assertFalse(getBooleanAttribute(connObjectTO, OperationalAttributes.ENABLE_NAME));
 
         // Reactivate on syncope and db => syncope and db should show the user as active
         statusMod = new StatusMod();
+        statusMod.setKey(userKey);
         statusMod.setType(StatusMod.ModType.REACTIVATE);
         statusMod.setOnSyncope(true);
         statusMod.getResourceNames().add(RESOURCE_NAME_TESTDB);
 
-        userTO = userService.status(userId, statusMod).readEntity(UserTO.class);
+        userTO = userService.status(statusMod).readEntity(UserTO.class);
         assertNotNull(userTO);
         assertEquals("active", userTO.getStatus());
 
-        connObjectTO = resourceService.readConnObject(RESOURCE_NAME_TESTDB, AnyTypeKind.USER.name(), userId);
+        connObjectTO = resourceService.readConnObject(RESOURCE_NAME_TESTDB, AnyTypeKind.USER.name(), userKey);
         assertTrue(getBooleanAttribute(connObjectTO, OperationalAttributes.ENABLE_NAME));
     }
 
@@ -1795,7 +1801,8 @@ public class UserITCase extends AbstractITCase {
         final ResourceAssociationMod associationMod = new ResourceAssociationMod();
         associationMod.getTargetResources().addAll(CollectionWrapper.wrap(RESOURCE_NAME_CSV, ResourceKey.class));
 
-        assertNotNull(userService.associate(actual.getKey(), ResourceAssociationAction.LINK, associationMod).readEntity(BulkActionResult.class));
+        assertNotNull(userService.associate(actual.getKey(), ResourceAssociationAction.LINK, associationMod).readEntity(
+                BulkActionResult.class));
 
         actual = userService.read(actual.getKey());
         assertNotNull(actual);


[03/31] syncope git commit: [SYNCOPE-652] Preliminary work (still struggling with OpenJPA slices)

Posted by md...@apache.org.
http://git-wip-us.apache.org/repos/asf/syncope/blob/252b1510/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/data/DomainDataBinder.java
----------------------------------------------------------------------
diff --git a/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/data/DomainDataBinder.java b/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/data/DomainDataBinder.java
new file mode 100644
index 0000000..0b85441
--- /dev/null
+++ b/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/data/DomainDataBinder.java
@@ -0,0 +1,31 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.syncope.core.provisioning.api.data;
+
+import org.apache.syncope.common.lib.to.DomainTO;
+import org.apache.syncope.core.persistence.api.entity.Domain;
+
+public interface DomainDataBinder {
+
+    Domain create(DomainTO domainTO);
+
+    void update(Domain domain, DomainTO domainTO);
+
+    DomainTO getDomainTO(Domain domain);
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/252b1510/core/provisioning-java/pom.xml
----------------------------------------------------------------------
diff --git a/core/provisioning-java/pom.xml b/core/provisioning-java/pom.xml
index 200ae0a..a1dc161 100644
--- a/core/provisioning-java/pom.xml
+++ b/core/provisioning-java/pom.xml
@@ -38,6 +38,12 @@ under the License.
   </properties>
 
   <dependencies>
+    <dependency> 
+      <groupId>javax.servlet</groupId> 
+      <artifactId>javax.servlet-api</artifactId> 
+      <scope>provided</scope>
+    </dependency>
+
     <dependency>
       <groupId>org.springframework</groupId>
       <artifactId>spring-context-support</artifactId>

http://git-wip-us.apache.org/repos/asf/syncope/blob/252b1510/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/DomainDataBinderImpl.java
----------------------------------------------------------------------
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/DomainDataBinderImpl.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/DomainDataBinderImpl.java
new file mode 100644
index 0000000..4ef408c
--- /dev/null
+++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/DomainDataBinderImpl.java
@@ -0,0 +1,70 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.syncope.core.provisioning.java.data;
+
+import org.apache.commons.lang3.StringUtils;
+import org.apache.syncope.common.lib.SyncopeClientException;
+import org.apache.syncope.common.lib.to.DomainTO;
+import org.apache.syncope.common.lib.types.ClientExceptionType;
+import org.apache.syncope.core.persistence.api.entity.EntityFactory;
+import org.apache.syncope.core.persistence.api.entity.Domain;
+import org.apache.syncope.core.provisioning.api.data.DomainDataBinder;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+
+@Component
+public class DomainDataBinderImpl implements DomainDataBinder {
+
+    @Autowired
+    private EntityFactory entityFactory;
+
+    @Override
+    public Domain create(final DomainTO domainTO) {
+        Domain domain = entityFactory.newEntity(Domain.class);
+        update(domain, domainTO);
+        return domain;
+    }
+
+    @Override
+    public void update(final Domain domain, final DomainTO domainTO) {
+        if (domain.getKey() == null) {
+            domain.setKey(domainTO.getKey());
+        }
+
+        if (StringUtils.isBlank(domainTO.getAdminPwd()) || domainTO.getAdminCipherAlgorithm() == null) {
+            SyncopeClientException sce = SyncopeClientException.build(ClientExceptionType.RequiredValuesMissing);
+            sce.getElements().add("Actual password value and / or cipher algorithm");
+        }
+
+        domain.setPassword(domainTO.getAdminPwd(), domainTO.getAdminCipherAlgorithm());
+    }
+
+    @Override
+    public DomainTO getDomainTO(final Domain domain) {
+        DomainTO domainTO = new DomainTO();
+
+        domainTO.setKey(domain.getKey());
+
+        domainTO.setAdminCipherAlgorithm(domain.getAdminCipherAlgorithm());
+        domainTO.setAdminPwd(domainTO.getAdminPwd());
+
+        return domainTO;
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/252b1510/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/UserDataBinderImpl.java
----------------------------------------------------------------------
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/UserDataBinderImpl.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/UserDataBinderImpl.java
index b0fb8b0..f52b941 100644
--- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/UserDataBinderImpl.java
+++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/UserDataBinderImpl.java
@@ -88,7 +88,7 @@ public class UserDataBinderImpl extends AbstractAnyDataBinder implements UserDat
     public UserTO getAuthenticatedUserTO() {
         final UserTO authUserTO;
 
-        final String authUsername = AuthContextUtils.getAuthenticatedUsername();
+        final String authUsername = AuthContextUtils.getUsername();
         if (anonymousUser.equals(authUsername)) {
             authUserTO = new UserTO();
             authUserTO.setKey(-2);
@@ -244,8 +244,12 @@ public class UserDataBinderImpl extends AbstractAnyDataBinder implements UserDat
         if (userMod.getUsername() != null && !userMod.getUsername().equals(user.getUsername())) {
             propByRes.addAll(ResourceOperation.UPDATE, currentResources);
 
+            String oldUsername = user.getUsername();
             user.setUsername(userMod.getUsername());
-            AuthContextUtils.updateAuthenticatedUsername(userMod.getUsername());
+
+            if (oldUsername.equals(AuthContextUtils.getUsername())) {
+                AuthContextUtils.updateUsername(userMod.getUsername());
+            }
         }
 
         // security question / answer:

http://git-wip-us.apache.org/repos/asf/syncope/blob/252b1510/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/sync/AbstractProvisioningJob.java
----------------------------------------------------------------------
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/sync/AbstractProvisioningJob.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/sync/AbstractProvisioningJob.java
index 8f80ac0..34ca299 100644
--- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/sync/AbstractProvisioningJob.java
+++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/sync/AbstractProvisioningJob.java
@@ -24,11 +24,13 @@ import java.lang.reflect.ParameterizedType;
 import java.util.ArrayList;
 import java.util.Collection;
 import java.util.List;
+import javax.annotation.Resource;
 import org.apache.commons.collections4.CollectionUtils;
 import org.apache.commons.collections4.Transformer;
 import org.apache.syncope.common.lib.SyncopeConstants;
 import org.apache.syncope.common.lib.types.Entitlement;
 import org.apache.syncope.common.lib.types.TraceLevel;
+import org.apache.syncope.core.misc.security.SyncopeAuthenticationDetails;
 import org.apache.syncope.core.misc.security.SyncopeGrantedAuthority;
 import org.apache.syncope.core.persistence.api.dao.AnyTypeDAO;
 import org.apache.syncope.core.persistence.api.dao.ExternalResourceDAO;
@@ -49,7 +51,6 @@ import org.springframework.security.authentication.UsernamePasswordAuthenticatio
 import org.springframework.security.core.GrantedAuthority;
 import org.springframework.security.core.context.SecurityContextHolder;
 import org.springframework.security.core.userdetails.User;
-import org.springframework.security.core.userdetails.UserDetails;
 
 /**
  * Job for executing synchronization tasks.
@@ -61,6 +62,9 @@ import org.springframework.security.core.userdetails.UserDetails;
 public abstract class AbstractProvisioningJob<T extends ProvisioningTask, A extends ProvisioningActions>
         extends AbstractTaskJob {
 
+    @Resource(name = "adminUser")
+    protected String adminUser;
+
     /**
      * ConnInstance loader.
      */
@@ -404,10 +408,10 @@ public abstract class AbstractProvisioningJob<T extends ProvisioningTask, A exte
                     }
                 }, new ArrayList<GrantedAuthority>());
 
-        UserDetails userDetails = new User("admin", "FAKE_PASSWORD", authorities);
-
-        SecurityContextHolder.getContext().setAuthentication(
-                new UsernamePasswordAuthenticationToken(userDetails, "FAKE_PASSWORD", authorities));
+        UsernamePasswordAuthenticationToken auth = new UsernamePasswordAuthenticationToken(
+                new User(adminUser, "FAKE_PASSWORD", authorities), "FAKE_PASSWORD", authorities);
+        auth.setDetails(new SyncopeAuthenticationDetails(taskDAO.getDomain(task)));
+        SecurityContextHolder.getContext().setAuthentication(auth);
 
         try {
             Class<T> clazz = getTaskClassReference();
@@ -415,16 +419,14 @@ public abstract class AbstractProvisioningJob<T extends ProvisioningTask, A exte
                 throw new JobExecutionException("Task " + taskId + " isn't a SyncTask");
             }
 
-            T provisioningTask = clazz.cast(this.task);
+            T provisioningTask = clazz.cast(task);
 
             Connector connector;
             try {
                 connector = connFactory.getConnector(provisioningTask.getResource());
             } catch (Exception e) {
-                final String msg = String.
-                        format("Connector instance bean for resource %s and connInstance %s not found",
-                                provisioningTask.getResource(), provisioningTask.getResource().getConnector());
-
+                String msg = String.format("Connector instance bean for resource %s and connInstance %s not found",
+                        provisioningTask.getResource(), provisioningTask.getResource().getConnector());
                 throw new JobExecutionException(msg, e);
             }
 

http://git-wip-us.apache.org/repos/asf/syncope/blob/252b1510/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/AddDomainFilter.java
----------------------------------------------------------------------
diff --git a/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/AddDomainFilter.java b/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/AddDomainFilter.java
new file mode 100644
index 0000000..1ae087a
--- /dev/null
+++ b/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/AddDomainFilter.java
@@ -0,0 +1,39 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.syncope.core.rest.cxf;
+
+import java.io.IOException;
+import javax.ws.rs.container.ContainerRequestContext;
+import javax.ws.rs.container.ContainerResponseContext;
+import javax.ws.rs.container.ContainerResponseFilter;
+import javax.ws.rs.ext.Provider;
+import org.apache.syncope.common.rest.api.RESTHeaders;
+import org.apache.syncope.core.misc.security.AuthContextUtils;
+
+/**
+ * Adds the domain header to all responses.
+ */
+@Provider
+public class AddDomainFilter implements ContainerResponseFilter {
+
+    @Override
+    public void filter(final ContainerRequestContext reqCtx, final ContainerResponseContext resCtx) throws IOException {
+        resCtx.getHeaders().add(RESTHeaders.DOMAIN, AuthContextUtils.getDomain());
+    }
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/252b1510/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/AddETagFilter.java
----------------------------------------------------------------------
diff --git a/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/AddETagFilter.java b/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/AddETagFilter.java
new file mode 100644
index 0000000..31c4d69
--- /dev/null
+++ b/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/AddETagFilter.java
@@ -0,0 +1,48 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.syncope.core.rest.cxf;
+
+import java.io.IOException;
+import javax.ws.rs.container.ContainerRequestContext;
+import javax.ws.rs.container.ContainerResponseContext;
+import javax.ws.rs.container.ContainerResponseFilter;
+import javax.ws.rs.core.EntityTag;
+import javax.ws.rs.core.HttpHeaders;
+import javax.ws.rs.ext.Provider;
+import org.apache.commons.lang3.StringUtils;
+import org.apache.syncope.common.lib.to.AbstractAnnotatedBean;
+
+/**
+ * Adds the <tt>ETag</tt> header to any response containing an instance of {@link AbstractAnnotatedBean} as entity.
+ * The actual ETag value is computed on the basis of last change date (or creation date if not available).
+ */
+@Provider
+public class AddETagFilter implements ContainerResponseFilter {
+
+    @Override
+    public void filter(final ContainerRequestContext reqCtx, final ContainerResponseContext resCtx) throws IOException {
+        if (resCtx.getEntity() instanceof AbstractAnnotatedBean && resCtx.getEntityTag() == null) {
+            AbstractAnnotatedBean sysInfo = (AbstractAnnotatedBean) resCtx.getEntity();
+            String etagValue = sysInfo.getETagValue();
+            if (StringUtils.isNotBlank(etagValue)) {
+                resCtx.getHeaders().add(HttpHeaders.ETAG, new EntityTag(etagValue).toString());
+            }
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/252b1510/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/AddETagFilter.java
----------------------------------------------------------------------
diff --git a/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/AddETagFilter.java b/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/AddETagFilter.java
deleted file mode 100644
index bdb40ac..0000000
--- a/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/AddETagFilter.java
+++ /dev/null
@@ -1,50 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.syncope.core.rest.cxf.service;
-
-import java.io.IOException;
-import javax.ws.rs.container.ContainerRequestContext;
-import javax.ws.rs.container.ContainerResponseContext;
-import javax.ws.rs.container.ContainerResponseFilter;
-import javax.ws.rs.core.EntityTag;
-import javax.ws.rs.core.HttpHeaders;
-import javax.ws.rs.ext.Provider;
-import org.apache.commons.lang3.StringUtils;
-import org.apache.syncope.common.lib.to.AbstractAnnotatedBean;
-
-/**
- * Adds the <tt>ETag</tt> filter to any response containing an instance of <tt>AbstractSysInfoTO</tt> as entity.
- * The actual ETag value is computed on the basis of last change date (or creation date if not available).
- *
- * @see AbstractSysInfoTO
- */
-@Provider
-public class AddETagFilter implements ContainerResponseFilter {
-
-    @Override
-    public void filter(final ContainerRequestContext reqCtx, final ContainerResponseContext resCtx) throws IOException {
-        if (resCtx.getEntity() instanceof AbstractAnnotatedBean && resCtx.getEntityTag() == null) {
-            AbstractAnnotatedBean sysInfo = (AbstractAnnotatedBean) resCtx.getEntity();
-            String etagValue = sysInfo.getETagValue();
-            if (StringUtils.isNotBlank(etagValue)) {
-                resCtx.getHeaders().add(HttpHeaders.ETAG, new EntityTag(etagValue).toString());
-            }
-        }
-    }
-}

http://git-wip-us.apache.org/repos/asf/syncope/blob/252b1510/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/DomainServiceImpl.java
----------------------------------------------------------------------
diff --git a/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/DomainServiceImpl.java b/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/DomainServiceImpl.java
new file mode 100644
index 0000000..6632424
--- /dev/null
+++ b/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/DomainServiceImpl.java
@@ -0,0 +1,66 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.syncope.core.rest.cxf.service;
+
+import java.net.URI;
+import java.util.List;
+import javax.ws.rs.core.Response;
+import org.apache.syncope.common.lib.to.DomainTO;
+import org.apache.syncope.common.rest.api.RESTHeaders;
+import org.apache.syncope.common.rest.api.service.DomainService;
+import org.apache.syncope.core.logic.DomainLogic;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+@Service
+public class DomainServiceImpl extends AbstractServiceImpl implements DomainService {
+
+    @Autowired
+    private DomainLogic logic;
+
+    @Override
+    public List<DomainTO> list() {
+        return logic.list();
+    }
+
+    @Override
+    public DomainTO read(final String key) {
+        return logic.read(key);
+    }
+
+    @Override
+    public Response create(final DomainTO anyTypeTO) {
+        DomainTO created = logic.create(anyTypeTO);
+        URI location = uriInfo.getAbsolutePathBuilder().path(String.valueOf(created.getKey())).build();
+        return Response.created(location).
+                header(RESTHeaders.RESOURCE_KEY, created.getKey()).
+                build();
+    }
+
+    @Override
+    public void update(final DomainTO anyTypeTO) {
+        logic.update(anyTypeTO);
+    }
+
+    @Override
+    public void delete(final String key) {
+        logic.delete(key);
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/252b1510/core/rest-cxf/src/main/resources/restCXFContext.xml
----------------------------------------------------------------------
diff --git a/core/rest-cxf/src/main/resources/restCXFContext.xml b/core/rest-cxf/src/main/resources/restCXFContext.xml
index c6a472e..5818422 100644
--- a/core/rest-cxf/src/main/resources/restCXFContext.xml
+++ b/core/rest-cxf/src/main/resources/restCXFContext.xml
@@ -88,9 +88,10 @@ under the License.
     <property name="javaDocPath" value="/WEB-INF/lib/syncope-common-rest-api-${syncope.version}-javadoc.jar"/>
   </bean>
   
-  <bean id="addETagFilter" class="org.apache.syncope.core.rest.cxf.service.AddETagFilter"/>
+  <bean id="addDomainFilter" class="org.apache.syncope.core.rest.cxf.AddDomainFilter"/>
+  <bean id="addETagFilter" class="org.apache.syncope.core.rest.cxf.AddETagFilter"/>
   
-  <jaxrs:server id="restContainer" address="/" 
+  <jaxrs:server id="restContainer" address="/"
                 basePackages="org.apache.syncope.common.rest.api.service, org.apache.syncope.core.rest.cxf.service" 
                 staticSubresourceResolution="true">
     <jaxrs:properties> 
@@ -108,6 +109,7 @@ under the License.
       <ref bean="exceptionMapper"/>
       <ref bean="searchContextProvider"/>
       <ref bean="wadlGenerator"/>
+      <ref bean="addDomainFilter"/>
       <ref bean="addETagFilter"/>
     </jaxrs:providers>
     <jaxrs:extensionMappings>

http://git-wip-us.apache.org/repos/asf/syncope/blob/252b1510/core/workflow-activiti/src/main/java/org/apache/syncope/core/workflow/activiti/ActivitiUserWorkflowAdapter.java
----------------------------------------------------------------------
diff --git a/core/workflow-activiti/src/main/java/org/apache/syncope/core/workflow/activiti/ActivitiUserWorkflowAdapter.java b/core/workflow-activiti/src/main/java/org/apache/syncope/core/workflow/activiti/ActivitiUserWorkflowAdapter.java
index 11bfce0..c124c05 100644
--- a/core/workflow-activiti/src/main/java/org/apache/syncope/core/workflow/activiti/ActivitiUserWorkflowAdapter.java
+++ b/core/workflow-activiti/src/main/java/org/apache/syncope/core/workflow/activiti/ActivitiUserWorkflowAdapter.java
@@ -252,7 +252,7 @@ public class ActivitiUserWorkflowAdapter extends AbstractUserWorkflowAdapter {
             final Boolean enabled, final boolean storePassword) {
 
         Map<String, Object> variables = new HashMap<>();
-        variables.put(WF_EXECUTOR, AuthContextUtils.getAuthenticatedUsername());
+        variables.put(WF_EXECUTOR, AuthContextUtils.getUsername());
         variables.put(USER_TO, userTO);
         variables.put(ENABLED, enabled);
         variables.put(STORE_PASSWORD, storePassword);
@@ -299,7 +299,7 @@ public class ActivitiUserWorkflowAdapter extends AbstractUserWorkflowAdapter {
         Set<String> preTasks = getPerformedTasks(user);
 
         final Map<String, Object> variables = new HashMap<>();
-        variables.put(WF_EXECUTOR, AuthContextUtils.getAuthenticatedUsername());
+        variables.put(WF_EXECUTOR, AuthContextUtils.getUsername());
         variables.put(TASK, task);
 
         // using BeanUtils to access all user's properties and trigger lazy loading - we are about to
@@ -674,7 +674,7 @@ public class ActivitiUserWorkflowAdapter extends AbstractUserWorkflowAdapter {
     public List<WorkflowFormTO> getForms() {
         List<WorkflowFormTO> forms = new ArrayList<>();
 
-        final String authUser = AuthContextUtils.getAuthenticatedUsername();
+        final String authUser = AuthContextUtils.getUsername();
         if (adminUser.equals(authUser)) {
             forms.addAll(getForms(taskService.createTaskQuery().
                     taskVariableValueEquals(TASK_IS_FORM, Boolean.TRUE)));
@@ -788,7 +788,7 @@ public class ActivitiUserWorkflowAdapter extends AbstractUserWorkflowAdapter {
     @Transactional
     @Override
     public WorkflowFormTO claimForm(final String taskId) {
-        final String authUser = AuthContextUtils.getAuthenticatedUsername();
+        final String authUser = AuthContextUtils.getUsername();
         Pair<Task, TaskFormData> checked = checkTask(taskId, authUser);
 
         if (!adminUser.equals(authUser)) {
@@ -813,7 +813,7 @@ public class ActivitiUserWorkflowAdapter extends AbstractUserWorkflowAdapter {
     @Transactional
     @Override
     public WorkflowResult<UserMod> submitForm(final WorkflowFormTO form) {
-        final String authUser = AuthContextUtils.getAuthenticatedUsername();
+        final String authUser = AuthContextUtils.getUsername();
         Pair<Task, TaskFormData> checked = checkTask(form.getTaskId(), authUser);
 
         if (!checked.getKey().getOwner().equals(authUser)) {

http://git-wip-us.apache.org/repos/asf/syncope/blob/252b1510/fit/core-reference/pom.xml
----------------------------------------------------------------------
diff --git a/fit/core-reference/pom.xml b/fit/core-reference/pom.xml
index d9716ec..166a394 100644
--- a/fit/core-reference/pom.xml
+++ b/fit/core-reference/pom.xml
@@ -261,7 +261,7 @@ under the License.
             </deployable>
             <deployable>
               <location>${project.build.directory}/${project.build.finalName}</location>
-              <pingURL>http://localhost:${cargo.servlet.port}/syncope/cacheStats.jsp</pingURL>
+              <pingURL>http://localhost:${cargo.servlet.port}/syncope/db.jsp</pingURL>
               <pingTimeout>60000</pingTimeout>
               <properties>
                 <context>syncope</context>

http://git-wip-us.apache.org/repos/asf/syncope/blob/252b1510/pom.xml
----------------------------------------------------------------------
diff --git a/pom.xml b/pom.xml
index 26e5754..7d722b3 100644
--- a/pom.xml
+++ b/pom.xml
@@ -335,7 +335,7 @@ under the License.
     <spring.version>4.1.7.RELEASE</spring.version>
     <spring-security.version>4.0.2.RELEASE</spring-security.version>
 
-    <openjpa.version>2.4.0</openjpa.version>
+    <openjpa.version>2.4.1-SNAPSHOT</openjpa.version>
     <commons-dbcp.version>2.1</commons-dbcp.version>
     <hibernate-validator.version>5.2.1.Final</hibernate-validator.version>
 
@@ -533,7 +533,12 @@ under the License.
         <artifactId>openjpa-persistence-jdbc</artifactId>
         <version>${openjpa.version}</version>
       </dependency>
-
+      <dependency>
+        <groupId>org.apache.openjpa</groupId>
+        <artifactId>openjpa-slice</artifactId>
+        <version>${openjpa.version}</version>
+      </dependency>
+    
       <dependency>
         <groupId>org.apache.commons</groupId>
         <artifactId>commons-dbcp2</artifactId>


[15/31] syncope git commit: [SYNCOPE-652] Still several things to refine, but it starts taking shape

Posted by md...@apache.org.
http://git-wip-us.apache.org/repos/asf/syncope/blob/6dfedd8f/core/persistence-jpa/src/test/resources/content.xml
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/test/resources/content.xml b/core/persistence-jpa/src/test/resources/content.xml
deleted file mode 100644
index ffbd42f..0000000
--- a/core/persistence-jpa/src/test/resources/content.xml
+++ /dev/null
@@ -1,1138 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
-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.
--->
-<dataset>
-  <SyncopeConf id="1" 
-               creator="admin" lastModifier="admin"
-               creationDate="2014-06-20 11:00:00" lastChangeDate="2014-06-20 11:00:00"/>
-
-  <PlainSchema name="password.cipher.algorithm" type="String"
-               mandatoryCondition="true" multivalue="0" uniqueConstraint="0" readonly="0"/>
-  <CPlainAttr id="1" owner_id="1" schema_name="password.cipher.algorithm"/>
-  <CPlainAttrValue id="1" attribute_id="1" stringValue="SHA1"/>
-
-  <!-- notificationjob.cronExpression:
-  + not existing: NotificationJob runs according to Notification.DEFAULT_CRON_EXP
-  + provided as empty string: NotificationJob disabled
-  + provided as non-empty string: NotificationJob runs according to the given value -->
-  <PlainSchema name="notificationjob.cronExpression" type="String"
-               mandatoryCondition="false" multivalue="0" uniqueConstraint="0" readonly="0"/>
-  <CPlainAttr id="2" owner_id="1" schema_name="notificationjob.cronExpression"/>
-  <CPlainAttrValue id="2" attribute_id="2" stringValue=""/>
-  
-  <PlainSchema name="notification.maxRetries" type="Long"
-               mandatoryCondition="true" multivalue="0" uniqueConstraint="0" readonly="0"/>
-  <CPlainAttr id="3" owner_id="1" schema_name="notification.maxRetries"/>
-  <CPlainAttrValue id="3" attribute_id="3" longValue="3"/>
-
-  <PlainSchema name="token.length" type="Long"
-               mandatoryCondition="true" multivalue="0" uniqueConstraint="0" readonly="0"/>
-  <CPlainAttr id="4" owner_id="1" schema_name="token.length"/>
-  <CPlainAttrValue id="4" attribute_id="4" longValue="256"/>
-
-  <PlainSchema name="token.expireTime" type="Long"
-               mandatoryCondition="true" multivalue="0" uniqueConstraint="0" readonly="0"/>
-  <CPlainAttr id="5" owner_id="1" schema_name="token.expireTime"/>
-  <CPlainAttrValue id="5" attribute_id="5" longValue="60"/>
-
-  <PlainSchema name="selfRegistration.allowed" type="Boolean"
-               mandatoryCondition="true" multivalue="0" uniqueConstraint="0" readonly="0"/>
-  <CPlainAttr id="6" owner_id="1" schema_name="selfRegistration.allowed"/>
-  <CPlainAttrValue id="6" attribute_id="6" booleanValue="1"/>
-
-  <PlainSchema name="passwordReset.allowed" type="Boolean"
-               mandatoryCondition="true" multivalue="0" uniqueConstraint="0" readonly="0"/>
-  <CPlainAttr id="7" owner_id="1" schema_name="passwordReset.allowed"/>
-  <CPlainAttrValue id="7" attribute_id="7" booleanValue="1"/>
-
-  <PlainSchema name="passwordReset.securityQuestion" type="Boolean"
-               mandatoryCondition="true" multivalue="0" uniqueConstraint="0" readonly="0"/>
-  <CPlainAttr id="8" owner_id="1" schema_name="passwordReset.securityQuestion"/>
-  <CPlainAttrValue id="8" attribute_id="8" booleanValue="1"/>
-
-  <PlainSchema name="authentication.statuses" type="String"
-               mandatoryCondition="true" multivalue="1" uniqueConstraint="0" readonly="0"/>
-  <CPlainAttr id="9" owner_id="1" schema_name="authentication.statuses"/>
-  <CPlainAttrValue id="9" attribute_id="9" stringValue="created"/>
-  <CPlainAttrValue id="10" attribute_id="9" stringValue="active"/>
-
-  <!-- Save user login date upon successful authentication -->
-  <PlainSchema name="log.lastlogindate" type="Boolean"
-               mandatoryCondition="true" multivalue="0" uniqueConstraint="0" readonly="0"/>
-  <CPlainAttr id="11" owner_id="1" schema_name="log.lastlogindate"/>
-  <CPlainAttrValue id="11" attribute_id="11" booleanValue="1"/>
-
-  <PlainSchema name="tasks.interruptMaxRetries" type="Long"
-               mandatoryCondition="true" multivalue="0" uniqueConstraint="0" readonly="0"/>
-  <CPlainAttr id="12" owner_id="1" schema_name="tasks.interruptMaxRetries"/>
-  <CPlainAttrValue id="12" attribute_id="12" longValue="20"/>
-
-  <!-- For usage with admin console -->
-  <PlainSchema name="admin.user.layout" type="String"
-               mandatoryCondition="false" multivalue="1" uniqueConstraint="0" readonly="0"/>
-  <PlainSchema name="self.user.layout" type="String"
-               mandatoryCondition="false" multivalue="1" uniqueConstraint="0" readonly="0"/>
-  <PlainSchema name="admin.group.layout" type="String"
-               mandatoryCondition="false" multivalue="1" uniqueConstraint="0" readonly="0"/>
-  <PlainSchema name="self.group.layout" type="String"
-               mandatoryCondition="false" multivalue="1" uniqueConstraint="0" readonly="0"/>
-  <PlainSchema name="admin.membership.layout" type="String"
-               mandatoryCondition="false" multivalue="1" uniqueConstraint="0" readonly="0"/>
-  <PlainSchema name="self.membership.layout" type="String"
-               mandatoryCondition="false" multivalue="1" uniqueConstraint="0" readonly="0"/>
-  
-  <!-- sample policies -->
-  <Policy DTYPE="SyncPolicy" id="1" description="a sync policy" type="SYNC" 
-          specification='{"conflictResolutionAction":"IGNORE","items":[]}'/>
-  <Policy DTYPE="PasswordPolicy" id="2" description="a password policy" type="PASSWORD" 
-          specification='{"historyLength":1,"maxLength":0,"minLength":8,"nonAlphanumericRequired":false,"alphanumericRequired":false,"digitRequired":false,"lowercaseRequired":false,"uppercaseRequired":false,"mustStartWithDigit":false,"mustntStartWithDigit":false,"mustEndWithDigit":false,"mustntEndWithDigit":false,"mustStartWithNonAlpha":false,"mustStartWithAlpha":false,"mustntStartWithNonAlpha":false,"mustntStartWithAlpha":false,"mustEndWithNonAlpha":false,"mustEndWithAlpha":false,"mustntEndWithNonAlpha":false,"mustntEndWithAlpha":false,"wordsNotPermitted":[],"schemasNotPermitted":[],"prefixesNotPermitted":["notpermitted1","notpermitted2"],"suffixesNotPermitted":[],"allowNullPassword":true}'/>
-  <Policy DTYPE="SyncPolicy" id="3" description="sync policy 2" type="SYNC" 
-          specification='{"conflictResolutionAction":"ALL","items":[{"anyTypeKey":"USER","javaRule":null,"altSearchSchemas":["username","firstname"]}]}'/>
-  <Policy DTYPE="PasswordPolicy" id="4" description="sample password policy" type="PASSWORD" 
-          specification='{"historyLength":0,"maxLength":0,"minLength":10,"nonAlphanumericRequired":false,"alphanumericRequired":false,"digitRequired":true,"lowercaseRequired":false,"uppercaseRequired":false,"mustStartWithDigit":false,"mustntStartWithDigit":false,"mustEndWithDigit":false,"mustntEndWithDigit":false,"mustStartWithNonAlpha":false,"mustStartWithAlpha":false,"mustntStartWithNonAlpha":false,"mustntStartWithAlpha":false,"mustEndWithNonAlpha":false,"mustEndWithAlpha":false,"mustntEndWithNonAlpha":false,"mustntEndWithAlpha":false,"wordsNotPermitted":[],"schemasNotPermitted":[],"prefixesNotPermitted":["notpermitted1","notpermitted2"],"suffixesNotPermitted":[], "allowNullPassword":true}'/>
-  <Policy DTYPE="AccountPolicy" id="5" description="an account policy" type="ACCOUNT" 
-          specification='{"maxLength":0,"minLength":0,"pattern":null,"allUpperCase":false,"allLowerCase":false,"propagateSuspension":false,"maxAuthenticationAttempts":0,"wordsNotPermitted":[],"schemasNotPermitted":[],"prefixesNotPermitted":[],"suffixesNotPermitted":[]}'/>
-  <Policy DTYPE="AccountPolicy" id="6" description="sample account policy" type="ACCOUNT" 
-          specification='{"maxLength":0,"minLength":4,"pattern":null,"allUpperCase":false,"allLowerCase":false,"propagateSuspension":false,"maxAuthenticationAttempts":3,"wordsNotPermitted":[],"schemasNotPermitted":[],"prefixesNotPermitted":["notpermitted1","notpermitted2"],"suffixesNotPermitted":[]}'/>
-  <Policy DTYPE="SyncPolicy" id="7" description="sync policy 1" type="SYNC" 
-          specification='{"conflictResolutionAction":"IGNORE","items":[]}'/>
-  <Policy DTYPE="PasswordPolicy" id="8" description="sample password policy" type="PASSWORD" 
-          specification='{"historyLength":0,"maxLength":0,"minLength":10,"nonAlphanumericRequired":true,"alphanumericRequired":false,"digitRequired":true,"lowercaseRequired":true,"uppercaseRequired":true,"mustStartWithDigit":true,"mustntStartWithDigit":false,"mustEndWithDigit":true,"mustntEndWithDigit":false,"mustStartWithNonAlpha":false,"mustStartWithAlpha":false,"mustntStartWithNonAlpha":false,"mustntStartWithAlpha":false,"mustEndWithNonAlpha":false,"mustEndWithAlpha":false,"mustntEndWithNonAlpha":false,"mustntEndWithAlpha":false,"wordsNotPermitted":[],"schemasNotPermitted":[],"prefixesNotPermitted":["notpermitted1","notpermitted2"],"suffixesNotPermitted":[],"allowNullPassword":false}'/>
-  <Policy DTYPE="SyncPolicy" id="9" description="sync policy for java rule" type="SYNC" 
-          specification='{"conflictResolutionAction":"IGNORE","items":[]}'/>
-
-  <RelationshipType name="inclusion" description="Models the act that an object is included in another"/>
-  <RelationshipType name="neighborhood"/>
-  
-  <AnyTypeClass name="generic membership"/>
-
-  <AnyType name="USER" kind="USER"/>
-  <AnyTypeClass name="minimal user"/>
-  <AnyType_AnyTypeClass anyType_name="USER" anyTypeClass_name="minimal user"/>
-  <AnyTypeClass name="other"/>
-  <AnyType_AnyTypeClass anyType_name="USER" anyTypeClass_name="other"/>
-
-  <AnyType name="GROUP" kind="GROUP"/>
-  <AnyTypeClass name="minimal group"/>
-  <AnyType_AnyTypeClass anyType_name="GROUP" anyTypeClass_name="minimal group"/>
-  
-  <AnyType name="PRINTER" kind="ANY_OBJECT"/>
-  <AnyTypeClass name="minimal printer"/>
-  <AnyType_AnyTypeClass anyType_name="PRINTER" anyTypeClass_name="minimal printer"/>
-      
-  <AnyTypeClass name="csv"/>
-
-  <Realm id="1" name="/" passwordPolicy_id="4"/>
-  <Realm id="2" name="odd" parent_id="1" accountPolicy_id="6"/>
-  <Realm id="3" name="even" parent_id="1"/>
-  <Realm id="4" name="two" parent_id="3" accountPolicy_id="5" passwordPolicy_id="2"/>
-  
-  <AnyObject id="1" realm_id="1" type_name="PRINTER"
-             creator="admin" lastModifier="admin" 
-             creationDate="2010-10-20 11:00:00" lastChangeDate="2010-10-20 11:00:00"/>
-  <AnyObject id="2" realm_id="1" type_name="PRINTER"
-             creator="admin" lastModifier="admin" 
-             creationDate="2010-10-20 11:00:00" lastChangeDate="2010-10-20 11:00:00"/>
-  
-  <ARelationship id="1" left_anyObject_id="1" right_anyObject_id="2" type_name="neighborhood"/>
-  
-  <SyncopeRole id="1" name="User reviewer"/>
-  <SyncopeRole_entitlements entitlement="USER_READ" role_id="1"/>
-  <SyncopeRole_entitlements entitlement="USER_LIST" role_id="1"/>
-  <SyncopeRole_entitlements entitlement="USER_SEARCH" role_id="1"/>
-  <SyncopeRole_Realm role_id="1" realm_id="2"/>
-  <SyncopeRole_Realm role_id="1" realm_id="3"/>
-  
-  <SyncopeRole id="2" name="User manager"/>
-  <SyncopeRole_entitlements entitlement="USER_READ" role_id="2"/>
-  <SyncopeRole_entitlements entitlement="USER_LIST" role_id="2"/>
-  <SyncopeRole_entitlements entitlement="USER_SEARCH" role_id="2"/>
-  <SyncopeRole_entitlements entitlement="WORKFLOW_FORM_CLAIM" role_id="2"/>
-  <SyncopeRole_entitlements entitlement="WORKFLOW_FORM_SUBMIT" role_id="2"/>
-  <SyncopeRole_Realm role_id="2" realm_id="1"/>
-
-  <SyncopeRole id="3" name="Other"/>
-  <SyncopeRole_entitlements entitlement="SCHEMA_READ" role_id="3"/>
-  <SyncopeRole_entitlements entitlement="GROUP_READ" role_id="3"/>
-  <SyncopeRole_entitlements entitlement="WORKFLOW_FORM_CLAIM" role_id="3"/>
-  <SyncopeRole_Realm role_id="3" realm_id="2"/>
-  
-  <SyncopeRole id="4" name="Search for /even/two"/>
-  <SyncopeRole_entitlements entitlement="USER_READ" role_id="4"/>
-  <SyncopeRole_entitlements entitlement="USER_SEARCH" role_id="4"/>
-  <SyncopeRole_Realm role_id="4" realm_id="4"/>
-
-  <SyncopeUser id="1" workflowId="4" status="active" password="5baa61e4c9b93f3f0682250b6cf8331b7ee68fd8" cipherAlgorithm="SHA1"
-               realm_id="3"
-               username="rossini" creator="admin" lastModifier="admin"
-               creationDate="2010-10-20 11:00:00" lastChangeDate="2010-10-20 11:00:00" suspended="0"/>
-  <SyncopeUser_SyncopeRole user_id="1" role_id="3"/>
-  <SyncopeUser id="2" workflowId="6" status="active" password="5baa61e4c9b93f3f0682250b6cf8331b7ee68fd8" cipherAlgorithm="SHA1"
-               realm_id="1"
-               username="verdi" creator="admin" lastModifier="admin"
-               creationDate="2010-10-20 11:00:00" lastChangeDate="2010-10-20 11:00:00" suspended="0"/>
-  <SyncopeUser id="3" workflowId="8" status="active" password="5baa61e4c9b93f3f0682250b6cf8331b7ee68fd8" cipherAlgorithm="SHA1"
-               realm_id="1"
-               username="vivaldi" creator="admin" lastModifier="admin"
-               creationDate="2010-10-20 11:00:00" lastChangeDate="2010-10-20 11:00:00" suspended="0"/>
-  <SyncopeUser id="4" workflowId="10" status="active" password="5baa61e4c9b93f3f0682250b6cf8331b7ee68fd8" cipherAlgorithm="SHA1"
-               realm_id="1"
-               username="bellini" creator="admin" lastModifier="admin"
-               creationDate="2010-10-20 11:00:00" lastChangeDate="2010-10-20 11:00:00" suspended="0"/>
-  <SyncopeUser_SyncopeRole user_id="4" role_id="1"/>
-  <SyncopeUser_SyncopeRole user_id="4" role_id="2"/>
-  <SyncopeUser id="5" workflowId="12" status="active" password="5baa61e4c9b93f3f0682250b6cf8331b7ee68fd8" cipherAlgorithm="SHA1"
-               realm_id="1"
-               username="puccini" creator="admin" lastModifier="admin" 
-               creationDate="2010-10-20 11:00:00" lastChangeDate="2010-10-20 11:00:00" suspended="0"/>
-  <SyncopeUser_SyncopeRole user_id="5" role_id="4"/>
-  
-  <SyncopeGroup id="1" name="root"
-                realm_id="1"
-                creator="admin" lastModifier="admin" 
-                creationDate="2010-10-20 11:00:00" lastChangeDate="2010-10-20 11:00:00"/>
-  <SyncopeGroup id="2" name="child"
-                realm_id="1"
-                creator="admin" lastModifier="admin" 
-                creationDate="2010-10-20 11:00:00" lastChangeDate="2010-10-20 11:00:00"/>
-  <SyncopeGroup id="3" name="citizen"
-                realm_id="1"
-                creator="admin" lastModifier="admin" 
-                creationDate="2010-10-20 11:00:00" lastChangeDate="2010-10-20 11:00:00"/>
-  <SyncopeGroup id="4" name="employee"
-                realm_id="1"
-                creator="admin" lastModifier="admin" 
-                creationDate="2010-10-20 11:00:00" lastChangeDate="2010-10-20 11:00:00"/>
-  <SyncopeGroup id="5" name="secretary"
-                realm_id="1"
-                creator="admin" lastModifier="admin" 
-                creationDate="2010-10-20 11:00:00" lastChangeDate="2010-10-20 11:00:00"/>
-  <SyncopeGroup id="6" name="director" userOwner_id="5"
-                realm_id="1"
-                creator="admin" lastModifier="admin" 
-                creationDate="2010-10-20 11:00:00" lastChangeDate="2010-10-20 11:00:00"/>
-  <SyncopeGroup id="7" name="managingDirector"
-                realm_id="1"
-                creator="admin" lastModifier="admin" 
-                creationDate="2010-10-20 11:00:00" lastChangeDate="2010-10-20 11:00:00"/>
-  <SyncopeGroup id="8" name="otherchild"
-                realm_id="1"
-                creator="admin" lastModifier="admin" 
-                creationDate="2010-10-20 11:00:00" lastChangeDate="2010-10-20 11:00:00"/>
-  <SyncopeGroup id="9" name="groupForWorkflowApproval"
-                realm_id="1"
-                creator="admin" lastModifier="admin" 
-                creationDate="2010-10-20 11:00:00" lastChangeDate="2010-10-20 11:00:00"/>
-  <SyncopeGroup id="10" name="managingConsultant"
-                realm_id="1"
-                creator="admin" lastModifier="admin" 
-                creationDate="2010-10-20 11:00:00" lastChangeDate="2010-10-20 11:00:00"/>
-  <SyncopeGroup id="11" name="groupForWorkflowOptIn"
-                realm_id="1"
-                creator="admin" lastModifier="admin" 
-                creationDate="2010-10-20 11:00:00" lastChangeDate="2010-10-20 11:00:00"/>
-  <SyncopeGroup id="12" name="aGroupForPropagation"
-                realm_id="1"
-                creator="admin" lastModifier="admin" 
-                creationDate="2010-10-20 11:00:00" lastChangeDate="2010-10-20 11:00:00"/>
-  <SyncopeGroup_AnyTypeClass group_id="12" anyTypeClass_name="csv"/>  
-  <SyncopeGroup id="13" name="bGroupForPropagation"
-                realm_id="1"
-                creator="admin" lastModifier="admin" 
-                creationDate="2010-10-20 11:00:00" lastChangeDate="2010-10-20 11:00:00"/>
-  <SyncopeGroup_AnyTypeClass group_id="13" anyTypeClass_name="csv"/>  
-  <SyncopeGroup id="14" name="artDirector"
-                realm_id="1"
-                creator="admin" lastModifier="admin" 
-                creationDate="2010-10-20 11:00:00" lastChangeDate="2010-10-20 11:00:00"/>
-  
-  <URelationship id="1" user_id="4" anyObject_id="1" type_name="neighborhood"/>
-
-  <UMembership id="1" user_id="1" group_id="1"/>
-  <UMembership id="2" user_id="2" group_id="1"/>
-  <UMembership id="3" user_id="2" group_id="2"/>
-  <UMembership id="4" user_id="4" group_id="7"/>
-  <UMembership id="5" user_id="1" group_id="8"/>
-  <UMembership id="6" user_id="2" group_id="3"/>
-  <UMembership id="7" user_id="5" group_id="14"/>
-
-  <PlainSchema name="fullname" type="String" anyTypeClass_name="minimal user"
-               mandatoryCondition="true" multivalue="0" uniqueConstraint="1" readonly="0"/>
-  <PlainSchema name="userId" type="String" anyTypeClass_name="minimal user"
-               mandatoryCondition="true" multivalue="0" uniqueConstraint="1" readonly="0"
-               validatorClass="org.apache.syncope.core.persistence.jpa.attrvalue.validation.EmailAddressValidator"/>
-  <PlainSchema name="loginDate" type="Date" anyTypeClass_name="other"
-               mandatoryCondition="false" multivalue="1" uniqueConstraint="0" readonly="0"
-               conversionPattern="yyyy-MM-dd"/>
-  <PlainSchema name="firstname" type="String" anyTypeClass_name="minimal user"
-               mandatoryCondition="false" multivalue="0" uniqueConstraint="0" readonly="0"/>
-  <PlainSchema name="surname" type="String" anyTypeClass_name="minimal user"
-               mandatoryCondition="true" multivalue="0" uniqueConstraint="0" readonly="0"/>
-  <PlainSchema name="type" type="String" anyTypeClass_name="other"
-               mandatoryCondition="false" multivalue="0" uniqueConstraint="0" readonly="0"/>
-  <PlainSchema name="email" type="String" anyTypeClass_name="minimal user"
-               mandatoryCondition="false" multivalue="0" uniqueConstraint="0" readonly="0"
-               validatorClass="org.apache.syncope.core.persistence.jpa.attrvalue.validation.EmailAddressValidator"/>
-  <PlainSchema name="activationDate" type="Date" anyTypeClass_name="other"
-               mandatoryCondition="false" multivalue="0" uniqueConstraint="0" readonly="0"
-               conversionPattern="yyyy-MM-dd'T'HH:mm:ss.SSSZ"/>
-  <PlainSchema name="uselessReadonly" type="String" anyTypeClass_name="other"
-               mandatoryCondition="false" multivalue="0" uniqueConstraint="0" readonly="1"/>
-  <PlainSchema name="cool" type="Boolean" anyTypeClass_name="other" 
-               mandatoryCondition="false" multivalue="0" uniqueConstraint="0" readonly="0"/>
-  <PlainSchema name="gender" type="Enum" anyTypeClass_name="other"
-               mandatoryCondition="false" multivalue="0" uniqueConstraint="0" readonly="0"
-               enumerationValues="M;F"/>
-  <PlainSchema name="aLong" type="Long" anyTypeClass_name="other"
-               mandatoryCondition="false" multivalue="0" uniqueConstraint="0" readonly="0"/>
-  <PlainSchema name="makeItDouble" type="Long" anyTypeClass_name="other"
-               mandatoryCondition="false" multivalue="0" uniqueConstraint="0" readonly="0"/>
-  <PlainSchema name="obscure" type="Encrypted" anyTypeClass_name="other"
-               mandatoryCondition="false" multivalue="0" uniqueConstraint="0" readonly="0"
-               secretKey="7abcdefghilmnopqrstuvz9#" cipherAlgorithm="SHA"/>
-  <PlainSchema name="photo" type="Binary" anyTypeClass_name="other"
-               mandatoryCondition="false" multivalue="0" uniqueConstraint="0" readonly="0"
-               mimeType="image/jpeg"/>
-
-  <DerSchema name="csvuserid" expression="firstname + ',' + surname" anyTypeClass_name="csv"/>
-  <DerSchema name="cn" expression="surname + ', ' + firstname" anyTypeClass_name="minimal user"/>
-  <DerSchema name="noschema" expression="surname + ', ' + notfound" anyTypeClass_name="other"/>
-
-  <VirSchema name="virtualdata" anyTypeClass_name="minimal user"/>
-  <VirSchema name="virtualReadOnly" READONLY="1"  anyTypeClass_name="minimal user"/>
-
-  <PlainSchema name="icon" type="String" anyTypeClass_name="minimal group"
-               mandatoryCondition="false" multivalue="0" uniqueConstraint="0" readonly="0"/>                
-  <PlainSchema name="show" type="Boolean" anyTypeClass_name="minimal group"
-               mandatoryCondition="false" multivalue="0" uniqueConstraint="0" readonly="0"/>
-  <PlainSchema name="rderived_sx" type="String" anyTypeClass_name="minimal group"
-               mandatoryCondition="false" multivalue="0" uniqueConstraint="0" readonly="0"/>
-  <PlainSchema name="rderived_dx" type="String" anyTypeClass_name="minimal group"
-               mandatoryCondition="false" multivalue="0" uniqueConstraint="0" readonly="0"/>           
-  <PlainSchema name="title" type="String" anyTypeClass_name="minimal group"
-               mandatoryCondition="false" multivalue="1" uniqueConstraint="0" readonly="0"/>
-
-  <DerSchema name="rderiveddata" expression="rderived_sx + '-' + rderived_dx"
-             anyTypeClass_name="minimal group"/>
-  <DerSchema name="displayProperty" expression="icon + ': ' + show"
-             anyTypeClass_name="minimal group"/>
-  <DerSchema name="rderToBePropagated" expression="rderived_sx + '-' + rderived_dx"
-             anyTypeClass_name="minimal group"/>
-
-  <VirSchema name="rvirtualdata" anyTypeClass_name="minimal group"/>
-
-  <DerSchema name="rderivedschema" expression="rderived_sx + '-' + rderived_dx"  anyTypeClass_name="minimal group"/>
-
-  <PlainSchema name="subscriptionDate" type="Date" anyTypeClass_name="generic membership"
-               mandatoryCondition="false" multivalue="0" uniqueConstraint="0" readonly="0"
-               conversionPattern="yyyy-MM-dd'T'HH:mm:ss.SSSZ"/>
-  <PlainSchema name="mderived_sx" type="String" anyTypeClass_name="generic membership"
-               mandatoryCondition="false" multivalue="0" uniqueConstraint="0" readonly="0"/>
-  <PlainSchema name="mderived_dx" type="String" anyTypeClass_name="generic membership"
-               mandatoryCondition="false" multivalue="0" uniqueConstraint="0" readonly="0"/>          
-  <PlainSchema name="postalAddress" type="String" anyTypeClass_name="generic membership"
-               mandatoryCondition="false" multivalue="0" uniqueConstraint="0" readonly="0"/>
-
-  <DerSchema name="mderiveddata" expression="mderived_sx + '-' + mderived_dx"/>
-  <DerSchema name="mderToBePropagated" expression="mderived_sx + '-' + mderived_dx" 
-             anyTypeClass_name="generic membership"/>
-
-  <VirSchema name="mvirtualdata"/>
-        
-  <PlainSchema name="model" type="String" anyTypeClass_name="minimal printer"
-               mandatoryCondition="false" multivalue="0" uniqueConstraint="0" readonly="0"/>
-  <PlainSchema name="location" type="String" anyTypeClass_name="minimal printer"
-               mandatoryCondition="false" multivalue="0" uniqueConstraint="0" readonly="0"/>
-    
-  <APlainAttr id="1" owner_id="1" schema_name="model"/>
-  <APlainAttrValue id="1" attribute_id="1" stringValue="Canon MFC8030"/>
-  <APlainAttr id="2" owner_id="1" schema_name="location"/>
-  <APlainAttrValue id="2" attribute_id="2" stringValue="1st floor"/>
-    
-  <APlainAttr id="3" owner_id="2" schema_name="model"/>
-  <APlainAttrValue id="3" attribute_id="3" stringValue="HP Laserjet 1300n"/>
-  <APlainAttr id="4" owner_id="2" schema_name="location"/>
-  <APlainAttrValue id="4" attribute_id="4" stringValue="2nd floor"/>
-
-  <UPlainAttr id="99" owner_id="1" schema_name="type"/>
-  <UPlainAttrValue id="9" attribute_id="99" stringValue="G"/>
-  <UPlainAttr id="100" owner_id="1" schema_name="fullname"/>
-  <UPlainAttrUniqueValue id="10" attribute_id="100" schema_name="fullname" stringValue="Gioacchino Rossini"/>
-  <UPlainAttr id="101" owner_id="1" schema_name="firstname"/>
-  <UPlainAttrValue id="11" attribute_id="101" stringValue="Gioacchino"/>
-  <UPlainAttr id="102" owner_id="1" schema_name="surname"/>
-  <UPlainAttrValue id="12" attribute_id="102" stringValue="Rossini"/>
-  <UPlainAttr id="103" owner_id="1" schema_name="userId"/>
-  <UPlainAttrUniqueValue id="13" attribute_id="103" schema_name="userId" stringValue="rossini@apache.org"/>
-  <UPlainAttr id="104" owner_id="1" schema_name="loginDate"/>
-  <UPlainAttrValue id="14" attribute_id="104" dateValue="2009-05-26"/>
-  <UPlainAttrValue id="15" attribute_id="104" dateValue="2010-05-26 15:40:04"/>
-
-  <UPlainAttr id="105" owner_id="2" schema_name="fullname"/>
-  <UPlainAttrUniqueValue id="16" attribute_id="105" schema_name="fullname" stringValue="Giuseppe Verdi"/>
-  <UPlainAttr id="106" owner_id="2" schema_name="firstname"/>
-  <UPlainAttrValue id="17" attribute_id="106" stringValue="Giuseppe"/>
-  <UPlainAttr id="107" owner_id="2" schema_name="surname"/>
-  <UPlainAttrValue id="18" attribute_id="107" stringValue="Verdi"/>
-  <UPlainAttr id="108" owner_id="2" schema_name="userId"/>
-  <UPlainAttrUniqueValue id="19" attribute_id="108" schema_name="userId" stringValue="verdi@apache.org"/>
-
-  <UPlainAttr id="109" owner_id="3" schema_name="firstname"/>
-  <UPlainAttrValue id="20" attribute_id="109" stringValue="Antonio"/>
-  <UPlainAttr id="110" owner_id="3" schema_name="surname"/>
-  <UPlainAttrValue id="21" attribute_id="110" stringValue="Vivaldi"/>
-  <UPlainAttr id="111" owner_id="3" schema_name="fullname"/>
-  <UPlainAttrUniqueValue id="22" attribute_id="111" schema_name="fullname" stringValue="Antonio Vivaldi"/>
-  <UPlainAttr id="112" owner_id="3" schema_name="userId"/>
-  <UPlainAttrUniqueValue id="23" attribute_id="112" schema_name="userId" stringValue="vivaldi@apache.org"/>
-
-  <UPlainAttr id="113" owner_id="4" schema_name="firstname"/>
-  <UPlainAttrValue id="24" attribute_id="113" stringValue="Vincenzo"/>
-  <UPlainAttr id="114" owner_id="4" schema_name="surname"/>
-  <UPlainAttrValue id="25" attribute_id="114" stringValue="Bellini"/>
-  <UPlainAttr id="115" owner_id="4" schema_name="fullname"/>
-  <UPlainAttrUniqueValue id="26" attribute_id="115" schema_name="fullname" stringValue="Vincenzo Bellini"/>
-  <UPlainAttr id="116" owner_id="4" schema_name="userId"/>
-  <UPlainAttrUniqueValue id="27" attribute_id="116" schema_name="userId" stringValue="bellini@apache.org"/>
-  <UPlainAttr id="117" owner_id="4" schema_name="loginDate"/>
-  <UPlainAttrValue id="28" attribute_id="117" dateValue="2009-06-24"/>
-  <UPlainAttr id="118" owner_id="4" schema_name="cool"/>
-  <UPlainAttrValue id="29" attribute_id="118" booleanValue="1"/>
-  <UPlainAttr id="119" owner_id="4" schema_name="gender"/>
-  <UPlainAttrValue id="30" attribute_id="119" stringValue="M"/>
-  
-  <UPlainAttr id="120" owner_id="5" schema_name="firstname"/>
-  <UPlainAttrValue id="31" attribute_id="120" stringValue="Giacomo"/>
-  <UPlainAttr id="121" owner_id="5" schema_name="surname"/>
-  <UPlainAttrValue id="32" attribute_id="121" stringValue="Puccini"/>
-  <UPlainAttr id="122" owner_id="5" schema_name="fullname"/>
-  <UPlainAttrUniqueValue id="33" attribute_id="122" schema_name="fullname" stringValue="Giacomo Puccini"/>
-  <UPlainAttr id="123" owner_id="5" schema_name="userId"/>
-  <UPlainAttrUniqueValue id="34" attribute_id="123" schema_name="userId" stringValue="puccini@apache.org"/>
-  
-  <UPlainAttr id="124" owner_id="2" schema_name="email"/>
-  <UPlainAttrValue id="35" attribute_id="124" stringValue="verdi@syncope.org"/>
-  <UPlainAttr id="125" owner_id="3" schema_name="email"/>
-  <UPlainAttrValue id="36" attribute_id="125" stringValue="vivaldi@syncope.org"/>
-  <UPlainAttr id="126" owner_id="3" schema_name="type"/>
-  <UPlainAttrValue id="37" attribute_id="126" stringValue="F"/>
-    
-  <UVirAttr id="100" schema_name="virtualdata" owner_id="3"/>
-  
-  <UDerAttr id="100" schema_name="cn" owner_id="3"/>
-  <UDerAttr id="101" schema_name="cn" owner_id="1"/>
-
-  <GPlainAttr id="600" owner_id="1" schema_name="icon"/>
-  <GPlainAttrValue attribute_id="600" id="40" stringValue="niceIcon"/>
-
-  <GPlainAttr id="700" owner_id="2" schema_name="icon"/>
-  <GPlainAttrValue attribute_id="700" id="41" stringValue="badIcon"/>
-
-  <GPlainAttr id="800" owner_id="1"  schema_name="show"/>
-  <GPlainAttrValue attribute_id="800" id="42" booleanValue="1"/>
-
-  <GPlainAttr id="900" owner_id="6" schema_name="icon"/>
-  <GPlainAttrValue attribute_id="900" id="43" stringValue="icon6"/>
-
-  <GPlainAttr id="950" owner_id="4" schema_name="icon"/>
-  <GPlainAttrValue attribute_id="950" id="44" stringValue="icon4"/>
-
-  <GPlainAttr id="992" owner_id="1" schema_name="rderived_sx"/>
-  <GPlainAttrValue attribute_id="992" id="92" stringValue="sx"/>
-
-  <GPlainAttr id="993" owner_id="1" schema_name="rderived_dx"/>
-  <GPlainAttrValue attribute_id="993" id="93" stringValue="dx"/>
-
-  <GPlainAttr id="994" owner_id="12" schema_name="title"/>
-  <GPlainAttrValue attribute_id="994" id="94" stringValue="r12"/>
-  
-  <GPlainAttr id="995" owner_id="13" schema_name="title"/>
-  <GPlainAttrValue attribute_id="995" id="95" stringValue="r13"/>
-
-  <GDerAttr id="100" owner_id="1" schema_name="rderiveddata"/>
-    
-  <GDerAttr id="101" owner_id="1" schema_name="displayProperty"/>
-  
-  <GDerAttr id="102" owner_id="4" schema_name="displayProperty"/>
-
-  <GDerAttr id="103" owner_id="1" schema_name="rderToBePropagated"/>    
-
-  <GVirAttr id="98" owner_id="4" schema_name="rvirtualdata"/>
-
-  <ConnInstance id="100" displayName="ConnInstance100"
-                location="${connid.location}"
-                bundleName="net.tirasa.connid.bundles.soap"
-                connectorName="net.tirasa.connid.bundles.soap.WebServiceConnector"
-                version="${connid.soap.version}"
-                jsonConf='[{"schema":{"name":"endpoint","displayName":null,"helpMessage":null,"type":"java.lang.String","required":true,"order":0,"confidential":false,"defaultValues":null},"overridable":false,"values":["http://localhost:${cargo.servlet.port}/wssample/services/provisioning"]},{"schema":{"name":"servicename","displayName":null,"helpMessage":null,"type":"java.lang.String","required":true,"order":0,"confidential":false,"defaultValues":null},"overridable":false,"values":["net.tirasa.connid.bundles.soap.provisioning.interfaces.Provisioning"]}]'/>
-  <ConnInstance_capabilities ConnInstance_id="100" capability="ONE_PHASE_CREATE"/>
-  <ConnInstance_capabilities ConnInstance_id="100" capability="ONE_PHASE_UPDATE"/>
-  <ConnInstance_capabilities ConnInstance_id="100" capability="ONE_PHASE_DELETE"/>
-  <ConnInstance_capabilities ConnInstance_id="100" capability="TWO_PHASES_CREATE"/>
-  <ConnInstance_capabilities ConnInstance_id="100" capability="TWO_PHASES_UPDATE"/>
-  <ConnInstance_capabilities ConnInstance_id="100" capability="TWO_PHASES_DELETE"/>
-  <ConnInstance_capabilities ConnInstance_id="100" capability="SEARCH"/>
-
-  <ConnInstance id="101" displayName="H2"
-                location="connid://${testconnectorserver.key}@localhost:${testconnectorserver.port}"
-                bundleName="net.tirasa.connid.bundles.db.table"
-                connectorName="net.tirasa.connid.bundles.db.table.DatabaseTableConnector"
-                version="${connid.database.version}"
-                jsonConf='[{"schema":{"name":"disabledStatusValue","displayName":null,"helpMessage":null,"type":"java.lang.String","required":false,"order":0,"confidential":false,"defaultValues":null},"overridable":false,"values":["false"]},{"schema":{"name":"user","displayName":null,"helpMessage":null,"type":"java.lang.String","required":false,"order":0,"confidential":false,"defaultValues":null},"overridable":false,"values":["sa"]},{"schema":{"name":"keyColumn","displayName":null,"helpMessage":null,"type":"java.lang.String","required":true,"order":0,"confidential":false,"defaultValues":null},"overridable":false,"values":["id"]},{"schema":{"name":"retrievePassword","displayName":null,"helpMessage":null,"type":"boolean","required":false,"order":0,"confidential":false,"defaultValues":null},"overridable":false,"values":["true"]},{"schema":{"name":"cipherAlgorithm","displayName":null,"helpMessage":null,"type":"java.lang.String","required":true,"order":0,"confidential":false,"defaultValu
 es":null},"overridable":false,"values":["SHA1"]},{"schema":{"name":"enabledStatusValue","displayName":null,"helpMessage":null,"type":"java.lang.String","required":false,"order":0,"confidential":false,"defaultValues":null},"overridable":false,"values":["true"]},{"schema":{"name":"passwordColumn","displayName":null,"helpMessage":null,"type":"java.lang.String","required":false,"order":0,"confidential":false,"defaultValues":null},"overridable":false,"values":["password"]},{"schema":{"name":"jdbcDriver","displayName":null,"helpMessage":null,"type":"java.lang.String","required":false,"order":0,"confidential":false,"defaultValues":null},"overridable":false,"values":["org.h2.Driver"]},{"schema":{"name":"defaultStatusValue","displayName":null,"helpMessage":null,"type":"java.lang.String","required":false,"order":0,"confidential":false,"defaultValues":null},"overridable":false,"values":["true"]},{"schema":{"name":"table","displayName":null,"helpMessage":null,"type":"java.lang.String","required
 ":true,"order":0,"confidential":false,"defaultValues":null},"overridable":false,"values":["test"]},{"schema":{"name":"password","displayName":null,"helpMessage":null,"type":"org.identityconnectors.common.security.GuardedString","required":false,"order":0,"confidential":false,"defaultValues":null},"overridable":false,"values":["sa"]},{"schema":{"name":"statusColumn","displayName":null,"helpMessage":null,"type":"java.lang.String","required":false,"order":0,"confidential":false,"defaultValues":null},"overridable":false,"values":["status"]},{"schema":{"name":"jdbcUrlTemplate","displayName":null,"helpMessage":null,"type":"java.lang.String","required":false,"order":0,"confidential":false,"defaultValues":null},"overridable":false,"values":["${testdb.url}"]}]'/>
-  <ConnInstance_capabilities ConnInstance_id="101" capability="AUTHENTICATE"/>
-  <ConnInstance_capabilities ConnInstance_id="101" capability="ONE_PHASE_CREATE"/>
-  <ConnInstance_capabilities ConnInstance_id="101" capability="ONE_PHASE_UPDATE"/>
-  <ConnInstance_capabilities ConnInstance_id="101" capability="ONE_PHASE_DELETE"/>
-  <ConnInstance_capabilities ConnInstance_id="101" capability="TWO_PHASES_CREATE"/>
-  <ConnInstance_capabilities ConnInstance_id="101" capability="TWO_PHASES_UPDATE"/>
-  <ConnInstance_capabilities ConnInstance_id="101" capability="TWO_PHASES_DELETE"/>
-  <ConnInstance_capabilities ConnInstance_id="101" capability="SEARCH"/>
-  <ConnInstance_capabilities ConnInstance_id="101" capability="SYNC"/>
-
-  <ConnInstance id="102" displayName="ConnInstance102"
-                location="${connid.location}"
-                bundleName="net.tirasa.connid.bundles.soap"
-                connectorName="net.tirasa.connid.bundles.soap.WebServiceConnector"
-                version="${connid.soap.version}"
-                connRequestTimeout="10"
-                jsonConf='[{"schema":{"name":"servicename","displayName":null,"helpMessage":null,"type":"java.lang.String","required":true,"order":0,"confidential":false,"defaultValues":null},"overridable":false,"values":["net.tirasa.connid.bundles.soap.provisioning.interfaces.Provisioning"]},{"schema":{"name":"endpoint","displayName":null,"helpMessage":null,"type":"java.lang.String","required":true,"order":0,"confidential":false,"defaultValues":null},"overridable":true,"values":["http://localhost:${cargo.servlet.port}/wssample/services/provisioning"]}]'/>
-  <ConnInstance_capabilities ConnInstance_id="102" capability="ONE_PHASE_CREATE"/>
-  <ConnInstance_capabilities ConnInstance_id="102" capability="ONE_PHASE_UPDATE"/>
-  <ConnInstance_capabilities ConnInstance_id="102" capability="ONE_PHASE_DELETE"/>
-  <ConnInstance_capabilities ConnInstance_id="102" capability="TWO_PHASES_CREATE"/>
-  <ConnInstance_capabilities ConnInstance_id="102" capability="TWO_PHASES_UPDATE"/>
-  <ConnInstance_capabilities ConnInstance_id="102" capability="TWO_PHASES_DELETE"/>
-  <ConnInstance_capabilities ConnInstance_id="102" capability="SEARCH"/>
-
-  <ConnInstance id="103" displayName="ConnInstance103"
-                location="${connid.location}"
-                bundleName="net.tirasa.connid.bundles.soap"
-                connectorName="net.tirasa.connid.bundles.soap.WebServiceConnector"
-                version="${connid.soap.version}"
-                jsonConf='[{"schema":{"name":"endpoint","displayName":null,"helpMessage":null,"type":"java.lang.String","required":true,"order":0,"confidential":false,"defaultValues":null},"overridable":false,"values":["http://localhost:${cargo.servlet.port}/wssample/services/provisioning"]},{"schema":{"name":"servicename","displayName":null,"helpMessage":null,"type":"java.lang.String","required":true,"order":0,"confidential":false,"defaultValues":null},"overridable":false,"values":["net.tirasa.connid.bundles.soap.provisioning.interfaces.Provisioning"]}]'/>
-
-  <ConnInstance id="104" displayName="CSVDir"
-                location="${connid.location}"
-                bundleName="net.tirasa.connid.bundles.csvdir"
-                connectorName="net.tirasa.connid.bundles.csvdir.CSVDirConnector"
-                version="${connid.csvdir.version}"
-                jsonConf='[{"schema":{"name":"fields","displayName":"fields","helpMessage":"Column names separated by comma","type":"[Ljava.lang.String;","required":true,"order":0,"confidential":false,"defaultValues":null},"overridable":false,"values":["id","name","surname","email","password","theirgroup","membership","status","deleted"]},{"schema":{"name":"keyColumnNames","displayName":"Key column name","helpMessage":"Name of the column used to identify user uniquely","type":"[Ljava.lang.String;","required":true,"order":0,"confidential":false,"defaultValues":null},"overridable":false,"values":["name","surname"]},{"schema":{"name":"deleteColumnName","displayName":"Delete column name","helpMessage":"Name of the column used to specify users to be deleted","type":"java.lang.String","required":false,"order":0,"confidential":false,"defaultValues":null},"overridable":false,"values":["deleted"]},{"schema":{"name":"passwordColumnName","displayName":"Password column name","helpMessage":"Name
  of the column used to specify user password","type":"java.lang.String","required":false,"order":0,"confidential":false,"defaultValues":null},"overridable":false,"values":["password"]},{"schema":{"name":"keyseparator","displayName":"Key separator","helpMessage":"Character used to separate keys in a multi-key scenario","type":"java.lang.String","required":true,"order":0,"confidential":false,"defaultValues":null},"overridable":false,"values":[","]},{"schema":{"name":"ignoreHeader","displayName":"Ignore header","helpMessage":"Specify it first line file must be ignored","type":"java.lang.Boolean","required":true,"order":0,"confidential":false,"defaultValues":null},"overridable":false,"values":[false]},{"schema":{"name":"fieldDelimiter","displayName":"fieldDelimiter","helpMessage":"fieldDelimiter","type":"char","required":true,"order":0,"confidential":false,"defaultValues":null},"overridable":false,"values":[","]},{"schema":{"name":"quotationRequired","displayName":"Value quotation requi
 red","helpMessage":"Specify if value quotation is required","type":"java.lang.Boolean","required":true,"order":0,"confidential":false,"defaultValues":null},"overridable":false,"values":[false]},{"schema":{"name":"statusColumn","displayName":"statusColumn","helpMessage":"Status column","type":"java.lang.String","required":false,"order":0,"confidential":false,"defaultValues":null},"overridable":false,"values":["status"]},{"schema":{"name":"sourcePath","displayName":"Source path","helpMessage":"Absolute path of a directory where are located CSV files to be processed","type":"java.lang.String","required":true,"order":0,"confidential":false,"defaultValues":null},"overridable":false,"values":["${test.csvdir.path}"]},{"schema":{"name":"fileMask","displayName":"File mask","helpMessage":"Regular expression describing files to be processed","type":"java.lang.String","required":true,"order":0,"confidential":false,"defaultValues":null},"overridable":false,"values":["test.csv"]}]'/>
-  <ConnInstance_capabilities ConnInstance_id="104" capability="ONE_PHASE_CREATE"/>
-  <ConnInstance_capabilities ConnInstance_id="104" capability="ONE_PHASE_UPDATE"/>
-  <ConnInstance_capabilities ConnInstance_id="104" capability="ONE_PHASE_DELETE"/>
-  <ConnInstance_capabilities ConnInstance_id="104" capability="TWO_PHASES_CREATE"/>
-  <ConnInstance_capabilities ConnInstance_id="104" capability="TWO_PHASES_UPDATE"/>
-  <ConnInstance_capabilities ConnInstance_id="104" capability="TWO_PHASES_DELETE"/>
-  <ConnInstance_capabilities ConnInstance_id="104" capability="SEARCH"/>
-  <ConnInstance_capabilities ConnInstance_id="104" capability="SYNC"/>
-    
-  <ConnInstance id="105" bundleName="net.tirasa.connid.bundles.ldap" displayName="ApacheDS"
-                location="${connid.location}"
-                connectorName="net.tirasa.connid.bundles.ldap.LdapConnector"
-                version="${connid.ldap.version}" 
-                jsonConf='[{"schema":{"name":"synchronizePasswords","displayName":"Enable Password Synchronization","helpMessage":"If true, the connector will synchronize passwords. The Password Capture Plugin needs to be installed for password synchronization to work.","type":"boolean","required":false,"order":0,"confidential":false,"defaultValues":null},"overridable":false,"values":["false"]},{"schema":{"name":"maintainLdapGroupMembership","displayName":"Maintain LDAP Group Membership","helpMessage":"When enabled and a user is renamed or deleted, update any LDAP groups to which the user belongs to reflect the new name. Otherwise, the LDAP resource must maintain referential integrity with respect to group membership.","type":"boolean","required":false,"order":0,"confidential":false,"defaultValues":null},"overridable":false,"values":["true"]},{"schema":{"name":"host","displayName":"Host","helpMessage":"The name or IP address of the host where the LDAP server is running.","type":"jav
 a.lang.String","required":false,"order":0,"confidential":false,"defaultValues":null},"overridable":false,"values":["localhost"]},{"schema":{"name":"passwordHashAlgorithm","displayName":"Password Hash Algorithm","helpMessage":"Indicates the algorithm that the Identity system should use to hash the password. Currently supported values are SSHA, SHA, SSHA1, and SHA1. A blank value indicates that the system will not hash passwords. This will cause cleartext passwords to be stored in LDAP unless the LDAP server performs the hash (Netscape Directory Server and iPlanet Directory Server do).","type":"java.lang.String","required":false,"order":0,"confidential":false,"defaultValues":null},"overridable":false,"values":["SHA"]},{"schema":{"name":"blockSize","displayName":"Block Size","helpMessage":"The maximum number of accounts that can be in a block when retrieving accounts in blocks.","type":"int","required":false,"order":0,"confidential":false,"defaultValues":null},"overridable":false,"valu
 es":[]},{"schema":{"name":"useBlocks","displayName":"Use Blocks","helpMessage":"When performing operations on large numbers of accounts, the accounts are processed in blocks to reduce the amount of memory used by the operation. Select this option to process accounts in blocks.","type":"boolean","required":false,"order":0,"confidential":false,"defaultValues":null},"overridable":false,"values":[false]},{"schema":{"name":"usePagedResultControl","displayName":"Use Paged Result Control","helpMessage":"When enabled, the LDAP Paged Results control is preferred over the VLV control when retrieving accounts.","type":"boolean","required":false,"order":0,"confidential":false,"defaultValues":null},"overridable":false,"values":["false"]},{"schema":{"name":"port","displayName":"TCP Port","helpMessage":"TCP/IP port number used to communicate with the LDAP server.","type":"int","required":false,"order":0,"confidential":false,"defaultValues":null},"overridable":false,"values":[1389]},{"schema":{"nam
 e":"vlvSortAttribute","displayName":"VLV Sort Attribute","helpMessage":"Specify the sort attribute to use for VLV indexes on the resource.","type":"java.lang.String","required":false,"order":0,"confidential":false,"defaultValues":null},"overridable":false,"values":[]},{"schema":{"name":"statusManagementClass","displayName":"Status management class ","helpMessage":"Class to be used to manage enabled/disabled status. If no class is specified then identity status management wont be possible.","type":"java.lang.String","required":false,"order":0,"confidential":false,"defaultValues":null},"overridable":false,"values":["net.tirasa.connid.bundles.ldap.commons.AttributeStatusManagement"]},{"schema":{"name":"accountObjectClasses","displayName":"Account Object Classes","helpMessage":"The object class or classes that will be used when creating new user objects in the LDAP tree. When entering more than one object class, each entry should be on its own line; do not use commas or semi-colons to s
 eparate multiple object classes. Some object classes may require that you specify all object classes in the class hierarchy.","type":"[Ljava.lang.String;","required":false,"order":0,"confidential":false,"defaultValues":null},"overridable":false,"values":["inetOrgPerson"]},{"schema":{"name":"accountUserNameAttributes","displayName":"Account User Name Attributes","helpMessage":"Attribute or attributes which holds the account user name. They will be used when authenticating to find the LDAP entry for the user name to authenticate.","type":"[Ljava.lang.String;","required":false,"order":0,"confidential":false,"defaultValues":null},"overridable":false,"values":["uid"]},{"schema":{"name":"baseContextsToSynchronize","displayName":"Base Contexts to Synchronize","helpMessage":"One or more starting points in the LDAP tree that will be used to determine if a change should be synchronized. The base contexts attribute will be used to synchronize a change if this property is not set.","type":"[Lja
 va.lang.String;","required":false,"order":0,"confidential":false,"defaultValues":null},"overridable":false,"values":["ou=people,o=isp","ou=groups,o=isp"]},{"schema":{"name":"accountSynchronizationFilter","displayName":"LDAP Filter for Accounts to Synchronize","helpMessage":"An optional LDAP filter for the objects to synchronize. Because the change log is for all objects, this filter updates only objects that match the specified filter. If you specify a filter, an object will be synchronized only if it matches the filter and includes a synchronized object class.","type":"java.lang.String","required":false,"order":0,"confidential":false,"defaultValues":null},"overridable":false,"values":[]},{"schema":{"name":"removeLogEntryObjectClassFromFilter","displayName":"Remove Log Entry Object Class from Filter","helpMessage":"If this property is set (the default), the filter used to fetch change log entries does not contain the \"changeLogEntry\" object class, expecting that there are no entri
 es of other object types in the change log.","type":"boolean","required":false,"order":0,"confidential":false,"defaultValues":null},"overridable":false,"values":["false"]},{"schema":{"name":"passwordDecryptionKey","displayName":"Password Decryption Key","helpMessage":"The key to decrypt passwords with when performing password synchronization.","type":"org.identityconnectors.common.security.GuardedByteArray","required":false,"order":0,"confidential":false,"defaultValues":null},"overridable":false,"values":[]},{"schema":{"name":"readSchema","displayName":"Read Schema","helpMessage":"If true, the connector will read the schema from the server. If false, the connector will provide a default schema based on the object classes in the configuration. This property must be true in order to use extended object classes.","type":"boolean","required":false,"order":0,"confidential":false,"defaultValues":null},"overridable":false,"values":["false"]},{"schema":{"name":"ssl","displayName":"SSL","hel
 pMessage":"Select the check box to connect to the LDAP server using SSL.","type":"boolean","required":false,"order":0,"confidential":false,"defaultValues":null},"overridable":false,"values":["false"]},{"schema":{"name":"passwordAttributeToSynchronize","displayName":"Password Attribute to Synchronize","helpMessage":"The name of the password attribute to synchronize when performing password synchronization.","type":"java.lang.String","required":false,"order":0,"confidential":false,"defaultValues":null},"overridable":false,"values":[]},{"schema":{"name":"accountSearchFilter","displayName":"LDAP Filter for Retrieving Accounts","helpMessage":"An optional LDAP filter to control which accounts are returned from the LDAP resource. If no filter is specified, only accounts that include all specified object classes are returned.","type":"java.lang.String","required":false,"order":0,"confidential":false,"defaultValues":null},"overridable":false,"values":["uid=*"]},{"schema":{"name":"passwordDec
 ryptionInitializationVector","displayName":"Password Decryption Initialization Vector","helpMessage":"The initialization vector to decrypt passwords with when performing password synchronization.","type":"org.identityconnectors.common.security.GuardedByteArray","required":false,"order":0,"confidential":false,"defaultValues":null},"overridable":false,"values":[]},{"schema":{"name":"groupMemberAttribute","displayName":"Group Member Attribute","helpMessage":"The name of the group attribute that will be updated with the distinguished name of the user when the user is added to the group.","type":"java.lang.String","required":false,"order":0,"confidential":false,"defaultValues":null},"overridable":false,"values":[]},{"schema":{"name":"failover","displayName":"Failover Servers","helpMessage":"List all servers that should be used for failover in case the preferred server fails. If the preferred server fails, JNDI will connect to the next available server in the list. List all servers in the
  form of \"ldap://ldap.example.com:389/\", which follows the standard LDAP v3 URLs described in RFC 2255. Only the host and port parts of the URL are relevant in this setting.","type":"[Ljava.lang.String;","required":false,"order":0,"confidential":false,"defaultValues":null},"overridable":false,"values":[]},{"schema":{"name":"modifiersNamesToFilterOut","displayName":"Filter Out Changes By","helpMessage":"The names (DNs) of directory administrators to filter from the changes. Changes with the attribute \"modifiersName\" that match entries in this list will be filtered out. The standard value is the administrator name used by this adapter, to prevent loops. Entries should be of the format \"cn=Directory Manager\".","type":"[Ljava.lang.String;","required":false,"order":0,"confidential":false,"defaultValues":null},"overridable":false,"values":[]},{"schema":{"name":"groupNameAttributes","displayName":"Group Name Attributes","helpMessage":"Attribute or attributes which holds the group nam
 e.","type":"[Ljava.lang.String;","required":false,"order":0,"confidential":false,"defaultValues":null},"overridable":false,"values":["cn"]},{"schema":{"name":"uidAttribute","displayName":"Uid Attribute","helpMessage":"The name of the LDAP attribute which is mapped to the Uid attribute.","type":"java.lang.String","required":false,"order":0,"confidential":false,"defaultValues":null},"overridable":false,"values":["cn"]},{"schema":{"name":"respectResourcePasswordPolicyChangeAfterReset","displayName":"Respect Resource Password Policy Change-After-Reset","helpMessage":"When this resource is specified in a Login Module (i.e., this resource is a pass-through authentication target) and the resource password policy is configured for change-after-reset, a user whose resource account password has been administratively reset will be required to change that password after successfully authenticating.","type":"boolean","required":false,"order":0,"confidential":false,"defaultValues":null},"overrida
 ble":false,"values":["false"]},{"schema":{"name":"filterWithOrInsteadOfAnd","displayName":"Filter with Or Instead of And","helpMessage":"Normally the the filter used to fetch change log entries is an and-based filter retrieving an interval of change entries. If this property is set, the filter will or together the required change numbers instead.","type":"boolean","required":false,"order":0,"confidential":false,"defaultValues":null},"overridable":false,"values":["false"]},{"schema":{"name":"principal","displayName":"Principal","helpMessage":"The distinguished name with which to authenticate to the LDAP server.","type":"java.lang.String","required":false,"order":0,"confidential":false,"defaultValues":null},"overridable":false,"values":["uid=admin,ou=system"]},{"schema":{"name":"changeLogBlockSize","displayName":"Change Log Block Size","helpMessage":"The number of change log entries to fetch per query.","type":"int","required":true,"order":0,"confidential":false,"defaultValues":null},
 "overridable":false,"values":[100]},{"schema":{"name":"baseContexts","displayName":"Base Contexts","helpMessage":"One or more starting points in the LDAP tree that will be used when searching the tree. Searches are performed when discovering users from the LDAP server or when looking for the groups of which a user is a member.","type":"[Ljava.lang.String;","required":false,"order":0,"confidential":false,"defaultValues":null},"overridable":false,"values":["ou=people,o=isp","ou=groups,o=isp"]},{"schema":{"name":"passwordAttribute","displayName":"Password Attribute","helpMessage":"The name of the LDAP attribute which holds the password. When changing an user password, the new password is set to this attribute.","type":"java.lang.String","required":false,"order":0,"confidential":false,"defaultValues":null},"overridable":false,"values":["userpassword"]},{"schema":{"name":"changeNumberAttribute","displayName":"Change Number Attribute","helpMessage":"The name of the change number attribute
  in the change log entry.","type":"java.lang.String","required":true,"order":0,"confidential":false,"defaultValues":null},"overridable":false,"values":["changeNumber"]},{"schema":{"name":"objectClassesToSynchronize","displayName":"Object Classes to Synchronize","helpMessage":"The object classes to synchronize. The change log is for all objects; this filters updates to just the listed object classes. You should not list the superclasses of an object class unless you intend to synchronize objects with any of the superclass values. For example, if only \"inetOrgPerson\" objects should be synchronized, but the superclasses of \"inetOrgPerson\" (\"person\", \"organizationalperson\" and \"top\") should be filtered out, then list only \"inetOrgPerson\" here. All objects in LDAP are subclassed from \"top\". For this reason, you should never list \"top\", otherwise no object would be filtered.","type":"[Ljava.lang.String;","required":true,"order":0,"confidential":false,"defaultValues":null},
 "overridable":false,"values":["inetOrgPerson","groupOfUniqueNames"]},{"schema":{"name":"credentials","displayName":"Password","helpMessage":"Password for the principal.","type":"org.identityconnectors.common.security.GuardedString","required":false,"order":0,"confidential":false,"defaultValues":null},"overridable":false,"values":["secret"]},{"schema":{"name":"attributesToSynchronize","displayName":"Attributes to Synchronize","helpMessage":"The names of the attributes to synchronize. This ignores updates from the change log if they do not update any of the named attributes. For example, if only \"department\" is listed, then only changes that affect \"department\" will be processed. All other updates are ignored. If blank (the default), then all changes are processed.","type":"[Ljava.lang.String;","required":false,"order":0,"confidential":false,"defaultValues":null},"overridable":false,"values":[]},{"schema":{"name":"maintainPosixGroupMembership","displayName":"Maintain POSIX Group M
 embership","helpMessage":"When enabled and a user is renamed or deleted, update any POSIX groups to which the user belongs to reflect the new name. Otherwise, the LDAP resource must maintain referential integrity with respect to group membership.","type":"boolean","required":false,"order":0,"confidential":false,"defaultValues":null},"overridable":false,"values":["truemaintainLdapGroupMembership"]}]'/>
-  <ConnInstance_capabilities ConnInstance_id="105" capability="ONE_PHASE_CREATE"/>
-  <ConnInstance_capabilities ConnInstance_id="105" capability="ONE_PHASE_UPDATE"/>
-  <ConnInstance_capabilities ConnInstance_id="105" capability="ONE_PHASE_DELETE"/>
-  <ConnInstance_capabilities ConnInstance_id="105" capability="SEARCH"/>
-  
-  <ConnInstance id="106" displayName="H2-test2"
-                location="connid://${testconnectorserver.key}@localhost:${testconnectorserver.port}"
-                bundleName="net.tirasa.connid.bundles.db.table"
-                connectorName="net.tirasa.connid.bundles.db.table.DatabaseTableConnector"
-                version="${connid.database.version}"
-                jsonConf='[{"schema":{"name":"disabledStatusValue","displayName":null,"helpMessage":null,"type":"java.lang.String","required":false,"order":0,"confidential":false,"defaultValues":null},"overridable":false,"values":["false"]},{"schema":{"name":"user","displayName":null,"helpMessage":null,"type":"java.lang.String","required":false,"order":0,"confidential":false,"defaultValues":null},"overridable":false,"values":["sa"]},{"schema":{"name":"keyColumn","displayName":null,"helpMessage":null,"type":"java.lang.String","required":true,"order":0,"confidential":false,"defaultValues":null},"overridable":false,"values":["id"]},{"schema":{"name":"cipherAlgorithm","displayName":null,"helpMessage":null,"type":"java.lang.String","required":true,"order":0,"confidential":false,"defaultValues":null},"overridable":false,"values":["SHA1"]},{"schema":{"name":"enabledStatusValue","displayName":null,"helpMessage":null,"type":"java.lang.String","required":false,"order":0,"confidential":false,"
 defaultValues":null},"overridable":false,"values":["true"]},{"schema":{"name":"passwordColumn","displayName":null,"helpMessage":null,"type":"java.lang.String","required":false,"order":0,"confidential":false,"defaultValues":null},"overridable":false,"values":["password"]},{"schema":{"name":"jdbcDriver","displayName":null,"helpMessage":null,"type":"java.lang.String","required":false,"order":0,"confidential":false,"defaultValues":null},"overridable":false,"values":["org.h2.Driver"]},{"schema":{"name":"retrievePassword","displayName":null,"helpMessage":null,"type":"java.lang.Boolean","required":false,"order":0,"confidential":false,"defaultValues":null},"overridable":false,"values":["true"]},{"schema":{"name":"defaultStatusValue","displayName":null,"helpMessage":null,"type":"java.lang.String","required":false,"order":0,"confidential":false,"defaultValues":null},"overridable":false,"values":["true"]},{"schema":{"name":"password","displayName":null,"helpMessage":null,"type":"org.identityco
 nnectors.common.security.GuardedString","required":false,"order":0,"confidential":false,"defaultValues":null},"overridable":false,"values":["sa"]},{"schema":{"name":"statusColumn","displayName":null,"helpMessage":null,"type":"java.lang.String","required":false,"order":0,"confidential":false,"defaultValues":null},"overridable":false,"values":["status"]},{"schema":{"name":"jdbcUrlTemplate","displayName":null,"helpMessage":null,"type":"java.lang.String","required":false,"order":0,"confidential":false,"defaultValues":null},"overridable":false,"values":["${testdb.url}"]},{"schema":{"name":"table","displayName":null,"helpMessage":null,"type":"java.lang.String","required":true,"order":0,"confidential":false,"defaultValues":null},"overridable":false,"values":["test2"]}]'/>
-  <ConnInstance_capabilities ConnInstance_id="106" capability="ONE_PHASE_CREATE"/>
-  <ConnInstance_capabilities ConnInstance_id="106" capability="ONE_PHASE_UPDATE"/>
-  <ConnInstance_capabilities ConnInstance_id="106" capability="SEARCH"/>
-  <ConnInstance_capabilities ConnInstance_id="106" capability="SYNC"/>
-  
-  <ConnInstance id="107" bundleName="net.tirasa.connid.bundles.db.table" 
-                location="connid://${testconnectorserver.key}@localhost:${testconnectorserver.port}"
-                connectorName="net.tirasa.connid.bundles.db.table.DatabaseTableConnector" 
-                displayName="H2-testsync" version="${connid.database.version}"
-                jsonConf='[{"schema":{"name":"changeLogColumn","displayName":"Change Log Column (Sync)","helpMessage":"=&lt;b&gt;Change Log Column&lt;/b&gt;&lt;br&gt;The change log column store the latest change time. Providing this value the Sync capabilities are activated.","type":"java.lang.String","required":false,"order":21,"confidential":false,"defaultValues":null},"overridable":false,"values":[]},{"schema":{"name":"nativeTimestamps","displayName":"Native Timestamps ","helpMessage":"&lt;b&gt;Native Timestamps&lt;/b&gt;&lt;br&gt;Select to retrieve Timestamp data type of the columns in java.sql.Timestamp format from the database table.","type":"boolean","required":false,"order":18,"confidential":false,"defaultValues":null},"overridable":false,"values":["false"]},{"schema":{"name":"cipherAlgorithm","displayName":"Password cipher algorithm (defaults to CLEARTEXT)","helpMessage":"Cipher algorithm used to encode password before to store it onto the database table.\nSpecify one of th
 e values among CLEARTEXT,AES, MD5, SHA1, SHA256 or a custom implementation identified by its class name.","type":"java.lang.String","required":false,"order":24,"confidential":false,"defaultValues":null},"overridable":false,"values":[]},{"schema":{"name":"enabledStatusValue","displayName":"Enabled Status Value","helpMessage":"&lt;b&gt;Enabled Status Value&lt;/b&gt;&lt;br&gt;Enter the value for enabled status.","type":"java.lang.String","required":false,"order":12,"confidential":false,"defaultValues":null},"overridable":false,"values":[]},{"schema":{"name":"retrievePassword","displayName":"Retrieve password","helpMessage":"Specify if password must be retrieved by default.","type":"boolean","required":true,"order":27,"confidential":false,"defaultValues":null},"overridable":false,"values":["false"]},{"schema":{"name":"datasource","displayName":"Datasource Path","helpMessage":"&lt;b&gt;JDBC Data Source Name/Path&lt;/b&gt;&lt;br&gt;Enter the JDBC Data Source Name/Path to connect to the Or
 acle server. If specified, connector will only try to connect using Datasource and ignore other resource parameters specified.&lt;br&gt;the example value is: &lt;CODE&gt;jdbc/SampleDataSourceName&lt;/CODE&gt;","type":"java.lang.String","required":false,"order":22,"confidential":false,"defaultValues":null},"overridable":false,"values":[]},{"schema":{"name":"allNative","displayName":"All native","helpMessage":"&lt;b&gt;All native&lt;/b&gt;&lt;br&gt;Select to retrieve all data type of the columns in a native format from the database table.","type":"boolean","required":false,"order":19,"confidential":false,"defaultValues":null},"overridable":false,"values":["false"]},{"schema":{"name":"user","displayName":"User","helpMessage":"&lt;b&gt;User&lt;/b&gt;&lt;br&gt;Enter the name of the mandatory Database user with permission to account table.","type":"java.lang.String","required":false,"order":4,"confidential":false,"defaultValues":null},"overridable":false,"values":["sa"]},{"schema":{"name"
 :"pwdEncodeToLowerCase","displayName":"Force password encoding to lower case","helpMessage":"Force password encoding to lower case.","type":"boolean","required":false,"order":26,"confidential":false,"defaultValues":null},"overridable":false,"values":["false"]},{"schema":{"name":"jdbcUrlTemplate","displayName":"JDBC Connection URL","helpMessage":"&lt;b&gt;JDBC Connection URL&lt;/b&gt;&lt;br&gt;Specify the JDBC Driver Connection URL.&lt;br&gt; Oracle template is jdbc:oracle:thin:@[host]:[port(1521)]:[DB].&lt;br&gt;  MySQL template is jdbc:mysql://[host]:[port(3306)]/[db], for more info, read the JDBC driver documentation.&lt;br&gt;Could be empty if datasource is provided.","type":"java.lang.String","required":false,"order":15,"confidential":false,"defaultValues":null},"overridable":false,"values":["${testdb.url}"]},{"schema":{"name":"keyColumn","displayName":"Key Column","helpMessage":"&lt;b&gt;Key Column&lt;/b&gt;&lt;br&gt;This mandatory column value will be used as the unique identi
 fier for rows in the table.&lt;br&gt;","type":"java.lang.String","required":true,"order":8,"confidential":false,"defaultValues":null},"overridable":false,"values":["id"]},{"schema":{"name":"validConnectionQuery","displayName":"Validate Connection Query","helpMessage":"&lt;b&gt;Validate Connection Query&lt;/b&gt;&lt;br&gt;There can be specified the check connection alive query. If empty, default implementation will test it using the switch on/off the autocommit. Some select 1 from dummy table could be more efficient.","type":"java.lang.String","required":false,"order":20,"confidential":false,"defaultValues":null},"overridable":false,"values":[]},{"schema":{"name":"rethrowAllSQLExceptions","displayName":"Rethrow all SQLExceptions","helpMessage":"If this is not checked, SQL statements which throw SQLExceptions with a 0 ErrorCode will be have the exception caught and suppressed. Check it to have exceptions with 0 ErrorCodes rethrown.","type":"boolean","required":false,"order":17,"confid
 ential":false,"defaultValues":null},"overridable":false,"values":["false"]},{"schema":{"name":"passwordColumn","displayName":"Password Column","helpMessage":"&lt;b&gt;Password Column&lt;/b&gt;&lt;br&gt;Enter the name of the column in the table that will hold the password values. If empty, no validation on resource and passwords are activated.","type":"java.lang.String","required":false,"order":9,"confidential":false,"defaultValues":null},"overridable":false,"values":[]},{"schema":{"name":"jndiProperties","displayName":"Initial JNDI Properties","helpMessage":"&lt;b&gt;Initial JNDI Properties&lt;/b&gt;&lt;br&gt;Could be empty or enter the JDBC JNDI Initial context factory, context provider in a format: key = value.","type":"[Ljava.lang.String;","required":false,"order":23,"confidential":false,"defaultValues":null},"overridable":false,"values":[]},{"schema":{"name":"password","displayName":"User Password","helpMessage":"&lt;b&gt;User Password&lt;/b&gt;&lt;br&gt;Enter a user account tha
 t has permission to access accounts table.","type":"org.identityconnectors.common.security.GuardedString","required":false,"order":5,"confidential":true,"defaultValues":null},"overridable":false,"values":["sa"]},{"schema":{"name":"host","displayName":"Host","helpMessage":"&lt;b&gt;Host&lt;/b&gt;&lt;br&gt;Enter the name of the host where the database is running.","type":"java.lang.String","required":false,"order":2,"confidential":false,"defaultValues":null},"overridable":false,"values":[]},{"schema":{"name":"port","displayName":"Port","helpMessage":"&lt;b&gt;TCP Port&lt;/b&gt;&lt;br&gt;Enter the port number the database server is listening on.","type":"java.lang.String","required":false,"order":3,"confidential":false,"defaultValues":null},"overridable":false,"values":[]},{"schema":{"name":"statusColumn","displayName":"Status Column","helpMessage":"&lt;b&gt;Status Column&lt;/b&gt;&lt;br&gt;Enter the name of the column in the table that will hold the status values. If empty enabled and
  disabled operation wont be performed.","type":"java.lang.String","required":false,"order":10,"confidential":false,"defaultValues":null},"overridable":false,"values":[]},{"schema":{"name":"pwdEncodeToUpperCase","displayName":"Force password encoding to upper case","helpMessage":"Force password encoding to upper case.","type":"boolean","required":false,"order":25,"confidential":false,"defaultValues":null},"overridable":false,"values":["false"]},{"schema":{"name":"enableEmptyString","displayName":"Enable writing empty string","helpMessage":"&lt;b&gt;Enable writing empty string&lt;/b&gt;&lt;br&gt;Select to enable support for writing an empty strings, instead of a NULL value, in character based columns defined as not-null in the table schema. This option does not influence the way strings are written for Oracle based tables. By default empty strings are written as a NULL value.","type":"boolean","required":false,"order":16,"confidential":false,"defaultValues":null},"overridable":false,"
 values":["false"]},{"schema":{"name":"database","displayName":"Database","helpMessage":"&lt;b&gt;Database&lt;/b&gt;&lt;br&gt;Enter the name of the database on the database server that contains the table.","type":"java.lang.String","required":false,"order":6,"confidential":false,"defaultValues":null},"overridable":false,"values":[]},{"schema":{"name":"defaultStatusValue","displayName":"Default Status Value","helpMessage":"&lt;b&gt;Default Status Value&lt;/b&gt;&lt;br&gt;Enter the value for status in case of status not specified.","type":"java.lang.String","required":false,"order":13,"confidential":false,"defaultValues":null},"overridable":false,"values":[]},{"schema":{"name":"table","displayName":"Table","helpMessage":"&lt;b&gt;Table&lt;/b&gt;&lt;br&gt;Enter the name of the table in the database that contains the accounts.","type":"java.lang.String","required":true,"order":7,"confidential":false,"defaultValues":null},"overridable":false,"values":["testsync"]},{"schema":{"name":"disab
 ledStatusValue","displayName":"Disabled Status Value","helpMessage":"&lt;b&gt;Disabled Status Value&lt;/b&gt;&lt;br&gt;Enter the value for disabled status.","type":"java.lang.String","required":false,"order":11,"confidential":false,"defaultValues":null},"overridable":false,"values":[]},{"schema":{"name":"jdbcDriver","displayName":"JDBC Driver","helpMessage":"&lt;b&gt;JDBC Driver&lt;/b&gt;&lt;br&gt;Specify the JDBC Driver class name. Oracle is oracle.jdbc.driver.OracleDriver. MySQL is org.gjt.mm.mysql.Driver.&lt;br&gt;Could be empty if datasource is provided.","type":"java.lang.String","required":false,"order":14,"confidential":false,"defaultValues":null},"overridable":false,"values":["org.h2.Driver"]},{"schema":{"name":"quoting","displayName":"Name Quoting","helpMessage":"&lt;b&gt;Name Quoting&lt;/b&gt;&lt;br&gt;Select whether database column names for this resource should be quoted, and the quoting characters. By default, database column names are not quoted (None). For other selec
 tions (Single, Double, Back, or Brackets), column names will appear between single quotes, double quotes, back quotes, or brackets in the SQL generated to access the database.","type":"java.lang.String","required":false,"order":1,"confidential":false,"defaultValues":null},"overridable":false,"values":[]},{"schema":{"name":"cipherKey","displayName":"Password cipher key","helpMessage":"Specify key in case of reversible algorithm.","type":"java.lang.String","required":false,"order":25,"confidential":false,"defaultValues":null},"overridable":false,"values":[]}]'/>
-  <ConnInstance_capabilities ConnInstance_id="107" capability="ONE_PHASE_CREATE"/>
-  <ConnInstance_capabilities ConnInstance_id="107" capability="TWO_PHASES_CREATE"/>
-  <ConnInstance_capabilities ConnInstance_id="107" capability="ONE_PHASE_UPDATE"/>
-  <ConnInstance_capabilities ConnInstance_id="107" capability="TWO_PHASES_UPDATE"/>
-  <ConnInstance_capabilities ConnInstance_id="107" capability="ONE_PHASE_DELETE"/>
-  <ConnInstance_capabilities ConnInstance_id="107" capability="TWO_PHASES_DELETE"/>
-  <ConnInstance_capabilities ConnInstance_id="107" capability="SEARCH"/>
-  
-  <ConnInstance id="108" bundleName="net.tirasa.connid.bundles.db.scriptedsql" 
-                location="connid://${testconnectorserver.key}@localhost:${testconnectorserver.port}"
-                connectorName="net.tirasa.connid.bundles.db.scriptedsql.ScriptedSQLConnector"
-                displayName="Scripted SQL" version="${connid.database.version}"
-                jsonConf='[{&quot;schema&quot;:{&quot;name&quot;:&quot;updateScriptFileName&quot;,&quot;displayName&quot;:&quot;updateScriptFileName&quot;,&quot;helpMessage&quot;:&quot;updateScriptFileName&quot;,&quot;type&quot;:&quot;java.lang.String&quot;,&quot;required&quot;:false,&quot;order&quot;:0,&quot;confidential&quot;:false,&quot;defaultValues&quot;:[]},&quot;overridable&quot;:false,&quot;values&quot;:[&quot;${basedir}/src/main/resources/scriptedsql/UpdateScript.groovy&quot;]},{&quot;schema&quot;:{&quot;name&quot;:&quot;testScript&quot;,&quot;displayName&quot;:&quot;testScript&quot;,&quot;helpMessage&quot;:&quot;testScript&quot;,&quot;type&quot;:&quot;java.lang.String&quot;,&quot;required&quot;:false,&quot;order&quot;:0,&quot;confidential&quot;:false,&quot;defaultValues&quot;:[&quot;&quot;]},&quot;overridable&quot;:false,&quot;values&quot;:[]},{&quot;schema&quot;:{&quot;name&quot;:&quot;host&quot;,&quot;displayName&quot;:&quot;Host&quot;,&quot;helpMessage&quot;:&quot;&lt;b
 &gt;Host&lt;/b&gt;&lt;br/&gt;Enter the name of the host where the database is running.&quot;,&quot;type&quot;:&quot;java.lang.String&quot;,&quot;required&quot;:false,&quot;order&quot;:2,&quot;confidential&quot;:false,&quot;defaultValues&quot;:[&quot;localhost&quot;]},&quot;overridable&quot;:false},{&quot;schema&quot;:{&quot;name&quot;:&quot;port&quot;,&quot;displayName&quot;:&quot;Port&quot;,&quot;helpMessage&quot;:&quot;&lt;b&gt;TCP Port&lt;/b&gt;&lt;br/&gt;Enter the port number the database server is listening on.&quot;,&quot;type&quot;:&quot;java.lang.String&quot;,&quot;required&quot;:false,&quot;order&quot;:3,&quot;confidential&quot;:false,&quot;defaultValues&quot;:[&quot;3306&quot;]},&quot;overridable&quot;:false},{&quot;schema&quot;:{&quot;name&quot;:&quot;database&quot;,&quot;displayName&quot;:&quot;Database&quot;,&quot;helpMessage&quot;:&quot;&lt;b&gt;Database&lt;/b&gt;&lt;br/&gt;Enter the name of the database on the database server that contains the table.&quot;,&quot;type&
 quot;:&quot;java.lang.String&quot;,&quot;required&quot;:false,&quot;order&quot;:6,&quot;confidential&quot;:false,&quot;defaultValues&quot;:[&quot;&quot;]},&quot;overridable&quot;:false},{&quot;schema&quot;:{&quot;name&quot;:&quot;createScript&quot;,&quot;displayName&quot;:&quot;createScript&quot;,&quot;helpMessage&quot;:&quot;createScript&quot;,&quot;type&quot;:&quot;java.lang.String&quot;,&quot;required&quot;:false,&quot;order&quot;:0,&quot;confidential&quot;:false,&quot;defaultValues&quot;:[&quot;&quot;]},&quot;overridable&quot;:false,&quot;values&quot;:[]},{&quot;schema&quot;:{&quot;name&quot;:&quot;jdbcUrlTemplate&quot;,&quot;displayName&quot;:&quot;JDBC Connection URL&quot;,&quot;helpMessage&quot;:&quot;&lt;b&gt;JDBC Connection URL&lt;/b&gt;&lt;br/&gt;Specify the JDBC Driver Connection URL.&lt;br/&gt; Oracle template is jdbc:oracle:thin:@[host]:[port(1521)]:[DB].&lt;br/&gt;  MySQL template is jdbc:mysql://[host]:[port(3306)]/[db], for more info, read the JDBC driver documentati
 on.&lt;br/&gt;Could be empty if datasource is provided.&quot;,&quot;type&quot;:&quot;java.lang.String&quot;,&quot;required&quot;:false,&quot;order&quot;:11,&quot;confidential&quot;:false,&quot;defaultValues&quot;:[&quot;jdbc:mysql://%h:%p/%d&quot;]},&quot;overridable&quot;:false,&quot;values&quot;:[&quot;${testdb.url}&quot;]},{&quot;schema&quot;:{&quot;name&quot;:&quot;jndiProperties&quot;,&quot;displayName&quot;:&quot;Initial JNDI Properties&quot;,&quot;helpMessage&quot;:&quot;&lt;b&gt;Initial JNDI Properties&lt;/b&gt;&lt;br/&gt;Could be empty or enter the JDBC JNDI Initial context factory, context provider in a format: key = value.&quot;,&quot;type&quot;:&quot;[Ljava.lang.String;&quot;,&quot;required&quot;:false,&quot;order&quot;:21,&quot;confidential&quot;:false,&quot;defaultValues&quot;:[]},&quot;overridable&quot;:false,&quot;values&quot;:[]},{&quot;schema&quot;:{&quot;name&quot;:&quot;enableEmptyString&quot;,&quot;displayName&quot;:&quot;Enable writing empty string&quot;,&quot;
 helpMessage&quot;:&quot;&lt;b&gt;Enable writing empty string&lt;/b&gt;&lt;br/&gt;Select to enable support for writing an empty strings, instead of a NULL value, in character based columns defined as not-null in the table schema. This option does not influence the way strings are written for Oracle based tables. By default empty strings are written as a NULL value.&quot;,&quot;type&quot;:&quot;boolean&quot;,&quot;required&quot;:false,&quot;order&quot;:12,&quot;confidential&quot;:false,&quot;defaultValues&quot;:[false]},&quot;overridable&quot;:false,&quot;values&quot;:[&quot;false&quot;]},{&quot;schema&quot;:{&quot;name&quot;:&quot;allNative&quot;,&quot;displayName&quot;:&quot;All native&quot;,&quot;helpMessage&quot;:&quot;&lt;b&gt;All native&lt;/b&gt;&lt;br/&gt;Select to retrieve all data type of the columns in a native format from the database table.&quot;,&quot;type&quot;:&quot;boolean&quot;,&quot;required&quot;:false,&quot;order&quot;:16,&quot;confidential&quot;:false,&quot;defaul
 tValues&quot;:[false]},&quot;overridable&quot;:false,&quot;values&quot;:[false]},{&quot;schema&quot;:{&quot;name&quot;:&quot;password&quot;,&quot;displayName&quot;:&quot;User Password&quot;,&quot;helpMessage&quot;:&quot;&lt;b&gt;User Password&lt;/b&gt;&lt;br/&gt;Enter a user account that has permission to access accounts table.&quot;,&quot;type&quot;:&quot;org.identityconnectors.common.security.GuardedString&quot;,&quot;required&quot;:false,&quot;order&quot;:5,&quot;confidential&quot;:true,&quot;defaultValues&quot;:[]},&quot;overridable&quot;:false,&quot;values&quot;:[&quot;${testdb.password}&quot;]},{&quot;schema&quot;:{&quot;name&quot;:&quot;validConnectionQuery&quot;,&quot;displayName&quot;:&quot;Validate Connection Query&quot;,&quot;helpMessage&quot;:&quot;&lt;b&gt;Validate Connection Query&lt;/b&gt;&lt;br/&gt;There can be specified the check connection alive query. If empty, default implementation will test it using the switch on/off the autocommit. Some select 1 from dummy tab
 le could be more efficient.&quot;,&quot;type&quot;:&quot;java.lang.String&quot;,&quot;required&quot;:false,&quot;order&quot;:17,&quot;confidential&quot;:false,&quot;defaultValues&quot;:[]},&quot;overridable&quot;:false,&quot;values&quot;:[]},{&quot;schema&quot;:{&quot;name&quot;:&quot;reloadScriptOnExecution&quot;,&quot;displayName&quot;:&quot;reloadScriptOnExecution&quot;,&quot;helpMessage&quot;:&quot;reloadScriptOnExecution&quot;,&quot;type&quot;:&quot;boolean&quot;,&quot;required&quot;:false,&quot;order&quot;:0,&quot;confidential&quot;:false,&quot;defaultValues&quot;:[false]},&quot;overridable&quot;:false,&quot;values&quot;:[&quot;true&quot;]},{&quot;schema&quot;:{&quot;name&quot;:&quot;schemaScriptFileName&quot;,&quot;displayName&quot;:&quot;schemaScriptFileName&quot;,&quot;helpMessage&quot;:&quot;schemaScriptFileName&quot;,&quot;type&quot;:&quot;java.lang.String&quot;,&quot;required&quot;:false,&quot;order&quot;:0,&quot;confidential&quot;:false,&quot;defaultValues&quot;:[]},&qu
 ot;overridable&quot;:true,&quot;values&quot;:[&quot;${basedir}/src/main/resources/scriptedsql/SchemaScript.groovy&quot;]},{&quot;schema&quot;:{&quot;name&quot;:&quot;jdbcDriver&quot;,&quot;displayName&quot;:&quot;JDBC Driver&quot;,&quot;helpMessage&quot;:&quot;&lt;b&gt;JDBC Driver&lt;/b&gt;&lt;br/&gt;Specify the JDBC Driver class name. Oracle is oracle.jdbc.driver.OracleDriver. MySQL is org.gjt.mm.mysql.Driver.&lt;br/&gt;Could be empty if datasource is provided.&quot;,&quot;type&quot;:&quot;java.lang.String&quot;,&quot;required&quot;:false,&quot;order&quot;:10,&quot;confidential&quot;:false,&quot;defaultValues&quot;:[&quot;com.mysql.jdbc.Driver&quot;]},&quot;overridable&quot;:false,&quot;values&quot;:[&quot;${testdb.driver}&quot;]},{&quot;schema&quot;:{&quot;name&quot;:&quot;testScriptFileName&quot;,&quot;displayName&quot;:&quot;testScriptFileName&quot;,&quot;helpMessage&quot;:&quot;testScriptFileName&quot;,&quot;type&quot;:&quot;java.lang.String&quot;,&quot;required&quot;:false,&qu
 ot;order&quot;:0,&quot;confidential&quot;:false,&quot;defaultValues&quot;:[]},&quot;overridable&quot;:true,&quot;values&quot;:[&quot;${basedir}/src/main/resources/scriptedsql/TestScript.groovy&quot;]},{&quot;schema&quot;:{&quot;name&quot;:&quot;quoting&quot;,&quot;displayName&quot;:&quot;Name Quoting&quot;,&quot;helpMessage&quot;:&quot;&lt;b&gt;Name Quoting&lt;/b&gt;&lt;br/&gt;Select whether database column names for this resource should be quoted, and the quoting characters. By default, database column names are not quoted (None). For other selections (Single, Double, Back, or Brackets), column names will appear between single quotes, double quotes, back quotes, or brackets in the SQL generated to access the database.&quot;,&quot;type&quot;:&quot;java.lang.String&quot;,&quot;required&quot;:false,&quot;order&quot;:-1,&quot;confidential&quot;:false,&quot;defaultValues&quot;:[&quot;&quot;]},&quot;overridable&quot;:false,&quot;values&quot;:[]},{&quot;schema&quot;:{&quot;name&quot;:&quo
 t;createScriptFileName&quot;,&quot;displayName&quot;:&quot;createScriptFileName&quot;,&quot;helpMessage&quot;:&quot;createScriptFileName&quot;,&quot;type&quot;:&quot;java.lang.String&quot;,&quot;required&quot;:false,&quot;order&quot;:0,&quot;confidential&quot;:false,&quot;defaultValues&quot;:[]},&quot;overridable&quot;:false,&quot;values&quot;:[&quot;${basedir}/src/main/resources/scriptedsql/CreateScript.groovy&quot;]},{&quot;schema&quot;:{&quot;name&quot;:&quot;clearTextPasswordToScript&quot;,&quot;displayName&quot;:&quot;clearTextPasswordToScript&quot;,&quot;helpMessage&quot;:&quot;clearTextPasswordToScript&quot;,&quot;type&quot;:&quot;boolean&quot;,&quot;required&quot;:false,&quot;order&quot;:0,&quot;confidential&quot;:false,&quot;defaultValues&quot;:[true]},&quot;overridable&quot;:false,&quot;values&quot;:[&quot;false&quot;]},{&quot;schema&quot;:{&quot;name&quot;:&quot;nativeTimestamps&quot;,&quot;displayName&quot;:&quot;Native Timestamps&quot;,&quot;helpMessage&quot;:&quot;&lt;
 b&gt;Native Timestamps&lt;/b&gt;&lt;br/&gt;Select to retrieve Timestamp data type of the columns in java.sql.Timestamp format from the database table.&quot;,&quot;type&quot;:&quot;boolean&quot;,&quot;required&quot;:false,&quot;order&quot;:15,&quot;confidential&quot;:false,&quot;defaultValues&quot;:[false]},&quot;overridable&quot;:false,&quot;values&quot;:[false]},{&quot;schema&quot;:{&quot;name&quot;:&quot;syncScript&quot;,&quot;displayName&quot;:&quot;syncScript&quot;,&quot;helpMessage&quot;:&quot;syncScript&quot;,&quot;type&quot;:&quot;java.lang.String&quot;,&quot;required&quot;:false,&quot;order&quot;:0,&quot;confidential&quot;:false,&quot;defaultValues&quot;:[&quot;&quot;]},&quot;overridable&quot;:false,&quot;values&quot;:[]},{&quot;schema&quot;:{&quot;name&quot;:&quot;autoCommit&quot;,&quot;displayName&quot;:&quot;autoCommit&quot;,&quot;helpMessage&quot;:&quot;autoCommit&quot;,&quot;type&quot;:&quot;boolean&quot;,&quot;required&quot;:false,&quot;order&quot;:0,&quot;confidential
 &quot;:false,&quot;defaultValues&quot;:[true]},&quot;overridable&quot;:false,&quot;values&quot;:[true]},{&quot;schema&quot;:{&quot;name&quot;:&quot;scriptingLanguage&quot;,&quot;displayName&quot;:&quot;scriptingLanguage&quot;,&quot;helpMessage&quot;:&quot;scriptingLanguage&quot;,&quot;type&quot;:&quot;java.lang.String&quot;,&quot;required&quot;:false,&quot;order&quot;:0,&quot;confidential&quot;:false,&quot;defaultValues&quot;:[&quot;GROOVY&quot;]},&quot;overridable&quot;:false,&quot;values&quot;:[&quot;GROOVY&quot;]},{&quot;schema&quot;:{&quot;name&quot;:&quot;datasource&quot;,&quot;displayName&quot;:&quot;Datasource Path&quot;,&quot;helpMessage&quot;:&quot;&lt;b&gt;JDBC Data Source Name/Path&lt;/b&gt;&lt;br/&gt;Enter the JDBC Data Source Name/Path to connect to the Oracle server. If specified, connector will only try to connect using Datasource and ignore other resource parameters specified.&lt;br/&gt;the example value is: &lt;CODE&gt;jdbc/SampleDataSourceName&lt;/CODE&gt;&quot;,&q
 uot;type&quot;:&quot;java.lang.String&quot;,&quot;required&quot;:false,&quot;order&quot;:20,&quot;confidential&quot;:false,&quot;defaultValues&quot;:[&quot;&quot;]},&quot;overridable&quot;:false,&quot;values&quot;:[]},{&quot;schema&quot;:{&quot;name&quot;:&quot;deleteScript&quot;,&quot;displayName&quot;:&quot;deleteScript&quot;,&quot;helpMessage&quot;:&quot;deleteScript&quot;,&quot;type&quot;:&quot;java.lang.String&quot;,&quot;required&quot;:false,&quot;order&quot;:0,&quot;confidential&quot;:false,&quot;defaultValues&quot;:[&quot;&quot;]},&quot;overridable&quot;:false,&quot;values&quot;:[]},{&quot;schema&quot;:{&quot;name&quot;:&quot;rethrowAllSQLExceptions&quot;,&quot;displayName&quot;:&quot;Rethrow all SQLExceptions&quot;,&quot;helpMessage&quot;:&quot;If this is not checked, SQL statements which throw SQLExceptions with a 0 ErrorCode will be have the exception caught and suppressed. Check it to have exceptions with 0 ErrorCodes rethrown.&quot;,&quot;type&quot;:&quot;boolean&quot;,
 &quot;required&quot;:false,&quot;order&quot;:14,&quot;confidential&quot;:false,&quot;defaultValues&quot;:[true]},&quot;overridable&quot;:false,&quot;values&quot;:[true]},{&quot;schema&quot;:{&quot;name&quot;:&quot;syncScriptFileName&quot;,&quot;displayName&quot;:&quot;syncScriptFileName&quot;,&quot;helpMessage&quot;:&quot;syncScriptFileName&quot;,&quot;type&quot;:&quot;java.lang.String&quot;,&quot;required&quot;:false,&quot;order&quot;:0,&quot;confidential&quot;:false,&quot;defaultValues&quot;:[]},&quot;overridable&quot;:true,&quot;values&quot;:[&quot;${basedir}/src/main/resources/scriptedsql/SyncScript.groovy&quot;]},{&quot;schema&quot;:{&quot;name&quot;:&quot;updateScript&quot;,&quot;displayName&quot;:&quot;updateScript&quot;,&quot;helpMessage&quot;:&quot;updateScript&quot;,&quot;type&quot;:&quot;java.lang.String&quot;,&quot;required&quot;:false,&quot;order&quot;:0,&quot;confidential&quot;:false,&quot;defaultValues&quot;:[&quot;&quot;]},&quot;overridable&quot;:false,&quot;values&q
 uot;:[]},{&quot;schema&quot;:{&quot;name&quot;:&quot;user&quot;,&quot;displayName&quot;:&quot;User&quot;,&quot;helpMessage&quot;:&quot;&lt;b&gt;User&lt;/b&gt;&lt;br/&gt;Enter the name of the mandatory Database user with permission to account table.&quot;,&quot;type&quot;:&quot;java.lang.String&quot;,&quot;required&quot;:false,&quot;order&quot;:4,&quot;confidential&quot;:false,&quot;defaultValues&quot;:[&quot;&quot;]},&quot;overridable&quot;:false,&quot;values&quot;:[&quot;${testdb.username}&quot;]},{&quot;schema&quot;:{&quot;name&quot;:&quot;deleteScriptFileName&quot;,&quot;displayName&quot;:&quot;deleteScriptFileName&quot;,&quot;helpMessage&quot;:&quot;deleteScriptFileName&quot;,&quot;type&quot;:&quot;java.lang.String&quot;,&quot;required&quot;:false,&quot;order&quot;:0,&quot;confidential&quot;:false,&quot;defaultValues&quot;:[]},&quot;overridable&quot;:false,&quot;values&quot;:[&quot;${basedir}/src/main/resources/scriptedsql/DeleteScript.groovy&quot;]},{&quot;schema&quot;:{&quot;n
 ame&quot;:&quot;searchScriptFileName&quot;,&quot;displayName&quot;:&quot;searchScriptFileName&quot;,&quot;helpMessage&quot;:&quot;searchScriptFileName&quot;,&quot;type&quot;:&quot;java.lang.String&quot;,&quot;required&quot;:false,&quot;order&quot;:0,&quot;confidential&quot;:false,&quot;defaultValues&quot;:[]},&quot;overridable&quot;:true,&quot;values&quot;:[&quot;${basedir}/src/main/resources/scriptedsql/SearchScript.groovy&quot;]},{&quot;schema&quot;:{&quot;name&quot;:&quot;searchScript&quot;,&q

<TRUNCATED>

[14/31] syncope git commit: [SYNCOPE-652] Still several things to refine, but it starts taking shape

Posted by md...@apache.org.
http://git-wip-us.apache.org/repos/asf/syncope/blob/6dfedd8f/core/persistence-jpa/src/test/resources/domains/Master.properties
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/test/resources/domains/Master.properties b/core/persistence-jpa/src/test/resources/domains/Master.properties
new file mode 100644
index 0000000..40a3852
--- /dev/null
+++ b/core/persistence-jpa/src/test/resources/domains/Master.properties
@@ -0,0 +1,28 @@
+# 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.
+Master.driverClassName=org.h2.Driver
+Master.url=jdbc:h2:mem:syncopedb;DB_CLOSE_DELAY=-1
+Master.schema=
+Master.username=sa
+Master.password=
+Master.databasePlatform=org.apache.openjpa.jdbc.sql.H2Dictionary
+Master.orm=META-INF/spring-orm.xml
+
+# note: other connection pool settings can also be configured here, see DataSource definition
+Master.pool.validationQuery=SELECT 1
+
+Master.audit.sql=audit.sql