Activiti 7 Beta 2 comes with a new BPMN modeling application that we will have a look at in this article. It supports the BPMN 2.0 standard. It’s been developed with the help of the Alfresco Application Development Framework (ADF). The source code is available here.
Activiti 7 Deep Dive Article Series
- You have read and worked through the "
- You are familiar with Business Process Model and Notation (BPMN) 2.0 and you have designed and created business processes before, maybe even with previous versions of Activiti. This article will not cover too much around how to design business processes with BPMN.
Running the Activiti Modeler Application
The Activiti deployment that we did in the previous article already got the modeler up and running. If you don’t have it running, then go back and start it up as per instructions in that article. You can access the modeler via the http://activiti-cloud-gateway.<IP>.nip.io/activiti-cloud-modeling URL. Login with modeler/password as this user is part of the ACTIVITI_MODELER role, which have the rights to use the modelling capabilities, you should now see:
You might see an application if you created one the first time you accessed the modeler in the previous article.
Creating a Process Application
A process definition lives inside a so called Process Application. Let's create one that will contain our process definition. Click Create new | Application and give it a name and description:
Click Create button to create the new Process Application:
Now, click on the Sample App application to start modelling:
Creating a Process Definition
A Process Application can contain more than one Process Definition, so we need to create one before we start modelling the business process. Click on the Create new | Process menu item:
That should take you to a form where you fill in the name and description of the Process Definition:
Click Create button to create the new Process Definition:
Now, click on the Sample Process in the left navigation to start BPMN 2.0 modelling:
We already got a start node on the canvas in the middle. Now let’s continue with the activities that we want for our sample process.
Let’s start by adding a new User Task, in the left toolbar select the rectangle with a person icon in it and then drag-n-drop the User Task onto the canvas. Call it User Task 1:
We want to assign the user task to a specific user (i.e. not the the initiator of the process instance). We got the following users in Keycloak that we can choose from:
Click on the user task on the canvas and then fill in Assignee as testuser to the right in the Properties pane, then click the check button after the field to save the assignee value:
Then drag-n-drop a Service Task onto the canvas after the User task and call it Service Task 1:
To implement the Service Task we use something called Cloud Connectors, they run as their own processes in their own containers, which means they can be scaled and managed separately from the process execution.
Cloud Connector implementations are specified with the standard implementation property. Click on the Service Task 1 and then fill in the implementation property as follows with the serviceTask1Impl value:
The implementation property value on the Service Task definition will be used as a Spring Cloud Stream channel destination name (on the bound middleware RabbitMQ). So we have to make sure the custom Cloud Connector that we will build in the next article creates a consumer bound to this name with the spring.cloud.stream.bindings.<channel>.destination property value.
Now add an End node and then Save the whole process definition by clicking on the disk in the upper right corner. Also, make sure to download the XML for the new process definition by clicking on the download button next to the save button.
Important, if the session timeout expired and you cannot save, then just download and then import the process definition when logged in again.
You might be used to working with process listeners and task listeners in previous versions of Activiti. Listeners are an Activiti extension to BPMN 2.0 that implement hook points inside a process definition which are triggered by events during process execution. In Activiti 7 we can implement “listener” functionality by listening to events emitted by the process engine. This is better for Cloud deployments as events are async and Activiti listeners are synchronous. We will have a look at how to implement event handlers in the next article when we implement a custom Cloud Connector.
Sample Process Definition BPMN 2.0 XML
The exported BPMN 2.0 sample process definition looks something like this (double check that you got the User task set up properly with assignee and the Service Task with the implementation attribute):
<?xml version="1.0" encoding="UTF-8"?>
<bpmn2:process id="sampleproc-e9b76ff9-6f70-42c9-8dee-f6116c533a6d" name="Sample Process" isExecutable="true">
<bpmn2:userTask id="UserTask_0b6cp1l" name="User Task 1" activiti:assignee="testuser">
<bpmn2:sequenceFlow id="SequenceFlow_0qdq7ff" sourceRef="StartEvent_1" targetRef="UserTask_0b6cp1l" />
<bpmn2:serviceTask id="ServiceTask_1wg38me" name="Service Task 1" implementation="serviceTask1Impl">
<bpmn2:sequenceFlow id="SequenceFlow_1sc9dgy" sourceRef="UserTask_0b6cp1l" targetRef="ServiceTask_1wg38me" />
<bpmn2:sequenceFlow id="SequenceFlow_0t37jio" sourceRef="ServiceTask_1wg38me" targetRef="EndEvent_0irytw8" />
<bpmndi:BPMNPlane id="BPMNPlane_1" bpmnElement="sampleproc-e9b76ff9-6f70-42c9-8dee-f6116c533a6d">
<bpmndi:BPMNShape id="_BPMNShape_StartEvent_2" bpmnElement="StartEvent_1">
<dc:Bounds x="105" y="121" width="36" height="36" />
<dc:Bounds x="78" y="157" width="90" height="20" />
<bpmndi:BPMNShape id="UserTask_0b6cp1l_di" bpmnElement="UserTask_0b6cp1l">
<dc:Bounds x="233" y="98.5" width="100" height="80" />
<bpmndi:BPMNEdge id="SequenceFlow_0qdq7ff_di" bpmnElement="SequenceFlow_0qdq7ff">
<di:waypoint x="141" y="139" />
<di:waypoint x="283" y="139" />
<dc:Bounds x="212" y="117.5" width="0" height="13" />
<bpmndi:BPMNShape id="ServiceTask_1wg38me_di" bpmnElement="ServiceTask_1wg38me">
<dc:Bounds x="422" y="99" width="100" height="80" />
<bpmndi:BPMNEdge id="SequenceFlow_1sc9dgy_di" bpmnElement="SequenceFlow_1sc9dgy">
<di:waypoint x="333" y="139" />
<di:waypoint x="422" y="139" />
<dc:Bounds x="377.5" y="117" width="0" height="13" />
<bpmndi:BPMNShape id="EndEvent_0irytw8_di" bpmnElement="EndEvent_0irytw8">
<dc:Bounds x="611" y="121" width="36" height="36" />
<dc:Bounds x="629" y="160" width="0" height="13" />
<bpmndi:BPMNEdge id="SequenceFlow_0t37jio_di" bpmnElement="SequenceFlow_0t37jio">
<di:waypoint x="522" y="139" />
<di:waypoint x="611" y="139" />
<dc:Bounds x="566.5" y="117" width="0" height="13" />
The bpmndi:BPMNDiagram section defines the process definition graphical layout.
In the next article we will build a custom Runtime Bundle containing this process definition and a custom Cloud Connector that will provide an implementation for the Service Task.