Presented by Jan Galinski
Zeebe is the new microservice orchestration engine by camunda. It allows clients to subscribe to tasks and track the completion and overall end-to-end progress of your business processes. It basically consists of a network of brokers and clients, which can be written in multiple languages.
Spring Boot is a platform to create self-contained microservice on the JVM and supports integration in „cloud“ environments.
Bringing those two ideas together seems like a natural fit. To simplify writing jvm-based zeebe-clients with spring boot, I set up the spring-zeebe extension, which brings the „everything just works“ feeling you expect from a spring boot starter to the zeebee world.
But what if you run these spring boot clients in a cloud environment? The current broker-client architecture relies on host/port binding, a luxuary you might not have when your components are highly distributed and cannot see each other in the network.
That’s where apache camel comes to the rescue. Camel is an enterprise integration solution that supports many messaging middlewares and frees your code from actually knowing if the communication will be tcp, jms, kafka or even file-based. With the camel-zeebe extension you can leverage these benefits and subscribe to arbitrary message channels to connect to the broker instead of relying on a tcp host/port connection.
What happens in this talk: – short introduction to zeebe, spring boot, camel – life demo setting up broker/client with spring boot – life demo enhancing this approach with camel and rabbitMq
6. zeebe
■ developed by camunda
■ decentralized process engine
■ orchestration of microservices
■ current version 0.11.0 (release planned
2019/Q1)
■ Broker and Client API
8. spring boot
■ developed by pivotal
■ current version 2.0.5 (2018/09)
■ annotation based
■ opinionated - convention over configuration
■ "starter" concept
■ executable jars
10. spring-zeebe
■ "Requested" by Bernd
■ First Release End 2017
■ can run broker and clients
■ yaml based configuration
■ allows annotation based subscriptions
■ current version: 0.3.0-SNAPSHOT
https://github.com/zeebe-io/spring-zeebe
11. Example: spring-zeebe-
starter
@SpringBootApplication
@EnableZeebeClient
public class WorkerApplication {
public static void main(final String... args) {
SpringApplication.run(WorkerApplication.class, args);
}
@ZeebeWorker(taskType = "sayHello")
public void sayHello(final JobClient client, final JobEvent job) {
client.newCompleteCommand(job)
.payload("{"hello": "world"}")
.send().join();
}
}
13. Apache Camel
■ Apache Foundation Open Source
■ First commit 2007 (!)
■ Implements Enterprise Integration Patterns
■ 200+ production ready components
■ (almost) any transport protocol
14.
15. Camel building blocks
A Route
■ defines a data flow
■ starts with an Endpoint
■ can have (multiple) Processors modifying
data
■ ends with an Endpoint
16. Camel building blocks
An Endpoint
Is either a ...
■ Consumer - starts a route, creates an
Exchange
or a
■ Producer - ends a route, exposes Exchange
17. Camel building blocks
A Component
■ provides a name-space (file://folder)
■ is a factory for Endpoints
18. Camel building blocks
An Exchange
■ represents data in a Route
■ encloses Messages (In and Out)
■ Messages have a Header (Map) and a Body
19. Route Example
// subscribe to topic
from("activemq:topic?[options]")
.filter(doSomeFiltering())
// call a processor-method
.process(convertToPojo())
// process input using spring service
.bean(TheBusinessService.class)
// write csv
.marshal().csv()
// store result on server
.to("ftp:host?[options]")
21. Motivation
■ Do not assume that worker can connect to
broker via tcp
■ do not require worker to speak "zeebe"
■ support any worker language
■ support any messaging protocol
22. Camel Zeebe API
■ immutable Commands and Events
■ no dependency on zeebe-lib
■ Supports
□ Register Self
□ Start Process
□ Complete Job
□ ...
23. Camel Zeebe API
data class StartProcessCommand(
val bpmnProcessId: String,
val payload: Json? = null
)
interface StartProcessGateway {
companion object { const val ENDPOINT = "direct:startProcess" }
fun send(command: StartProcessCommand)
}
startProcessGateway.send(StartProcessCommand("process_dummy", <payloadJson>))
24. Camel Zeebe Core
■ Zeebe Client connected to Broker
■ Camel Component defining zeebe://...
■ Provides Endpoints to
□ Register Worker
□ Start Process
□ Complete Job
□ ...
25. Camel Zeebe Core
class ProcessStartEndpoint(context: ZeebeComponentContext) : ZeebeProducerOnlyEndpoint(...) {
override fun createProducer(): Producer = object : DefaultProducer(this) {
override fun process(exchange: Exchange) {
val cmd = exchange.getIn().getMandatoryBody(StartProcessCommand::class.java)
context.workflowClient
.newCreateInstanceCommand()
.bpmnProcessId(cmd.bpmnProcessId)
.latestVersion()
.payload(cmd.payload)
.send()
.join()
}
}
}
34. What just happened
■ Zeebe Broker does not know workers
■ Workers do not use Zeebe-API
■ Only Orchestrator is connected to Broker
■ Camel routes connect everything
35. What we could do
■ replace file system with messaging
infrastructure
■ any camel supported route will work out of the
box
■ any program that can write/read the JSON-API
can be a worker
■ Test routes by mocking components