busybee 0.1.0 → 0.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (55) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +71 -7
  3. data/README.md +70 -42
  4. data/docs/client/quick_start.md +279 -0
  5. data/docs/client.md +825 -0
  6. data/docs/configuration.md +550 -0
  7. data/docs/grpc.md +50 -25
  8. data/docs/testing.md +118 -28
  9. data/docs/workers.md +982 -0
  10. data/exe/busybee +6 -0
  11. data/lib/busybee/cli.rb +173 -0
  12. data/lib/busybee/client/error_handling.rb +37 -0
  13. data/lib/busybee/client/job_operations.rb +236 -0
  14. data/lib/busybee/client/message_operations.rb +84 -0
  15. data/lib/busybee/client/process_operations.rb +108 -0
  16. data/lib/busybee/client/variable_operations.rb +64 -0
  17. data/lib/busybee/client.rb +87 -0
  18. data/lib/busybee/configure.rb +290 -0
  19. data/lib/busybee/credentials/camunda_cloud.rb +58 -0
  20. data/lib/busybee/credentials/insecure.rb +24 -0
  21. data/lib/busybee/credentials/oauth.rb +157 -0
  22. data/lib/busybee/credentials/tls.rb +43 -0
  23. data/lib/busybee/credentials.rb +200 -0
  24. data/lib/busybee/defaults.rb +20 -0
  25. data/lib/busybee/error.rb +50 -0
  26. data/lib/busybee/grpc/error.rb +60 -0
  27. data/lib/busybee/grpc.rb +2 -2
  28. data/lib/busybee/job.rb +219 -0
  29. data/lib/busybee/job_stream.rb +85 -0
  30. data/lib/busybee/logging.rb +61 -0
  31. data/lib/busybee/railtie.rb +113 -0
  32. data/lib/busybee/runner/hybrid.rb +64 -0
  33. data/lib/busybee/runner/multi.rb +101 -0
  34. data/lib/busybee/runner/polling.rb +54 -0
  35. data/lib/busybee/runner/streaming.rb +159 -0
  36. data/lib/busybee/runner.rb +97 -0
  37. data/lib/busybee/runtime_config.rb +184 -0
  38. data/lib/busybee/serialization.rb +100 -0
  39. data/lib/busybee/testing/activated_job.rb +33 -8
  40. data/lib/busybee/testing/helpers/execution.rb +139 -0
  41. data/lib/busybee/testing/helpers/support.rb +78 -0
  42. data/lib/busybee/testing/helpers.rb +56 -66
  43. data/lib/busybee/testing/matchers/complete_job.rb +55 -0
  44. data/lib/busybee/testing/matchers/fail_job.rb +75 -0
  45. data/lib/busybee/testing/matchers/have_activated.rb +1 -1
  46. data/lib/busybee/testing/matchers/have_available_jobs.rb +44 -0
  47. data/lib/busybee/testing/matchers/throw_bpmn_error_on.rb +72 -0
  48. data/lib/busybee/testing.rb +5 -33
  49. data/lib/busybee/version.rb +1 -1
  50. data/lib/busybee/worker/configuration.rb +287 -0
  51. data/lib/busybee/worker/dsl.rb +187 -0
  52. data/lib/busybee/worker/shutdown.rb +27 -0
  53. data/lib/busybee/worker.rb +130 -0
  54. data/lib/busybee.rb +134 -2
  55. metadata +80 -3
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: c005e2f714f3f1ea1b3eedf3d8e7b6ce72ad88fe27cf2a8e84637ca4fe3de281
4
- data.tar.gz: cbefb422a412d32143493b8903886e6429f59bd639a3a05de052f89a94be9edb
3
+ metadata.gz: a3bba732da4bc16cfdcf50a8ad7815d8c5dd45d7ae71d5e2978ebe7ba357d1f9
4
+ data.tar.gz: 33cf8753e76eedc975b779185fd38134597a198ef4c8522b090fcfb4d600d390
5
5
  SHA512:
6
- metadata.gz: e812d00b20c0ff7395b72db6225d57a2adcdee6ad9ecf7381215cd5352b5b034458df6bb3728a3cd25429effee83bc1f85c941dc2f4a7937f86cfb3d64f21688
7
- data.tar.gz: 61a813477c650a801a04d6d5ed50dc2a5bbef5686de5690599943a61898d2b77a3d66c52109c037c4e99fcf0cfb02c2393cb9f369cac9a65d3ef9da20a8d9da2
6
+ metadata.gz: 5d068b139505b17f1b91cfdd86c53420c284133507e0dd3263a00236708abb261b0b2318524bbff816cbbf9407961d00610a8d35dab438f7a7b268ade9595f39
7
+ data.tar.gz: aeb232681e9084912c491e3baee068b189975822eead0bfeaaa8907ed1ca72325db699c84d69fc523495a652a604cfe5a836d86571badc83274a91e00b5259ad
data/CHANGELOG.md CHANGED
@@ -1,12 +1,74 @@
1
- ## [Unreleased]
1
+ # Changelog
2
2
 
3
- ## [0.1.0] - 2025-12-29
3
+ ## v0.3.0 (2026-03-13)
4
+
5
+ Worker Pattern Framework and CLI, with testing helpers and YAML configuration support.
6
+
7
+ ### New Features:
8
+
9
+ - **Worker Pattern** (`Busybee::Worker`) – Define job handlers as Ruby classes with a clean DSL:
10
+ - Declarative inputs (`variable`, `header`) and outputs with type hints, defaults, and validation
11
+ - Accessor methods for inputs – use `order_id` directly in `perform` instead of `variables[:order_id]`
12
+ - Automatic job completion on success and failure reporting on exception (`complete_job_on_success`, `fail_job_on_error`)
13
+ - Manual lifecycle control via `complete!`, `fail!`, `throw_bpmn_error!` for complex flows
14
+ - Configurable `shutdown_on` for exceptions that should trigger graceful process shutdown (e.g., `PG::ConnectionBad`)
15
+ - Per-worker configuration via DSL (`worker_mode`, `polling`, `streaming`, `job_timeout`, `backoff`, `backpressure_delay`)
16
+
17
+ - **CLI** (`bundle exec busybee`) – Run workers as long-lived processes:
18
+ - Positional args: `busybee Worker1 Worker2 Worker3`
19
+ - YAML config: `busybee --config config/busybee.yml`
20
+ - Flags: `--worker-mode`, `--log-format`, `--worker-name`, `--cluster-address`
21
+ - Automatic Rails environment loading (skip with `BUSYBEE_SKIP_RAILS=1`)
22
+ - Graceful shutdown on INT/TERM/QUIT; force shutdown on second signal
23
+
24
+ - **Three Worker Modes:**
25
+ - **Polling** – long-polls the Zeebe gateway for available jobs
26
+ - **Streaming** – persistent gRPC stream for lowest-latency job delivery, with optional in-memory buffer and throttle
27
+ - **Hybrid** (default) – combines streaming with polling to handle both new jobs and pre-existing backlogs while still guaranteeing sequential execution
28
+
29
+ - **Multiple Workers:** – run multiple worker classes in a single process, each in its own thread with independently-resolved configuration
30
+
31
+ - **YAML Configuration** – define workers and per-worker configuration in a config file. Top-level settings apply to all workers; per-worker overrides take precedence
32
+
33
+ - **Worker Testing Helpers:**
34
+ - `execute_worker(WorkerClass, variables: {...})` – run a worker's full lifecycle against a test job without Zeebe
35
+ - `build_test_job(variables: {...})` – construct a test job backed by a stub client for state inspection
36
+ - RSpec matchers: `complete_job(job)`, `fail_job(job)`, `throw_bpmn_error_on(job)` with chainable assertions (`.with_vars`, `.with_error`, `.with_code`)
37
+
38
+ ## v0.2.0 (2026-02-05)
39
+
40
+ Production-ready Client API with Rails integration.
41
+
42
+ ### New Features:
43
+
44
+ - **Client Class** (`Busybee::Client`) - a Ruby-idiomatic wrapper around the Zeebe gRPC API:
45
+ - Pluggable authentication with four credential types: `Insecure`, `TLS`, `OAuth`, and `CamundaCloud`
46
+ - Automatic credential type detection from parameters
47
+ - Almost all GRPC operations, including `deploy_process`, `start_instance`, `cancel_instance`, `publish_message`, `broadcast_signal` `set_variables`, `resolve_incident`, `complete_job`, `fail_job`, `throw_bpmn_error`, `update_job_retries`, `update_job_timeout`
48
+ - Two job activation methods: `with_each_job` (long-polling), and `open_job_stream` (continuous stream) with Enumerable wrapper class
49
+ - Rich wrapper class (`Busybee::Job`) for activated jobs:
50
+ - `variables` and `headers` with indifferent access (string or symbol keys)
51
+ - Status tracking (`:ready`, `:complete`, `:failed`) to prevent double-completion
52
+ - Action methods: `complete!`, `fail!`, `throw_bpmn_error!`
53
+ - Variable serialization handles ActiveRecord or other custom objects
54
+
55
+ - **Rails Integration** - Automatic configuration from `config.x.busybee.*`, works seamlessly with Rails secrets
56
+ - Defaults to using Rails logger
57
+ - Structured logs with a `[busybee]` prefix, supporting text or JSON modes
58
+
59
+ ### Breaking Changes:
60
+
61
+ - **Testing::Helpers:**
62
+ - Now uses `Busybee.cluster_address` instead of `Busybee::Testing.address`, which has been removed
63
+ - Was refactored for namespace safety and some methods are no longer accessible within specs
64
+
65
+ ## v0.1.0 (2025-12-29)
4
66
 
5
67
  Initial public release with foundational components for testing BPMN workflows.
6
68
 
7
- ### Added
69
+ ### New Features:
8
70
 
9
- - **Testing module** (`Busybee::Testing`) - RSpec helpers and matchers for testing BPMN workflows against Zeebe:
71
+ - **Testing Module** (`Busybee::Testing`) - RSpec helpers and matchers for testing BPMN workflows against Zeebe:
10
72
  - `deploy_process` - Deploy BPMN files with optional unique IDs for test isolation
11
73
  - `with_process_instance` - Create process instances with automatic cleanup
12
74
  - `activate_job` / `activate_jobs` - Activate jobs for assertions
@@ -16,8 +78,10 @@ Initial public release with foundational components for testing BPMN workflows.
16
78
  - `ActivatedJob` fluent API with `expect_variables`, `expect_headers`, `and_complete`, `and_fail`, `and_throw_error_event`
17
79
  - RSpec matchers: `have_activated`, `have_received_variables`, `have_received_headers`
18
80
 
19
- - **GRPC layer** (`Busybee::GRPC`) - Generated protocol buffer classes from the Zeebe 8.8 proto definition for direct Zeebe API access
81
+ - **GRPC Layer** (`Busybee::GRPC`) - Generated protocol buffer classes from the Zeebe 8.8 proto definition for direct Zeebe API access
82
+
83
+ ## v0.0.1 (2025-12-03)
84
+
85
+ - Initial development, not released
20
86
 
21
- ## [0.0.1] - 2025-12-03
22
87
 
23
- - Initial development, not for release
data/README.md CHANGED
@@ -2,9 +2,9 @@
2
2
 
3
3
  **A complete Ruby toolkit for workflow-based orchestration with BPMN, running on Camunda Platform.**
4
4
 
5
- If you're a Ruby shop that needs workflow orchestration, you've probably noticed the gap: Camunda Platform is powerful, but the Ruby ecosystem support is thin. Busybee fills that gap. One gem, one Camunda Cloud account, and you're ready to start building. And when you're ready to scale further, Busybee is ready to grow with you, with battle-proven patterns for large distributed systems.
5
+ If you're a Ruby shop considering workflow orchestration, you might have noticed: Camunda Platform is powerful, but the Ruby ecosystem support is thin. Busybee fills that gap. One gem, one Camunda Cloud account, and you're ready to start building. And when you're ready to scale further, Busybee is ready to grow with you, with battle-proven patterns for large distributed systems.
6
6
 
7
- Busybee provides everything you need to work with Camunda Platform or self-hosted Zeebe from Ruby:
7
+ Busybee provides everything you need to work with Camunda Platform or self-hosted Zeebe in a Ruby world:
8
8
 
9
9
  - **Worker Pattern Framework** - Define job handlers as classes with a clean DSL. Busybee handles polling, execution, and lifecycle.
10
10
  - **Idiomatic Zeebe Client** - Ruby-native interface with keyword arguments, sensible defaults, and proper exception handling.
@@ -17,10 +17,10 @@ Busybee provides everything you need to work with Camunda Platform or self-hoste
17
17
  | Version | Features | Status |
18
18
  |---------|---------|--------|
19
19
  | v0.1 | BPMN Testing Tools, GRPC Layer | Available now! |
20
- | v0.2 | Client, Rails Integration | January 2026 |
21
- | v0.3 | Worker Pattern & CLI | Early 2026 |
22
- | v0.4 | Instrumentation Hooks, Deployment Tools | Planned for Early 2026 |
23
- | v1.0 | Production Polish | Planned for Mid 2026 |
20
+ | v0.2 | Client, Rails Integration | Available now! |
21
+ | v0.3 | Worker Pattern & CLI | Available now! |
22
+ | v0.4 | Instrumentation Hooks, Deployment Tools | Mid 2026 |
23
+ | v1.0 | Production Polish | Late 2026 |
24
24
 
25
25
  ## Installation
26
26
 
@@ -44,50 +44,63 @@ gem install busybee
44
44
 
45
45
  ## Usage
46
46
 
47
- ### Worker Pattern Framework (coming in early 2026)
47
+ ### Worker Pattern Framework (available now!)
48
48
 
49
- Define job handlers as Ruby classes. Busybee manages the process lifecycle, the connection to Camunda Cloud, and requesting jobs from Zeebe. If you've used Racecar to build Kafka handlers, or Sidekiq to build background jobs, this should feel very familiar.
50
-
51
- > This feature is still being designed. The example shown here is only representative and will change before implementation.
49
+ Define job handlers as Ruby classes. Busybee manages the process lifecycle, the connection to Camunda Cloud, and requesting jobs from Zeebe. If you've used Sidekiq to build background jobs, this should feel very familiar.
52
50
 
53
51
  ```ruby
54
52
  class ProcessOrderWorker < Busybee::Worker
55
- type "process-order"
53
+ job_type "process_order"
56
54
 
57
- input :order_id, required: true
58
- input :customer_email
55
+ variable :order_id, type: :uuid
56
+ variable :customer_email, required: false
59
57
 
60
- output :confirmation_number
58
+ output :confirmation_number, type: :string
61
59
 
62
60
  def perform
63
- confirmation = OrderService.process(order_id)
64
- complete(confirmation_number: confirmation)
61
+ order = Order.find(order_id)
62
+ confirmation = order.process!
63
+ EmailService.send_confirmation(customer_email, confirmation) if customer_email
64
+ { confirmation_number: confirmation }
65
65
  end
66
66
  end
67
67
  ```
68
68
 
69
- Planned capabilities:
69
+ Run workers from the command line:
70
70
 
71
- - Declarative input/output definitions with validation
72
- - Automatic job activation and completion
73
- - Configurable timeouts and retry behavior
74
- - Graceful shutdown on SIGTERM
75
- - CLI for running workers: `bundle exec busybee work` or similar
71
+ ```bash
72
+ bundle exec busybee ProcessOrderWorker ShipOrderWorker
76
73
 
77
- ### Idiomatic Zeebe Client (coming in January 2026)
74
+ # Or with a YAML config file
75
+ bundle exec busybee --config config/busybee.yml
76
+ ```
78
77
 
79
- A Ruby-native client for Zeebe with keyword arguments, sensible defaults, and proper exception handling.
78
+ Capabilities:
79
+
80
+ - Declarative input/output definitions with validation and accessor methods
81
+ - Automatic job completion and failure reporting
82
+ - Three worker modes (polling, streaming, hybrid) for different workload patterns
83
+ - Configurable timeouts, retry backoff, and backpressure handling
84
+ - Graceful shutdown on SIGTERM/SIGINT
85
+ - YAML configuration with per-worker overrides
86
+ - RSpec matchers for unit testing workers without Zeebe
87
+
88
+ **[Full worker documentation &rarr;](docs/workers.md)**
89
+
90
+ ### Idiomatic Zeebe Client (available now!)
80
91
 
81
- > This feature is still being designed. The example shown here is only representative and will change before implementation.
92
+ A Ruby-native client for Zeebe with keyword arguments, sensible defaults, and proper exception handling.
82
93
 
83
94
  ```ruby
95
+ # Connect to Camunda Cloud with environment variables
96
+ # (CAMUNDA_CLIENT_ID, CAMUNDA_CLIENT_SECRET, CAMUNDA_CLUSTER_ID, CAMUNDA_CLUSTER_REGION)
84
97
  client = Busybee::Client.new
85
98
 
86
99
  # Deploy a workflow
87
100
  client.deploy_process("workflows/order-fulfillment.bpmn")
88
101
 
89
102
  # Start a process instance
90
- instance_key = client.start_process("order-fulfillment",
103
+ instance_key = client.start_instance("order-fulfillment",
91
104
  vars: { order_id: "123", items: ["widget", "gadget"] }
92
105
  )
93
106
 
@@ -96,19 +109,27 @@ client.publish_message("payment-received",
96
109
  correlation_key: "order-123",
97
110
  vars: { amount: 99.99 }
98
111
  )
112
+
113
+ # Process jobs (for ad-hoc use; for production job processing, use the Worker pattern above)
114
+ client.with_each_job("send-confirmation") do |job|
115
+ EmailService.send(job.variables.customer_email)
116
+ job.complete!(sent_at: Time.now.iso8601)
117
+ end
99
118
  ```
100
119
 
101
- Planned capabilities:
120
+ Capabilities:
121
+
122
+ - Multiple credential types (Insecure, TLS, OAuth, Camunda Cloud) with automatic detection
123
+ - Complete process lifecycle: deploy, start, cancel, set variables, resolve incidents
124
+ - Job operations: activate, complete, fail, throw BPMN errors, streaming
125
+ - Rails integration via Railtie with `config.x.busybee.*` configuration
126
+ - GRPC error wrapping with configurable retry
102
127
 
103
- - Connection management with automatic reconnection
104
- - Multiple credential types (insecure, TLS, OAuth, Camunda Cloud)
105
- - GRPC error wrapping with preserved cause chains
106
- - Rails integration via Railtie and `config/busybee.yml`
107
- - Duration support for timeouts (works with ActiveSupport if present)
128
+ **[Full client documentation →](docs/client.md)**
108
129
 
109
130
  ### RSpec Testing Integration (available now!)
110
131
 
111
- Deploy processes, create instances, activate jobs, and verify workflow behavior against a real Zeebe instance. A full replacement for the [zeebe_bpmn_rspec](https://github.com/ezcater/zeebe_bpmn_rspec) gem.
132
+ Allows you to unit test your BPMN files. Deploy processes, create instances, activate jobs, and verify workflow behavior against a real Zeebe instance.
112
133
 
113
134
  #### Setup
114
135
 
@@ -117,8 +138,9 @@ Deploy processes, create instances, activate jobs, and verify workflow behavior
117
138
  require "rspec"
118
139
  require "busybee/testing"
119
140
 
120
- Busybee::Testing.configure do |config|
121
- config.address = "localhost:26500" # or use ZEEBE_ADDRESS env var
141
+ # Optional: defaults to localhost:26500, or set CLUSTER_ADDRESS env var
142
+ Busybee.configure do |config|
143
+ config.cluster_address = "localhost:26500"
122
144
  end
123
145
  ```
124
146
 
@@ -156,9 +178,9 @@ end
156
178
  - `assert_process_completed!` - Verify workflow reached an end event
157
179
  - `have_activated`, `have_received_variables`, `have_received_headers` - RSpec matchers
158
180
 
159
- **[Full testing documentation](docs/testing.md)**
181
+ **For more info, see our [full testing documentation here](docs/testing.md).** For unit testing workers, see [Workers: Testing Workers](docs/workers.md#testing-workers).
160
182
 
161
- ### Deployment Tools (coming in early 2026)
183
+ ### Deployment Tools (coming in mid 2026)
162
184
 
163
185
  CI/CD tooling for deploying BPMN processes to your Zeebe clusters. Version tracking, environment-specific deployments, and pre-deployment validation.
164
186
 
@@ -166,6 +188,8 @@ CI/CD tooling for deploying BPMN processes to your Zeebe clusters. Version track
166
188
 
167
189
  For edge cases where the higher-level abstractions don't cover what you need, busybee exposes the raw GRPC interface to Zeebe. This is a complete drop-in replacement for the now-discontinued [zeebe-client](https://github.com/zeebe-io/zeebe-client-ruby) gem.
168
190
 
191
+ > Most users won't need this, as the Testing module, Client class, and Worker pattern cover most common use cases.
192
+
169
193
  ```ruby
170
194
  require "busybee/grpc"
171
195
 
@@ -179,17 +203,21 @@ response = stub.topology(request)
179
203
  puts response.brokers.map(&:host)
180
204
  ```
181
205
 
182
- Most users won't need this—the Testing module and future Client cover common workflows. See **[GRPC documentation](docs/grpc.md)** for details.
206
+ **For more info, see the [full GRPC documentation here](docs/grpc.md).**
207
+
208
+ ### Demo Application
209
+
210
+ The [Dropship Co. demo app](spec/demo/README.md) is a multi-domain Rails application that showcases busybee in action. It orchestrates order fulfillment across warehousing, logistics, and delivery services using BPMN workflows and busybee workers. It's a good place to see realistic usage patterns and to experiment with the framework.
183
211
 
184
212
  ## Ruby Implementation Support
185
213
 
186
- Busybee currently only supports MRI (CRuby). JRuby is not supported because it cannot run C extensions (it would require `grpc-java` with a Ruby wrapper). TruffleRuby's C extension support is experimental and the `grpc` gem does not currently build on it.
214
+ Busybee currently only supports MRI (CRuby). This is due to the state of `grpc` support on other implementations. JRuby is not supported because it cannot run C extensions (it would require `grpc-java` with a Ruby wrapper). TruffleRuby's C extension support is experimental and the `grpc` gem does not currently build on it.
187
215
 
188
- If you successfully run busybee on an alternative Ruby implementation, please open an issue. We'd welcome contributions to expand platform support!
216
+ If you successfully run busybee on an alternative Ruby implementation, please open a GitHub issue to let us know! We'd welcome contributions to expand platform support.
189
217
 
190
218
  ## Development
191
219
 
192
- Busybee includes a Docker Compose setup for running Zeebe locally, plus rake tasks for common development workflows.
220
+ Busybee includes a Docker Compose setup for running Zeebe locally, plus rake tasks for common development workflows:
193
221
 
194
222
  ```bash
195
223
  bin/setup # Install dependencies
@@ -199,7 +227,7 @@ bundle exec rspec # Run unit tests
199
227
  RUN_INTEGRATION_TESTS=1 bundle exec rspec # Run all tests including integration
200
228
  ```
201
229
 
202
- **[Full development guide](docs/development.md)** Local environment setup, running tests, regenerating GRPC classes, and release procedures.
230
+ **The full development guide for contributors [is available here](docs/development.md),** including local environment setup, running tests, regenerating GRPC classes, and release procedures.
203
231
 
204
232
  ## Contributing
205
233
 
@@ -0,0 +1,279 @@
1
+ # Busybee::Client Quick Start
2
+
3
+ This tutorial gets you from zero to a deployed process and running instance in about 10 minutes. By the end, you'll have:
4
+
5
+ 1. A Zeebe environment (local or Camunda Cloud)
6
+ 2. Busybee configured with appropriate credentials
7
+ 3. A BPMN process deployed
8
+ 4. A running process instance
9
+
10
+ ## Prerequisites
11
+
12
+ Before starting, you'll need:
13
+
14
+ - Ruby 3.2+
15
+ - A Zeebe environment (see "Choose Your Environment" below)
16
+ - A BPMN process file (we'll create a simple one, or you can use an existing one)
17
+
18
+ ## Step 1: Install Busybee
19
+
20
+ Add to your Gemfile:
21
+
22
+ ```ruby
23
+ gem "busybee"
24
+ ```
25
+
26
+ Then run:
27
+
28
+ ```bash
29
+ bundle install
30
+ ```
31
+
32
+ ## Step 2: Choose Your Environment
33
+
34
+ Busybee supports both local Zeebe (typical for development) and Camunda Cloud (recommended for production).
35
+
36
+ ### Option A: Local Zeebe
37
+
38
+ For local development, you can run Zeebe using Docker. The simplest setup is:
39
+
40
+ ```bash
41
+ docker run -d --name zeebe -p 26500:26500 camunda/zeebe:latest
42
+ ```
43
+
44
+ For a more complete setup with Operate (the web UI for monitoring workflows), see the [Camunda Docker Compose documentation](https://docs.camunda.io/docs/self-managed/setup/deploy/local/docker-compose/).
45
+
46
+ When using local Zeebe, you'll use insecure (non-TLS) connections.
47
+
48
+ ### Option B: Camunda Cloud
49
+
50
+ Camunda Cloud is Camunda's managed SaaS offering. To get started:
51
+
52
+ 1. Create a free account at [camunda.io](https://camunda.io/)
53
+ 2. Create a cluster (the free tier includes a development cluster)
54
+ 3. Create API credentials:
55
+ - Go to your cluster's "API" tab
56
+ - Click "Create new client"
57
+ - Select "Zeebe" scope
58
+ - Save the credentials (you'll need: Client ID, Client Secret, Cluster ID, and Region)
59
+
60
+ For detailed setup instructions, see [Camunda Cloud Getting Started](https://docs.camunda.io/docs/guides/getting-started/).
61
+
62
+ ## Step 3: Configure Credentials
63
+
64
+ A Busybee::Client needs to know where to find the Zeebe cluster and how to authenticate to it. There are many ways to provide or configure this information, which you can find in the [Client reference](../client.md). For the purpose of this tutorial, we'll pass this information directly to `new`:
65
+
66
+ ### For Local Zeebe
67
+
68
+ ```ruby
69
+ require "busybee"
70
+
71
+ client = Busybee::Client.new(
72
+ cluster_address: "localhost:26500",
73
+ insecure: true
74
+ )
75
+ ```
76
+
77
+ ### For Camunda Cloud
78
+
79
+ ```ruby
80
+ require "busybee"
81
+
82
+ client = Busybee::Client.new(
83
+ client_id: "your client ID",
84
+ client_secret: "your client secret",
85
+ cluster_id: "your cluster ID (typically a UUID)",
86
+ region: "your cluster region (e.g. 'bru-2')"
87
+ )
88
+ ```
89
+
90
+ ### Rails Configuration
91
+
92
+ In a Rails app, configure via `config/application.rb` or an initializer:
93
+
94
+ ```ruby
95
+ # config/application.rb or config/initializers/busybee.rb
96
+ Rails.application.configure do
97
+ config.x.busybee.credential_type = :camunda_cloud
98
+ config.x.busybee.cluster_address = ENV["CLUSTER_ADDRESS"] # for local/TLS
99
+ # OAuth credentials are passed to Client.new, not configured globally
100
+ end
101
+ ```
102
+
103
+ ## Step 4: Create a BPMN Process
104
+
105
+ BPMN (Business Process Model and Notation) files define your workflows. You can create them using:
106
+
107
+ - **Camunda Modeler** (desktop app) - Download from [camunda.com/download/modeler](https://camunda.com/download/modeler/)
108
+ - **Camunda Cloud Web Modeler** - Available in your Camunda Cloud console
109
+ - **Any BPMN 2.0 editor** - Busybee works with standard BPMN files
110
+
111
+ Here's a minimal example you can save as `simple_process.bpmn`:
112
+
113
+ ```xml
114
+ <?xml version="1.0" encoding="UTF-8"?>
115
+ <bpmn:definitions xmlns:bpmn="http://www.omg.org/spec/BPMN/20100524/MODEL"
116
+ xmlns:zeebe="http://camunda.org/schema/zeebe/1.0"
117
+ id="Definitions_1"
118
+ targetNamespace="http://bpmn.io/schema/bpmn">
119
+ <bpmn:process id="hello-world" name="Hello World" isExecutable="true">
120
+ <bpmn:startEvent id="Start">
121
+ <bpmn:outgoing>Flow1</bpmn:outgoing>
122
+ </bpmn:startEvent>
123
+ <bpmn:endEvent id="End">
124
+ <bpmn:incoming>Flow1</bpmn:incoming>
125
+ </bpmn:endEvent>
126
+ <bpmn:sequenceFlow id="Flow1" sourceRef="Start" targetRef="End"/>
127
+ </bpmn:process>
128
+ </bpmn:definitions>
129
+ ```
130
+
131
+ This creates a process that starts and immediately ends. Real processes would include service tasks, gateways, and other BPMN elements.
132
+
133
+ For more about BPMN modeling, see the [Camunda BPMN documentation](https://docs.camunda.io/docs/components/modeler/bpmn/).
134
+
135
+ ## Step 5: Deploy the Process
136
+
137
+ Deploy your BPMN file to Zeebe:
138
+
139
+ ```ruby
140
+ # Deploy a single file
141
+ result = client.deploy_process("simple_process.bpmn")
142
+ # => { "hello-world" => 2251799813685249 }
143
+
144
+ # The result maps process IDs to definition keys
145
+ process_id = result.keys.first # => "hello-world"
146
+ definition_key = result.values.first # => 2251799813685249
147
+
148
+ # Deploy multiple files at once
149
+ result = client.deploy_process("order.bpmn", "payment.bpmn")
150
+ # => { "order-process" => 123, "payment-process" => 456 }
151
+ ```
152
+
153
+ The returned hash maps BPMN process IDs (the `id` attribute on the `<bpmn:process>` element) to process definition keys (unique identifiers assigned by Zeebe).
154
+
155
+ ## Step 6: Start a Process Instance
156
+
157
+ Now start an instance of your deployed process:
158
+
159
+ ```ruby
160
+ # Start a basic instance
161
+ instance_key = client.start_instance("hello-world")
162
+ # => 2251799813685300
163
+
164
+ # Start with variables
165
+ instance_key = client.start_instance("order-process",
166
+ vars: { order_id: "ORD-123", customer: "Alice", total: 99.99 }
167
+ )
168
+
169
+ # Start a specific version (not the latest)
170
+ instance_key = client.start_instance("order-process",
171
+ vars: { order_id: "ORD-456" },
172
+ version: 2
173
+ )
174
+ ```
175
+
176
+ The returned `instance_key` is the unique identifier for this process instance.
177
+
178
+ ## Putting It All Together
179
+
180
+ Here's a complete example:
181
+
182
+ ```ruby
183
+ require "busybee"
184
+
185
+ # Configure for local development
186
+ client = Busybee::Client.new(insecure: true)
187
+
188
+ # Deploy the process
189
+ deployments = client.deploy_process("workflows/order-fulfillment.bpmn")
190
+ puts "Deployed: #{deployments.keys.join(', ')}"
191
+
192
+ # Start an instance
193
+ instance_key = client.start_instance("order-fulfillment",
194
+ vars: {
195
+ order_id: "ORD-2024-001",
196
+ items: ["widget", "gadget"],
197
+ total: 149.99
198
+ }
199
+ )
200
+ puts "Started instance: #{instance_key}"
201
+
202
+ # You can now monitor this instance in Operate (web UI)
203
+ # or interact with it via messages and signals
204
+ ```
205
+
206
+ ## What's Next?
207
+
208
+ Now that you have a running process instance, you might want to:
209
+
210
+ - **Cancel an instance**: `client.cancel_instance(instance_key)`
211
+ - **Publish a message** to trigger a message catch event: `client.publish_message("payment-received", correlation_key: "ORD-2024-001", vars: { amount: 149.99 })`
212
+ - **Broadcast a signal** to all waiting instances: `client.broadcast_signal("system-shutdown")`
213
+ - **Set variables** on a running instance: `client.set_variables(instance_key, vars: { status: "approved" })`
214
+
215
+ See the API Reference section below for complete documentation of all available methods.
216
+
217
+ # Credential Types
218
+
219
+ Busybee supports four credential types for different environments:
220
+
221
+ | Type | Use Case | TLS | Authentication |
222
+ |------|----------|-----|----------------|
223
+ | `:insecure` | Local development, Docker, CI | No | None |
224
+ | `:tls` | Self-hosted with TLS | Yes | Server cert only |
225
+ | `:oauth` | Self-hosted with OAuth | Yes | OAuth2 client credentials |
226
+ | `:camunda_cloud` | Camunda Cloud SaaS | Yes | OAuth2 (auto-configured) |
227
+
228
+ ## Insecure Credentials
229
+
230
+ For local development with no TLS or authentication:
231
+
232
+ ```ruby
233
+ client = Busybee::Client.new(insecure: true)
234
+
235
+ # Or with explicit address
236
+ client = Busybee::Client.new(insecure: true, cluster_address: "zeebe:26500")
237
+ ```
238
+
239
+ ## TLS Credentials
240
+
241
+ For self-hosted Zeebe with TLS but no client authentication:
242
+
243
+ ```ruby
244
+ client = Busybee::Client.new(
245
+ cluster_address: "zeebe.example.com:443",
246
+ certificate_file: "/path/to/ca.crt" # Optional: custom CA certificate
247
+ )
248
+ ```
249
+
250
+ ## OAuth Credentials
251
+
252
+ For self-hosted Zeebe with OAuth2 authentication:
253
+
254
+ ```ruby
255
+ client = Busybee::Client.new(
256
+ cluster_address: "zeebe.example.com:443",
257
+ token_url: "https://auth.example.com/oauth/token",
258
+ client_id: "my-client-id",
259
+ client_secret: "my-client-secret",
260
+ audience: "zeebe.example.com"
261
+ )
262
+ ```
263
+
264
+ ## Camunda Cloud Credentials
265
+
266
+ For Camunda Cloud, the cluster address and OAuth configuration are derived automatically:
267
+
268
+ ```ruby
269
+ client = Busybee::Client.new(
270
+ client_id: ENV["CAMUNDA_CLIENT_ID"],
271
+ client_secret: ENV["CAMUNDA_CLIENT_SECRET"],
272
+ cluster_id: ENV["CAMUNDA_CLUSTER_ID"],
273
+ region: ENV["CAMUNDA_CLUSTER_REGION"] # e.g., "bru-2", "us-east-1"
274
+ )
275
+ ```
276
+
277
+ # Next Steps
278
+
279
+ For complete API documentation, error handling details, and advanced usage, see the [Client documentation](../client.md).