Finding executions waiting for messages based on process variable matches

Hi,

I’ve tried to get intermediate message catch events working. I’m trying to trigger the correct execution based on some correlation key I have.

The documentation on messages states that this query should work:

Execution execution = runtimeService.createExecutionQuery()
      .messageEventSubscriptionName("paymentReceived")
      .variableValueEquals("orderId", message.getOrderId())
      .singleResult();

However, I find that this query does always result in an empty set. I added a workaround in my code which does two queries, one for the Process Instance where I do the correlation, and another one for the execution where I use the PI as a parent along the message name.

Am I missing something or is this expected behaviour?

The query look ok at first glance. When are you setting the orderId variable? Are you sure the state is persisted already when doing this query?

An alternative is to use the RuntimeService#createEventSubscriptionQuery method (finding the event subscriptions and then getting the execution).

Another alternative to look into can be the eventing that was added in the 6.5.0 release. They have correlation parameter built in. See https://blog.flowable.org/2020/03/24/flowable-business-processing-from-kafka-events/ for more information.

Thanks for the reply!

This is the actual code I use now – as a workaround. As this works, I’m pretty sure that the state is persisted. I use this code to get the execution which is waiting for a message. I call this code from within a camel route. I can’t get the query from the documentation to work, even outside the camel route.

Anything else what I could try?

Ultimatively all I want to do is to send a message to some process waiting. As I need to be specific, I can’t do broadcast messages.

I’m aware of the new eventing code – eventually I might start using it, but for now it seems overkill.

private Execution getExecutionForProjectIdAndMessageName(
                      String projectId, String messageName) {
    Execution parent = runtimeService.createExecutionQuery()
            .processInstanceBusinessKey(projectId)
            .singleResult();

    if (parent == null) {
        log.error("Could not find process instance for project id {}", projectId);
        throw new RuntimeException("Could not find process instance for project id " + projectId);
    }

    Execution execution = runtimeService.createExecutionQuery()
            .messageEventSubscriptionName(messageName)
            .parentId(parent.getId())
            .singleResult();

    if (execution == null) {
        log.error("Could not find execution: project id {}, message name '{}'", projectId, messageName);
        throw new RuntimeException("Could not find execution: project id " + projectId + " , message name '" + messageName + "'");
    }

   return execution;
}

Looking at the original query better, it looks like the db join is made on the process instance level. This is also where the variables are stored. But the message is added to a child execution, hence why no results are returned.

What happens when the .variableValueEquals("orderId", message.getOrderId()) is removed? Do you get back a list that contains the execution you’re looking for?

Sorry for the late answer. I’m pretty sure that I tested this – I’ll try this again later today and report back.

Hello there.
@joram is the messageEventSubscriptionName and messageRef the same thing? If not how to define the messageEventSubscriptionName in BPMN.

No, it’s not. The reference is used to reference a message element at the root of the xml. The name is a human-readable name.

The xml is

<message id="test" name="My name" />