Skip to content

Commit c08b0a7

Browse files
committed
Add initial external worker implementation
Provide Spring based worker and sample
0 parents  commit c08b0a7

File tree

74 files changed

+8911
-0
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

74 files changed

+8911
-0
lines changed

.gitignore

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
HELP.md
2+
target/
3+
!.mvn/wrapper/maven-wrapper.jar
4+
!**/src/main/**/target/
5+
!**/src/test/**/target/
6+
7+
### STS ###
8+
.apt_generated
9+
.classpath
10+
.factorypath
11+
.project
12+
.settings
13+
.springBeans
14+
.sts4-cache
15+
16+
### IntelliJ IDEA ###
17+
.idea
18+
*.iws
19+
*.iml
20+
*.ipr
21+
22+
### NetBeans ###
23+
/nbproject/private/
24+
/nbbuild/
25+
/dist/
26+
/nbdist/
27+
/.nb-gradle/
28+
build/
29+
!**/src/main/**/build/
30+
!**/src/test/**/build/
31+
32+
### VS Code ###
33+
.vscode/

.mvn/wrapper/maven-wrapper.jar

61.1 KB
Binary file not shown.
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.9.4/apache-maven-3.9.4-bin.zip
2+
wrapperUrl=https://repo.maven.apache.org/maven2/org/apache/maven/wrapper/maven-wrapper/3.2.0/maven-wrapper-3.2.0.jar

README.md

Lines changed: 96 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,96 @@
1+
# Flowable External Worker Library for Java
2+
3+
To use Flowable together with a Java application external workers can be used.
4+
This project allows to connect a Java library to Flowable.
5+
To connect to a Flowable installation it is required [to authenticate](#authentication).
6+
With the client it is possible to specify a callback method which is called for every job executed.
7+
8+
## Authentication
9+
10+
There are 2 ways that the application can be authenticated with a Flowable installation.
11+
12+
* Using HTTP Basic authentication with a provided username and password
13+
* Using HTTP Bearer authentication with a provided access token
14+
15+
## Spring Boot Sample
16+
17+
The following dependency needs to be added to start using Flowable workers.
18+
19+
```xml
20+
<dependency>
21+
<groupId>org.flowable.client.spring</groupId>
22+
<artifactId>flowable-external-worker-spring-boot-starter</artifactId>
23+
<version>${flowable-worker-client.version}</version>
24+
</dependency>
25+
```
26+
27+
The following is an example Flowable Worker that is retrieving jobs from the `myTopic` topic
28+
29+
```java
30+
import org.springframework.stereotype.Component;
31+
32+
import org.flowable.external.client.AcquiredExternalWorkerJob;
33+
import org.flowable.external.worker.annotation.FlowableWorker;
34+
35+
@Component
36+
public class ExampleWorker {
37+
38+
@FlowableWorker(topic = "myTopic")
39+
public void processJob(AcquiredExternalWorkerJob job) {
40+
System.out.println("Executed job: " + job.getId());
41+
}
42+
43+
}
44+
```
45+
46+
Using the example above the job will be completed if the method completes successfully, and it will fail if the method throws an exception.
47+
48+
In order to pass additional data for a failure or a completion the following example can be used:
49+
50+
```java
51+
import org.springframework.stereotype.Component;
52+
53+
import org.flowable.external.client.AcquiredExternalWorkerJob;
54+
import org.flowable.external.worker.annotation.FlowableWorker;
55+
import org.flowable.external.worker.WorkerResult;
56+
import org.flowable.external.worker.WorkerResultBuilder;
57+
58+
@Component
59+
public class ExampleWorker {
60+
61+
@FlowableWorker(topic = "myTopic")
62+
public WorkerResult processJob(AcquiredExternalWorkerJob job, WorkerResultBuilder resultBuilder) {
63+
System.out.println("Executed job: " + job.getId());
64+
Object errorMessage = job.getVariables().get("errorMessage");
65+
if (errorMessage != null) {
66+
return resultBuilder.failure()
67+
.message(errorMessage.toString())
68+
.details("Error message details");
69+
}
70+
71+
return resultBuilder.success()
72+
.variable("message", "Job has been executed");
73+
}
74+
}
75+
```
76+
77+
78+
### Local
79+
80+
The following properties are example how you can connect to a Flowable instance running at `http://host.docker.internal:8090`
81+
82+
```properties
83+
flowable.external.worker.rest.base-url=http://host.docker.internal:8090
84+
flowable.external.worker.rest.authentication.basic.username=admin
85+
flowable.external.worker.rest.authentication.basic.password=test
86+
```
87+
88+
### Cloud
89+
90+
The usage with Flowable Cloud is simpler, since everything is pre-configured.
91+
However, it's required to either use the user credentials or to pre-configure a personal access token.
92+
93+
94+
```properties
95+
flowable.external.worker.rest.authentication.bearer.token=<personal-access-token>
96+
```

client/pom.xml

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
3+
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
4+
<modelVersion>4.0.0</modelVersion>
5+
<parent>
6+
<groupId>org.flowable.client</groupId>
7+
<artifactId>flowable-external-worker-client-parent</artifactId>
8+
<version>0.0.1-SNAPSHOT</version>
9+
</parent>
10+
<artifactId>flowable-external-worker-client-java</artifactId>
11+
<version>0.0.1-SNAPSHOT</version>
12+
13+
14+
<dependencies>
15+
<dependency>
16+
<groupId>com.fasterxml.jackson.core</groupId>
17+
<artifactId>jackson-databind</artifactId>
18+
</dependency>
19+
<dependency>
20+
<groupId>org.slf4j</groupId>
21+
<artifactId>slf4j-api</artifactId>
22+
</dependency>
23+
24+
<dependency>
25+
<groupId>org.junit.jupiter</groupId>
26+
<artifactId>junit-jupiter</artifactId>
27+
<scope>test</scope>
28+
</dependency>
29+
<dependency>
30+
<groupId>org.assertj</groupId>
31+
<artifactId>assertj-core</artifactId>
32+
<scope>test</scope>
33+
</dependency>
34+
<dependency>
35+
<groupId>org.microhttp</groupId>
36+
<artifactId>microhttp</artifactId>
37+
<scope>test</scope>
38+
</dependency>
39+
<dependency>
40+
<groupId>net.javacrumbs.json-unit</groupId>
41+
<artifactId>json-unit-assertj</artifactId>
42+
<scope>test</scope>
43+
</dependency>
44+
45+
<dependency>
46+
<groupId>ch.qos.logback</groupId>
47+
<artifactId>logback-classic</artifactId>
48+
<scope>test</scope>
49+
</dependency>
50+
51+
</dependencies>
52+
</project>
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
/* Licensed under the Apache License, Version 2.0 (the "License");
2+
* you may not use this file except in compliance with the License.
3+
* You may obtain a copy of the License at
4+
*
5+
* http://www.apache.org/licenses/LICENSE-2.0
6+
*
7+
* Unless required by applicable law or agreed to in writing, software
8+
* distributed under the License is distributed on an "AS IS" BASIS,
9+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
10+
* See the License for the specific language governing permissions and
11+
* limitations under the License.
12+
*/
13+
package org.flowable.external.client;
14+
15+
import java.util.Map;
16+
17+
/**
18+
* A job that has been acquired and lock and is ready to be executed.
19+
*
20+
* @author Filip Hrisafov
21+
*/
22+
public interface AcquiredExternalWorkerJob extends ExternalWorkerJob {
23+
24+
Map<String, Object> getVariables();
25+
26+
}
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
/* Licensed under the Apache License, Version 2.0 (the "License");
2+
* you may not use this file except in compliance with the License.
3+
* You may obtain a copy of the License at
4+
*
5+
* http://www.apache.org/licenses/LICENSE-2.0
6+
*
7+
* Unless required by applicable law or agreed to in writing, software
8+
* distributed under the License is distributed on an "AS IS" BASIS,
9+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
10+
* See the License for the specific language governing permissions and
11+
* limitations under the License.
12+
*/
13+
package org.flowable.external.client;
14+
15+
/**
16+
* Defines a Java API that can be used to write clients for the external worker jobs in Flowable.
17+
* It provides a basic API for acquiring, completing and failing jobs.
18+
*
19+
* @author Filip Hrisafov
20+
*/
21+
public interface ExternalWorkerClient {
22+
23+
/**
24+
* Create a builder that can be used to acquire jobs from a Flowable application.
25+
*/
26+
ExternalWorkerJobAcquireBuilder createJobAcquireBuilder();
27+
28+
/**
29+
* Create a builder that can be used to complete the given job
30+
*
31+
* @param job the job that should be completed
32+
*/
33+
ExternalWorkerJobCompletionBuilder createCompletionBuilder(AcquiredExternalWorkerJob job);
34+
35+
/**
36+
* Create a builder that can be used to fail the given job
37+
*
38+
* @param job the job that should be failed
39+
*/
40+
ExternalWorkerJobFailureBuilder createFailureBuilder(AcquiredExternalWorkerJob job);
41+
42+
}
Lines changed: 102 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,102 @@
1+
/* Licensed under the Apache License, Version 2.0 (the "License");
2+
* you may not use this file except in compliance with the License.
3+
* You may obtain a copy of the License at
4+
*
5+
* http://www.apache.org/licenses/LICENSE-2.0
6+
*
7+
* Unless required by applicable law or agreed to in writing, software
8+
* distributed under the License is distributed on an "AS IS" BASIS,
9+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
10+
* See the License for the specific language governing permissions and
11+
* limitations under the License.
12+
*/
13+
package org.flowable.external.client;
14+
15+
import java.time.Instant;
16+
17+
/**
18+
* @author Filip Hrisafov
19+
*/
20+
public interface ExternalWorkerJob {
21+
22+
/**
23+
* Returns the unique identifier for this job.
24+
*/
25+
String getId();
26+
27+
/**
28+
* Returns the correlation id of a job.
29+
* The same job can be moved around and have its technical id changed.
30+
* This id allows tracking that job.
31+
*/
32+
String getCorrelationId();
33+
34+
/**
35+
* Returns the number of retries this job has left. Whenever the jobexecutor fails to execute the job, this value is decremented.
36+
* When it hits zero, the job is supposed to be dead and not retried again (ie a manual retry is required then).
37+
*/
38+
int getRetries();
39+
40+
/**
41+
* Returns the date on which this job is supposed to be processed.
42+
*/
43+
Instant getDueDate();
44+
45+
/**
46+
* Returns the message of the exception that occurred, the last time the job was executed. Returns null when no exception occurred.
47+
* <p>
48+
* To get the full exception stacktrace, use ManagementService#getJobExceptionStacktrace(String)
49+
*/
50+
String getExceptionMessage();
51+
52+
/**
53+
* Get the tenant identifier for this job.
54+
*/
55+
String getTenantId();
56+
57+
/**
58+
* Reference to an element identifier or null if none is set.
59+
*/
60+
String getElementId();
61+
62+
/**
63+
* Reference to an element name or null if none is set.
64+
*/
65+
String getElementName();
66+
67+
/**
68+
* Reference to a scope identifier or null if none is set.
69+
*/
70+
String getScopeId();
71+
72+
/**
73+
* Reference to a sub scope identifier or null if none is set.
74+
*/
75+
String getSubScopeId();
76+
77+
/**
78+
* Reference to a scope type or null if none is set.
79+
*/
80+
String getScopeType();
81+
82+
/**
83+
* Reference to a scope definition identifier or null if none is set.
84+
*/
85+
String getScopeDefinitionId();
86+
87+
/**
88+
* Returns the creation datetime of the job.
89+
*/
90+
Instant getCreateTime();
91+
92+
/**
93+
* The id of the worker that has the lock on the job
94+
*/
95+
String getWorkerId();
96+
97+
/**
98+
* The time when the lock expires
99+
*/
100+
Instant getLockExpirationTime();
101+
102+
}

0 commit comments

Comments
 (0)