Search code examples
javaspringbpmncamunda

Camunda BPMN - accessing variables inside a thread


In a Camunda process flow, I'm trying to access variables that are created inside a RabbitMQ onMessage thread ... In short, I have a RabbitMQ consumer listening to a queue, once a message is published to the queue, onMessage is executed and inside this onMessage I start the BPMN process.

@Component("MyProcessor")
public class MyProcessor implements ChannelAwareMessageListener {

    public final void onMessage(Message message, Channel channel){
        // create some variables based on the message
        ....
        // do some database lookups based on the message
        ....
        // enrich message based on some other factors
        ....
        SomeService service = new SomeService(message);
        if (service.isThisOrThatEnabled()){
            System.out.println("Yes, it's enabled");
        }
        ....
        runtimeService.startProcessInstanceByKey("ABC");
        ....

    }

}

So based on the incoming message, I set certain variables with a scope that doesn't go outside onMessage.

When I call a service task or use an expression inside a service task in Camunda:

${MyProcessor.isThisOrThatEnabled() == true}

This will obviously call the singleton annotated with @Component and have no access to the actual message in onMessage. If MyProcessor.isThisOrThatEnabled wraps service.isThisOrThatEnabled, I'll probably get a null pointer exception as service is not initialized when the Singleton is created, only inside the onMessage thread.

So to sum up my question, how do I access variables in BPMN that are inside a thread ...

1: If singletons are the wrong way to access variables in a thread, how else should I be accessing them? Is it possible to inject that SomeService instance into the BPMN flow?

2: If service tasks are the wrong component to be using to access these variables, which component should I be using instead?


Solution

  • You can set a process variable like

    Map<String, Object> variables = new HashMap<String, Object>();
    variables.put("service", service);
    runtimeService.startProcessInstanceByKey("ABC", variables);
    

    In an expression, you can then write

    ${service.isThisOrThatEnabled()}
    

    The above assumes that SomeService implements the interface java.io.Serializable. If that is not the case, you might create a POJO class that implements Serializable and that you fill with the relevant Service/Message properties that your process needs.