This page provides an overview of the CMMN 1.0 elements and the current coverage of the process engine.
The elements marked in orange are supported. Hover over the element to see since which version of the Camunda BPM platform they are supported.
Type | Marker | ||||||
---|---|---|---|---|---|---|---|
Planning Table |
|
|
AutoComplete |
|
Required |
Repetition |
|
Case Plan Model |
|
|
|
||||
Stage |
|
|
|
|
|
|
|
Task |
|
|
|
|
|
|
|
Milestone |
|
|
|
||||
EventListener | |||||||
CaseFileItem | |||||||
PlanFragment |
To interact with case instances and executions, the process engine offers the case service. It can be retrieved by processEngine.getCaseService()
.
The CaseService
offers two API variants. One is in the following referred to as the classic API, since it is very similar to the API offered by the RuntimeService
for BPMN processes. The fluent API follows a different concept in that it allows composition of case service commands by method chaining.
As an example, the CaseService
offers two classic methods to manually start a task:
caseService.manuallyStartCaseExecution(caseExecutionId);
Map<String, Object> variables = new HashMap<String, Object>();
variables.put("aVariableToSet", "aValueToSet");
caseService.manuallyStartCaseExecution(caseExecutionId, variables);
The same can be expressed using the fluent API as follows:
caseService
.withCaseExecution(caseExecutionId)
.manualStart();
Map<String, Object> variables = new HashMap<String, Object>();
variables.put("aVariableToSet", "aValueToSet");
caseService
.withCaseExecution(caseExecutionId)
.setVariables(variables)
.manualStart();
In this way, the fluent API is another, fluently readable way of expressing the same functionality. On top, the fluent API, due to its flexibility, allows expression of very specific interactions that the classic API does not offer. For example, the following snippet manually starts a case execution, sets variables and removes another variable in one command (and therefore transaction):
Map<String, Object> variables = new HashMap<String, Object>();
variables.put("aVariableToSet", "aValueToSet");
caseService
.withCaseExecution(caseExecutionId)
.setVariables(variables)
.removeVariable("aVariableToRemove")
.manualStart();
The fluent API can be used to work with case definitions and case executions. The entry points are as follows:
caseService.withCaseDefinition(caseDefinitionId)
: Offers interactions on the case definition that has the provided id, such as creating a new case instance.caseService.withCaseDefinitionByKey(caseDefinitionKey)
: Offers interactions on the case definition that has the latest version of those that have the provided key.caseService.withCaseExecution(caseExecutionId)
: Offers interactions on case executions, such as starting and completing tasks.CMMN differentiates between plan items and plan item definitions. While plan items represent actual units of work that are enacted as part of the case, plan item definitions serve as the blueprint for how a plan item has to be enacted. This concept simplifies reuse of plan item definitions and furthermore enables dynamic planning such that additional items can be generated at runtime from a definition.
As an example, consider the following fragment of a case definition:
<definitions>
<case id="case" name="Case">
<casePlanModel id="CasePlanModel_1">
<planItem id="PlanItem_HumanTask_1" definitionRef="HumanTask_1" />
<planItem id="PlanItem_HumanTask_2" definitionRef="HumanTask_1" />
<humanTask id="HumanTask_1" camunda:assignee="kermit" />
</casePlanModel>
</case>
</defintions>
This model contains one plan item definition, namely the humanTask
element. This definition is referenced by two plan items, PlanItem_HumanTask_1
and PlanItem_HumanTask_2
. When a new case of this model is created, there will be two human task instances, one for each plan item. The plan item definition is the single point at which the human task is configured. Thus, the assignee specification by the attribute camunda:assignee="kermit"
is valid for both plan items.
Accordingly, a case plan model that contains plan item definitions but no plan items will appear as a case with no tasks at runtime.
Apart from reuse of configuration, plan item definitions can be instantiated at runtime, typically referred to as planning. Planning allows users to create plan items of a well-defined set of plan item definitions dynamically as needed. Note that planning is currently not supported by the Camunda engine.
This reference describes, if not otherwise noted, the plan item definitions supported by the Camunda engine. Whenever there is a consideration of runtime state, it is assumed that a plan item referencing that definition exists.
Transitions in a CMMN case can happen in two ways: Either by external interaction or by events occurring and conditions being fulfilled. The former refers to any explicit interaction with a case that is triggered from the outside. For example, a human worker completing a human task would be such an interaction. Completing a task means that the corresponding plan item is completed, depending on the actual case model, the case instance may complete.
Similar changes in the state of a case instance may be driven by events occurring or conditions getting fulfilled. For example, it is possible to define that when one plan item completes, another is enabled. Similarly, a plan item can terminate when an event triggers. When specifying plan items, this concept is referred to as entry criteria and exit criteria. These criteria are always defined for individual plan items, not for plan item definitions. For example, the following case model fragment defines an entry criterion for the plan item PlanItem_HumanTask_1
:
<definitions>
<case id="case" name="Case">
<casePlanModel id="CasePlanModel_1">
<planItem id="PlanItem_HumanTask_1" definitionRef="HumanTask_1" entryCriteriaRefs="Sentry_1" />
<planItem id="PlanItem_HumanTask_2" definitionRef="HumanTask_1"/>
<sentry id="Sentry_1">
<planItemOnPart sourceRef="PlanItem_HumanTask_2">
<standardEvent>complete</standardEvent>
</planItemOnPart>
</sentry>
<humanTask id="HumanTask_1" camunda:assignee="kermit" />
</casePlanModel>
</case>
</defintions>
Similarly, PlanItem_HumanTask_1
with an exit criterion looks as follows:
<planItem id="PlanItem_HumanTask_1" definitionRef="HumanTask_1" exitCriteriaRefs="Sentry_1" />
The conditions and events behind entry and exit criteria can be expressed by so-called sentries. Refer to the Sentry section on how sentries work and what kind of conditions can be expressed by them.
When any entry criterion is met, the plan item it is defined for performs the state transition from AVAILABLE
to ENABLED
. While the plan item is not in state AVAILABLE
, entry criteria are not relevant.
Similarly, when any exit criterion is met, a plan item performs a state transition from any of the states AVAILABE
, ENABLED
, DISABLED
, or ACTIVE
to state TERMINATED
.
The details of plan item states and transitions are provided in the Plan Item Lifecycles section.
CMMN case instances and plan items go through a lifecycle of states during their execution. Depending on their state, different actions may be carried out to interact with them. Moreover, state transitions may automatically trigger changes in other plan items. The concrete lifecycle of a plan item depends on its plan item definition.
The following descriptions cover the CMMN lifecycles as supported by the Camunda engine. This is a subset of states and transitions that the CMMN standard defines. Any state or transition that is currently not supported is marked in grey.
The descriptions in this section are general for the constructs they describe. Considerations that are specific for individual plan item definitions can be found in the respective sections of this guide.
In order to understand the role lifecycles play for CMMN execution, consider the following case:
This case contains two human tasks Task A and Task B that are connected by a sentry. The sentry expresses that Task B can be enacted when Task A finishes. This is formally specified by lifecycles. In our example, the following steps might take place:
caseService.createCaseInstanceByKey("case");
. A new case instance is created in state ACTIVE
.AVAILABLE
.ENABLED
. Note that the steps 1 to 3 all happens synchronously with the caseService
invocation from step 1. The case is now in the following state:caseService.manuallyStartCaseExecution(taskAExecutionId);
. As a consequence, Task A reaches state ACTIVE
and a task instance is added to the assignee's task list. Note that starting a task is only allowed if that task is in state ENABLED
. Thus, trying to manually start Task B here by caseService.manuallyStartCaseExecution(taskBExecutionId);
would fail. The state is now:taskService.complete(taskId);
. Task A reaches the state COMPLETED
.ENABLED
. This happens synchronously in the invocation from step 5. Accordingly, the case's new state is:CaseService
and TaskService
to start Task B, complete the corresponding task instance, and complete Task B. Ultimately, Task B reaches the state COMPLETED
.COMPLETED
, the case instance automatically reaches the state COMPLETED
as well. The state has case has reached the following state:caseService.closeCaseInstance(caseInstanceId);
. The case instance reaches the state CLOSED
.Notice how the lifecycle states define the overall state of the case and restrict the interactions that are possible. For example, the tasks A and B can only be worked on when in state ACTIVE
. Before, they go through states AVAILABLE
and ENABLED
that represent that conditions for working on the task are not yet met, for example that the task was not manually started or that a sentry is not fulfilled yet.
This formal lifecycle model is exposed via the CaseService
API in Camunda. Not only is it possible to trigger state transitions as in the code examples above. By making a case instance or case execution query, the current lifecycles state of a plan items are exposed. For example, the following code gets the state of the plan item for Task A:
CaseExecution caseExecution = caseService.createCaseExecutionQuery().activityId("taskA").singleResult();
caseExecution.isAvailable();
caseExecution.isActive();
caseExecution.isCompleted();
...
Note that a CaseExecution
object corresponds to a plan item, here the plan item for Task A.
Case instance refers to an instance of the case plan model. More specific, it is an instance of the single top-level stage in a case definition. The lifecycle of a case instance is the following:
States:
State | Description |
---|---|
active |
The state active is the initial state when a case is instantiated via the CaseService API. Subsequently, all plan items defined in the case plan model are created and enter the state available.
|
completed |
The transition complete automatically triggers when all plan items contained in the case plan model are completed, terminated, or disabled. Furthermore, it is possible to manually complete a case instance via the CaseService API if it has no active tasks or stages.
|
terminated | The transition terminate automatically triggers when the case instance's exit criteria are fulfilled. |
closed |
A case instance can be manually closed at any time via the CaseService API. This removes the case instance from the runtime database.
|
The lifecycle of a task or stage plan item is the following:
States:
State | Description |
---|---|
available | A task/stage becomes available as soon as the stage it is contained in becomes active. |
enabled | A task or stage becomes enabled as soon as any of its entry criteria is fulfilled. If this is given when a the task/stage becomes available, it immediately becomes enabled or, depending on its manual activation rule, active. |
disabled |
A task or stage can be disabled by using the CaseService API. While an enabled task prevents the containing stage from completion, disabling contained tasks is one way of making a stage completable. Similarly, a disabled task/stage can be re-enabled using the CaseService API.
|
active |
When a task or stage becomes active, its actual work is performed. For a stage, all contained plan items are instantiated. For a task, its actual work is issued, e.g., for a human task, a task instance is created and needs to be worked on by a user. In order for a task or stage to become active, at least one entry criterion has to be fulfilled and it has to be activated. Activation can either be performed manually by a human worker using the CaseService API or by specifying a manual activation rule that evaluates to false .
|
completed | The complete transition triggers for a task when its actual work is done. For a stage, this transition triggers when all contained tasks/stages are either completed, terminated, or disabled. A task/stage in state completed is removed from the runtime database. |
terminated | The exit transition triggers when the task's/stage's exit criteria are met. A task/stage in state terminated is removed from the runtime database. |
The lifecycle of a milestone plan item is the following:
States
State | Description |
---|---|
available | A milestone becomes available as soon as the stage it is contained in becomes active. |
completed | The transition occur automatically triggers when all entry criteria of the milestone are fulfilled. |
A human task is used to model work that needs to be done by a human actor.
A human task is defined in XML as follows:
<humanTask id="theHumanTask" name="A Human Task" />
A human task in state ENABLED
can be started manually using the CaseService
as follows:
caseService.manuallyStartCaseExecution("aCaseExecutionId");
When the human task becomes ACTIVE
, a new task is created in the task list of the user(s) or group(s) assigned to that task.
If the work associated with the human task is done, it is possible to complete the human task manually using the CaseService
as follows:
caseService.completeCaseExecution("aCaseExecutionId");
This completes the created task as well.
Instead of using the CaseService
it is also possible to use the TaskService
to complete a human task:
taskService.complete("aTaskId");
In that case the associated human task is completed as well.
A human task can have a description. In fact, any CMMN 1.0 element can have a description. A description is defined by adding the description
attribute.
<humanTask id="theTask" name="Schedule meeting" description="Schedule an engineering meeting for next week with the new hire" />
The description text can be retrieved from the task in the standard Java way:
task.getDescription();
Each task has a field indicating the due date of that task. The Query API can be used to query for tasks that are due on, before or after a certain date.
There is an extension attribute that allows to specify an expression in a task definition to set the initial due date of a task when it is created. The expression should always resolve to a java.util.Date
, java.util.String
(ISO8601 formatted) or null
. When using ISO8601 formatted Strings, you may either specify an exact point in time or a time period relative to the time the task is created.
<humanTask id="theTask" name="Important task" camunda:dueDate="${dateVariable}"/>
The due date of a task can also be altered using the task service or in task listeners using the passed delegate task.
Each task has a field indicating the follow up date of that task. The Query API can be used to query for tasks that need to be followed up on, before or after a certain date.
There is an extension attribute that allows you to specify an expression in a task definition to set the initial follow up date of a task when it is created. The expression should always resolve to a java.util.Date
, java.util.String
(ISO8601 formatted) or null
. When using ISO8601 formatted Strings, you may either specify an exact point in time or a time period relative to the time the task is created.
<humanTask id="theTask" name="Important task" camunda:followUpDate="${dateVariable}"/>
A human task can be directly assigned to a user. This is done by using the attribute performerRef
on a human task element. The defined performerRef
attribute references an existing role. Such a role definition needs a name that defines the user.
<case ... >
...
<humanTask id="theTask" name='important task' perfomerRef="aCaseRole" />
<caseRoles id="aCaseRole" name="kermit" />
</case>
Only one user can be assigned to the task as a performer. This user is called the assignee. Tasks that have an assignee are not visible in the task lists of other users and can only be found in the personal task list of the assignee.
Tasks directly assigned to users can be retrieved through the task service as follows:
List<Task> tasks = taskService.createTaskQuery().taskAssignee("kermit").list();
When strictly following the CMMN standard, user and group assignments can be quite cumbersome for use cases where the assignment is more complicated. To avoid these complexities, custom extensions on the human task element can be set.
assignee
attribute: this custom extension allows direct assignment of a human task to a given user.
<humanTask id="theTask" name="my task" camunda:assignee="kermit" />
This is exactly the same as using a perfomerRef
construct as defined above.
candidateUsers
attribute: this custom extension makes a user a candidate for a task.
<humanTask id="theTask" name="my task" camunda:candidateUsers="kermit, gonzo" />
candidateGroups
attribute: this custom extension allows makes a group a candidate for a task.
<humanTask id="theTask" name="my task" camunda:candidateGroups="management, accountancy" />
candidateUsers
and candidateGroups
can both be defined for the same human task.
Note: Although the Camunda engine provides an identity management component, which is exposed through the IdentityService
, it does not check whether a provided user is known by the identity component. This allows integration of the engine with existing identity management solutions when it is embedded into an application.
When using Spring or CDI it is possible to use the custom assignment attributes as described in the section above and delegate to a bean with an expression that listens to task create events. In the following example, the assignee will be set by calling the findManagerOfEmployee()
on the ldapService
Spring/CDI bean. The emp
parameter is a variable of the case instance.
<humanTask id="task" name="My Task" camunda:assignee="${ldapService.findManagerForEmployee(emp)}"/>
It works in a similar way for candidate users and groups:
<humanTask id="task" name="My Task" camunda:candidateUsers="${ldapService.findAllSales()}"/>
Note that this only works if the return type of the invoked methods is String or Collection
public class FakeLdapService {
public String findManagerForEmployee(String employee) {
return "Kermit The Frog";
}
public List<String> findAllSales() {
return Arrays.asList("kermit", "gonzo", "fozzie");
}
}
It is possible to provide information to render a human task form by using the camunda:formKey
attribute:
<humanTask id="someTask" camunda:formKey="someForm.html">
...
</humanTask>
The form key is a symbolic value which can be set in the CMMN XML file by using the extension
attribute formKey
and retrieved at runtime using the process engine API.
If the user task form is displayed inside the Camunda Tasklist, the format of the formKey must follow special rules. See the corresponding section in the user guide for details.
In custom applications, the value of the form key can be chosen freely. In a custom application the value of the form key attribute can be interpreted freely. Based on the specific UI technology used, it can reference the name of an HTML file, a JSF / Facelets template, a Vaadin / GWT view, ...
String formKey = formService.getTaskFormData(someTaskId).getFormKey();
When performing a task query, it is possible to retrieve the form key as well. This is most useful if the form keys need to be retrieved for a complete list of tasks:
List<Task> tasks = TaskService.createTaskQuery()
.assignee("jonny")
.initializeFormKeys() // must be invoked
.list();
for(Task task : tasks) {
String formKey = task.getFormKey();
}
Note that it is required to call the .initializeFormKeys()
method on the TaskQuery
object to
make sure the form keys are initialized.
Attributes | camunda:assignee, camunda:candidateGroups, camunda:candidateUsers, camunda:dueDate, camunda:formKey, camunda:priority |
---|---|
Extension Elements | camunda:in, camunda:out, camunda:caseExecutionListener, camunda:taskListener, camunda:variableListener |
Constraints |
The attribute camunda:assignee cannot be used simultaneously with the perfomerRef
attribute on a human task element.
|
A process task can be used to invoke a BPMN 2.0 process from a case.
A process task is a regular task that requires an attribute processRef
which references a process definition by its key. Such a process task can be defined as follows:
<processTask id="checkCreditProcess" name="Check credit" processRef="checkCreditProcess" />
The referenced process definition is resolved at runtime. This means that the process can be deployed independently from the calling case, if needed.
A process task in state ENABLED
can be started manually using the CaseService
as follows:
caseService.manuallyStartCaseExecution("aCaseExecutionId");
When the process task instance becomes ACTIVE
, a new process instance is launched. In the above example a new process instance of the process checkCreditProcess
is created.
If a process task is blocking (i.e., the attribute isBlocking
is set to true
), the process task remains ACTIVE
until the process instance associated with the process task is completed. After a successful completion of the called process instance, the corresponding process task completes automatically. It is not possible to complete a blocking process task manually.
In case of a non-blocking (the attribute isBlocking
is set to false
) task, the process task is not waiting for the process instance to complete and completes immediately after its activation and calling its associated process.
Note: The default value for the attribute isBlocking
is true
. To define a non-blocking
process task the attribute isBlocking
must be set to false
as follows:
<processTask id="checkCreditProcess" name="Check credit" processRef="checkCreditProcess" isBlocking="false" />
The activation of the process task as well as the creation and execution of the process instance are performed in the same transaction. The transaction is executed until a wait state or an asynchronous continuation is reached inside the called process instance (for further details read the Transactions in Processes section of the user guide). To launch a process instance asynchronously it is possible to declare the process' start event as asynchronous with the XML attribute asyncBefore="true"
(see Asynchronous Instantiation).
By default, the process task creates a new process instance of the latest process definition with the specified key. In order to specify a different version of a process, it is possible to define a binding with the Camunda custom attribute processBinding
. The following values are allowed for the attribute processBinding
:
latest
: use the latest process definition version (which is also the default behavior if the attribute is not defined)deployment
: use the process definition version that is part of the calling case definition's deployment (note: this requires that a process with the specified key is deployed along with the case definition)version
: use a fixed version of the process definition, in this case the attribute processVersion
is requiredThe following is an example of a process task that calls the checkCreditProcess
process with version 3.
<processTask id="checkCreditProcess" processRef="checkCreditProcess"
camunda:processBinding="version"
camunda:processVersion="3">
</processTask>
Note: It is also possible to use an expression for the attribute processVersion
that must resolve to an integer when the task is executed.
The Camunda custom extensions elements in
and out
allow to exchange variables between the process task (in a case instance) and the process instance that it creates: in
elements of a process task map case variables to input variables of the launched process instance and out
mappings of a process task map output variables of the process instance to case variables, e.g.,
<processTask id="checkCreditProcess" name="Check credit" processRef="checkCreditProcess">
<extensionElements>
<camunda:in source="aCaseVariable" target="aProcessVariable" />
<camunda:out source="aProcessVariable" target="anotherCaseVariable" />
</extensionElements>
</processTask>
In the above example, the value of the input variable aCaseVariable
is passed to the newly created process instance. Inside the process instance, the value of the input variable aCaseVariable
is available as aProcessVariable
. After successful completion of the called process instance, the value of the output variable aProcessVariable
is passed back to the calling process task where it can be accessed by the name anotherCaseVariable
.
In addition, it is possible to use expressions:
<processTask id="checkCreditProcess" name="Check credit" processRef="checkCreditProcess">
<extensionElements>
<camunda:in sourceExpression="${x+5}" target="y" />
<camunda:out sourceExpression="${y+5}" target="z" />
</extensionElements>
</processTask>
Assuming y
is not updated by the process instance, the following holds after the process task completes: z = y+5 = x+5+5
.
Source expressions are evaluated in the context of the called process instance. That means, in cases where calling and called case/process definition belong to different process applications, context like Java classes, Spring or CDI beans is resolved from the process application the called process definition belongs to.
Furthermore, the process task can be configured to pass all variables to the called process instance and to pass all variables of the process instance back to the associated process task:
<processTask id="checkCreditProcess" name="Check credit" processRef="checkCreditProcess">
<extensionElements>
<camunda:in variables="all" />
<camunda:out variables="all" />
</extensionElements>
</processTask>
Note: The variables keep their names.
In addition to exchanging variables, it is possible to pass a business key to the called process instance. Since a business key is immutable, this is one way mapping. It is not possible to have output mapping for a business key.
The following example shows how the business key of the calling case instance can be passed to the called process instance. In this case, the calling case instance and the called process instance end up with the same business key.
<processTask id="checkCreditProcess" name="Check credit" processRef="checkCreditProcess">
<extensionElements>
<camunda:in businessKey="#{caseExecution.caseBusinessKey}" />
</extensionElements>
</processTask>
If the business key of the called process instance should be different than the business key of the calling case instance, it is possible to use an expression that, for example, references a variable:
<processTask id="checkCreditProcess" name="Check credit" processRef="checkCreditProcess">
<extensionElements>
<camunda:in businessKey="#{customerId}" />
</extensionElements>
</processTask>
Attributes | camunda:processBinding, camunda:processVersion |
---|---|
Extension Elements | camunda:in, camunda:out, camunda:caseExecutionListener, camunda:variableListener |
Constraints |
The attribute camunda:processVersion should only be set if
the attribute camunda:processBinding is equal to version
|
A case task can be used to call another CMMN 1.0 case.
A case task is a regular task that requires a caseRef
attribute that references a case definition by its key. Such a case task can be defined as follows:
<caseTask id="checkCreditCase" name="Check credit" caseRef="checkCreditCase" />
The referenced case definition is resolved at runtime. This means that the referenced case can be deployed independently from the calling case, if needed.
A case task in state ENABLED
can be started manually using the CaseService
as follows:
caseService.manuallyStartCaseExecution("aCaseExecutionId");
When the case task instance becomes ACTIVE
, a new case instance will be launched. In the above example a new case instance of the case checkCreditCase
will be created.
If a case task is blocking (the attribute isBlocking
is set to true
), the case task remains ACTIVE
until the case instance associated with the case task is completed. When the called case instance reaches the state COMPLETED
for the first time, the corresponding case task completes automatically. It is not possible to complete a blocking case task manually.
In case of a non-blocking (the attribute isBlocking
is set to false
) task, the case task does not wait for the case instance to complete, and completes immediately upon its activation and after calling its associated case.
Note: The default value for the attribute isBlocking
is true
. To define a non-blocking case task the attribute isBlocking
must be set to false
as follows:
<caseTask id="checkCreditCase" name="Check credit" caseRef="checkCreditCase" isBlocking="false" />
The activation of the case task as well as the creation and execution of the case instance are performed in the same transaction.
By default, the case task always creates a new case instance of the latest case definition with the specified key. In order to specify a different version of a case, it is possible to define a binding with the Camunda custom attribute caseBinding
. The following values are allowed for the attribute caseBinding
:
latest
: use the latest case definition version (which is also the default behavior if the attribute is not defined)deployment
: use the case definition version that is part of the calling case definition's deployment (note: this requires that a case with the specified key is deployed along with the calling case definition)version
: use a fixed version of the case definition, in this case the attribute caseVersion
is requiredThe following is an example of a case task that calls the checkCreditCase
case with version 3.
<caseTask id="checkCreditCase" caseRef="checkCreditCase"
camunda:caseBinding="latest|deployment|version"
camunda:caseVersion="3">
</caseTask>
Note: It is also possible to use an expression for the attribute caseVersion
that must resolve to an integer at runtime.
The Camunda custom extensions elements in
and out
allow to exchange variables between the case task (in a case instance) and the case instance that it creates: in
elements of a case task map variables of the calling case to input variables of the launched case instance and out
mappings of a case task map output variables of the called case instance to variables of the calling case, e.g.,
<caseTask id="checkCreditCase" name="Check credit" caseRef="checkCreditCase">
<extensionElements>
<camunda:in source="aCaseVariable" target="aSubCaseVariable" />
<camunda:out source="aSubCaseVariable" target="anotherCaseVariable" />
</extensionElements>
</caseTask>
In the above example, the value of the input variable aCaseVariable
is passed to the newly created case instance. Inside the case instance, the value of the input variable aCaseVariable
is available as aSubCaseVariable
. After successful completion of the called case instance, the value of the output variable aSubCaseVariable
is passed back to the calling case task where it can be accessed by the name anotherCaseVariable
.
In addition, it is also possible to use expressions:
<caseTask id="checkCreditCase" name="Check credit" caseRef="checkCreditCase">
<extensionElements>
<camunda:in sourceExpression="${x+5}" target="y" />
<camunda:out sourceExpression="${y+5}" target="z" />
</extensionElements>
</caseTask>
Assuming y
is not updated by the called case instance, the following holds after the case task completes: z = y+5 = x+5+5
.
Source expressions are evaluated in the context of the called case instance. That means, in cases where calling and called case definition belong to different process applications, context like Java classes, Spring or CDI beans is resolved from the process application the called case definition belongs to.
Furthermore, the case task can be configured to pass all variables to the called case instance, and to pass all variables of the case instance back to the associated case task:
<caseTask id="checkCreditCase" name="Check credit" caseRef="checkCreditCase">
<extensionElements>
<camunda:in variables="all" />
<camunda:out variables="all" />
</extensionElements>
</caseTask>
Note: The variables keeps their names.
In addition to exchanging variables, it is possible to pass a business key to the called case instance as well. Since a business key is immutable, this is one way mapping. It is not possible to have output mapping for a business key.
The following example shows how the business key of the calling case instance can be passed to the called case instance. In this case, the calling case instance and the called case instance end up with the same business key.
<caseTask id="checkCreditCase" name="Check credit" caseRef="checkCreditCase">
<extensionElements>
<camunda:in businessKey="#{caseExecution.caseBusinessKey}" />
</extensionElements>
</caseTask>
If the business key of the called case instance should be different from the business key of the calling case instance, it is possible to use an expression that, for example, references a variable:
<caseTask id="checkCreditCase" name="Check credit" caseRef="checkCreditCase">
<extensionElements>
<camunda:in businessKey="#{customerId}" />
</extensionElements>
</caseTask>
Attributes | camunda:caseBinding, camunda:caseVersion |
---|---|
Extension Elements | camunda:in, camunda:out, camunda:caseExecutionListener, camunda:variableListener |
Constraints |
The attribute camunda:caseVersion should only be set if
the attribute camunda:caseBinding equals version
|
A stage can contain other plan items like a human task, a process task, a case task or another stage. Stages may be considered 'episodes' of a case. However, stages are not necessarily planned sequentially but can also be active in parallel.
If a stage is collapsed, only its name and a plus sign are displayed:
If a stage is expanded, its plan items are displayed within its boundaries:
A stage is defined in XML as follows:
<stage id="checkCredit">
<!-- plan items -->
<planItem id="PI_checkSolvency" definitionRef="checkSolvency" />
<planItem id="PI_calculateCredit" definitionRef="calculateCredit" />
<planItem id="PI_calculateHousekeepingBill" definitionRef="calculateHousekeepingBill" />
</stage>
Furthermore, a case always refers to one stage as its case plan model. The case plan model defines the outermost stage of the case. This outermost stage also contains all plan item definitions that are used in the case.
<case>
<casePlanModel>
<!-- plan items -->
<planItem id="PI_checkCredit" definitionRef="checkCredit" />
<!-- plan item definitions -->
<humanTask id="checkSolvency" name="Check Solvency" />
<humanTask id="calculateCredit" name="Calculate Credit" />
<humanTask id="calculateHousekeepingBill" name="Calculate Hausekeeping Bill" />
<stage id="checkCredit">
<!-- plan items -->
<planItem id="PI_checkSolvency" definitionRef="checkSolvency" />
<planItem id="PI_calculateCredit" definitionRef="calculateCredit" />
<planItem id="PI_calculateHousekeepingBill" definitionRef="calculateHousekeepingBill" />
</stage>
</casePlanModel>
</case>
Note: The listed plan item definitions inside the casePlanModel
are referenced by plan items in the case plan model itself (i.e., stage), as well as by plan items in nested stages. Plan item definitions must not be contained by any other stage than the case plan model.
A stage in state ENABLED
can be started manually using the CaseService
as follows:
caseService.manuallyStartCaseExecution("aCaseExecutionId");
When the stage becomes ACTIVE
, the contained plan items are instantiated and reach the state AVAILABLE
. A stage in this state always contains at least one stage or task instance in the state AVAILABLE
, ENABLED
, or ACTIVE
. In other words, a stage completes automatically if a user has no option to do further work on its contained plan items. This means that if a contained plan item completes or is disabled, the stage is notified about that state transition and checks if it is able to complete. A stage instance can only complete if there are no contained plan items in the state ACTIVE
, and all are either in state DISABLED
or COMPLETED
. In case the check succeeds, the stage instance completes.
Extension Elements | camunda:caseExecutionListener, camunda:variableListener |
---|
A milestone is used to represent achievable targets within the case. It is not associated with any work but rather marks that certain conditions have been reached within the case. As a milestone is a regular plan item definition, a milestone's completion may be used as entry criteria for other tasks and stages. This way, a milestone can be used to bring logical stages within a case into order.
In XML, a milestone is defined as follows:
<milestone id="theMilestone" name="A Milestone"/>
When referenced in a case plan, a milestone gets completed as soon as its entry criteria are fulfilled. This requires no human interaction. A more complete example of a milestone depending on the completion of a human task is the following:
<definitions>
<case id="case" name="Case">
<casePlanModel id="CasePlanModel_1">
<planItem id="PlanItem_HumanTask" definitionRef="HumanTask_1"/>
<planItem id="PlanItem_Milestone" definitionRef="Milestone_1" entryCriteriaRefs="Sentry_1"/>
<sentry id="Sentry_1">
<planItemOnPart sourceRef="PlanItem_HumanTask">
<standardEvent>complete</standardEvent>
</planItemOnPart>
</sentry>
<humanTask id="HumanTask_1" />
<milestone id="Milestone_1" name="A Milestone" />
</casePlanModel>
</case>
</defintions>
In this case, the milestone will complete as soon as as the human task completes.
A milestone cannot have exit criteria.
Always define Milestones with Entry Criteria
A milestone without entry criteria is fulfilled as soon as the stage it is contained in becomes active. For example, a milestone item that is defined on the case definition level is completed as soon as the case is instantiated. It is therefore advisable to define at least one entry criterion for a milestone plan item.
In order to check whether a milestone has occurred, the history service can be used. The following checks the state of a milestone instance:
HistoricCaseActivityInstance milestoneInstance = historyService
.createHistoricCaseActivityInstanceQuery()
.caseInstanceId("aCaseInstanceId")
.caseActivityId("theMilestone")
.singleResult();
milestoneInstance.isCompleted(); // true if milestone occurred
Extension Elements | camunda:caseExecutionListener |
---|
A sentry captures the occurrence of a certain event occurring or a condition being fulfilled within a case. Sentries are used as entry and exit criteria. Note that the black and white diamonds represent the criteria. A sentry itself has no graphical representation.
In XML, a sentry can be specified as follows:
<planItem id="PlanItem_HumanTask_1" definitionRef="HumanTask_1"/>
<planItem id="PlanItem_HumanTask_2" definitionRef="HumanTask_1" entryCriteriaRefs="Sentry_1" />
<sentry id="Sentry_1">
<planItemOnPart sourceRef="PlanItem_HumanTask_1">
<standardEvent>complete</standardEvent>
</planItemOnPart>
<ifPart>
<condition>
<body>${myVar > 100}</body>
</condition>
</ifPart>
</sentry>
<humanTask id="HumanTask_1"/>
The above example defines a sentry that is fulfilled when the plan item PlanItem_HumanTask_1
performs the state transition complete
(note the planItemOnPart
element) and a variable named myVar
has a value greater than 100 (note the ifPart
element). Furthermore, it serves as an entry criterion for the plan item PlanItem_HumanTask_2
that becomes ENABLED
as soon as the sentry is fulfilled (note the entryCriteriaRefs
attribute of the element PlanItem_HumanTask_2
).
As conditions or event triggers, sentries may define the following elements:
OnParts are defined on lifecycle transitions for plan items or case file items. As the Camunda engine does not currently support case file items, it is only possible to use plan item OnParts. A sentry with an OnPart can be defined as follows:
<sentry id="Sentry_1">
<planItemOnPart sourceRef="PlanItem_1">
<standardEvent>complete</standardEvent>
</planItemOnPart>
</sentry>
A planItemOnPart
must always reference a plan item by the attribute sourceRef
. This plan item must be contained by the same stage the sentry is defined in. The child element standardEvent
can the identifier of any lifecycle transition from that plan item's lifecycle and that is supported by the camunda engine. Note that different plan item definitions define different lifecycles. For details on valid lifecycle transitions, see the Lifecycles section.
As an alternative to sourceRef
, the CMMN specification allows to define an attribute sentryRef
responsible for referencing another sentry such that the onPart is fulfilled when the plan item that sentry references performs the exit state transition. This attribute is currently not supported by the Camunda engine.
Note that it is possible to have any number of OnParts which allows to combine multiple events. All OnParts must be fulfilled for a sentry to occur, i.e., specifying multiple OnParts is a conjunction of multiple events. An OnPart is fulfilled as soon as the element it is defined on performs the specified lifecycle transition. It is irrelevant whether this element performs any other subsequent lifecycle transitions.
An IfPart defines an additional condition that is checked when all OnParts of the sentry are fulfilled. Only if the IfPart evaluates to true
, the sentry is fulfilled. In Camunda, a sentry with an IfPart looks as follows:
<sentry id="Sentry_1">
<ifPart>
<condition>
<body>${myVar > 100}</body>
</condition>
</ifPart>
</sentry>
A sentry can have at most one IfPart and that IfPart can have at most one condition
element. In the condition
element, expression language must be used. In such an expression, case variables can be accessed by their name. The above example defines a condition that evaluates to true
if there is a variable named myVar
and that variable's value is greater than 100.
In addition to variable names, the identifier caseExecution
can be used to access the execution object for the stage that the sentry is defined in. The below example explicitly accesses a local variable of that execution:
<sentry id="Sentry_1">
<ifPart>
<condition>
<body>${caseExecution.getVariableLocal("myVar") > 100}</body>
</condition>
</ifPart>
</sentry>
The CMMN specification allows to reference a case file item by the sentry attribute contextRef
. This attribute is not supported by the Camunda engine and therefore ignored.
The engine evaluates IfParts at every lifecycle transition of a plan item contained in the sentry's stage. That means, if an IfPart is not satisfied immediately when all OnParts have occurred, the sentry may still occur at any later lifecycle transition.
Sentries allow a flexible definition of event occurrences and data-based conditions to be fulfilled. The following rules apply for combining OnParts and IfParts
true
.There are no custom Camunda extensions for sentries.
Whether the actual work of a task or stage can be performed depends on its entry criteria. Given that an entry criterion is fulfilled, there are two ways to activate a task:
Manual activation is the default behavior in which it is required that a user manually activates a task. In camunda, this can be done by using the CaseService
API with caseService.manuallyStartCaseExecution(caseExecutionId)
. By specifying a manual activation rule, it is possible to omit this step or make it depend on case variable payload. With manual activation, a user can decide to activate a task or instead disable it. A task that is automatically activated must be carried out.
In XML, a manual activation rule can be specified as follows:
<planItem id="PlanItem_HumanTask_1" definitionRef="HumanTask_1"/>
<humanTask id="HumanTask_1">
<defaultControl>
<manualActivationRule>
<condition>
<body>${false}</body>
</condition>
</manualActivationRule>
</defaultControl>
</humanTask>
The rule specified in the humanTask
element is valid for all plan items that reference it, here PlanItem_HumanTask_1
. The specified expression ${false}
evaluates to the boolean value false
and means that the plan item should become active in any case without human intervention. As with any expression, you can use case variables to determine the result. The following snippet expresses that manual activation is required when a variable var
has a value greater than 100:
<manualActivationRule>
<condition>
<body>${var > 100}</body>
</condition>
</manualActivationRule>
Tricky Specification
Manual activation is the default behavior. Thus, by specifying the element manualActivationRule
you can express exceptions from that default for cases in which a task does not need manual activation.
In terms of the task/stage lifecycle, manual activation corresponds to the transition from AVAILABLE
to ENABLED
when an entry criterion occurs, and from ENABLED
to ACTIVE
when the task is manually activated. In contrast, automatic activation corresponds to the direct transition from AVAILABLE
to ACTIVE
that fires immediately when an entry criterion occurs.
It is also possible to define manual activation rules for individual plan items instead of plan item definitions. This is currently not supported by the Camunda engine.
The following elements are extension elements for the camunda
namespace http://camunda.org/schema/1.0/cmmn
.
Description | Add an execution listener to an event in the lifecycle of a case item. | |
---|---|---|
Attributes | event |
The type of the lifecycle event for which the listener is called |
class |
see camunda:class | |
expression |
see camunda:expression | |
delegateExpression |
see camunda:delegateExpression | |
Constraints |
The event attribute is required and must be one of the lifecycle events that are valid for the plan item it is defined on. For regular tasks, these are: create , enable , disable , reenable , start , manualStart , complete , reactivate , terminate , exit parentTerminate, suspend , resume , parentSuspend , parentSuspend , close , occur
|
|
One of the attributes class , expression or delegateExpression is mandatory
|
||
Parent elements | Case, Human Task, Process Task, Case Task, Stage, Milestone, | |
Child elements | camunda:field, camunda:script |
Description | Defines an expression to inject in delegated classes (see Field Injection). | |
---|---|---|
Attributes | – | |
Text Content | The expression to inject | |
Constraints | – | |
Parent elements | camunda:field | |
Child elements | – |
Description | Defines the value to inject in delegated classes (see Field Injection). | |
---|---|---|
Attributes | name |
The name of the field |
expression |
The value of the field as expression | |
stringValue |
The value of the field as String | |
Constraints |
Only one attribute of stringValue and expression or one of the child elements string and expression can be used
|
|
Parent elements | camunda:variableListener, camunda:caseExecutionListener | |
Child elements | camunda:expression, camunda:string |
Description | This element specifies variables which should be passed to the sub instance (process instance or case instance), see passing variables to called process or passing variables to called case for more information. | |
---|---|---|
Attributes | source |
A name of a variable to be passed in |
sourceExpression |
An expression to be evaluated and passed in | |
variables |
Can be set to all to pass all variables in
|
|
target |
Name of the variable inside the sub instance | |
businessKey |
Set the business key of the sub instance | |
Constraints |
Only one of the attributes source , sourceExpression , variables or businessKey can be used
|
|
The attribute target is required if the source or sourceExpression attribute is used
|
||
Parent elements | Process Task, Case Task | |
Child elements | – |
Description | This element specifies variables which should be passed back from the sub instance (process instance or case instance), see passing variables to called process or passing variables to called case for more information. | |
---|---|---|
Attributes | source |
A name of a variable to be passed back |
sourceExpression |
An expression to be evaluated and passed back | |
variables |
Can be set to all to pass all sub instance variables back
|
|
target |
Name of the variable inside the calling case instance | |
Constraints |
Only one of the attributes source , sourceExpression , variables or businessKey can be used
|
|
The attribute target is required if the source or sourceExpression attribute is used
|
||
Parent elements | Process Task, Case Task | |
Child elements | – |
Description | A script element. The script is executed and the return value is used as mapping value. | |
---|---|---|
Attributes | scriptFormat |
The format identifier, normally the language of the script source code |
resource |
equivalent to camunda:resource | |
Constraints |
The scriptFormat attribute is required
|
If the resource attribute is used, no source code text content is allowed
|
Parent elements | camunda:variableListener, camunda:caseExecutionListener | |
Child elements | – |
Description | Defines a String value to inject in delegated classes (see Field Injection). | |
---|---|---|
Attributes | – | |
Text Content | The String value to inject | |
Constraints | – | |
Parent elements | camunda:field | |
Child elements | – |
Description | Add a task listener to a task event. | |
---|---|---|
Attributes | event |
The type of the event for which the listener is called |
class |
see camunda:class | |
expression |
see camunda:expression | |
delegateExpression |
see camunda:delegateExpression | |
Constraints |
The event attribute is required and must be one of the task events: create , assignment , complete or delete
|
|
One of the attributes class , expression or delegateExpression is mandatory
|
||
Parent elements | Human Task | |
Child elements | camunda:field, camunda:script |
Description | Adds custom code to listen to variable events such as the creation, update or deletion of a variable. A listener defined on a model scope (like the case plan model, a human task, etc.) is notified for all variable events that occur in this scope or any of its subordinate scopes. | |
---|---|---|
Attributes | event |
The type of the event for which the listener is called |
class |
see camunda:class | |
expression |
see camunda:expression | |
delegateExpression |
see camunda:delegateExpression | |
Constraints |
Valid values for the event attribute are create , update and delete . This attribute is optional and if left out, the listener is notified for all kinds of events.
|
|
Either one of the attributes class , expression or delegateExpression , or a camunda:script child element is mandatory.
|
||
Parent elements | Case Plan Model, Stage, Human Task, Process Task, Case Task | |
Child elements | camunda:field, camunda:script |
The following attributes are extension attributes for the camunda
namespace http://camunda.org/schema/1.0/cmmn
.
Description | This attribute specifies a performer of a Human Task. |
---|---|
Type | java.lang.String or org.camunda.bpm.engine.delegate.Expression |
Possible Values |
The name of a performer as java.lang.String or an expression which evaluates to a java.lang.String e.g. ${perfomer}
|
Default Value | – |
CMMN 1.0 Elements | Human Task |
Description | This attribute specifies which group(s) will be candidate for performing the Human Task. |
---|---|
Type | java.lang.String or org.camunda.bpm.engine.delegate.Expression |
Possible Values |
Comma separated list of group ids as java.lang.String or expressions that evaluate to a java.lang.String or a java.util.Collection of java.lang.String , e.g. management or management, ${accountancyGroupId()}
|
Default Value | – |
CMMN 1.0 Elements | Human Task |
Description | This attribute specifies which user(s) will be candidate for performing the Human Task. |
---|---|
Type | java.lang.String or org.camunda.bpm.engine.delegate.Expression |
Possible Values |
Comma separated list of user ids as java.lang.String or expressions that evaluate to a java.lang.String or a java.util.Collection of java.lang.String , e.g. kermit, gonzo or ${ldapService.findAllSales()}
|
Default Value | – |
CMMN 1.0 Elements | Human Task |
Description | This attribute specifies which case definition version should be called inside the case task. | |
---|---|---|
Type | java.lang.String |
|
Possible Values |
latest , deployment , version
|
|
Constraints |
If the value is set to version the attribute camunda:caseVersion is required, see Case Binding for more information.
|
|
Default Value | – | |
CMMN 1.0 Elements | Case Task |
Description | This attribute explicitly defines which case definition version should be called inside the case task. |
---|---|
Type | java.lang.Integer or org.camunda.bpm.engine.delegate.Expression |
Possible Values |
All deployed version numbers of the case definition to call or an expression which evaluates to a java.lang.Integer
|
Default Value | – |
CMMN 1.0 Elements | Case Task |
Description | The attribute specifies which Java class will be executed at runtime. The stated class must implement a Java delegate interface. |
---|---|
Type | java.lang.String |
Possible Values |
Fully qualified Java class name of a class which implements a Java Delegate interface, e.g org.camunda.bpm.MyJavaDelegate
|
Default Value | – |
CMMN 1.0 Elements | camunda:variableListener, camunda:caseExecutionListener |
Description | The attribute allows specification of an expression which must resolve to an object that implements the corresponding interface (see delegation code). |
---|---|
Type | org.camunda.bpm.engine.delegate.Expression |
Possible Values |
Expression which evaluates to a Java class implementing a delegation interface, e.g. ${myVariableListener} .
|
Default Value | – |
CMMN 1.0 Elements | camunda:variableListener, camunda:caseExecutionListener |
Description | This attribute specifies the initial due date of a Human Task when it is created. |
---|---|
Type | org.camunda.bpm.engine.delegate.Expression |
Possible Values |
An expression which evaluates to a java.util.Date , java.util.String (ISO 8601 formatted) or null , e.g. ${dueDate}
|
Default Value | – |
CMMN 1.0 Elements | Human Task |
Description | The attribute defines an expression which will be evaluated at runtime. |
---|---|
Type | org.camunda.bpm.engine.delegate.Expression |
Possible Values |
Expression, e.g. ${gender == 'male' ? 'Mr.' : 'Mrs.'} or #{printer.printMessage()}
|
Default Value | – |
CMMN 1.0 Elements | camunda:variableListener, camunda:caseExecutionListener |
Description | This attribute specifies a form resource. See task forms for more information. |
---|---|
Type | java.lang.String |
Possible Values |
A java.lang.String of a form resource which can be evaluated by the Tasklist
|
Default Value | – |
CMMN 1.0 Elements | Human Task |
Description | This attribute specifies the initial priority of a Human Task when it is created. |
---|---|
Type | org.camunda.bpm.engine.delegate.Expression |
Possible Values |
An expression which evaluates to a java.lang.Number or a java.lang.String which represents a number or null , e.g. ${priority}
|
Default Value | – |
CMMN 1.0 Elements | Human Task |
Description | This attribute specifies which process definition version should be called inside the process task. | |
---|---|---|
Type | java.lang.String |
|
Possible Values |
latest , deployment , version
|
|
Constraints |
If the value is set to version the attribute camunda:processVersion is required, see Process Binding for more information.
|
|
Default Value | – | |
CMMN 1.0 Elements | Process Task |
Description | This attribute explicitly defines which process definition version should be called inside the process task. |
---|---|
Type | java.lang.Integer or org.camunda.bpm.engine.delegate.Expression |
Possible Values |
All deployed version numbers of the process definition to call or an expression which evaluates to a java.lang.Integer
|
Default Value | – |
CMMN 1.0 Elements | Process Task |
Description |
The attribute specifies an external resource. The resource can be part of the deployment or
exists in the classpath. To specify the type of resource, a URL scheme like prefix
deployment:// resp. classpath:// can be supplied. If the scheme is
omitted, it is assumed that the resource exists in the classpath.
|
---|---|
Type | java.lang.String or org.camunda.bpm.engine.delegate.Expression |
Possible Values |
The path to a resource or an expression which returns the path. Optional the path can
start with an URL like scheme classpath:// or deployment:// to
specify where to find the resource. If omitted the resource is assumed to exists in the
classpath.
|
Default Value | – |
CMMN 1.0 Elements | camunda:variableListener, camunda:caseExecutionListener |