You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
> Unified event-driven architecture library with Kafka, RabbitMQ, and Spring Application Events support.
8
+
> Unified event-driven architecture library with Kafka, RabbitMQ, PostgreSQL (LISTEN/NOTIFY + outbox), and Spring Application Events support.
9
9
10
10
---
11
11
@@ -23,15 +23,15 @@
23
23
24
24
## Overview
25
25
26
-
Firefly Framework EDA provides a standardized messaging abstraction for event-driven architectures, supporting multiple broker implementations through a unified publisher/consumer API. It enables reactive event publishing and consumption with built-in support for Apache Kafka, RabbitMQ, and Spring Application Events as transport mechanisms.
26
+
Firefly Framework EDA provides a standardized messaging abstraction for event-driven architectures, supporting multiple broker implementations through a unified publisher/consumer API. It enables reactive event publishing and consumption with built-in support for Apache Kafka, RabbitMQ, PostgreSQL (via `LISTEN`/`NOTIFY` backed by a transactional outbox table), and Spring Application Events as transport mechanisms.
27
27
28
28
The library features annotation-driven event publishing (`@EventPublisher`, `@PublishResult`), declarative event listeners (`@EventListener`), and a comprehensive set of event filtering, serialization, and error handling capabilities. It includes support for JSON, Avro, and Protobuf message serialization formats.
29
29
30
30
The resilient publisher wrapper provides circuit breaker integration, while the dead letter queue handler ensures no events are lost during processing failures. Metrics collection and health indicators provide full observability into the messaging infrastructure.
31
31
32
32
## Features
33
33
34
-
- Multi-broker support: Apache Kafka, RabbitMQ, Spring Application Events
The PostgreSQL publisher uses an outbox table together with `pg_notify` to deliver events. Configuration lives under `firefly.eda.publishers.postgres.<connection-id>` -- never under `spring.r2dbc.*`.
185
+
186
+
```yaml
187
+
firefly:
188
+
eda:
189
+
publishers:
190
+
postgres:
191
+
default: # Connection ID
192
+
enabled: true
193
+
host: "localhost"
194
+
port: 5432
195
+
database: "app"
196
+
username: "app"
197
+
password: "secret"
198
+
schema: "public"
199
+
outbox-table: "firefly_eda_outbox"
200
+
default-destination: "events"
201
+
auto-create-schema: true
202
+
max-pool-size: 10
203
+
properties:
204
+
statement_timeout: "30000"
205
+
```
206
+
207
+
| Property | Type | Default | Description |
208
+
|----------|------|---------|-------------|
209
+
| `enabled` | boolean | `false` | Whether this PostgreSQL publisher connection is enabled |
When `auto-create-schema: true`, the publisher provisions:
223
+
224
+
- `firefly_eda_outbox`table with `id`, `destination`, `channel`, `payload (BYTEA)`, `headers (JSONB)`, `status`, `attempts`, `error_message`, and timestamp columns
225
+
- An index on `(status, created_at)` filtered to `status = 'PENDING'`
226
+
- An index on `(channel, status)`
227
+
- A `firefly_eda_notify_event()` trigger function that calls `pg_notify(NEW.channel, NEW.id::text)`
228
+
- An `AFTER INSERT` trigger on the outbox table that runs the function
229
+
182
230
## Consumer Configuration
183
231
184
232
Consumers are configured under `firefly.eda.consumer`.
@@ -289,6 +337,51 @@ firefly:
289
337
290
338
**Important**: RabbitMQ queues must be pre-declared and configured here. The `@EventListener` destinations are used for filtering messages after they are consumed from these queues, not for determining which queues to subscribe to.
291
339
340
+
### PostgreSQL Consumer
341
+
342
+
The PostgreSQL consumer holds one long-lived R2DBC connection to receive `NOTIFY` messages and creates short-lived connections to drain the outbox table. Configuration lives under `firefly.eda.consumer.postgres.<connection-id>`. Channels are derived from `@EventListener` annotations with `consumerType=POSTGRES` or `consumerType=AUTO`, and additionally from the `channels` property.
343
+
344
+
```yaml
345
+
firefly:
346
+
eda:
347
+
consumer:
348
+
postgres:
349
+
default:
350
+
enabled: true
351
+
host: "localhost"
352
+
port: 5432
353
+
database: "app"
354
+
username: "app"
355
+
password: "secret"
356
+
schema: "public"
357
+
outbox-table: "firefly_eda_outbox"
358
+
channels: "events,order-events" # comma-separated destinations to LISTEN on
359
+
polling-interval: 30s # NOTIFY-loss fallback poll cadence; set to 0s to disable
360
+
max-attempts: 3 # rows beyond this attempt count are marked DEAD_LETTER
361
+
batch-size: 50 # max rows fetched per poll cycle
362
+
max-pool-size: 5
363
+
properties: {}
364
+
```
365
+
366
+
| Property | Type | Default | Description |
367
+
|----------|------|---------|-------------|
368
+
| `enabled` | boolean | `false` | Whether this PostgreSQL consumer connection is enabled |
**How acknowledgement works**: On successful dispatch, the row is updated to `status='PROCESSED', processed_at=NOW()`. On failure, `attempts` is incremented and `error_message` is recorded; once `attempts >= max-attempts`, the row moves to `status='DEAD_LETTER'`. Use the outbox table directly to inspect, reset, or requeue events.
**Best For**: Services that already use PostgreSQL and want reliable event publishing without an additional broker; outbox-style transactional event publishing
67
+
**Persistence**: ✅ Yes (outbox table rows)
68
+
**Ordering**: ✅ Yes (per destination -- rows are ordered by `created_at` / `id`)
69
+
**Cloud Service**: ❌ No (self-hosted; works with managed PostgreSQL services)
0 commit comments