Running DMN Decisions using Embeded Literal Expression Scripts

Hello,

What I am trying to accomplish is execute the DMN Decision Table several times in a loop through Decision Literal Expression Groovy Script. Through every iteration of the loop I need to be able to set different values for the input variable of the decision table. Through searching around I figured out that I can do so by using a property binding.setVariable().

Just like “binding” are there other standard properties that are there which I should be knowing to do my job better and use them in future in implementations. I found binding and its setVariable, hasVariable through hit and trial. Is there any documentation that can give me more insights

Also need help for a couple of things

  1. How to explicitly call/execute the DMN table underlying to the script?

  2. How to catch all the output variables appropriately?

  3. How to catch the output variables if the return is a Collection of results? I need to be able to get it and iterate it as well

Consider that I need to return multiple Output variables/columns and sometimes the return could be a list/collection based on multiple rules met

It would be great help if you can guide me through this Journey

Thanks in advance for the immense support and guidance from the Camunda

Posts that i referred and used

Regards,
JRK

Hi @jagatramkhanna,

I can’t provide the Groovy script but maybe this post is interesting for you:
https://blog.camunda.com/post/2018/11/dmn-scala-extension/

Best regards,
Philipp

Hello Philipp,

This certainly helps. Though while making use of this another issue came up if you can help with.
Through our java code we are creating a DMN engine at run time as embedded DMNEngines and not using process engines at all in our services. Our existing Pseudo code is as below

****** private method to create engine config *******************

private static DmnEngine createDmnEngine() {
// create default DMN engine configuration
DefaultDmnEngineConfiguration configuration = (DefaultDmnEngineConfiguration) DmnEngineConfiguration
.createDefaultDmnEngineConfiguration();
configuration.setFeelEngineFactory(new CamundaFeelEngineFactory());
// build a new DMN engine
return configuration.buildEngine();
}
******************* End**************
*********** service Code **************
//create new engine
org.camunda.bpm.dmn.engine.DmnEngine dmnEngine = createDmnEngine();
//create variable map
VariableMap variables = Variables.createVariables().putValue(“contracts”, contracts);
evaluate the DMN file coming in as an inputStream or as a Decision
DmnDecisionResult result = dmnEngine.evaluateDecision(“contractRanking”, dmnFileInputStream, variables);
************ end **************

now when we try using the new DMN Engine link you have provided. It has a Scala example and no java usage. When I tried to work with it there are multiple issues that were coming. For one to instantiate the DMNEngie two parameters are required 1) Configuration and 2) List of AuditLogListener
Configuration Object I was able to create a new object as below
Configuration configuration =new Configuration(false, false);

But everytime I tried to a AuditLogListener list it didn;t work out it always kept throwing different errors.
Finally tried to work with below code:

{

Configuration configuration = new Configuration(false, false);
AuditLogListener auditLogListeners = new AuditLogListener() {

			public void onEval(AuditLog log) {
				// TODO Auto-generated method stub
				
			}
		};
		scala.collection.immutable.List<AuditLogListener> list = null;
		
		VariableMap variables = Variables.createVariables().putValue("contracts", contracts);
		
		DmnEngine dmnEngine = new DmnEngine(configuration,list);
		//dmnEngine.parse(dmnFileInputStream);
		dmnEngine.eval(dmnFileInputStream, "contractRanking", variables);

}

With this i started getting errors ::

java.lang.NoSuchMethodError: org.camunda.bpm.model.dmn.instance.Binding.getParameter()Lorg/camunda/bpm/model/dmn/instance/Parameter;
at org.camunda.dmn.parser.DmnParser.$anonfun$parseInvocation$1(DmnParser.scala:326)
at scala.collection.TraversableLike.$anonfun$map$1(TraversableLike.scala:234)
at scala.collection.Iterator.foreach(Iterator.scala:929)
at scala.collection.Iterator.foreach$(Iterator.scala:929)
at scala.collection.AbstractIterator.foreach(Iterator.scala:1406)
at scala.collection.IterableLike.foreach(IterableLike.scala:71)
at scala.collection.IterableLike.foreach$(IterableLike.scala:70)
at scala.collection.AbstractIterable.foreach(Iterable.scala:54)
at scala.collection.TraversableLike.map(TraversableLike.scala:234)
at scala.collection.TraversableLike.map$(TraversableLike.scala:227)
at scala.collection.AbstractTraversable.map(Traversable.scala:104)
at org.camunda.dmn.parser.DmnParser.parseInvocation(DmnParser.scala:323)
at org.camunda.dmn.parser.DmnParser.parseAnyExpression(DmnParser.scala:363)
at org.camunda.dmn.parser.DmnParser.$anonfun$parseContext$1(DmnParser.scala:251)
at scala.collection.TraversableLike.$anonfun$map$1(TraversableLike.scala:234)
at scala.collection.Iterator.foreach(Iterator.scala:929)
at scala.collection.Iterator.foreach$(Iterator.scala:929)
at scala.collection.AbstractIterator.foreach(Iterator.scala:1406)
at scala.collection.IterableLike.foreach(IterableLike.scala:71)
at scala.collection.IterableLike.foreach$(IterableLike.scala:70)
at scala.collection.AbstractIterable.foreach(Iterable.scala:54)
at scala.collection.TraversableLike.map(TraversableLike.scala:234)
at scala.collection.TraversableLike.map$(TraversableLike.scala:227)
at scala.collection.AbstractTraversable.map(Traversable.scala:104)
at org.camunda.dmn.parser.DmnParser.parseContext(DmnParser.scala:250)
at org.camunda.dmn.parser.DmnParser.parseBusinessKnowledgeModel(DmnParser.scala:162)
at org.camunda.dmn.parser.DmnParser.$anonfun$parseDecision$7(DmnParser.scala:116)
at scala.collection.mutable.HashMap.getOrElseUpdate(HashMap.scala:79)
at org.camunda.dmn.parser.DmnParser.$anonfun$parseDecision$6(DmnParser.scala:116)
at scala.collection.TraversableLike.$anonfun$map$1(TraversableLike.scala:234)
at scala.collection.immutable.List.foreach(List.scala:378)
at scala.collection.TraversableLike.map(TraversableLike.scala:234)
at scala.collection.TraversableLike.map$(TraversableLike.scala:227)
at scala.collection.immutable.List.map(List.scala:284)
at org.camunda.dmn.parser.DmnParser.parseDecision(DmnParser.scala:115)
at org.camunda.dmn.parser.DmnParser.$anonfun$parseModel$3(DmnParser.scala:91)
at scala.collection.mutable.HashMap.getOrElseUpdate(HashMap.scala:79)
at org.camunda.dmn.parser.DmnParser.$anonfun$parseModel$2(DmnParser.scala:91)
at scala.collection.TraversableLike.$anonfun$map$1(TraversableLike.scala:234)
at scala.collection.immutable.List.foreach(List.scala:378)
at scala.collection.TraversableLike.map(TraversableLike.scala:234)
at scala.collection.TraversableLike.map$(TraversableLike.scala:227)
at scala.collection.immutable.List.map(List.scala:284)
at org.camunda.dmn.parser.DmnParser.parseModel(DmnParser.scala:89)
at org.camunda.dmn.parser.DmnParser.parse(DmnParser.scala:74)
at org.camunda.dmn.DmnEngine.parse(DmnEngine.scala:134)
at org.camunda.dmn.DmnEngine.eval(DmnEngine.scala:129)
at org.camunda.dmn.DmnEngine.eval(DmnEngine.scala:162)

It would be really helpful if you can guide me on a Java implementation use case like you have for the other DMN engine

Also in the previous DMN engines there was an option to parse the DMN file and keep the decision objects and then reuse them as and when needed. Can the same be done with this new DMN engine

Thanks
JRK

Hi @jagatramkhanna,

I agree that the API of the DMN engine cannot be used so smoothly from Java yet. You can use the following code to parse and evaluate decisions:

final DmnEngine dmnEngine =
        new DmnEngine(
            new DmnEngine.Configuration(false, false),
            JavaConversions.asScalaBuffer(new ArrayList<AuditLogListener>()).toList());

    final ParsedDmn parsedDmn =
        dmnEngine.parse(getClass().getResourceAsStream("/contract-ranking.dmn")).right().get();

    final HashMap<String, Object> variables = new HashMap<String, Object>();    
    variables.put("contracts", contracts);

    final EvalResult result = dmnEngine.eval(parsedDmn, "contractRanking", variables).right().get();
    if (result.isNil()) {
      System.out.println("null");
    } else {
      final Object value = ((DmnEngine.Result) result).value();
      System.out.println(value);
    }

Does this help you?

Regardings

It seems that there is something wrong with the dependencies. Please make sure that you don’t override the version of the DMN engine.

Best regards,
Philipp