Skip to content

feat: add CloudEvents deserialization support to all eventbus engines#177

Merged
kristopherchun merged 7 commits intomainfrom
feat/cloudevents-eventbus-decode
Feb 10, 2026
Merged

feat: add CloudEvents deserialization support to all eventbus engines#177
kristopherchun merged 7 commits intomainfrom
feat/cloudevents-eventbus-decode

Conversation

@kristopherchun
Copy link

Summary

External producers publishing domain events in CloudEvents v1.0 format are silently dropped because the eventbus engines deserialize records directly into eventbus.Event, whose JSON tags don't match CloudEvents fields. This results in zero-value structs with empty topics that match no subscriptions.

This PR introduces auto-detection and mapping of CloudEvents envelopes so that all four eventbus engines (Kafka, Kinesis, NATS, Redis) can consume both native eventbus.Event and CloudEvents records without any configuration changes.

Changes

  • Add parseRecord() entry point that auto-detects CloudEvents by probing for specversion, falling back to native eventbus.Event deserialization
  • Map CloudEvents fields to eventbus equivalents: typeTopic, dataPayload, timeCreatedAt
  • Preserve CloudEvents context and extension attributes in Metadata with a ce_ prefix (e.g., ce_source, ce_id, ce_tenantid)
  • Replace json.Unmarshal calls in all four engine consume paths (Kafka, Kinesis, NATS, Redis) with parseRecord()
  • Validate all four required CloudEvents attributes (specversion, type, source, id)

External producers publish domain events using the CloudEvents v1.0 spec,
but all eventbus engines (Kinesis, Kafka, NATS, Redis) unmarshal records
directly into eventbus.Event whose JSON tags don't match CloudEvents fields.
This causes CloudEvents records to deserialize as zero-value structs with
empty topics that match no subscriptions, silently dropping messages.

Introduce parseRecord() which detects CloudEvents by the presence of
"specversion", maps type→Topic, data→Payload, time→CreatedAt, and
preserves context/extension attributes in Metadata with a ce_ prefix.
Native eventbus.Event format continues to work unchanged.
@github-actions
Copy link

github-actions bot commented Feb 9, 2026

📋 API Contract Changes Summary

No breaking changes detected - only additions and non-breaking modifications

Changed Components:

Core Framework

Contract diff saved to artifacts/diffs/core.json

Module: auth

Contract diff saved to artifacts/diffs/auth.json

Module: cache

Contract diff saved to artifacts/diffs/cache.json

Module: chimux

Contract diff saved to artifacts/diffs/chimux.json

Module: database

Contract diff saved to artifacts/diffs/database.json

Module: eventbus

Contract diff saved to artifacts/diffs/eventbus.json

Module: eventlogger

Contract diff saved to artifacts/diffs/eventlogger.json

Module: httpclient

Contract diff saved to artifacts/diffs/httpclient.json

Module: httpserver

Contract diff saved to artifacts/diffs/httpserver.json

Module: jsonschema

Contract diff saved to artifacts/diffs/jsonschema.json

Module: letsencrypt

Contract diff saved to artifacts/diffs/letsencrypt.json

Module: logmasker

Contract diff saved to artifacts/diffs/logmasker.json

Module: reverseproxy

Contract diff saved to artifacts/diffs/reverseproxy.json

Module: scheduler

Contract diff saved to artifacts/diffs/scheduler.json

Artifacts

📁 Full contract diffs and JSON artifacts are available in the workflow artifacts.

@codecov
Copy link

codecov bot commented Feb 9, 2026

Codecov Report

❌ Patch coverage is 97.24771% with 3 lines in your changes missing coverage. Please review.
✅ Project coverage is 56.63%. Comparing base (b6869b9) to head (cf22350).
⚠️ Report is 1 commits behind head on main.

Files with missing lines Patch % Lines
modules/eventbus/redis.go 0.00% 2 Missing ⚠️
modules/eventbus/nats.go 50.00% 0 Missing and 1 partial ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main     #177      +/-   ##
==========================================
- Coverage   60.44%   56.63%   -3.82%     
==========================================
  Files          93       94       +1     
  Lines       19538    19637      +99     
==========================================
- Hits        11810    11121     -689     
- Misses       6607     7320     +713     
- Partials     1121     1196      +75     
Flag Coverage Δ
auth ?
bdd-auth 70.97% <ø> (ø)
bdd-cache 67.15% <ø> (ø)
bdd-chimux 73.80% <ø> (ø)
bdd-database 51.85% <ø> (ø)
bdd-eventbus 31.23% <0.00%> (-1.63%) ⬇️
bdd-eventlogger 61.86% <ø> (?)
bdd-httpclient 42.50% <ø> (ø)
bdd-httpserver 62.29% <ø> (ø)
bdd-jsonschema 77.31% <ø> (ø)
bdd-letsencrypt 19.70% <ø> (ø)
bdd-logmasker 36.02% <ø> (ø)
bdd-reverseproxy 54.68% <ø> (ø)
bdd-scheduler 60.97% <ø> (?)
cache ?
chimux ?
cli 47.27% <ø> (ø)
core-bdd 17.70% <ø> (ø)
database ?
eventbus 58.77% <97.24%> (+5.93%) ⬆️
eventlogger ?
httpclient ?
httpserver ?
jsonschema ?
letsencrypt ?
logmasker ?
merged-bdd 43.44% <0.00%> (-0.34%) ⬇️
reverseproxy ?
scheduler ?
total 57.11% <ø> (ø)
unit 64.16% <ø> (ø)

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds CloudEvents v1.0 JSON envelope deserialization to the eventbus module so all supported engines can consume events produced in either the native eventbus.Event format or CloudEvents without configuration changes.

Changes:

  • Introduces parseRecord() to auto-detect CloudEvents (via specversion) and map CloudEvents → eventbus.Event.
  • Updates Kafka/Kinesis/NATS/Redis consume paths to use parseRecord() instead of direct json.Unmarshal.
  • Adds unit tests covering CloudEvents detection/mapping and fallback to native eventbus.Event.

Reviewed changes

Copilot reviewed 6 out of 6 changed files in this pull request and generated 5 comments.

Show a summary per file
File Description
modules/eventbus/cloudevents_decode.go Implements CloudEvents detection and mapping into eventbus.Event.
modules/eventbus/cloudevents_decode_test.go Adds tests for CloudEvents detection/mapping and native fallback.
modules/eventbus/kafka.go Switches Kafka consume path to use parseRecord().
modules/eventbus/kinesis.go Switches Kinesis record deserialization to use parseRecord().
modules/eventbus/nats.go Switches NATS message deserialization to use parseRecord().
modules/eventbus/redis.go Switches Redis message deserialization to use parseRecord().

Replace triple-unmarshal approach (probe map, envelope struct, extension
map) with a single unmarshal into map[string]json.RawMessage that is
reused for detection, field extraction, and extension collection.

Add extractString helper and tests for non-string attributes, invalid
data fields, and malformed extensions to achieve 100% coverage on
cloudevents_decode.go.
- Add data_base64 handling per CloudEvents spec with JSON-aware
  decode when datacontenttype is application/json
- Move Kafka parseRecord call before subscriber loop to deserialize
  once per message instead of once per subscription
- Use sentinel errors for required attribute validation (err113)
- Fix discarded time.Parse error in test
Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 6 out of 6 changed files in this pull request and generated 3 comments.

- Parse datacontenttype with mime.ParseMediaType to handle parameters
  like "application/json; charset=utf-8"
- Preserve ce_type in metadata for full CloudEvent context reconstruction
- Fix misleading parseRecord doc comment about single-unmarshal behavior
…tests

Validate specversion is "1.0" (reject unknown versions), add dataschema
to known keys, warn on data+data_base64 mutual exclusivity violation,
and log warnings on extension attribute JSON parse failures. Add Kinesis
readShard integration tests exercising CloudEvent and native Event
deserialization through the mock KinesisClient.
Cover the deserialization and dispatch path in ConsumeClaim using
lightweight test doubles for sarama.ConsumerGroupSession and
ConsumerGroupClaim. Tests verify CloudEvent decode, native Event
decode, invalid record rejection with offset commit, and multi-
message batch dispatch to topic-matched subscribers.
@kristopherchun kristopherchun merged commit c29c322 into main Feb 10, 2026
31 of 32 checks passed
@kristopherchun kristopherchun deleted the feat/cloudevents-eventbus-decode branch February 10, 2026 19:30
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants