LiteBus
CatalogDispatch

Transport Envelope Mapping

  • ID: dispatch.transport-envelope-mapping
  • Name: Transport envelope mapping
  • Maturity: GA
  • Summary: Copy durable envelope metadata (contract, trace, tenant, idempotency) onto transport publish headers so downstream consumers and ingress can reconstruct context.

What It Does

InboxTransportEnvelopeMapper and OutboxTransportEnvelopeMapper (internal in dispatch packages) delegate to TransportEnvelopeHeaderMapper in LiteBus.Transport. They build a header dictionary from envelope fields: message id, contract name and version, correlation and causation ids, tenant id, trace context, idempotency key, and visible-after scheduling.

Ingress adapters on the receiving side read the same header conventions to populate InboxAcceptMetadata when accepting into a remote inbox. Symmetric headers let an outbox publish on one service become an ingress accept on another without ad hoc header names per team.

Packages

PackageRole
LiteBus.Inbox.DispatchInbox-side mapper
LiteBus.Outbox.DispatchOutbox-side mapper
LiteBus.TransportShared header mapping
LiteBus.Transport.AbstractionsTransportHeaders name constants

Requires

  • dispatch.transport-core (mappers run inside transport dispatchers)
  • runtime.contract-registry (contract name/version on envelope)

Invariants

  • Contract identity on the wire uses stable contract name and version, not CLR type names.
  • Message body remains the serialized payload from storage; headers carry metadata only.
  • Header mapping lives in dispatch and ingress adapter packages, not in storage or core processors.

Non-Goals

  • Does not define broker-specific property bags beyond what ITransportPublisher abstracts.
  • Does not validate header round-trip at dispatch time (consumer/ingress responsibility).
  • Does not encrypt header values (payload protection applies to body only).

Public Surface

var headers = TransportEnvelopeHeaderMapper.BuildHeaders(new TransportEnvelopeHeaderSource(
    messageId,
    "orders.ship",
    1,
    correlationId,
    causationId,
    tenantId,
    traceContext,
    idempotencyKey,
    visibleAfter));

InboxTransportEnvelopeMapper.BuildHeaders(InboxEnvelope) (Internal)

PackageLiteBus.Inbox.Dispatch
VisibilityInternal; invoked from TransportInboxDispatcher.DispatchAsync
ReturnsDictionary<string, object?> passed to TransportPublishRequest.Headers

OutboxTransportEnvelopeMapper.BuildHeaders(OutboxEnvelope) (Internal)

PackageLiteBus.Outbox.Dispatch
VisibilityInternal; invoked from TransportOutboxDispatcher.DispatchAsync

TransportEnvelopeHeaderMapper.BuildHeaders(TransportEnvelopeHeaderSource)

PackageLiteBus.Transport
VisibilityPublic shared mapper
Headers always setTransportHeaders.MessageId, ContractName, ContractVersion
Headers when presentCorrelationId, CausationId, TenantId, TraceContext, IdempotencyKey, VisibleAfter (ISO 8601)

TransportPublishRequest.Headers

Wire carrier on publish; broker adapters map dictionary entries to AMQP properties, Kafka record headers, SQS message attributes, or Service Bus application properties.

Observability

SignalRole
send {destination} activity tagsmessaging.message.id, messaging.destination.name, conversation id, and route attributes from the publish request
Trace context headerTransportHeaders.TraceContext copied to wire; downstream process {destination} can continue or link the stored W3C context
Correlation idSet on TransportPublishRequest.CorrelationId and duplicated in headers when envelope carries a value

No dedicated header-mapping counter or meter. Mapping failures surface as dispatch exceptions before publish.

Deep Docs

Test Coverage

Covered

Test methodProject
BuildHeaders_ShouldMapAllMetadataFieldsLiteBus.Inbox.UnitTests (Dispatch/)
ProcessPendingAsync_ShouldPublishLeasedEnvelopeToAmqpQueueLiteBus.Durable.IntegrationTests (Dispatch/Inbox/Amqp/)
ProcessPendingAsync_ShouldPublishLeasedEnvelopeToServiceBusQueueLiteBus.Durable.IntegrationTests (Dispatch/Inbox/AzureServiceBus/)
ProcessPendingAsync_ShouldPublishLeasedEnvelopeToKafkaTopicLiteBus.Durable.IntegrationTests (Dispatch/Inbox/Kafka/)
ProcessPendingAsync_ShouldPublishLeasedEnvelopeToSqsQueueLiteBus.Durable.IntegrationTests (Dispatch/Inbox/AwsSqs/)
DispatchAsync_ShouldPublishEnvelopeThroughTransportLiteBus.Inbox.UnitTests (Dispatch/)
BuildHeaders_ShouldMapAllMetadataFieldsLiteBus.Outbox.UnitTests (Dispatch/)
ProcessPendingAsync_ShouldPublishEnvelopeToAmqpQueueLiteBus.Durable.IntegrationTests (Dispatch/Outbox/Amqp/)
DispatchAsync_ShouldPublishEnvelopeThroughTransportLiteBus.Outbox.UnitTests (Dispatch/)

Untested

  • Direct unit tests for TransportEnvelopeHeaderMapper.BuildHeaders.
  • Idempotency key round-trip through full remote ingress acceptance.
  • VisibleAfter interpretation in dispatch-only suites.
  • Header mapping behavior with encrypted payload body scenarios.

Out-of-Scope

  • Broker-specific property bags beyond ITransportPublisher abstraction
  • Dispatch-time validation of header round-trip (consumer and ingress responsibility)
  • Encrypting header values (payload protection applies to body only)

On this page