It it possible to create a user defined function in a literal expression and call it from a decision table?

Hello,

I am trying to create user defined literal expression. I was able to call the built in functions without any problem in decision tables. I need to create some complexe calculation which is beyond a simple FEEL expression. I have 3 questions:

  1. Is it possible to create a complexe function in as a literal expression?

  2. Can I call the function from a decision table? another literal expression?

3 ) If yes. What is the camunda version that supports these functionalities?

Thank you and best regards,
Marc

Welcome @m_fawaz. :wave:

Yes, this is possible. Here is an example DMN:

decision-literal-function-dmn.dmn (4.6 KB)

I recommend the latest Camunda version: 8.2

Does this help you?

Best regards,
Philipp

4 Likes

Hi @Philipp_Ossler ,

Thank you for the sample dmn for creating a user defined function. Was wondering if there is a possibility to define the function at a single place and reuse it across multiple dmns?

No, currently this is not possible.

Hi philipp just saw this post i have this custom function , anyway to use this inside input cell eg rule1: proximityCheck(media.news,media.company,[list of keywords],15) and then next rule proximityCheck((media.news,media.company,[list of new keyword],20) , media is the element which i am passing from subprocess to dmn , anyway to do this ?

function proximityCheck(news, company, keyword, distance) {
                const words = news.split(/\s+/);
                let companyIndexes = [], keywordIndexes = [];
                words.forEach((word, index) => {
                    if (word.includes(company)) companyIndexes.push(index);
                    if (word.includes(keyword)) keywordIndexes.push(index);
                });
                return companyIndexes.some(ci => keywordIndexes.some(ki => Math.abs(ci - ki) <= distance));
            }

Hi @Aryan_Agarwal ,
have a look at the attached DMN.
Best regards,
Enrico
EvaluateProximity.dmn (5.4 KB)

Hi enrico thanks for your reply actually my use case is different , i am trying to create dmn like this
media_rules.dmn (2.1 KB)
and i try to create my custom function for myFunction

package com.aryan;
import org.camunda.bpm.dmn.feel.impl.scala.function.CustomFunction;
import org.camunda.bpm.dmn.feel.impl.scala.function.FeelCustomFunctionProvider;
import java.util.Collection;
import java.util.HashMap;
import java.util.Map;
import java.util.Optional;
import java.util.Arrays;
import java.util.List;

public class MyCustomFunctionProvider implements FeelCustomFunctionProvider {
    private final Map<String, CustomFunction> functions = new HashMap<>();

    public MyCustomFunctionProvider() {
        CustomFunction myFunction = CustomFunction.create()
            .setParams("news", "companyName", "keywords", "proximity")
            .setFunction(args -> {
                String news = (String) args.get(0);
                String companyName = (String) args.get(1);
                String keywords = (String) args.get(2);
                Integer proximity = ((Number) args.get(3)).intValue();
                System.out.println(proximity);
                if (news == null || companyName == null || keywords == null || proximity < 0) {
                    return false;
                }

                List<String> keywordList = Arrays.asList(keywords.split("\\s*,\\s*"));
                int index = news.indexOf(companyName);
                while (index >= 0) {
                    int start = Math.max(0, index - proximity);
                    int end = Math.min(news.length(), index + companyName.length() + proximity);
                    String window = news.substring(start, end);

                    for (String keyword : keywordList) {
                        if (window.contains(keyword)) {
                            return true;
                        }
                    }
                    index = news.indexOf(companyName, index + 1);
                }
                return false;
            })
            .build();

        functions.put("myfunction", myFunction);
    }

    @Override
    public Optional<CustomFunction> resolveFunction(String functionName) {
        return Optional.ofNullable(functions.get(functionName));
    }

    @Override
    public Collection<String> getFunctionNames() {
        return functions.keySet();
    }
}

and then i register this function, but when the dmn evaluates it gives all value as true and everything goes into database

, i am trying to go through all the forum but unable to solve this issue

I’ve changed the DMN diagram so now it’s working with using the function inside each rule as per your example.
But as for the function itself I’ve put it in a BKM. I guess it should be equivalent to your custom function, but you should verify that.
The business requirement should be satisfied by this diagram attached

Evaluate proximity.dmn (4.0 KB)