You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@syncope.apache.org by il...@apache.org on 2015/02/12 10:14:12 UTC
[07/54] [abbrv] [partial] syncope git commit: [SYNCOPE-620] Renaming
'server' after 'core',
to provide continuity with older releases (especially for archetype)
http://git-wip-us.apache.org/repos/asf/syncope/blob/d30c8526/syncope620/fit/core-reference/src/main/resources/userWorkflow.bpmn20.xml
----------------------------------------------------------------------
diff --git a/syncope620/fit/core-reference/src/main/resources/userWorkflow.bpmn20.xml b/syncope620/fit/core-reference/src/main/resources/userWorkflow.bpmn20.xml
new file mode 100644
index 0000000..d26dbe3
--- /dev/null
+++ b/syncope620/fit/core-reference/src/main/resources/userWorkflow.bpmn20.xml
@@ -0,0 +1,577 @@
+<?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.
+-->
+<definitions xmlns="http://www.omg.org/spec/BPMN/20100524/MODEL"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xmlns:activiti="http://activiti.org/bpmn"
+ xmlns:bpmndi="http://www.omg.org/spec/BPMN/20100524/DI"
+ xmlns:omgdc="http://www.omg.org/spec/DD/20100524/DC"
+ xmlns:omgdi="http://www.omg.org/spec/DD/20100524/DI"
+ typeLanguage="http://www.w3.org/2001/XMLSchema"
+ expressionLanguage="http://www.w3.org/1999/XPath"
+ targetNamespace="http://activiti.org/bpmn20">
+
+ <process id="userWorkflow" name="User Workflow" isExecutable="true">
+ <startEvent id="theStart"/>
+ <sequenceFlow id="flow1" sourceRef="theStart" targetRef="create"/>
+ <serviceTask id="create" name="Create" activiti:expression="#{create.execute(execution.processInstanceId)}"/>
+ <sequenceFlow id="flow2" sourceRef="create" targetRef="createGW"/>
+ <exclusiveGateway id="createGW"/>
+ <sequenceFlow id="createAsAnonymous2Approval" sourceRef="createGW" targetRef="createApproval">
+ <conditionExpression xsi:type="tFormalExpression"><![CDATA[${wfExecutor == 'anonymous' || user.getRoleKeys().contains(9)}]]></conditionExpression>
+ </sequenceFlow>
+ <sequenceFlow id="create2Activate" sourceRef="createGW" targetRef="enableGW">
+ <conditionExpression xsi:type="tFormalExpression"><![CDATA[${!user.getRoleKeys().contains(9)}]]></conditionExpression>
+ </sequenceFlow>
+ <userTask id="createApproval" name="Create approval" activiti:candidateGroups="7" activiti:formKey="createApproval">
+ <extensionElements>
+ <activiti:formProperty id="username" name="Username" type="string" expression="${user.username}" writable="false"/>
+ <activiti:formProperty id="approve" name="Approve?" type="boolean" variable="approve" required="true"/>
+ <activiti:formProperty id="rejectReason" name="Reason for rejecting" type="string" variable="rejectReason"/>
+ </extensionElements>
+ </userTask>
+ <sequenceFlow id="flow3" sourceRef="createApproval" targetRef="createApprovalGW"/>
+ <exclusiveGateway id="createApprovalGW"/>
+ <sequenceFlow id="createApprovalGW2EnableGW" sourceRef="createApprovalGW" targetRef="enableGW">
+ <conditionExpression xsi:type="tFormalExpression"><![CDATA[${approve}]]></conditionExpression>
+ </sequenceFlow>
+ <sequenceFlow id="createApproval2Reject" sourceRef="createApprovalGW" targetRef="reject">
+ <conditionExpression xsi:type="tFormalExpression"><![CDATA[${!approve}]]></conditionExpression>
+ </sequenceFlow>
+ <exclusiveGateway id="enableGW"/>
+ <sequenceFlow id="createApprovalGW2OptIn" sourceRef="enableGW" targetRef="generateToken">
+ <conditionExpression xsi:type="tFormalExpression"><![CDATA[${user.getRoleKeys().contains(11)}]]></conditionExpression>
+ </sequenceFlow>
+ <sequenceFlow id="createApprovalGW2Activate" sourceRef="enableGW" targetRef="activate">
+ <conditionExpression xsi:type="tFormalExpression"><![CDATA[${enabled == null}]]></conditionExpression>
+ </sequenceFlow>
+ <sequenceFlow id="createApprovalGW2Active" sourceRef="enableGW" targetRef="active">
+ <conditionExpression xsi:type="tFormalExpression"><![CDATA[${enabled}]]></conditionExpression>
+ </sequenceFlow>
+ <sequenceFlow id="createApprovalGW2Suspended" sourceRef="enableGW" targetRef="suspend">
+ <conditionExpression xsi:type="tFormalExpression"><![CDATA[${!enabled}]]></conditionExpression>
+ </sequenceFlow>
+ <serviceTask id="activate" name="Activate" activiti:expression="#{autoActivate.execute(execution.processInstanceId)}"/>
+ <sequenceFlow id="flow4" sourceRef="activate" targetRef="active"/>
+ <serviceTask id="generateToken" name="Generate token" activiti:expression="#{generateToken.execute(execution.processInstanceId)}"/>
+ <sequenceFlow id="flow5" sourceRef="generateToken" targetRef="created"/>
+ <userTask id="created" name="Created"/>
+ <sequenceFlow id="flow6" sourceRef="created" targetRef="optinGW"/>
+ <exclusiveGateway id="optinGW"/>
+ <sequenceFlow id="created2Activate" sourceRef="optinGW" targetRef="removeToken">
+ <conditionExpression xsi:type="tFormalExpression"><![CDATA[${user.checkToken(token)}]]></conditionExpression>
+ </sequenceFlow>
+ <sequenceFlow id="created2Created" sourceRef="optinGW" targetRef="created">
+ <conditionExpression xsi:type="tFormalExpression"><![CDATA[${!user.checkToken(token)}]]></conditionExpression>
+ </sequenceFlow>
+ <scriptTask id="removeToken" name="Remove Token and Activate" scriptFormat="groovy" activiti:autoStoreVariables="false">
+ <script>
+ user.removeToken()
+ </script>
+ </scriptTask>
+ <sequenceFlow id="flow7" sourceRef="removeToken" targetRef="active"/>
+ <userTask id="active" name="Active"/>
+ <sequenceFlow id="flow8" sourceRef="active" targetRef="activeGw"/>
+ <exclusiveGateway id="activeGw"/>
+ <sequenceFlow id="active2UpdateApproval" sourceRef="activeGw" targetRef="updateApproval">
+ <conditionExpression xsi:type="tFormalExpression"><![CDATA[${wfExecutor == user.getUsername() and task == 'update'
+ and (!userMod.getMembershipsToAdd().isEmpty() or !userMod.getMembershipsToRemove().isEmpty())}]]></conditionExpression>
+ </sequenceFlow>
+ <sequenceFlow id="active2DeleteApproval" sourceRef="activeGw" targetRef="deleteApproval">
+ <conditionExpression xsi:type="tFormalExpression"><![CDATA[${wfExecutor == user.getUsername() and task == 'delete'}]]></conditionExpression>
+ </sequenceFlow>
+ <sequenceFlow id="active2Update" sourceRef="activeGw" targetRef="update">
+ <conditionExpression xsi:type="tFormalExpression"><![CDATA[${task == 'update'}]]></conditionExpression>
+ </sequenceFlow>
+ <sequenceFlow id="active2Suspend" sourceRef="activeGw" targetRef="suspend">
+ <conditionExpression xsi:type="tFormalExpression"><![CDATA[${task == 'suspend'}]]></conditionExpression>
+ </sequenceFlow>
+ <sequenceFlow id="active2Delete" sourceRef="activeGw" targetRef="delete">
+ <conditionExpression xsi:type="tFormalExpression"><![CDATA[${task == 'delete'}]]></conditionExpression>
+ </sequenceFlow>
+ <sequenceFlow id="active2RequestPasswordReset" sourceRef="activeGw" targetRef="generateToken4PasswordReset">
+ <conditionExpression xsi:type="tFormalExpression"><![CDATA[${task == 'requestPasswordReset'}]]></conditionExpression>
+ </sequenceFlow>
+ <sequenceFlow id="active2ConfirmPasswordReset" sourceRef="activeGw" targetRef="checkToken4ConfirmPasswordReset">
+ <conditionExpression xsi:type="tFormalExpression"><![CDATA[${task == 'confirmPasswordReset'}]]></conditionExpression>
+ </sequenceFlow>
+ <userTask id="updateApproval" name="Update approval" activiti:candidateGroups="7" activiti:formKey="updateApproval">
+ <extensionElements>
+ <activiti:formProperty id="username" name="Username" type="string" expression="${user.username}" writable="false"/>
+ <activiti:formProperty id="approve" name="Approve?" type="boolean" variable="approve" required="true"/>
+ <activiti:formProperty id="rejectReason" name="Reason for rejecting" type="string" variable="rejectReason"/>
+ </extensionElements>
+ </userTask>
+ <sequenceFlow id="flow8bis" sourceRef="updateApproval" targetRef="updateApprovalGW"/>
+ <exclusiveGateway id="updateApprovalGW"/>
+ <sequenceFlow id="updateApprovalGW2Update" sourceRef="updateApprovalGW" targetRef="update">
+ <conditionExpression xsi:type="tFormalExpression"><![CDATA[${approve}]]></conditionExpression>
+ </sequenceFlow>
+ <sequenceFlow id="updateApprovalGW2Reject" sourceRef="updateApprovalGW" targetRef="rejectUpdate">
+ <conditionExpression xsi:type="tFormalExpression"><![CDATA[${!approve}]]></conditionExpression>
+ </sequenceFlow>
+ <scriptTask id="rejectUpdate" name="Reject update" scriptFormat="groovy" activiti:autoStoreVariables="false">
+ <script>
+ execution.setVariable("propByResource", null);
+ </script>
+ </scriptTask>
+ <sequenceFlow id="flow8ter" sourceRef="rejectUpdate" targetRef="active"/>
+ <serviceTask id="update" name="Update" activiti:expression="#{update.execute(execution.processInstanceId)}"/>
+ <sequenceFlow id="flow9" sourceRef="update" targetRef="active"/>
+ <serviceTask id="suspend" name="Suspend" activiti:expression="#{suspend.execute(execution.processInstanceId)}"/>
+ <sequenceFlow id="flow10" sourceRef="suspend" targetRef="suspended"/>
+ <userTask id="suspended" name="Suspended"/>
+ <sequenceFlow id="flow11" sourceRef="suspended" targetRef="suspendedGw"/>
+ <exclusiveGateway id="suspendedGw"/>
+ <sequenceFlow id="suspended2Reactivate" sourceRef="suspendedGw" targetRef="reactivate">
+ <conditionExpression xsi:type="tFormalExpression"><![CDATA[${task == 'reactivate'}]]></conditionExpression>
+ </sequenceFlow>
+ <sequenceFlow id="suspended2Delete" sourceRef="suspendedGw" targetRef="delete">
+ <conditionExpression xsi:type="tFormalExpression"><![CDATA[${task == 'delete'}]]></conditionExpression>
+ </sequenceFlow>
+ <serviceTask id="reactivate" name="Reactivate" activiti:expression="#{reactivate.execute(execution.processInstanceId)}"/>
+ <sequenceFlow id="flow12" sourceRef="reactivate" targetRef="active"/>
+ <scriptTask id="reject" name="Reject" scriptFormat="groovy" activiti:autoStoreVariables="false">
+ <script>
+ def scriptVar = rejectReason
+ execution.setVariable("propByResource", null);
+ </script>
+ </scriptTask>
+ <sequenceFlow id="flow13" sourceRef="reject" targetRef="rejected"/>
+ <userTask id="rejected" name="Rejected"/>
+ <sequenceFlow id="flow14" sourceRef="rejected" targetRef="rejectedGw"/>
+ <exclusiveGateway id="rejectedGw"/>
+ <sequenceFlow id="rejected2Delete" sourceRef="rejectedGw" targetRef="delete">
+ <conditionExpression xsi:type="tFormalExpression"><![CDATA[${task == 'delete'}]]></conditionExpression>
+ </sequenceFlow>
+ <sequenceFlow id="rejected2Rejected" sourceRef="rejectedGw" targetRef="rejected">
+ <conditionExpression xsi:type="tFormalExpression"><![CDATA[${empty task}]]></conditionExpression>
+ </sequenceFlow>
+ <userTask id="deleteApproval" name="Delete approval" activiti:candidateGroups="7" activiti:formKey="deleteApproval">
+ <extensionElements>
+ <activiti:formProperty id="username" name="Username" type="string" expression="${user.username}" writable="false"/>
+ <activiti:formProperty id="approve" name="Approve?" type="boolean" variable="approve" required="true"/>
+ <activiti:formProperty id="rejectReason" name="Reason for rejecting" type="string" variable="rejectReason"/>
+ </extensionElements>
+ </userTask>
+ <sequenceFlow id="flow14bis" sourceRef="deleteApproval" targetRef="deleteApprovalGW"/>
+ <exclusiveGateway id="deleteApprovalGW"/>
+ <sequenceFlow id="deleteApprovalGW2Delete" sourceRef="deleteApprovalGW" targetRef="delete">
+ <conditionExpression xsi:type="tFormalExpression"><![CDATA[${approve}]]></conditionExpression>
+ </sequenceFlow>
+ <sequenceFlow id="deleteApprovalGW2Reject" sourceRef="deleteApprovalGW" targetRef="rejectDelete">
+ <conditionExpression xsi:type="tFormalExpression"><![CDATA[${!approve}]]></conditionExpression>
+ </sequenceFlow>
+ <scriptTask id="rejectDelete" name="Reject delete" scriptFormat="groovy" activiti:autoStoreVariables="false">
+ <script>
+ execution.setVariable("propByResource", null);
+ </script>
+ </scriptTask>
+ <sequenceFlow id="flow14ter" sourceRef="rejectDelete" targetRef="active"/>
+
+ <serviceTask id="generateToken4PasswordReset" name="Generate token" activiti:expression="#{generateToken.execute(execution.processInstanceId)}"/>
+ <sequenceFlow id="flow15" sourceRef="generateToken4PasswordReset" targetRef="notify4RequestPasswordReset"/>
+ <serviceTask id="notify4RequestPasswordReset" name="Notification" activiti:expression="#{notify.execute(execution.processInstanceId)}"/>
+ <sequenceFlow id="flow16" sourceRef="notify4RequestPasswordReset" targetRef="active"/>
+
+ <serviceTask id="checkToken4ConfirmPasswordReset" name="Check token, remove and update password" activiti:expression="#{passwordReset.execute(execution.processInstanceId)}"/>
+ <sequenceFlow id="flow17" sourceRef="checkToken4ConfirmPasswordReset" targetRef="notify4ConfirmPasswordReset"/>
+ <serviceTask id="notify4ConfirmPasswordReset" name="Notification" activiti:expression="#{notify.execute(execution.processInstanceId)}"/>
+ <sequenceFlow id="flow18" sourceRef="notify4ConfirmPasswordReset" targetRef="active"/>
+
+ <serviceTask id="delete" name="Delete" activiti:expression="#{delete.execute(execution.processInstanceId)}"/>
+ <sequenceFlow id="flow99" sourceRef="delete" targetRef="theEnd"/>
+ <endEvent id="theEnd"/>
+ </process>
+
+ <bpmndi:BPMNDiagram id="BPMNDiagram_userWorkflow">
+ <bpmndi:BPMNPlane bpmnElement="userWorkflow" id="BPMNPlane_userWorkflow">
+ <bpmndi:BPMNShape bpmnElement="theStart" id="BPMNShape_theStart">
+ <omgdc:Bounds height="30.0" width="30.0" x="0.0" y="512.0"/>
+ </bpmndi:BPMNShape>
+ <bpmndi:BPMNShape bpmnElement="create" id="BPMNShape_create">
+ <omgdc:Bounds height="60.0" width="100.0" x="80.0" y="497.0"/>
+ </bpmndi:BPMNShape>
+ <bpmndi:BPMNShape bpmnElement="createGW" id="BPMNShape_createGW">
+ <omgdc:Bounds height="40.0" width="40.0" x="230.0" y="506.0"/>
+ </bpmndi:BPMNShape>
+ <bpmndi:BPMNShape bpmnElement="createApproval" id="BPMNShape_createApproval">
+ <omgdc:Bounds height="60.0" width="100.0" x="320.0" y="560.0"/>
+ </bpmndi:BPMNShape>
+ <bpmndi:BPMNShape bpmnElement="createApprovalGW" id="BPMNShape_createApprovalGW">
+ <omgdc:Bounds height="40.0" width="40.0" x="470.0" y="556.0"/>
+ </bpmndi:BPMNShape>
+ <bpmndi:BPMNShape bpmnElement="enableGW" id="BPMNShape_enableGW">
+ <omgdc:Bounds height="40.0" width="40.0" x="590.0" y="429.0"/>
+ </bpmndi:BPMNShape>
+ <bpmndi:BPMNShape bpmnElement="activate" id="BPMNShape_activate">
+ <omgdc:Bounds height="60.0" width="100.0" x="710.0" y="610.0"/>
+ </bpmndi:BPMNShape>
+ <bpmndi:BPMNShape bpmnElement="generateToken" id="BPMNShape_generateToken">
+ <omgdc:Bounds height="60.0" width="100.0" x="702.0" y="188.0"/>
+ </bpmndi:BPMNShape>
+ <bpmndi:BPMNShape bpmnElement="created" id="BPMNShape_created">
+ <omgdc:Bounds height="60.0" width="100.0" x="852.0" y="213.0"/>
+ </bpmndi:BPMNShape>
+ <bpmndi:BPMNShape bpmnElement="optinGW" id="BPMNShape_optinGW">
+ <omgdc:Bounds height="40.0" width="40.0" x="1002.0" y="240.0"/>
+ </bpmndi:BPMNShape>
+ <bpmndi:BPMNShape bpmnElement="removeToken" id="BPMNShape_removeToken">
+ <omgdc:Bounds height="60.0" width="100.0" x="1092.0" y="248.0"/>
+ </bpmndi:BPMNShape>
+ <bpmndi:BPMNShape bpmnElement="active" id="BPMNShape_active">
+ <omgdc:Bounds height="60.0" width="100.0" x="1030.0" y="511.0"/>
+ </bpmndi:BPMNShape>
+ <bpmndi:BPMNShape bpmnElement="activeGw" id="BPMNShape_activeGw">
+ <omgdc:Bounds height="40.0" width="40.0" x="1400.0" y="520.0"/>
+ </bpmndi:BPMNShape>
+ <bpmndi:BPMNShape bpmnElement="updateApproval" id="BPMNShape_updateApproval">
+ <omgdc:Bounds height="60.0" width="100.0" x="1490.0" y="740.0"/>
+ </bpmndi:BPMNShape>
+ <bpmndi:BPMNShape bpmnElement="updateApprovalGW" id="BPMNShape_updateApprovalGW">
+ <omgdc:Bounds height="40.0" width="40.0" x="1670.0" y="740.0"/>
+ </bpmndi:BPMNShape>
+ <bpmndi:BPMNShape bpmnElement="rejectUpdate" id="BPMNShape_rejectUpdate">
+ <omgdc:Bounds height="60.0" width="100.0" x="1790.0" y="840.0"/>
+ </bpmndi:BPMNShape>
+ <bpmndi:BPMNShape bpmnElement="update" id="BPMNShape_update">
+ <omgdc:Bounds height="60.0" width="100.0" x="1790.0" y="700.0"/>
+ </bpmndi:BPMNShape>
+ <bpmndi:BPMNShape bpmnElement="suspend" id="BPMNShape_suspend">
+ <omgdc:Bounds height="60.0" width="100.0" x="1490.0" y="100.0"/>
+ </bpmndi:BPMNShape>
+ <bpmndi:BPMNShape bpmnElement="suspended" id="BPMNShape_suspended">
+ <omgdc:Bounds height="60.0" width="100.0" x="1640.0" y="120.0"/>
+ </bpmndi:BPMNShape>
+ <bpmndi:BPMNShape bpmnElement="suspendedGw" id="BPMNShape_suspendedGw">
+ <omgdc:Bounds height="40.0" width="40.0" x="1820.0" y="180.0"/>
+ </bpmndi:BPMNShape>
+ <bpmndi:BPMNShape bpmnElement="reactivate" id="BPMNShape_reactivate">
+ <omgdc:Bounds height="60.0" width="100.0" x="1940.0" y="110.0"/>
+ </bpmndi:BPMNShape>
+ <bpmndi:BPMNShape bpmnElement="reject" id="BPMNShape_reject">
+ <omgdc:Bounds height="60.0" width="100.0" x="560.0" y="659.0"/>
+ </bpmndi:BPMNShape>
+ <bpmndi:BPMNShape bpmnElement="rejected" id="BPMNShape_rejected">
+ <omgdc:Bounds height="60.0" width="100.0" x="710.0" y="770.0"/>
+ </bpmndi:BPMNShape>
+ <bpmndi:BPMNShape bpmnElement="rejectedGw" id="BPMNShape_rejectedGw">
+ <omgdc:Bounds height="40.0" width="40.0" x="890.0" y="775.0"/>
+ </bpmndi:BPMNShape>
+ <bpmndi:BPMNShape bpmnElement="deleteApproval" id="BPMNShape_deleteApproval">
+ <omgdc:Bounds height="60.0" width="100.0" x="1490.0" y="280.0"/>
+ </bpmndi:BPMNShape>
+ <bpmndi:BPMNShape bpmnElement="deleteApprovalGW" id="BPMNShape_deleteApprovalGW">
+ <omgdc:Bounds height="40.0" width="40.0" x="1670.0" y="300.0"/>
+ </bpmndi:BPMNShape>
+ <bpmndi:BPMNShape bpmnElement="rejectDelete" id="BPMNShape_rejectDelete">
+ <omgdc:Bounds height="60.0" width="100.0" x="1790.0" y="240.0"/>
+ </bpmndi:BPMNShape>
+ <bpmndi:BPMNShape bpmnElement="delete" id="BPMNShape_delete">
+ <omgdc:Bounds height="60.0" width="100.0" x="1940.0" y="358.0"/>
+ </bpmndi:BPMNShape>
+ <bpmndi:BPMNShape bpmnElement="theEnd" id="BPMNShape_theEnd">
+ <omgdc:Bounds height="28.0" width="28.0" x="2078.1893792531678" y="374.0"/>
+ </bpmndi:BPMNShape>
+ <bpmndi:BPMNShape bpmnElement="generateToken4PasswordReset" id="BPMNShape_generateToken4PasswordReset">
+ <omgdc:Bounds height="59.99999999999994" width="100.0" x="1543.209935088986" y="452.6749142927693"/>
+ </bpmndi:BPMNShape>
+ <bpmndi:BPMNShape bpmnElement="notify4RequestPasswordReset" id="BPMNShape_notify4RequestPasswordReset">
+ <omgdc:Bounds height="60.00000000000006" width="100.0" x="1748.9712597675173" y="452.6749142927692"/>
+ </bpmndi:BPMNShape>
+ <bpmndi:BPMNShape bpmnElement="checkToken4ConfirmPasswordReset" id="BPMNShape_checkToken4ConfirmPasswordReset">
+ <omgdc:Bounds height="60.0" width="100.0" x="1558.797798366986" y="561.167207412115"/>
+ </bpmndi:BPMNShape>
+ <bpmndi:BPMNShape bpmnElement="notify4ConfirmPasswordReset" id="BPMNShape_notify4ConfirmPasswordReset">
+ <omgdc:Bounds height="60.0" width="100.0" x="1748.971259767517" y="561.167207412115"/>
+ </bpmndi:BPMNShape>
+ <bpmndi:BPMNEdge bpmnElement="flow17" id="BPMNEdge_flow17">
+ <omgdi:waypoint x="1658.797798366986" y="591.167207412115"/>
+ <omgdi:waypoint x="1748.971259767517" y="591.167207412115"/>
+ </bpmndi:BPMNEdge>
+ <bpmndi:BPMNEdge bpmnElement="flow12" id="BPMNEdge_flow12">
+ <omgdi:waypoint x="1940.0" y="129.51612903225805"/>
+ <omgdi:waypoint x="1928.0" y="127.0"/>
+ <omgdi:waypoint x="1378.0" y="40.0"/>
+ <omgdi:waypoint x="1097.8443113772455" y="511.0"/>
+ </bpmndi:BPMNEdge>
+ <bpmndi:BPMNEdge bpmnElement="flow11" id="BPMNEdge_flow11">
+ <omgdi:waypoint x="1740.0" y="150.0"/>
+ <omgdi:waypoint x="1752.0" y="150.0"/>
+ <omgdi:waypoint x="1752.0" y="200.0"/>
+ <omgdi:waypoint x="1820.0" y="200.0"/>
+ </bpmndi:BPMNEdge>
+ <bpmndi:BPMNEdge bpmnElement="active2DeleteApproval" id="BPMNEdge_active2DeleteApproval">
+ <omgdi:waypoint x="1440.0" y="540.0"/>
+ <omgdi:waypoint x="1454.0" y="540.0"/>
+ <omgdi:waypoint x="1454.0" y="310.0"/>
+ <omgdi:waypoint x="1490.0" y="310.0"/>
+ </bpmndi:BPMNEdge>
+ <bpmndi:BPMNEdge bpmnElement="flow14bis" id="BPMNEdge_flow14bis">
+ <omgdi:waypoint x="1590.0" y="310.0"/>
+ <omgdi:waypoint x="1602.0" y="310.0"/>
+ <omgdi:waypoint x="1602.0" y="320.0"/>
+ <omgdi:waypoint x="1670.0" y="320.0"/>
+ </bpmndi:BPMNEdge>
+ <bpmndi:BPMNEdge bpmnElement="flow10" id="BPMNEdge_flow10">
+ <omgdi:waypoint x="1590.0" y="130.0"/>
+ <omgdi:waypoint x="1602.0" y="130.0"/>
+ <omgdi:waypoint x="1602.0" y="150.0"/>
+ <omgdi:waypoint x="1640.0" y="150.0"/>
+ </bpmndi:BPMNEdge>
+ <bpmndi:BPMNEdge bpmnElement="active2RequestPasswordReset" id="BPMNEdge_active2RequestPasswordReset">
+ <omgdi:waypoint x="1439.5" y="540.5"/>
+ <omgdi:waypoint x="1593.209935088986" y="540.5"/>
+ <omgdi:waypoint x="1593.209935088986" y="512.6749142927692"/>
+ </bpmndi:BPMNEdge>
+ <bpmndi:BPMNEdge bpmnElement="active2ConfirmPasswordReset" id="BPMNEdge_active2ConfirmPasswordReset">
+ <omgdi:waypoint x="1439.5" y="540.5"/>
+ <omgdi:waypoint x="1608.797798366986" y="540.5"/>
+ <omgdi:waypoint x="1608.797798366986" y="561.167207412115"/>
+ </bpmndi:BPMNEdge>
+ <bpmndi:BPMNEdge bpmnElement="deleteApprovalGW2Delete" id="BPMNEdge_deleteApprovalGW2Delete">
+ <omgdi:waypoint x="1710.0" y="320.0"/>
+ <omgdi:waypoint x="1752.0" y="320.0"/>
+ <omgdi:waypoint x="1752.0" y="388.0"/>
+ <omgdi:waypoint x="1940.0" y="388.0"/>
+ </bpmndi:BPMNEdge>
+ <bpmndi:BPMNEdge bpmnElement="createApproval2Reject" id="BPMNEdge_createApproval2Reject">
+ <omgdi:waypoint x="510.0" y="576.0"/>
+ <omgdi:waypoint x="522.0" y="576.0"/>
+ <omgdi:waypoint x="522.0" y="689.0"/>
+ <omgdi:waypoint x="560.0" y="689.0"/>
+ </bpmndi:BPMNEdge>
+ <bpmndi:BPMNEdge bpmnElement="active2Delete" id="BPMNEdge_active2Delete">
+ <omgdi:waypoint x="1440.0" y="540.0"/>
+ <omgdi:waypoint x="1452.0" y="540.0"/>
+ <omgdi:waypoint x="1452.0" y="680.6812757582483"/>
+ <omgdi:waypoint x="1955.9214707261015" y="680.6812757582483"/>
+ <omgdi:waypoint x="1986.506931044467" y="418.0"/>
+ </bpmndi:BPMNEdge>
+ <bpmndi:BPMNEdge bpmnElement="updateApprovalGW2Update" id="BPMNEdge_updateApprovalGW2Update">
+ <omgdi:waypoint x="1710.0" y="760.0"/>
+ <omgdi:waypoint x="1752.0" y="760.0"/>
+ <omgdi:waypoint x="1752.0" y="730.0"/>
+ <omgdi:waypoint x="1790.0" y="730.0"/>
+ </bpmndi:BPMNEdge>
+ <bpmndi:BPMNEdge bpmnElement="active2UpdateApproval" id="BPMNEdge_active2UpdateApproval">
+ <omgdi:waypoint x="1440.0" y="540.0"/>
+ <omgdi:waypoint x="1454.0" y="540.0"/>
+ <omgdi:waypoint x="1454.0" y="770.0"/>
+ <omgdi:waypoint x="1490.0" y="770.0"/>
+ </bpmndi:BPMNEdge>
+ <bpmndi:BPMNEdge bpmnElement="rejected2Delete" id="BPMNEdge_rejected2Delete">
+ <omgdi:waypoint x="930.0" y="795.0"/>
+ <omgdi:waypoint x="972.0" y="795.0"/>
+ <omgdi:waypoint x="1470.0" y="911.0"/>
+ <omgdi:waypoint x="1990.0" y="911.0"/>
+ <omgdi:waypoint x="1990.0" y="418.0"/>
+ </bpmndi:BPMNEdge>
+ <bpmndi:BPMNEdge bpmnElement="createApprovalGW2Active" id="BPMNEdge_createApprovalGW2Active">
+ <omgdi:waypoint x="630.0" y="449.0"/>
+ <omgdi:waypoint x="674.0" y="449.0"/>
+ <omgdi:waypoint x="674.0" y="540.0"/>
+ <omgdi:waypoint x="1030.0" y="540.8768472906404"/>
+ </bpmndi:BPMNEdge>
+ <bpmndi:BPMNEdge bpmnElement="updateApprovalGW2Reject" id="BPMNEdge_updateApprovalGW2Reject">
+ <omgdi:waypoint x="1710.0" y="760.0"/>
+ <omgdi:waypoint x="1752.0" y="760.0"/>
+ <omgdi:waypoint x="1752.0" y="870.0"/>
+ <omgdi:waypoint x="1790.0" y="870.0"/>
+ </bpmndi:BPMNEdge>
+ <bpmndi:BPMNEdge bpmnElement="flow8ter" id="BPMNEdge_flow8ter">
+ <omgdi:waypoint x="1790.0" y="879.6774193548387"/>
+ <omgdi:waypoint x="1778.0" y="882.0"/>
+ <omgdi:waypoint x="1225.0" y="787.0"/>
+ <omgdi:waypoint x="1080.0" y="726.0"/>
+ <omgdi:waypoint x="1080.0" y="571.0"/>
+ </bpmndi:BPMNEdge>
+ <bpmndi:BPMNEdge bpmnElement="flow15" id="BPMNEdge_flow15">
+ <omgdi:waypoint x="1643.209935088986" y="482.6749142927693"/>
+ <omgdi:waypoint x="1748.9712597675173" y="482.67491429276924"/>
+ </bpmndi:BPMNEdge>
+ <bpmndi:BPMNEdge bpmnElement="suspended2Reactivate" id="BPMNEdge_suspended2Reactivate">
+ <omgdi:waypoint x="1860.0" y="200.0"/>
+ <omgdi:waypoint x="1902.0" y="200.0"/>
+ <omgdi:waypoint x="1902.0" y="140.0"/>
+ <omgdi:waypoint x="1940.0" y="140.0"/>
+ </bpmndi:BPMNEdge>
+ <bpmndi:BPMNEdge bpmnElement="flow13" id="BPMNEdge_flow13">
+ <omgdi:waypoint x="660.0" y="689.0"/>
+ <omgdi:waypoint x="672.0" y="689.0"/>
+ <omgdi:waypoint x="672.0" y="800.0"/>
+ <omgdi:waypoint x="710.0" y="800.0"/>
+ </bpmndi:BPMNEdge>
+ <bpmndi:BPMNEdge bpmnElement="flow14" id="BPMNEdge_flow14">
+ <omgdi:waypoint x="760.0" y="770.0"/>
+ <omgdi:waypoint x="760.0" y="732.8074937730017"/>
+ <omgdi:waypoint x="910.0" y="732.8074937730017"/>
+ <omgdi:waypoint x="910.0" y="775.0"/>
+ </bpmndi:BPMNEdge>
+ <bpmndi:BPMNEdge bpmnElement="createApprovalGW2EnableGW" id="BPMNEdge_createApprovalGW2EnableGW">
+ <omgdi:waypoint x="510.0" y="576.0"/>
+ <omgdi:waypoint x="522.0" y="576.0"/>
+ <omgdi:waypoint x="522.0" y="449.0"/>
+ <omgdi:waypoint x="590.0" y="449.0"/>
+ </bpmndi:BPMNEdge>
+ <bpmndi:BPMNEdge bpmnElement="active2Update" id="BPMNEdge_active2Update">
+ <omgdi:waypoint x="1440.0" y="540.0"/>
+ <omgdi:waypoint x="1456.0" y="540.0"/>
+ <omgdi:waypoint x="1456.0" y="730.0"/>
+ <omgdi:waypoint x="1790.0" y="730.0"/>
+ </bpmndi:BPMNEdge>
+ <bpmndi:BPMNEdge bpmnElement="create2Activate" id="BPMNEdge_create2Activate">
+ <omgdi:waypoint x="270.0" y="526.0"/>
+ <omgdi:waypoint x="282.0" y="526.0"/>
+ <omgdi:waypoint x="282.0" y="449.0"/>
+ <omgdi:waypoint x="590.0" y="449.0"/>
+ </bpmndi:BPMNEdge>
+ <bpmndi:BPMNEdge bpmnElement="active2Suspend" id="BPMNEdge_active2Suspend">
+ <omgdi:waypoint x="1440.0" y="540.0"/>
+ <omgdi:waypoint x="1452.0" y="540.0"/>
+ <omgdi:waypoint x="1452.0" y="130.0"/>
+ <omgdi:waypoint x="1490.0" y="130.0"/>
+ </bpmndi:BPMNEdge>
+ <bpmndi:BPMNEdge bpmnElement="suspended2Delete" id="BPMNEdge_suspended2Delete">
+ <omgdi:waypoint x="1860.0" y="200.0"/>
+ <omgdi:waypoint x="1990.0" y="200.0"/>
+ <omgdi:waypoint x="1990.0" y="358.0"/>
+ </bpmndi:BPMNEdge>
+ <bpmndi:BPMNEdge bpmnElement="created2Activate" id="BPMNEdge_created2Activate">
+ <omgdi:waypoint x="1042.0" y="260.0"/>
+ <omgdi:waypoint x="1054.0" y="260.0"/>
+ <omgdi:waypoint x="1054.0" y="278.0"/>
+ <omgdi:waypoint x="1092.0" y="278.0"/>
+ </bpmndi:BPMNEdge>
+ <bpmndi:BPMNEdge bpmnElement="createAsAnonymous2Approval" id="BPMNEdge_createAsAnonymous2Approval">
+ <omgdi:waypoint x="270.0" y="526.0"/>
+ <omgdi:waypoint x="282.0" y="526.0"/>
+ <omgdi:waypoint x="282.0" y="590.0"/>
+ <omgdi:waypoint x="320.0" y="590.0"/>
+ </bpmndi:BPMNEdge>
+ <bpmndi:BPMNEdge bpmnElement="flow3" id="BPMNEdge_flow3">
+ <omgdi:waypoint x="420.0" y="590.0"/>
+ <omgdi:waypoint x="432.0" y="590.0"/>
+ <omgdi:waypoint x="432.0" y="576.0"/>
+ <omgdi:waypoint x="470.0" y="576.0"/>
+ </bpmndi:BPMNEdge>
+ <bpmndi:BPMNEdge bpmnElement="flow2" id="BPMNEdge_flow2">
+ <omgdi:waypoint x="180.0" y="527.0"/>
+ <omgdi:waypoint x="192.0" y="527.0"/>
+ <omgdi:waypoint x="192.0" y="526.0"/>
+ <omgdi:waypoint x="230.0" y="526.0"/>
+ </bpmndi:BPMNEdge>
+ <bpmndi:BPMNEdge bpmnElement="rejected2Rejected" id="BPMNEdge_rejected2Rejected">
+ <omgdi:waypoint x="890.6451612903226" y="795.6451612903226"/>
+ <omgdi:waypoint x="810.0" y="798.3333333333334"/>
+ </bpmndi:BPMNEdge>
+ <bpmndi:BPMNEdge bpmnElement="flow5" id="BPMNEdge_flow5">
+ <omgdi:waypoint x="802.0" y="218.0"/>
+ <omgdi:waypoint x="814.0" y="218.0"/>
+ <omgdi:waypoint x="814.0" y="243.0"/>
+ <omgdi:waypoint x="852.0" y="243.0"/>
+ </bpmndi:BPMNEdge>
+ <bpmndi:BPMNEdge bpmnElement="flow4" id="BPMNEdge_flow4">
+ <omgdi:waypoint x="810.0" y="640.0"/>
+ <omgdi:waypoint x="822.0" y="640.0"/>
+ <omgdi:waypoint x="959.0" y="640.0"/>
+ <omgdi:waypoint x="1043.3333333333333" y="571.0"/>
+ </bpmndi:BPMNEdge>
+ <bpmndi:BPMNEdge bpmnElement="createApprovalGW2Suspended" id="BPMNEdge_createApprovalGW2Suspended">
+ <omgdi:waypoint x="630.0" y="449.0"/>
+ <omgdi:waypoint x="672.0" y="449.0"/>
+ <omgdi:waypoint x="672.0" y="130.0"/>
+ <omgdi:waypoint x="1490.0" y="130.0"/>
+ </bpmndi:BPMNEdge>
+ <bpmndi:BPMNEdge bpmnElement="flow14ter" id="BPMNEdge_flow14ter">
+ <omgdi:waypoint x="1790.0" y="260.7608891486752"/>
+ <omgdi:waypoint x="1424.117736926915" y="193.1523534073587"/>
+ <omgdi:waypoint x="1109.678315230625" y="511.0"/>
+ </bpmndi:BPMNEdge>
+ <bpmndi:BPMNEdge bpmnElement="createApprovalGW2OptIn" id="BPMNEdge_createApprovalGW2OptIn">
+ <omgdi:waypoint x="630.0" y="449.0"/>
+ <omgdi:waypoint x="674.0" y="449.0"/>
+ <omgdi:waypoint x="700.0" y="449.0"/>
+ <omgdi:waypoint x="745.2467532467532" y="248.0"/>
+ </bpmndi:BPMNEdge>
+ <bpmndi:BPMNEdge bpmnElement="flow1" id="BPMNEdge_flow1">
+ <omgdi:waypoint x="30.0" y="527.0"/>
+ <omgdi:waypoint x="80.0" y="527.0"/>
+ </bpmndi:BPMNEdge>
+ <bpmndi:BPMNEdge bpmnElement="flow16" id="BPMNEdge_flow16">
+ <omgdi:waypoint x="1748.9712597675173" y="459.5470829510475"/>
+ <omgdi:waypoint x="1592.4096593525787" y="387.128477171313"/>
+ <omgdi:waypoint x="1130.0" y="525.9854974413342"/>
+ </bpmndi:BPMNEdge>
+ <bpmndi:BPMNEdge bpmnElement="created2Created" id="BPMNEdge_created2Created">
+ <omgdi:waypoint x="1002.0" y="260.0"/>
+ <omgdi:waypoint x="990.0" y="260.0"/>
+ <omgdi:waypoint x="990.0" y="243.0"/>
+ <omgdi:waypoint x="952.0" y="243.0"/>
+ </bpmndi:BPMNEdge>
+ <bpmndi:BPMNEdge bpmnElement="flow18" id="BPMNEdge_flow18">
+ <omgdi:waypoint x="1748.971259767517" y="619.7464352880323"/>
+ <omgdi:waypoint x="1673.525420205687" y="662.8701121105813"/>
+ <omgdi:waypoint x="1130.0" y="551.266629529393"/>
+ </bpmndi:BPMNEdge>
+ <bpmndi:BPMNEdge bpmnElement="createApprovalGW2Activate" id="BPMNEdge_createApprovalGW2Activate">
+ <omgdi:waypoint x="630.0" y="449.0"/>
+ <omgdi:waypoint x="672.0" y="449.0"/>
+ <omgdi:waypoint x="672.0" y="640.0"/>
+ <omgdi:waypoint x="710.0" y="640.0"/>
+ </bpmndi:BPMNEdge>
+ <bpmndi:BPMNEdge bpmnElement="flow7" id="BPMNEdge_flow7">
+ <omgdi:waypoint x="1134.9277566539924" y="308.0"/>
+ <omgdi:waypoint x="1087.0722433460076" y="511.0"/>
+ </bpmndi:BPMNEdge>
+ <bpmndi:BPMNEdge bpmnElement="flow6" id="BPMNEdge_flow6">
+ <omgdi:waypoint x="952.0" y="252.67741935483872"/>
+ <omgdi:waypoint x="964.0" y="255.0"/>
+ <omgdi:waypoint x="964.0" y="260.0"/>
+ <omgdi:waypoint x="1002.0" y="260.0"/>
+ </bpmndi:BPMNEdge>
+ <bpmndi:BPMNEdge bpmnElement="flow9" id="BPMNEdge_flow9">
+ <omgdi:waypoint x="1828.6246202240113" y="760.0"/>
+ <omgdi:waypoint x="1811.88836468294" y="804.1381014189917"/>
+ <omgdi:waypoint x="1474.4398193359375" y="804.1381014189917"/>
+ <omgdi:waypoint x="1124.969521769241" y="571.0"/>
+ </bpmndi:BPMNEdge>
+ <bpmndi:BPMNEdge bpmnElement="deleteApprovalGW2Reject" id="BPMNEdge_deleteApprovalGW2Reject">
+ <omgdi:waypoint x="1710.0" y="320.0"/>
+ <omgdi:waypoint x="1752.0" y="320.0"/>
+ <omgdi:waypoint x="1752.0" y="270.0"/>
+ <omgdi:waypoint x="1790.0" y="270.0"/>
+ </bpmndi:BPMNEdge>
+ <bpmndi:BPMNEdge bpmnElement="flow8bis" id="BPMNEdge_flow8bis">
+ <omgdi:waypoint x="1590.0" y="770.0"/>
+ <omgdi:waypoint x="1602.0" y="770.0"/>
+ <omgdi:waypoint x="1602.0" y="760.0"/>
+ <omgdi:waypoint x="1670.0" y="760.0"/>
+ </bpmndi:BPMNEdge>
+ <bpmndi:BPMNEdge bpmnElement="flow99" id="BPMNEdge_flow99">
+ <omgdi:waypoint x="2040.0" y="388.0"/>
+ <omgdi:waypoint x="2078.1893792531678" y="388.0"/>
+ </bpmndi:BPMNEdge>
+ <bpmndi:BPMNEdge bpmnElement="flow8" id="BPMNEdge_flow8">
+ <omgdi:waypoint x="1130.0" y="540.8529411764706"/>
+ <omgdi:waypoint x="1400.058651026393" y="540.0586510263929"/>
+ </bpmndi:BPMNEdge>
+ </bpmndi:BPMNPlane>
+ </bpmndi:BPMNDiagram>
+</definitions>
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/syncope/blob/d30c8526/syncope620/fit/core-reference/src/main/resources/workflow.properties
----------------------------------------------------------------------
diff --git a/syncope620/fit/core-reference/src/main/resources/workflow.properties b/syncope620/fit/core-reference/src/main/resources/workflow.properties
new file mode 100644
index 0000000..9f0e35e
--- /dev/null
+++ b/syncope620/fit/core-reference/src/main/resources/workflow.properties
@@ -0,0 +1,20 @@
+# 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.
+wf.directory=${conf.directory}
+jobExecutorActivate=false
+uwfAdapter=org.apache.syncope.core.workflow.java.DefaultUserWorkflowAdapter
+rwfAdapter=org.apache.syncope.core.workflow.java.DefaultRoleWorkflowAdapter
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/syncope/blob/d30c8526/syncope620/fit/core-reference/src/main/webapp/WEB-INF/glassfish-web.xml
----------------------------------------------------------------------
diff --git a/syncope620/fit/core-reference/src/main/webapp/WEB-INF/glassfish-web.xml b/syncope620/fit/core-reference/src/main/webapp/WEB-INF/glassfish-web.xml
new file mode 100644
index 0000000..ab6a9bf
--- /dev/null
+++ b/syncope620/fit/core-reference/src/main/webapp/WEB-INF/glassfish-web.xml
@@ -0,0 +1,33 @@
+<?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>
+ <!-- Uncomment this when using JNDI DataSource -->
+ <!--<resource-ref>
+ <res-ref-name>jdbc/syncopeDataSource</res-ref-name>
+ <jndi-name>jdbc/syncopeDataSource</jndi-name>
+ </resource-ref>-->
+ <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/d30c8526/syncope620/fit/core-reference/src/main/webapp/WEB-INF/jboss-deployment-structure.xml
----------------------------------------------------------------------
diff --git a/syncope620/fit/core-reference/src/main/webapp/WEB-INF/jboss-deployment-structure.xml b/syncope620/fit/core-reference/src/main/webapp/WEB-INF/jboss-deployment-structure.xml
new file mode 100644
index 0000000..f47298d
--- /dev/null
+++ b/syncope620/fit/core-reference/src/main/webapp/WEB-INF/jboss-deployment-structure.xml
@@ -0,0 +1,38 @@
+<?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"/>
+ <subsystem name="jaxrs"/>
+ </exclude-subsystems>
+ <dependencies>
+ <module name="org.apache.xalan"/>
+ </dependencies>
+ <exclusions>
+ <module name="javax.ws.rs.api"/>
+ <module name="org.apache.cxf"/>
+ <module name="org.apache.cxf.impl"/>
+ <module name="org.hibernate"/>
+ <module name="org.slf4j"/>
+ <module name="org.slf4j.impl"/>
+ </exclusions>
+ </deployment>
+</jboss-deployment-structure>
http://git-wip-us.apache.org/repos/asf/syncope/blob/d30c8526/syncope620/fit/core-reference/src/main/webapp/WEB-INF/weblogic.xml
----------------------------------------------------------------------
diff --git a/syncope620/fit/core-reference/src/main/webapp/WEB-INF/weblogic.xml b/syncope620/fit/core-reference/src/main/webapp/WEB-INF/weblogic.xml
new file mode 100644
index 0000000..6eeb9c2
--- /dev/null
+++ b/syncope620/fit/core-reference/src/main/webapp/WEB-INF/weblogic.xml
@@ -0,0 +1,46 @@
+<?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.
+-->
+<weblogic-web-app xmlns="http://xmlns.oracle.com/weblogic/weblogic-web-app"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://xmlns.oracle.com/weblogic/weblogic-web-app
+ http://xmlns.oracle.com/weblogic/weblogic-web-app/1.4/weblogic-web-app.xsd">
+
+ <context-root>syncope</context-root>
+
+ <container-descriptor>
+ <prefer-application-packages>
+ <package-name>javax.ws.rs.*</package-name>
+ <package-name>javax.validation.*</package-name>
+ <package-name>org.hibernate.validator.*</package-name>
+ <package-name>org.apache.cxf.*</package-name>
+ <package-name>org.apache.commons.*</package-name>
+ <package-name>org.apache.openjpa.*</package-name>
+ <package-name>org.slf4j.*</package-name>
+ <package-name>org.apache.logging.log4j.*</package-name>
+ <package-name>com.fasterxml.jackson.*</package-name>
+ </prefer-application-packages>
+ </container-descriptor>
+
+ <!-- Uncomment this when using JNDI DataSource -->
+ <!--<resource-description>
+ <jndi-name>syncopeDataSource</jndi-name>
+ <res-ref-name>jdbc/syncopeDataSource</res-ref-name>
+ </resource-description>-->
+</weblogic-web-app>
http://git-wip-us.apache.org/repos/asf/syncope/blob/d30c8526/syncope620/fit/core-reference/src/main/webapp/cacheStats.jsp
----------------------------------------------------------------------
diff --git a/syncope620/fit/core-reference/src/main/webapp/cacheStats.jsp b/syncope620/fit/core-reference/src/main/webapp/cacheStats.jsp
new file mode 100644
index 0000000..4e4bf1b
--- /dev/null
+++ b/syncope620/fit/core-reference/src/main/webapp/cacheStats.jsp
@@ -0,0 +1,190 @@
+<%--
+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.
+--%>
+<%@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"%>
+<%@taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
+<%@taglib uri="http://java.sun.com/jsp/jstl/functions" prefix="fn"%>
+<%@page import="java.text.SimpleDateFormat"%>
+<%@page import="java.util.Date"%>
+<%@page import="org.apache.openjpa.datacache.CacheStatisticsImpl"%>
+<%@page import="javax.persistence.EntityManagerFactory"%>
+<%@page import="org.apache.openjpa.persistence.OpenJPAPersistence"%>
+<%@page import="org.apache.openjpa.persistence.OpenJPAEntityManagerFactory"%>
+<%@page import="org.springframework.context.ConfigurableApplicationContext"%>
+<%@page import="org.apache.openjpa.datacache.QueryKey"%>
+<%@page import="org.apache.openjpa.kernel.QueryStatistics"%>
+<%@page import="org.apache.openjpa.persistence.QueryResultCacheImpl"%>
+<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<html>
+ <head>
+ <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+ <title>Cache Statistics</title>
+ <style type="text/css">
+ .c{
+ text-align: center;
+ }
+ .r{
+ text-align: right;
+ }
+ .l{
+ text-align: left;
+ }
+ .t{
+ vertical-align: top;
+ }
+ .b{
+ vertical-align: bottom;
+ }
+ .odd{
+ background-color: #D4D4D4;
+ }
+ .even{
+ background-color: #EEEEEE;
+ }
+ .bd1{
+ border: solid #888888 1px;
+ }
+ .bg1{
+ background-color: #CCCCCC;
+ }
+ .bg2{
+ background-color: #DDDDDD;
+ }
+ </style>
+ </head>
+ <body>
+ <p/>
+ <%
+ ConfigurableApplicationContext context = ApplicationContextProvider.getApplicationContext();
+
+ EntityManagerFactory emf = context.getBean(EntityManagerFactory.class);
+ OpenJPAEntityManagerFactory oemf = OpenJPAPersistence.cast(emf);
+
+ QueryStatistics<QueryKey> queryStatistics =
+ ((QueryResultCacheImpl) oemf.getQueryResultCache()).getDelegate().getStatistics();
+
+ CacheStatisticsImpl statistics = (CacheStatisticsImpl) oemf.getStoreCache().getStatistics();
+
+ String action = request.getParameter("do");
+ StringBuilder info = new StringBuilder(512);
+
+ if ("activate".equals(action) && !statistics.isEnabled()) {
+ statistics.enable();
+ info.append("Statistics enabled\n");
+ } else if ("deactivate".equals(action) && !statistics.isEnabled()) {
+ statistics.disable();
+ info.append("Statistics disabled\n");
+ } else if ("clear".equals(action)) {
+ queryStatistics.reset();
+ statistics.reset();
+ info.append("Statistics cleared\n");
+ }
+
+ SimpleDateFormat sdf = new SimpleDateFormat(SyncopeConstants.DEFAULT_DATE_PATTERN);
+ if (info.length() > 0) {
+ %>
+ <p/><div class="success">
+ <c:out value="${fn:escapeXml(info)}"/>
+ </div>
+ <% }%>
+ <p/>
+ <a href="?">Reload</a>
+ <p/>
+ <a href="?do=<%=(statistics.isEnabled() ? "deactivate" : "activate")%>">
+ <%=(statistics.isEnabled() ? "DEACTIVATE" : "ACTIVATE")%></a>
+ <a href="?do=clear">CLEAR</a>
+ <p/>
+ Last update: <%=sdf.format(statistics.since())%><br/>
+ Activation: <%=sdf.format(statistics.start())%><br/>
+ <p/>
+ <table>
+ <tr>
+ <th class="c bd1 bg1">Hits</th>
+ <td><%=statistics.getHitCount()%></td>
+ </tr>
+ <tr>
+ <th class="c bd1 bg1">Reads</th>
+ <td><%=statistics.getReadCount()%></td>
+ </tr>
+ <tr>
+ <th class="c bd1 bg1">Writes</th>
+ <td><%=statistics.getWriteCount()%></td>
+ </tr>
+ <tr>
+ <th class="c bd1 bg1">Query Hits</th>
+ <td><%=queryStatistics.getHitCount()%></td>
+ </tr>
+ <tr>
+ <th class="c bd1 bg1">Query Executions</th>
+ <td><%=queryStatistics.getExecutionCount()%></td>
+ </tr>
+ <tr>
+ <th class="c bd1 bg1">Query Evictions</th>
+ <td><%=queryStatistics.getEvictionCount()%></td>
+ </tr>
+ </table>
+ <p/>
+ <table width="100%">
+ <tr><th colspan="3" class="c bd1 bg2">Query statistics</th></tr>
+ <tr>
+ <th class="c bd1 bg1">Query</th>
+ <th class="c bd1 bg1">Hits</th>
+ <th class="c bd1 bg1">Executions</th>
+ </tr>
+ <%
+ boolean odd = true;
+ for (QueryKey key : queryStatistics.keys()) {
+ %>
+ <tr class="<%=(odd ? "odd" : "even")%>">
+ <td><%=key%></td>
+ <td><%=queryStatistics.getHitCount(key)%></td>
+ <td><%=queryStatistics.getExecutionCount(key)%></td>
+ </tr>
+ <%
+ odd = !odd;
+ }
+ %>
+ </table>
+ <p/>
+ <table width="100%">
+ <tr><th colspan="4" class="c bd1 bg2">2nd level cache statistics</th></tr>
+ <tr>
+ <th class="c bd1 bg1">Region</th>
+ <th class="c bd1 bg1">Hits</th>
+ <th class="c bd1 bg1">Reads</th>
+ <th class="c bd1 bg1">Writes</th>
+ </tr>
+ <%
+ odd = true;
+ for (String className : statistics.classNames()) {
+ %>
+ <tr class="<%=(odd ? "odd" : "even")%>">
+ <td><%=className%></td>
+ <td><%=statistics.getHitCount(className)%></td>
+ <td><%=statistics.getReadCount(className)%></td>
+ <td><%=statistics.getWriteCount(className)%></td>
+ </tr>
+ <%
+ odd = !odd;
+ }
+ %>
+ </table>
+ </body>
+</html>
http://git-wip-us.apache.org/repos/asf/syncope/blob/d30c8526/syncope620/fit/core-reference/src/main/webapp/db.jsp
----------------------------------------------------------------------
diff --git a/syncope620/fit/core-reference/src/main/webapp/db.jsp b/syncope620/fit/core-reference/src/main/webapp/db.jsp
new file mode 100644
index 0000000..2a4c6ac
--- /dev/null
+++ b/syncope620/fit/core-reference/src/main/webapp/db.jsp
@@ -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.
+--%>
+<%@page import="java.sql.SQLException"%>
+<%@page import="org.h2.tools.Server"%>
+<%@page contentType="text/html" pageEncoding="UTF-8"%>
+<%
+ Server h2Datastore = (Server) getServletConfig().getServletContext().getAttribute("H2_DATASTORE");
+ if (h2Datastore == null || !h2Datastore.isRunning(true)) {
+ try {
+ h2Datastore = Server.createWebServer("-webPort", "8082");
+ h2Datastore.start();
+
+ getServletConfig().getServletContext().setAttribute("H2_DATASTORE", h2Datastore);
+ } catch (SQLException e) {
+ getServletConfig().getServletContext().log("Could not start H2 web console (datastore)", e);
+ }
+
+ response.sendRedirect("http://localhost:8082");
+ }
+%>
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/syncope/blob/d30c8526/syncope620/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/AbstractITCase.java
----------------------------------------------------------------------
diff --git a/syncope620/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/AbstractITCase.java b/syncope620/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/AbstractITCase.java
new file mode 100644
index 0000000..0f0560a
--- /dev/null
+++ b/syncope620/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/AbstractITCase.java
@@ -0,0 +1,388 @@
+/*
+ * 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.assertNotNull;
+
+import java.io.InputStream;
+import java.net.URI;
+import java.util.Hashtable;
+import java.util.Map;
+import java.util.Properties;
+import java.util.UUID;
+import javax.naming.Context;
+import javax.naming.NamingException;
+import javax.naming.directory.InitialDirContext;
+import javax.sql.DataSource;
+import javax.ws.rs.core.Response;
+import org.apache.commons.io.IOUtils;
+import org.apache.commons.lang3.StringUtils;
+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.mod.AttrMod;
+import org.apache.syncope.common.lib.mod.RoleMod;
+import org.apache.syncope.common.lib.mod.UserMod;
+import org.apache.syncope.common.lib.to.AbstractPolicyTO;
+import org.apache.syncope.common.lib.to.AbstractSchemaTO;
+import org.apache.syncope.common.lib.to.AttrTO;
+import org.apache.syncope.common.lib.to.ResourceTO;
+import org.apache.syncope.common.lib.to.RoleTO;
+import org.apache.syncope.common.lib.to.UserTO;
+import org.apache.syncope.common.lib.types.AttributableType;
+import org.apache.syncope.common.lib.types.ConnConfProperty;
+import org.apache.syncope.common.lib.types.SchemaType;
+import org.apache.syncope.common.rest.api.RESTHeaders;
+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.EntitlementService;
+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;
+import org.apache.syncope.common.rest.api.service.ReportService;
+import org.apache.syncope.common.rest.api.service.ResourceService;
+import org.apache.syncope.common.rest.api.service.RoleService;
+import org.apache.syncope.common.rest.api.service.SchemaService;
+import org.apache.syncope.common.rest.api.service.SecurityQuestionService;
+import org.apache.syncope.common.rest.api.service.SyncopeService;
+import org.apache.syncope.common.rest.api.service.TaskService;
+import org.apache.syncope.common.rest.api.service.UserSelfService;
+import org.apache.syncope.common.rest.api.service.UserService;
+import org.apache.syncope.common.rest.api.service.UserWorkflowService;
+import org.apache.syncope.common.rest.api.service.WorkflowService;
+import org.identityconnectors.common.security.Encryptor;
+import org.junit.BeforeClass;
+import org.junit.runner.RunWith;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.test.context.ContextConfiguration;
+import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
+
+@RunWith(SpringJUnit4ClassRunner.class)
+@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";
+
+ private static final String ENV_KEY_CONTENT_TYPE = "jaxrsContentType";
+
+ protected static final SyncopeClientFactoryBean clientFactory = new SyncopeClientFactoryBean().setAddress(ADDRESS);
+
+ protected static final String RESOURCE_NAME_WS1 = "ws-target-resource-1";
+
+ protected static final String RESOURCE_NAME_WS2 = "ws-target-resource-2";
+
+ protected static final String RESOURCE_NAME_LDAP = "resource-ldap";
+
+ protected static final String RESOURCE_NAME_TESTDB = "resource-testdb";
+
+ protected static final String RESOURCE_NAME_TESTDB2 = "resource-testdb2";
+
+ protected static final String RESOURCE_NAME_CSV = "resource-csv";
+
+ protected static final String RESOURCE_NAME_DBSYNC = "resource-db-sync";
+
+ protected static final String RESOURCE_NAME_DBVIRATTR = "resource-db-virattr";
+
+ protected static final String RESOURCE_NAME_NOPROPAGATION = "ws-target-resource-nopropagation";
+
+ protected static final String RESOURCE_NAME_NOPROPAGATION2 = "ws-target-resource-nopropagation2";
+
+ protected static final String RESOURCE_NAME_NOPROPAGATION3 = "ws-target-resource-nopropagation3";
+
+ protected static final String RESOURCE_NAME_NOPROPAGATION4 = "ws-target-resource-nopropagation4";
+
+ protected static final String RESOURCE_NAME_RESETSYNCTOKEN = "ws-target-resource-update-resetsynctoken";
+
+ protected static final String RESOURCE_NAME_TIMEOUT = "ws-target-resource-timeout";
+
+ protected static final String RESOURCE_NAME_MAPPINGS1 = "ws-target-resource-list-mappings-1";
+
+ protected static final String RESOURCE_NAME_MAPPINGS2 = "ws-target-resource-list-mappings-2";
+
+ protected static final String RESOURCE_NAME_CREATE = "ws-target-resource-create";
+
+ protected static final String RESOURCE_NAME_CREATE_SINGLE = "ws-target-resource-create-single";
+
+ protected static final String RESOURCE_NAME_CREATE_WRONG = "ws-target-resource-create-wrong";
+
+ protected static final String RESOURCE_NAME_DELETE = "ws-target-resource-delete";
+
+ protected static final String RESOURCE_NAME_UPDATE = "ws-target-resource-update";
+
+ protected static final String RESOURCE_NAME_CREATE_NONE = "ws-target-resource-create-none";
+
+ protected static String ANONYMOUS_UNAME;
+
+ protected static String ANONYMOUS_KEY;
+
+ protected static SyncopeClient adminClient;
+
+ protected static SyncopeService syncopeService;
+
+ protected static UserService userService;
+
+ protected static UserSelfService userSelfService;
+
+ protected static UserWorkflowService userWorkflowService;
+
+ protected static RoleService roleService;
+
+ protected static ResourceService resourceService;
+
+ protected static EntitlementService entitlementService;
+
+ protected static ConfigurationService configurationService;
+
+ protected static ConnectorService connectorService;
+
+ protected static LoggerService loggerService;
+
+ protected static ReportService reportService;
+
+ protected static TaskService taskService;
+
+ protected static WorkflowService workflowService;
+
+ protected static NotificationService notificationService;
+
+ protected static SchemaService schemaService;
+
+ protected static PolicyService policyService;
+
+ protected static SecurityQuestionService securityQuestionService;
+
+ protected static CamelRouteService camelRouteService;
+
+ @Autowired
+ protected DataSource testDataSource;
+
+ @BeforeClass
+ public static void securitySetup() {
+ InputStream propStream = null;
+ try {
+ propStream = Encryptor.class.getResourceAsStream("/security.properties");
+ Properties props = new Properties();
+ props.load(propStream);
+
+ ANONYMOUS_UNAME = props.getProperty("anonymousUser");
+ ANONYMOUS_KEY = props.getProperty("anonymousKey");
+ } catch (Exception e) {
+ LOG.error("Could not read secretKey", e);
+ } finally {
+ IOUtils.closeQuietly(propStream);
+ }
+
+ assertNotNull(ANONYMOUS_UNAME);
+ assertNotNull(ANONYMOUS_KEY);
+ }
+
+ @BeforeClass
+ public static void restSetup() {
+ final 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, ADMIN_PWD);
+
+ syncopeService = adminClient.getService(SyncopeService.class);
+ userService = adminClient.getService(UserService.class);
+ userSelfService = adminClient.getService(UserSelfService.class);
+ userWorkflowService = adminClient.getService(UserWorkflowService.class);
+ roleService = adminClient.getService(RoleService.class);
+ resourceService = adminClient.getService(ResourceService.class);
+ entitlementService = adminClient.getService(EntitlementService.class);
+ configurationService = adminClient.getService(ConfigurationService.class);
+ connectorService = adminClient.getService(ConnectorService.class);
+ loggerService = adminClient.getService(LoggerService.class);
+ reportService = adminClient.getService(ReportService.class);
+ taskService = adminClient.getService(TaskService.class);
+ policyService = adminClient.getService(PolicyService.class);
+ workflowService = adminClient.getService(WorkflowService.class);
+ notificationService = adminClient.getService(NotificationService.class);
+ schemaService = adminClient.getService(SchemaService.class);
+ securityQuestionService = adminClient.getService(SecurityQuestionService.class);
+ camelRouteService = adminClient.getService(CamelRouteService.class);
+ }
+
+ protected static String getUUIDString() {
+ return UUID.randomUUID().toString().substring(0, 8);
+ }
+
+ protected static AttrTO attrTO(final String schema, final String value) {
+ AttrTO attr = new AttrTO();
+ attr.setSchema(schema);
+ attr.getValues().add(value);
+ return attr;
+ }
+
+ protected static AttrMod attrMod(final String schema, final String valueToBeAdded) {
+ AttrMod attr = new AttrMod();
+ attr.setSchema(schema);
+ attr.getValuesToBeAdded().add(valueToBeAdded);
+ return attr;
+ }
+
+ protected UserTO createUser(final UserTO userTO) {
+ return createUser(userTO, true);
+ }
+
+ protected UserTO createUser(final UserTO userTO, final boolean storePassword) {
+ Response response = userService.create(userTO, storePassword);
+ if (response.getStatusInfo().getStatusCode() != Response.Status.CREATED.getStatusCode()) {
+ Exception ex = clientFactory.getExceptionMapper().fromResponse(response);
+ if (ex != null) {
+ throw (RuntimeException) ex;
+ }
+ }
+ return response.readEntity(UserTO.class);
+ }
+
+ protected UserTO readUser(final String username) {
+ return userService.read(Long.valueOf(
+ userService.getUserId(username).getHeaderString(RESTHeaders.USER_ID)));
+ }
+
+ protected UserTO updateUser(final UserMod userMod) {
+ return userService.update(userMod.getKey(), userMod).readEntity(UserTO.class);
+ }
+
+ protected UserTO deleteUser(final Long id) {
+ return userService.delete(id).readEntity(UserTO.class);
+ }
+
+ public <T> T getObject(final URI location, final Class<?> serviceClass, final Class<T> resultClass) {
+ WebClient webClient = WebClient.fromClient(WebClient.client(adminClient.getService(serviceClass)));
+ webClient.accept(clientFactory.getContentType().getMediaType()).to(location.toASCIIString(), false);
+
+ return webClient.get(resultClass);
+ }
+
+ @SuppressWarnings("unchecked")
+ protected <T extends AbstractSchemaTO> T createSchema(final AttributableType kind,
+ final SchemaType type, final T schemaTO) {
+
+ Response response = schemaService.create(kind, type, schemaTO);
+ if (response.getStatusInfo().getStatusCode() != Response.Status.CREATED.getStatusCode()) {
+ Exception ex = clientFactory.getExceptionMapper().fromResponse(response);
+ if (ex != null) {
+ throw (RuntimeException) ex;
+ }
+ }
+
+ return (T) getObject(response.getLocation(), SchemaService.class, schemaTO.getClass());
+ }
+
+ protected RoleTO createRole(final RoleTO newRoleTO) {
+ Response response = roleService.create(newRoleTO);
+ if (response.getStatusInfo().getStatusCode() != Response.Status.CREATED.getStatusCode()) {
+ Exception ex = clientFactory.getExceptionMapper().fromResponse(response);
+ if (ex != null) {
+ throw (RuntimeException) ex;
+ }
+ }
+ return getObject(response.getLocation(), RoleService.class, RoleTO.class);
+ }
+
+ protected RoleTO updateRole(final RoleMod roleMod) {
+ return roleService.update(roleMod.getKey(), roleMod).readEntity(RoleTO.class);
+ }
+
+ protected RoleTO deleteRole(final Long id) {
+ return roleService.delete(id).readEntity(RoleTO.class);
+ }
+
+ @SuppressWarnings("unchecked")
+ protected <T extends AbstractPolicyTO> T createPolicy(final T policy) {
+ Response response = policyService.create(policy);
+ if (response.getStatusInfo().getStatusCode() != Response.Status.CREATED.getStatusCode()) {
+ Exception ex = clientFactory.getExceptionMapper().fromResponse(response);
+ if (ex != null) {
+ throw (RuntimeException) ex;
+ }
+ }
+ return (T) getObject(response.getLocation(), PolicyService.class, policy.getClass());
+ }
+
+ protected ResourceTO createResource(final ResourceTO resourceTO) {
+ Response response = resourceService.create(resourceTO);
+ if (response.getStatusInfo().getStatusCode() != Response.Status.CREATED.getStatusCode()) {
+ Exception ex = clientFactory.getExceptionMapper().fromResponse(response);
+ if (ex != null) {
+ throw (RuntimeException) ex;
+ }
+ }
+ return getObject(response.getLocation(), ResourceService.class, ResourceTO.class);
+ }
+
+ @SuppressWarnings({ "unchecked", "rawtypes", "UseOfObsoleteCollectionType" })
+ protected InitialDirContext getLdapResourceDirContext(final String bindDn, final String bindPwd)
+ throws NamingException {
+ ResourceTO ldapRes = resourceService.read(RESOURCE_NAME_LDAP);
+ final Map<String, ConnConfProperty> ldapConnConf =
+ connectorService.read(ldapRes.getConnectorId()).getConfigurationMap();
+
+ Hashtable env = new Hashtable();
+ env.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.ldap.LdapCtxFactory");
+ env.put(Context.PROVIDER_URL, "ldap://" + ldapConnConf.get("host").getValues().get(0)
+ + ":" + ldapConnConf.get("port").getValues().get(0) + "/");
+ env.put(Context.SECURITY_AUTHENTICATION, "simple");
+ env.put(Context.SECURITY_PRINCIPAL,
+ bindDn == null ? ldapConnConf.get("principal").getValues().get(0) : bindDn);
+ env.put(Context.SECURITY_CREDENTIALS,
+ bindPwd == null ? ldapConnConf.get("credentials").getValues().get(0) : bindPwd);
+
+ return new InitialDirContext(env);
+ }
+
+ protected Object getLdapRemoteObject(final String bindDn, final String bindPwd, final String objectDn) {
+ InitialDirContext ctx = null;
+ try {
+ ctx = getLdapResourceDirContext(bindDn, bindPwd);
+ return ctx.lookup(objectDn);
+ } catch (Exception e) {
+ return null;
+ } finally {
+ if (ctx != null) {
+ try {
+ ctx.close();
+ } catch (NamingException e) {
+ // ignore
+ }
+ }
+ }
+ }
+
+ protected Object getLdapRemoteObject(final String objectDn) {
+ return getLdapRemoteObject(null, null, objectDn);
+ }
+}
http://git-wip-us.apache.org/repos/asf/syncope/blob/d30c8526/syncope620/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/AbstractTaskITCase.java
----------------------------------------------------------------------
diff --git a/syncope620/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/AbstractTaskITCase.java b/syncope620/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/AbstractTaskITCase.java
new file mode 100644
index 0000000..6ba1dd8
--- /dev/null
+++ b/syncope620/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/AbstractTaskITCase.java
@@ -0,0 +1,137 @@
+/*
+ * 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.fail;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.concurrent.Callable;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+import java.util.concurrent.Future;
+import java.util.concurrent.TimeUnit;
+import org.apache.syncope.common.lib.to.AbstractTaskTO;
+import org.apache.syncope.common.lib.to.TaskExecTO;
+import org.apache.syncope.common.lib.to.UserTO;
+
+public abstract class AbstractTaskITCase extends AbstractITCase {
+
+ protected static final Long SYNC_TASK_ID = 4L;
+
+ protected static final Long SCHED_TASK_ID = 5L;
+
+ protected static class ThreadExec implements Callable<TaskExecTO> {
+
+ private final AbstractTaskITCase test;
+
+ private final Long taskKey;
+
+ private final int maxWaitSeconds;
+
+ private final boolean dryRun;
+
+ public ThreadExec(AbstractTaskITCase test, Long taskKey, int maxWaitSeconds, boolean dryRun) {
+ this.test = test;
+ this.taskKey = taskKey;
+ this.maxWaitSeconds = maxWaitSeconds;
+ this.dryRun = dryRun;
+ }
+
+ @Override
+ public TaskExecTO call() throws Exception {
+ return test.execSyncTask(taskKey, maxWaitSeconds, dryRun);
+ }
+ }
+
+ /**
+ * Remove initial and synchronized users to make test re-runnable.
+ */
+ protected void removeTestUsers() {
+ for (int i = 0; i < 10; i++) {
+ String cUserName = "test" + i;
+ try {
+ UserTO cUserTO = readUser(cUserName);
+ userService.delete(cUserTO.getKey());
+ } catch (Exception e) {
+ // Ignore
+ }
+ }
+ }
+
+ protected TaskExecTO execSyncTask(final Long taskKey, final int maxWaitSeconds, final boolean dryRun) {
+ AbstractTaskTO taskTO = taskService.read(taskKey);
+ assertNotNull(taskTO);
+ assertNotNull(taskTO.getExecutions());
+
+ int preSyncSize = taskTO.getExecutions().size();
+ TaskExecTO execution = taskService.execute(taskTO.getKey(), dryRun);
+ assertEquals("JOB_FIRED", execution.getStatus());
+
+ int i = 0;
+ int maxit = maxWaitSeconds;
+
+ // wait for sync completion (executions incremented)
+ do {
+ try {
+ Thread.sleep(1000);
+ } catch (InterruptedException e) {
+ }
+
+ taskTO = taskService.read(taskTO.getKey());
+
+ assertNotNull(taskTO);
+ assertNotNull(taskTO.getExecutions());
+
+ i++;
+ } while (preSyncSize == taskTO.getExecutions().size() && i < maxit);
+ if (i == maxit) {
+ fail("Timeout when executing task " + taskKey);
+ }
+ return taskTO.getExecutions().get(taskTO.getExecutions().size() - 1);
+ }
+
+ protected Map<Long, TaskExecTO> execSyncTasks(
+ final Set<Long> taskKeys, final int maxWaitSeconds, final boolean dryRun) throws Exception {
+
+ final ExecutorService service = Executors.newFixedThreadPool(taskKeys.size());
+ final List<Future<TaskExecTO>> futures = new ArrayList<>();
+
+ for (Long key : taskKeys) {
+ futures.add(service.submit(new ThreadExec(this, key, maxWaitSeconds, dryRun)));
+ }
+
+ final Map<Long, TaskExecTO> res = new HashMap<>();
+
+ for (Future<TaskExecTO> future : futures) {
+ TaskExecTO taskExecTO = future.get(100, TimeUnit.SECONDS);
+ res.put(taskExecTO.getTask(), taskExecTO);
+ }
+
+ service.shutdownNow();
+
+ return res;
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/syncope/blob/d30c8526/syncope620/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/ActivitiDetector.java
----------------------------------------------------------------------
diff --git a/syncope620/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/ActivitiDetector.java b/syncope620/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/ActivitiDetector.java
new file mode 100644
index 0000000..f697c19
--- /dev/null
+++ b/syncope620/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/ActivitiDetector.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.fit.core.reference;
+
+import org.apache.syncope.common.rest.api.service.SyncopeService;
+
+public class ActivitiDetector {
+
+ public static boolean isActivitiEnabledForUsers(final SyncopeService syncopeService) {
+ return syncopeService.info().getUserWorkflowAdapter().indexOf("Activiti") != -1;
+ }
+
+ public static boolean isActivitiEnabledForRoles(final SyncopeService syncopeService) {
+ return syncopeService.info().getRoleWorkflowAdapter().indexOf("Activiti") != -1;
+ }
+}