Camunda BPM: User Task Assignment based on a DMN Decision Table

In business processes involving human workflow the task assignment logic can become quite elaborate. For instance the processing of insurance claims, or other variants of approval processes, may require many or complex task assignment rules. The Decision Model and Notation (DMN) decision tables are an excellent tool to manage such rules — outside of code, in a business user-friendly way.

Camunda Release 7.13.0 will ship in Early June with the FEEL Scala Engine,
which already supports the DMN standard version 1.3, released in March 2020. Friendly Enough Expression Language (FEEL) expressions now allow us a more elegant mapping between decision table results and task assignment parameters.

Example Process

This example uses a trivial BPMN Process consisting of a business rule task, implemented by a DMN file, and a user task, which gets assigned based on the output variables of the rules task. The data object reference shown in the diagram is only for documentation purposes. It has no technical implications and can be removed.

Process with Business Rule Task and User Task

User Task

A Camunda User Task has three parameters relevant to task assignment:

  • assignee (a specific user who must perform the task)
  • candidate users (a list of specific users who can perform a task)
  • candidate groups (a list of user groups who can perform the task)

In this example these parameters get bound to a process variable using ${variable_name}. This allows us to let the task assignment depend on the output of previous elements (here the business rule task).

User Task Details: Assignee, Candidate Users, Candidate groups

Decision Table

The example DMN file uses three product attributes as input to determine the task assignment. The Hit Policy is set to Collect because the intention is to evaluate all rules and create lists of all possible task assignments. (The task assignment logic will later automatically assign the task to an individual user in case a specific assignee is set by a rule.)

Example DMN Table for Task Assignment

Business Rule Task

Due to the hit policy (C) the result will be a list of rules (rows) which fire for a given instance. As the decision table produces several outputs (columns) each item in the result list will contain a collection of up to three values (assignee, candidateUsers, candidateGroups). In the properties tab of the business rule task, the decision result needs to be set to reflect this expected data structure (a List of collections), as shown below. The result variable name, here dmnResult, can be chosen freely. The variable name is subsequently used in the mapping expressions.

Setting Business Rule Task Properties to store the Result

The final step is to map the output of the business rule task to the three variables used for the task assignment. This can be done on the “Input/Output” properties tab of the business rule task using feel scripts.

To determine the list of candidate users / candidate user groups we:

  • go through list of results (rows), picking the “candidateUsers” / “candidateGroups” value from each row
  • filter empty entries from the resulting list
    • (for r in dmnResult return get value(r, “candidateUsers”))[item != null]
    • (for r in dmnResult return get value(r, “candidateGroups”))[item != null]

To determine the assignee we:

  • go through list of results (rows), picking the “assignee” value from each row
  • filter empty values from the resulting list
  • pick the first assignee in the list (assignee can only be one value, not a list)
    • ((for r in dmnResult return get value(r, “assignee”))[item != null])[1]

Mapping of DMN result to process variables on the Business Rule Task

Value Mapper Configuration

CustomValueMapper registration in META-INFservices

For this approach to work, as of version 7.13.0-alpha4, Camunda still requires the registration of a customer value mapper. The mapper is registered by placing a text file called org.camunda.feel.valuemapper.CustomValueMapper
with the content: org.camunda.feel.impl.JavaValueMapper
into the folder: _METAINF/services.
This step will likely no longer be required in newer versions.

Unit and manual Tests

The project can be Unit tested as shown in AssignmentTest.java in a few tests for different task assignments. You can run it in your IDE or using mvn clean test.

To step through the process manually, you can start the server using your IDE or mvn spring-boot:run. After the server has started you can access the Camunda tasklist via https://localhost:8080/app/tasklist/default. Use the credentials demo / demo to login.

The complete example project is available on Github:
camunda-consulting/code

Credits and many thanks to Philipp Ossler for developing the Feel engine and teaching me about the available FEEL expressions.

Want to learn more? Check out this blog for a better understanding of how FEEL 1.2 integrates with Camunda BPM and test it out with a complete example prepackaged as a Spring Boot application.

  • Is there an alternative to spaghetti?

    When it comes to food, definitely not. Spaghetti Bolognese needs few ingredients, is quickly prepared and always tastes great – at least to me 😉 But what I am actually getting at? Spaghetti Code. In contrast to a meal, Spaghetti Code is not eaten up in a few minutes. It stays, is extended, changes, grows and grows and grows. It is the same with microservices. If you start with microservices, you always have to consider how fine-grained services are cut. In the end, the spaghetti effect shifts from code to orchestrating components. This component must know all the small services and connect them with each other. The same can be found in manual activities that have not been automated or...

    Read more
  • chor-js – an Editor for BPMN Choreography...

    Let’s say you are craving your favorite pizza from that pizza place a ten-minute walk away. You call them up, place your order, and are then asked whether you would like to have the pizza delivered or pick it up yourself. In your mind, you think about how convenient it would be to have a delivery driver knock on your door and hand you the pizza within half an hour or so, but then again it is only a short walk, and some fresh air would really do you good… Putting somewhat existential questions aside, what we just described is a prime example for a so-called choreography in Business Process Management. Different participants (you, the pizza place and the delivery...

    Read more
  • Test Your Processes With JUnit 5

    If you’re a fan of JUnit5 for testing on the JVM, we have good news — there’s a brand-new library available: camunda-bpm-junit5, published as a community extension for Camunda BPM. The project is now available on Maven central, so you can start testing your processes with the latest technology. Getting started To add the extension to your project, just add the Maven dependency to your pom file: <dependency> <groupId>org.camunda.bpm.extension</groupId> <artifactId>camunda-bpm-junit5</artifactId> <version>1.0.0</version> <scope>test</scope> </dependency> Add the dependencies to JUnit 5 if you don’t already have them (they are included in the spring-boot-starter-test artifact): <dependency> <groupId>org.junit.jupiter</groupId> <artifactId>junit-jupiter</artifactId> <version>5.6.2</version> <scope>test</scope> </dependency> To start testing you can extend your test class with the ProcessEngineExtension: This injects the ProcessEngine configured in the camunda.cfg.xml file into...

    Read more