Using process instance id as correlation key for intermediate catch events

Hi i am new to camunda and switching from RHPAM (redhat jbpm engine).

We have used there a lot of intermediate message catch events. In the redhat engine the message is always send to a specific process instance id, so this is then stored on our objects so we can easily push a message to a process. Is it possible to define in the camunda modeler that the correlation key is the process instance id? is there some internal variable which points the the process instance id?

Hello @mho ,

using the process instance key as correlation key is good idea in first place, but not recommended for production. The process instance is indeed designed to last, but it can be restarted to solve some issue. This would cause a change in the process instance key and destroy your binding.

My recommendation is to control message correlation by providing a process variable that serves. This process variable can be retrieved in a send task and be transferred along with the outbound message. The inbound message will still hold this information and can then use it as correlation key again.

This information can be business-wise (for example an order id, a customer id ā€¦). By doing this, you have more control over the actual correlation.

I hope this helps

Jonathan

1 Like

Hi @jonathan.lukas,

thanks for the fast reply.

I understand that to bind the correlation key to a business object is much butter, but i would like to migrate some older processes from RHPAM to camunda. i am using everywhere the process instance id, this would cost a lot of effort to change that in the backend logic.
So is there a possibility to set a correlation key to a process instance id or not?

@jonathan.lukas @mho
Hi all,

I have a similar problem.

In Camunda 7 there was ability to send the process instance id during message correlation:

runtimeService
                .createMessageCorrelation(MESSAGE_NAME)
                .processInstanceId(processInstanceId)
                .setVariables(variables)
                .correlateWithResult();

If I understood Lukas answer good, the above code can be written in Camunda 8 like this:

        Map<String, Object> correlationKey = Map.of("MESSAGE_CORRELATION", processInstanceId);
        return zeebeClient.newPublishMessageCommand()
                .messageName("MESSAGE_NAME")
                .correlationKey(correlationKey.get("MESSAGE_CORRELATION").toString())
                .variables(correlationKey)
                .variables(variables)
                .send();

EDIT:

After testing I noticed that variables cannot be send at the same time as message, i.e. all variables which is used by message boundary event should be defined before token arrives to (wait for) that event (which is expected):
- Error type: EXTRACT_VALUE_ERROR
- Error message: failed to evaluate expression ā€˜MESSAGE_CORRELATIONā€™: no variable found for name ā€˜MESSAGE_CORRELATIONā€™

My question is what is the best practice, where to define correlation key variables?
In the service task immediately after process is started?

Hello @Jovan_Zoric ,

the correlation key works like the following:

  • in your message catch event, you define a binding for the correlation key which is an expression that has the correlation key as result
  • in your code, you put the value you expect the message catch event to have as value in the correlation key field
  • then, you can also transfer variables. This field is not intended as correlation field rather than data transfer (message body)

Example:


Here, it is expected that your process instance contains a variable called businessKey. The value of this variable will become your correlation key.

If you start a process instance, you would now use these variables:

{"businessKey":"abc123"}

To correlate a message to this process instance, you would use this command:

return zeebeClient.newPublishMessageCommand()
                .messageName("My message")
                .correlationKey("abc123")
                .variables(variables)
                .send()
                .join();

I hope this helps

@mho no there is no way at the moment. This could be enabled if the processInstanceKey would somehow be available as FEEL expression input, which is not the case. As workaround, you could set the processInstanceKey after process start as variable to a process instance. This would not work if you have a process-wide event-subprocess.

Jonathan

1 Like