LiteBus
CatalogIngress

Azure Service Bus Inbox Ingress

  • ID: ingress.azure-service-bus
  • Name: Azure Service Bus inbox ingress
  • Maturity: Beta
  • Summary: Consumes Azure Service Bus queues or subscriptions and accepts messages into the inbox.

Purpose and Scope

UseAzureServiceBusIngress registers AzureServiceBusInboxIngressModule. The module maps AzureServiceBusInboxIngressOptions into shared transport ingress options, requires a root AzureServiceBusTransportModule, and registers the shared handler and consumer loop. Queue destinations use Destination; topic destinations also set SubscriptionName.

Failed store writes can abandon messages for retry when RequeueOnFailure is true (Service Bus retry semantics via transport adapter).

Beta Rationale

Service Bus ingress is Beta because ingress flow is stable but matrix depth is narrower than AMQP:

  • Duplicate MessageId and full header edge-case matrices are missing in emulator ingress tests.
  • Requeue-off poison drain matrix is not covered.
  • Broker option surface is intentionally narrower than AMQP.

Public Surface

bus.AddAzureServiceBusTransport(serviceBusOptions);
bus.AddInbox(inbox => inbox.UseAzureServiceBusIngress(ingress =>
{
    ingress.UseOptions(new AzureServiceBusInboxIngressOptions
    {
        Destination = "commands-inbox",
        SubscriptionName = "orders-worker",
        PrefetchCount = 10,
        MaxConcurrentCalls = 4,
        RequeueOnFailure = true,
        Safety = new TransportInboxIngressSafetyOptions
        {
            MaxInFlightMessages = 4
        }
    });
}));
Builder APIRole
InboxModuleBuilder.UseAzureServiceBusIngress(Action<AzureServiceBusInboxIngressModuleBuilder>)Registration extension
AzureServiceBusInboxIngressModuleBuilder.UseOptions(AzureServiceBusInboxIngressOptions)Queue or topic path and ingress behavior
AzureServiceBusInboxIngressModuleBuilder.DisableIngressConsumer()Handler without processor loop
AzureServiceBusInboxIngressModuleChild module

Azure Options and Parity vs AMQP

CapabilityAzure Service Bus ingressAMQP ingress
Destination requiredDestination requiredQueueName required
Root transport requiredAddAzureServiceBusTransport(...)AddAmqpTransport(...)
Prefetch settingyesyes
Named topic subscriptionyesno
Separate native handler concurrencyyes (MaxConcurrentCalls)no
RequeueOnFailure toggleyes (default true)yes (default true)
Shared Safety settingsyesyes
Declare destination knobsnoyes

Packages

  • LiteBus.Inbox.Ingress.AzureServiceBus
  • LiteBus.Transport.AzureServiceBus (explicit root transport)

Requires

  • ingress.registration
  • Shared ingress capabilities
  • transport.azure-service-bus
  • Inbox storage and contracts

Invariants

  • Destination and root AddAzureServiceBusTransport(...) are required at compose time.
  • SubscriptionName is required when Destination is a topic.
  • PrefetchCount fills the Azure client cache, while MaxConcurrentCalls controls Azure processor callbacks. Safety.MaxInFlightMessages applies the final LiteBus handler cap.
  • LiteBus contract headers are required on the wire payload.
  • Beta tier per v6 feature index; treat broker edge cases as application-tested.
  • Identity and idempotency default to broker-scoped values (Safety.RequireStableIdentity=true, Safety.TrustApplicationHeaders=false).

Non-Goals

  • GA tier declaration.
  • AMQP or Kafka ingress in the same package.
  • Built-in Service Bus dead-letter administration.

Observability

Ingress Metrics

InstrumentWhen incremented
ingress.ack_failed_after_acceptComplete/abandon fails after inbox accept

Meter LiteBus.Inbox via AddLiteBusInboxMetrics().

Transport Tracing and Metrics

SignalBroker tagRegistration
process {destination} activityservicebusAddLiteBusTransportInstrumentation()
litebus.transport.circuit_breaker.openazure_service_busTransport metrics from the root adapter
litebus.transport.circuit_breaker.failure_countazure_service_bussame

Structured Logs

EventId 3002, 3003, 3004 from TransportInboxIngressLogMessages on shared consumer.

Identity, Idempotency, and Trusted Headers

Service Bus ingress uses shared mapper defaults:

SettingDefaultResult
RequireStableIdentitytrueMissing broker id fails closed
Safety.TrustApplicationHeadersfalseApp idempotency and tenant headers are ignored
Broker-scoped idempotency keyingress:{destination}:{brokerMessageId}Stable duplicate absorption when delivery id is stable

Test Coverage

Covered

Test methodProject
PublishThroughServiceBus_ShouldAcceptProcessAndDispatchCommandLiteBus.Durable.IntegrationTests (Ingress/AzureServiceBus/)
UnknownContract_ShouldNotWriteToStoreLiteBus.Durable.IntegrationTests (Ingress/AzureServiceBus/)
InvalidJson_ShouldNotWriteToStoreLiteBus.Durable.IntegrationTests (Ingress/AzureServiceBus/)
StoreFull_ShouldDrainQueueAndKeepPrefilledRowLiteBus.Durable.IntegrationTests (Ingress/AzureServiceBus/)
RequeueEnabled_WithTransientStoreFailure_ShouldEventuallyAcceptLiteBus.Durable.IntegrationTests (Ingress/AzureServiceBus/)
InboxIngressExtensions_ShouldRegisterIngressServicesLiteBus.Durable.IntegrationTests (Registration/)

Untested

  • Header edge cases (missing contract name, wrong version, invalid message id) on Service Bus emulator.
  • RequeueOnFailure = false poison message drain.
  • Prefetch and lock duration tuning under load.
  • Duplicate MessageId idempotency matrix for ingress on emulator.
  • Ack-failed-after-accept metric assertion in emulator suite.

Out-of-Scope

  • GA tier declaration.
  • AMQP or Kafka ingress in the same package.
  • Built-in Service Bus dead-letter administration.

Deep Docs

On this page