What are you looking for?

Spring Boot Starter for the External Task Client

  • Blog
  • >
  • Spring Boot Starter for the External Task Client

We are happy to announce that Camunda Platform Runtime 7.15 will provide a Spring Boot Starter for the External Task Client. It allows you to implement Service Tasks decoupled from the Process Engine using Spring Boot. In seconds, you can build an executable JAR that can run almost anywhere.

In 2018, Camunda released the first version of the External Task Client. Since then, our community member Oliver Steinhauer developed a Starter that combines the External Task Client with Spring Boot. With the 7.15 release, we will add the former Community Extension to the official Camunda Stack and will maintain it as part of future product releases.

Let’s look at the following example to get a better understanding of the Spring Boot Starter.

We want to automate granting a loan to a customer. For this, we need to retrieve the customer’s ID and credit score from our database. We check if the credit score is higher than five, which we consider good to grant a loan. If the credit score is weaker than five, we have to reject the loan request.

Based on this business context, I have created the following BPMN Process.

BPMN Process “Granting Loans”

Let’s Automate the Process!

In six simple steps, we can build an executable JAR that automates the process with the Spring Boot Starter for the External Task Client.

Step 0: Run Camunda Platform Runtime

Download the latest developer preview (alpha5) of Camunda Platform Runtime 7.15.0, and start it.

Step 1: Deploy Process Model and Start Instances

Download the process model loan-granting.bpmn (right-click & save link as…), deploy it to Camunda Platform Runtime, and start a couple of process instances. The quickest way to achieve this is by deploying and starting a new process instance with Camunda Modeler‘s help.

Step 2: Add Dependency

Create a new Maven project and add the following dependency to your <a href="https://raw.githubusercontent.com/tasso94/external-task-client-spring-boot-starter-example/master/pom.xml">pom.xml</a> file:

<dependency>
  <groupId>org.camunda.bpm.springboot</groupId>
  <artifactId>camunda-bpm-spring-boot-starter-external-task-client</artifactId>
  <version>7.15.0-alpha5</version>
</dependency>

Step 3: Add Main Class

Add the main class to your Spring Boot project:

@SpringBootApplication
public class Application {
  public static void main(String... args) {
    SpringApplication.run(Application.class, args);
  }
}

Step 4: Add application.yml file

The application.yml file is the central configuration point. Add it to your project under ./src/main/resources:

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:
    scoreProvider: # topic name of the External Service Task
      variable-names: [] # our business logic doesn't require any variables, so don't fetch them
      process-definition-key: loan_process # only filter for External Tasks with this process definition key
    loanGranter:
      variable-names: customerId, creditScore # only fetch these two variables
      process-definition-key: loan_process

logging.level.org.camunda.bpm.client: DEBUG # increase the log level of the application

Step 5: Implement Service Tasks

Next, we implement our custom business logic that is executed whenever a process instance waits in an External Service Task. For the topic name scoreProvider, we create the following handler class:

@Component
@ExternalTaskSubscription("scoreProvider") // create a subscription for this topic name
public class ProvideScoreHandler implements ExternalTaskHandler {

  @Override
  public void execute(ExternalTask externalTask, ExternalTaskService externalTaskService) {

    // only for the sake of this demonstration, we generate random data
    // in a real-world scenario, we would load the data from a database
    String customerId = "C-" + UUID.randomUUID().toString().substring(32);
    int creditScore = (int) (Math.random() * 11);

    VariableMap variables = Variables.createVariables();
    variables.put("customerId", customerId);
    variables.put("creditScore", creditScore);

    // complete the external task
    externalTaskService.complete(externalTask, variables);

    Logger.getLogger("scoreProvider")
        .log(Level.INFO, "Credit score {0} for customer {1} provided!", new Object[]{creditScore, customerId});
  }

}

For the topic name loanGranter, we create the following handler class:

@Component
@ExternalTaskSubscription("loanGranter") // create a subscription for this topic name
public class GrantLoanHandler implements ExternalTaskHandler {

  @Override
  public void execute(ExternalTask externalTask, ExternalTaskService externalTaskService) {
    // get variables
    String customerId = externalTask.getVariable("customerId");
    int creditScore = externalTask.getVariable("creditScore");

    // we could call an external service to create the loan documents here

    // complete the external task
    externalTaskService.complete(externalTask);

    Logger.getLogger("loanGranter")
        .log(Level.INFO, "Loan for customer {0} with credit score {1} granted!", new Object[]{customerId, creditScore});
  }

}

Step 6: Build & Run

Build a JAR and run it with the following commands:

$ mvn clean install
$ java -jar target/external-task-client-starter-example-1.0-SNAPSHOT.jar

Watch out for a similar output on your console:

...
2021-03-24 15:37:46.391 DEBUG 52264 --- ...: TASK/CLIENT/SPRING-01003 Client successfully bootstrapped
2021-03-24 15:37:46.416  INFO 52264 --- ...: Started Application in 1.42 seconds (JVM running for 1.894)
2021-03-24 15:37:46.418 DEBUG 52264 --- ...: TASK/CLIENT/SPRING-02006 Subscription for topic name provideScore opened
2021-03-24 15:37:46.418 DEBUG 52264 --- ...: TASK/CLIENT/SPRING-02005 Subscription for topic name provideScore initialized
2021-03-24 15:37:46.418 DEBUG 52264 --- ...: TASK/CLIENT/SPRING-02006 Subscription for topic name loanGranter opened
2021-03-24 15:37:46.418 DEBUG 52264 --- ...: TASK/CLIENT-03008 Fetch and lock new external tasks for 1 topics
2021-03-24 15:37:46.418 DEBUG 52264 --- ...: TASK/CLIENT/SPRING-02005 Subscription for topic name loanGranter initialized
2021-03-24 15:37:46.620  INFO 52264 --- ...: Score 6 for customer C-4e06 provided!
2021-03-24 15:37:46.620  INFO 52264 --- ...: Score 1 for customer C-c00e provided!
2021-03-24 15:37:46.620  INFO 52264 --- ...: Score 9 for customer C-5b69 provided!
2021-03-24 15:37:46.620  INFO 52264 --- ...: Score 2 for customer C-c1f7 provided!
2021-03-24 15:37:46.620 DEBUG 52264 --- ...: TASK/CLIENT-03008 Fetch and lock new external tasks for 2 topics
2021-03-24 15:37:46.691  INFO 52264 --- ...: Loan for customer C-5b69 with credit score 9 granted!
2021-03-24 15:37:46.722  INFO 52264 --- ...: Loan for customer C-4e06 with credit score 6 granted!
...

Since we generate random data in this example, your console output might look slightly different. However, you should see that External Service Tasks with the topic name provideScore and loanGranter were fetched, and our business logic was executed successfully. Hurray! 🥳 🚀

Step 6: Monitor the Process Instances in Camunda Cockpit

Let’s have a look at the state of the process instances in Camunda Cockpit. Open Camunda Cockpit, click in the top navigation on “Processes” and then on the process “Granting Loans”:

Process Definition View of “Granting Loans” Process

You might see some process instances waiting in the External Service Task “Reject loan request” but none waiting in “Grant loan”. Our handler with the topic name loanGranter has completed all instances waiting in the External Service Task “Grant loan”. Since we didn’t implement the External Service Task “Reject loan request”, you might see some process instances that still wait there.

Now it’s your turn, complete the example by implementing the External Service Task “Reject loan request” with the topic name requestRejecter.
You can find the example’s source code on GitHub: External Task Client Spring Boot Starter Example

Further Reading

You can find detailed documentation about the Spring Boot Starter External Task Client in our User Guide. Please also check out our Examples.

Housekeeping

If you have used the Java External Task Client or the community extension already before, please note the following changes that we introduced in the course of making the latter part of the product stack:

  • The Java External Task Client and the Spring Boot Starter External Task Client are now released together with the Camunda Platform Runtime and thus share the same version
  • The codebases of the Java External Task Client and the Spring Boot Starter External Task Client were relocated to our main repository. From now on, you can find their source code here: 
  • We moved the Examples of the Java External Task Client and the Spring Boot Starter External Task Client to our Examples Repository

Get in touch with us!

Do you like what we’ve built, do you miss an important feature, or do you want to share some feedback with us?

You can ping us on Twitter @Camunda, reach us out on the Forum, or create a ticket in our issue tracker.

Camunda Developer Community

Have deeper questions about this release?

Try All Features of Camunda

Related Content

Transition from simple deployments to a fully integrated production setup smoothly.
We're excited to announce the November 2024 alpha release of Camunda. Check out what's new.
Announcing our new SAP integration: find out what inspired us to build the solution, how it works and what you can expect (hint: flexibility, speed and reduced risk).