How can I make rule dynamic

I have created a DMN diagram file to validate amount is less than limit or not. My use case is I don’t want to use Hardcore value.


I am trying to run the rule in spring boot. Here is the below implementation.

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
	<modelVersion>4.0.0</modelVersion>
	<parent>
		<groupId>org.springframework.boot</groupId>
		<artifactId>spring-boot-starter-parent</artifactId>
		<version>3.1.4</version>
		<relativePath/> <!-- lookup parent from repository -->
	</parent>
	<groupId>com.example</groupId>
	<artifactId>camunda-demo</artifactId>
	<version>0.0.1-SNAPSHOT</version>
	<name>camunda-demo</name>
	<description>Demo project for Spring Boot</description>

	<properties>
		<java.version>17</java.version>
	</properties>

	<dependencyManagement>
		<dependencies>
			<dependency>
				<groupId>org.camunda.bpm.dmn</groupId>
				<artifactId>camunda-engine-dmn-bom</artifactId>
				<version>7.19.0</version>
				<type>pom</type>
				<scope>import</scope>
			</dependency>

		</dependencies>
	</dependencyManagement>



	<dependencies>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-web</artifactId>
		</dependency>

		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-test</artifactId>
			<scope>test</scope>
		</dependency>

		<dependency>
			<groupId>org.camunda.bpm.dmn</groupId>
			<artifactId>camunda-engine-dmn</artifactId>
		</dependency>
	</dependencies>

	<build>
		<plugins>
			<plugin>
				<groupId>org.springframework.boot</groupId>
				<artifactId>spring-boot-maven-plugin</artifactId>
			</plugin>
		</plugins>
	</build>

</project>
package com.example.camundademo.config;


import org.camunda.bpm.dmn.engine.DmnDecision;
import org.camunda.bpm.dmn.engine.DmnEngine;
import org.camunda.bpm.dmn.engine.DmnEngineConfiguration;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.Resource;

import java.io.IOException;
import java.io.InputStream;

@Configuration
public class DmnConfiguration {

    @Bean
    public DmnEngine createDmnEngine() {
        DmnEngineConfiguration configuration = DmnEngineConfiguration.createDefaultDmnEngineConfiguration();
        return configuration.buildEngine();
    }


    @Bean
    public DmnDecision transactionLimit(DmnEngine dmnEngine) {
        return getDmnDecision(dmnEngine, "dmn/transactionLimit.dmn", "transactionLimit");
    }


    private DmnDecision getDmnDecision(DmnEngine dmnEngine, String dmnFilePath, String decisionId) {

        Resource resource = new ClassPathResource(dmnFilePath);

        InputStream inputStream = null;
        try {
            inputStream = resource.getInputStream();
        }
        catch (IOException exception) {
            exception.printStackTrace();
        }
        return dmnEngine.parseDecision(decisionId, inputStream);
    }
}
package com.example.camundademo.service;


import org.camunda.bpm.dmn.engine.DmnDecision;
import org.camunda.bpm.dmn.engine.DmnDecisionTableResult;
import org.camunda.bpm.dmn.engine.DmnEngine;
import org.camunda.bpm.engine.variable.VariableMap;
import org.camunda.bpm.engine.variable.Variables;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Service;

@Service
public class TransactionLimitService {

    private final DmnEngine engine;

    private final DmnDecision decision;

    public AddService(DmnEngine engine, @Qualifier("transactionLimit") DmnDecision decision) {
        this.engine = engine;
        this.decision = decision;
    }

    public int validateRule(int amount, int limit) {
        VariableMap variables = Variables.putValue("amount", amount)
                .putValue("limit", limit);
        DmnDecisionTableResult result = engine.evaluateDecisionTable(decision, variables);
        return (int) result.getSingleResult().get("transactionLimit");
    }
}

When I am calling new TransactionLimitService().validateRule(amount, limit), I am getting below error:

org.camunda.bpm.dmn.feel.impl.FeelException: FEEL/SCALA-01008 Error while evaluating expression: failed to parse expression '${amount}':

can anyone suggest me how can I make those input attribute dynamic so that I can pass those value in runtime

Hi @skhaque,

By default, the expression language in DMN is FEEL. The parsing fails because your expressions are not valid FEEL but look more like JUEL.

Please have a look at the documentation: DMN Decision Table | docs.camunda.org

In general, you can use variables for a dynamic limit. For example, by changing the input entry in the table to < limit.