eventhub-processor2 1.25.0 → 1.26.1

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: d78c7de7448b619cc5dce05f62af274a5310e1abf85986e8cd7e014d49e8bbb5
4
- data.tar.gz: c56a15cde07013aea85c6d1c67c674fa55802e7c0cf8299a54f7b6a48f0e7278
3
+ metadata.gz: d95676a331273b8afbe6f83ed5349e515ff7631d3217df6338b79f2e6e125f4f
4
+ data.tar.gz: 18b6632417f91ff8795d9e2b755dea4cd4c0f0eddfec10afa9a375c9ba717a13
5
5
  SHA512:
6
- metadata.gz: dc364064bc7c6c54444c15165c204b4314533f7df2e4fd0e1a3d065e2ec19b5b6586501a603e0b1b8e3fb3b8f0357a9a3279b70ab9e45198e061a77c28b29a9b
7
- data.tar.gz: 65e9922a923b95ecdbade34deb040abee4a9575772df22cf183340182d26f9353a04f53b39ea69b6346c2ae4858ec9b8265095b98bb241ceefea673aaf3458ea
6
+ metadata.gz: db9e521ff4185fd17012c8beaf62e11d440469116c77a02b246c4b675e4abab3d3f863985f4a55c99908cffeec2f500298f2bbffb803f4fabcf41934ca1774b3
7
+ data.tar.gz: d6686f41f63a610a7a66eaf3f476e8e5a0d0de3a8e387fc70a972969b95690170c82e8d5f1ae06d05afc38a8dc69c4ff1c0dffe0f1604cb299458d954c958600
@@ -1,4 +1,4 @@
1
- name: ci
1
+ name: 01 - Test
2
2
 
3
3
  on:
4
4
  push:
@@ -23,7 +23,7 @@ jobs:
23
23
  strategy:
24
24
  fail-fast: false
25
25
  matrix:
26
- ruby: [ '4.0', '3.4', '3.3', '3.2']
26
+ ruby: [ '4.0', '3.4', '3.3']
27
27
 
28
28
  name: Ruby ${{ matrix.ruby }}
29
29
  steps:
@@ -0,0 +1,57 @@
1
+ name: 02 - Test, Build and Release
2
+
3
+ on:
4
+ push:
5
+ tags:
6
+ - 'v*'
7
+
8
+ jobs:
9
+
10
+ test:
11
+ runs-on: ubuntu-latest
12
+ env:
13
+ CC_TEST_REPORTER_ID: ${{ secrets.CC_TEST_REPORTER_ID }}
14
+
15
+ steps:
16
+ - uses: actions/checkout@v6
17
+
18
+ - name: Set up Ruby
19
+ uses: ruby/setup-ruby@v1
20
+ with:
21
+ ruby-version: '4.0'
22
+ bundler: latest
23
+ bundler-cache: true
24
+ cache-version: 4
25
+
26
+ - name: Setup RabbitMQ
27
+ run: |
28
+ cd docker && docker build -t processor-rabbitmq .
29
+ docker run -d -p 5672:5672 -p 15672:15672 --name processor-rabbitmq processor-rabbitmq
30
+
31
+ - name: Run default task
32
+ run: |
33
+ bundle exec rake
34
+
35
+ build:
36
+ needs: test
37
+ runs-on: ubuntu-latest
38
+ permissions:
39
+ id-token: write # Required for OIDC
40
+ contents: write # Required for pushing tags
41
+
42
+ steps:
43
+ - name: Checkout current code
44
+ uses: actions/checkout@v6
45
+
46
+ - name: Set up Ruby
47
+ uses: ruby/setup-ruby@v1
48
+ with:
49
+ ruby-version: '4.0'
50
+ bundler-cache: true
51
+ cache-version: 1
52
+
53
+ - name: Build gem
54
+ run: gem build *.gemspec
55
+
56
+ - name: Push to Rubygems
57
+ uses: rubygems/release-gem@v1
data/.tool-versions CHANGED
@@ -1 +1 @@
1
- ruby 4.0.1
1
+ ruby 4.0.2
data/CHANGELOG.md CHANGED
@@ -1,5 +1,19 @@
1
1
  # Changelog of EventHub::Processor2
2
2
 
3
+ # 1.26.1 / 2026-03-20
4
+
5
+ * Show only processor name in browser tab title
6
+
7
+ # 1.26.0 / 2026-03-18
8
+
9
+ * Add HTTP resources for version, docs, changelog, and configuration with HTML rendering
10
+ * Add processor hooks for HTTP resource customization: `version`, `company_name`, `readme_as_html`, `changelog_as_html`, `configuration_as_html`, `sensitive_keys`, and `http_resources`
11
+ * Heartbeat endpoint returns detailed JSON status (version, pid, uptime, messages)
12
+ * Add distributed tracing with correlation_id and execution_id in structured log output
13
+ * Simplify HTTP configuration with shared `http.bind_address`, `http.port`, and `http.base_path`
14
+ * Add kramdown dependency for markdown to HTML conversion
15
+ * Rename GitHub Actions workflows and add test step to release workflow
16
+
3
17
  # 1.25.0 / 2026-01-13
4
18
 
5
19
  * Replace uuidtools dependency with Ruby's built-in SecureRandom
data/README.md CHANGED
@@ -1,5 +1,6 @@
1
1
  [![Gem Version](https://badge.fury.io/rb/eventhub-processor2.svg)](https://badge.fury.io/rb/eventhub-processor2)
2
- [![ci](https://github.com/thomis/eventhub-processor2/actions/workflows/ci.yml/badge.svg)](https://github.com/thomis/eventhub-processor2/actions/workflows/ci.yml)
2
+ [![01 - Test](https://github.com/thomis/eventhub-processor2/actions/workflows/01_test.yml/badge.svg)](https://github.com/thomis/eventhub-processor2/actions/workflows/01_test.yml)
3
+ [![02 - Test, Build and Release](https://github.com/thomis/eventhub-processor2/actions/workflows/02_test_build_and_release.yml/badge.svg)](https://github.com/thomis/eventhub-processor2/actions/workflows/02_test_build_and_release.yml)
3
4
 
4
5
  # EventHub::Processor2
5
6
 
@@ -10,7 +11,7 @@ Processor2 has currently the following sub-components implemented
10
11
  * Publisher - responsible for message publishing
11
12
  * Watchdog - Checks regularly broker connection and defined listener queue(s)
12
13
  * Listener AMQP - Listens to defined AMQP queues, parses recevied message into a EventHub::Message instance and calls handle_message method as defined in derived class.
13
- * Listener HTTP - Provides an http endpoint for health checks (Exp. /svc/{class_name}/heartbeat)
14
+ * Listener HTTP - Provides HTTP endpoints for health checks and monitoring (e.g. /svc/{class_name}/heartbeat, /svc/{class_name}/version)
14
15
 
15
16
  Processor2 is using Bunny http://rubybunny.info a feature complete RabbitMQ Client to interact with message broker. Processor2 can deal with long running message processing.
16
17
 
@@ -18,11 +19,12 @@ Processor2 is using Bunny http://rubybunny.info a feature complete RabbitMQ Clie
18
19
 
19
20
  Currently supported and tested ruby versions are:
20
21
 
22
+ - 4.0 (EOL 2029-03-31)
21
23
  - 3.4 (EOL 2028-03-31)
22
24
  - 3.3 (EOL 2027-03-31)
23
- - 3.2 (EOL 2026-03-31)
24
25
 
25
26
  Ruby versions not tested anymore:
27
+ - 3.2 (EOL 2026-03-31)
26
28
  - 3.1 (EOL 2025-03-31)
27
29
  - 3.0 (EOL 2024-04-23)
28
30
 
@@ -65,6 +67,7 @@ module EventHub
65
67
  # => :content_type
66
68
  # => :priority
67
69
  # => :delivery_tag
70
+ # => :correlation_id (if present in incoming AMQP message)
68
71
 
69
72
  # if an exception is raised in your code
70
73
  # it will be automatically catched by
@@ -114,6 +117,73 @@ I, [2018-02-09T15:22:35.658522 #37966] INFO -- : Listener is starting...
114
117
  I, [2018-02-09T15:22:35.699161 #37966] INFO -- : Listening to queue [example]
115
118
  ```
116
119
 
120
+ ## Logging
121
+
122
+ By default, Processor2 logs to both stdout (standard format) and a logstash file. For containerized environments (Docker, Kubernetes), use the `--console-log-only` option to output structured JSON logs to stdout only:
123
+
124
+ ```bash
125
+ bundle exec ruby example.rb --console-log-only
126
+ ```
127
+
128
+ This outputs logs in JSON format suitable for log aggregation systems:
129
+
130
+ ```json
131
+ {"@timestamp":"2026-01-18T10:00:00.000Z","@version":"1","severity":"INFO","host":"server1","application":"example","environment":"production","message":"example (1.0.0): has been started"}
132
+ ```
133
+
134
+ ## Correlation ID
135
+
136
+ Processor2 supports automatic propagation of correlation IDs for distributed tracing. While EventHub messages already contain an `execution_id` in the message body for tracing, the AMQP `correlation_id` provides an additional benefit: it's part of the message metadata (envelope), not the payload. This means it's available even when the JSON body is invalid and cannot be parsed - useful for error tracking and debugging malformed messages.
137
+
138
+ When an incoming AMQP message includes a `correlation_id` in its metadata:
139
+
140
+ 1. **Automatic logging**: All log messages during message processing will include `correlation_id` as a separate field in structured JSON output
141
+ 2. **Automatic publishing**: Any messages published during processing will automatically include the same correlation_id in their AMQP headers
142
+ 3. **Available in args**: The correlation_id is passed to `handle_message` via `args[:correlation_id]`
143
+ 4. **Consistent execution_id**: When creating new messages, `execution_id` is automatically set to match `correlation_id`, ensuring consistent tracing across both AMQP metadata and message body
144
+
145
+ This happens transparently without any changes to your `handle_message` implementation:
146
+
147
+ ```ruby
148
+ def handle_message(message, args = {})
149
+ # correlation_id is available in args if needed
150
+ correlation_id = args[:correlation_id]
151
+
152
+ # Logging automatically includes correlation_id in JSON output
153
+ EventHub.logger.info("Processing order")
154
+
155
+ # Publishing automatically includes correlation_id
156
+ publish(message: response.to_json)
157
+
158
+ message.copy
159
+ end
160
+ ```
161
+
162
+ You can also explicitly set or override the correlation_id when publishing:
163
+
164
+ ```ruby
165
+ publish(message: msg.to_json, correlation_id: "550e8400-e29b-41d4-a716-446655440000")
166
+ ```
167
+
168
+ If no `correlation_id` is present in the AMQP metadata, the message body's `execution_id` is used as fallback to ensure tracing continuity.
169
+
170
+ ### How it works
171
+
172
+ 1. **Received**: When an AMQP message arrives, `correlation_id` is extracted from the message metadata
173
+ 2. **Fallback**: If no `correlation_id` in AMQP metadata, the message body's `execution_id` is used instead (ensuring tracing continuity)
174
+ 3. **Stored**: The value is stored in thread-local storage (`Thread.current`) for the duration of message processing
175
+ 4. **Passed**: The `correlation_id` is passed to `handle_message` via `args[:correlation_id]`
176
+ 5. **Logging**: The logger automatically reads from thread-local storage and includes it in JSON output
177
+ 6. **Publishing**: The publisher automatically reads from thread-local storage and adds it to outgoing AMQP message headers (can be overwritten by passing `correlation_id:` explicitly)
178
+ 7. **New messages**: When creating a new `EventHub::Message`:
179
+ - With `correlation_id` present → `execution_id` is set to match `correlation_id`
180
+ - Without `correlation_id` → `execution_id` is set to a new UUID (default behavior)
181
+ 8. **Cleared**: After message processing completes, the stored value is cleared
182
+
183
+ This design ensures correlation_id flows transparently through the entire message processing lifecycle. No code changes are required for existing implementations - just update the processor2 gem dependency.
184
+
185
+ **Note:** We use `correlation_id` (snake_case) to follow Ruby naming conventions, AMQP standard message properties, and stay consistent with other args keys like `:queue_name`, `:content_type`, etc. The `correlation_id` value is typically a UUID (e.g., `550e8400-e29b-41d4-a716-446655440000`).
186
+
117
187
  ## Configuration
118
188
 
119
189
  If --config option is not provided processor tries to load config/{class_name}.json. If file does not exist it loads default values as specified below.
@@ -133,10 +203,10 @@ If --config option is not provided processor tries to load config/{class_name}.j
133
203
  "tls_ca_certificates": [],
134
204
  "verify_peer": false,
135
205
  "show_bunny_logs": false,
136
- "heartbeat": {
206
+ "http": {
137
207
  "bind_address": "localhost",
138
208
  "port": 8080,
139
- "path": "/svc/{class_name}/heartbeat"
209
+ "base_path": "/svc/{class_name}"
140
210
  }
141
211
  },
142
212
  "processor": {
@@ -228,6 +298,239 @@ Final configuration result
228
298
 
229
299
  ```
230
300
 
301
+ ## HTTP Resources
302
+
303
+ Processor2 exposes HTTP resources for health checks and monitoring. All resources share the same HTTP server configuration.
304
+
305
+ **Configuration:**
306
+ ```json
307
+ {
308
+ "server": {
309
+ "http": {
310
+ "bind_address": "localhost",
311
+ "port": 8080,
312
+ "base_path": "/svc/{class_name}"
313
+ }
314
+ }
315
+ }
316
+ ```
317
+
318
+ Resources are mounted under the `base_path`:
319
+ - `{base_path}/heartbeat` - Health check
320
+ - `{base_path}/version` - Version info as JSON
321
+ - `{base_path}/docs` - README documentation as HTML
322
+ - `{base_path}/docs/configuration` - Configuration as HTML table
323
+ - `{base_path}/docs/changelog` - CHANGELOG as HTML
324
+ - `{base_path}/assets/*` - Static assets (CSS, images)
325
+
326
+ Accessing `{base_path}` or `{base_path}/` redirects to `{base_path}/docs`.
327
+
328
+ **Backward Compatibility:** If you have existing configuration using the old `heartbeat` block with `bind_address`, `port`, and `path`, it will continue to work. The new `http` configuration takes precedence when both are present.
329
+
330
+ ### Heartbeat
331
+
332
+ Returns detailed processor status information as JSON.
333
+
334
+ ```
335
+ GET {base_path}/heartbeat
336
+ ```
337
+
338
+ **Response:** `200 OK` with JSON body
339
+ ```json
340
+ {
341
+ "version": "1.0.0",
342
+ "pid": 12345,
343
+ "environment": "production",
344
+ "heartbeat": {
345
+ "started": "2026-01-18T10:00:00.000Z",
346
+ "stamp_last_request": "2026-01-18T12:30:00.000Z",
347
+ "uptime_in_ms": 9000000,
348
+ "heartbeat_cycle_in_ms": 300000,
349
+ "queues_consuming_from": ["my_processor"],
350
+ "queues_publishing_to": ["event_hub.inbound"],
351
+ "host": "server1.example.com",
352
+ "addresses": [
353
+ {"interface": "en0", "host_name": "server1", "ip_address": "192.168.1.100"}
354
+ ],
355
+ "messages": {
356
+ "total": 1000,
357
+ "successful": 995,
358
+ "unsuccessful": 5,
359
+ "average_size": 2048,
360
+ "average_process_time_in_ms": 50,
361
+ "total_process_time_in_ms": 50000
362
+ }
363
+ }
364
+ }
365
+ ```
366
+
367
+ ### Version
368
+
369
+ Returns the processor version as JSON.
370
+
371
+ ```
372
+ GET {base_path}/version
373
+ ```
374
+
375
+ **Response:** `200 OK` with JSON body
376
+ ```json
377
+ {
378
+ "version": "1.0.0"
379
+ }
380
+ ```
381
+
382
+ The version is taken from the `version` method in your derived processor class. If not defined, it returns `"?.?.?"`.
383
+
384
+ ```ruby
385
+ class MyProcessor < EventHub::Processor2
386
+ def version
387
+ "1.0.0" # your version
388
+ end
389
+ end
390
+ ```
391
+
392
+ ### Docs
393
+
394
+ Serves README.md as HTML with a built-in layout.
395
+
396
+ ```
397
+ GET {base_path}/docs
398
+ ```
399
+
400
+ **Response:** `200 OK` with HTML page
401
+
402
+ By default, looks for `README.md` in the current directory, then `doc/README.md`. You can customize the path via configuration:
403
+
404
+ ```json
405
+ {
406
+ "server": {
407
+ "http": {
408
+ "docs": {
409
+ "readme_path": "/custom/path/to/README.md"
410
+ }
411
+ }
412
+ }
413
+ }
414
+ ```
415
+
416
+ Or override completely by defining a `readme_as_html` method in your processor:
417
+
418
+ ```ruby
419
+ class MyProcessor < EventHub::Processor2
420
+ def readme_as_html
421
+ "<h1>Custom Documentation</h1><p>Your content here.</p>"
422
+ end
423
+ end
424
+ ```
425
+
426
+ ### Changelog
427
+
428
+ Serves CHANGELOG.md as HTML with a built-in layout.
429
+
430
+ ```
431
+ GET {base_path}/docs/changelog
432
+ ```
433
+
434
+ **Response:** `200 OK` with HTML page
435
+
436
+ By default, looks for `CHANGELOG.md` in the current directory, then `doc/CHANGELOG.md`. You can customize the path via configuration:
437
+
438
+ ```json
439
+ {
440
+ "server": {
441
+ "http": {
442
+ "docs": {
443
+ "changelog_path": "/custom/path/to/CHANGELOG.md"
444
+ }
445
+ }
446
+ }
447
+ }
448
+ ```
449
+
450
+ Or override completely by defining a `changelog_as_html` method in your processor:
451
+
452
+ ```ruby
453
+ class MyProcessor < EventHub::Processor2
454
+ def changelog_as_html
455
+ "<h1>Custom Changelog</h1><p>Your changes here.</p>"
456
+ end
457
+ end
458
+ ```
459
+
460
+ ### Configuration
461
+
462
+ Displays the active configuration as an HTML table. Sensitive values (passwords, tokens, keys) are automatically redacted.
463
+
464
+ ```
465
+ GET {base_path}/docs/configuration
466
+ ```
467
+
468
+ **Response:** `200 OK` with HTML page
469
+
470
+ By default, the following keys are redacted: `password`, `secret`, `token`, `api_key`, `credential`. You can customize the list by defining a `sensitive_keys` method in your processor:
471
+
472
+ ```ruby
473
+ # Override the entire list
474
+ class MyProcessor < EventHub::Processor2
475
+ def sensitive_keys
476
+ %w[password secret token api_key credential connection_string]
477
+ end
478
+ end
479
+
480
+ # Or extend the default list
481
+ class MyProcessor < EventHub::Processor2
482
+ def sensitive_keys
483
+ EventHub::DocsRenderer::DEFAULT_SENSITIVE_KEYS + %w[connection_string]
484
+ end
485
+ end
486
+ ```
487
+
488
+ Or override the entire page by defining a `configuration_as_html` method:
489
+
490
+ ```ruby
491
+ class MyProcessor < EventHub::Processor2
492
+ def configuration_as_html
493
+ "<h1>Custom Configuration</h1><p>Your content here.</p>"
494
+ end
495
+ end
496
+ ```
497
+
498
+ ### Disabling Resources
499
+
500
+ By default, all HTTP resources are enabled. You can control which resources are available by defining an `http_resources` method in your processor. The navbar adapts automatically.
501
+
502
+ ```ruby
503
+ class MyProcessor < EventHub::Processor2
504
+ def http_resources
505
+ [:heartbeat, :version, :docs, :changelog, :configuration] # default: all enabled
506
+ end
507
+ end
508
+ ```
509
+
510
+ To disable the configuration page for example:
511
+
512
+ ```ruby
513
+ class MyProcessor < EventHub::Processor2
514
+ def http_resources
515
+ [:heartbeat, :version, :docs, :changelog]
516
+ end
517
+ end
518
+ ```
519
+
520
+ ### Customizing Footer
521
+
522
+ The documentation pages display company name, version, and environment in the footer. Company name defaults to "Novartis" but can be customized by defining a `company_name` method in your processor:
523
+
524
+ ```ruby
525
+ class MyProcessor < EventHub::Processor2
526
+ def company_name
527
+ "My Company"
528
+ end
529
+ end
530
+ ```
531
+
532
+ **Future Extension:** A future version could allow overriding the default layout template and CSS assets using convention over configuration (e.g., placing custom files in `doc/layout.erb` or `doc/app.css`).
533
+
231
534
  ## Development
232
535
 
233
536
  ```
@@ -244,13 +547,21 @@ Final configuration result
244
547
  bundle exec rake
245
548
  ```
246
549
 
247
- To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org).
550
+ To install this gem onto your local machine, run `bundle exec rake install`.
248
551
 
249
552
  ## Publishing
250
553
 
251
- This project uses [Trusted Publishing](https://guides.rubygems.org/trusted-publishing/) to securely publish gems to RubyGems.org. Trusted Publishing eliminates the need for long-lived API tokens by using OpenID Connect (OIDC) to establish a trusted relationship between GitHub Actions and RubyGems.org.
252
-
253
- With Trusted Publishing configured, gem releases are automatically published to RubyGems when the release workflow runs, providing a more secure and streamlined publishing process.
554
+ This project uses [Trusted Publishing](https://guides.rubygems.org/trusted-publishing/) to securely publish gems to RubyGems.org via GitHub Actions. To release a new version:
555
+
556
+ 1. Update the version number in `lib/eventhub/version.rb`
557
+ 2. Merge changes to `main`
558
+ 3. Create a version tag either via command line or GitHub:
559
+ ```
560
+ git tag v1.x.x
561
+ git push origin v1.x.x
562
+ ```
563
+ Or on GitHub: go to **Releases** → **Create a new release** → enter the tag name (e.g. `v1.26.0`), select `main` as target, and publish.
564
+ 4. The `02 - Test, Build and Release` workflow triggers automatically, runs tests, builds the gem, and publishes it to [rubygems.org](https://rubygems.org)
254
565
 
255
566
  ## Contributing
256
567
 
@@ -28,6 +28,7 @@ Gem::Specification.new do |spec|
28
28
  spec.add_dependency "eventhub-components", "~> 0.4"
29
29
  spec.add_dependency "base64", "~> 0.3.0"
30
30
  spec.add_dependency "logger", "~> 1.6"
31
+ spec.add_dependency "kramdown", "~> 2.4"
31
32
 
32
33
  spec.add_development_dependency "rake", "~> 13.2"
33
34
  spec.add_development_dependency "rspec", "~> 3.13"
@@ -0,0 +1,8 @@
1
+ # Changelog
2
+
3
+ ## [1.0.0] 2026-01-18
4
+
5
+ * Initial release
6
+ * Routes messages from example.outbound to example.inbound queue
7
+ * Supports JSON message format
8
+ * Preserves message headers
data/example/receiver.rb CHANGED
@@ -2,6 +2,44 @@ require_relative "../lib/eventhub/base"
2
2
 
3
3
  module EventHub
4
4
  class Receiver < Processor2
5
+ def version
6
+ "2.0.0"
7
+ end
8
+
9
+ def company_name
10
+ "Example Company"
11
+ end
12
+
13
+ # Custom README served via method instead of file
14
+ def readme_as_html
15
+ <<~HTML
16
+ <h1>Receiver Processor</h1>
17
+ <p>This processor receives messages and deletes associated files.</p>
18
+ <h2>Features</h2>
19
+ <ul>
20
+ <li>Receives messages from the queue</li>
21
+ <li>Deletes files based on message ID</li>
22
+ <li>Logs all operations</li>
23
+ </ul>
24
+ <h2>Configuration</h2>
25
+ <p>No special configuration required.</p>
26
+ HTML
27
+ end
28
+
29
+ # Custom CHANGELOG served via method instead of file
30
+ def changelog_as_html
31
+ <<~HTML
32
+ <h1>Changelog</h1>
33
+ <h2>[2.0.0] 2026-01-18</h2><ul>
34
+ <li>Added custom documentation via methods</li>
35
+ <li>Improved error handling</li>
36
+ </ul>
37
+ <h2>[1.0.0] 2025-01-01</h2><ul>
38
+ <li>Initial release</li>
39
+ </ul>
40
+ HTML
41
+ end
42
+
5
43
  def handle_message(message, args = {})
6
44
  id = message.body["id"]
7
45
  EventHub.logger.info("[#{id}] - Received")
data/example/router.rb CHANGED
@@ -3,6 +3,10 @@ require_relative "../lib/eventhub/base"
3
3
  module EventHub
4
4
  # Demo class
5
5
  class Router < Processor2
6
+ def version
7
+ "1.0.0"
8
+ end
9
+
6
10
  def handle_message(message, args = {})
7
11
  id = message.body["id"]
8
12
  EventHub.logger.info("Received: [#{id}]")
@@ -13,7 +13,8 @@ module EventHub
13
13
  end
14
14
 
15
15
  def start
16
- EventHub.logger.info("Heartbeat is starting...")
16
+ cycle = Configuration.processor[:heartbeat_cycle_in_s]
17
+ EventHub.logger.info("Heartbeat is starting [cycle: #{cycle}s]...")
17
18
 
18
19
  every(60 * 60 * 24) { EventHub.logger.info("Actual actors: #{Celluloid::Actor.all.size}: #{Celluloid::Actor.all.map { |a| a.class }.join(", ")}") }
19
20
 
@@ -16,8 +16,18 @@ module EventHub
16
16
  end
17
17
 
18
18
  def start
19
- EventHub.logger.info("Listener amqp is starting...")
20
- EventHub::Configuration.processor[:listener_queues].each_with_index do |queue_name, index|
19
+ server = EventHub::Configuration.server
20
+ queues = EventHub::Configuration.processor[:listener_queues]
21
+ settings = [
22
+ server[:user],
23
+ server[:host],
24
+ server[:port],
25
+ server[:vhost],
26
+ "tls=#{server[:tls]}",
27
+ queues.join(", ")
28
+ ].join(", ")
29
+ EventHub.logger.info("Listener amqp is starting [#{settings}]...")
30
+ queues.each_with_index do |queue_name, index|
21
31
  async.listen(queue_name: queue_name, index: index)
22
32
  end
23
33
  end
@@ -30,21 +40,26 @@ module EventHub
30
40
  with_listen(args) do |connection, channel, consumer, queue, queue_name|
31
41
  EventHub.logger.info("Listening to queue [#{queue_name}]")
32
42
  consumer.on_delivery do |delivery_info, metadata, payload|
33
- EventHub.logger.info("#{queue_name}: [#{delivery_info.delivery_tag}]" \
34
- " delivery")
35
-
36
- @processor_instance.statistics.measure(payload.size) do
37
- handle_payload(payload: payload,
38
- connection: connection,
39
- queue_name: queue_name,
40
- content_type: metadata[:content_type],
41
- priority: metadata[:priority],
42
- delivery_tag: delivery_info.delivery_tag)
43
- channel.acknowledge(delivery_info.delivery_tag, false)
43
+ CorrelationId.with(metadata[:correlation_id]) do
44
+ EventHub.logger.info("#{queue_name}: [#{delivery_info.delivery_tag}]" \
45
+ " delivery")
46
+
47
+ @processor_instance.statistics.measure(payload.size) do
48
+ handle_payload(payload: payload,
49
+ connection: connection,
50
+ queue_name: queue_name,
51
+ content_type: metadata[:content_type],
52
+ priority: metadata[:priority],
53
+ delivery_tag: delivery_info.delivery_tag,
54
+ correlation_id: metadata[:correlation_id])
55
+ channel.acknowledge(delivery_info.delivery_tag, false)
56
+ end
57
+
58
+ EventHub.logger.info("#{queue_name}: [#{delivery_info.delivery_tag}]" \
59
+ " acknowledged")
60
+ ensure
61
+ ExecutionId.clear
44
62
  end
45
-
46
- EventHub.logger.info("#{queue_name}: [#{delivery_info.delivery_tag}]" \
47
- " acknowledged")
48
63
  end
49
64
  queue.subscribe_with(consumer, block: false)
50
65
  end
@@ -77,6 +92,15 @@ module EventHub
77
92
  # convert to EventHub message
78
93
  message = EventHub::Message.from_json(args[:payload])
79
94
 
95
+ # set execution_id for logging
96
+ ExecutionId.current = message.process_execution_id if message.valid?
97
+
98
+ # use execution_id as correlation_id if not already set from AMQP metadata
99
+ if CorrelationId.current.nil? && message.valid?
100
+ CorrelationId.current = message.process_execution_id
101
+ args[:correlation_id] ||= message.process_execution_id
102
+ end
103
+
80
104
  # append to execution history
81
105
  message.append_to_execution_history(EventHub::Configuration.name)
82
106
 
@@ -105,7 +129,7 @@ module EventHub
105
129
  end
106
130
 
107
131
  def pass_arguments(args = {})
108
- keys_to_pass = [:queue_name, :content_type, :priority, :delivery_tag]
132
+ keys_to_pass = [:queue_name, :content_type, :priority, :delivery_tag, :correlation_id]
109
133
  args.select { |key| keys_to_pass.include?(key) }
110
134
  end
111
135