Subprocesses can be divided into embedded subprocesses and call activities. The former are usual processes enclosed inside the parent process and don't live by its own. Embedded subprocesses are mainly used to reduce the visual complexity of a process. Therefore, they can be in an expanded and in a collapsed (with a plus symbol) state.
A call activity references another process, so that a process can be reused in multiple processes. For instance, a billing process is a typical example of a reusable process. The Call Activity is marked with a thick border and requires the referenced process to have at least one non-typed start event.
Embedded expanded or collapsed Subprocess
Embedded processes are part of the parent process and include the process logic inside the subProcess
element.
They always start with a non-typed start event and should also end with one.
It is purely part of the graphical specification inside BPMNDiagram
, if the subprocess is displayed in the collapsed or expanded form.
In both cases, the semantic part is contained in the parent process.
In the PROCEED MS it is not possible to convert a collapsed subprocess into an expanded one, because this would interfere with the graphical layout of the remaining process and would maybe shift or overlap some other elements.
<bpmn:process ... >
...
<bpmn:startEvent id="StartEvent_1"></bpmn:startEvent>
<bpmn:sequenceFlow id="Flow_1x5to91" sourceRef="StartEvent_1" targetRef="Activity_1juds8c" />
<bpmn:subProcess id="Activity_1juds8c" name="Collapsed Embedded Subprocess">
<bpmn:startEvent id="Event_0ex1c4k"></bpmn:startEvent>
<bpmn:sequenceFlow id="Flow_1lkyh0w" sourceRef="Event_0ex1c4k" targetRef="Event_1tkfgjp" />
<bpmn:endEvent id="Event_1tkfgjp"></bpmn:endEvent>
</bpmn:subProcess>
<bpmn:sequenceFlow id="Flow_0ncxhf9" sourceRef="Activity_1juds8c" targetRef="Activity_0491dp9" />
<bpmn:subProcess id="Activity_0491dp9" name="Expanded Embedded Subprocess">
<bpmn:startEvent id="Event_0zqe4lt"></bpmn:startEvent>
<bpmn:sequenceFlow id="Flow_123mirk" sourceRef="Event_0zqe4lt" targetRef="Event_1bpeq3v" />
<bpmn:endEvent id="Event_1bpeq3v"></bpmn:endEvent>
</bpmn:subProcess>
<bpmn:sequenceFlow id="Flow_0f1uvb4" sourceRef="Activity_0491dp9" targetRef="Event_0gso4th" />
<bpmn:endEvent id="Event_0gso4th"></bpmn:endEvent>
...
</bpmn:process>
<bpmndi:BPMNDiagram ... >
<bpmndi:BPMNShape id="Activity_0491dp9_di" bpmnElement="Activity_0491dp9" isExpanded="true">
...
</bpmndi:BPMNDiagram>
Call Activities
A call activity references another process, so that one process can be reused in multiple other processes. Currently the PROCEED MS can store processes private (in the users browser storage) and publicly (on the server). Other processes can only be selected as call activity if the referenced process is public.
Reason why only public processes can be selected for call activities...
- if a process is public which references private processes as call activities, other users can't open them and would be confused
- only public processes can be deployed, so we would need to check if every call activity is available on the server
- an option would be to allow private processes reference other private processes, and if the parent process is made public then also transform all referenced processes
- public and private processes are only an intermediate solution until the user mgmt exists
The following code shows how call activities are serialized:
<definitions
xmlns="http://www.omg.org/spec/BPMN/20100524/MODEL"
xmlns:p33c24="https://docs.proceed-labs.org/_17c6fed0-8a8c-4722-a62f-86ebf1324c33"
...
id="_e292e6c4-4d7f-4aff-b91f-c102d5ea4ae8"
name="Global Task Process"
targetNamespace="https://docs.proceed-labs.org/_e292e6c4-4d7f-4aff-b91f-c102d5ea4ae8"
>
<import namespace="https://docs.proceed-labs.org/_17c6fed0-8a8c-4722-a62f-86ebf1324c33" location="_17c6fed0-8a8c-4722-a62f-86ebf1324c33" importType="http://www.omg.org/spec/BPMN/20100524/MODEL">
<process ...>
...
<callActivity id="Task_0ul33bj" name="Call the global process" calledElement="p33c24:Process_1wqd8fv">
...
</callActivity>
...
</process>
</definitions>
- the imported process is not contained within the same BPMN file (not within
<definitions>
, this would be another option) - the
import
element can occur multiple times for multiple processes, but always as the first child element ofdefinitions
(not after<process>
) - the
import
attributenamespace
is thetargetNamespace
of the imported process - a prefix is defined for the namespace of the imported process
- the
import
attributelocation
is thedefinitions id
of the imported BPMN file - the
import
attributeimportType
indicates that the imported file is a BPMN file (static value) - the
callActivity
attributecalledElement
links to the processid
of the imported process
_17c6fed0-8a8c-4722-a62f-86ebf1324c33:
<definitions
xmlns="http://www.omg.org/spec/BPMN/20100524/MODEL"
...
id="_17c6fed0-8a8c-4722-a62f-86ebf1324c33"
name="Imported Other Process"
targetNamespace="https://docs.proceed-labs.org/_17c6fed0-8a8c-4722-a62f-86ebf1324c33"
>
<process id="Process_1wqd8fv" ...>
...
<startEvent id="StartEvent_1">
</startEvent>
...
</process>
</definitions>
Data transfer to and from Call Activities
Attention: this is not BPMN standard conform yet
During runtime, when entering a call activity, the call activity is started as a new process and all process variables of the main process are copied into the new process.
After the called process ends, all variables of this process are copied back into the main process. This may results in a set of updated/overwritten variables, but it can also contain new variables which were created in the call activity itself.
Note that changes to variables, which are performed in the main process in parallel to the call activity execution, do not affect the variables of the latter during its runtime (there is no variable synchonization between a call activity and parallel activities). Depending on which of the parallel activities ends last, the existing variables are overwritten.
What is currently done at the Management System to link a Call Activity
-
at design time: if the link to the global process is created, the modeler does the following:
- sets the
namespace
and adds a XML prefix todefinitions
((p+(last 5 chars from the imported namespace)
) ) - sets the
location
: just the name of the BPMN file (not the folder) - sets
calledElement
- checks if the imported process has exactly one non-typed starting event
- checks for cyclic references, if other call activities exists in the referenced process
- sets the
-
at deployment time:
- checks if there is
<import>
inside definitions - deploys all imported processes and recursive processes to a sub-endpoint under
/imported/{processName}
- deploys all user tasks of imported processes and recursive processes to a sub-endpoint under
/imported/user-tasks/{html-file}
- checks for cyclic references, if other call activities exists in the referenced process
- checks if there is
-
at execution time:
- the referenced process is started with the non-typed start event
Why don't we use another <process>
element inside <definitions>
?
- before deployment we would have to copy the other process and its graphical model into the
<definitions>
element; after an import we would have to split it again into two processes - problem: if we want to start a process, the executor has to select one process of all the available processes inside
<definitions>
. There is no standard way to say which one of all processes is the main one- we could use the
executable
orprocessType
attribute, but this would somehow change the original semantics
- we could use the
Exporting Sub Processes
If a process is exported that contains call activities (other referenced processes), the folder structure of the zip file is as follows:
/PROCEED-Processes_BPMN.zip
- {Process-Name_ABC}/
--- {Process-Name_ABC}.bpmn
--- User-Tasks/
----- {User_Task-Name}.html
----- {User_Task-Name}.html
- {Process-Name_XYZ}/
--- {Process-Name_XYZ}.bpmn
--- User-Tasks/
----- {User_Task-Name}.html
----- {User_Task-Name}.html
Every process is exported with its own folder and its own user tasks.