Camunda process orchestration.
- Hanno Van Der Walt
- Jan 26, 2023
- 5 min read
Updated: Jan 30, 2023
In this article, we will learn how to use the Camunda platform and achieve end-to-end automation using external Java tasks.
How about we start with what Camunda is? Camunda is software designed for process orchestration and aims to achieve end-to-end automation. It allows us to visualize and create business process flows called BPMN diagrams.
Camunda can be used in a few different ways, but one of the most popular ways is by using external tasks. The benefit of using external tasks is that the workers that do the work are separated from the Camunda engine and make use of Camunda’s REST API to fetch instances to process. This results in a true decoupled microservice architecture.
A few of the benefits of using external tasks include but is not limited to independent maintenance, independent scaling, being able to use different programming language per individual task, etc.
Next, we will get some hands-on experience by making a simple application called ‘let’s fly’.
Here are my Git repositories for the Camunda Engine and the let’s fly Spring Boot application. Please follow along and refer to it when you are stuck :
You can start by cloning the Camunda-Engine Git repository and have a look at the lets_go_fly.bpmn file under the resources folder. We can open and edit BPMN files using Camunda Modeler, which you can download here.

On a high level overview, the application is for deciding whether you will be going on a flight or not. We will decide if we go for a flight or not by checking if the weather is good enough to go flying and if the aircraft passes the preflight inspection and is safe to fly. We first try to check the weather via an API service and set the isGoodWeather Camunda variable according to the weather. If the weather is good we proceed to do the preflight inspection. If the weather is bad, we cancel our flight and end the process. Then we do the preflight inspection which is also an external task and set the isPassedPFI variable to true or false depending on whether it passed or not. If it passed, we take off, if it failed, we cancel the flight. The weather API can be down from time to time, so if an error is thrown, we can manually approve the weather.
Setup
In the Lets-Fly Spring Boot project, under the camundaworkers folder, we will find the CheckWeather Java class, which is used for the checkWeather external task. The class uses the service called WeatherService, which generates a random integer and sets the Camunda variables based on the value :
@Component
@ExternalTaskSubscription("checkWeather")
public class CheckWeather implements ExternalTaskHandler {
private final WeatherService weatherService;
@Autowired
public CheckWeather( WeatherService weatherService) {
this.weatherService = weatherService;
}
@Override
public void execute(ExternalTask externalTask, ExternalTaskService externalTaskService) {
Weather weather = weatherService.getWeather();
boolean isGoodWeather;
isGoodWeather = ((weather.getWindSpeed() > 10) ? false : true);
VariableMap variables = Variables.createVariables();
variables.put("isGoodWeather", isGoodWeather);
if(weather.getWindSpeed() > 14){
externalTaskService.handleBpmnError(externalTask , "Simulated_Error");
}
externalTaskService.complete(externalTask,variables);
}
}
To enable the external task to poll the Camunda engine for process instances, there are a few things we have to do :
When clicking on the task block, make sure to choose External under the Implementation dropdown, and choose a topic (in our case checkWeather). Make sure to change the task to a service task by clicking on the wrench icon.

2.) Next, we add the topic we chose in the Camunda modeler to the Java external task class in the @ExternalTaskSubscription as shown in the above CheckWeather Java class.
3.) Update the application.yml file to configure the external workers like in the following code. You have to configure Camunda variable names (that the external task will fetch) isGoodWeather and isPassedPFI, your process definition key (lets_go_fly), and the topic names of the external workers (checkWeather and isPassedPFI).
camunda.bpm.client:
base-url:http://localhost:8080/engine-rest# the URL pointing to the Camunda Platform Runtime REST API
lock-duration:10000# defines how many milliseconds the External Tasks are locked until they can be fetched again
subscriptions:
checkWeather:# topic name of the External Service Task
variable-names: [isGoodWeather] # our business logic doesn't require any variables, so don't fetch them
process-definition-key:lets_go_fly# only filter for External Tasks with this process definition key
preFlightInspection:# topic name of the External Service Task
variable-names: [isGoodWeather, isPassedPFI] # our business logic doesn't require any variables, so don't fetch them
process-definition-key:lets_go_fly# only filter for External Tasks with this process definition key
logging.level.org.camunda.bpm.client:DEBUG# increase the log level of the application
server.port:8181
Error Handling
Next, we will look at how to handle any errors that occur in the checkWeather external worker. To do this, we need to add an error boundary event to our BPMN diagram :

This allows us to catch any BPMN errors thrown from within our external tasks. We used the following code to throw a BPMN error from within our external Java task:
externalTaskService.handleBpmnError(externalTask , "Simulated_Error");
The thrown BPMN error then gets caught by the boundary error event and passes it to the user task where we can manually approve the weather.
Next, we have the preflight inspection external task. It works similar to the CheckWeather worker. Note we also create a subscription using the ExternalTaskSubscription decorator which should align with the application.yml file and the topic name in the BPMN file.
@Component
@ExternalTaskSubscription("preFlightInspection")
public class PreFlightInspection implements ExternalTaskHandler {
@Override
public void execute(ExternalTask externalTask, ExternalTaskService externalTaskService) {
boolean isPassedPreFlightInspection;
RandomrandomNum=newRandom();
intrandomNumber= randomNum.nextInt(20);
isPassedPreFlightInspection = ((randomNumber > 10) ? false :
true);
VariableMapvariables= Variables.createVariables();
variables.put("isPassedPFI", isPassedPreFlightInspection);
externalTaskService.complete(externalTask,variables);
}
}
Starting a process
Now that we have a high-level and technical understanding of the application, let’s start a process. To do this we will use Postman to make an HTTP POST request to the Camunda engine like the following :

URL: localhost:8080/engine-rest/process-definition/key/lets_go_fly/submit-form (make sure to use the port where your Camunda engine is running on)
{
"variables": {
"isGoodWeather" : {"value":false}
},
"businessKey" : "TestFlight_2"
}
After sending the request, go to Camunda cockpit on http://localhost:18080/. Go into the Let’s Go Fly process definition and you will see your process token on the checkWeather task like below.

Let’s start a few processes using postman and investigate the different paths it can take.

As you can see, the processes can follow multiple paths based on the variables, let’s look at a few scenarios:
) the isWeatherGood and isPassedPFI Camunda variables are true and we will take off :

2.) The isGoodWeather Camunda variable is false, and we cancel the flight :

3.) Something went wrong while checking the weather and we have to approve manually

We can claim the user task and set the isGoodWeather variable manually :

As we can see Camunda is a very powerful tool and the implementations are endless. If you would like to learn more I recommend you go check out the official Camunda courses and documentation.
Comentários