external-task-retry-aspect
external-task-retry-aspect copied to clipboard
This tool helps to control the retry-behaviour in external-task-handlers based on the official java-client provided by Camunda BPM
external-task-retry-aspect
ℹ️ Description
This tool helps to control the retry-behaviour in external-task-handlers based on the official java-client provided by Camunda BPM.
⭐ Features
- Retry-behaviour for external-tasks can be configured in process-models as known from
JavaDelegates
likeR3/PT1M
, meaning three times each after one minute - Every
Exception
leads to a retry - no manual handling within handlers necessary - Special error-type to force instant incidents - skipping any retry-behaviour
- Additional error-type to create a business-error, which must be handled in process
- Configurable default retry-behaviour
🚀 How to use
- Besides the
camunda-external-task-client
dependency, the following maven-coordinate needs to be added to thepom.xml
. As aspring-boot-starter
, the aspect will be loaded automatically as soon as the handler-application starts:
<dependencies>
<!-- works either with the original external-task-client... -->
<dependency>
<groupId>org.camunda.bpm</groupId>
<artifactId>camunda-external-task-client</artifactId>
<version>...</version>
</dependency>
<!-- ...or with new spring-boot-starter-external-task-client since version 7.15.0 -->
<dependency>
<groupId>org.camunda.bpm.springboot</groupId>
<artifactId>camunda-bpm-spring-boot-starter-external-task-client</artifactId>
<version>...</version>
</dependency>
<!-- finally: the retry-aspect itself -->
<dependency>
<groupId>de.viadee.bpm.camunda</groupId>
<artifactId>external-task-retry-aspect-spring-boot-starter</artifactId>
<version>...</version>
</dependency>
</dependencies>
-
Add extension-property to an external-task:
- The property-name is configurable (see below), default:
RETRY_CONFIG
- Possible values might be, default:
R3/PT5M
-
R1/P1D
: 1 retry after 1 day -
R2/PT2H
: 2 retries after 2 hours each -
R3/PT3M
: 3 retries after 3 minutes each -
PT5M,PT10M,PT20M,PT1H,PT12H,P1D
: 6 increasing retries; 5, 10, 20 minutes, 12 hours, 1 day
-
- The property-name is configurable (see below), default:
-
Make sure, the
ExternalTaskHandler
is capable to access extension-properties :
public class HandlerConfig {
@Autowired // e.g. spring component
private ExternalTaskHandler myExternalTaskHandler;
public void openHandler() {
new ExternalTaskClientBuilderImpl()
.baseUrl("http://camunda/engine-rest").build()
.subscribe("worker-topic")
.handler(myExternalTaskHandler) // injected spring component
.includeExtensionProperties(true) // important, bc. the default: false
.open();
}
}
Alternatively, if using spring-boot-starter-external-task-client
, activate extension-properties e.g. in the application.yaml (more information):
camunda.bpm.client:
subscriptions:
worker-topic:
include-extension-properties: true
Configuration options
These properties are available, they can be set e.g. in application.properties
:
# Default retry-behaviour, if no retry is configured.
# Whenever this property is configured incorrectly, 'R3/PT5M' is also used as fallback
de.viadee.bpm.camunda.external-task.retry-config.default-behavior=R3/PT5M
# Identifier used in bpmn-extension-properties, default=RETRY_CONFIG
de.viadee.bpm.camunda.external-task.retry-config.identifier=RETRY_CONFIG
🧙 How this might help?
A comparison of some ConventionalHandler
with an AspectedHandler
explains how the error-handling
can be completely left out, because anything is done by the retry-aspect
:
ConventionalHandler
without Retry-Aspect
@Component
public class ConventionalHandler implements ExternalTaskHandler {
public void execute(ExternalTask task, ExternalTaskService service) {
try {
// do some business-logic and complete if fine...
service.complete(task);
// ...or maybe end with some bpmn-error, that has to be handled within process
service.handleBpmnError(task, "bpmn-error-code");
} catch (Exception error) {
// catch errors and think about retries and timeout
service.handleFailure(task,
"error-message", // shown in Camunda Cockpit
"error-details", // e.g. stacktrace, available in Camunda Cockpit
task.getRetries() - 1, // how many retries are left? (initial null)
300000L); // time to next retry in ms
}
}
}
AspectedHandler
using Retry-Aspect
- No
try-catch
needed, this is done automatically, i.e. all errors thrown in anExternalTaskHandler
execute()
-method will be caught automatically and handled as follows:-
ExternalTaskBusinessError
can be used to triggerhandleBpmnError()
-
InstantIncidentException
can be used to skip retries and create an incident instantly - Any other exception leads to the specified retry-behaviour
-
@Component
@ExternalTaskSubscription("my-topic")
public class AspectedHandler implements ExternalTaskHandler {
public void execute(ExternalTask task, ExternalTaskService service) {
// do some business-logic and complete if fine...
service.complete(task);
// ...or maybe end with some bpmn-error, that has to be handled within process
throw ExternalTaskBusinessError("bpmn-error-code");
}
}
:computer: Versions
The following versions are used. Older versions are probably not maintained, but in most cases, it should be possible to use a newer version of the Retry-Aspect in combination with an older version of the External-Task-Client. If you encounter any issue, please feel free to contact me.
Retry-Aspect | External-Task-Client | Spring Boot |
---|---|---|
1.2.x | 7.15.0 | 2.5.x |
1.3.x | 7.16.0 | 2.6.x |
1.4.x | 7.17.0 | 2.6.x |
1.4.2 | 7.17.0 | 2.7.x |
1.5.x | 7.18.0 | 2.7.x |
1.6.x | 7.19.0 | 2.7.x |
1.7.x | 7.19.0 | 2.7.x |
1.8.x | 7.20.0 | 3.1.x |
🤹 Collaboration
This tool was build by viadee Unternehmensberatung AG. If you are interested to find out what else we are doing, check out our website viadee.de. If you have any feedback, ideas or extensions feel free to contact or create a GitHub issue.
🏆 Thanks
- Many thanks to @ChrisSchoe for making the external-task-retry-aspect spring-boot-3-ready (#107)