Correlate message to waiting event subprocess within multi-instance subprocess

Hi,

I have a parallel multi-instance subprocess that may be interrupted for a particular instance. I’ve defined an event subprocess inside of the multi-instance subprocess to listen for an interruption message, similar to this (contrived) example:

multi instance event subprocess.bpmn (7.2 KB)

However, I’m having trouble creating the correlation for this message. The following code results in an error:

engine.getRuntimeService()
    .createMessageCorrelation("ItemCanceledEvent")
    .processInstanceBusinessKey(sessionId)
    .processInstanceVariableEquals("item", item) // where "item" is the name of the element variable as defined in the model
    .setVariable("someCancelationKey", someValue)
    .correlate(); // org.camunda.bpm.engine.MismatchingMessageCorrelationException: ENGINE-13031 Cannot correlate a message with name 'ItemCanceledEvent' to a single execution. n executions match the correlation keys ...

According to the docs, it seems I should be able to pass variables from the process instance to each of the event subprocess executions, but the modeler doesn’t allow for creating input/output mappings for the event subprocess or the message start event. Also, I get an error at runtime if I try to manually define these mappings directly in the bpmn file.

What is the best way to correlate this message?

I am using camunda-bpm-spring-boot-starter version 3.4.2 (which references version 7.12 of the Camunda engine).

Thanks in advance!

When using a multi-instance sub process that is running for each item in a given collection a local variable is created for each instance of the sub process.

This issue with your code is that your trying to correlate the message against a global variable.
Try checking for the local variable instead.

Hi @Niall,

Glad to see you’re active on these forums. I really enjoyed your introductory videos on Camunda.

My original attempt was actually the following:

engine.getRuntimeService()
    .createMessageCorrelation("ItemCanceledEvent")
    .processInstanceBusinessKey(sessionId)
    .localVariableEquals("item", item)
    .setVariable("someCancelationKey", someValue)
    .correlate();

but that results in a different error:

ENGINE-16004 Exception while closing command context: Cannot correlate message 'ItemCanceledEvent': No process definition or execution matches the parameters

FWIW, I have several other message receive tasks in the “real” model for which I had to explicitly set the element variable in the Input/Output mapping before it would correlate properly (as inspired by this comment).

After fumbling around in the Camunda database, I can confirm the variables are indeed tied to the multi-instance subprocess. However, the waiting message events appear to be linked to a new execution created by the event subprocess, not the multi-instance subprocess execution. This extra layer seems to contradict the docs which state:

The embedded subprocess is executed using the same execution which executed the scope it is hosted in. This means that an embedded subprocess has access to the variables local to it’s scope.

or perhaps my understanding is flawed?

In any case, is there a way to pass these variables from the parent execution to the event subprocess?

If you’re talking about an embedded sub process then it can always access the global scope of the process. It also happens to have access to local variables. Depending on the API you’re using.

Are you able to trigger the message events via postman?

Nope, I’m getting the same error:

{
    "type": "RestException",
    "message": "org.camunda.bpm.engine.MismatchingMessageCorrelationException: Cannot correlate message 'ItemCanceledEvent': No process definition or execution matches the parameters"
}

I am able to trigger the message via the /execution/{id}/messageSubscriptions/{messageName}/trigger endpoint after drilling down to the correct execution.

Incidentally, the /execution/{id}/localVariables endpoint returns an empty list for this execution.

How are you starting the process instance exactly.
and how are you setting the business key for the process?

I’ve created a quick-and-dirty test project for this issue. For this project, I’m starting the process from Tasklist and not setting a business key (although it doesn’t seem to make a difference if I do).

For the “real” project, the process is started from a message start event. The business key is a generated UUID.

Both projects are exhibiting the same behavior.

Have you tried removing the business key parameter from the message correlation method?

Yep, here’s my request for the test project:

{
    "messageName": "ItemCanceledEvent",
    "localCorrelationKeys": {
        "item": {
            "value": "1",
            "type": "String"
        }
    },
    "resultEnabled": false
}

where “1” is a String element variable from the multi-instance subprocess.

If it helps, I’ve pushed the test project to GitHub at https://github.com/jdmcmahan/camunda-test.git. The message correlation can be triggered (with failure) via the Camunda REST API or by sending a DELETE request to /items/{item}.

I also added a user task to the multi-instance subprocess so that the process stops long enough to play around.

Hi I have had multiple issues surrounding this area and in this instance to get it working I added a listener to the start element in the multi instance to set items as a local variable, unfortunately this does effectively duplicate that variable

During our development we have found our preferred way of handling message correlation is to created a composite message name so for example ItemCanceledEvent_${item}

        engine.getRuntimeService()
                .createMessageCorrelation("ItemCanceledEvent_"+item)
                .correlate();

which also works in your diagram without the need of the listener.

Hope that helps,

Matt

2 Likes

I think this whole local correlation problems needs a bit of additional explanation.
I’ll try to take some time and build an example project where i can keep and maintain some of the solutions. I’ll post up here when I’ve got something.

2 Likes

Thanks @matt!! I can confirm both of these approaches do the trick.

2 Likes

I’ve created this example to help people in the future.

2 Likes

Huge thanks @Niall for your insight.

To be honest, I’m having trouble relating the example to the issue of event subprocesses within multi instance subprocesses. Can you elaborate?

Regardless, this example definitely helps to demonstrate a working scenario with messages and multiple instances.