Rest api to evaluate an expression of gateway


#1

Imaging a process: a user task point to a xor gateway, a gateway point to 2 other user tasks with conditions;
I want to pre-evaluate outgoing conditions of gateway without complete current task to trigger it. Any way by rest api?

The rest api will be looked like:
task/{taskId}/evaluate

the output will be looked like:

list all outgoing user tasks with expression value pre evaluated:

 [
        {
            "activityId": "UserTask_1rayuk1",
            "assignee": "xxx",
            "activityType": "userTask",
            "inExpressionText": "${approved}",
            "inExpressionValue" : true
        },
        {
            "activityId": "UserTask_1rayuk2",
            "assignee": "xxx",
            "activityType": "userTask",
            "inExpressionText": "${!approved}",
            "inExpressionValue" : false
        },
    ]

Any suggestion to implement it?


#2

Hi @ymiao,

I’m afraid there is no such API. You could implement a custom REST endpoint that pre-evaluates sequence flow conditions for you. To evaluate EL, either embed the EL library and provide the process variables as context, or use the process engine’s ExpressionManager instance (accessible via ProcessEngineConfigurationImpl, see its usage in the codebase). The Camunda-way is internal API and therefore has no guarantees.

Cheers,
Thorben


Camunda Expression Evaluation
#3

Thanks for your help, Thorben, i had extent the “TaskResourceImpl.java” & “TaskResource.java” by adding new evalulate api:


    static ExpressionFactory expressionFactory = new ExpressionFactoryImpl();

    @Override
    public List<OutgoingActivityDto> evaluate(Request request) {
        CustomTaskDto task = getJsonTask();
        // query process instance variables and current task variables
        String processInstanceId = task.getProcessInstanceId();
        RuntimeService runtimeService = (RuntimeService) SpringContextUtil.getBean("runtimeService");
        Map<String, Object> variables = runtimeService.getVariables(processInstanceId);
        Iterator<String> iterator = variables.keySet().iterator();
        SimpleContext context = new SimpleContext();
        while (iterator.hasNext()) {
            String key = iterator.next();
            Object value = variables.get(key);
            context.setVariable(key, expressionFactory.createValueExpression(value, Object.class));
        }
        // query outgoing activities if any
        String processDefId = task.getProcessDefinitionId();
        String activityId = task.getTaskDefinitionKey();
        List<OutgoingActivityDto> outgoingActivityDtos = WorkflowUtils.getOutgoingActivities(processDefId, activityId);
        for (OutgoingActivityDto outgoingActivityDto : outgoingActivityDtos) {
            // calculate expression value
            ValueExpression expression = expressionFactory.createValueExpression(context, outgoingActivityDto.getConditionExpression(), Boolean.class);
            outgoingActivityDto.setConditionExpressionValue((Boolean) expression.getValue(context));
        }
        return outgoingActivityDtos;
    }

But as you see, i did not use ExpressionManager you suggested, because i got a null point exception when evaluate expression by JuelExpression.getValue(). As for me use embeded expressionManager in ProcessEngineConfigurationImpl is a bit heavy. So i just create my own ExpressionFactoryImpl object with SimpleContext. Seem works well.


#4

Hello brother, i have the same problem, ¿Can you share the code of your ExpressionFactoryImpl? thnx a lot