Understanding Call Activity Variables and Boundary Events

Hello,

I’ve been working on a series of POCs to prove out the viability of Camunda for an upcoming project, and I’ve run into a problem / question regarding how process variables are passed between a call activity and a boundary event. Below I’ve created a simplified example of the flow that is causing me this issue.

This is the parent process:
28%20PM

Here, a process instance invokes a call activity. That call activity has an interrupting timer boundary event attached to it. When the timer triggers, my expectation is that it should redirect the process instance to the new path and through my helper service that simply logs the process variables. The call activity here is configured such that the “Out Mapping” for variables is set to “all”, with “local” unchecked.

This is the process invoked by the call activity:
05%20PM

Here is where things get interesting. The purpose of this process, by flow chart element here, is:

  1. Create a new execution variable “smsSendCount” with the script element and increment it.
  2. Contact a 3rd party API to send a text.
  3. Wait until a text response is received.

The relevant bit here is the first step, in which smsSendCount is created and / or incremented. My expectation, based on what I’ve seen in the documentation so far, is that if the timer boundary event in the parent process is triggered after the “Increment SMS Count” step has been completed, that the new “smsSendCount” variable will be passed to the “Log Vars” step in the parent process. However, in practice that variable is not present.

So my question is this: does a call activity only pass newly created variables back to the parent process if the call activity has completed? Is this behavior actually expected, or should all execution variables, even new ones, be passed to the interrupting boundary event?

Hello,

We observe the same behavior in our BPM:

“The interrupting boundary event does not call the variable output mapping declared on the interrupted activity.”

And we think, this is done by design.

However, our bypass solution is currently:

  1. We add an end ExecutionListener on the subprocess which can be interrupted

  1. The listener detects is the activity is cancelled or not
final ExecutionEntity executionEntity = (ExecutionEntity) execution;
boolean isCanceled = executionEntity.isCanceled();
  1. If the activity is not cancelled, we do nothing and the variable output mapping is done.

  2. If the activity is cancelled, we process the output mappings in code

if (isCanceled) {
   executionEntity.getParentScopeExecution(true).setVariable("result", execution.getVariable("result"));
}

But ideally, we would like to process the Variable output mapping defined in the activity but we haven’t succeeded yet.

Is there another way to do ?
Thanks and regards,

Hello again,

We finally found a generic solution for this use case.

Here is the code of our ExecutionListener :

public class ForceOutputMappingAfterInterruption implements ExecutionListener {
    @Override
    public void notify(DelegateExecution execution) throws Exception {
        final ExecutionEntity executionEntity = (ExecutionEntity) execution;
        if (executionEntity.isCanceled()) {
            ActivityImpl parentActivity = executionEntity.getParentScopeExecution(true).getActivity();
            if (parentActivity != null) {
                ActivityBehavior parentActivityBehavior = parentActivity.getActivityBehavior();
                if (parentActivityBehavior instanceof CallActivityBehavior) {
                    CallActivityBehavior parentCallActivityBehavior = (CallActivityBehavior) parentActivityBehavior;
                    ExecutionEntity superExecution = executionEntity.getSuperExecution();
                    parentCallActivityBehavior.passOutputVariables(superExecution, execution);
                }
            }
        } 

    }

We are now able to call the output variable mapping by getting the CallActivityBehavior attached to the parent execution.

Regards,

1 Like

Thanks for posting the solution you’re using :slight_smile: