Correlating multiple messages within one process instance

Hello,

I have a process model with two intermediate message receive events. Both events refer to the same message but are located at different places in the process.

During the process execution, at some moment, the tokens will arrive at just the one event or the other or both.

If in that moment I will call MessageCorrelationBuilder.correlateAll() with the processInstanceId and message name as the correlation criteria, would that call activate all messages that hold the token at this moment? I.e., if the process has reached both message events, both of them would be activated by the call, and the process execution would continue at two places.

Is my understandng correct?

A message is meant to be a 1:1 communication. Hence Camunda tries to match a message to one unique recipient. You can use the same message name on two receive events, but you should ensure the paths are mutually exclusive, otherwise Camunda will throw an exception:

org.camunda.bpm.engine.MismatchingMessageCorrelationException: ENGINE-13031 Cannot correlate a message with name ‘MessageA’ to a single execution. 2 executions match the correlation keys: CorrelationSet [businessKey=null, processInstanceId=null, processDefinitionId=null, correlationKeys=null, localCorrelationKeys=null, tenantId=null, isTenantIdSet=false]

Here is a test case:

public class MessageCorrelationTest {

    @Rule
    public ProcessEngineRule engine = new ProcessEngineRule();
    public static final String MESSAGE_A = "MessageA";

    @Test
    public void twoReceiversTest() {
        BpmnModelInstance modelInst = Bpmn.createExecutableProcess("MessageCorrelationTest")
                .startEvent()
                .parallelGateway("parallelGateway")
                .intermediateCatchEvent("Event1").message(MESSAGE_A)
                .endEvent("Path1Ended")
                .done();
        ((Gateway) modelInst.getModelElementById("parallelGateway")).builder()
                .intermediateCatchEvent("Event2").message(MESSAGE_A)
                .endEvent().name("Path2Ended");

        repositoryService().createDeployment()
                .addModelInstance("MessageCorrelationTest.bpmn", modelInst).deploy();

        ProcessInstance pi = runtimeService().startProcessInstanceByKey("MessageCorrelationTest");
        assertThat(pi).isWaitingAt("Event1", "Event2");
        runtimeService().correlateMessage(MESSAGE_A);
    }
}

Signals can be used to broadcast to multiple (unknown) recipients, also across multiple process instances. However, I would carefully evaluate if you cannot change your process model using simple BPMN2 means to have only one message receive event waiting when the message arrives.

Thank you very much for the test template. Things work as I expected. Just replace the last line in your test with

runtimeService().createMessageCorrelation(MESSAGE_A).correlateAll();
assertThat(pi).isEnded();

The important detail is “correlateAll”. Thank you again.