Camunda Service Tasks: A Step-by-Step Guide To External Tasks (Topics)

Shashir
Nerd For Tech
Published in
6 min readMay 26, 2024

In this article, we’ll explore the concept of external tasks, their benefits, and how to configure a service task implementation as an external task, also known as topics, within Camunda. Using a simple example, we’ll walk through the process step-by-step, including how to set up retry attempts on periodic intervals.

Photo by Callum Shaw on Unsplash

Version used: Camunda 7.0

Camunda Service Tasks: Workflow Automation and Integration

A service task in Camunda allows us to seamlessly integrate and execute business logic within the same application or from a remote system, providing flexibility and scalability in our workflow automation.

  1. Java Delegate (Java class)
  2. Delegate Expression
  3. Connectors
  4. External Task
  5. Expression

After reading this article, you’ll have a comprehensive understanding of external tasks, their advantages, and how to configure them in Camunda to optimize your workflow management.

What is an External Task?

As the name suggests, the process engine publishes work to an external system, which is then executed by a worker and completed as a task. The invoked business service can be local or remote, and the remote system can be implemented in any programming language, using REST or SOAP web services for invocation. This allows for flexibility and scalability in integrating with external systems.

Example:

How it works?

As we’re aware, the process engine governs the workflow. When a service task with an external task implementation is encountered, the process engine generates an external task instance (as illustrated in steps 1 and 2) and adds it to the external task list, enabling seamless integration with external systems.

How External Task Works in Camunda

Each external task instance is assigned a distinct topic, which specifies the particular work to be executed by the corresponding external worker. As illustrated in the diagram, an external task instance with a matching colour to an external worker represents the system responsible for executing the actual business logic, such as External Worker 1, 2, or 3. Once the task is complete, the external worker sends a confirmation back to the process engine, enabling the engine to proceed with the workflow (step 3).

External workers retrieve and lock external tasks associated with a specific topic, using a timestamp-based locking mechanism that prevents multiple workers from accessing the same task simultaneously. This ensures that each task is processed exclusively by a single worker, avoiding potential conflicts and ensuring efficient workflow execution.

When to Use External Workers and when to use Connectors

  1. Is low-level API access needed?
    Use job workers for tasks that demand direct access to Camunda’s low-level API, enabling precise control and customization.
  2. Non-Java worker logic?
    Job workers provide the flexibility to implement logic in any programming language of your choice, enabling language-independent development and integration.
  3. Reusable worker logic?
    Develop a Connector to encapsulate reusable logic, enabling seamless deployment and integration across various environments, promoting scalability and flexibility.
  4. Focus on worker logic only?
    Use Connectors to abstract away low-level Camunda API details.
  5. Standardized modelling experience?
    Develop a Connector to integrate a standardized modelling experience with runtime behaviour, ensuring consistency and alignment between design and execution, and streamlining the workflow development process.

Let’s understand external tasks with an example:

Consider a typical business scenario: a customer places an order for coffee and completes the payment process, expecting to receive their coffee delivery. This everyday use case illustrates a straightforward workflow, where the customer’s order and payment trigger a series of processes that ultimately lead to the delivery of their coffee

Example: Coffee Order Process flow

Step 1: Let’s configure the External task for “Order Coffee” as below

Step 2: Configure “Payment Success” as an external task

Token Simulation across the workflow with parallel gateway

In this scenario, the ‘Order Coffee’ and ‘Payment Success’ external task services are implemented in a remote system, requiring subscription and configuration of external task handler properties. This can be achieved through either a property/yml file or Java annotations, as shown below.

Two ways to subscribe to a Camunda topic

Properties:

  • camunda.bpm.client.base-url to configure the URL pointing to the Camunda Platform Runtime REST API
  • camunda.bpm.client.lock-duration → defines how many milliseconds the External Tasks are locked until they can be fetched again
  1. @ExternalTaskSubscription — Camunda Topic subscription on Java class
@Component
@ExternalTaskSubscription(
topicName = "payment-success-topic",
processDefinitionKey = "coffee-order-process",
lockDuration = 10000,
includeExtensionProperties = true,
variableNames = "price"
)
public class PaymentSuccessExternalHandler implements ExternalTaskHandler {
...
...
}

application.yml:

camunda.bpm.client:
base-url: http://localhost:9991/engine-rest

2. Topic subscription from application.yml file

@Component
@ExternalTaskSubscription("order-coffee-topic")
public class OrderCoffeeExternalHandler implements ExternalTaskHandler {
...
...
}
camunda.bpm.client:
base-url: http://localhost:9991/engine-rest #
lock-duration: 10000
subscriptions:
order-coffee-topic:
variable-names: []
process-definition-key: coffee-order-process

Below we can find the heatmap representing traffic across the workflow.

Testing — Coffee Order process from Postman: Trigger a request as below to start the process.

Note: The message name is the name of the message start event (global message reference).

Enabling Automated Retry Mechanism for External Tasks: A Guide to Configuring Retry Intervals for Failures

@Component
@ExternalTaskSubscription(
topicName = "payment-success-topic",
processDefinitionKey = "coffee-order-process",
lockDuration = 10000,
includeExtensionProperties = true,
variableNames = "price"
)
public class PaymentSuccessExternalHandler implements ExternalTaskHandler {

private final static int DEFAULT_RETRIES_NO = 3;
private final static int RETRY_TIMEOUT = 30_000; // retry every 30 seconds

@Override
public void execute(ExternalTask externalTask, ExternalTaskService externalTaskService) {
System.out.println("PaymentSuccessExternalHandler :: STARTED");
....
....
try{
... BUSINESS LOGIC: THROWS EXCEPTION - if PRICE is EVEN
externalTaskService.complete(externalTask, variableMap);
}catch (Exception exception) {
System.out.println("PaymentSuccessExternalHandler :: EXCEPTION - "+price);
externalTaskService.handleFailure(
externalTask,
exception.getMessage(),
exception.getStackTrace().toString(),
retryCount(externalTask.getRetries()),
RETRY_TIMEOUT);
}

System.out.println("PaymentSuccessExternalHandler :: END");
}

private int retryCount(Integer taskRetries) {
Logger.getLogger("Payment Success")
.log(Level.INFO, "RETRY-COUNT::: " + taskRetries);
if (taskRetries == null) { // initially task.retries is null
return DEFAULT_RETRIES_NO;
}
return taskRetries - 1;
}
}

Following three retry attempts, as configured, incidents are generated post 30-second intervals, as seen in the system.

Given that the provided value for the ‘price’ variable is an even number, an exception will be thrown, triggering a retry mechanism that will attempt to resolve the issue up to three times before exhausting the attempts and resulting in an incident being logged in the cockpit.

I hope this article has helped explain the fundamental configurations for external tasks, also known as Camunda topics, using a coffee shop process as an example. We explored the various configuration properties and their purposes, leveraging annotation levels and property configurations provided by the Camunda library. This knowledge should help you set up and manage external tasks efficiently in your Camunda workflows.

Reference:

  1. https://docs.camunda.org/manual/7.21/user-guide/process-engine/external-tasks/
  2. https://docs.camunda.org/manual/7.21/webapps/cockpit/bpmn/failed-jobs/
  3. https://docs.camunda.io/docs/components/
  4. http://camunda.org/bpmn/reference.html

--

--

Shashir
Nerd For Tech

Middleware Chapter Lead & Java Developer — Java/Python/Spring/Microservices/Kafka/Kubernetes/OCP/Camunda/Splunk/Az Cloud https://www.linkedin.com/in/shashi999