This open source project allows you to easily integrate Camunda's External Task Clients into Micronaut projects: simply add a dependency in your Micronaut project

Overview

micronaut-camunda-external-client

This open source project allows you to easily integrate Camunda 's External Task Clients into Micronaut projects.

Micronaut is known for its efficient use of resources. With this integration you can easily implement an external client which to process external tasks. If you use GraalVM you have startup times of about 35ms!

The integration is preconfigured with sensible defaults, so that you can get started with minimal configuration: simply add a dependency in your Micronaut project!

If you also want to run the Camunda Workflow Engine on Micronaut, have a look at the open source project micronaut-camunda-bpm.


We're not aware of all installations of our Open Source project. However, we love

  • listening to your feedback,
  • discussing possible use cases with you,
  • aligning the roadmap to your needs!

📨 Please contact us!


Do you want to try it out? Please jump to the Getting Started section.

Do you want to contribute to our open source project? Please read the Contribution Guidelines and contact us.

Micronaut + Camunda = ❤️

Release License Continuous Integration GitHub Discussions

Table of Contents

Features

  • Camunda external client can be integrated by simply adding a dependency to your project.
  • A worker can subscribe to multiple topics.
  • The worker's external task client can be configured with properties and programmatically.

🚀 Getting Started

This section describes what needs to be done to use micronaut-camunda-external-client-feature in a Micronaut project.

Here are some example applications:

Supported JDKs

We officially support the following JDKs:

  • JDK 8 (LTS)
  • JDK 11 (LTS)
  • JDK 15 (the latest version supported by Micronaut)

Dependency Management

The Camunda integration works with both Gradle and Maven, but we recommend using Gradle because it has better Micronaut Support.

Click to show Gradle configuration
  1. Optional: Create an empty Micronaut project using Micronaut Launch or alternatively with the CLI: mn create-app my-example.
  2. Add the dependency to the build.gradle:
implementation("info.novatec:micronaut-camunda-external-client-feature:0.2.0")
Click to show Maven configuration
  1. Optional: Create an empty Micronaut using Micronaut Launch or alternatively with the CLI: mn create-app my-example --build=maven.
  2. Add the dependency to the pom.xml:
<dependency>
  <groupId>info.novatec</groupId>
  <artifactId>micronaut-camunda-external-client-feature</artifactId>
  <version>0.2.0</version>
</dependency>

Note: The module micronaut-camunda-external-client-feature includes the dependency org.camunda.bpm:camunda-external-task-client which will be resolved transitively.

Creating a Client

The minimal configuration requires you to provide a handler for a specific topic and a configuration that points to the Camunda REST API. You can register multiple handlers in this way for different topics. To register a handler you just need to add the annotation ExternalTaskSubscription and specify the topic to listen to. On start of the application the external task client will automatically connect to the specified Camunda REST API and start fetching tasks.

Example configuration in application.yml

camunda.external-client:
  base-url: http://localhost:8080/engine-rest

Example handler:

import info.novatec.micronaut.camunda.external.client.feature.ExternalTaskSubscription;
import org.camunda.bpm.client.task.ExternalTask;
import org.camunda.bpm.client.task.ExternalTaskHandler;
import org.camunda.bpm.client.task.ExternalTaskService;

import javax.inject.Singleton;

@Singleton
@ExternalTaskSubscription(topicName = "my-topic")
public class ExampleHandler implements ExternalTaskHandler {

    @Override
    public void execute(ExternalTask externalTask, ExternalTaskService externalTaskService) {
        // Put your business logic here
    
        externalTaskService.complete(externalTask);
    }
}

ExternalTaskSubscription Annotation

The annotation accepts the following properties:

Property Default Description
topicName The mandatory topic name the client subscribes to.
lockDuration 20000 Lock duration in milliseconds to lock external tasks. Must be greater than zero.
variables The name of the variables that are supposed to be retrieved.
localVariables false Whether or not variables from greater scope than the external task should be fetched. false means all variables visible in the scope of the external task will be fetched, true means only local variables (to the scope of the external task) will be fetched.
businessKey A business key to filter for external tasks that are supposed to be fetched and locked.
processDefinitionId A process definition id to filter for external tasks that are supposed to be fetched and locked.
processDefinitionIdIn Process definition ids to filter for external tasks that are supposed to be fetched and locked.
processDefinitionKey A process definition key to filter for external tasks that are supposed to be fetched and locked.
processDefinitionKeyIn Process definition keys to filter for external tasks that are supposed to be fetched and locked.
processDefinitionVersionTag Process definition version tag to filter for external tasks that are supposed to be fetched and locked.
withoutTenantId false Filter for external tasks without tenant.
tenantIdIn Tenant ids to filter for external tasks that are supposed to be fetched and locked.
includeExtensionProperties false Whether or not to include custom extension properties for fetched external tasks. true means all extensionProperties defined in the external task activity will be provided. false means custom extension properties are not available within the external-task-client

Configuration

You may use the following properties (typically in application.yml) to configure the external task client.

Prefix Property Default Description
camunda.external-client .base-url Mandatory base url of the Camunda Platform REST API.
.worker-id Generated out of hostname + 128 Bit UUID A custom worker id the Workflow Engine is aware of.
.max-tasks 10 Maximum amount of tasks that will be fetched with each request.
.use-priority true Specifies whether tasks should be fetched based on their priority or arbitrarily.
.default-serialization-format application/json Specifies the serialization format that is used to serialize objects when no specific format is requested.
.date-format Specifies the date format to de-/serialize date variables.
.async-response-timeout Asynchronous response (long polling) is enabled if a timeout is given. Specifies the maximum waiting time for the response of fetched and locked external tasks. The response is performed immediately, if external tasks are available in the moment of the request. Unless a timeout is given, fetch and lock responses are synchronous.
.lock-duration 20000 (milliseconds) Lock duration in milliseconds to lock external tasks. Must be greater than zero. This gets overridden by the lock duration configured on a topic subscription
.disable-auto-fetching false Disables immediate fetching for external tasks after creating the client. To start fetching ExternalTaskClient.start() must be called.
.disable-backoff-strategy false Disables the client-side backoff strategy. On invocation, the configuration option backoffStrategy is ignored. Please bear in mind that disabling the client-side backoff can lead to heavy load situations on engine side. To avoid this, please specify an appropriate long async-response-timeout.

🏆 Advanced Topics

Customize the External Task Client

With the following bean it is possible to customize the external task client, e.g. to implement custom backoff strategies or register a client request interceptor.

import info.novatec.micronaut.camunda.external.client.feature.ExternalClientCustomizer;
import io.micronaut.context.annotation.Replaces;
import org.camunda.bpm.client.ExternalTaskClientBuilder;
import javax.inject.Singleton;
import org.camunda.bpm.client.backoff.BackoffStrategy;
import org.camunda.bpm.client.interceptor.ClientRequestInterceptor;

@Singleton
@Replaces(ExternalClientCustomizer.class)
public class MyExternalClientCustomizer implements ExternalClientCustomizer {

    @Override
    public void customize(ExternalTaskClientBuilder builder) {
        // Do your customization here e.g.:
        BackoffStrategy backoffStrategy = ...
        ClientRequestInterceptor interceptor = ...

        builder.backoffStrategy(backoffStrategy)
                .addInterceptor(interceptor);
    }
}

Important: the values set within your customizer have higher priority than the properties set in your configuration file.

GraalVM

With GraalVM you can reduce start-up time and memory usage even more! For example, on a developer environment the start-up time will drop to about 35ms!

The following instructions are based on macOS - other operating systems will probably be similar. Feel free to create a pull request with updated instructions for other operating systems.

Initial Setup

Install the gu executable to be able to install native-image based on instructions: https://www.graalvm.org/docs/getting-started/macos/

tar -xvf graalvm-ce-java11-darwin-amd64-21.0.0.2.tar.gz
sudo mv graalvm-ce-java11-21.0.0.2 /Library/Java/JavaVirtualMachines
/usr/libexec/java_home -V
gu install native-image

Install GraalVM

Install GraalVM using SDKMAN!:

curl -s "https://get.sdkman.io" | bash
sdk install java 21.0.0.2.r11-grl

Initialize Environment

sdk use java 21.0.0.2.r11-grl
export PATH=/Library/Java/JavaVirtualMachines/graalvm-ce-java11-21.0.0.2/Contents/Home/bin:$PATH
export JAVA_HOME=/Library/Java/JavaVirtualMachines/graalvm-ce-java11-21.0.0.2/Contents/Home

Create Reflection Configuration

cd micronaut-camunda-external-client-example
../gradlew build
mkdir -p src/main/resources/META-INF/native-image/info/novatec/micronaut/camunda/external/client/example
java -agentlib:native-image-agent=config-output-dir=src/main/resources/META-INF/native-image/info/novatec/micronaut/camunda/external/client/example -jar build/libs/micronaut-camunda-external-client-example-0.0.1-SNAPSHOT-all.jar

and cancel the client with Ctrl-C once you see that the client is running when it repeatedly logs Completed external task.

Build Image

Now build the native image - note: this will take a few minutes:

../gradlew clean nativeImage

Start Native Client

You can then start the external client (Note: Server must be running):

build/native-image/application

The application will be up and processing the first tasks in about 35ms (!):

INFO  io.micronaut.runtime.Micronaut - Startup completed in 33ms. Server Running: http://localhost:8888
INFO  i.n.m.c.e.c.example.SimpleHandler - Completed external task
INFO  i.n.m.c.e.c.example.SimpleHandler - Completed external task
INFO  i.n.m.c.e.c.example.SimpleHandler - Completed external task

📚 Releases

The list of releases contains a detailed changelog.

We use Semantic Versioning which does allow incompatible changes before release 1.0.0, but we try to minimize them.

The following compatibility matrix shows the officially supported Micronaut and Camunda versions for each release. Other combinations might also work but have not been tested. The current release of the external client will probably work with a server running on Camunda 7.9.0 and newer.

Release Micronaut Camunda
0.2.0 2.4.2 7.15.0
Click to see older releases
Release Micronaut Camunda
0.1.0 2.4.2 7.14.0

Download of Releases:

📨 Contact

This open source project is being developed by Novatec Consulting GmbH with the support of the open source community.

If you have any questions or ideas feel free to create an issue or contact us via GitHub Discussions or mail.

We love listening to your feedback, and of course also discussing the project roadmap and possible use cases with you!

You can reach us:

Issues
  • Bump actions/cache from v2 to v2.1.4

    Bump actions/cache from v2 to v2.1.4

    Bumps actions/cache from v2 to v2.1.4.

    Release notes

    Sourced from actions/cache's releases.

    v2.1.4

    • Make caching more verbose #650
    • Use GNU tar on macOS if available #701
    Commits
    • 26968a0 Make save/restore logs akin (#509)
    • aeaf731 Use @actions/cache version 1.0.6 (#525)
    • 56a8a2f Merge pull request #514 from eregon/recommend-setup-ruby-bundler-cache
    • 1bfe3ac Recommend ruby/setup-ruby's bundler-cache: true option
    • 3543324 Merge pull request #434 from DanielHabenicht/patch-1
    • 3303695 Merge pull request #507 from odin-delrio/patch-1
    • e64ab30 Improved gradle cache key calculation example
    • 26c48dc Merge pull request #506 from actions/cache-matrix-example
    • 72f66cf Added a cache example when using matrix
    • 9f3a4d3 Merge pull request #443 from guilleijo/pipenv-example
    • Additional commits viewable in compare view

    Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting @dependabot rebase.


    Dependabot commands and options

    You can trigger Dependabot actions by commenting on this PR:

    • @dependabot rebase will rebase this PR
    • @dependabot recreate will recreate this PR, overwriting any edits that have been made to it
    • @dependabot merge will merge this PR after your CI passes on it
    • @dependabot squash and merge will squash and merge this PR after your CI passes on it
    • @dependabot cancel merge will cancel a previously requested merge and block automerging
    • @dependabot reopen will reopen this PR if it is closed
    • @dependabot close will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually
    • @dependabot ignore this major version will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself)
    • @dependabot ignore this minor version will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself)
    • @dependabot ignore this dependency will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
    dependencies github_actions 
    opened by dependabot[bot] 2
  • Bump actions/setup-java from v1 to v2

    Bump actions/setup-java from v1 to v2

    Bumps actions/setup-java from v1 to v2.

    Commits
    • 8764a52 Rename v2-preview to v2 in docs and tests (#151)
    • b53500d Merge "v2-preview" branch into "main" (#150)
    • ebb424f Beatify "main" warning about breaking changes (#144)
    • 9c7940b Add breaking change warning to 'main' branch (#138)
    • fc62cca V2 setup-java ADR (#97)
    • e73e96a Merge pull request #131 from actions/v-malob/update-codeowners
    • ea31b1d Update CODEOWNERS
    • ff0054d Merge pull request #123 from dmitry-shibanov/fix-documentation-for-gpg-import...
    • 81290cd change imported to exported
    • 546dae7 Merge pull request #122 from dmitry-shibanov/update-docs-for-maven-and-gpg
    • Additional commits viewable in compare view

    Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting @dependabot rebase.


    Dependabot commands and options

    You can trigger Dependabot actions by commenting on this PR:

    • @dependabot rebase will rebase this PR
    • @dependabot recreate will recreate this PR, overwriting any edits that have been made to it
    • @dependabot merge will merge this PR after your CI passes on it
    • @dependabot squash and merge will squash and merge this PR after your CI passes on it
    • @dependabot cancel merge will cancel a previously requested merge and block automerging
    • @dependabot reopen will reopen this PR if it is closed
    • @dependabot close will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually
    • @dependabot ignore this major version will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself)
    • @dependabot ignore this minor version will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself)
    • @dependabot ignore this dependency will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
    dependencies github_actions 
    opened by dependabot[bot] 1
  • Update to Micronaut 2.5.1

    Update to Micronaut 2.5.1

    opened by tobiasschaefer 0
  • JDK 16 is now also supported

    JDK 16 is now also supported

    opened by tobiasschaefer 0
  • Configure TopicSubscription with properties

    Configure TopicSubscription with properties

    Currently, the topic subscription can only be configured with annotation properties

    @ExternalTaskSubscription(
        topicName = "test-topic",
        lockDuration = 19000,
        variables = ["test-one", "test-two"],
        localVariables = true
    )
    

    Let's also make these available via properties, i.e.

    camunda.external-client:
      subscriptions:
        my-topic:
          lock-duration: 19000
          variables:
            - test-one
            - test-two
          local-variables: true
    

    Note: Camel-Case and Kebab-Case should both be supported.

    opened by tobiasschaefer 0
Releases(v0.3.0)
Java 8 annotation processor and framework for deriving algebraic data types constructors, pattern-matching, folds, optics and typeclasses.

Derive4J: Java 8 annotation processor for deriving algebraic data types constructors, pattern matching and more! tl;dr Show me how to write, say, the

null 511 Feb 23, 2021
A Java API for generating .java source files.

JavaPoet JavaPoet is a Java API for generating .java source files. Source file generation can be useful when doing things such as annotation processin

Square 8.7k Mar 12, 2021
GraalVM: Run Programs Faster Anywhere :rocket:

GraalVM GraalVM is a universal virtual machine for running applications written in JavaScript, Python, Ruby, R, JVM-based languages like Java, Scala,

Oracle 14.7k Mar 13, 2021
Java 1-15 Parser and Abstract Syntax Tree for Java, including preview features to Java 13

JavaParser This project contains a set of libraries implementing a Java 1.0 - Java 14 Parser with advanced analysis functionalities. This includes pre

JavaParser 3.6k Mar 13, 2021
Compiler of Java bytecode to JavaScript

TeaVM See documentation at the project web site. Useful links: Getting started Gallery Flavour source code repository Site source code repository Disc

Alexey Andreev 1.7k Mar 13, 2021
Write parsers for arbitrary text inputs, entirely in Java, with no preprocessing phase

Read me first The license of this project is Apache 2.0. Requires Java 7 or later. The latest versions are: development: 2.1.0-beta.3; requires Java 8

Francis Galiegue 63 Nov 10, 2020
提供Java对动态字符串支持的语法插件

Zircon 支持在Java语言中使用内插字符串 实现类似于kotlin、Groovy等语言中内插字符串 支持android、java等所有使用javac的项目 几乎不会增加额外编译时间 代码内容支持idea补全提示(需自行配置) 使用示例 String add = "test2"; ass

null 15 Mar 7, 2021
Build parsers in Java

jparsec Builds mini parsers in pure Java. Latest version: 3.0 (requires Java 8+) News 2016-12-05 Removed references to Codehaus in copyright and packa

null 288 Feb 24, 2021
The Eta Programming Language, a dialect of Haskell on the JVM

Eta - Modern Haskell on the JVM The Eta programming language is a dialect of Haskell which runs on the JVM and has the following goals: accessibility

TypeLead 2.5k Mar 13, 2021
将枚举映射为数据字典,可用于前后端共享数据字典

DictMapper 这是一个从个人项目中剥离出来的小组件,用于前后端统一维护数据字典。在我的项目里面,它叫常量字典。 使用场景 被注解的枚举类 @MapDict(code = "status_flags", name = "状态") public enum StatusEnum { @Labe

null 13 Mar 22, 2021
Obsolete repository. Moved to oracle/graal.

Obsolete Repository This repository is obsolete. Sulong is now integrated in the Graal repository. Please open new issues or pull requests directly in

GraalVM 618 Jan 20, 2021
Catch common Java mistakes as compile-time errors

Error Prone Error Prone is a static analysis tool for Java that catches common programming mistakes at compile-time. public class ShortSet { public

Google 5.5k Mar 13, 2021
A collection of source code generators for Java.

Auto A collection of source code generators for Java. Auto‽ Java is full of code that is mechanical, repetitive, typically untested and sometimes the

Google 9.1k Mar 13, 2021
Testing tools for javac and annotation processors

Compile Testing A library for testing javac compilation with or without annotation processors. See the javadoc for usage examples. License Copyright 2

Google 559 Mar 10, 2021