DMN Enumeration Data Types
Blog: Collaborative Planning & Social Business
If you are modeling a decision, it is likely that you will want to make use of an enumeration, that is, a data type which restricts the options to a fixed set of values. I tested this on four different DMN modeling tools, and I found the output is different for the different tools. That has implications for interoperability.
Make a decision process to determine the annual fee of a credit card. The fee depends only on the credit card type. There are three kinds of cards: silver, gold, and platinum. The fees are $12/year for a silver card, $120/year for a gold card, and $600/year for a platinum card. You should end up with a model that returns the annual fee when given the card type.
What is an Enumeration?
There are three kinds of cards. You could made the input for card type be a string which would hold any kind of text value. But you really would like to build into the model the idea that there really are only three card types, and any attempt to specify a fourth type should be either prevented, or have a warning of some type. Restricting the data in this way will help to catch typos and programming mistakes.
An enumeration then is a data type that is restricted to a particular set of values. You create a data type. It seems that in the DMN community the standard pattern is to name this data type starting with a lower case t. For example: tCardType. This is not required by the spec, and so this is really more of a style, however if everyone does it, then you have the advantage that you can easily recognize data types from all the other values you see on the screen. This style seems useful to me.
In this case the base type is string. You could have a data type which is a specific set of numbers, such as shoe sizes or dress sizes. With a number the concept of ranges becomes important. But when you have a set of string values, you must use the base type of string.
You then add a constraint on the value. A constraint can be expression, range, or enumeration in the tools that I tested. Enumeration simply means that you are going to supply all the possible values right here when defining the type, and no other values will be allowed. It becomes an easy job to enter “silver”, “gold”, and “platinum” into the list provided and save it.
Then, when you declare an input or an output, you can specify
tCardType as the type of the value, and that should allow the system to check the input value to make sure that it is one of those defined. What is even nicer is that the testing tool can use this to provide a pull-down list of possible values, and you can avoid the entire problem with making a typo.
DMN is an XML file format defined by a XML Schema file. Unfortunately, the standard apparently does not define how to specify an enumeration. This means that the files might be created differently, and that is what I found. If the files are created differently, then it will not be possible to bring a file created by one tool into another and get the enumeration transferred correctly. If you use enumerations — and I feel they are a very important part of proper modeling of decisions — then you need to be very careful which style you want to use, and make sure that both your execution environment and modeling environment use the same thing. Models that use enumeration are not interchangeable.
Using the Trisotech DMN modeler, I was able to define the data type. There is a series of pop-up windows that allow entering the appropriate values, and define the enumeration. This was pretty easy to do.
Trisotech output the following XML for the enumeration. Note that the tags that start with “triso” are Trisotech specific tags. Notice that the values are defined as separate tags, and that there is a display value separate from the underlying data value:
I was not able to figure out how to get the Camunda DMN modeler to create an enumeration data type. It is possible there are some other way to do it, but I could not find it.
Creating an enumerated type in KIE Sandbox was similarly easy to create the type, using string as a base type, and then a constraint on that for the enumeration. Again, you enter the values on separate lines of a list:
KIE Sandbox produced the following XML for the enumerated type. Here the tags that start with “kie” are custom tags. Here there is a single tag containing the values as a quoted, comma delimited list. I also tried creating values with quotes and commas, and I was successful in doing that.
Red Hat Business Central
The user interface for Red Hat was identical to that of KIE Sandbox. It is clear they are using the same editor user interface. But surprisingly, the Red Hat file was produced differently because the enumeration values were not quoted. Instead it is a flat list of values. The use of the quotes allows the values to have commas in them if you need it. In Red Hat, I tried to create a value with a comma in it, and it instead created two values, each on their own row. I don’t know whether it is important to have commas in the enumeration values (I can’t think of any example) however just the fact that this is done differently is concerning.
I tried moving the files back and forth between the editors:
- KIE to Trisotech: Data type was received correctly.
- Red Hat to Trisotech: Data type was received correctly.
- Red Hat to KIE Sandbox: Data type was received correctly.
- Trisotech (DMN 1.1) to KIE Sandbox: Data type was received correctly. Trisotech exports four different versions, version 1.1, 1.2, 1.3, and 1.4 of DMN. Version 1.1 imported correctly. I also tried version 1.4 but it failed for a reason unrelated to the enumeration type. KIE Sandbox does not support this version yet, so something like this is not surprising.
- KIE to Red Hat: Data type was received correctly.
- Trisotech (DMN 1.1) to Red Hat: Data type was received correctly.
In conclusion, the tools involved were able to exchange the data type successfully, but the differences in the way they are encoded still leave me wary that there might be a problem in the future.
The rest of the decision model looked like this at the highest level:
And then the decision table looks like this: