How to correlate data to Subprocesses (Parallel execution and not call activity) of same process instance Id

Hi, How can I correlate data to respective subprocess (Parallel execution) of same process instance Id? Because the correlation scope executionId is different from subprocess executionId and I am not able to find one using the other.

Here is the code from sample project I created to test this. First send GET request to /start and then GET request to /camunda-correlate-data to test the correlation problem.

I tried the code runtimeService.serVariableLocal(executionId, varname, varvalue) but the delegate in subprocess will not get value because the executionId will be different.

I tried the code runtimeService.serVariable(executionId, varname, varvalue) but last subprocess data is getting overridden for all subprocesses.

How to solve this?

@Component
@Slf4j
@AllArgsConstructor
public class SetCamundaValues implements JavaDelegate {
    @Override
    public void execute(final DelegateExecution execution) {
        log.info("SetCamundaValues processInstanceId {}, " +
                "executionId {}", execution.getProcessInstanceId(), execution.getId());
        execution.setVariableLocal("processList", List.of("1", "2", "3")); // create 3 child processes
    }
}
@Component
@Slf4j
@AllArgsConstructor
public class SetCamundaValuesChildProcess implements JavaDelegate {
    @Override
    public void execute(final DelegateExecution execution) {
        log.info("SetCamundaValuesChildProcess processInstanceId {}, " +
                "executionId {}", execution.getProcessInstanceId(), execution.getId());
        execution.setVariableLocal("a-child-execution-var", "value"+execution.getId());
    }
}
@Slf4j
@RestController
public class CamundaController {
    private final RuntimeService runtimeService;

    public CamundaController(
            RuntimeService runtimeService
    ) {
        this.runtimeService = runtimeService;
    }

    @GetMapping(value = "/start", produces = APPLICATION_JSON_VALUE)
    public void start() {
        runtimeService.createProcessInstanceByKey("Process_Test").execute();
    }

    @GetMapping(value = "/camunda-correlate-data", produces = APPLICATION_JSON_VALUE)
    public void camunda() {
        final List<Execution> waitingExecutions = runtimeService.createExecutionQuery()
                .messageEventSubscriptionName("Message_RECEIVE")
                .list();
        final var executionId = waitingExecutions.get(0).getId();
        final var executionId2 = waitingExecutions.get(1).getId();
        final var executionId3 = waitingExecutions.get(2).getId();

        // The delegate in the respective Child process cannot read this variable value because the executionId here
        // will be different from executionId in the subsequent delegate of the child process which tries to read this variable.
        // I tried to use setVariable(executionId) instead of setVariableLocal(executionId) but the variable value is getting
        // overridden so only the last variable value is accessible to all child processes.
        runtimeService.setVariableLocal(executionId, "correlated-data", "value of correlated data variable1");
        runtimeService.setVariableLocal(executionId2, "correlated-data", "value of correlated data variable2");
        runtimeService.setVariableLocal(executionId3, "correlated-data", "value of correlated data variable3");

        runtimeService.messageEventReceived("Message_RECEIVE", executionId);
        runtimeService.messageEventReceived("Message_RECEIVE", executionId2);
        runtimeService.messageEventReceived("Message_RECEIVE", executionId3);
    }
}
@Component
@Slf4j
@AllArgsConstructor
public class ReadCorrelationData implements JavaDelegate {

    @Override
    public void execute(final DelegateExecution execution) {
        log.info("ReadCorrelationData processInstanceId {}, " +
                "executionId {}", execution.getProcessInstanceId(), execution.getId());

        // How to get correlated data variable value of respective executionId???
        final var correlatedDataText = (String) execution.getVariable("correlated-data");

        log.info("ReadCorrelationData executionId: {}, correlatedDataText {}", execution.getId(), correlatedDataText);
    }
}

diagram_1.bpmn (6.9 KB)

Solved it this way:

In sub-process in any delegate before the message-received step, set the sub-process executionId in a Camunda variable called, let’s say, “subProcessExecutionIdToBeUsedLaterInCorrelationCode”.

Later in the code where message correlation is to be done, you already have the waitingExecution.getId() which is the correlation executionId. Now you can use it to get its respective subprocess executionId using:

runtimeService.getVariable(correlationScopeExecutionId, subProcessExecutionIdToBeUsedLaterInCorrelationCode); // This will work because correlation executionId is like a child of sub-process so all the sub-process local variables are visible to correlation executionId

Now you have both sub process executionId and correlation scope executionId with you at the time of correlation. Now you have to set variables to sub process execution and message correlation to correlation executionId:

runtimeService.setVariablesLocal(subProcessExecutionId, variablesMap);

runtimeService.messageEventReceived(Constants.MESSAGE_RECEIVED, correlationScopeExecutionId);