LiteBus
CatalogDispatch

Outbox AMQP Dispatch

  • ID: dispatch.outbox.amqp
  • Name: Outbox AMQP dispatch
  • Maturity: GA
  • Summary: Publish leased outbox envelopes to RabbitMQ with LiteBus contract headers through TransportOutboxDispatcher.

What It Does

AddAmqpTransport(...) registers AmqpTransportModule once at the root. UseAmqpDispatch(configure) on OutboxModuleBuilder registers TransportOutboxDispatchModule as a feature bridge to that transport. After domain logic enqueues events to outbox storage, the processor publishes to the configured exchange when rows are leased.

Route resolution prefers envelope Topic, then custom resolver, then contract name. Headers carry contract identity and trace context for downstream ingress.

Packages

PackageRole
LiteBus.Outbox.Dispatch.AmqpRegistration glue
LiteBus.Outbox.DispatchShared transport outbox dispatcher
LiteBus.Transport.AmqpRabbitMQ client

Requires

  • dispatch.transport-core
  • transport.amqp
  • durable-core.outbox

Invariants

  • Default hook failure policy is CompleteDespiteHookFailure for transport outbox modules.
  • At-least-once publication: crash after broker ack but before terminal persist can duplicate messages.
  • Downstream consumers must deduplicate (message id, idempotency header, or business keys).

Non-Goals

  • Does not subscribe to queues.
  • Does not guarantee transactional outbox with broker (two-phase ack not built in).

Public Surface

services.AddLiteBus(litebus =>
{
    litebus.AddAmqpTransport(new AmqpConnectionOptions
    {
        HostName = "localhost",
        Port = 5672,
        UserName = "guest",
        Password = "guest"
    });

    litebus.AddOutbox(outbox =>
    {
        outbox.EnableOutboxProcessor();
        outbox.UseAmqpDispatch(
            options =>
            {
                options.DefaultDestination = "events.exchange";
                options.ResolveRoute = envelope => envelope.Topic ?? envelope.ContractName;
                options.Persistent = true;
            });
    });
});
APIRole
OutboxModuleBuilder.UseAmqpDispatch(Action<TransportOutboxDispatcherOptions>)Registers outbox transport dispatcher that requires the root AMQP transport
TransportOutboxDispatchModule.DefaultHookFailurePolicyDefaults to CompleteDespiteHookFailure
TransportOutboxDispatcher.DispatchAsync(OutboxEnvelope, CancellationToken)Publishes outbox envelope to broker with canonical headers

TransportOutboxDispatcherOptions:

PropertyDefaultRole
DefaultDestination""Exchange name
ContentTypeapplication/jsonOutgoing MIME content type
PersistenttrueDurable message flag
MandatoryfalseFail publish when unroutable
ResolveRoutenullRoute selector after topic fallback
ValidatePayloadBeforeDispatchfalseDeserialize payload before publish for validation

Outbox route order is tenant strategy, then envelope Topic, then ResolveRoute, then contract name.

AmqpConnectionOptions:

PropertyDefaultRole
UrinullFull AMQP URI, overrides host/port/credentials when set
HostNamelocalhostBroker host
Port5672Broker port
VirtualHost/AMQP virtual host
UserName / Passwordguest / guestBroker credentials
ClientProvidedNamenullConnection name shown in broker UI
AutomaticRecoveryEnabledtrueEnables reconnect
NetworkRecoveryInterval00:00:05Delay between reconnect attempts
CircuitBreakerconfigured objectSeparate connection and per-exchange publisher breaker thresholds

Observability

SignalDetail
send {destination}Exchange, RabbitMQ routing key, and envelope id on the AMQP send path
litebus.transport.circuit_breaker.*Broker tag amqp on shared transport meter
litebus.outbox.processor.published / failed / dead_letteredAfter dispatch and terminal persist
litebus.outbox.processor.dispatch_durationIncludes AMQP publish latency

Deep Docs

Test Coverage

Covered

Test methodProject
UseAmqpDispatch_WithAmqpTransportModule_ShouldRegisterTransportOutboxDispatcherLiteBus.Durable.IntegrationTests (Dispatch/Outbox/Amqp/)
OutboxDispatchExtensions_ShouldRegisterTransportDispatcherLiteBus.Durable.IntegrationTests (Registration/)
ProcessPendingAsync_ShouldPublishEnvelopeToAmqpQueueLiteBus.Durable.IntegrationTests (Dispatch/Outbox/Amqp/)
ProcessPendingAsync_WhenTopicMissing_ShouldUseContractNameAsRoutingKeyLiteBus.Durable.IntegrationTests (Dispatch/Outbox/Amqp/)
ProcessPendingAsync_ShouldPublishToAmqpAndMarkPostgreSqlEnvelopePublishedLiteBus.Durable.IntegrationTests (Dispatch/Outbox/Amqp/)

Untested

  • After-dispatch hook failure path with CompleteDespiteHookFailure under live AMQP.
  • Outbox dispatch failure and circuit breaker behavior for AMQP dispatch projects.
  • Route override via tenant strategy in AMQP-specific coverage.

Out-of-Scope

  • Subscribing to or consuming AMQP queues
  • Two-phase transactional outbox with broker acknowledgment persisted before terminal store state

On this page