Camunda BPM External service pattern
ARAVINDH RAVI
Engineering @ Convera | Cloud Native Architecture | Distributed Systems | BOAT | Process Automation | Camunda ?? | Kubernetes | Helm | Docker | Spring Boot | Python
An external task client is a simple client that allows you to implement business logic of your choosing and interact easily with the Camunda External Task REST api.
The External Task pattern utilizes a polling mechanism. Polling means that the workers periodically asking the process engine if there is any work item in the queue for processing.
The way this commonly works is:
- A task worker will fetch and lock tasks from Camunda
- The task worker then calls your external service to do the work.
- When the external service completes its work the task worker would then complete the task(s) in Camunda.
Camunda External Task Client allows to set up and execute the business logic by remote Service Tasks for your workflow. External tasks are wait states. External task client can be embedded in any client applications by adding dependencies to the classpath or we can execute it as standalone java application or separate microservice. Based on the load and resource utilization we can scale the individual workers.
In this pattern when the process engine reaches the external task then the process engine puts some tasks in a queue, workers poll this queue in regular periods to check for new tasks, claim and work on them if there are new task and mark them afterwards as finished.
There are client libraries in Java and Javascript that do this for you:
- https://github.com/camunda/camunda-external-task-client-js 11
- https://github.com/camunda/camunda-external-task-client-java
While modelling BPMN need to set Implementation="external" with topic="aTopicName"
Actions on External tasks:
- Complete External Tasks
- Extend the lock duration of External Tasks
- Unlock External Tasks
- Report BPMN errors and failures
- Share variables with the Workflow Engine
When a token reached an External Task in a BPMN process, a corresponding activity instance is created, which is waiting to be fetched and locked by a client.
We can pass a payload to the External Task upon completion of the task.
Worker class implementation
@Slf4j
public class ExternalWorker {
public static void main(String[] args) {
log.info("External task client is executing...");
ExternalTaskClient externalTaskClient = ExternalTaskClient.create().baseUrl("https://localhost:8080/engine-rest")
.asyncResponseTimeout(10000) // long polling timeout
.build();
// subscribe to an external task topic as specified in the process
// the default lock duration is 20 seconds, but you can override this
externalTaskClient.subscribe("aTopicName").lockDuration(1000).handler((externalTask, externalTaskService) -> {
String item = externalTask.getVariable("item");
Long amount = externalTask.getVariable("amount");
log.info("Charging credit card with an amount of '" + amount + "'€ for the item '" + item + "'...");
// Put your business logic here
Map<String, Object> variables = new HashMap<>();
variables.put("invoiceId", "INV001");
variables.put("invoice", "2500.00");
externalTaskService.complete(externalTask, variables);
System.out.println("The External Task " + externalTask.getId() + " has been completed!");
}).open();
}
}
External Task Handler code
subscriptionBuilder.handler((externalTask, externalTaskService) -> {
Integer retries = externalTask.getRetries();
if (retries == null) {
retries = 3;
}
String content = externalTask.getVariable("content");
String message = "Sorry, your tweet has been rejected: " + content;
System.out.println(message);
if (content.equals("retry!")) {
externalTaskService.handleFailure(externalTask, "one more", "change content!", retries - 1, 10000);
} else {
Map<String, Object> variables = new HashMap<String, Object>();
variables.put("message", message);
externalTaskService.complete(externalTask, variables);
}
Maven dependency
<dependency><groupId>org.camunda.bpm</groupId><artifactId>camunda-external-task-client</artifactId><version>${version}</version>
</dependency>
JDK 9+ Support
If you want to use a JDK higher than 1.8, please add the following dependency to the projects pom.xml<dependency><groupId>com.sun.xml.bind</groupId><artifactId>jaxb-impl</artifactId><version>2.2.4</version>
</dependency>
Camunda Java Developer
3 年How can I use another application or language for executing this external task?