Is it possible to do array Input?

Building on knowledge I have gained from the tutorials.

I have the following dish order object that is passed into my DMN model.

public class AllergyOrderDto implements Serializable {
    private static final long serialVersionUID = 11L;
    private String name;
    private String dish;
    private List<String> allergies;
    private String singleAllergy;
    
    // getters setters etc
}

And this is my decision table

This gets passed into my decision table. Now the following decision works.

Request

{
  "name" : "Robs Order",
  "singleAllergy" : "PEANUTS",
}

Response. Correctly matches the right dish. a nice salad without any nuts or wheat

{
    "name": "Robs Order",
    "dish": "LIGHT SALAD",
    "singleAllergy": "PEANUTS"
}

So far so good. However what I’m trying to do next is pass in a list of allergies into the order. Replacing singleAllergy with an array of allergies represented as a list of strings.

Request very similar to previous

{
  "name" : "Robs Order",
  "allergies" : ["PEANUTS","WHEAT"]
}

However I cannot get the DMN working. From reading around the FEEL expression seems to be correct avenue to explore. However Im confused about what to put here?

What should my DMN input statement look like?

allergyOrder.singleAllergy; // old value
allergyOrderDto.allergies.contains(?notsure what this value is?) . // new value

Any help would be much appreciated. Also Besides FEEL are there other options I could explore?

1 Like

Hi @Rob_Davidson,

how do you evaluate the decision? Via Rest API?
Do you use the FEEL extension already?
What exception do you get?

Your input expression looks good so far. You can use an expression language (e.g. JavaScript, JUEL, Groovy):
allergyOrderDto.allergies.contains("PEANUTS")

Or using the FEEL extension:
list contains(allergyOrderDto.allergies, "PEANUTS").

Best regards,
Philipp

1 Like

Isnt working for me. Mine looks like the following

Can the list contains part where PENAUTS is contain multiple values? i.e.

list contains(allergyOrderDto.allergies, "PEANUTS","ANOTHER_VAL","AND ANOTHER VAL");

It seems that you override the variable allergyOrder with allergyOrder.allergies if you set the input variable to allergyOrder.

No, the built-in function accepts only a single value. You could invoke the function for each value

list contains(allergyOrderDto.allergies, "PEANUTS"), list contains(allergyOrderDto.allergies, "ANOTHER_VAL")

or use a more advanced expression like:

some allergy in allergyOrderDto.allergies satisfies list contains(["PEANUTS","ANOTHER_VAL","AND ANOTHER VAL"], allergy)

count(allergyOrderDto.allergies[list contains(["PEANUTS","ANOTHER_VAL","AND ANOTHER VAL"], item)]) > 0
1 Like

@Philipp_Ossler is there a another solution for a some allergy in allergyOrderDto.allergies satisfies list contains(["PEANUTS","ANOTHER_VAL","AND ANOTHER VAL"], allergy) but that will work in 7.12 ?

For Camunda 7.12, you could embed the FEEL-Scala engine explicitly. Either as process engine plugin (using version 1.10.1) or using it as script engine.

@Philipp_Ossler Is there ways to use other scripting langs (like nashorn JS) as DMN row input expressions (unary tests) in the same way that FEEL can be used? I could not find doc examples.

Yes. You can change the expression language of the unary-tests expression, for example, to use JavaScript.

In the Camunda Modeler, do a right-click on the input entry and select “Change Cell Expression Language”.

Does this help you?

Yes that helps.

For others future ref here is a solution for using javascript to interate over DMN inputs that are arrays:

inputArray.elements().stream().anyMatch(function(e){
   return java.util.stream.Stream.of("value1","value2").anyMatch(function(x){
      return x == e.value()
   })
})

where inputArray is array/collection you are passing into the DMN’s input, and the value1, value2, etc is the list of values you are validating against.

1 Like