Retrieve variables instance with synchrones call

Hello Community

I want to know how can I start a process with a REST call (synchronous) and retrieve a variable after the end of the process and return it in the call response?.

This is how I did it but the response is not synchronus :

Controller
@PostMapping(path =“/publish”)
public ResponseEntity publishAd(@RequestBody Ad ad) {

    String responseStatus= publishAdService.PublishAds(ad);

return ResponseEntity.status(responseStatus).Body(“SomeVariable”);

}

Service
public String PublishAds(Ad ad) {

	ProcessInstance instance=camunda.getRuntimeService()
			.createMessageCorrelation("PublishAdEvent")		
			.processInstanceBusinessKey(message.getTraceid())
			.setVariable("Ad",ad)					
			.correlateWithResult()
			.getProcessInstance();

	
            // Here I retrieve the variable in data base with the id of the instance		
	String responseStatus = historicRepo.getLastStatus(instance.getId());

            // I want to return the response after the end of the process but it doesn't work!!!
	return responseStatus;

}

Some Adapter
@Component
public class PublishAdAdapter implements JavaDelegate {

@Override
public void execute(DelegateExecution execution) throws Exception {
	
            //I want to retrieve this Variable after the end of the process
	execution.setVariable("responseStatus", "Created");
						
}

}

This is my BPMN: I’m working with Kafka, that’s why i used Send Task

@Adel16 if you want to execute the whole process execution in single thread(synchronously), then you shouldn’t mark asyncBefore/asyncAfter = true.

And to return the variables in the response you need to use the function .correlateAllWithResultAndVariables(), refer below code.


import java.util.List;

import org.camunda.bpm.engine.ProcessEngine;
import org.camunda.bpm.engine.runtime.MessageCorrelationResultWithVariables;
import org.camunda.bpm.engine.variable.VariableMap;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

@Service
public class MessagingService {

	@Autowired
	private ProcessEngine processEngine;

	public String PublishAds(String ad) {

		List<MessageCorrelationResultWithVariables> messageCorrelationResultWithVariables = processEngine
				.getRuntimeService().createMessageCorrelation("PublishAdEvent").processInstanceBusinessKey("traceId")
				.setVariable("Ad", ad).correlateAllWithResultAndVariables(true);

        //looping through each variable instances
		messageCorrelationResultWithVariables.forEach(var -> {
			VariableMap variableMap = var.getVariables();
			String someValue = (String) variableMap.get("someVariable");
		});

		// Here I retrieve the variable in data base with the id of the instance
		String responseStatus = "";

		// I want to return the response after the end of the process but it doesn't
		// work!!!
		return responseStatus;

	}

}

@aravindhrs thank’s for your response,

I try it but I have the same behaviour, the return is excuted before the execution of Service 2 and both services have asyncBefore/asyncAfter = false.

Even, the variable “SomeVariable” witch is set in the Adapter of Service 2 is not returned in messageCorrelationResultWithVariables.

I don’t know if there is a relation with the rest of the code!

Here is the code of my Listener to kick off the service 2 after recieving the message “AdSavedEvent” from service 1

@StreamListener(target = Sink.INPUT, condition="(headers[‘type’]?:’’)==‘AdSavedEvent’")
@Transactional
public void adSavedReceived(String messageJson) throws Exception {

	Message<JsonNode> message = objectMapper.readValue(messageJson, new TypeReference<Message<JsonNode>>() {});

	long correlatingInstances = camunda.getRuntimeService().createExecutionQuery() //
			.messageEventSubscriptionName(message.getType()) //
			.processInstanceBusinessKey(message.getTraceid()) //
			.count();

	if (correlatingInstances==1) {

		camunda.getRuntimeService().createMessageCorrelation(message.getType())
		.processInstanceBusinessKey(message.getTraceid())
		.correlateWithResult();

	}
} 

Thank’s a lot for your help

@Adel16 A Receive Task is a simple task that waits for the arrival of a certain message. When the process execution arrives at a Receive Task, the process state is committed to the persistence storage. This means that the process will stay in this wait state until a specific message is received by the engine, which triggers continuation of the process beyond the Receive Task., so you’ll get response once the execution token arrives at the first waiting state (response 1 task). If you would like to receive the response with variables at the end of the process execution, then I would suggest you to add webhooks as callback in the end event of the process to return the variables.

@aravindhrs

I tried asyncBefore/asyncAfter = false and the code bellow did not return to me the variable witch is setted in the last Adapter (“responseStatus”), so I don’t understand how the Rest Call for the whole process is Synchronous?, because i’m not able to return this variable to my Client

Do you have any example with a REST CALL to the whole process with a response retrieved in the end event?

Thank’s a lot

Best

ADEL

Dummy solution would be to spin instance of process in rest call and loop with sleep checking if processes ended and then returning response to caller.

Hello @BerndRuecker,

I didn’t find solution for this problem, I want to know if Camunda allows to do REST Call and return response after the end of the whole process or every execution is synchronus? If Yes, do you have any example or video to solve this kind of need?

Thank’s a lot

I have a code example here: flowing-retail/PaymentRestHacksControllerV4.java at master · berndruecker/flowing-retail · GitHub using a Semaphore - not the only way to do it - but works well for me.

Sorry for the late response - got a bit stuck in my inbox :frowning: