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?
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.