Add event-integration pattern guides (Pub/Sub, CQRS, Outbox, Competing Consumers, Saga, DLQ) - #602
Conversation
…ets, and Try it yourself sections Six new guides under en/docs/guides/event-integration/ covering Pub/Sub (Kafka), CQRS (Kafka), Transactional Outbox with CDC (RabbitMQ), Competing Consumers (RabbitMQ), Saga choreography (Solace), and DLQ + Retry (Azure Service Bus). Each guide includes an architecture diagram, runnable code snippets matching the integration-samples PR source, and a Try it yourself section with Deploy to Devant badge and View source on GitHub link.
|
Warning Review limit reached
Next review available in: 6 minutes Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available. How can I continue?After more reviews become available, a review can be triggered using the To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews. How do review limits work?CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability. For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window. Please refer docs for additional details. Review details⚙️ Run configurationConfiguration used: Path: .coderabbit.yaml Review profile: CHILL Plan: Pro Plus Run ID: 📒 Files selected for processing (5)
📝 WalkthroughWalkthroughAdds six event-integration pattern guides with Ballerina examples, deployment links, and navigation entries in the guides index and sidebar. ChangesEvent-driven integration
Estimated code review effort: 3 (Moderate) | ~20 minutes Suggested reviewers: 🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
Broken links, images & orphan pages
Links/images come from one crawl of the production build (baseUrl-aware). Orphans are docs not referenced by Summary
Broken links & imagesIntroduced by this PRNo new broken link(s)/image(s) introduced by this PR. ✅ Already on
|
There was a problem hiding this comment.
Actionable comments posted: 12
Note
Due to the large number of review comments, Critical, Major severity comments were prioritized as inline comments.
🟡 Minor comments (10)
en/docs/guides/event-integration/competing-consumers.md-85-85 (1)
85-85: 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick winFix the contradictory logging description.
A job cannot be visible in both instances’ logs while also appearing in only one instance. Say that each job appears in the logs of the single instance that consumes it.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@en/docs/guides/event-integration/competing-consumers.md` at line 85, Update the competing-consumers documentation sentence so each job is described as appearing only in the logs of the single instance that consumes it, removing the contradictory claim that both instances log every job.en/docs/guides/event-integration/pub-sub.md-18-18 (1)
18-18: 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick winQualify the replay guarantee by Kafka retention.
OFFSET_RESET_EARLIESTstarts at the earliest offset still available when no committed offset exists; expired or deleted records cannot be replayed. State that replay is limited by the topic’s retention policy. (central.ballerina.io)🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@en/docs/guides/event-integration/pub-sub.md` at line 18, Update the replay statement near the consumer-group description to clarify that a new consumer can replay only records still retained by the Kafka topic; expired or deleted records are unavailable, so replay from the beginning is bounded by the topic’s retention policy.Source: MCP tools
en/docs/guides/event-integration/pub-sub.md-2-2 (1)
2-2: 📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick winAlign both page slugs with their titles.
en/docs/guides/event-integration/pub-sub.md#L2-L2: rename the page topub-sub-kafka.mdand update navigation references.en/docs/guides/event-integration/competing-consumers.md#L2-L2: rename the page tocompeting-consumers-rabbitmq.mdand update navigation references.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@en/docs/guides/event-integration/pub-sub.md` at line 2, Rename en/docs/guides/event-integration/pub-sub.md to pub-sub-kafka.md and update all navigation references; rename en/docs/guides/event-integration/competing-consumers.md to competing-consumers-rabbitmq.md and update all navigation references, keeping each page title aligned with its new slug.Source: Path instructions
en/docs/guides/event-integration/pub-sub.md-48-66 (1)
48-66: 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick winAdd the missing consumer helper or link the complete sample.
The consumer block references
updateRecommendations, which is not defined anywhere in this guide, so the example is not self-contained even though the shared definitions are present and the live sample is linked.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@en/docs/guides/event-integration/pub-sub.md` around lines 48 - 66, Add the missing updateRecommendations helper referenced by the Kafka listener’s onConsumerRecord function, or link to a complete sample that defines it. Ensure the guide’s consumer example is self-contained and retains the existing event-processing flow.en/docs/guides/event-integration/competing-consumers.md-24-26 (1)
24-26: 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick winAdd
import ballerina/http;before usinghttp:Listener.The first Bala snippet types
new http:Listener(httpPort)but only importsballerinax/rabbitmq; add the HTTP module import so the advertised example compiles.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@en/docs/guides/event-integration/competing-consumers.md` around lines 24 - 26, Add the ballerina/http import alongside the existing ballerina/rabbitmq import in the supporting definitions snippet before the first http:Listener usage, ensuring the documented example compiles.en/docs/guides/event-integration/pub-sub.md-74-76 (1)
74-76: 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick winRefresh the WSO2 Cloud deployment links.
Both event-integration guides still link the sample to the Devant-brandedconsole.devant.devroute,openindevant.choreoapps.dev, andevent-integration/sample paths. Replace the deployment button/asset with the current WSO2 Cloud sample link, and update the GitHub source links to the actual integration-samples paths.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@en/docs/guides/event-integration/pub-sub.md` around lines 74 - 76, Refresh the deployment button and GitHub source links in en/docs/guides/event-integration/pub-sub.md (lines 74-76) and en/docs/guides/event-integration/competing-consumers.md (lines 91-93): replace the Devant-branded asset and console.devant.dev URL with the current WSO2 Cloud sample link, and update each source link from the event-integration paths to its actual integration-samples path.Source: Path instructions
en/docs/guides/event-integration/cqrs.md-16-16 (1)
16-16: 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick winUse “CQRS,” not “SQRS.”
“SQRS” is a typo for the pattern documented by this guide and could confuse readers searching for the standard term.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@en/docs/guides/event-integration/cqrs.md` at line 16, In the CQRS guide introduction, replace the incorrect “SQRS” acronym with “CQRS” while preserving the surrounding explanation and terminology.Source: Linters/SAST tools
en/docs/guides/event-integration/cqrs.md-104-104 (1)
104-104: 📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick winUpdate the deployment links after the Devant rename.
These guides now say “Try this sample on WSO2 Cloud”, but the badge images and deployment URLs still point to Devant domains (
openindevant.choreoapps.dev/console.devant.dev). Update both guides to the WSO2 Cloud deployment assets/target if that is the renamed deployment path.
en/docs/guides/event-integration/cqrs.md#L104: update badge asset and deployment link.en/docs/guides/event-integration/outbox-cdc.md#L103: update badge asset and deployment link.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@en/docs/guides/event-integration/cqrs.md` at line 104, Update the deployment badge asset URL and target link in en/docs/guides/event-integration/cqrs.md lines 104-104 and en/docs/guides/event-integration/outbox-cdc.md lines 103-103, replacing the Devant domains with the corresponding WSO2 Cloud deployment assets and destination while preserving the existing sample-specific paths.en/docs/guides/event-integration/saga.md-155-157 (1)
155-157: 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick winReplace the stale Devant deployment URLs.
en/docs/guides/event-integration/saga.md#L155-L157: update the badge asset and deployment target to WSO2 Cloud.en/docs/guides/event-integration/dlq-retry.md#L91-L93: update the badge asset and deployment target to WSO2 Cloud.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@en/docs/guides/event-integration/saga.md` around lines 155 - 157, Update the deployment badge and target in en/docs/guides/event-integration/saga.md:155-157 and en/docs/guides/event-integration/dlq-retry.md:91-93, replacing stale Devant image and console URLs with the corresponding WSO2 Cloud URLs while preserving each sample’s repository target.en/docs/guides/event-integration/dlq-retry.md-67-80 (1)
67-80: 🩺 Stability & Availability | 🟡 Minor | ⚡ Quick winSettle malformed messages explicitly.
With
autoComplete: false, anycheckthat fails while decoding or deserializing exitsonMessagewithout acomplete,abandon, ordeadLetter. Catch body/JSON conversion failures, dead-letter them withdeadLetterReason/deadLetterErrorDescription, and document why malformed payloads are classified as permanent failures instead of count towards Azure’smaxDeliveryCountredelivery limit.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@en/docs/guides/event-integration/dlq-retry.md` around lines 67 - 80, Update the onMessage decoding and deserialization flow to catch failures from message.body.ensureType, string:fromBytes, and text.fromJsonStringWithType, then explicitly dead-letter malformed messages with descriptive deadLetterReason and deadLetterErrorDescription values. Preserve existing handling for valid messages, and add documentation explaining that malformed payloads are permanent failures and should not consume Azure’s maxDeliveryCount redelivery attempts.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@en/docs/guides/event-integration/competing-consumers.md`:
- Around line 75-81: Update the rabbitmq:Service example and surrounding
guidance so its requeue behavior matches the implementation: either remove
claims that failures are redelivered to another consumer, or configure autoAck:
false, accept a rabbitmq:Caller in onMessage, acknowledge only after successful
thumbnail generation, and call basicNack with requeue enabled for retryable
failures.
In `@en/docs/guides/event-integration/cqrs.md`:
- Around line 81-95: Update the query service snippet to import the HTTP and SQL
modules used by http:Listener and sql:Error?, and declare or initialize the
PostgreSQL database client as leaderboardDb before the service definition so the
example compiles independently.
- Around line 50-61: The CQRS Kafka consumer snippet is not self-contained
because it lacks the Kafka import and definitions for referenced configuration
and types. Update the supporting definitions around kafkaListener to import
ballerinax/kafka and declare or reuse dbHost, dbUser, dbPassword, dbName,
dbPort, bootstrapServers, topicName, and MatchResult; alternatively, explicitly
state that the snippets must be combined.
- Around line 64-74: Make the leaderboard projection in onConsumerRecord
idempotent across Kafka redeliveries by using a stable match event ID to detect
and ignore previously processed events. Persist the event ID alongside each
applied update, and ensure ON CONFLICT or equivalent logic only increments
total_score and games_played once per event while retaining normal updates for
new events.
- Around line 24-45: Add the Ballerina HTTP and logging imports alongside the
existing kafka import so the service declaration using http:Listener and the add
resource's log:printInfo call compile correctly. Keep the rest of the CQRS
example unchanged.
In `@en/docs/guides/event-integration/dlq-retry.md`:
- Around line 48-51: Update the send function’s INFO-level “Notification queued”
log to avoid including the raw job.recipient identifier. Remove the recipient
field or replace it with an appropriate redacted or hashed representation, while
preserving the existing notification send behavior and other safe log fields.
In `@en/docs/guides/event-integration/outbox-cdc.md`:
- Around line 58-95: Update the outbox CDC publish flow in cdc:Service.onCreate
and the RabbitMQ message construction to include the stable row.id alongside
row.payload. Document or implement the downstream idempotent
handling/processed-state mechanism so repeated delivery of the same outbox ID is
safely deduplicated while preserving at-least-once delivery.
- Line 35: Update the `@cdc`:ServiceConfig table selector to use the same dbName
value passed to the postgresql:Client usersDb connection and CDC listener,
replacing the hard-coded accounts database while preserving the public.outbox
schema and table.
- Around line 24-53: Add the missing ballerina/http and ballerina/log imports to
the supporting definitions so http:Listener and log:printInfo resolve while
leaving the service logic unchanged.
In `@en/docs/guides/event-integration/saga.md`:
- Around line 143-147: Update the onMessage compensation handler in the
solace:Service definition to perform the actual flight seat cancellation/release
operation using event.payload.tripId, or explicitly label the current logging
behavior as a placeholder and document the required release action. Ensure the
sample no longer presents a log-only handler as a completed compensation flow.
- Around line 28-58: Add the missing standard-library imports to the samples: in
en/docs/guides/event-integration/saga.md lines 28-58, import ballerina/http and
ballerina/log for http:Listener and log:printInfo; in
en/docs/guides/event-integration/dlq-retry.md lines 28-51, import
ballerina/http, ballerina/log, and ballerina/string for the referenced APIs.
- Around line 40-57: The saga example uses the outdated Solace producer API.
Update each affected producer construction to include the topic via its
destination configuration, and change the corresponding send calls to pass only
the message; apply this consistently at the usages around sagaProducer and the
other affected lines (57, 83, 104, and 139), or explicitly document the
connector version if retaining the old API.
---
Minor comments:
In `@en/docs/guides/event-integration/competing-consumers.md`:
- Line 85: Update the competing-consumers documentation sentence so each job is
described as appearing only in the logs of the single instance that consumes it,
removing the contradictory claim that both instances log every job.
- Around line 24-26: Add the ballerina/http import alongside the existing
ballerina/rabbitmq import in the supporting definitions snippet before the first
http:Listener usage, ensuring the documented example compiles.
In `@en/docs/guides/event-integration/cqrs.md`:
- Line 16: In the CQRS guide introduction, replace the incorrect “SQRS” acronym
with “CQRS” while preserving the surrounding explanation and terminology.
- Line 104: Update the deployment badge asset URL and target link in
en/docs/guides/event-integration/cqrs.md lines 104-104 and
en/docs/guides/event-integration/outbox-cdc.md lines 103-103, replacing the
Devant domains with the corresponding WSO2 Cloud deployment assets and
destination while preserving the existing sample-specific paths.
In `@en/docs/guides/event-integration/dlq-retry.md`:
- Around line 67-80: Update the onMessage decoding and deserialization flow to
catch failures from message.body.ensureType, string:fromBytes, and
text.fromJsonStringWithType, then explicitly dead-letter malformed messages with
descriptive deadLetterReason and deadLetterErrorDescription values. Preserve
existing handling for valid messages, and add documentation explaining that
malformed payloads are permanent failures and should not consume Azure’s
maxDeliveryCount redelivery attempts.
In `@en/docs/guides/event-integration/pub-sub.md`:
- Line 18: Update the replay statement near the consumer-group description to
clarify that a new consumer can replay only records still retained by the Kafka
topic; expired or deleted records are unavailable, so replay from the beginning
is bounded by the topic’s retention policy.
- Line 2: Rename en/docs/guides/event-integration/pub-sub.md to pub-sub-kafka.md
and update all navigation references; rename
en/docs/guides/event-integration/competing-consumers.md to
competing-consumers-rabbitmq.md and update all navigation references, keeping
each page title aligned with its new slug.
- Around line 48-66: Add the missing updateRecommendations helper referenced by
the Kafka listener’s onConsumerRecord function, or link to a complete sample
that defines it. Ensure the guide’s consumer example is self-contained and
retains the existing event-processing flow.
- Around line 74-76: Refresh the deployment button and GitHub source links in
en/docs/guides/event-integration/pub-sub.md (lines 74-76) and
en/docs/guides/event-integration/competing-consumers.md (lines 91-93): replace
the Devant-branded asset and console.devant.dev URL with the current WSO2 Cloud
sample link, and update each source link from the event-integration paths to its
actual integration-samples path.
In `@en/docs/guides/event-integration/saga.md`:
- Around line 155-157: Update the deployment badge and target in
en/docs/guides/event-integration/saga.md:155-157 and
en/docs/guides/event-integration/dlq-retry.md:91-93, replacing stale Devant
image and console URLs with the corresponding WSO2 Cloud URLs while preserving
each sample’s repository target.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro Plus
Run ID: 5389fdd4-53b2-459f-95e1-c304eae07072
⛔ Files ignored due to path filters (6)
en/static/img/guides/event-integration/competing-consumers.pngis excluded by!**/*.pngen/static/img/guides/event-integration/cqrs.pngis excluded by!**/*.pngen/static/img/guides/event-integration/dlq-retry.pngis excluded by!**/*.pngen/static/img/guides/event-integration/outbox-cdc.pngis excluded by!**/*.pngen/static/img/guides/event-integration/pub-sub.pngis excluded by!**/*.pngen/static/img/guides/event-integration/saga.pngis excluded by!**/*.png
📒 Files selected for processing (8)
en/docs/guides/event-integration/competing-consumers.mden/docs/guides/event-integration/cqrs.mden/docs/guides/event-integration/dlq-retry.mden/docs/guides/event-integration/outbox-cdc.mden/docs/guides/event-integration/pub-sub.mden/docs/guides/event-integration/saga.mden/docs/guides/guides.mden/sidebars.ts
…urables, remove inaccurate requeue claim
Summary
Adds six new how-to guides under
en/docs/guides/event-integration/covering the most common EDA patterns, each implemented end-to-end in WSO2 Integrator against the broker that fits it best.pubsub_kafkacqrs_kafkaoutbox_cdc_rabbitmqcompeting_consumers_rabbitmqsaga_solacedlq_asbEach guide includes:
Also updates:
en/sidebars.ts— adds an Event-Driven Integration category under Guides, listing all six pagesen/docs/guides/guides.md— adds an Event-driven integration section to the Guides overview pageRunnable samples are in wso2/integration-samples#147.
Test plan
npm startinen/)Summary by CodeRabbit