http://git-wip-us.apache.org/repos/asf/syncope/blob/d30c8526/syncope620/core/workflow-activiti/src/main/resources/userWorkflow.bpmn20.xml ---------------------------------------------------------------------- diff --git a/syncope620/core/workflow-activiti/src/main/resources/userWorkflow.bpmn20.xml b/syncope620/core/workflow-activiti/src/main/resources/userWorkflow.bpmn20.xml new file mode 100644 index 0000000..510ce9f --- /dev/null +++ b/syncope620/core/workflow-activiti/src/main/resources/userWorkflow.bpmn20.xml @@ -0,0 +1,232 @@ +<?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="activate"/> + <scriptTask id="activate" name="Activate" scriptFormat="groovy" activiti:autoStoreVariables="false"> + <script>execution.setVariable("propagateEnable", Boolean.TRUE);</script> + </scriptTask> + <sequenceFlow id="flow3" sourceRef="activate" targetRef="active"/> + <userTask id="active" name="Active"/> + <sequenceFlow id="flow8" sourceRef="active" targetRef="activeGw"/> + <exclusiveGateway id="activeGw"/> + <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> + <serviceTask id="update" name="Update" activiti:expression="#{update.execute(execution.processInstanceId)}"/> + <sequenceFlow id="sid-EA22026A-25F0-4ED0-AB6E-9CE9CE74623C" 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"/> + + <serviceTask id="generateToken4PasswordReset" name="Generate Token" activiti:expression="#{generateToken.execute(execution.processInstanceId)}"/> + <sequenceFlow id="sid-7F78CE07-A7A1-467F-BB4B-40FB234AEFF7" sourceRef="generateToken4PasswordReset" targetRef="notify4RequestPasswordReset"/> + <serviceTask id="notify4RequestPasswordReset" name="Notification" activiti:expression="#{notify.execute(execution.processInstanceId)}"/> + <sequenceFlow id="sid-CF9ACA40-7750-47C3-A508-7250D24D4F1F" sourceRef="notify4RequestPasswordReset" targetRef="active"/> + + <serviceTask id="checkToken4ConfirmPasswordReset" name="Check token, remove and update password" activiti:expression="#{passwordReset.execute(execution.processInstanceId)}"/> + <sequenceFlow id="sid-3E9FE01D-CC60-4A95-B356-CA0DC000FAD6" sourceRef="checkToken4ConfirmPasswordReset" targetRef="notify4ConfirmPasswordReset"/> + <serviceTask id="notify4ConfirmPasswordReset" name="Notification" activiti:expression="#{notify.execute(execution.processInstanceId)}"/> + <sequenceFlow id="sid-A37806A7-6B7B-48A2-BB37-DAE640231144" 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="540.0" y="525.0"/> + </bpmndi:BPMNShape> + <bpmndi:BPMNShape bpmnElement="create" id="BPMNShape_create"> + <omgdc:Bounds height="60.00000000000006" width="100.0" x="620.0" y="509.99999999999994"/> + </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="update" id="BPMNShape_update"> + <omgdc:Bounds height="60.0" width="100.0" x="1370.0" y="615.0"/> + </bpmndi:BPMNShape> + <bpmndi:BPMNShape bpmnElement="suspend" id="BPMNShape_suspend"> + <omgdc:Bounds height="60.0" width="100.0" x="1490.0" y="370.0"/> + </bpmndi:BPMNShape> + <bpmndi:BPMNShape bpmnElement="suspended" id="BPMNShape_suspended"> + <omgdc:Bounds height="60.0" width="100.0" x="1640.0" y="370.0"/> + </bpmndi:BPMNShape> + <bpmndi:BPMNShape bpmnElement="suspendedGw" id="BPMNShape_suspendedGw"> + <omgdc:Bounds height="40.0" width="40.0" x="1820.0" y="380.0"/> + </bpmndi:BPMNShape> + <bpmndi:BPMNShape bpmnElement="reactivate" id="BPMNShape_reactivate"> + <omgdc:Bounds height="60.0" width="100.0" x="1940.0" y="290.0"/> + </bpmndi:BPMNShape> + <bpmndi:BPMNShape bpmnElement="generateToken4PasswordReset" id="BPMNShape_generateToken4PasswordReset"> + <omgdc:Bounds height="81.0" width="121.0" x="1515.0" y="604.5"/> + </bpmndi:BPMNShape> + <bpmndi:BPMNShape bpmnElement="notify4RequestPasswordReset" id="BPMNShape_notify4RequestPasswordReset"> + <omgdc:Bounds height="81.0" width="121.0" x="1515.0" y="750.0"/> + </bpmndi:BPMNShape> + <bpmndi:BPMNShape bpmnElement="checkToken4ConfirmPasswordReset" id="BPMNShape_checkToken4ConfirmPasswordReset"> + <omgdc:Bounds height="81.0" width="121.0" x="1725.0" y="664.5"/> + </bpmndi:BPMNShape> + <bpmndi:BPMNShape bpmnElement="notify4ConfirmPasswordReset" id="BPMNShape_notify4ConfirmPasswordReset"> + <omgdc:Bounds height="81.0" width="121.0" x="1725.0" y="810.0"/> + </bpmndi:BPMNShape> + <bpmndi:BPMNShape bpmnElement="delete" id="BPMNShape_delete"> + <omgdc:Bounds height="60.0" width="100.0" x="1940.0" y="438.0"/> + </bpmndi:BPMNShape> + <bpmndi:BPMNShape bpmnElement="theEnd" id="BPMNShape_theEnd"> + <omgdc:Bounds height="28.0" width="28.0" x="2080.0" y="451.0"/> + </bpmndi:BPMNShape> + <bpmndi:BPMNShape bpmnElement="activate" id="BPMNShape_activate"> + <omgdc:Bounds height="80.0" width="100.0" x="828.286878319943" y="500.0"/> + </bpmndi:BPMNShape> + <bpmndi:BPMNEdge bpmnElement="flow12" id="BPMNEdge_flow12"> + <omgdi:waypoint x="1990.0" y="290.0"/> + <omgdi:waypoint x="1990.0" y="261.0"/> + <omgdi:waypoint x="1080.0" y="261.0"/> + <omgdi:waypoint x="1080.0" y="511.0"/> + </bpmndi:BPMNEdge> + <bpmndi:BPMNEdge bpmnElement="flow11" id="BPMNEdge_flow11"> + <omgdi:waypoint x="1740.0" y="400.0"/> + <omgdi:waypoint x="1820.0" y="400.0"/> + </bpmndi:BPMNEdge> + <bpmndi:BPMNEdge bpmnElement="flow10" id="BPMNEdge_flow10"> + <omgdi:waypoint x="1590.0" y="400.0"/> + <omgdi:waypoint x="1640.0" y="400.0"/> + </bpmndi:BPMNEdge> + <bpmndi:BPMNEdge bpmnElement="active2Suspend" id="BPMNEdge_active2Suspend"> + <omgdi:waypoint x="1440.0" y="540.0"/> + <omgdi:waypoint x="1540.0" y="540.0"/> + <omgdi:waypoint x="1540.0" y="430.0"/> + </bpmndi:BPMNEdge> + <bpmndi:BPMNEdge bpmnElement="sid-A37806A7-6B7B-48A2-BB37-DAE640231144" id="BPMNEdge_sid-A37806A7-6B7B-48A2-BB37-DAE640231144"> + <omgdi:waypoint x="1725.0" y="850.4571226080794"/> + <omgdi:waypoint x="1080.0" y="850.0"/> + <omgdi:waypoint x="1080.0" y="571.0"/> + </bpmndi:BPMNEdge> + <bpmndi:BPMNEdge bpmnElement="suspended2Delete" id="BPMNEdge_suspended2Delete"> + <omgdi:waypoint x="1860.0" y="400.0"/> + <omgdi:waypoint x="1990.0" y="400.0"/> + <omgdi:waypoint x="1990.0" y="438.0"/> + </bpmndi:BPMNEdge> + <bpmndi:BPMNEdge bpmnElement="active2RequestPasswordReset" id="BPMNEdge_active2RequestPasswordReset"> + <omgdi:waypoint x="1440.0" y="540.0"/> + <omgdi:waypoint x="1575.0" y="540.0"/> + <omgdi:waypoint x="1575.307142857143" y="604.5"/> + </bpmndi:BPMNEdge> + <bpmndi:BPMNEdge bpmnElement="active2Delete" id="BPMNEdge_active2Delete"> + <omgdi:waypoint x="1440.0" y="540.0"/> + <omgdi:waypoint x="1990.0" y="540.0"/> + <omgdi:waypoint x="1990.0" y="498.0"/> + </bpmndi:BPMNEdge> + <bpmndi:BPMNEdge bpmnElement="flow2" id="BPMNEdge_flow2"> + <omgdi:waypoint x="720.0" y="540.0"/> + <omgdi:waypoint x="828.286878319943" y="540.0"/> + </bpmndi:BPMNEdge> + <bpmndi:BPMNEdge bpmnElement="sid-3E9FE01D-CC60-4A95-B356-CA0DC000FAD6" id="BPMNEdge_sid-3E9FE01D-CC60-4A95-B356-CA0DC000FAD6"> + <omgdi:waypoint x="1785.5" y="745.5"/> + <omgdi:waypoint x="1785.5" y="810.0"/> + </bpmndi:BPMNEdge> + <bpmndi:BPMNEdge bpmnElement="sid-7F78CE07-A7A1-467F-BB4B-40FB234AEFF7" id="BPMNEdge_sid-7F78CE07-A7A1-467F-BB4B-40FB234AEFF7"> + <omgdi:waypoint x="1575.5" y="685.5"/> + <omgdi:waypoint x="1575.5" y="750.0"/> + </bpmndi:BPMNEdge> + <bpmndi:BPMNEdge bpmnElement="sid-EA22026A-25F0-4ED0-AB6E-9CE9CE74623C" id="BPMNEdge_sid-EA22026A-25F0-4ED0-AB6E-9CE9CE74623C"> + <omgdi:waypoint x="1370.0" y="645.0"/> + <omgdi:waypoint x="1080.0" y="645.0"/> + <omgdi:waypoint x="1080.0" y="571.0"/> + </bpmndi:BPMNEdge> + <bpmndi:BPMNEdge bpmnElement="flow1" id="BPMNEdge_flow1"> + <omgdi:waypoint x="570.0" y="540.0"/> + <omgdi:waypoint x="620.0" y="540.0"/> + </bpmndi:BPMNEdge> + <bpmndi:BPMNEdge bpmnElement="active2ConfirmPasswordReset" id="BPMNEdge_active2ConfirmPasswordReset"> + <omgdi:waypoint x="1440.0" y="540.0"/> + <omgdi:waypoint x="1785.0" y="540.0"/> + <omgdi:waypoint x="1785.3772727272726" y="664.5"/> + </bpmndi:BPMNEdge> + <bpmndi:BPMNEdge bpmnElement="flow3" id="BPMNEdge_flow3"> + <omgdi:waypoint x="928.286878319943" y="540.2478767845322"/> + <omgdi:waypoint x="1030.0" y="540.7521232154678"/> + </bpmndi:BPMNEdge> + <bpmndi:BPMNEdge bpmnElement="sid-CF9ACA40-7750-47C3-A508-7250D24D4F1F" id="BPMNEdge_sid-CF9ACA40-7750-47C3-A508-7250D24D4F1F"> + <omgdi:waypoint x="1515.0" y="790.4389505549949"/> + <omgdi:waypoint x="1080.0" y="790.0"/> + <omgdi:waypoint x="1080.0" y="571.0"/> + </bpmndi:BPMNEdge> + <bpmndi:BPMNEdge bpmnElement="suspended2Reactivate" id="BPMNEdge_suspended2Reactivate"> + <omgdi:waypoint x="1860.0" y="400.0"/> + <omgdi:waypoint x="1902.0" y="400.0"/> + <omgdi:waypoint x="1902.0" y="320.0"/> + <omgdi:waypoint x="1940.0" y="320.0"/> + </bpmndi:BPMNEdge> + <bpmndi:BPMNEdge bpmnElement="flow99" id="BPMNEdge_flow99"> + <omgdi:waypoint x="2040.0" y="466.5576923076923"/> + <omgdi:waypoint x="2080.005821071606" y="465.40367823831906"/> + </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:BPMNEdge bpmnElement="active2Update" id="BPMNEdge_active2Update"> + <omgdi:waypoint x="1420.0" y="560.0"/> + <omgdi:waypoint x="1420.0" y="615.0"/> + </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/core/workflow-activiti/src/main/resources/workflow.properties ---------------------------------------------------------------------- diff --git a/syncope620/core/workflow-activiti/src/main/resources/workflow.properties b/syncope620/core/workflow-activiti/src/main/resources/workflow.properties new file mode 100644 index 0000000..04e7d05 --- /dev/null +++ b/syncope620/core/workflow-activiti/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=true +uwfAdapter=org.apache.syncope.core.workflow.activiti.ActivitiUserWorkflowAdapter +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/core/workflow-activiti/src/main/resources/workflowActivitiContext.xml ---------------------------------------------------------------------- diff --git a/syncope620/core/workflow-activiti/src/main/resources/workflowActivitiContext.xml b/syncope620/core/workflow-activiti/src/main/resources/workflowActivitiContext.xml new file mode 100644 index 0000000..d5e9b02 --- /dev/null +++ b/syncope620/core/workflow-activiti/src/main/resources/workflowActivitiContext.xml @@ -0,0 +1,79 @@ +<?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:context="http://www.springframework.org/schema/context" + xsi:schemaLocation="http://www.springframework.org/schema/beans + http://www.springframework.org/schema/beans/spring-beans.xsd + http://www.springframework.org/schema/context + http://www.springframework.org/schema/context/spring-context.xsd"> + + <bean id="userWorkflowDef" class="org.apache.syncope.core.misc.spring.ResourceWithFallbackLoader"> + <property name="primary" value="file:${wf.directory}/userWorkflow.bpmn20.xml"/> + <property name="fallback" value="classpath:userWorkflow.bpmn20.xml"/> + </bean> + + <bean id="syncopeActivitiUserManager" class="org.apache.syncope.core.workflow.activiti.SyncopeUserManager"/> + <bean id="syncopeActivitiGroupManager" class="org.apache.syncope.core.workflow.activiti.SyncopeGroupManager"/> + + <bean id="processEngineConfiguration" class="org.activiti.spring.SpringProcessEngineConfiguration"> + <property name="dataSource" ref="dataSource"/> + <property name="transactionManager" ref="transactionManager"/> + <property name="transactionsExternallyManaged" value="true"/> + <property name="databaseSchemaUpdate" value="true"/> + + <property name="jpaEntityManagerFactory" ref="entityManagerFactory"/> + <property name="jpaHandleTransaction" value="true"/> + <property name="jpaCloseEntityManager" value="false"/> + + <property name="jobExecutorActivate" value="${jobExecutorActivate}"/> + + <property name="customSessionFactories"> + <list> + <bean class="org.apache.syncope.core.workflow.activiti.SyncopeSessionFactory"> + <property name="syncopeSession" ref="syncopeActivitiUserManager"/> + </bean> + <bean class="org.apache.syncope.core.workflow.activiti.SyncopeSessionFactory"> + <property name="syncopeSession" ref="syncopeActivitiGroupManager"/> + </bean> + </list> + </property> + <property name="customPreVariableTypes"> + <list> + <bean class="org.apache.syncope.core.workflow.activiti.SyncopeEntitiesVariableType"/> + </list> + </property> + </bean> + + <bean id="processEngine" class="org.activiti.spring.ProcessEngineFactoryBean"> + <property name="processEngineConfiguration" ref="processEngineConfiguration"/> + </bean> + + <bean id="repositoryService" factory-bean="processEngine" factory-method="getRepositoryService"/> + <bean id="runtimeService" factory-bean="processEngine" factory-method="getRuntimeService"/> + <bean id="taskService" factory-bean="processEngine" factory-method="getTaskService"/> + <bean id="historyService" factory-bean="processEngine" factory-method="getHistoryService"/> + <bean id="managementService" factory-bean="processEngine" factory-method="getManagementService"/> + <bean id="identityService" factory-bean="processEngine" factory-method="getIdentityService"/> + <bean id="formService" factory-bean="processEngine" factory-method="getFormService"/> + + <context:component-scan base-package="org.apache.syncope.core.workflow.activiti"/> + +</beans> http://git-wip-us.apache.org/repos/asf/syncope/blob/d30c8526/syncope620/core/workflow-api/pom.xml ---------------------------------------------------------------------- diff --git a/syncope620/core/workflow-api/pom.xml b/syncope620/core/workflow-api/pom.xml new file mode 100644 index 0000000..e1003cb --- /dev/null +++ b/syncope620/core/workflow-api/pom.xml @@ -0,0 +1,60 @@ +<?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. +--> +<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> + + <modelVersion>4.0.0</modelVersion> + + <parent> + <groupId>org.apache.syncope</groupId> + <artifactId>syncope-core</artifactId> + <version>2.0.0-SNAPSHOT</version> + </parent> + + <name>Apache Syncope Core Workflow API</name> + <description>Apache Syncope Core Workflow API</description> + <groupId>org.apache.syncope.core</groupId> + <artifactId>syncope-core-workflow-api</artifactId> + <packaging>jar</packaging> + + <properties> + <rootpom.basedir>${basedir}/../..</rootpom.basedir> + </properties> + + <dependencies> + <dependency> + <groupId>org.apache.syncope.core</groupId> + <artifactId>syncope-core-provisioning-api</artifactId> + <version>${project.version}</version> + </dependency> + </dependencies> + + <build> + <plugins> + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-checkstyle-plugin</artifactId> + </plugin> + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-pmd-plugin</artifactId> + </plugin> + </plugins> + </build> +</project> http://git-wip-us.apache.org/repos/asf/syncope/blob/d30c8526/syncope620/core/workflow-api/src/main/java/org/apache/syncope/core/workflow/api/RoleWorkflowAdapter.java ---------------------------------------------------------------------- diff --git a/syncope620/core/workflow-api/src/main/java/org/apache/syncope/core/workflow/api/RoleWorkflowAdapter.java b/syncope620/core/workflow-api/src/main/java/org/apache/syncope/core/workflow/api/RoleWorkflowAdapter.java new file mode 100644 index 0000000..ce67a4d --- /dev/null +++ b/syncope620/core/workflow-api/src/main/java/org/apache/syncope/core/workflow/api/RoleWorkflowAdapter.java @@ -0,0 +1,71 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.syncope.core.workflow.api; + +import org.apache.syncope.core.provisioning.api.WorkflowResult; +import org.apache.syncope.common.lib.mod.RoleMod; +import org.apache.syncope.common.lib.to.RoleTO; +import org.apache.syncope.core.persistence.api.dao.NotFoundException; + +/** + * Interface for calling underlying workflow implementations. + */ +public interface RoleWorkflowAdapter extends WorkflowAdapter { + + /** + * Create a role. + * + * @param roleTO role to be created and wether to propagate it as active + * @return role just created + * @throws WorkflowException workflow exception + */ + WorkflowResult<Long> create(RoleTO roleTO) throws WorkflowException; + + /** + * Execute a task on a role. + * + * @param roleTO role to be subject to task + * @param taskId to be executed + * @return role just updated + * @throws NotFoundException role not found exception + * @throws WorkflowException workflow exception + */ + WorkflowResult<Long> execute(RoleTO roleTO, String taskId) + throws NotFoundException, WorkflowException; + + /** + * Update a role. + * + * @param roleMod modification set to be performed + * @return role just updated and propagations to be performed + * @throws NotFoundException role not found exception + * @throws WorkflowException workflow exception + */ + WorkflowResult<Long> update(RoleMod roleMod) + throws NotFoundException, WorkflowException; + + /** + * Delete a role. + * + * @param roleKey role to be deleted + * @throws NotFoundException role not found exception + * @throws WorkflowException workflow exception + */ + void delete(Long roleKey) throws NotFoundException, WorkflowException; +} http://git-wip-us.apache.org/repos/asf/syncope/blob/d30c8526/syncope620/core/workflow-api/src/main/java/org/apache/syncope/core/workflow/api/UserWorkflowAdapter.java ---------------------------------------------------------------------- diff --git a/syncope620/core/workflow-api/src/main/java/org/apache/syncope/core/workflow/api/UserWorkflowAdapter.java b/syncope620/core/workflow-api/src/main/java/org/apache/syncope/core/workflow/api/UserWorkflowAdapter.java new file mode 100644 index 0000000..6475bcc --- /dev/null +++ b/syncope620/core/workflow-api/src/main/java/org/apache/syncope/core/workflow/api/UserWorkflowAdapter.java @@ -0,0 +1,151 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.syncope.core.workflow.api; + +import org.apache.syncope.core.provisioning.api.WorkflowResult; +import java.util.Map; +import org.apache.syncope.common.lib.mod.UserMod; +import org.apache.syncope.common.lib.to.UserTO; +import org.apache.syncope.core.persistence.api.entity.user.User; + +/** + * Interface for calling underlying workflow implementations. + */ +public interface UserWorkflowAdapter extends WorkflowAdapter { + + /** + * Create an user. + * + * @param userTO user to be created and whether to propagate it as active + * @param storePassword whether password shall be stored into the internal storage + * @return user just created + * @throws WorkflowException workflow exception + */ + WorkflowResult<Map.Entry<Long, Boolean>> create(UserTO userTO, boolean storePassword) + throws WorkflowException; + + /** + * Create an user, optionally disabling password policy check. + * + * @param userTO user to be created and whether to propagate it as active + * @param disablePwdPolicyCheck disable password policy check? + * @param storePassword whether password shall be stored into the internal storage + * @return user just created + * @throws WorkflowException workflow exception + */ + WorkflowResult<Map.Entry<Long, Boolean>> create(UserTO userTO, boolean disablePwdPolicyCheck, + boolean storePassword) throws WorkflowException; + + /** + * Create an user, optionally disabling password policy check. + * + * @param userTO user to be created and whether to propagate it as active + * @param disablePwdPolicyCheck disable password policy check? + * @param enabled specify true/false to force active/supended status + * @param storePassword whether password shall be stored into the internal storage + * @return user just created + * @throws WorkflowException workflow exception + */ + WorkflowResult<Map.Entry<Long, Boolean>> create(UserTO userTO, boolean disablePwdPolicyCheck, final Boolean enabled, + boolean storePassword) throws WorkflowException; + + /** + * Execute a task on an user. + * + * @param userTO user to be subject to task + * @param taskId to be executed + * @return user just updated + * @throws WorkflowException workflow exception + */ + WorkflowResult<Long> execute(UserTO userTO, String taskId) throws WorkflowException; + + /** + * Activate an user. + * + * @param userKey user to be activated + * @param token to be verified for activation + * @return user just updated + * @throws WorkflowException workflow exception + */ + WorkflowResult<Long> activate(Long userKey, String token) throws WorkflowException; + + /** + * Update an user. + * + * @param userMod modification set to be performed + * @return user just updated and propagations to be performed + * @throws WorkflowException workflow exception + */ + WorkflowResult<Map.Entry<UserMod, Boolean>> update(UserMod userMod) + throws WorkflowException; + + /** + * Suspend an user. + * + * @param userKey user to be suspended + * @return user just suspended + * @throws WorkflowException workflow exception + */ + WorkflowResult<Long> suspend(Long userKey) throws WorkflowException; + + /** + * Suspend an user. + * + * @param user to be suspended + * @return user just suspended + * @throws WorkflowException workflow exception + */ + WorkflowResult<Long> suspend(User user) throws WorkflowException; + + /** + * Reactivate an user. + * + * @param userKey user to be reactivated + * @return user just reactivated + * @throws WorkflowException workflow exception + */ + WorkflowResult<Long> reactivate(Long userKey) throws WorkflowException; + + /** + * Request password reset for an user. + * + * @param userKey user requesting password reset + * @throws WorkflowException workflow exception + */ + void requestPasswordReset(Long userKey) throws WorkflowException; + + /** + * Confirm password reset for an user. + * + * @param userKey user confirming password reset + * @param token security token + * @param password new password value + * @throws WorkflowException workflow exception + */ + void confirmPasswordReset(Long userKey, String token, String password) + throws WorkflowException; + + /** + * Delete an user. + * + * @param userKey user to be deleted + * @throws WorkflowException workflow exception + */ + void delete(Long userKey) throws WorkflowException; +} http://git-wip-us.apache.org/repos/asf/syncope/blob/d30c8526/syncope620/core/workflow-api/src/main/java/org/apache/syncope/core/workflow/api/WorkflowAdapter.java ---------------------------------------------------------------------- diff --git a/syncope620/core/workflow-api/src/main/java/org/apache/syncope/core/workflow/api/WorkflowAdapter.java b/syncope620/core/workflow-api/src/main/java/org/apache/syncope/core/workflow/api/WorkflowAdapter.java new file mode 100644 index 0000000..85d8822 --- /dev/null +++ b/syncope620/core/workflow-api/src/main/java/org/apache/syncope/core/workflow/api/WorkflowAdapter.java @@ -0,0 +1,107 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.syncope.core.workflow.api; + +import org.apache.syncope.core.provisioning.api.WorkflowResult; +import java.io.OutputStream; +import java.util.List; +import org.apache.syncope.common.lib.mod.AbstractAttributableMod; +import org.apache.syncope.common.lib.to.WorkflowFormTO; +import org.apache.syncope.core.persistence.api.dao.NotFoundException; + +public interface WorkflowAdapter { + + /** + * @return any string that might be interpreted as "prefix"e; (say table prefix in SQL environments) + */ + String getPrefix(); + + /** + * Export workflow definition. + * + * @param format export format + * @param os export stream + * @throws WorkflowException workflow exception + */ + void exportDefinition(WorkflowDefinitionFormat format, OutputStream os) throws WorkflowException; + + /** + * Export workflow graphical representation (if available). + * + * @param os export stream + * @throws WorkflowException workflow exception + */ + void exportDiagram(OutputStream os) throws WorkflowException; + + /** + * Update workflow definition. + * + * @param format import format + * @param definition definition + * @throws WorkflowException workflow exception + */ + void importDefinition(WorkflowDefinitionFormat format, String definition) throws WorkflowException; + + /** + * Get all defined forms for current workflow process instances. + * + * @return list of defined forms + */ + List<WorkflowFormTO> getForms(); + + /** + * Gets all forms with the given name for the given workflowId(include historical forms). + * + * @param workflowId workflow id. + * @param name form name. + * @return forms (if present), otherwise an empty list. + */ + List<WorkflowFormTO> getForms(String workflowId, String name); + + /** + * Get form for given workflowId (if present). + * + * @param workflowId workflow id + * @return form (if present), otherwise null + * @throws NotFoundException definition not found exception + * @throws WorkflowException workflow exception + */ + WorkflowFormTO getForm(String workflowId) throws NotFoundException, WorkflowException; + + /** + * Claim a form for a given user. + * + * @param taskId Workflow task to which the form is associated + * @return updated form + * @throws NotFoundException not found exception + * @throws WorkflowException workflow exception + */ + WorkflowFormTO claimForm(String taskId) throws NotFoundException, WorkflowException; + + /** + * Submit a form. + * + * @param form to be submitted + * @return user updated by this form submit + * @throws NotFoundException not found exception + * @throws WorkflowException workflow exception + */ + WorkflowResult<? extends AbstractAttributableMod> submitForm(WorkflowFormTO form) + throws NotFoundException, WorkflowException; +} http://git-wip-us.apache.org/repos/asf/syncope/blob/d30c8526/syncope620/core/workflow-api/src/main/java/org/apache/syncope/core/workflow/api/WorkflowDefinitionFormat.java ---------------------------------------------------------------------- diff --git a/syncope620/core/workflow-api/src/main/java/org/apache/syncope/core/workflow/api/WorkflowDefinitionFormat.java b/syncope620/core/workflow-api/src/main/java/org/apache/syncope/core/workflow/api/WorkflowDefinitionFormat.java new file mode 100644 index 0000000..f7d67f2 --- /dev/null +++ b/syncope620/core/workflow-api/src/main/java/org/apache/syncope/core/workflow/api/WorkflowDefinitionFormat.java @@ -0,0 +1,29 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.syncope.core.workflow.api; + +/** + * Format for import / export of workflow definition. + */ +public enum WorkflowDefinitionFormat { + + XML, + JSON + +} http://git-wip-us.apache.org/repos/asf/syncope/blob/d30c8526/syncope620/core/workflow-api/src/main/java/org/apache/syncope/core/workflow/api/WorkflowException.java ---------------------------------------------------------------------- diff --git a/syncope620/core/workflow-api/src/main/java/org/apache/syncope/core/workflow/api/WorkflowException.java b/syncope620/core/workflow-api/src/main/java/org/apache/syncope/core/workflow/api/WorkflowException.java new file mode 100644 index 0000000..74abc21 --- /dev/null +++ b/syncope620/core/workflow-api/src/main/java/org/apache/syncope/core/workflow/api/WorkflowException.java @@ -0,0 +1,51 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.syncope.core.workflow.api; + +/** + * Wrapper for all workflow related exceptions. Original exceptions will depend on UserWorkflowAdapter implementation. + * + * @see UserWorkflowAdapter + */ +public class WorkflowException extends RuntimeException { + + /** + * Generated serialVersionUID. + */ + private static final long serialVersionUID = -6261173250078013869L; + + /** + * Return a new instance wrapping the original workflow exception. + * + * @param cause original workflow exception + */ + public WorkflowException(final Throwable cause) { + super(cause); + } + + /** + * Return a new instance wrapping the original workflow exception, additionally providing a local message. + * + * @param message local message + * @param cause original workflow exception + */ + public WorkflowException(final String message, final Throwable cause) { + super(message, cause); + } +} http://git-wip-us.apache.org/repos/asf/syncope/blob/d30c8526/syncope620/core/workflow-api/src/main/java/org/apache/syncope/core/workflow/api/package-info.java ---------------------------------------------------------------------- diff --git a/syncope620/core/workflow-api/src/main/java/org/apache/syncope/core/workflow/api/package-info.java b/syncope620/core/workflow-api/src/main/java/org/apache/syncope/core/workflow/api/package-info.java new file mode 100644 index 0000000..3482c77 --- /dev/null +++ b/syncope620/core/workflow-api/src/main/java/org/apache/syncope/core/workflow/api/package-info.java @@ -0,0 +1,19 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.syncope.core.workflow.api; http://git-wip-us.apache.org/repos/asf/syncope/blob/d30c8526/syncope620/core/workflow-java/pom.xml ---------------------------------------------------------------------- diff --git a/syncope620/core/workflow-java/pom.xml b/syncope620/core/workflow-java/pom.xml new file mode 100644 index 0000000..3d82fdd --- /dev/null +++ b/syncope620/core/workflow-java/pom.xml @@ -0,0 +1,69 @@ +<?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. +--> +<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> + + <modelVersion>4.0.0</modelVersion> + + <parent> + <groupId>org.apache.syncope</groupId> + <artifactId>syncope-core</artifactId> + <version>2.0.0-SNAPSHOT</version> + </parent> + + <name>Apache Syncope Core Workflow Java</name> + <description>Apache Syncope Core Workflow Java</description> + <groupId>org.apache.syncope.core</groupId> + <artifactId>syncope-core-workflow-java</artifactId> + <packaging>jar</packaging> + + <properties> + <rootpom.basedir>${basedir}/../..</rootpom.basedir> + </properties> + + <dependencies> + <dependency> + <groupId>org.springframework</groupId> + <artifactId>spring-context</artifactId> + </dependency> + <dependency> + <groupId>org.springframework</groupId> + <artifactId>spring-tx</artifactId> + </dependency> + + <dependency> + <groupId>org.apache.syncope.core</groupId> + <artifactId>syncope-core-workflow-api</artifactId> + <version>${project.version}</version> + </dependency> + </dependencies> + + <build> + <plugins> + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-checkstyle-plugin</artifactId> + </plugin> + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-pmd-plugin</artifactId> + </plugin> + </plugins> + </build> +</project> http://git-wip-us.apache.org/repos/asf/syncope/blob/d30c8526/syncope620/core/workflow-java/src/main/java/org/apache/syncope/core/workflow/java/AbstractRoleWorkflowAdapter.java ---------------------------------------------------------------------- diff --git a/syncope620/core/workflow-java/src/main/java/org/apache/syncope/core/workflow/java/AbstractRoleWorkflowAdapter.java b/syncope620/core/workflow-java/src/main/java/org/apache/syncope/core/workflow/java/AbstractRoleWorkflowAdapter.java new file mode 100644 index 0000000..54e00ab --- /dev/null +++ b/syncope620/core/workflow-java/src/main/java/org/apache/syncope/core/workflow/java/AbstractRoleWorkflowAdapter.java @@ -0,0 +1,66 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.syncope.core.workflow.java; + +import org.apache.syncope.common.lib.mod.RoleMod; +import org.apache.syncope.core.persistence.api.dao.NotFoundException; +import org.apache.syncope.core.persistence.api.dao.RoleDAO; +import org.apache.syncope.core.persistence.api.entity.EntityFactory; +import org.apache.syncope.core.persistence.api.entity.role.Role; +import org.apache.syncope.core.provisioning.api.WorkflowResult; +import org.apache.syncope.core.provisioning.api.data.RoleDataBinder; +import org.apache.syncope.core.workflow.api.RoleWorkflowAdapter; +import org.apache.syncope.core.workflow.api.WorkflowException; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.transaction.annotation.Transactional; + +@Transactional(rollbackFor = { Throwable.class }) +public abstract class AbstractRoleWorkflowAdapter implements RoleWorkflowAdapter { + + @Autowired + protected RoleDataBinder dataBinder; + + @Autowired + protected RoleDAO roleDAO; + + @Autowired + protected EntityFactory entityFactory; + + @Override + public String getPrefix() { + return null; + } + + protected abstract WorkflowResult<Long> doUpdate(Role role, RoleMod roleMod) + throws WorkflowException; + + @Override + public WorkflowResult<Long> update(final RoleMod roleMod) + throws NotFoundException, WorkflowException { + + return doUpdate(roleDAO.authFetch(roleMod.getKey()), roleMod); + } + + protected abstract void doDelete(Role role) throws WorkflowException; + + @Override + public void delete(final Long roleKey) throws NotFoundException, WorkflowException { + doDelete(roleDAO.authFetch(roleKey)); + } +} http://git-wip-us.apache.org/repos/asf/syncope/blob/d30c8526/syncope620/core/workflow-java/src/main/java/org/apache/syncope/core/workflow/java/AbstractUserWorkflowAdapter.java ---------------------------------------------------------------------- diff --git a/syncope620/core/workflow-java/src/main/java/org/apache/syncope/core/workflow/java/AbstractUserWorkflowAdapter.java b/syncope620/core/workflow-java/src/main/java/org/apache/syncope/core/workflow/java/AbstractUserWorkflowAdapter.java new file mode 100644 index 0000000..c37d8b2 --- /dev/null +++ b/syncope620/core/workflow-java/src/main/java/org/apache/syncope/core/workflow/java/AbstractUserWorkflowAdapter.java @@ -0,0 +1,136 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.syncope.core.workflow.java; + +import java.util.Map; +import org.apache.syncope.common.lib.mod.UserMod; +import org.apache.syncope.core.persistence.api.dao.UserDAO; +import org.apache.syncope.core.persistence.api.entity.EntityFactory; +import org.apache.syncope.core.persistence.api.entity.user.User; +import org.apache.syncope.core.provisioning.api.WorkflowResult; +import org.apache.syncope.core.provisioning.api.data.UserDataBinder; +import org.apache.syncope.core.workflow.api.UserWorkflowAdapter; +import org.apache.syncope.core.workflow.api.WorkflowException; +import org.identityconnectors.common.Base64; +import org.identityconnectors.common.security.EncryptorFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.transaction.annotation.Transactional; + +@Transactional(rollbackFor = { Throwable.class }) +public abstract class AbstractUserWorkflowAdapter implements UserWorkflowAdapter { + + @Autowired + protected UserDataBinder dataBinder; + + @Autowired + protected UserDAO userDAO; + + @Autowired + protected EntityFactory entityFactory; + + public static String encrypt(final String clear) { + byte[] encryptedBytes = EncryptorFactory.getInstance().getDefaultEncryptor().encrypt(clear.getBytes()); + return Base64.encode(encryptedBytes); + } + + public static String decrypt(final String crypted) { + byte[] decryptedBytes = EncryptorFactory.getInstance().getDefaultEncryptor().decrypt(Base64.decode(crypted)); + return new String(decryptedBytes); + } + + @Override + public String getPrefix() { + return null; + } + + protected abstract WorkflowResult<Long> doActivate(User user, String token) throws WorkflowException; + + @Override + public WorkflowResult<Long> activate(final Long userKey, final String token) + throws WorkflowException { + + return doActivate(userDAO.authFetch(userKey), token); + } + + protected abstract WorkflowResult<Map.Entry<UserMod, Boolean>> doUpdate(User user, UserMod userMod) + throws WorkflowException; + + @Override + public WorkflowResult<Map.Entry<UserMod, Boolean>> update(final UserMod userMod) + throws WorkflowException { + + return doUpdate(userDAO.authFetch(userMod.getKey()), userMod); + } + + protected abstract WorkflowResult<Long> doSuspend(User user) throws WorkflowException; + + @Override + public WorkflowResult<Long> suspend(final Long userKey) + throws WorkflowException { + + return suspend(userDAO.authFetch(userKey)); + } + + @Override + public WorkflowResult<Long> suspend(final User user) throws WorkflowException { + // set suspended flag + user.setSuspended(Boolean.TRUE); + + return doSuspend(user); + } + + protected abstract WorkflowResult<Long> doReactivate(User user) throws WorkflowException; + + @Override + public WorkflowResult<Long> reactivate(final Long userKey) throws WorkflowException { + final User user = userDAO.authFetch(userKey); + + // reset failed logins + user.setFailedLogins(0); + + // reset suspended flag + user.setSuspended(Boolean.FALSE); + + return doReactivate(user); + } + + protected abstract void doRequestPasswordReset(User user) throws WorkflowException; + + @Override + public void requestPasswordReset(final Long userKey) throws WorkflowException { + doRequestPasswordReset(userDAO.authFetch(userKey)); + } + + protected abstract void doConfirmPasswordReset(User user, String token, String password) + throws WorkflowException; + + @Override + public void confirmPasswordReset(final Long userKey, final String token, final String password) + throws WorkflowException { + + doConfirmPasswordReset(userDAO.authFetch(userKey), token, password); + } + + protected abstract void doDelete(User user) throws WorkflowException; + + @Override + public void delete(final Long userKey) throws WorkflowException { + doDelete(userDAO.authFetch(userKey)); + } +} http://git-wip-us.apache.org/repos/asf/syncope/blob/d30c8526/syncope620/core/workflow-java/src/main/java/org/apache/syncope/core/workflow/java/DefaultRoleWorkflowAdapter.java ---------------------------------------------------------------------- diff --git a/syncope620/core/workflow-java/src/main/java/org/apache/syncope/core/workflow/java/DefaultRoleWorkflowAdapter.java b/syncope620/core/workflow-java/src/main/java/org/apache/syncope/core/workflow/java/DefaultRoleWorkflowAdapter.java new file mode 100644 index 0000000..d4f8b52 --- /dev/null +++ b/syncope620/core/workflow-java/src/main/java/org/apache/syncope/core/workflow/java/DefaultRoleWorkflowAdapter.java @@ -0,0 +1,129 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.syncope.core.workflow.java; + +import java.io.OutputStream; +import java.util.Collections; +import java.util.List; +import org.apache.syncope.common.lib.mod.RoleMod; +import org.apache.syncope.common.lib.to.RoleTO; +import org.apache.syncope.common.lib.to.WorkflowFormTO; +import org.apache.syncope.common.lib.types.PropagationByResource; +import org.apache.syncope.common.lib.types.ResourceOperation; +import org.apache.syncope.core.persistence.api.dao.NotFoundException; +import org.apache.syncope.core.persistence.api.entity.role.Role; +import org.apache.syncope.core.provisioning.api.WorkflowResult; +import org.apache.syncope.core.workflow.api.WorkflowDefinitionFormat; +import org.apache.syncope.core.workflow.api.WorkflowException; +import org.springframework.transaction.annotation.Transactional; + +/** + * Simple implementation basically not involving any workflow engine. + */ +@Transactional(rollbackFor = { Throwable.class }) +public class DefaultRoleWorkflowAdapter extends AbstractRoleWorkflowAdapter { + + @Override + public WorkflowResult<Long> create(final RoleTO roleTO) throws WorkflowException { + Role role = entityFactory.newEntity(Role.class); + dataBinder.create(role, roleTO); + role = roleDAO.save(role); + + final PropagationByResource propByRes = new PropagationByResource(); + propByRes.set(ResourceOperation.CREATE, role.getResourceNames()); + + return new WorkflowResult<>(role.getKey(), propByRes, "create"); + } + + @Override + protected WorkflowResult<Long> doUpdate(final Role role, final RoleMod roleMod) + throws WorkflowException { + + PropagationByResource propByRes = dataBinder.update(role, roleMod); + + Role updated = roleDAO.save(role); + + return new WorkflowResult<>(updated.getKey(), propByRes, "update"); + } + + @Override + protected void doDelete(final Role role) + throws WorkflowException { + + roleDAO.delete(role); + } + + @Override + public WorkflowResult<Long> execute(RoleTO roleTO, String taskId) + throws NotFoundException, WorkflowException { + + throw new WorkflowException(new UnsupportedOperationException("Not supported.")); + } + + @Override + public void exportDefinition(final WorkflowDefinitionFormat format, final OutputStream os) + throws WorkflowException { + + throw new WorkflowException(new UnsupportedOperationException("Not supported.")); + } + + @Override + public void exportDiagram(final OutputStream os) throws WorkflowException { + throw new WorkflowException(new UnsupportedOperationException("Not supported.")); + } + + @Override + public void importDefinition(final WorkflowDefinitionFormat format, final String definition) + throws NotFoundException, WorkflowException { + + throw new WorkflowException(new UnsupportedOperationException("Not supported.")); + } + + @Override + public List<WorkflowFormTO> getForms() { + return Collections.emptyList(); + } + + @Override + public List<WorkflowFormTO> getForms(final String workflowId, final String name) { + return Collections.emptyList(); + } + + @Override + public WorkflowFormTO getForm(final String workflowId) + throws NotFoundException, WorkflowException { + + return null; + } + + @Override + public WorkflowFormTO claimForm(final String taskId) + throws NotFoundException, WorkflowException { + + throw new WorkflowException(new UnsupportedOperationException("Not supported.")); + } + + @Override + public WorkflowResult<RoleMod> submitForm(final WorkflowFormTO form) + throws NotFoundException, WorkflowException { + + throw new WorkflowException(new UnsupportedOperationException("Not supported.")); + } + +} http://git-wip-us.apache.org/repos/asf/syncope/blob/d30c8526/syncope620/core/workflow-java/src/main/java/org/apache/syncope/core/workflow/java/DefaultUserWorkflowAdapter.java ---------------------------------------------------------------------- diff --git a/syncope620/core/workflow-java/src/main/java/org/apache/syncope/core/workflow/java/DefaultUserWorkflowAdapter.java b/syncope620/core/workflow-java/src/main/java/org/apache/syncope/core/workflow/java/DefaultUserWorkflowAdapter.java new file mode 100644 index 0000000..1db511b --- /dev/null +++ b/syncope620/core/workflow-java/src/main/java/org/apache/syncope/core/workflow/java/DefaultUserWorkflowAdapter.java @@ -0,0 +1,233 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.syncope.core.workflow.java; + +import java.io.OutputStream; +import java.util.AbstractMap; +import java.util.AbstractMap.SimpleEntry; +import java.util.Collections; +import java.util.List; +import java.util.Map; +import org.apache.commons.lang3.SerializationUtils; +import org.apache.syncope.common.lib.mod.UserMod; +import org.apache.syncope.common.lib.to.UserTO; +import org.apache.syncope.common.lib.to.WorkflowFormTO; +import org.apache.syncope.common.lib.types.PropagationByResource; +import org.apache.syncope.common.lib.types.ResourceOperation; +import org.apache.syncope.core.persistence.api.dao.ConfDAO; +import org.apache.syncope.core.persistence.api.dao.NotFoundException; +import org.apache.syncope.core.persistence.api.entity.user.User; +import org.apache.syncope.core.provisioning.api.WorkflowResult; +import org.apache.syncope.core.workflow.api.WorkflowDefinitionFormat; +import org.apache.syncope.core.workflow.api.WorkflowException; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.transaction.annotation.Transactional; + +/** + * Simple implementation basically not involving any workflow engine. + */ +@Transactional(rollbackFor = { Throwable.class }) +public class DefaultUserWorkflowAdapter extends AbstractUserWorkflowAdapter { + + @Autowired + private ConfDAO confDAO; + + @Override + public WorkflowResult<Map.Entry<Long, Boolean>> create(UserTO userTO, boolean storePassword) + throws WorkflowException { + + return create(userTO, false, true); + } + + @Override + public WorkflowResult<Map.Entry<Long, Boolean>> create(final UserTO userTO, final boolean disablePwdPolicyCheck, + final boolean storePassword) throws WorkflowException { + + return create(userTO, disablePwdPolicyCheck, null, storePassword); + } + + @Override + public WorkflowResult<Map.Entry<Long, Boolean>> create(final UserTO userTO, final boolean disablePwdPolicyCheck, + final Boolean enabled, final boolean storePassword) throws WorkflowException { + + User user = entityFactory.newEntity(User.class); + dataBinder.create(user, userTO, storePassword); + + // this will make UserValidator not to consider password policies at all + if (disablePwdPolicyCheck) { + user.removeClearPassword(); + } + + String status; + boolean propagateEnable; + if (enabled == null) { + status = "created"; + propagateEnable = true; + } else { + status = enabled + ? "active" + : "suspended"; + propagateEnable = enabled; + user.setSuspended(!enabled); + } + + user.setStatus(status); + user = userDAO.save(user); + + final PropagationByResource propByRes = new PropagationByResource(); + propByRes.set(ResourceOperation.CREATE, user.getResourceNames()); + + return new WorkflowResult<Map.Entry<Long, Boolean>>( + new SimpleEntry<>(user.getKey(), propagateEnable), propByRes, "create"); + } + + @Override + protected WorkflowResult<Long> doActivate(final User user, final String token) + throws WorkflowException { + + if (!user.checkToken(token)) { + throw new WorkflowException(new IllegalArgumentException("Wrong token: " + token + " for " + user)); + } + + user.removeToken(); + user.setStatus("active"); + User updated = userDAO.save(user); + + return new WorkflowResult<>(updated.getKey(), null, "activate"); + } + + @Override + protected WorkflowResult<Map.Entry<UserMod, Boolean>> doUpdate(final User user, final UserMod userMod) + throws WorkflowException { + + // update password internally only if required + UserMod actualMod = SerializationUtils.clone(userMod); + if (actualMod.getPwdPropRequest() != null && !actualMod.getPwdPropRequest().isOnSyncope()) { + actualMod.setPassword(null); + } + // update User + PropagationByResource propByRes = dataBinder.update(user, actualMod); + + User updated = userDAO.save(user); + + userMod.setKey(updated.getKey()); + return new WorkflowResult<Map.Entry<UserMod, Boolean>>( + new AbstractMap.SimpleEntry<>(userMod, !user.isSuspended()), propByRes, "update"); + } + + @Override + protected WorkflowResult<Long> doSuspend(final User user) throws WorkflowException { + user.setStatus("suspended"); + User updated = userDAO.save(user); + + return new WorkflowResult<>(updated.getKey(), null, "suspend"); + } + + @Override + protected WorkflowResult<Long> doReactivate(final User user) throws WorkflowException { + user.setStatus("active"); + User updated = userDAO.save(user); + + return new WorkflowResult<>(updated.getKey(), null, "reactivate"); + } + + @Override + protected void doRequestPasswordReset(final User user) throws WorkflowException { + user.generateToken( + confDAO.find("token.length", "256").getValues().get(0).getLongValue().intValue(), + confDAO.find("token.expireTime", "60").getValues().get(0).getLongValue().intValue()); + userDAO.save(user); + } + + @Override + protected void doConfirmPasswordReset(final User user, final String token, final String password) + throws WorkflowException { + + if (!user.checkToken(token)) { + throw new WorkflowException(new IllegalArgumentException("Wrong token: " + token + " for " + user)); + } + + user.removeToken(); + user.setPassword(password, user.getCipherAlgorithm()); + userDAO.save(user); + } + + @Override + protected void doDelete(final User user) throws WorkflowException { + userDAO.delete(user); + } + + @Override + public WorkflowResult<Long> execute(final UserTO userTO, final String taskId) + throws NotFoundException, WorkflowException { + + throw new WorkflowException(new UnsupportedOperationException("Not supported.")); + } + + @Override + public void exportDefinition(final WorkflowDefinitionFormat format, final OutputStream os) + throws WorkflowException { + + throw new WorkflowException(new UnsupportedOperationException("Not supported.")); + } + + @Override + public void exportDiagram(final OutputStream os) throws WorkflowException { + throw new WorkflowException(new UnsupportedOperationException("Not supported.")); + } + + @Override + public void importDefinition(final WorkflowDefinitionFormat format, final String definition) + throws NotFoundException, WorkflowException { + + throw new WorkflowException(new UnsupportedOperationException("Not supported.")); + } + + @Override + public List<WorkflowFormTO> getForms() { + return Collections.emptyList(); + } + + @Override + public List<WorkflowFormTO> getForms(final String workflowId, final String name) { + return Collections.emptyList(); + } + + @Override + public WorkflowFormTO getForm(final String workflowId) + throws NotFoundException, WorkflowException { + + return null; + } + + @Override + public WorkflowFormTO claimForm(final String taskId) + throws NotFoundException, WorkflowException { + + throw new WorkflowException(new UnsupportedOperationException("Not supported.")); + } + + @Override + public WorkflowResult<UserMod> submitForm(final WorkflowFormTO form) + throws NotFoundException, WorkflowException { + + throw new WorkflowException(new UnsupportedOperationException("Not supported.")); + } + +} http://git-wip-us.apache.org/repos/asf/syncope/blob/d30c8526/syncope620/core/workflow-java/src/main/resources/workflow.properties ---------------------------------------------------------------------- diff --git a/syncope620/core/workflow-java/src/main/resources/workflow.properties b/syncope620/core/workflow-java/src/main/resources/workflow.properties new file mode 100644 index 0000000..9f0e35e --- /dev/null +++ b/syncope620/core/workflow-java/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/core/workflow-java/src/main/resources/workflowContext.xml ---------------------------------------------------------------------- diff --git a/syncope620/core/workflow-java/src/main/resources/workflowContext.xml b/syncope620/core/workflow-java/src/main/resources/workflowContext.xml new file mode 100644 index 0000000..54ac139 --- /dev/null +++ b/syncope620/core/workflow-java/src/main/resources/workflowContext.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. +--> +<beans xmlns="http://www.springframework.org/schema/beans" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://www.springframework.org/schema/beans + http://www.springframework.org/schema/beans/spring-beans.xsd"> + + <bean id="uwfAdapter" class="${uwfAdapter}"/> + <bean id="rwfAdapter" class="${rwfAdapter}"/> + +</beans> http://git-wip-us.apache.org/repos/asf/syncope/blob/d30c8526/syncope620/ext/camel/logic/pom.xml ---------------------------------------------------------------------- diff --git a/syncope620/ext/camel/logic/pom.xml b/syncope620/ext/camel/logic/pom.xml index 7e93f70..025ba02 100644 --- a/syncope620/ext/camel/logic/pom.xml +++ b/syncope620/ext/camel/logic/pom.xml @@ -39,8 +39,8 @@ under the License. <dependencies> <dependency> - <groupId>org.apache.syncope.server</groupId> - <artifactId>syncope-server-logic</artifactId> + <groupId>org.apache.syncope.core</groupId> + <artifactId>syncope-core-logic</artifactId> <version>${project.version}</version> </dependency> <dependency> http://git-wip-us.apache.org/repos/asf/syncope/blob/d30c8526/syncope620/ext/camel/logic/src/main/java/org/apache/syncope/core/logic/CamelRouteLogic.java ---------------------------------------------------------------------- diff --git a/syncope620/ext/camel/logic/src/main/java/org/apache/syncope/core/logic/CamelRouteLogic.java b/syncope620/ext/camel/logic/src/main/java/org/apache/syncope/core/logic/CamelRouteLogic.java new file mode 100644 index 0000000..0b3ff1e --- /dev/null +++ b/syncope620/ext/camel/logic/src/main/java/org/apache/syncope/core/logic/CamelRouteLogic.java @@ -0,0 +1,93 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.syncope.core.logic; + +import java.lang.reflect.Method; +import java.util.ArrayList; +import java.util.List; +import org.apache.syncope.common.lib.to.CamelRouteTO; +import org.apache.syncope.common.lib.types.SubjectType; +import org.apache.syncope.core.persistence.api.dao.CamelRouteDAO; +import org.apache.syncope.core.persistence.api.dao.NotFoundException; +import org.apache.syncope.core.persistence.api.entity.CamelRoute; +import org.apache.syncope.core.provisioning.api.data.CamelRouteDataBinder; +import org.apache.syncope.core.provisioning.camel.SyncopeCamelContext; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.security.access.prepost.PreAuthorize; +import org.springframework.stereotype.Component; +import org.springframework.transaction.annotation.Transactional; + +@Component +public class CamelRouteLogic extends AbstractTransactionalLogic<CamelRouteTO> { + + @Autowired + private CamelRouteDAO routeDAO; + + @Autowired + private CamelRouteDataBinder binder; + + @Autowired + private SyncopeCamelContext context; + + @PreAuthorize("hasRole('ROUTE_LIST')") + @Transactional(readOnly = true) + public List<CamelRouteTO> list(final SubjectType subjectType) { + List<CamelRouteTO> routes = new ArrayList<>(); + + for (CamelRoute route : routeDAO.find(subjectType)) { + routes.add(binder.getRouteTO(route)); + } + return routes; + } + + @PreAuthorize("hasRole('ROUTE_READ')") + @Transactional(readOnly = true) + public CamelRouteTO read(final String key) { + CamelRoute route = routeDAO.find(key); + if (route == null) { + throw new NotFoundException("CamelRoute with key=" + key); + } + + return binder.getRouteTO(route); + } + + @PreAuthorize("hasRole('ROUTE_UPDATE')") + public void update(final CamelRouteTO routeTO) { + CamelRoute route = routeDAO.find(routeTO.getKey()); + if (route == null) { + throw new NotFoundException("CamelRoute with key=" + routeTO.getKey()); + } + + LOG.debug("Updating route {} with content {}", routeTO.getKey(), routeTO.getContent()); + binder.update(route, routeTO); + + context.updateContext(routeTO.getKey()); + } + + @PreAuthorize("hasRole('ROUTE_UPDATE')") + public void restartContext() { + context.restartContext(); + } + + @Override + protected CamelRouteTO resolveReference(Method method, Object... args) throws UnresolvedReferenceException { + throw new UnresolvedReferenceException(); + } + +} http://git-wip-us.apache.org/repos/asf/syncope/blob/d30c8526/syncope620/ext/camel/logic/src/main/java/org/apache/syncope/core/logic/init/CamelRouteLoader.java ---------------------------------------------------------------------- diff --git a/syncope620/ext/camel/logic/src/main/java/org/apache/syncope/core/logic/init/CamelRouteLoader.java b/syncope620/ext/camel/logic/src/main/java/org/apache/syncope/core/logic/init/CamelRouteLoader.java new file mode 100644 index 0000000..a738012 --- /dev/null +++ b/syncope620/ext/camel/logic/src/main/java/org/apache/syncope/core/logic/init/CamelRouteLoader.java @@ -0,0 +1,167 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.syncope.core.logic.init; + +import java.io.StringWriter; +import java.util.List; +import java.util.Map; +import javax.sql.DataSource; +import org.apache.syncope.common.lib.types.SubjectType; +import org.apache.syncope.core.misc.spring.ResourceWithFallbackLoader; +import org.apache.syncope.core.persistence.api.SyncopeLoader; +import org.apache.syncope.core.persistence.api.entity.CamelEntityFactory; +import org.apache.syncope.core.persistence.api.entity.CamelRoute; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.core.io.Resource; +import org.springframework.dao.DataAccessException; +import org.springframework.jdbc.core.JdbcTemplate; +import org.springframework.stereotype.Component; +import org.springframework.transaction.annotation.Transactional; +import org.w3c.dom.Element; +import org.w3c.dom.Node; +import org.w3c.dom.NodeList; +import org.w3c.dom.bootstrap.DOMImplementationRegistry; +import org.w3c.dom.ls.DOMImplementationLS; +import org.w3c.dom.ls.LSInput; +import org.w3c.dom.ls.LSOutput; +import org.w3c.dom.ls.LSParser; +import org.w3c.dom.ls.LSSerializer; + +@Component +public class CamelRouteLoader implements SyncopeLoader { + + private static final Logger LOG = LoggerFactory.getLogger(CamelRouteLoader.class); + + @javax.annotation.Resource(name = "userRoutes") + private ResourceWithFallbackLoader userRoutesLoader; + + @javax.annotation.Resource(name = "roleRoutes") + private ResourceWithFallbackLoader roleRoutesLoader; + + @Autowired + private DataSource dataSource; + + @Autowired + private CamelEntityFactory entityFactory; + + private boolean loaded = false; + + @Override + public Integer getPriority() { + return 1000; + } + + @Transactional + public void load() { + synchronized (this) { + if (!loaded) { + loadRoutes(userRoutesLoader.getResource(), SubjectType.USER); + loadRoutes(roleRoutesLoader.getResource(), SubjectType.ROLE); + loadEntitlements(); + loaded = true; + } + } + } + + private boolean loadRoutesFor(final SubjectType subject) { + final String sql = String.format("SELECT * FROM %s WHERE SUBJECTTYPE = ?", CamelRoute.class.getSimpleName()); + final JdbcTemplate jdbcTemplate = new JdbcTemplate(dataSource); + final List<Map<String, Object>> rows = jdbcTemplate.queryForList(sql, new Object[] { subject.name() }); + return rows.isEmpty(); + } + + private String nodeToString(final Node content, final DOMImplementationLS domImpl) { + StringWriter writer = new StringWriter(); + try { + LSSerializer serializer = domImpl.createLSSerializer(); + serializer.getDomConfig().setParameter("xml-declaration", false); + LSOutput lso = domImpl.createLSOutput(); + lso.setCharacterStream(writer); + serializer.write(content, lso); + } catch (Exception e) { + LOG.debug("While serializing route node", e); + } + return writer.toString(); + } + + private void loadRoutes(final Resource resource, final SubjectType subjectType) { + if (loadRoutesFor(subjectType)) { + String query = String.format("INSERT INTO %s(NAME, SUBJECTTYPE, CONTENT) VALUES (?, ?, ?)", + CamelRoute.class.getSimpleName()); + JdbcTemplate jdbcTemplate = new JdbcTemplate(dataSource); + + try { + DOMImplementationRegistry reg = DOMImplementationRegistry.newInstance(); + DOMImplementationLS domImpl = (DOMImplementationLS) reg.getDOMImplementation("LS"); + LSInput lsinput = domImpl.createLSInput(); + lsinput.setByteStream(resource.getInputStream()); + + LSParser parser = domImpl.createLSParser(DOMImplementationLS.MODE_SYNCHRONOUS, null); + + NodeList routeNodes = parser.parse(lsinput).getDocumentElement().getElementsByTagName("route"); + for (int s = 0; s < routeNodes.getLength(); s++) { + Node routeElement = routeNodes.item(s); + String routeContent = nodeToString(routeNodes.item(s), domImpl); + String routeId = ((Element) routeElement).getAttribute("id"); + + CamelRoute route = entityFactory.newCamelRoute(); + route.setSubjectType(subjectType); + route.setKey(routeId); + route.setContent(routeContent); + + jdbcTemplate.update(query, new Object[] { routeId, subjectType.name(), routeContent }); + LOG.debug("Route {} successfully loaded", routeId); + } + } catch (DataAccessException e) { + LOG.error("While trying to store queries {}", e); + } catch (Exception e) { + LOG.error("Route load failed {}", e.getMessage()); + } + } + } + + private void loadEntitlements() { + final JdbcTemplate jdbcTemplate = new JdbcTemplate(dataSource); + + boolean existingData; + try { + existingData = jdbcTemplate.queryForObject( + "SELECT COUNT(0) FROM Entitlement WHERE NAME LIKE 'ROUTE_%'", Integer.class) > 0; + } catch (DataAccessException e) { + LOG.error("Could not access to Entitlement table", e); + existingData = true; + } + + if (existingData) { + LOG.info("Data found in the database, leaving untouched"); + } else { + LOG.info("Empty database found, loading default content"); + + try { + jdbcTemplate.update("INSERT INTO Entitlement(NAME) VALUES('ROUTE_READ')"); + jdbcTemplate.update("INSERT INTO Entitlement(NAME) VALUES('ROUTE_LIST')"); + jdbcTemplate.update("INSERT INTO Entitlement(NAME) VALUES('ROUTE_UPDATE')"); + } catch (Exception e) { + LOG.error("While adding additional entitlements", e); + } + } + } +} http://git-wip-us.apache.org/repos/asf/syncope/blob/d30c8526/syncope620/ext/camel/logic/src/main/java/org/apache/syncope/server/logic/CamelRouteLogic.java ---------------------------------------------------------------------- diff --git a/syncope620/ext/camel/logic/src/main/java/org/apache/syncope/server/logic/CamelRouteLogic.java b/syncope620/ext/camel/logic/src/main/java/org/apache/syncope/server/logic/CamelRouteLogic.java deleted file mode 100644 index 1b13166..0000000 --- a/syncope620/ext/camel/logic/src/main/java/org/apache/syncope/server/logic/CamelRouteLogic.java +++ /dev/null @@ -1,93 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ -package org.apache.syncope.server.logic; - -import java.lang.reflect.Method; -import java.util.ArrayList; -import java.util.List; -import org.apache.syncope.common.lib.to.CamelRouteTO; -import org.apache.syncope.common.lib.types.SubjectType; -import org.apache.syncope.server.persistence.api.dao.CamelRouteDAO; -import org.apache.syncope.server.persistence.api.dao.NotFoundException; -import org.apache.syncope.server.persistence.api.entity.CamelRoute; -import org.apache.syncope.server.provisioning.api.data.CamelRouteDataBinder; -import org.apache.syncope.server.provisioning.camel.SyncopeCamelContext; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.security.access.prepost.PreAuthorize; -import org.springframework.stereotype.Component; -import org.springframework.transaction.annotation.Transactional; - -@Component -public class CamelRouteLogic extends AbstractTransactionalLogic<CamelRouteTO> { - - @Autowired - private CamelRouteDAO routeDAO; - - @Autowired - private CamelRouteDataBinder binder; - - @Autowired - private SyncopeCamelContext context; - - @PreAuthorize("hasRole('ROUTE_LIST')") - @Transactional(readOnly = true) - public List<CamelRouteTO> list(final SubjectType subjectType) { - List<CamelRouteTO> routes = new ArrayList<>(); - - for (CamelRoute route : routeDAO.find(subjectType)) { - routes.add(binder.getRouteTO(route)); - } - return routes; - } - - @PreAuthorize("hasRole('ROUTE_READ')") - @Transactional(readOnly = true) - public CamelRouteTO read(final String key) { - CamelRoute route = routeDAO.find(key); - if (route == null) { - throw new NotFoundException("CamelRoute with key=" + key); - } - - return binder.getRouteTO(route); - } - - @PreAuthorize("hasRole('ROUTE_UPDATE')") - public void update(final CamelRouteTO routeTO) { - CamelRoute route = routeDAO.find(routeTO.getKey()); - if (route == null) { - throw new NotFoundException("CamelRoute with key=" + routeTO.getKey()); - } - - LOG.debug("Updating route {} with content {}", routeTO.getKey(), routeTO.getContent()); - binder.update(route, routeTO); - - context.updateContext(routeTO.getKey()); - } - - @PreAuthorize("hasRole('ROUTE_UPDATE')") - public void restartContext() { - context.restartContext(); - } - - @Override - protected CamelRouteTO resolveReference(Method method, Object... args) throws UnresolvedReferenceException { - throw new UnresolvedReferenceException(); - } - -}
