Question about message correlations

Hello dear camundians,

I’m a bit confused about the treatment of messages on API level. For demonstration purposes, I have modeled two pools in my .bpmn, MAIN and EXTERNAL, both marked as executable. The first is started manually, the latter should be triggered by a message event (name: “extMessage”, defined on the .bpmn level).

Inside MAIN a message-send task (QueryTask) is supposed to send such a message “extMessage” with the process variables as payload. After reading the message API documentation, I have set up the starting of the process like this (rts is the RuntimeService):

rts.correlateMessage("extMessage" , "EXTERNAL");
ProcessInstance instance = rts.startProcessInstanceByKey("MAIN", vars);

Inside QueryTask::execute I set up the actual message emit like this:

Map<String, Object> vars = execution.getVariables();
ProcessInstance pi = rts.startProcessInstanceByMessage("extMessage", vars);

EDIT: Withdrawing the original question, seems to be an issue with eclipse and tomcat server integration; New question below:

I observe a behavior I do not understand: Before the call to start MAIN is executed, EXTERNAL is already executed by the correlateMessage statement. After that, MAIN is excuted. Is this the correct behavior? How should I set up my logic in order to execute MAIN and then EXTERNAL upon emitting the message in QueryTask?

Hi @fbo,

You seem to misunderstand the message correlation API. When you call correlateMessage, the message you specified is correlated to either a) a process instance that waits for this message or b) a start event that matches the message. In case of a), the effect is that process execution advances in the existing process instance. In case of b), a new process instance is started at the message start event. This all happens synchronously in the correlateMessage invocation.

When you then start the MAIN process and call startProcessInstanceByMessage, you execute the behavior of b) effectively a second time .

In consequence, I think you should remove the correlateMessage invocation before starting the MAIN process.

Does this make sense?

Cheers,
Thorben

Right, removing that did the trick. Thanks.

Now I have the next problem: I want to get back from EXTERNAL into MAIN after reaching the message-end event. I have implemented this end event with a delegate, which invokes

rts.createMessageCorrelation("returnDataMsg") .processInstanceBusinessKey((String)vars.get("businessKey")) .setVariable("myVar" , vars.get("myVar")) .correlate();

That should be scenario a) according to your answer. I expected MAIN to be inactive, since it has reached a message-receive task, but I can see in the cockpit that it is not. This is also true if I define the process to be asynchronous at the corresponding step. Is the behavior different here when switching between processes within the same .bpmn?

Anyway, when the above code is reached, I am being told that

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

MAIN had been started with the correct business-key, though…

I can ignore that problem insofar as if I just correlate the end message with the receive task on bpmn level it works fine, but then how can I get payload back to MAIN with the message?

Hi @fbo,

How did you solve the exception?
I get the same error in the following process part:

The Receive Task “layer reset” has the correct message defined as the one in the message throw end event.
But what should I write in my Java class to attach it in the message throw end event?
I try the following:

public class ContinueProcessByMessageDelegate implements JavaDelegate {

@Override
public void execute(DelegateExecution execution) throws Exception {
	
	Integer layercounter = (Integer) execution.getVariable("layercounter");
	
	execution.getProcessEngineServices().getRuntimeService()
    .createMessageCorrelation("layer_reset")
    .processInstanceId(execution.getProcessInstanceId())
    //.processInstanceBusinessKey("AB-123")
    .setVariable("layercounter", layercounter)
    .correlateStartMessage();
	
}

Thanks!

Any help on what to check?

Thanks!

Hi there,
about how to get the businessKey >> execution.getBusinessKey() << this will give you businesskey of the current process instance.

And about message events, if you are getting error MismatchingMessageCorrelationException its one of these reasons: either too many executions/process definitions match the correlation or that no execution and process definition matches the correlation.
About the code fragment, hints are in the comments

execution.getProcessEngineServices().getRuntimeService()
.createMessageCorrelation(“layer_reset”)
.processInstanceId(execution.getProcessInstanceId()) // this looks like you are trying to correlate on the same process instace, are you sure the receive task has a token?
//.processInstanceBusinessKey(“AB-123”)
.setVariable(“layercounter”, layercounter)
.correlateStartMessage();

Here is my sample process for messages and correlation, all done using Camunda Modeler only.messages_events.bpmn (13.6 KB)

Hope this will help you.

Cheers,
Lukas

1 Like

I am getting the following error

org.camunda.bpm.engine.MismatchingMessageCorrelationException: Cannot correlate message ‘messageName’: No process definition or execution matches the parameters

I have two processes A and B. I am able to correlate message from A to B but the reverse is throwing the above error. What could be the reason for this issue.

Any idea to resolve this?

Regards,
Vinu

Hi Vinu,
could you please share your bpmn files with those processes?
Thanks,
Lukas

1 Like

@vinu_s, how did you solve your issue?
I have the same exact problem, I described it here:

@lhofer87, can you have a look?