Camunda Team Blog

DMN is more than a Decision Table

Written by Philipp Ossler on , under Community category.

Decision tables are the most common element from DMN. They are easy to use and can solve many problems. However, DMN has more elements like Business Knowledge Models, Contexts, Literal Expressions, Function Definitions, Invocations and more.

In this post, I want to introduce the new extension for DMN and show how it can be used to model an example decision with the full power of DMN.

The Extension

The DMN-Scala extension is a community project and has the goal to increase the DMN support for Camunda. It is based on the FEEL extension and the Camunda DMN Model API. It can be integrated into Camunda as a process engine plugin and replaces the Camunda DMN engine.

The Example

Assume that we are looking for a new contract for our mobile phone. We have a long list of different contracts and want to rank them based on our preferences. Our criteria are:

  • the network quality
  • the network speed
  • the included data volume
  • the monthly cost

We start by modeling the scoring of a contract by the criteria. This is a perfect use case for a decision table. We split the scoring into three decision tables for a better overview.

So far, so good. Now we come to the interesting part of the model: how we can combine the results of these decision tables and apply them to the list of contracts.

Combine the Results

We use a so-called context to combine the results. It is like a map with key-value-pair. The context has one entry for each result, one entry to calculate the total score and one entry for the contract name.

The results of the decision tables are retrieved by using invocations. An invocation evaluates a business knowledge model and returns the result. To make this work, we need to embed the decision tables into business knowledge models as their business logic. A business knowledge model is similar to a decision but it can be invoked by other decisions or business knowledge models.

The total score of the contract is calculated by using a literal expression. It aggregates the different results with the FEEL built-in function sum(). Each result is multiplied by a factor to represent that some criteria are more important than others.

Iterate over the Collection

In order to calculate the score for all contracts, we use a literal expression with the FEEL list operator for. It iterates over the contracts and invokes the score context as a function for each contract. This works when we use the same trick as we did with the decision tables and embed the context into a business knowledge model.

The result of the iteration is a list of tuples which contains the contract name and the calculated scores. As the final step, the list is sorted by the total score using the FEEL built-in function sort().

The final DMN Model

In the end, we have a DMN model with one decision and four business knowledge models. The decision is the entry point of the model and uses the business knowledge models to compute the contract score.

From a DRD perspective, it looks like this:

When we evaluate the decision with a list of contracts (e.g. via DecisionService), then we get a result like this

[
 {name=contract-4, mobileDataPlan=6, cost=6, networkQuality=9,  totalScore=39}, 
 {name=contract-5, mobileDataPlan=6, cost=3, networkQuality=10, totalScore=34}, 
 {name=contract-1, mobileDataPlan=3, cost=9, networkQuality=6,  totalScore=33}, 
 {name=contract-2, mobileDataPlan=2, cost=9, networkQuality=9,  totalScore=33}, 
 {name=contract-3, mobileDataPlan=2, cost=9, networkQuality=6,  totalScore=30}
]

We did it! We modeled the contract ranking using only DMN. By using the extension, we have the full power of DMN and don’t need to write additional business logic or use BPMN as a coordinator (i.e. Decision Flow).

How to use it?

With the Camunda Tomcat distribution

  • download the JAR from the Github site (dmn-engine-camunda-plugin-1.1.0-full.jar)
  • copy it to the lib folder of the Tomcat server
  • add the plugin to the process engine configuration (conf/bpm-platform.xml)
<process-engine>
    <plugins>
        <!-- ... -->    
        <plugin>
            <class>org.camunda.dmn.camunda.plugin.CamundaDmnEnginePlugin</class>
        </plugin>
    </plugins> 
</process-engine>

With an embedded Camunda engine or Spring Boot

  • add the extension as dependency to your project POM
<dependency>
  <groupId>org.camunda.bpm.extension.dmn.scala</groupId>
  <artifactId>dmn-engine-camunda-plugin</artifactId>
  <version>1.1.0</version>
</dependency>
  • register the plugin org.camunda.dmn.camunda.plugin.CamundaDmnEnginePlugin in your process engine configuration

Additional Information

More information about the extension can be found on the Github site.

The full example is available at the Github repository.