Activiti is an Apache licensed BPMN-2.0 workflow engine.
Activiti comes in the form of a set of JAR files. It uses an RDBMS as the persistence storage (through MyBatis) and a scheduler for executing time tasks.
Activiti provides a user interface – the Activiti Explorer – for deploying process definitions, inspecting variables, assigning tasks to users and executing user tasks. The Activiti Explorer is a Vaadin application and comes in the form of a WAR file.
The Activiti Explorer is useful not only as a visual debugging tool but also as a generic back office for deployed processes.
To use Activiti Explorer as a management tool for deployed processes, two sets of actions are required:
- Its configuration needs to be updated
- Processes that contain user tasks require minor design modifications
Activiti Explorer Configuration Update
The default database configured in Activiti Explorer is H2. A production environment is probably using a different database. Below are the changes required to let the Activiti Explorer access an Activiti deployment to MySQL.
Replace the following lines:
jdbc.driver=org.h2.Driver jdbc.url=jdbc:h2:mem:activiti;DB_CLOSE_DELAY=1000 jdbc.username=sa jdbc.password=
db=mysql jdbc.driver=com.mysql.jdbc.Driver jdbc.url=jdbc:mysql://myhost.domain.com:3306/activiti jdbc.username=activiti jdbc.password=secret
Disable the generation of demo data which will interfere with the application’s data in Activiti. Leave the user generation enabled, as this will create the user kermit with administrative privileges which is useful to get started with the UI:
<bean id="demoDataGenerator" class="org.activiti.explorer.demo.DemoDataGenerator" init-method="init"> <property name="processEngine" ref="processEngine" /> <!-- Set following properties to false if certain demo data is not wanted --> <property name="createDemoUsersAndGroups" value="true" /> <property name="createDemoProcessDefinitions" value="false" /> <property name="createDemoModels" value="false" /> <property name="generateReportData" value="false" /> </bean>
When a process reaches a user task node, it is suspended until signaled to continue execution. A user task may be assigned to a user or potentially claimed by one or more users or groups. When the task is assigned to a user, the Activiti Explorer displays a form with fields requested by the user task. The form is dynamic and based on the user task’s configured input fields. When the task is submitted, the process is signaled to move to the next node in the workflow.
Typically reaching a node in Activiti triggers an application-specific action. In some cases the action is fully contained in the process definition (e.g. running a script with the Script Task) and in other cases, the task delegates to services that are only available in the application context (e.g. posting to an Apache Camel endpoint), not in the Activiti Explorer context.
To be able to benefit from Activiti’s Explorer user task input fields rendering while still run the application completely independently, processes need to be updated to include a Timer Intermediate Catching Event after each User Task. In Activiti’s XML terms:
... <userTask id="actionFailTask" name="Action Fail Task" activiti:candidateUsers="kermit" activiti:formKey="manual"> <extensionElements> <activiti:formProperty id="manual" name="Manual Resolution" type="boolean" variable="manual" required="true"></activiti:formProperty> </extensionElements> </userTask> <sequenceFlow id="flow2" sourceRef="actionFailTask" targetRef="timerintermediatecatchevent1"> </sequenceFlow> <intermediateCatchEvent id="timerintermediatecatchevent1" name="TimerCatchEvent"> <timerEventDefinition> <timeDate>PT1S</timeDate> </timerEventDefinition> </intermediateCatchEvent> <sequenceFlow id="flow3" sourceRef="timerintermediatecatchevent1" targetRef="nextTask"> </sequenceFlow> ...
Finally, the Activiti Explorer’s own job executor needs to be disabled to avoid executing the timer task in the Activiti Explorer’s context:
<bean id="processEngineConfiguration" class="org.activiti.spring.SpringProcessEngineConfiguration"> <property name="dataSource" ref="dataSource" /> <property name="transactionManager" ref="transactionManager" /> <property name="databaseSchemaUpdate" value="true" /> <property name="jobExecutorActivate" value="false" /> <property name="customFormTypes"> <list> <bean class="org.activiti.explorer.form.UserFormType"/> <bean class="org.activiti.explorer.form.ProcessDefinitionFormType"/> <bean class="org.activiti.explorer.form.MonthFormType"/> </list> </property> </bean>