Skip to content

Map Wolverine TenantId from incoming MassTransit messages (supersedes #3167)#3192

Merged
jeremydmiller merged 3 commits into
mainfrom
feat/masstransit-map-tenant-id-3167
Jun 22, 2026
Merged

Map Wolverine TenantId from incoming MassTransit messages (supersedes #3167)#3192
jeremydmiller merged 3 commits into
mainfrom
feat/masstransit-map-tenant-id-3167

Conversation

@jeremydmiller

Copy link
Copy Markdown
Member

Supersedes #3167 by @outofrange-consulting (Geoffrey MARC), whose original commits are retained here with authorship intact. This adds the requested feature and then reworks the public surface per maintainer review.

Feature (from #3167)

IMassTransitInterop.MapTenantIdFrom<T>(...) lets you derive Wolverine's Envelope.TenantId for incoming MassTransit messages from either the deserialized message body or the surrounding MassTransit metadata (headers, addresses, ids). It affects only the inbound/deserialization path, supports multiple message types (each mapper fires only for its own T), and works on every MassTransit-interop listener (RabbitMQ, Azure Service Bus, Amazon SQS). The UseMassTransitInterop(configure) lambda is now threaded through to the serializer on the RabbitMQ and SQS listeners so the mapping actually takes effect.

What changed vs #3167 (public API rework)

#3167 exposed a new public interface IMassTransitEnvelope<T> as the MapTenantIdFrom hook type. Per review, this instead exposes the concrete MassTransitEnvelope type publicly and removes the interface abstraction:

  • MassTransitEnvelope is now a public abstract base (MassTransit transport metadata + TransferData); MassTransitEnvelope<T> is the public generic subclass adding the typed Message. (The non-generic type is now the base of the generic one — previously inverted — so it can serve as the non-generic handle the serializer needs.)
  • Removed both the internal non-generic IMassTransitEnvelope and the IMassTransitEnvelope<T> interface that Map Wolverine TenantId from incoming MassTransit messages #3167 introduced.
  • MapTenantIdFrom<T> now takes Func<MassTransitEnvelope<T>, string?>.
  • BusHostInfo is made public so the public MassTransitEnvelope.Host property has consistent accessibility.

Breaking-change assessment

  • IMassTransitInterop.MapTenantIdFrom<T> is a new member on a public interface → technically a source/binary break for any external implementer of IMassTransitInterop. In practice the only implementer is the internal MassTransitJsonSerializer (it's a config seam, not a user-implemented interface), and main is on the 6.0 line where deliberate breaks are acceptable. Low real-world impact.
  • Making MassTransitEnvelope/MassTransitEnvelope<T>/BusHostInfo public is additive (they were internal).
  • IMassTransitEnvelope<T> only ever existed in the unmerged Map Wolverine TenantId from incoming MassTransit messages #3167, so removing it is not a break to any shipped API.

Tests

All MassTransit interop tests pass locally: CoreTests (24, incl. the new MassTransitTenantMappingTests and the updated MassTransitEnvelopeTests), the RabbitMQ stubbed masstransit_interop_map_tenant_id, and the AWS SQS masstransit_mapper_tenant_mapping.

🤖 Generated with Claude Code

Geoffrey MARC and others added 3 commits June 22, 2026 12:34
…essages

Add IMassTransitInterop.MapTenantIdFrom<T>(env => ...) so applications consuming
MassTransit messages can derive Wolverine's Envelope.TenantId from either the
message body or the MassTransit envelope metadata (headers, addresses, ids).

The lambda receives a new public read-only view, IMassTransitEnvelope<T>, exposing
the deserialized Message alongside the MassTransit metadata. The concrete
MassTransitEnvelope<T> stays internal so the mutable serialization DTO is not
leaked. Multiple message types compose; each mapper only fires for its own T and a
null/empty result never clobbers an existing tenant id. Inbound (read) path only.
…nd SQS listeners

UseMassTransitInterop(configure) dropped the configure lambda on the Rabbit MQ and
Amazon SQS listeners: Rabbit MQ called InteropWithMassTransit() with no argument,
and the SQS MassTransitMapper never received it. As a result any serializer
customization (UseSystemTextJsonForSerialization, and now MapTenantIdFrom) silently
no-opped on those transports while only Azure Service Bus honored it.

Thread the configure action through to the MassTransit serializer on both. Covered
by no-broker tests driving the Rabbit MQ deserialization pipeline end to end and the
SQS mapper construction.
…elope interface

Follow-up on the MassTransit tenant-id mapping work: instead of exposing a new public
IMassTransitEnvelope<T> interface as the MapTenantIdFrom hook type, make the concrete
MassTransitEnvelope type public and remove the interface abstraction entirely.

- MassTransitEnvelope is now a public abstract base carrying the MassTransit transport
  metadata (ids, addresses, headers, TransferData); MassTransitEnvelope<T> is the public
  generic subclass adding the deserialized Message body. The non-generic class is now the
  base of the generic one (previously inverted) so it can serve as the non-generic handle
  the serializer needs.
- Removed both the internal non-generic IMassTransitEnvelope interface and the
  IMassTransitEnvelope<T> interface introduced alongside the tenant-id feature.
- IMassTransitInterop.MapTenantIdFrom<T> now takes Func<MassTransitEnvelope<T>, string?>.
- BusHostInfo is made public so the public MassTransitEnvelope.Host property is consistent.
- MassTransitEnvelopeTests now uses MassTransitEnvelope<object> for the non-generic case.

Co-authored-by: Geoffrey MARC <geoffrey.marc@consulting-for.edenred.com>
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@jeremydmiller
jeremydmiller merged commit 58a6e50 into main Jun 22, 2026
25 checks passed
This was referenced Jun 23, 2026
This was referenced Jul 9, 2026
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.

1 participant