Skip to content

viadee/external-task-retry-aspect

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

373 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

external-task-retry-aspect

GitHub tag (latest by date) GitHub Workflow Status

ℹ️ Description

This tool helps to control the retry-behaviour in external-task-handlers based on the official java-client provided by Camunda BPM.

⚠️ Important notice

With the latest release support for the Camunda 7 Fork Operaton is added. In this release we try to keep the compatibility to the previous releases as high as possible. Therefor the artifact is still located under de.viadee.bpm.camunda, we take the liberty to change this in upcoming releases. We also consider splitting this library into two releases one for each engine or dropping support for Camunda 7 in upcoming releases.

⭐ Features

  • Retry-behaviour for external-tasks can be configured in process-models as known from JavaDelegates like R3/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

🆕 New Feature

Starting with Release 1.12.0 to use this library with Operaton, simply replace the camunda-external-task-client dependency with the following, the retry-aspect automatically detects which library to bind to:

 <!-- works either with the original external-task-client... -->    
<dependency>
    <groupId>org.operaton.bpm</groupId>
    <artifactId>operaton-external-task-client</artifactId>
    <version>...</version>
</dependency>
        
<!-- ...or with new spring-boot-starter-external-task-client -->
<dependency>
    <groupId>org.operaton.bpm.springboot</groupId>
    <artifactId>operaton-bpm-spring-boot-starter-external-task-client</artifactId>
    <version>...</version>
</dependency>

⚠️ Also, starting with release 1.12.0 this library supports usage with either Spring-Boot 3 or Spring-Boot 4. To support this, the correct Aspect-Oriented Programming extension needs to be provided by the user at runtime. For mor info see the following dependencies section.

  1. Besides the camunda-external-task-client dependency, the following maven-coordinate needs to be added to the pom.xml. As a spring-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>
    
    <!-- The correct AspectJ Dependency at runtime for either Spring 3.x -->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-aop</artifactId>
        <version>...</version>
        <scope>runtime</scope>
    </dependency>

    <!-- ...or for Spring 4.x -->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-aspectj</artifactId>
        <version>...</version>
        <scope>runtime</scope>  
    </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>
  1. 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
  2. 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

🆕 New Feature

Starting with Version 1.12.0 for Operaton based engines, the configuration properties can also be the following, support for the camunda based properties is still available:

# Default retry-behaviour, if no retry is configured. 
# Whenever this property is configured incorrectly, 'R3/PT5M' is also used as fallback
de.viadee.bpm.operaton.external-task.retry-config.default-behavior=R3/PT5M

# Identifier used in bpmn-extension-properties, default=RETRY_CONFIG
de.viadee.bpm.operaton.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 an ExternalTaskHandler execute()-method will be caught automatically and handled as follows:
    • ExternalTaskBusinessError can be used to trigger handleBpmnError()
    • 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");
    }
}

💻 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 Camunda External-Task-Client Operaton External-Task-Client Spring Boot
1.2.x 7.15.0 Unsupported 2.5.x
1.3.x 7.16.0 Unsupported 2.6.x
1.4.x 7.17.0 Unsupported 2.6.x
1.4.2 7.17.0 Unsupported 2.7.x
1.5.x 7.18.0 Unsupported 2.7.x
1.6.x 7.19.0 Unsupported 2.7.x
1.7.x 7.19.0 Unsupported 2.7.x
1.8.x 7.20.0 Unsupported 3.1.x
1.9.0 7.21.0 Unsupported 3.3.x
1.9.1+ 7.22.0 Unsupported 3.3.x
1.10.0 7.23.0 Unsupported 3.4.x
1.11.0+ 7.24.0 Unsupported 3.5.x
1.12.0+ 7.24.0 1.0.3 3.5.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)
  • Many thanks to @jschneider97 for making the external-task-retry-aspect ready for Operaton and Springboot 4 (#147)

🔑 License


About

This tool helps to control the retry-behaviour in external-task-handlers based on the official java-clients provided by Camunda BPM and Operaton

Topics

Resources

License

Stars

Watchers

Forks

Contributors

Languages