How to set local variables for subprocess by Zeebe Client

Hi,
I have a process as shown in the picture below:

After Task 1, I have an array variable called “users” and I want to loop through each user to process and update their information in Task 2.

My problem is that I cannot set the variable as a subprocess scope by using the Zeebee client. The variable set by the Zeebee client in Task 2 is always in process scope.

P/s: I don’t want to use Response Mapping of REST connector because I have a method to check variable size before return to Camunda

Thanks in advance

I don’t think this is specific to Camunda 8. If you set the variable in Task1 then it will be process scope. See here Variables | Camunda 8 Docs

When the process instance enters a subprocess or an activity, a new scope is created. Activities in this scope can see all variables of this and of higher scopes (i.e. parent scopes). However, activities outside of this scope can not see the variables which are defined in this scope.

Hi @cma,
I understand your point about variables being set in Task1, and I don’t have any problems with that.

My concern is about how to set subprocess scope variables in Task2 using the Zeebee Client. Note that I do not want to use “Response Mapping” to create subprocess variables; I need to use the Zeebe Client to create variables because I have middleware that checks the variable size before returning it to Camunda.

Update their information WHERE?

If you want to update their information in the array variable (from Task 1), then that array variable CANNOT be scoped to the subprocess.
Have a good read of Variable Propagation

This statement is really unclear. Could you break it down more? The existence of middleware does not immediately infer the client creating variables.

Hi @GotnOGuts ,

My mean that I use ZeebeClient SDK to set variables as code below:

await _zeebeClient
  .NewSetVariablesCommand(processInstanceKey)
  .Variables(serializedVariables)
  .SendWithRetry(timeout);

The variables are set that are always in process scope. Are we able to set variable scope by ZeebeeClient SDK?

Regards,
Larry

Hi @Larry , I’d like to offer some guidance:

First, what you are trying to do, adding a variable with a specific scope via the Zeebe client, depends, with the Spring Zeebe Client, it is not yet implemented, could be that I have not seen any example so far. I normally use the Spring Zeebe Client, and an instruction like this:

@ZeebeWorker(type = "write-variables"):
public void writeVariables(final JobClient client, final ActivatedJob job) {
    ...
    Map<String, Object> map = new HashMap<>();
    map.put("Message", "Hello World");
    client.newCompleteCommand(job.getKey()).variables(map).send(); //This is writing variables to the process
    ...
}

results in setting the variables in the process scope. The documentation of the command I use, do not mention anything about the scope, see JobClient - zeebe-client-java 8.3.0-alpha1 javadoc

If you use the spring zeebe, then you will need here a workaround :

  • Make the subprocess a call activity, the call activity when invoked will have its own scope. You will only need to control the input and output mapping.

You could try without the Spring Zeebe, and use the raw Zeebe client, with it you would use something like this:

Map<String, Object> variablesMap = new HashMap<>();
map.put("text", "Some text");
ZeebeClientBuilder clientBuilder = ZeebeClient.newClientBuilder().gatewayAddress("some address");
ZeebeClient zeebeClient = clientBuilder.build();
zeebeClient.newSetVariablesCommand(1L).variables(variablesMap).local(true).send();

Here you are using this Command SetVariablesCommandImpl - zeebe-client-java 8.3.0-alpha1 javadoc, which has a local method to tell the process if a variable is local. I have not tested this extensively, but it could be what you need. Just remember, this is possible with the raw Zeebe client, not with the Spring Zeebe client. The Spring Zeebe client is just a wrapper around the Zeebe client.

Second, regarding the part “I need to use the Zeebe Client to create variables because I have middleware that checks the variable size before returning it to Camunda.” . I would like more context here, because as it is, sounds like a little misunderstanding of the architecture.

Let me explain, the Zeebe Client is ultimately responsible for sending commands to the brokers,so there is nothing in between the Zeebe Client and the Broker, unless you intercept the request, do something with the intercepted request, and then forward it again to the broker, for which you will need again the client.

I actually think your middleware uses the Zeebe client, and the situation is reduced to the first point.

Hi Gerardo,

I think you’ve misunderstood… I don’t have the issue here.
The clarifying questions that I asked of the Original Poster (@Larry ) have not actually been answered.

This might not be a case of missing features or commands, but of misset expectations.

True @GotnOGuts I tagged the incorrect person. I fixed, I tagged him now.

Hi @g.manzano ,

Thanks for your answer, that is exactly what I need.
I have another question, are we able to send element instance key such as process instance key via REST connector?

Second, regarding the part “I need to use the Zeebe Client to create variables because I have middleware that checks the variable size before returning it to Camunda.” . I would like more context here, because as it is, sounds like a little misunderstanding of the architecture.

At this point, due to the limitation of variable size, I have created a class that serves as a wrapper for the Zeebee Client. The purpose of this class is to check the size of the variables before invoking the Zeebee Client to send them to Camunda. In this scenario, there are two possible situations:

  1. If the variable size does not exceed the limitation, the class will proceed to call the Zeebee Client and send the variables as usual.
  2. If the variable size exceeds the limitation, the class will store the variable in an external storage and instead send a URL reference to Camunda, rather than the actual variable value.

Regards,
Larry

Hi @Larry

Your second question: are we able to send element instance key such as process instance key via REST connector?. I would try to send it in the query parameters: REST Connector | Camunda Platform 8 Docs, because the query parameters is a FEEL map, in that map you can try to set the value you want. FEEL should be able to read the instance variable from the context, because that is how FEEL expressions work, example, when you evaluate a gateway you use a FEEL expression that reads a instance variable, so based in that logic it should be possible, I have not tried it, the requirement is too specific, please try on your own.

So store the value you want inside an instance variable, and try to send that instance variable in the query parameters.

Hope that helps.