You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@syncope.apache.org by il...@apache.org on 2016/12/01 08:29:25 UTC

[5/6] syncope git commit: [SYNCOPE-978] REST resource provided, consolidated wssample into syncope-fit-build-tools

[SYNCOPE-978] REST resource provided, consolidated wssample into syncope-fit-build-tools


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

Branch: refs/heads/master
Commit: 5af8e4a4eed8e4bc0113d59641ef19aadf502ca0
Parents: e7e8e92
Author: Francesco Chicchiricc� <il...@apache.org>
Authored: Thu Dec 1 09:27:28 2016 +0100
Committer: Francesco Chicchiricc� <il...@apache.org>
Committed: Thu Dec 1 09:29:10 2016 +0100

----------------------------------------------------------------------
 archetype/pom.xml                               |   4 +
 .../archetype-resources/console/pom.xml         |  14 -
 .../archetype-resources/enduser/pom.xml         |  14 -
 .../persistence/jpa/inner/ResourceTest.java     |   2 +-
 .../test/resources/domains/MasterContent.xml    |  44 +-
 fit/build-tools/pom.xml                         | 103 ++++
 .../fit/buildtools/ConnIdStartStopListener.java |   1 +
 .../fit/buildtools/cxf/ProvisioningImpl.java    | 586 +++++++++++++++++++
 .../apache/syncope/fit/buildtools/cxf/User.java |  88 +++
 .../syncope/fit/buildtools/cxf/UserService.java |  66 +++
 .../fit/buildtools/cxf/UserServiceImpl.java     | 114 ++++
 .../src/main/resources/buildToolsContext.xml    |   3 +
 .../src/main/resources/cxfContext.xml           |  50 ++
 fit/build-tools/src/main/resources/testdb.sql   |  32 +
 .../src/main/webapp/WEB-INF/glassfish-web.xml   |  28 +
 .../WEB-INF/jboss-deployment-structure.xml      |  35 ++
 fit/build-tools/src/main/webapp/WEB-INF/web.xml |  13 +-
 fit/console-reference/pom.xml                   |  14 -
 fit/core-reference/pom.xml                      |  14 -
 .../syncope/fit/core/ConnectorITCase.java       |   6 +-
 .../org/apache/syncope/fit/core/UserITCase.java |  52 ++
 .../resources/rest/AuthenticateScript.groovy    |  55 ++
 .../src/test/resources/rest/CreateScript.groovy |  65 ++
 .../src/test/resources/rest/DeleteScript.groovy |  44 ++
 .../src/test/resources/rest/SchemaScript.groovy |  51 ++
 .../src/test/resources/rest/SearchScript.groovy | 100 ++++
 .../src/test/resources/rest/SyncScript.groovy   | 106 ++++
 .../src/test/resources/rest/TestScript.groovy   |  35 ++
 .../src/test/resources/rest/UpdateScript.groovy |  98 ++++
 fit/enduser-reference/pom.xml                   |  14 -
 pom.xml                                         |  13 +-
 src/main/asciidoc/getting-started/obtain.adoc   |   7 +-
 standalone/pom.xml                              |  24 +-
 33 files changed, 1793 insertions(+), 102 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/syncope/blob/5af8e4a4/archetype/pom.xml
----------------------------------------------------------------------
diff --git a/archetype/pom.xml b/archetype/pom.xml
index 79b0c12..0b1fcaf 100644
--- a/archetype/pom.xml
+++ b/archetype/pom.xml
@@ -176,6 +176,10 @@ under the License.
         <targetPath>${project.build.outputDirectory}/archetype-resources/core/src/test/resources/scriptedsql</targetPath>
       </resource>
       <resource>
+        <directory>../fit/core-reference/src/test/resources/rest</directory>
+        <targetPath>${project.build.outputDirectory}/archetype-resources/core/src/test/resources/rest</targetPath>
+      </resource>
+      <resource>
         <directory>../fit/core-reference/src/main/resources</directory>
         <targetPath>${project.build.outputDirectory}/archetype-resources/core/src/test/resources</targetPath>
         <includes>

http://git-wip-us.apache.org/repos/asf/syncope/blob/5af8e4a4/archetype/src/main/resources/archetype-resources/console/pom.xml
----------------------------------------------------------------------
diff --git a/archetype/src/main/resources/archetype-resources/console/pom.xml b/archetype/src/main/resources/archetype-resources/console/pom.xml
index 8b38e29..144757d 100644
--- a/archetype/src/main/resources/archetype-resources/console/pom.xml
+++ b/archetype/src/main/resources/archetype-resources/console/pom.xml
@@ -209,12 +209,6 @@ ORYX.Editor.createByUrl = function(modelUrl){"/>
           <scope>test</scope>
         </dependency>
         <dependency>
-          <groupId>net.tirasa.connid.bundles.soap</groupId>
-          <artifactId>wssample</artifactId>
-          <type>war</type>
-          <scope>test</scope>
-        </dependency>
-        <dependency>
           <groupId>com.h2database</groupId>
           <artifactId>h2</artifactId>
           <scope>test</scope>
@@ -283,14 +277,6 @@ ORYX.Editor.createByUrl = function(modelUrl){"/>
               </configuration>
               <deployables>
                 <deployable>
-                  <groupId>net.tirasa.connid.bundles.soap</groupId>
-                  <artifactId>wssample</artifactId>
-                  <type>war</type>
-                  <properties>
-                    <context>wssample</context>
-                  </properties>
-                </deployable>
-                <deployable>
                   <groupId>org.apache.syncope.fit</groupId>
                   <artifactId>syncope-fit-build-tools</artifactId>
                   <type>war</type>

http://git-wip-us.apache.org/repos/asf/syncope/blob/5af8e4a4/archetype/src/main/resources/archetype-resources/enduser/pom.xml
----------------------------------------------------------------------
diff --git a/archetype/src/main/resources/archetype-resources/enduser/pom.xml b/archetype/src/main/resources/archetype-resources/enduser/pom.xml
index f3ba241..6bbcfeb 100644
--- a/archetype/src/main/resources/archetype-resources/enduser/pom.xml
+++ b/archetype/src/main/resources/archetype-resources/enduser/pom.xml
@@ -152,12 +152,6 @@ under the License.
           <scope>test</scope>
         </dependency>
         <dependency>
-          <groupId>net.tirasa.connid.bundles.soap</groupId>
-          <artifactId>wssample</artifactId>
-          <type>war</type>
-          <scope>test</scope>
-        </dependency>
-        <dependency>
           <groupId>com.h2database</groupId>
           <artifactId>h2</artifactId>
           <scope>test</scope>
@@ -226,14 +220,6 @@ under the License.
               </configuration>
               <deployables>
                 <deployable>
-                  <groupId>net.tirasa.connid.bundles.soap</groupId>
-                  <artifactId>wssample</artifactId>
-                  <type>war</type>
-                  <properties>
-                    <context>wssample</context>
-                  </properties>
-                </deployable>
-                <deployable>
                   <groupId>org.apache.syncope.fit</groupId>
                   <artifactId>syncope-fit-build-tools</artifactId>
                   <type>war</type>

http://git-wip-us.apache.org/repos/asf/syncope/blob/5af8e4a4/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/inner/ResourceTest.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/inner/ResourceTest.java b/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/inner/ResourceTest.java
index 6698bf7..3fcf4ae 100644
--- a/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/inner/ResourceTest.java
+++ b/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/inner/ResourceTest.java
@@ -87,7 +87,7 @@ public class ResourceTest extends AbstractTest {
     public void findAll() {
         List<ExternalResource> resources = resourceDAO.findAll();
         assertNotNull(resources);
-        assertEquals(20, resources.size());
+        assertEquals(21, resources.size());
     }
 
     @Test

http://git-wip-us.apache.org/repos/asf/syncope/blob/5af8e4a4/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
index 40a2e63..50b8e47 100644
--- a/core/persistence-jpa/src/test/resources/domains/MasterContent.xml
+++ b/core/persistence-jpa/src/test/resources/domains/MasterContent.xml
@@ -583,7 +583,7 @@ under the License.
                 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"]}]'/>
+                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}/syncope-fit-build-tools/cxf/soap/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="88a7a819-dab5-46b4-9b90-0b9769eabdb8" capability="CREATE"/>
   <ConnInstance_capabilities connInstance_id="88a7a819-dab5-46b4-9b90-0b9769eabdb8" capability="UPDATE"/>
   <ConnInstance_capabilities connInstance_id="88a7a819-dab5-46b4-9b90-0b9769eabdb8" capability="DELETE"/>
@@ -608,7 +608,7 @@ under the License.
                 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"]}]'/>
+                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}/syncope-fit-build-tools/cxf/soap/provisioning"]}]'/>
   <ConnInstance_capabilities connInstance_id="5ffbb4ac-a8c3-4b44-b699-11b398a1ba08" capability="CREATE"/>
   <ConnInstance_capabilities connInstance_id="5ffbb4ac-a8c3-4b44-b699-11b398a1ba08" capability="UPDATE"/>
   <ConnInstance_capabilities connInstance_id="5ffbb4ac-a8c3-4b44-b699-11b398a1ba08" capability="DELETE"/>
@@ -619,7 +619,7 @@ under the License.
                 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"]}]'/>
+                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}/syncope-fit-build-tools/cxf/soap/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="6c2acf1b-b052-46f0-8c56-7a8ad6905edf" displayName="CSVDir"
                 location="${connid.location}"
@@ -675,6 +675,18 @@ under the License.
   <ConnInstance_capabilities connInstance_id="a6d017fd-a705-4507-bb7c-6ab6a6745997" capability="SEARCH"/>
   <ConnInstance_capabilities connInstance_id="a6d017fd-a705-4507-bb7c-6ab6a6745997" capability="SYNC"/>
   
+  <ConnInstance id="44c02549-19c3-483c-8025-4919c3283c37" bundlename="net.tirasa.connid.bundles.rest"
+                location="connid://${testconnectorserver.key}@localhost:${testconnectorserver.port}"
+                connectorname="net.tirasa.connid.bundles.rest.RESTConnector"
+                displayname="REST" version="${connid.rest.version}"
+                jsonconf="[{&quot;schema&quot;:{&quot;name&quot;:&quot;authenticateScript&quot;,&quot;displayName&quot;:&quot;authenticateScript&quot;,&quot;helpMessage&quot;:&quot;authenticateScript&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;values&quot;:[]},{&quot;schema&quot;:{&quot;name&quot;:&quot;contentType&quot;,&quot;displayName&quot;:&quot;contentType&quot;,&quot;helpMessage&quot;:&quot;contentType&quot;,&quot;type&quot;:&quot;java.lang.String&quot;,&quot;required&quot;:true,&quot;order&quot;:-1,&quot;confidential&quot;:false,&quot;defaultValues&quot;:[&quot;application/json&quot;]},&quot;overridable&quot;:false,&quot;values&quot;:[&quot;application/json&quot;]},{&quot;schema&quot;:{&quot;name&quot;:&quot;resolveUsernameScriptFileName&quot;,&quot;displayName&quot;:&quot;resolveUsernameScriptFileName&quot;,&quot
 ;helpMessage&quot;:&quot;resolveUsernameScriptFileName&quot;,&quot;type&quot;:&quot;java.lang.String&quot;,&quot;required&quot;:false,&quot;order&quot;:15,&quot;confidential&quot;:false,&quot;defaultValues&quot;:[]},&quot;overridable&quot;:false,&quot;values&quot;:[]},{&quot;schema&quot;:{&quot;name&quot;:&quot;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;:10,&quot;confidential&quot;:false,&quot;defaultValues&quot;:[]},&quot;overridable&quot;:false,&quot;values&quot;:[&quot;${conf.directory}/rest/CreateScript.groovy&quot;]},{&quot;schema&quot;:{&quot;name&quot;:&quot;username&quot;,&quot;displayName&quot;:&quot;username&quot;,&quot;helpMessage&quot;:&quot;username&quot;,&quot;type&quot;:&quot;java.lang.String&quot;,&quot;required&quot;:false,&quot;order&quot;:0,&quot;confidential&quot;:false,&quot;de
 faultValues&quot;:[]},&quot;overridable&quot;:false,&quot;values&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;:4,&quot;confidential&quot;:false,&quot;defaultValues&quot;:[&quot;&quot;]},&quot;overridable&quot;:false,&quot;values&quot;:[]},{&quot;schema&quot;:{&quot;name&quot;:&quot;searchScript&quot;,&quot;displayName&quot;:&quot;searchScript&quot;,&quot;helpMessage&quot;:&quot;searchScript&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;values&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;:1,&quot;confidential&quot;:false,&quot;defaultValues&quot;:[true]},&quot;overridable&quot;:false,&quot;values&quot;:[true]},{&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;:7,&quot;confidential&quot;:false,&quot;defaultValues&quot;:[&quot;&quot;]},&quot;overridable&quot;:false,&quot;values&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;:12,&quot;confidential&quot;:false,&quot;defaultValues&quot;:[]},&quot;overridable&quot;:false,&quot;val
 ues&quot;:[&quot;${conf.directory}/rest/DeleteScript.groovy&quot;]},{&quot;schema&quot;:{&quot;name&quot;:&quot;resolveUsernameScript&quot;,&quot;displayName&quot;:&quot;resolveUsernameScript&quot;,&quot;helpMessage&quot;:&quot;resolveUsernameScript&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;values&quot;:[]},{&quot;schema&quot;:{&quot;name&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;:13,&quot;confidential&quot;:false,&quot;defaultValues&quot;:[]},&quot;overridable&quot;:false,&quot;values&quot;:[&quot;${conf.directory}/rest/SearchScript.groovy&quot;]},{&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;:16,&quot;confidential&quot;:false,&quot;defaultValues&quot;:[]},&quot;overridable&quot;:false,&quot;values&quot;:[&quot;${conf.directory}/rest/SyncScript.groovy&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;:17,&quot;confidential&quot;:false,&quot;defaultValues&quot;:[]},&quot;overridable&quot;:false,&quot;values&quot;:[&quot;${conf.directory}/rest/SchemaScript.groovy&quot;]},{&quot;schema&quot;:{&quot;name&quot;:&quot;password&quot;,&quot;displayName&quot;:&quot;password&quot;,&quot;helpMessage&quot;:&quot;password&quot;,&quot;type&quot;:&quot;org.identityco
 nnectors.common.security.GuardedString&quot;,&quot;required&quot;:false,&quot;order&quot;:1,&quot;confidential&quot;:true,&quot;defaultValues&quot;:[]},&quot;overridable&quot;:false,&quot;values&quot;:[]},{&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;:11,&quot;confidential&quot;:false,&quot;defaultValues&quot;:[]},&quot;overridable&quot;:false,&quot;values&quot;:[&quot;${conf.directory}/rest/UpdateScript.groovy&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,&quot;order&quot;:18,&quot;confidential&quot;:false,&quot;defaultValues&quot;:[]},&quot;overr
 idable&quot;:false,&quot;values&quot;:[&quot;${conf.directory}/rest/TestScript.groovy&quot;]},{&quot;schema&quot;:{&quot;name&quot;:&quot;accept&quot;,&quot;displayName&quot;:&quot;accept&quot;,&quot;helpMessage&quot;:&quot;accept&quot;,&quot;type&quot;:&quot;java.lang.String&quot;,&quot;required&quot;:true,&quot;order&quot;:-2,&quot;confidential&quot;:false,&quot;defaultValues&quot;:[&quot;application/json&quot;]},&quot;overridable&quot;:false,&quot;values&quot;:[&quot;application/json&quot;]},{&quot;schema&quot;:{&quot;name&quot;:&quot;baseAddress&quot;,&quot;displayName&quot;:&quot;baseAddress&quot;,&quot;helpMessage&quot;:&quot;baseAddress&quot;,&quot;type&quot;:&quot;java.lang.String&quot;,&quot;required&quot;:true,&quot;order&quot;:-3,&quot;confidential&quot;:false,&quot;defaultValues&quot;:[]},&quot;overridable&quot;:false,&quot;values&quot;:[&quot;http://localhost:9080/syncope-fit-build-tools/cxf/rest&quot;]},{&quot;schema&quot;:{&quot;name&quot;:&quot;authenticateScriptFile
 Name&quot;,&quot;displayName&quot;:&quot;authenticateScriptFileName&quot;,&quot;helpMessage&quot;:&quot;authenticateScriptFileName&quot;,&quot;type&quot;:&quot;java.lang.String&quot;,&quot;required&quot;:false,&quot;order&quot;:14,&quot;confidential&quot;:false,&quot;defaultValues&quot;:[]},&quot;overridable&quot;:false,&quot;values&quot;:[&quot;${conf.directory}/rest/AuthenticateScript.groovy&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;:5,&quot;confidential&quot;:false,&quot;defaultValues&quot;:[&quot;&quot;]},&quot;overridable&quot;:false,&quot;values&quot;:[]},{&quot;schema&quot;:{&quot;name&quot;:&quot;schemaScript&quot;,&quot;displayName&quot;:&quot;schemaScript&quot;,&quot;helpMessage&quot;:&quot;schemaScript&quot;,&quot;type&quot;:&quot;java.lang.String&quot;,&quot
 ;required&quot;:false,&quot;order&quot;:8,&quot;confidential&quot;:false,&quot;defaultValues&quot;:[&quot;&quot;]},&quot;overridable&quot;:false,&quot;values&quot;:[]},{&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;:3,&quot;confidential&quot;:false,&quot;defaultValues&quot;:[&quot;&quot;]},&quot;overridable&quot;:false,&quot;values&quot;:[]},{&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;nam
 e&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;:9,&quot;confidential&quot;:false,&quot;defaultValues&quot;:[&quot;&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;:2,&quot;confidential&quot;:false,&quot;defaultValues&quot;:[false]},&quot;overridable&quot;:false,&quot;values&quot;:[false]}]"/>
+  <ConnInstance_capabilities connInstance_id="44c02549-19c3-483c-8025-4919c3283c37" capability="AUTHENTICATE"/>
+  <ConnInstance_capabilities connInstance_id="44c02549-19c3-483c-8025-4919c3283c37" capability="SYNC"/>
+  <ConnInstance_capabilities connInstance_id="44c02549-19c3-483c-8025-4919c3283c37" capability="CREATE"/>
+  <ConnInstance_capabilities connInstance_id="44c02549-19c3-483c-8025-4919c3283c37" capability="DELETE"/>
+  <ConnInstance_capabilities connInstance_id="44c02549-19c3-483c-8025-4919c3283c37" capability="SEARCH"/>
+  <ConnInstance_capabilities connInstance_id="44c02549-19c3-483c-8025-4919c3283c37" capability="UPDATE"/>
+
   <ExternalResource id="ws-target-resource-1" connector_id="88a7a819-dab5-46b4-9b90-0b9769eabdb8"
                     randomPwdIfNotProvided="0" enforceMandatoryCondition="0" overrideCapabilities="0"
                     propagationPriority="1" createTraceLevel="ALL" deleteTraceLevel="ALL" updateTraceLevel="ALL" provisioningTraceLevel="ALL"/>
@@ -753,6 +765,11 @@ under the License.
                     randomPwdIfNotProvided="0" createTraceLevel="ALL" deleteTraceLevel="ALL" provisioningTraceLevel="ALL" updateTraceLevel="ALL"
                     enforceMandatoryCondition="0" overrideCapabilities="0"/>
 
+  <ExternalResource id="rest-target-resource" connector_id="44c02549-19c3-483c-8025-4919c3283c37"
+                    createTraceLevel="ALL" updateTraceLevel="ALL"  deleteTraceLevel="ALL" provisioningTraceLevel="ALL" 
+                    enforceMandatoryCondition="1" overrideCapabilities="0"
+                    propagationPriority="0" randomPwdIfNotProvided="0"/>
+
   <!-- Use resource-testdb for passthrough authentication (SYNCOPE-164) -->
   <AccountPolicy_ExternalResource accountPolicy_id="20ab5a8c-4b0c-432c-b957-f7fb9784d9f7" resource_id="resource-testdb"/>
     
@@ -1040,6 +1057,27 @@ under the License.
                intAttrName="location"
                mandatoryCondition="false" connObjectKey="0" password="0" purpose="BOTH"/>
     
+  <Provision id="2e372858-f43c-4e1c-b728-58f43c5e1c23" objectClass="__ACCOUNT__" anyType_id="USER" resource_id="rest-target-resource"/>
+  <Mapping id="e6b64584-94a2-4890-b645-8494a2089011" provision_id="2e372858-f43c-4e1c-b728-58f43c5e1c23"/>
+  <MappingItem id="14726efb-09e1-441e-b26e-fb09e1841eb2" connObjectKey="0"
+               extAttrName="firstName" intAttrName="firstname" mandatoryCondition="true" password="0" purpose="BOTH"
+               mapping_id="e6b64584-94a2-4890-b645-8494a2089011"/>
+  <MappingItem id="4cdd1fd5-80cd-4fc1-9d1f-d580cd1fc11e" connObjectKey="1"
+               extAttrName="key" intAttrName="key" mandatoryCondition="true" password="0" purpose="BOTH"
+               mapping_id="e6b64584-94a2-4890-b645-8494a2089011"/>
+  <MappingItem id="4d7581b5-fe9b-49e6-b581-b5fe9bf9e60b" connObjectKey="0"
+               extAttrName="__PASSWORD__" intAttrName="password" mandatoryCondition="true" password="1" purpose="BOTH"
+               mapping_id="e6b64584-94a2-4890-b645-8494a2089011"/>
+  <MappingItem id="98f96cf4-fba2-4c68-b96c-f4fba2fc6834" connObjectKey="0"
+               extAttrName="username" intAttrName="username" mandatoryCondition="true" password="0" purpose="BOTH"
+               mapping_id="e6b64584-94a2-4890-b645-8494a2089011"/>
+  <MappingItem id="f3312f8f-1c94-493a-b12f-8f1c94093aa9" connObjectKey="0"
+               extAttrName="email" intAttrName="email" mandatoryCondition="true" password="0" purpose="BOTH"
+               mapping_id="e6b64584-94a2-4890-b645-8494a2089011"/>
+  <MappingItem id="ff49e982-fe60-4c1e-89e9-82fe60dc1ef9" connObjectKey="0"
+               extAttrName="surname" intAttrName="surname" mandatoryCondition="true" password="0" PURPOSE="BOTH"
+               mapping_id="e6b64584-94a2-4890-b645-8494a2089011"/>
+
   <Task DTYPE="PropagationTask" id="1e697572-b896-484c-ae7f-0c8f63fcbc6c" operation="UPDATE"
         objectClassName="__ACCOUNT__" resource_id="ws-target-resource-2" anyTypeKind="USER" entityKey="1417acbe-cbf6-4277-9372-e75e04f97000"
         attributes='[{"name":"__PASSWORD__","value":[{"readOnly":false,"disposed":false,"encryptedBytes":"m9nh2US0Sa6m+cXccCq0Xw==","base64SHA1Hash":"GFJ69qfjxEOdrmt+9q+0Cw2uz60="}]},{"name":"__NAME__","value":["userId"],"nameValue":"userId"},{"name":"fullname","value":["fullname"]},{"name":"type","value":["type"]}]'/>

http://git-wip-us.apache.org/repos/asf/syncope/blob/5af8e4a4/fit/build-tools/pom.xml
----------------------------------------------------------------------
diff --git a/fit/build-tools/pom.xml b/fit/build-tools/pom.xml
index 7eda7de..878ef5e 100644
--- a/fit/build-tools/pom.xml
+++ b/fit/build-tools/pom.xml
@@ -50,6 +50,56 @@ under the License.
     </dependency>
 
     <dependency>
+      <groupId>javax.xml.ws</groupId>
+      <artifactId>jaxws-api</artifactId>
+      <version>2.2.11</version>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.cxf</groupId>
+      <artifactId>cxf-core</artifactId>
+      <version>${cxf.version}</version>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.cxf</groupId>
+      <artifactId>cxf-rt-transports-http</artifactId>
+      <version>${cxf.version}</version>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.cxf</groupId>
+      <artifactId>cxf-rt-ws-policy</artifactId>
+      <version>${cxf.version}</version>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.cxf</groupId>
+      <artifactId>cxf-rt-wsdl</artifactId>
+      <version>${cxf.version}</version>
+    </dependency>
+
+    <dependency>
+      <groupId>net.tirasa.connid.bundles.soap</groupId>
+      <artifactId>soap-utilities</artifactId>
+      <version>${connid.soap.version}</version>
+    </dependency>
+
+    <dependency>
+      <groupId>org.apache.cxf</groupId>
+      <artifactId>cxf-rt-frontend-jaxrs</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.cxf</groupId>
+      <artifactId>cxf-rt-rs-service-description</artifactId>
+    </dependency>    
+    <dependency>
+      <groupId>com.fasterxml.jackson.jaxrs</groupId>
+      <artifactId>jackson-jaxrs-json-provider</artifactId>
+    </dependency>
+
+    <dependency>
+      <groupId>org.springframework</groupId>
+      <artifactId>spring-core</artifactId>
+      <version>${spring.version}</version>
+    </dependency>
+    <dependency>
       <groupId>org.springframework</groupId>
       <artifactId>spring-jdbc</artifactId>
     </dependency>
@@ -99,6 +149,12 @@ under the License.
       <version>${connid.database.version}</version>
       <scope>runtime</scope>
     </dependency>
+    <dependency>
+      <groupId>net.tirasa.connid.bundles</groupId>
+      <artifactId>net.tirasa.connid.bundles.rest</artifactId>
+      <version>${connid.rest.version}</version>
+      <scope>runtime</scope>
+    </dependency>
         
     <dependency>
       <groupId>org.slf4j</groupId>
@@ -150,4 +206,51 @@ under the License.
       </resource>
     </resources>
   </build>
+  
+  <profiles>
+    <profile>
+      <id>debug</id>
+      
+      <build>
+        <defaultGoal>clean verify cargo:run</defaultGoal>
+        
+        <plugins>
+          <plugin>
+            <groupId>org.codehaus.cargo</groupId>
+            <artifactId>cargo-maven2-plugin</artifactId>
+            <inherited>true</inherited>
+            <configuration>
+              <container>
+                <dependencies>
+                  <dependency>
+                    <groupId>com.h2database</groupId>
+                    <artifactId>h2</artifactId>
+                  </dependency>
+                </dependencies>
+              </container>
+              <configuration>
+                <type>standalone</type>
+                <properties>
+                  <cargo.servlet.port>${cargo.servlet.port}</cargo.servlet.port>
+                  <cargo.tomcat.ajp.port>${cargo.tomcat.ajp.port}</cargo.tomcat.ajp.port>
+                  <cargo.rmi.port>${cargo.rmi.port}</cargo.rmi.port>
+
+                  <cargo.jvmargs>-Xdebug -Djaxb.debug=true -Xrunjdwp:transport=dt_socket,address=8000,server=y,suspend=n
+                    -XX:+CMSClassUnloadingEnabled -XX:+UseConcMarkSweepGC -XX:MaxPermSize=512m -Xmx1024m -Xms512m</cargo.jvmargs>
+                </properties>
+              </configuration>
+              <deployables>
+                <deployable>
+                  <location>${project.build.directory}/${project.build.finalName}</location>
+                  <properties>
+                    <context>syncope-fit-build-tools</context>
+                  </properties>
+                </deployable>
+              </deployables>
+            </configuration>
+          </plugin>
+        </plugins>
+      </build>
+    </profile>
+  </profiles>
 </project>

http://git-wip-us.apache.org/repos/asf/syncope/blob/5af8e4a4/fit/build-tools/src/main/java/org/apache/syncope/fit/buildtools/ConnIdStartStopListener.java
----------------------------------------------------------------------
diff --git a/fit/build-tools/src/main/java/org/apache/syncope/fit/buildtools/ConnIdStartStopListener.java b/fit/build-tools/src/main/java/org/apache/syncope/fit/buildtools/ConnIdStartStopListener.java
index 67567ec..1cb8370 100644
--- a/fit/build-tools/src/main/java/org/apache/syncope/fit/buildtools/ConnIdStartStopListener.java
+++ b/fit/build-tools/src/main/java/org/apache/syncope/fit/buildtools/ConnIdStartStopListener.java
@@ -49,6 +49,7 @@ public class ConnIdStartStopListener implements ServletContextListener {
 
         for (String bundleFile : new String[] {
             "testconnectorserver.soap.bundle",
+            "testconnectorserver.rest.bundle",
             "testconnectorserver.dbtable.bundle",
             "testconnectorserver.scriptedsql.bundle",
             "testconnectorserver.csvdir.bundle",

http://git-wip-us.apache.org/repos/asf/syncope/blob/5af8e4a4/fit/build-tools/src/main/java/org/apache/syncope/fit/buildtools/cxf/ProvisioningImpl.java
----------------------------------------------------------------------
diff --git a/fit/build-tools/src/main/java/org/apache/syncope/fit/buildtools/cxf/ProvisioningImpl.java b/fit/build-tools/src/main/java/org/apache/syncope/fit/buildtools/cxf/ProvisioningImpl.java
new file mode 100644
index 0000000..e5854d7
--- /dev/null
+++ b/fit/build-tools/src/main/java/org/apache/syncope/fit/buildtools/cxf/ProvisioningImpl.java
@@ -0,0 +1,586 @@
+/*
+ * 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.buildtools.cxf;
+
+import java.sql.Connection;
+import java.sql.ResultSet;
+import java.sql.ResultSetMetaData;
+import java.sql.SQLException;
+import java.sql.Statement;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+import javax.jws.WebService;
+import javax.sql.DataSource;
+import net.tirasa.connid.bundles.soap.exceptions.ProvisioningException;
+import net.tirasa.connid.bundles.soap.provisioning.interfaces.Provisioning;
+import net.tirasa.connid.bundles.soap.to.WSAttribute;
+import net.tirasa.connid.bundles.soap.to.WSAttributeValue;
+import net.tirasa.connid.bundles.soap.to.WSChange;
+import net.tirasa.connid.bundles.soap.to.WSUser;
+import net.tirasa.connid.bundles.soap.utilities.Operand;
+import org.identityconnectors.common.StringUtil;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.jdbc.datasource.DataSourceUtils;
+import org.springframework.stereotype.Service;
+
+@WebService(
+        endpointInterface = "net.tirasa.connid.bundles.soap.provisioning.interfaces.Provisioning",
+        serviceName = "Provisioning")
+@Service
+public class ProvisioningImpl implements Provisioning {
+
+    private static final Logger LOG = LoggerFactory.getLogger(Provisioning.class);
+
+    @Autowired
+    private DataSource dataSource;
+
+    @Override
+    public String delete(final String accountid) throws ProvisioningException {
+        LOG.debug("Delete request received");
+
+        Connection conn = null;
+        try {
+            conn = DataSourceUtils.getConnection(dataSource);
+
+            Statement statement = conn.createStatement();
+
+            String query = "DELETE FROM user WHERE userId='" + accountid + "';";
+            LOG.debug("Execute query: " + query);
+
+            statement.executeUpdate(query);
+
+            return accountid;
+        } catch (SQLException e) {
+            throw new ProvisioningException("Delete operation failed", e);
+        } finally {
+            DataSourceUtils.releaseConnection(conn, dataSource);
+        }
+    }
+
+    @Override
+    public Boolean isSyncSupported() {
+        LOG.debug("isSyncSupported request received");
+
+        return Boolean.FALSE;
+    }
+
+    @Override
+    public String checkAlive() {
+        return "OK";
+    }
+
+    @Override
+    public String update(final String accountid, final List<WSAttributeValue> data)
+            throws ProvisioningException {
+
+        LOG.debug("Update request received");
+
+        if (data == null || data.isEmpty()) {
+            LOG.warn("Empty data recevied");
+            return accountid;
+        }
+
+        List<WSAttribute> schema = schema();
+        Set<String> schemaNames = new HashSet<>();
+        for (WSAttribute attr : schema) {
+            schemaNames.add(attr.getName());
+        }
+        schemaNames.add("__NAME__");
+        schemaNames.add("__PASSWORD__");
+
+        Connection conn = null;
+
+        try {
+            conn = DataSourceUtils.getConnection(dataSource);
+            final Statement statement = conn.createStatement();
+
+            String value;
+
+            StringBuilder set = new StringBuilder();
+            for (WSAttributeValue attr : data) {
+                if (schemaNames.contains(attr.getName())) {
+                    if (attr.getValues() == null || attr.getValues().isEmpty()) {
+                        value = null;
+                    } else if (attr.getValues().size() == 1) {
+                        value = attr.getValues().get(0).toString();
+                    } else {
+                        value = attr.getValues().toString();
+                    }
+
+                    if (!attr.isKey() || !accountid.equals(value)) {
+                        if (set.length() > 0) {
+                            set.append(",");
+                        }
+
+                        if (null == attr.getName()) {
+                            set.append(attr.getName()).append('=');
+                        } else {
+                            switch (attr.getName()) {
+                                case "__NAME__":
+                                    set.append("userId=");
+                                    break;
+                                case "__PASSWORD__":
+                                    set.append("password=");
+                                    break;
+                                default:
+                                    set.append(attr.getName()).append('=');
+                                    break;
+                            }
+                        }
+
+                        set.append(value == null ? null : "'" + value + "'");
+                    }
+                }
+            }
+
+            if (set.length() > 0) {
+                String query = "UPDATE user SET " + set.toString() + " WHERE userId='" + accountid + "';";
+                LOG.debug("Execute query: " + query);
+
+                statement.executeUpdate(query);
+            }
+
+            return accountid;
+        } catch (SQLException e) {
+            LOG.error("Update failed", e);
+            throw new ProvisioningException("Update operation failed", e);
+        } finally {
+            DataSourceUtils.releaseConnection(conn, dataSource);
+        }
+    }
+
+    @Override
+    public List<WSUser> query(final Operand query) {
+        LOG.debug("Query request received");
+
+        List<WSUser> results = new ArrayList<>();
+
+        Connection conn = null;
+        try {
+
+            String queryString = "SELECT * FROM user" + (query == null ? "" : " WHERE " + query.toString());
+
+            queryString = queryString.replaceAll("__NAME__", "userId").
+                    replaceAll("__UID__", "userId").
+                    replaceAll("__PASSWORD__", "password");
+
+            LOG.debug("Execute query: {}", queryString);
+
+            if (queryString == null || queryString.length() == 0) {
+                throw new SQLException("Invalid query [" + queryString + "]");
+            }
+
+            conn = DataSourceUtils.getConnection(dataSource);
+            Statement statement = conn.createStatement();
+
+            ResultSet rs = statement.executeQuery(queryString);
+
+            ResultSetMetaData metaData = rs.getMetaData();
+            LOG.debug("Metadata: {}", metaData);
+
+            while (rs.next()) {
+                WSUser user = new WSUser();
+
+                for (int i = 0; i < metaData.getColumnCount(); i++) {
+                    WSAttributeValue attr = new WSAttributeValue();
+                    attr.setName(metaData.getColumnLabel(i + 1));
+                    if (StringUtil.isNotBlank(rs.getString(i + 1))) {
+                        attr.addValue(rs.getString(i + 1));
+                    }
+                    if ("userId".equalsIgnoreCase(metaData.getColumnName(i + 1))) {
+                        attr.setKey(true);
+                        user.setAccountid(rs.getString(i + 1));
+                    }
+
+                    user.addAttribute(attr);
+                }
+
+                results.add(user);
+            }
+
+            LOG.debug("Retrieved users: {}", results);
+        } catch (SQLException e) {
+            LOG.error("Search operation failed", e);
+        } finally {
+            DataSourceUtils.releaseConnection(conn, dataSource);
+        }
+
+        return results;
+    }
+
+    @Override
+    public String create(final List<WSAttributeValue> data) throws ProvisioningException {
+        LOG.debug("Create request received with data {}", data);
+
+        final List<WSAttribute> schema = schema();
+        final Set<String> schemaNames = new HashSet<>();
+        for (WSAttribute attr : schema) {
+            schemaNames.add(attr.getName());
+        }
+        schemaNames.add("__NAME__");
+        schemaNames.add("__PASSWORD__");
+
+        Connection conn = null;
+        String query = null;
+        try {
+            conn = DataSourceUtils.getConnection(dataSource);
+            final Statement statement = conn.createStatement();
+
+            final StringBuilder keys = new StringBuilder();
+            final StringBuilder values = new StringBuilder();
+
+            String accountid = null;
+            String value;
+            for (WSAttributeValue attr : data) {
+                if (schemaNames.contains(attr.getName())) {
+                    LOG.debug("Bind attribute: {}", attr);
+
+                    if (attr.getValues() == null || attr.getValues().isEmpty()) {
+                        value = null;
+                    } else if (attr.getValues().size() == 1) {
+                        value = attr.getValues().get(0).toString();
+                    } else {
+                        value = attr.getValues().toString();
+                    }
+
+                    if (keys.length() > 0) {
+                        keys.append(",");
+                    }
+
+                    if (null == attr.getName()) {
+                        keys.append(attr.getName());
+                    } else {
+                        switch (attr.getName()) {
+                            case "__NAME__":
+                                keys.append("userId");
+                                break;
+                            case "__PASSWORD__":
+                                keys.append("password");
+                                break;
+                            default:
+                                keys.append(attr.getName());
+                                break;
+                        }
+                    }
+
+                    if (values.length() > 0) {
+                        values.append(",");
+                    }
+
+                    values.append(value == null ? null : "'" + value + "'");
+
+                    if (attr.isKey() && !attr.getValues().isEmpty()) {
+                        accountid = attr.getValues().get(0).toString();
+                    }
+                }
+            }
+
+            query = "INSERT INTO user (" + keys.toString() + ") VALUES (" + values.toString() + ")";
+
+            LOG.debug("Execute query: " + query);
+
+            statement.executeUpdate(query);
+
+            return accountid;
+        } catch (SQLException e) {
+            LOG.error("Creation failed:\n" + query, e);
+            throw new ProvisioningException("Create operation failed", e);
+        } finally {
+            DataSourceUtils.releaseConnection(conn, dataSource);
+        }
+    }
+
+    @Override
+    public int getLatestChangeNumber()
+            throws ProvisioningException {
+
+        LOG.debug("getLatestChangeNumber request received");
+
+        return 0;
+    }
+
+    @Override
+    public List<WSChange> sync()
+            throws ProvisioningException {
+
+        LOG.debug("sync request received");
+
+        return Collections.<WSChange>emptyList();
+    }
+
+    @Override
+    public String resolve(final String username) throws ProvisioningException {
+
+        LOG.debug("Resolve request operation received: " + username);
+
+        String resolved = "";
+
+        Connection conn = null;
+        try {
+            conn = DataSourceUtils.getConnection(dataSource);
+            Statement statement = conn.createStatement();
+
+            final String query = "SELECT userId FROM user WHERE userId='" + username + "';";
+
+            LOG.debug("Execute query: " + query);
+
+            ResultSet rs = statement.executeQuery(query);
+
+            resolved = rs.next() ? rs.getString(1) : null;
+
+            if (resolved == null) {
+                statement = conn.createStatement();
+                final String roleQuery = "SELECT roleName FROM role WHERE roleName='" + username + "';";
+                LOG.debug("Execute query: " + roleQuery);
+
+                rs = statement.executeQuery(roleQuery);
+
+                resolved = rs.next() ? rs.getString(1) : null;
+            }
+        } catch (SQLException e) {
+            throw new ProvisioningException("Resolve operation failed", e);
+        } finally {
+            DataSourceUtils.releaseConnection(conn, dataSource);
+        }
+
+        return resolved;
+    }
+
+    @Override
+    public List<WSAttribute> schema() {
+        LOG.debug("schema request received");
+
+        final List<WSAttribute> attrs = new ArrayList<>();
+
+        WSAttribute attr = new WSAttribute();
+        attr.setName("userId");
+        attr.setNullable(false);
+        attr.setPassword(false);
+        attr.setKey(true);
+        attr.setType("String");
+        attrs.add(attr);
+
+        attr = new WSAttribute();
+        attr.setName("password");
+        attr.setNullable(false);
+        attr.setPassword(true);
+        attr.setKey(false);
+        attr.setType("String");
+        attrs.add(attr);
+
+        attr = new WSAttribute();
+        attr.setName("type");
+        attr.setNullable(false);
+        attr.setPassword(false);
+        attr.setKey(false);
+        attr.setType("String");
+        attrs.add(attr);
+
+        attr = new WSAttribute();
+        attr.setName("residence");
+        attr.setNullable(true);
+        attr.setPassword(false);
+        attr.setKey(false);
+        attr.setType("String");
+        attrs.add(attr);
+
+        attr = new WSAttribute();
+        attr.setName("telephone");
+        attr.setNullable(true);
+        attr.setPassword(false);
+        attr.setKey(false);
+        attr.setType("String");
+        attrs.add(attr);
+
+        attr = new WSAttribute();
+        attr.setName("fax");
+        attr.setNullable(true);
+        attr.setPassword(false);
+        attr.setKey(false);
+        attr.setType("String");
+        attrs.add(attr);
+
+        attr = new WSAttribute();
+        attr.setName("preference");
+        attr.setNullable(true);
+        attr.setPassword(false);
+        attr.setKey(false);
+        attr.setType("String");
+        attrs.add(attr);
+
+        attr = new WSAttribute();
+        attr.setName("name");
+        attr.setNullable(true);
+        attr.setPassword(false);
+        attr.setKey(false);
+        attr.setType("String");
+        attrs.add(attr);
+
+        attr = new WSAttribute();
+        attr.setName("surname");
+        attr.setNullable(true);
+        attr.setPassword(false);
+        attr.setKey(false);
+        attr.setType("String");
+        attrs.add(attr);
+
+        attr = new WSAttribute();
+        attr.setName("fullname");
+        attr.setNullable(false);
+        attr.setPassword(false);
+        attr.setKey(false);
+        attr.setType("String");
+        attrs.add(attr);
+
+        attr = new WSAttribute();
+        attr.setName("birthdate");
+        attr.setNullable(true);
+        attr.setPassword(false);
+        attr.setKey(false);
+        attr.setType("Date");
+        attrs.add(attr);
+
+        attr = new WSAttribute();
+        attr.setName("telephone");
+        attr.setNullable(true);
+        attr.setPassword(false);
+        attr.setKey(false);
+        attr.setType("String");
+        attrs.add(attr);
+
+        attr = new WSAttribute();
+        attr.setName("gender");
+        attr.setNullable(true);
+        attr.setPassword(false);
+        attr.setKey(false);
+        attr.setType("String");
+        attrs.add(attr);
+
+        attr = new WSAttribute();
+        attr.setName("taxNumber");
+        attr.setNullable(true);
+        attr.setPassword(false);
+        attr.setKey(false);
+        attr.setType("String");
+        attrs.add(attr);
+
+        attr = new WSAttribute();
+        attr.setName("state");
+        attr.setNullable(true);
+        attr.setPassword(false);
+        attr.setKey(false);
+        attr.setType("String");
+        attrs.add(attr);
+
+        attr = new WSAttribute();
+        attr.setName("studyTitle");
+        attr.setNullable(true);
+        attr.setPassword(false);
+        attr.setKey(false);
+        attr.setType("String");
+        attrs.add(attr);
+
+        attr = new WSAttribute();
+        attr.setName("studyArea");
+        attr.setNullable(true);
+        attr.setPassword(false);
+        attr.setKey(false);
+        attr.setType("String");
+        attrs.add(attr);
+
+        attr = new WSAttribute();
+        attr.setName("job");
+        attr.setNullable(true);
+        attr.setPassword(false);
+        attr.setKey(false);
+        attr.setType("String");
+        attrs.add(attr);
+
+        attr = new WSAttribute();
+        attr.setName("companyType");
+        attr.setNullable(true);
+        attr.setPassword(false);
+        attr.setKey(false);
+        attr.setType("String");
+        attrs.add(attr);
+
+        attr = new WSAttribute();
+        attr.setName("companyName");
+        attr.setNullable(true);
+        attr.setPassword(false);
+        attr.setKey(false);
+        attr.setType("String");
+        attrs.add(attr);
+
+        attr = new WSAttribute();
+        attr.setName("vatNumber");
+        attr.setNullable(true);
+        attr.setPassword(false);
+        attr.setKey(false);
+        attr.setType("String");
+        attrs.add(attr);
+
+        attr = new WSAttribute();
+        attr.setName("mandatoryDisclaimer");
+        attr.setNullable(true);
+        attr.setPassword(false);
+        attr.setKey(false);
+        attr.setType("Boolean");
+        attrs.add(attr);
+
+        attr = new WSAttribute();
+        attr.setName("promoRCSDisclaimer");
+        attr.setNullable(true);
+        attr.setPassword(false);
+        attr.setKey(false);
+        attr.setType("Boolean");
+        attrs.add(attr);
+
+        attr = new WSAttribute();
+        attr.setName("promoThirdPartyDisclaimer");
+        attr.setNullable(true);
+        attr.setPassword(false);
+        attr.setKey(false);
+        attr.setType("Boolean");
+        attrs.add(attr);
+
+        return attrs;
+    }
+
+    @Override
+    public String authenticate(final String username, final String password)
+            throws ProvisioningException {
+
+        LOG.debug("authenticate request received");
+
+        return username;
+    }
+
+    @Override
+    public Boolean isAuthenticationSupported() {
+        LOG.debug("isAuthenticationSupported request received");
+
+        return Boolean.FALSE;
+    }
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/5af8e4a4/fit/build-tools/src/main/java/org/apache/syncope/fit/buildtools/cxf/User.java
----------------------------------------------------------------------
diff --git a/fit/build-tools/src/main/java/org/apache/syncope/fit/buildtools/cxf/User.java b/fit/build-tools/src/main/java/org/apache/syncope/fit/buildtools/cxf/User.java
new file mode 100644
index 0000000..18b3c7b
--- /dev/null
+++ b/fit/build-tools/src/main/java/org/apache/syncope/fit/buildtools/cxf/User.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.fit.buildtools.cxf;
+
+import java.io.Serializable;
+import java.util.UUID;
+
+public class User implements Serializable {
+
+    private static final long serialVersionUID = -7906946710921162676L;
+
+    private UUID key;
+
+    private String username;
+
+    private String password;
+
+    private String firstName;
+
+    private String surname;
+
+    private String email;
+
+    public UUID getKey() {
+        return key;
+    }
+
+    public void setKey(final UUID key) {
+        this.key = key;
+    }
+
+    public String getUsername() {
+        return username;
+    }
+
+    public void setUsername(final String username) {
+        this.username = username;
+    }
+
+    public String getPassword() {
+        return password;
+    }
+
+    public void setPassword(final String password) {
+        this.password = password;
+    }
+
+    public String getFirstName() {
+        return firstName;
+    }
+
+    public void setFirstName(final String firstName) {
+        this.firstName = firstName;
+    }
+
+    public String getSurname() {
+        return surname;
+    }
+
+    public void setSurname(final String surname) {
+        this.surname = surname;
+    }
+
+    public String getEmail() {
+        return email;
+    }
+
+    public void setEmail(final String email) {
+        this.email = email;
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/5af8e4a4/fit/build-tools/src/main/java/org/apache/syncope/fit/buildtools/cxf/UserService.java
----------------------------------------------------------------------
diff --git a/fit/build-tools/src/main/java/org/apache/syncope/fit/buildtools/cxf/UserService.java b/fit/build-tools/src/main/java/org/apache/syncope/fit/buildtools/cxf/UserService.java
new file mode 100644
index 0000000..5d64cfc
--- /dev/null
+++ b/fit/build-tools/src/main/java/org/apache/syncope/fit/buildtools/cxf/UserService.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.fit.buildtools.cxf;
+
+import java.util.List;
+import java.util.UUID;
+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.QueryParam;
+import javax.ws.rs.core.MediaType;
+
+@Path("users")
+public interface UserService {
+
+    @GET
+    List<User> list();
+
+    @GET
+    @Path("{key}")
+    @Produces({ MediaType.APPLICATION_JSON })
+    User read(@PathParam("key") UUID key);
+
+    @POST
+    @Consumes({ MediaType.APPLICATION_JSON })
+    void create(User user);
+
+    @PUT
+    @Path("{key}")
+    @Consumes({ MediaType.APPLICATION_JSON })
+    void update(@PathParam("key") UUID key, User user);
+
+    @DELETE
+    @Path("{key}")
+    void delete(@PathParam("key") UUID key);
+
+    @POST
+    @Path("authenticate")
+    @Produces({ MediaType.APPLICATION_JSON })
+    User authenticate(@QueryParam("username") String username, @QueryParam("password") String password);
+
+    @POST
+    @Path("clear")
+    void clear();
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/5af8e4a4/fit/build-tools/src/main/java/org/apache/syncope/fit/buildtools/cxf/UserServiceImpl.java
----------------------------------------------------------------------
diff --git a/fit/build-tools/src/main/java/org/apache/syncope/fit/buildtools/cxf/UserServiceImpl.java b/fit/build-tools/src/main/java/org/apache/syncope/fit/buildtools/cxf/UserServiceImpl.java
new file mode 100644
index 0000000..dea0f63
--- /dev/null
+++ b/fit/build-tools/src/main/java/org/apache/syncope/fit/buildtools/cxf/UserServiceImpl.java
@@ -0,0 +1,114 @@
+/*
+ * 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.buildtools.cxf;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.UUID;
+import javax.ws.rs.ForbiddenException;
+import javax.ws.rs.NotFoundException;
+import org.springframework.stereotype.Service;
+
+@Service
+public class UserServiceImpl implements UserService {
+
+    private static final Map<UUID, User> USERS = new HashMap<UUID, User>();
+
+    @Override
+    public List<User> list() {
+        return new ArrayList<>(USERS.values());
+    }
+
+    @Override
+    public User read(final UUID key) {
+        User user = USERS.get(key);
+        if (user == null) {
+            throw new NotFoundException(key.toString());
+        }
+        return user;
+    }
+
+    @Override
+    public void create(final User user) {
+        if (user.getKey() == null) {
+            user.setKey(UUID.randomUUID());
+        }
+        if (USERS.containsKey(user.getKey())) {
+            throw new IllegalArgumentException("User already exists: " + user.getKey());
+        }
+        USERS.put(user.getKey(), user);
+    }
+
+    @Override
+    public void update(final UUID key, final User updatedUser) {
+        if (!USERS.containsKey(key)) {
+            throw new NotFoundException(updatedUser.getKey().toString());
+        }
+        User user = USERS.get(key);
+        if (updatedUser.getUsername() != null) {
+            user.setUsername(updatedUser.getUsername());
+        }
+        if (updatedUser.getPassword() != null) {
+            user.setPassword(updatedUser.getPassword());
+        }
+        if (updatedUser.getFirstName() != null) {
+            user.setFirstName(updatedUser.getFirstName());
+        }
+        if (updatedUser.getSurname() != null) {
+            user.setSurname(updatedUser.getSurname());
+        }
+        if (updatedUser.getEmail() != null) {
+            user.setEmail(updatedUser.getEmail());
+        }
+    }
+
+    @Override
+    public void delete(final UUID key) {
+        if (!USERS.containsKey(key)) {
+            throw new NotFoundException(key.toString());
+        }
+        USERS.remove(key);
+    }
+
+    @Override
+    public User authenticate(final String username, final String password) {
+        User user = null;
+        for (User entry : USERS.values()) {
+            if (username.equals(entry.getUsername())) {
+                user = entry;
+            }
+        }
+        if (user == null) {
+            throw new NotFoundException(username);
+        }
+        if (!password.equals(user.getPassword())) {
+            throw new ForbiddenException();
+        }
+
+        return user;
+    }
+
+    @Override
+    public void clear() {
+        USERS.clear();
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/5af8e4a4/fit/build-tools/src/main/resources/buildToolsContext.xml
----------------------------------------------------------------------
diff --git a/fit/build-tools/src/main/resources/buildToolsContext.xml b/fit/build-tools/src/main/resources/buildToolsContext.xml
index e0f5678..a4433c9 100644
--- a/fit/build-tools/src/main/resources/buildToolsContext.xml
+++ b/fit/build-tools/src/main/resources/buildToolsContext.xml
@@ -45,6 +45,9 @@ under the License.
   <bean id="testconnectorserver.soap.bundle" class="java.lang.String">
     <constructor-arg value="net.tirasa.connid.bundles.soap-${connid.soap.version}.jar"/>
   </bean>  
+  <bean id="testconnectorserver.rest.bundle" class="java.lang.String">
+    <constructor-arg value="net.tirasa.connid.bundles.rest-${connid.rest.version}.jar"/>
+  </bean>  
   <bean id="testconnectorserver.dbtable.bundle" class="java.lang.String">
     <constructor-arg value="net.tirasa.connid.bundles.db.table-${connid.database.version}.jar"/>
   </bean>  

http://git-wip-us.apache.org/repos/asf/syncope/blob/5af8e4a4/fit/build-tools/src/main/resources/cxfContext.xml
----------------------------------------------------------------------
diff --git a/fit/build-tools/src/main/resources/cxfContext.xml b/fit/build-tools/src/main/resources/cxfContext.xml
new file mode 100644
index 0000000..9a6c959
--- /dev/null
+++ b/fit/build-tools/src/main/resources/cxfContext.xml
@@ -0,0 +1,50 @@
+<?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:jaxws="http://cxf.apache.org/jaxws"
+       xmlns:jaxrs="http://cxf.apache.org/jaxrs"
+       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://cxf.apache.org/jaxws
+                           http://cxf.apache.org/schemas/jaxws.xsd
+                           http://cxf.apache.org/jaxrs
+                           http://cxf.apache.org/schemas/jaxrs.xsd
+                           http://www.springframework.org/schema/context
+                           http://www.springframework.org/schema/context/spring-context.xsd">
+
+  <import resource="classpath:META-INF/cxf/cxf.xml"/>
+  <import resource="classpath:META-INF/cxf/cxf-servlet.xml"/>
+
+  <context:component-scan base-package="org.apache.syncope.fit.buildtools.cxf"/>  
+      
+  <jaxws:endpoint id="soapProvisioning" address="/soap" implementor="#provisioningImpl"/>
+  
+  <bean id="jsonProvider" class="com.fasterxml.jackson.jaxrs.json.JacksonJaxbJsonProvider"/>
+  <jaxrs:server id="restProvisioning" address="/rest"
+                basePackages="org.apache.syncope.fit.buildtools.cxf" 
+                staticSubresourceResolution="true">
+    <jaxrs:providers>
+      <ref bean="jsonProvider"/>
+    </jaxrs:providers>
+  </jaxrs:server>
+
+</beans>

http://git-wip-us.apache.org/repos/asf/syncope/blob/5af8e4a4/fit/build-tools/src/main/resources/testdb.sql
----------------------------------------------------------------------
diff --git a/fit/build-tools/src/main/resources/testdb.sql b/fit/build-tools/src/main/resources/testdb.sql
index 36d228b..0eb42e8 100644
--- a/fit/build-tools/src/main/resources/testdb.sql
+++ b/fit/build-tools/src/main/resources/testdb.sql
@@ -49,3 +49,35 @@ printername VARCHAR(80),
 location VARCHAR(80),
 deleted BOOLEAN DEFAULT FALSE,
 lastModification TIMESTAMP);
+
+CREATE TABLE user (
+capsId INTEGER GENERATED BY DEFAULT AS IDENTITY(START WITH 1) PRIMARY KEY,
+userId VARCHAR(30) NOT NULL,
+password VARCHAR(255) NOT NULL,
+type VARCHAR(17) NOT NULL,
+residence VARCHAR(60),
+telephone VARCHAR(20),
+fax VARCHAR(20),
+preference VARCHAR(120),
+name VARCHAR(30),
+surname VARCHAR(35),
+fullname VARCHAR(35) NOT NULL,
+birthdate VARCHAR(30),
+gender VARCHAR(1),
+taxNumber VARCHAR(30),
+state VARCHAR(15),
+studyTitle VARCHAR(30),
+studyArea VARCHAR(30),
+job VARCHAR(30),
+companyType VARCHAR(30),
+companyName VARCHAR(30),
+vatNumber VARCHAR(30),
+mandatoryDisclaimer BOOLEAN,
+promoRCSDisclaimer BOOLEAN,
+promoThirdPartyDisclaimer BOOLEAN,
+UNIQUE(userId));
+
+CREATE TABLE role (
+roleId INTEGER GENERATED BY DEFAULT AS IDENTITY(START WITH 1) PRIMARY KEY,
+roleName VARCHAR(120),
+UNIQUE(roleName));

http://git-wip-us.apache.org/repos/asf/syncope/blob/5af8e4a4/fit/build-tools/src/main/webapp/WEB-INF/glassfish-web.xml
----------------------------------------------------------------------
diff --git a/fit/build-tools/src/main/webapp/WEB-INF/glassfish-web.xml b/fit/build-tools/src/main/webapp/WEB-INF/glassfish-web.xml
new file mode 100644
index 0000000..aca226e
--- /dev/null
+++ b/fit/build-tools/src/main/webapp/WEB-INF/glassfish-web.xml
@@ -0,0 +1,28 @@
+<?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.
+-->
+<!DOCTYPE glassfish-web-app PUBLIC "-//GlassFish.org//DTD 
+GlassFish Application Server 3.1 Servlet 3.0//EN" "http://glassfish.org/dtds/glassfish-web-app_3_0-1.dtd">
+<glassfish-web-app>
+  <context-root>/syncope</context-root>
+  <class-loader delegate="false"/>
+  <jsp-config>
+    <property name="httpMethods" value="GET,POST,HEAD,PUT,DELETE"/>
+  </jsp-config>
+</glassfish-web-app>
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/syncope/blob/5af8e4a4/fit/build-tools/src/main/webapp/WEB-INF/jboss-deployment-structure.xml
----------------------------------------------------------------------
diff --git a/fit/build-tools/src/main/webapp/WEB-INF/jboss-deployment-structure.xml b/fit/build-tools/src/main/webapp/WEB-INF/jboss-deployment-structure.xml
new file mode 100644
index 0000000..388b98b
--- /dev/null
+++ b/fit/build-tools/src/main/webapp/WEB-INF/jboss-deployment-structure.xml
@@ -0,0 +1,35 @@
+<?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.
+-->
+<jboss-deployment-structure xmlns="urn:jboss:deployment-structure:1.2">
+  <deployment>
+    <exclude-subsystems>
+      <subsystem name="webservices"/>
+    </exclude-subsystems>
+    <dependencies>
+      <module name="org.apache.xalan"/>
+    </dependencies>
+    <exclusions>
+      <module name="org.apache.cxf"/>
+      <module name="org.apache.cxf.impl"/>
+      <module name="org.slf4j"/>
+      <module name="org.slf4j.impl"/>
+    </exclusions>
+  </deployment>
+</jboss-deployment-structure>

http://git-wip-us.apache.org/repos/asf/syncope/blob/5af8e4a4/fit/build-tools/src/main/webapp/WEB-INF/web.xml
----------------------------------------------------------------------
diff --git a/fit/build-tools/src/main/webapp/WEB-INF/web.xml b/fit/build-tools/src/main/webapp/WEB-INF/web.xml
index df3438d..b1b6ec7 100644
--- a/fit/build-tools/src/main/webapp/WEB-INF/web.xml
+++ b/fit/build-tools/src/main/webapp/WEB-INF/web.xml
@@ -25,7 +25,7 @@ under the License.
 
   <context-param>
     <param-name>contextConfigLocation</param-name>
-    <param-value>classpath*:/buildToolsContext.xml</param-value>
+    <param-value>classpath:/*Context.xml</param-value>
   </context-param>
   
   <listener>
@@ -40,6 +40,12 @@ under the License.
   <listener>
     <listener-class>org.apache.syncope.fit.buildtools.ConnIdStartStopListener</listener-class>
   </listener>
+  
+  <servlet>
+    <servlet-name>CXFServlet</servlet-name>
+    <servlet-class>org.apache.cxf.transport.servlet.CXFServlet</servlet-class>
+    <load-on-startup>1</load-on-startup> 
+  </servlet>
   <servlet>
     <servlet-name>ApacheDSRootDseServlet</servlet-name>
     <servlet-class>org.apache.syncope.fit.buildtools.ApacheDSRootDseServlet</servlet-class>
@@ -48,6 +54,11 @@ under the License.
     <servlet-name>ServiceTimeoutServlet</servlet-name>
     <servlet-class>org.apache.syncope.fit.buildtools.ServiceTimeoutServlet</servlet-class>
   </servlet>
+  
+  <servlet-mapping>
+    <servlet-name>CXFServlet</servlet-name>
+    <url-pattern>/cxf/*</url-pattern>
+  </servlet-mapping>  
   <servlet-mapping>
     <servlet-name>ApacheDSRootDseServlet</servlet-name>
     <url-pattern>/apacheDS</url-pattern>

http://git-wip-us.apache.org/repos/asf/syncope/blob/5af8e4a4/fit/console-reference/pom.xml
----------------------------------------------------------------------
diff --git a/fit/console-reference/pom.xml b/fit/console-reference/pom.xml
index 7fc1c44..6377efd 100644
--- a/fit/console-reference/pom.xml
+++ b/fit/console-reference/pom.xml
@@ -117,12 +117,6 @@ under the License.
       <scope>test</scope>
     </dependency>
     <dependency>
-      <groupId>net.tirasa.connid.bundles.soap</groupId>
-      <artifactId>wssample</artifactId>
-      <type>war</type>
-      <scope>test</scope>
-    </dependency>
-    <dependency>
       <groupId>org.apache.syncope.fit</groupId>
       <artifactId>syncope-fit-core-reference</artifactId>
       <version>${project.version}</version>
@@ -204,14 +198,6 @@ under the License.
           </configuration>
           <deployables>
             <deployable>
-              <groupId>net.tirasa.connid.bundles.soap</groupId>
-              <artifactId>wssample</artifactId>
-              <type>war</type>
-              <properties>
-                <context>wssample</context>
-              </properties>
-            </deployable>
-            <deployable>
               <groupId>org.apache.syncope.fit</groupId>
               <artifactId>syncope-fit-build-tools</artifactId>
               <type>war</type>

http://git-wip-us.apache.org/repos/asf/syncope/blob/5af8e4a4/fit/core-reference/pom.xml
----------------------------------------------------------------------
diff --git a/fit/core-reference/pom.xml b/fit/core-reference/pom.xml
index 789e6f9..44a5fda 100644
--- a/fit/core-reference/pom.xml
+++ b/fit/core-reference/pom.xml
@@ -120,12 +120,6 @@ under the License.
       <scope>test</scope>
     </dependency>
     <dependency>
-      <groupId>net.tirasa.connid.bundles.soap</groupId>
-      <artifactId>wssample</artifactId>
-      <type>war</type>
-      <scope>test</scope>
-    </dependency>
-    <dependency>
       <groupId>com.h2database</groupId>
       <artifactId>h2</artifactId>
       <scope>test</scope>
@@ -267,14 +261,6 @@ under the License.
           </configuration>
           <deployables>
             <deployable>
-              <groupId>net.tirasa.connid.bundles.soap</groupId>
-              <artifactId>wssample</artifactId>
-              <type>war</type>
-              <properties>
-                <context>wssample</context>
-              </properties>
-            </deployable>
-            <deployable>
               <groupId>org.apache.syncope.fit</groupId>
               <artifactId>syncope-fit-build-tools</artifactId>
               <type>war</type>

http://git-wip-us.apache.org/repos/asf/syncope/blob/5af8e4a4/fit/core-reference/src/test/java/org/apache/syncope/fit/core/ConnectorITCase.java
----------------------------------------------------------------------
diff --git a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/ConnectorITCase.java b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/ConnectorITCase.java
index 45616f8..65f37f4 100644
--- a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/ConnectorITCase.java
+++ b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/ConnectorITCase.java
@@ -132,7 +132,7 @@ public class ConnectorITCase extends AbstractITCase {
         endpointSchema.setRequired(true);
         ConnConfProperty endpoint = new ConnConfProperty();
         endpoint.setSchema(endpointSchema);
-        endpoint.getValues().add("http://localhost:8888/wssample/services");
+        endpoint.getValues().add("http://localhost:8888/syncope-fit-build-tools/cxf/soap");
         endpoint.getValues().add("Provisioning");
         conf.add(endpoint);
 
@@ -239,7 +239,7 @@ public class ConnectorITCase extends AbstractITCase {
         endpointSchema.setRequired(true);
         ConnConfProperty endpoint = new ConnConfProperty();
         endpoint.setSchema(endpointSchema);
-        endpoint.getValues().add("http://localhost:8888/wssample/services");
+        endpoint.getValues().add("http://localhost:8888/syncope-fit-build-tools/cxf/soap");
         conf.add(endpoint);
 
         ConnConfPropSchema servicenameSchema = new ConnConfPropSchema();
@@ -652,7 +652,7 @@ public class ConnectorITCase extends AbstractITCase {
 
             conf = new HashSet<>();
             endpoint.getValues().clear();
-            endpoint.getValues().add("http://localhost:9080/wssample/services/provisioning");
+            endpoint.getValues().add("http://localhost:9080/syncope-fit-build-tools/cxf/soap/provisioning");
             conf.add(endpoint);
 
             resourceTO.getConfOverride().addAll(conf);

http://git-wip-us.apache.org/repos/asf/syncope/blob/5af8e4a4/fit/core-reference/src/test/java/org/apache/syncope/fit/core/UserITCase.java
----------------------------------------------------------------------
diff --git a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/UserITCase.java b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/UserITCase.java
index 456c728..9cea62a 100644
--- a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/UserITCase.java
+++ b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/UserITCase.java
@@ -41,6 +41,7 @@ import org.apache.commons.collections4.Transformer;
 import org.apache.commons.lang3.time.DateFormatUtils;
 import org.apache.commons.lang3.time.FastDateFormat;
 import org.apache.commons.lang3.tuple.Pair;
+import org.apache.cxf.jaxrs.client.WebClient;
 import org.apache.syncope.common.lib.SyncopeClientException;
 import org.apache.syncope.common.lib.SyncopeConstants;
 import org.apache.syncope.common.lib.patch.AssociationPatch;
@@ -1309,4 +1310,55 @@ public class UserITCase extends AbstractITCase {
         }
     }
 
+    @Test
+    public void restResource() {
+        UserTO userTO = getUniqueSampleTO("rest@syncope.apache.org");
+        userTO.getResources().clear();
+        userTO.getResources().add("rest-target-resource");
+
+        // 1. create
+        ProvisioningResult<UserTO> result = userService.create(userTO).readEntity(
+                new GenericType<ProvisioningResult<UserTO>>() {
+        });
+        assertEquals(1, result.getPropagationStatuses().size());
+        assertEquals(PropagationTaskExecStatus.SUCCESS, result.getPropagationStatuses().get(0).getStatus());
+        assertEquals("rest-target-resource", result.getPropagationStatuses().get(0).getResource());
+        assertEquals("surname", userTO.getPlainAttrMap().get("surname").getValues().get(0));
+
+        // verify user exists on the backend REST service
+        WebClient webClient = WebClient.create(
+                "http://localhost:9080/syncope-fit-build-tools/cxf/rest/users/" + result.getEntity().getKey());
+        Response response = webClient.get();
+        assertEquals(200, response.getStatus());
+        assertNotNull(response.getEntity());
+
+        // 2. update
+        UserPatch patch = new UserPatch();
+        patch.setKey(result.getEntity().getKey());
+        patch.getPlainAttrs().add(new AttrPatch.Builder().
+                attrTO(new AttrTO.Builder().schema("surname").value("surname2").build()).build());
+        result = userService.update(patch).readEntity(
+                new GenericType<ProvisioningResult<UserTO>>() {
+        });
+        assertEquals(1, result.getPropagationStatuses().size());
+        assertEquals(PropagationTaskExecStatus.SUCCESS, result.getPropagationStatuses().get(0).getStatus());
+        assertEquals("rest-target-resource", result.getPropagationStatuses().get(0).getResource());
+        assertEquals("surname2", result.getEntity().getPlainAttrMap().get("surname").getValues().get(0));
+
+        // verify user still exists on the backend REST service
+        response = webClient.get();
+        assertEquals(200, response.getStatus());
+        assertNotNull(response.getEntity());
+
+        // 3. delete
+        result = userService.delete(result.getEntity().getKey()).readEntity(
+                new GenericType<ProvisioningResult<UserTO>>() {
+        });
+        assertEquals(1, result.getPropagationStatuses().size());
+        assertEquals(PropagationTaskExecStatus.SUCCESS, result.getPropagationStatuses().get(0).getStatus());
+        assertEquals("rest-target-resource", result.getPropagationStatuses().get(0).getResource());
+
+        // verify user was removed by the backend REST service
+        assertEquals(404, webClient.get().getStatus());
+    }
 }

http://git-wip-us.apache.org/repos/asf/syncope/blob/5af8e4a4/fit/core-reference/src/test/resources/rest/AuthenticateScript.groovy
----------------------------------------------------------------------
diff --git a/fit/core-reference/src/test/resources/rest/AuthenticateScript.groovy b/fit/core-reference/src/test/resources/rest/AuthenticateScript.groovy
new file mode 100644
index 0000000..8ec4128
--- /dev/null
+++ b/fit/core-reference/src/test/resources/rest/AuthenticateScript.groovy
@@ -0,0 +1,55 @@
+/*
+ * 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.
+ */
+import com.fasterxml.jackson.databind.ObjectMapper
+import com.fasterxml.jackson.databind.node.ObjectNode
+import org.apache.cxf.jaxrs.client.WebClient
+import org.identityconnectors.framework.common.objects.Uid
+
+// Parameters:
+// The connector sends us the following:
+// client : CXF WebClient
+// action: String correponding to the action ("AUTHENTICATE" here)
+// log: a handler to the Log facility
+// objectClass: a String describing the Object class (__ACCOUNT__ / __GROUP__ / other)
+// username: username
+// password: password string, clear text or GuardedString depending on configuration
+// options: a handler to the OperationOptions Map
+
+log.info("Entering " + action + " Script");
+
+WebClient webClient = client;
+ObjectMapper mapper = new ObjectMapper();
+
+String key;
+
+switch (objectClass) {  
+case "__ACCOUNT__":
+  webClient.path("/users/authenticate").query("username", username).query("password", password);
+  response = webClient.post(null);
+  if (response.getStatus() == 200) {
+    ObjectNode node = mapper.readTree(response.getEntity());
+    return node.get("key").textValue();
+  } else {
+    throw new RuntimeException("Could not authenticate " + username);
+  }
+  break
+
+default:
+  throw new RuntimeException();
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/5af8e4a4/fit/core-reference/src/test/resources/rest/CreateScript.groovy
----------------------------------------------------------------------
diff --git a/fit/core-reference/src/test/resources/rest/CreateScript.groovy b/fit/core-reference/src/test/resources/rest/CreateScript.groovy
new file mode 100644
index 0000000..f97961e
--- /dev/null
+++ b/fit/core-reference/src/test/resources/rest/CreateScript.groovy
@@ -0,0 +1,65 @@
+/*
+ * 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.
+ */
+import com.fasterxml.jackson.databind.ObjectMapper
+import com.fasterxml.jackson.databind.node.ObjectNode
+import org.apache.cxf.jaxrs.client.WebClient
+import org.identityconnectors.framework.common.objects.Uid
+
+// Parameters:
+// The connector sends us the following:
+// client : CXF WebClient
+// action: String correponding to the action ("CREATE" here)
+// log: a handler to the Log facility
+// objectClass: a String describing the Object class (__ACCOUNT__ / __GROUP__ / other)
+// id: The entry identifier (ConnId's "Name" atribute. (most often matches the uid))
+// attributes: an Attribute Map, containg the <String> attribute name as a key
+// and the <List> attribute value(s) as value.
+// password: password string, clear text
+// options: a handler to the OperationOptions Map
+
+log.info("Entering " + action + " Script");
+
+WebClient webClient = client;
+ObjectMapper mapper = new ObjectMapper();
+
+String key;
+
+switch (objectClass) {  
+case "__ACCOUNT__":
+  ObjectNode node = mapper.createObjectNode();
+  node.set("key", node.textNode(id));
+  node.set("username", node.textNode(attributes.get("username").get(0)));
+  node.set("password", node.textNode(password));
+  node.set("firstName", node.textNode(attributes.get("firstName").get(0)));
+  node.set("surname", node.textNode(attributes.get("surname").get(0)));
+  node.set("email", node.textNode(attributes.get("email").get(0)));
+  
+  String payload = mapper.writeValueAsString(node);
+  
+  webClient.path("/users");
+  webClient.post(payload);
+  
+  key = node.get("key").textValue();
+  break
+
+default:
+  key = id;
+}
+
+return key;