Skip to content

Commit 6e5f8cf

Browse files
committed
Merge branch 'release/0.3.0'
2 parents e0c0144 + 7ec5a92 commit 6e5f8cf

File tree

10 files changed

+94
-14
lines changed

10 files changed

+94
-14
lines changed

docs/process-engine-worker.md

Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
---
2+
title: Process Engine Worker
3+
---
4+
5+
Process Engine Worker is an independent component built on top of Process Engine API in order to accelerate the development of agnostic workers
6+
for any process engine supported by Process Engine API in Spring Boot ecosystem. By doing so, it abstracts from specific worker clients and
7+
API and allows to build universal workers.
8+
9+
First of all add the Process Engine Worker dependency to you project classpath. In Maven add the following to you `pom.xml`:
10+
11+
```xml
12+
<dependency>
13+
<groupId>dev.bpm-crafters.process-engine-worker</groupId>
14+
<artifactId>process-engine-worker-spring-boot-starter</artifactId>
15+
<version>${process-engine-worker.version}</version>
16+
</dependency>
17+
```
18+
19+
Now create a simple Spring component and annotate a method with a special annotation `@ProcessEngineWorker`:
20+
21+
```java
22+
@Component
23+
@RequiredArgsConstructor
24+
public class MySmartWorker {
25+
26+
private final FetchGoodsInPort fetchGoodsInPort;
27+
28+
@ProcessEngineWorker(topic = "fetchGoods")
29+
public Map<String, Object> fetchGoods(
30+
@Variable(name = "order") Order order
31+
) {
32+
// execute some business code
33+
var fetched = fetchGoodsInPort.fetchGoods(order);
34+
35+
return Map.of("shipped", fetched);
36+
}
37+
}
38+
```
39+
40+
## Method parameter resolution
41+
42+
Parameter resolution of the method annotated with `ProcessEngineWorker` is based on a set of strategies
43+
registered by the `ParameterResolver` bean. Currently, the following parameters are resolved:
44+
45+
| Type | Purpose |
46+
|----------------------------------------|---------------------------------------------------------------------------|
47+
| TaskInformation | Helper abstracting all information about the external task. |
48+
| ExternTaskCompletionApi | API for completing the external task manually |
49+
| VariableConverter | Special utility to read the process variable map and deliver typed value |
50+
| Map<String, Object> | Payload object containing all variables. |
51+
| Type annotated with @Variable("name") | Marker for a process variable. |
52+
53+
Usually, the requested variable is mandatory and the parameter resolver reports an error, if the requested variable is not
54+
available in the process payload. If you want to inject the variable only if it exists in the payload you have two options.
55+
Either you set the parameter `@Variable(name = "...", mandatory = false)` or you use `Optional<T>` instead of `T` as a variable
56+
type. If you are using Kotlin and don't like `Optional`, make sure to declare variable type as nullable (`T?` instead of `T`) and
57+
set the mandatory flag to `false`.
58+
59+
## Method return type
60+
61+
If the return type of the method is of type `Map<String, Object>` or compatible and the `autoComplete` flag is turned
62+
on the annotation (defaults to `true`), the library will try to automatically complete the External Task
63+
using the returned map as completion variables. If `autoComplete` is `true`, but no return value is provided, the task
64+
will be completed without empty payload. This functionality is provided by the `ResultResolver` based on registered strategies.
65+
66+
## Throwing a BPMN Error
67+
68+
If you want to throw a BPMN error, please throw an instance of a `BPMNErrorOccured` exception from the method body. The exception
69+
is a checked exception, in order to comply with Spring behavior of not rolling back transaction on checked exceptions.
70+
71+
## Transactional support
72+
73+
The worker method can be marked transactional by adding Spring or Jakarta EE transactional annotations to the method or to the worker class.
74+
If the annotation `@org.springframework.transaction.annotation.Transactional` with propagation `REQUIRES`, `REQUIRES_NEW`, `SUPPORTS` and `MANDATORY`
75+
is used, the library will execute the worker method and the completion of the external task via API in the same transaction. This will lead to
76+
a transaction rollback, if the external task can't be completed (e.g. due to a network error).
77+
78+
79+
80+
81+
82+

examples/camunda7-remote-starter-native/pom.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
<parent>
66
<groupId>dev.bpm-crafters.process-engine-worker</groupId>
77
<artifactId>process-engine-worker-examples</artifactId>
8-
<version>0.2.0</version>
8+
<version>0.3.0</version>
99
<relativePath>../pom.xml</relativePath>
1010
</parent>
1111

examples/order-fulfillment/pom.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
<parent>
66
<groupId>dev.bpm-crafters.process-engine-worker</groupId>
77
<artifactId>process-engine-worker-examples</artifactId>
8-
<version>0.2.0</version>
8+
<version>0.3.0</version>
99
<relativePath>../pom.xml</relativePath>
1010
</parent>
1111

examples/order-fulfillment/src/main/java/dev/bpmcrafters/example/order/fulfillment/order/adapter/out/usertasks/UserTaskPool.java

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,6 @@
2525
public class UserTaskPool implements UserTaskOutPort {
2626

2727
private final TaskSubscriptionApi subscriptionApi;
28-
2928
private final ConcurrentHashMap<TaskInformation, Map<String, ?>> tasks = new ConcurrentHashMap<>();
3029

3130
@PostConstruct
@@ -48,8 +47,8 @@ public void subscribe() throws ExecutionException, InterruptedException {
4847
tasks.put(taskInformation, payload);
4948
}
5049
},
51-
taskId -> {
52-
tasks.keySet().stream().filter(ti -> ti.getTaskId().equals(taskId)).findFirst().ifPresent(ti -> {
50+
(TaskInformation taskInformation) -> {
51+
tasks.keySet().stream().filter(ti -> ti.getTaskId().equals(taskInformation.getTaskId())).findFirst().ifPresent(ti -> {
5352
tasks.remove(ti);
5453
log.info("EXAMPLE: <USER TASKS> Removed user task {} ({}:{})",
5554
ti.getTaskId(),

examples/pom.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
<parent>
66
<groupId>dev.bpm-crafters.process-engine-worker</groupId>
77
<artifactId>process-engine-worker-root</artifactId>
8-
<version>0.2.0</version>
8+
<version>0.3.0</version>
99
<relativePath>../pom.xml</relativePath>
1010
</parent>
1111

pom.xml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,16 +11,16 @@
1111

1212
<groupId>dev.bpm-crafters.process-engine-worker</groupId>
1313
<artifactId>process-engine-worker-root</artifactId>
14-
<version>0.2.0</version>
14+
<version>0.3.0</version>
1515
<name>${project.artifactId}</name>
1616
<description>Process Engine Worker</description>
1717
<url>https://github.com/bpm-crafters/process-engine-worker/</url>
1818
<packaging>pom</packaging>
1919

2020
<properties>
2121
<spring-boot.version>3.4.4</spring-boot.version>
22-
<process-engine-api.version>1.0</process-engine-api.version>
23-
<process-engine-adapters-c7.version>2025.04.1</process-engine-adapters-c7.version>
22+
<process-engine-api.version>1.1</process-engine-api.version>
23+
<process-engine-adapters-c7.version>2025.04.2</process-engine-adapters-c7.version>
2424
<process-engine-adapters-c8.version>2025.04.1</process-engine-adapters-c8.version>
2525
<!-- TEST -->
2626
<mockito.version>5.4.0</mockito.version>

spring-boot-starter/pom.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
<parent>
55
<groupId>dev.bpm-crafters.process-engine-worker</groupId>
66
<artifactId>process-engine-worker-root</artifactId>
7-
<version>0.2.0</version>
7+
<version>0.3.0</version>
88
</parent>
99

1010
<artifactId>process-engine-worker-spring-boot-starter</artifactId>

spring-boot-starter/src/main/kotlin/dev/bpmcrafters/processengine/worker/registrar/ProcessEngineStarterRegistrar.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -181,7 +181,7 @@ class ProcessEngineStarterRegistrar(
181181

182182
},
183183
termination = {
184-
logger.debug { "PROCESS-ENGINE-WORKER-010: Terminating task from topic $topic." }
184+
logger.debug { "PROCESS-ENGINE-WORKER-010: Terminating task ${it.taskId} from topic $topic" }
185185
}
186186
)
187187

spring-boot-starter/src/test/kotlin/dev/bpmcrafters/processengine/worker/TestHelper.kt

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,12 +10,11 @@ import org.testcontainers.utility.DockerImageName
1010
object TestHelper {
1111

1212
class Camunda7RunTestContainer(tag: String) : GenericContainer<Camunda7RunTestContainer>("camunda/camunda-bpm-platform:$tag") {
13-
1413
init {
14+
1515
withCommand("./camunda.sh", "--rest")
1616
withEnv("CAMUNDA_BPM_DEFAULT-SERIALIZATION-FORMAT", "application/json")
1717
withExposedPorts(8080)
18-
addFixedExposedPort(38080, 8080)
1918
waitingFor(
2019
Wait
2120
.forHttp("/engine-rest/engine/")

spring-boot-starter/src/test/kotlin/dev/bpmcrafters/processengine/worker/registrar/ResultResolverTest.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ class ResultResolverTest {
2727
fun `detects method returning generic map`() {
2828
class Worker {
2929
@ProcessEngineWorker
30-
fun work(): Map<String, out Any> {
30+
fun work(): Map<String, Any> {
3131
return mapOf("string" to "value", "string2" to "other")
3232
}
3333
}

0 commit comments

Comments
 (0)