Skip to content

Fixes found bug on Messaging Gateway#3905

Merged
lillo42 merged 2 commits into
masterfrom
fixes-messaging-gateway
Nov 14, 2025
Merged

Fixes found bug on Messaging Gateway#3905
lillo42 merged 2 commits into
masterfrom
fixes-messaging-gateway

Conversation

@lillo42

@lillo42 lillo42 commented Nov 12, 2025

Copy link
Copy Markdown
Contributor

In PR (#3896), I've found some bugs around Messaging Gateway, since it can take a long time to be resolved. I've decided to create a new PR with the fixes, unblock any new release.

This is a continuation of my work on improving tests. In this PR, I'm creating a base suite test case for Messaging Gateway

Founded Bugs:

  • RabbitMQ Async
    • TTL property was not properly set
    • Error when configuring Max Queue Length + Dead Letter
    • The TraceState header is using the wrong header
    • RmqSubscription<T> don't have support for Max Queue Length
  • RabbitMQ Sync
    • TTL property was not properly set
    • Error when configuring Max Queue Length + Dead Letter
    • RmqSubscription<T> don't have support for Max Queue Length
    • The DisposibleAsync was never completed
  • Postgres
    • SendAsync did not propagate the Span
    • ReceivingAsync with BinaryMessagePayload wasn't working
    • Consuming the BinaryMessagePayload + LargarMessageTable wasn't working
    • Activity Span was not propagated
  • SQL Server
    • Activity Span was not propagated
    • Add class to create DDL script for MsSql Queue via MsSqlQueueBuilder
  • Kafka
    • Activity Span was not propagated
  • Redis
    • Activity Span was not propagated
    • Only accepting Source & Subject property as Absolute URI
    • Error during TimeStamp serialisation/deserialization
  • AWS V3
    • Activity Span was not propagated
    • CloudEvents via headers was not properly resolved
    • The TraceParent/TraceState/Baggage was not flow
  • AWS V4
    • Activity Span was not propagated
    • CloudEvents via headers was not properly resolved
    • The TraceParent/TraceState/Baggage was not flow
  • RocketMQ
    • CloudEvents via headers was not properly resolved
    • The TraceParent/TraceState/Baggage was not flow
  • GCP Pub/Sub
    • The TraceParent/TraceState/Baggage was not flow
    • Error during setup dead letter queue, the IAM Policy was not properly set
    • Allow to publish a message with PartitionKey
  • Azure
    • Activity Span was not propagated
    • CloudEvents via headers was not properly resolved
    • The TraceParent/TraceState/Baggage was not flow

@lillo42 lillo42 added 3 - Done Bug .NET Pull requests that update .net code V10.X labels Nov 12, 2025
codescene-delta-analysis[bot]

This comment was marked as outdated.

@claude

claude Bot commented Nov 12, 2025

Copy link
Copy Markdown

Pull Request Review - PR #3905: Fixes found bug on Messaging Gateway

Overview

This is an extensive bug fix PR addressing critical issues across multiple messaging gateway implementations (RabbitMQ, Postgres, SQL Server, Kafka, Redis, AWS SQS V3/V4, RocketMQ, GCP Pub/Sub, and Azure). The PR fixes observability/tracing issues, CloudEvents header handling, and various gateway-specific bugs. With 1225 additions and 381 deletions across 44 files, this is a substantial change.


✅ Strengths

  1. Comprehensive Bug Fixes: Addresses critical issues across all major messaging gateways, particularly around Activity Span propagation and CloudEvents compliance.

  2. Consistent Implementation: The fixes follow a consistent pattern across different gateway implementations, making the codebase more maintainable.

  3. Improved Observability: The addition of BrighterTracer.WriteProducerEvent calls across producers ensures proper distributed tracing support.

  4. CloudEvents Compliance: Proper handling of TraceParent, TraceState, and Baggage headers brings the implementation closer to CloudEvents and W3C Trace Context specifications.

  5. Error Handling: Changes maintain existing error handling patterns with proper try-catch blocks and failure message creation.


⚠️ Concerns and Issues

1. Test Coverage - CRITICAL

  • Issue: No test files are included in this PR despite fixing bugs across 9+ messaging gateways.
  • Impact: High risk of regression and unverified fixes.
  • Recommendation: According to the repository's testing guidelines, "Ensure all new features and bug fixes include appropriate test coverage." Each bug fix should have:
    • A test demonstrating the bug (failing test first - TDD approach)
    • Verification that the fix resolves the issue
    • Tests following the naming convention: When_[condition]_should_[expected_behavior]
  • Specific tests needed:
    • RabbitMQ: TTL property setting, Max Queue Length + Dead Letter configuration, TraceState header usage
    • Postgres: Span propagation in SendAsync, BinaryMessagePayload with ReceivingAsync
    • Redis: TimeStamp serialization/deserialization, non-absolute URI handling for Source/Subject
    • AWS: TraceParent/TraceState/Baggage flow, CloudEvents via headers
    • GCP: Partition key support, IAM Policy for dead letter queues

2. Null Reference Risks

// SqsInlineMessageCreator.cs:88-89
messageId: messageId.Result!,  // Null-forgiving operator without null check
topic: topic.Result!,
  • Issue: Using null-forgiving operator (!) without verifying Success property on HeaderResult.
  • Risk: If ReadMessageId() or ReadTopic() fail to read these critical values, this will throw NullReferenceException.
  • Found in: Multiple message creator classes across AWS, RabbitMQ implementations
  • Recommendation: Either check Success property before using Result, or provide default values like the existing pattern: messageId.Success ? messageId.Result : Id.Empty

3. Breaking Change in Method Signatures

// SnsMessageProducer.cs:67-70
public SnsMessageProducer(AWSMessagingGatewayConnection connection, 
    SnsPublication publication,
    InstrumentationOptions instrumentation = InstrumentationOptions.All)  // New parameter
  • Issue: Adding a new constructor parameter could break existing code that instantiates this class.
  • Impact: This is a public API change that affects consumers of the library.
  • Recommendation: Consider backward compatibility. The default parameter helps, but verify if there are any factory methods or dependency injection configurations that need updating.

4. Inconsistent Default Values

// SqsInlineMessageCreator.cs:57-74
var cloudEvents = ReadMessageCloudEvents(); 
var contentType = ReadContentType(cloudEvents);  // Now depends on cloudEvents
// vs
var contentType = ReadContentType();  // Before: standalone
  • Issue: Some methods now have dual lookup paths (message attributes vs CloudEvents headers), but the fallback logic differs between implementations.
  • Example: ReadContentType in inline creator checks CloudEvents headers but returns null instead of MediaTypeNames.Text.Plain when both sources are empty, while the regular creator returns a default.
  • Recommendation: Standardize the fallback behavior for consistency.

5. Code Duplication

The same header reading logic (ReadCloudEventsTraceParent, ReadCloudEventsTraceState, ReadCloudEventsBaggage) is duplicated across:

  • SqsInlineMessageCreator.cs
  • SqsMessageCreator.cs
  • Similar patterns in other gateways

Recommendation: Extract these into shared utility methods or a base class to follow DRY principles and reduce maintenance burden.

6. Performance Consideration - Redis

// RedisMessagePublisher.cs (in diff)
// Multiple Uri.TryCreate calls and string parsing in message creation path
  • Issue: Redis message creators now perform more validation and parsing (URI creation, DateTimeOffset parsing) on every message.
  • Impact: Could affect throughput for high-volume scenarios.
  • Recommendation: Consider performance testing, especially for the Redis gateway which is often used for high-throughput scenarios. Profile before/after to ensure acceptable impact.

7. Documentation Gap

public const string TraceState = "tracestate";
public const string TraceParent = "traceparent";
public const string Baggage = "baggage";
  • Issue: New header constants lack XML documentation comments.
  • Repository standard: According to CLAUDE.md, "XML documentation standards" should be followed.
  • Recommendation: Add XML doc comments explaining these W3C Trace Context headers and their purpose.

8. GCP Pub/Sub - Partition Key Feature

// GcpPublication.cs - adds partition key support
  • Issue: The PR description mentions "Allow to publish a message with PartitionKey" as a bug fix, but this appears to be a new feature.
  • Concern: Mixing features with bug fixes makes it harder to review and potentially introduces new bugs under the guise of fixes.
  • Recommendation: Consider whether this should be in a separate PR for new features.

🔒 Security Considerations

  1. No obvious security vulnerabilities in the changes themselves.
  2. Tracing data exposure: The addition of baggage propagation means more metadata flows through systems. Ensure sensitive data isn't accidentally included in baggage.
  3. IAM Policy changes in GCP Pub/Sub: Review the IAM policy changes for dead letter queues to ensure they follow principle of least privilege.

📋 Code Quality & Best Practices

Positive:

  • ✅ Follows C# naming conventions
  • ✅ Uses nullable reference types appropriately in most places
  • ✅ Maintains existing error handling patterns
  • ✅ Consistent code style across files

Areas for Improvement:

  • ⚠️ Methods are getting long (some over 70 lines) - consider extracting helper methods
  • ⚠️ Consider using more descriptive variable names (e.g., valheaderValue)
  • ⚠️ The multiple ReadX() methods could benefit from a more polymorphic approach

🎯 Recommendations Summary

High Priority:

  1. Add comprehensive test coverage for all bug fixes mentioned in the PR description
  2. Fix null reference risks by properly checking HeaderResult.Success before using .Result!
  3. Verify breaking changes in constructor signatures don't break existing code

Medium Priority:
4. Extract duplicated code into shared utilities
5. Standardize fallback/default value behavior across message creators
6. Add XML documentation for new constants and public APIs
7. Performance test the Redis gateway with the new validation logic

Low Priority:
8. Consider splitting the partition key feature into a separate PR
9. Refactor long methods using the Extract Method pattern
10. Consider a more consistent approach to header reading across all gateways


Conclusion

This is a valuable PR that addresses real bugs across the entire messaging infrastructure. However, the lack of test coverage is a significant concern given the scope and critical nature of these fixes. The changes look correct at a code review level, but without tests, there's high risk of:

  • Unverified fixes (are the bugs actually fixed?)
  • Future regressions
  • Difficulty understanding intended behavior

Recommendation: I suggest adding test coverage before merging. Given the repository follows TDD practices, this PR should include tests demonstrating each bug and verifying the fix. The null reference risks should also be addressed to prevent runtime exceptions.

Once tests are added and null safety is improved, this will be an excellent contribution to the project. Great work on identifying and fixing these issues across so many gateways! 👍

@codescene-delta-analysis codescene-delta-analysis Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Code Health Improved (4 files improve in Code Health)

Gates Failed
Enforce critical code health rules (1 file with Bumpy Road Ahead)
Enforce advisory code health rules (5 files with Complex Method, Code Duplication, Primitive Obsession, Complex Conditional, Overall Code Complexity)

Gates Passed
2 Quality Gates Passed

See analysis details in CodeScene

Reason for failure
Enforce critical code health rules Violations Code Health Impact
RocketMqMessageProducer.cs 1 critical rule 9.47 → 8.19 Suppress
Enforce advisory code health rules Violations Code Health Impact
RocketMqMessageProducer.cs 3 advisory rules 9.47 → 8.19 Suppress
GcpPubSubMessageGateway.cs 2 advisory rules 9.10 → 8.28 Suppress
AzureServiceBusMessagePublisher.cs 1 advisory rule 10.00 → 9.69 Suppress
Parser.cs 1 advisory rule 9.39 → 9.10 Suppress
PostgresMessageConsumer.cs 1 advisory rule 8.55 → 8.28 Suppress
View Improvements
File Code Health Impact Categories Improved
SqsInlineMessageCreator.cs 8.93 → 9.39 Complex Method, Bumpy Road Ahead
SqsMessageCreator.cs 8.55 → 8.82 Code Duplication, Complex Method
SqsInlineMessageCreator.cs 8.93 → 9.24 Complex Method, Bumpy Road Ahead
SqsMessageCreator.cs 8.55 → 8.82 Code Duplication, Complex Method

Quality Gate Profile: Clean Code Collective
Want more control? Customize Code Health rules or catch issues early with our IDE extension and CLI tool.

@claude

claude Bot commented Nov 12, 2025

Copy link
Copy Markdown

Pull Request Review: Messaging Gateway Bug Fixes

Thank you for this comprehensive bug fix PR! This addresses critical issues across multiple messaging gateways. Here's my detailed review:

Overall Assessment

Strong Points:

  • Excellent scope: Fixes multiple critical bugs across 11+ messaging gateway implementations
  • Consistent approach: Applies similar fixes (TraceParent, TraceState, Baggage propagation) across all gateways
  • Well-documented: The PR description clearly lists all bugs found and fixed
  • Good refactoring: Simplifies error handling patterns by reducing nesting

Code Quality & Best Practices

✅ Positive Observations

  1. Improved Error Handling Pattern

    • Files like SqsInlineMessageCreator.cs now return early from the try-catch block instead of assigning to a variable
    • This reduces indentation and follows the codebase principle of "one level of indentation"
    • Example: Changed from message = new Message(...) to direct return new Message(...)
  2. Consistent Observability Improvements

    • Properly added BrighterTracer.WriteProducerEvent() calls across all producers
    • Ensures Activity Span propagation is consistent across AWS, Azure, Kafka, Redis, etc.
  3. CloudEvents Headers Consolidation

    • Good refactoring to read CloudEvents headers once and pass them to multiple methods
    • Reduces redundant parsing and improves performance

⚠️ Areas for Improvement

1. Null-Forgiving Operator Usage (Critical)

In SqsInlineMessageCreator.cs:88-89:

messageId: messageId.Result\!,
topic: topic.Result\!,

Issue: Using null-forgiving operator (\!) without validation is risky. If Result is null, this will cause a runtime exception.

Recommendation: Add explicit null checks before using null-forgiving operators:

if (\!messageId.Success || messageId.Result == null || \!topic.Success || topic.Result == null)
{
    throw new InvalidOperationException("Required message header values are missing");
}

This pattern is used correctly in RmqMessageCreator.cs:93-94 - consider applying it consistently.

2. Method Parameter Consistency

Methods like ReadTimestamp() and ReadContentType() now accept cloudEvents/headers parameters but also access class-level _messageAttributes. This creates implicit dependencies.

Recommendation: Make the design more explicit - either:

  • Pass both _messageAttributes and cloudEvents as parameters (better testability)
  • Or consistently use instance state

3. Return Type Changes May Break Behavior

In multiple files, ReadTimestamp() changed from returning DateTime to DateTimeOffset:

// Before
private HeaderResult<DateTime> ReadTimestamp()

// After  
private HeaderResult<DateTimeOffset> ReadTimestamp(Dictionary<string, string> headers)

Recommendation: Verify all callers handle DateTimeOffset correctly. While this is generally an improvement (better timezone handling), ensure it doesn't introduce subtle bugs in date comparisons.

4. Dictionary Mutation Timing

In SqsInlineMessageCreator.cs:76-85, you mutate the bag dictionary before passing it to MessageHeader:

var bag = ReadMessageBag();
if (deduplicationId.Success)
{
   bag[HeaderNames.DeduplicationId] = deduplicationId.Result;
}
// ... then pass to MessageHeader constructor

This is fine, but consider if it's clearer to populate the bag completely before construction, or pass it unpopulated and use a property setter.

5. MsSqlQueueBuilder.cs Addition

The diff shows 86 new lines in MsSqlQueueBuilder.cs but the file content isn't fully visible in the diff.

Recommendation: Ensure this follows the codebase patterns and includes:

  • Proper XML documentation
  • License header (MIT)
  • Follows naming conventions for DDL generation

Performance Considerations

Good:

  • Consolidated CloudEvents header reading reduces multiple JSON parsing passes
  • Early returns improve performance by avoiding unnecessary object construction

⚠️ Watch:

  • Multiple TryGetValue calls on dictionaries in a sequence - consider caching lookups if the same key is accessed multiple times
  • Example in ReadSource(): checks both _messageAttributes and headers for the same key

Security Concerns

No major security issues identified

Observations:

  • TraceParent/TraceState/Baggage propagation is correctly implemented
  • No unsafe deserialization patterns
  • Proper validation when parsing URIs and timestamps

⚠️ Minor Concerns:

  • Ensure Baggage.LoadBaggage() properly validates/sanitizes input strings to prevent injection attacks
  • Consider size limits when loading baggage from untrusted sources

Test Coverage

⚠️ Insufficient Visibility

The PR shows only 1 test file changed (When_parsing_a_good_redis_message_to_brighter.cs), but fixes bugs in 11+ gateway implementations.

Critical Recommendations:

  1. Each bug fix should have a corresponding test case demonstrating:

    • The bug existed (red test)
    • The fix resolves it (green test)
  2. Specifically needed tests:

    • RabbitMQ: TTL property setting, Max Queue Length + Dead Letter configuration
    • Postgres: BinaryMessagePayload with LargeMessageTable, span propagation
    • AWS V3/V4: TraceParent/TraceState/Baggage flow through headers
    • GCP Pub/Sub: IAM Policy for dead letter queue, PartitionKey publishing
    • Redis: Absolute URI validation for Source/Subject, TimeStamp serialization
  3. The PR description mentions this is "creating a base suite test case for Messaging Gateway" - where are these test suites?

Testing Philosophy (per CLAUDE.md):

  • "Ensure all new features and bug fixes include appropriate test coverage"
  • "Use TDD where possible" - these fixes should ideally have been test-driven
  • "Tests should confirm the behavior of the SUT"

Breaking Changes

⚠️ Potential Breaking Changes:

  1. Constructor signature change in SnsMessageProducer.cs:67:

    • Added InstrumentationOptions instrumentation parameter
    • Has default value, so technically not breaking, but worth noting
  2. Return type changes:

    • Various methods changing from DateTime to DateTimeOffset
    • Methods returning non-nullable types where they previously returned nullable

Recommendation: Document any behavioral changes in release notes.

Specific File Comments

Redis (RedisMessageCreator.cs / RedisMessagePublisher.cs)

✅ Fixed timestamp serialization issues
✅ Removed incorrect absolute URI requirement for Source/Subject
⚠️ Verify backward compatibility with messages already in Redis queues

RabbitMQ Async (RmqMessageConsumer.cs)

✅ Good: Removed commented-out code (lines 7-12 in old version)
✅ Fixed TraceState header name
⚠️ Ensure MaxQueueLength support is tested with actual RabbitMQ broker

GCP Pub/Sub (GcpPubSubMessageGateway.cs)

✅ Good: Added IAM policy configuration for dead letter queue
✅ Added partition key support
⚠️ Ensure GcpPublication.PartitionKey is properly documented

Final Recommendations

Must Have Before Merge:

  1. ✅ Add null checks before using null-forgiving operators
  2. ✅ Add comprehensive test coverage for each bug fix
  3. ✅ Verify no breaking changes or document them clearly

Nice to Have:

  1. Consider extracting common trace header reading logic to reduce duplication
  2. Add inline documentation for complex methods like ReadTimestamp()
  3. Consider performance profiling for high-throughput scenarios

Verdict

This PR fixes critical bugs and improves observability across the entire messaging gateway infrastructure. The changes are well-structured and consistent. However, the lack of test coverage is concerning given the scope of changes.

Recommendation: Request comprehensive test coverage before merge. Once tests are added and the null-safety issues are addressed, this is ready to merge.


Great work on identifying and fixing these issues across so many implementations! The systematic approach to adding trace propagation is particularly commendable.

@iancooper

iancooper commented Nov 12, 2025

Copy link
Copy Markdown
Member

High Priority:

  1. Add comprehensive test coverage for all bug fixes mentioned in the PR description

OK, we know these fixes come from the test rewrite which will address this

  1. Fix null reference risks by properly checking HeaderResult.Success before using .Result!

Might be useful to fix under the "boy scout rule"

  1. Verify breaking changes in constructor signatures don't break existing code

OK

Medium Priority:

  1. Extract duplicated code into shared utilities

Don't worry unless they are obvious, it would be better to do this post your tests working

  1. Standardize fallback/default value behavior across message creators

As above

  1. Add XML documentation for new constants and public APIs

Yep please, do this one

  1. Performance test the Redis gateway with the new validation logic

Again, let's wait until tests are done

Low Priority:

  1. Consider splitting the partition key feature into a separate PR

Ignore

  1. Refactor long methods using the Extract Method pattern

As above, let's wait for the refactoring of the tests

  1. Consider a more consistent approach to header reading across all gateways

Again, a good point, we could build a general utility, but let's wait for the test rewrite

@lillo42 lillo42 merged commit 4e26a47 into master Nov 14, 2025
93 of 109 checks passed
@lillo42 lillo42 deleted the fixes-messaging-gateway branch November 14, 2025 09:05
AboubakrNasef pushed a commit to AboubakrNasef/Brighter that referenced this pull request Nov 16, 2025
* Fixes found bug on Messaging Gateway

* fixes build
iancooper added a commit that referenced this pull request Nov 22, 2025
* add tickerq and test project

* add TickerQ library

* add test for schedule message

* Implement the Schedule Message Functions

* add request shceduler messages WIP

* add documentation

* refactor test fixtures

* pass the cacnelation token

* refactor the creation logic of the timeTicker

* fix typo

* remove launch settings

* use the Id instead of guid

* add the strong namer for the TickerQ.Utilities isn't signed with strong name

* remove properites folder

* update the package to not Sign the assembly

* remove space  from file serviceActivator api

* Remove the AckOnRead flag in AzureServiceBusConfiguration (#3899)

See #3895

* Fixes found bug on Messaging Gateway (#3905)

* Fixes found bug on Messaging Gateway

* fixes build

* Make RedisSubscription constructor as public (#3906)

* add MIT License to files

---------

Co-authored-by: Doğan Çeçen <sepeth@hey.com>
Co-authored-by: Rafael Lillo <rafael.andrade@justeattakeaway.com>
Co-authored-by: Ian Cooper <ian_hammond_cooper@yahoo.co.uk>
DevJonny pushed a commit to DevJonny/Brighter that referenced this pull request Feb 28, 2026
* Fixes found bug on Messaging Gateway

* fixes build
DevJonny pushed a commit to DevJonny/Brighter that referenced this pull request Feb 28, 2026
* add tickerq and test project

* add TickerQ library

* add test for schedule message

* Implement the Schedule Message Functions

* add request shceduler messages WIP

* add documentation

* refactor test fixtures

* pass the cacnelation token

* refactor the creation logic of the timeTicker

* fix typo

* remove launch settings

* use the Id instead of guid

* add the strong namer for the TickerQ.Utilities isn't signed with strong name

* remove properites folder

* update the package to not Sign the assembly

* remove space  from file serviceActivator api

* Remove the AckOnRead flag in AzureServiceBusConfiguration (BrighterCommand#3899)

See BrighterCommand#3895

* Fixes found bug on Messaging Gateway (BrighterCommand#3905)

* Fixes found bug on Messaging Gateway

* fixes build

* Make RedisSubscription constructor as public (BrighterCommand#3906)

* add MIT License to files

---------

Co-authored-by: Doğan Çeçen <sepeth@hey.com>
Co-authored-by: Rafael Lillo <rafael.andrade@justeattakeaway.com>
Co-authored-by: Ian Cooper <ian_hammond_cooper@yahoo.co.uk>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

3 - Done Bug .NET Pull requests that update .net code V10.X

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants