Use of FEEL engine

Hi everyone,

I’m working on some lightweight decision table implementation and I would like to use the Camunda FEEL engine.

I think, I figured out, how the engine evaluates the condition fields, but now I’m asking myself - actually now I’m asking you - how the action fields work. I was expecting some kind of value assignments, like assign the value in the action field to variable given in the corresponding header column. Should it work like that?

Is there an example for such a scenario? Is the FEEL engine meant to be used “standalone”?

Thanks in advance,
Stephan

Can you explain a little big about why you’d want to use the FEEL engine independently?

Actually it’s just an option, currently.

I need some decision table functionality, but I’m not in the context of a bpm process. And I don’t want to force my business analyst to deal with the Modeler, but use Excel/ CSV, for example.

So, one option is a custom implementation, but I don’t want to implement a FEEL engine myself. :slight_smile:

Sure thing!
Well you can indeed use the FEEL engine independently of DMN or BPMN a good example and usecase for this is @nikku 's FEEL Playground which can probably help you understand how to do your own integration.

Hope that helps.

1 Like

Hi @Niall,

first of all thank you for your help. I did some progress meanwhile, but now I’m facing the next issue.

Is there also some kind of FEEL playground implemented in Java? Some example, how the Java engine should be used.

Let me show you some of my implementation. I implemented a service, that takes a Map of Strings to Objects and I tested an option of directly adding some objects to the map and also one, where I’m mapping them via Jackson to Maps, in advance.

        Map<String, Object> context = new HashMap<>();

        var field1Object = DummyObject.builder()
                .size(4)
                .height(8)
                .width(12)
                .build();
        var field1 = objectMapper.convertValue(field1Object, new TypeReference<Map<String, Object>>() {
        });

        var field2Object = DummyObject.builder()
                .size(1)
                .height(3)
                .width(9)
                .build();
        var field2 = objectMapper.convertValue(field2Object, new TypeReference<Map<String, Object>>() {
        });

        context.put("field1", field1Object);
        context.put("field2", field2Object);
        context = service.run(context);

This snippet curretly does the direct mapping.

Afterwards I put the Map into a VariableMapImpl, to be able to provide it to the engine.

var feelContext = new VariableMapImpl(context);

Then I select some decision table and step through each of its rows, like that:

        for (var currentCondition : currentRow.getConditions()) {
            var currentFieldToCheck = conditionHeaders.next();
            var worm = engine.evaluateSimpleExpression(currentFieldToCheck, context);
            LOG.debug("Expression = {}", worm);
            var conditionMet = engine.evaluateSimpleUnaryTests(currentCondition, currentFieldToCheck, context);
            LOG.debug("Check {} for {}: {}", currentFieldToCheck, currentCondition, conditionMet);

            if (!conditionMet) {
                allConditionsMet = false;
            }
        }

There is a list of conditions and a list of the corresponding headers. Then I call the engine’s evaluateSimpleUnaryTests-method for each condition.

But I receive the following error:

org.camunda.bpm.dmn.feel.impl.FeelException: FEEL/SCALA-01008 Error while evaluating expression: failed to evaluate expression '>8': no variable found for name 'field1.size'

I understand this, like the engine doesn’t understand, that it should access the property size of the variable field1.

I added another call to the engine’s evaluateSimpleExpression, just trying to evaluate the expression “field1.size” and this call works (the “worm-line”).

So, there’s something, I’m doing wrong, but I have no clue, what it is…