--- title: "Azure Service Bus transport" description: "The babelqueue-azure-servicebus transport — a canonical-envelope publisher and a URN-routed consumer over azure-messaging-servicebus, on the framework-agnostic core." source: https://babelqueue.com/docs/babelqueue-java/1.x/azure-service-bus/ updated: 2026-06-14T00:00:00.000Z --- # Azure Service Bus transport `com.babelqueue:babelqueue-azure-servicebus` is an Azure Service Bus transport on the Java core. It sends the [canonical envelope](/docs/spec/1.x/envelope/) as the message body with the [§4 native projection](/docs/spec/1.x/broker-bindings/#azure-service-bus), and consumes by routing each message to a handler by URN — so a message it produces is consumed by any other BabelQueue SDK, and vice-versa. ## Install Maven: ```xml com.babelqueue babelqueue-azure-servicebus 1.0.0 ``` Requirements: **Java 17+**. It pulls `babelqueue-core` and `azure-messaging-servicebus` transitively. You supply the Azure `ServiceBusClient`. ## Produce ```java import com.babelqueue.azureservicebus.AsbPublisher; import com.azure.messaging.servicebus.ServiceBusClientBuilder; import com.azure.messaging.servicebus.ServiceBusSenderClient; import java.util.Map; ServiceBusClientBuilder builder = new ServiceBusClientBuilder().connectionString(cs); ServiceBusSenderClient sender = builder.sender().queueOrTopicName("orders").buildClient(); String id = AsbPublisher.create(sender) .publish("urn:babel:orders:created", Map.of("order_id", 1042L)); ``` `publish(urn, data)` returns the message `meta.id`; overloads add a `traceId` and a relative `Duration delay` (native `ScheduledEnqueueTime`). ## Consume ```java import com.babelqueue.azureservicebus.AsbConsumer; import com.azure.messaging.servicebus.ServiceBusReceiverClient; ServiceBusReceiverClient receiver = builder.receiver().queueName("orders").buildClient(); AsbConsumer consumer = AsbConsumer.builder(receiver) .handler("urn:babel:orders:created", (envelope, message) -> { // envelope.data(), envelope.traceId(), envelope.attempts() ... }) .onError((error, envelope, message) -> error.printStackTrace()) .build(); while (running) { consumer.poll(); } ``` A throwing handler `abandon`s the message — the broker redelivers it and increments `DeliveryCount` (at-least-once); at `MaxDeliveryCount` it auto-moves to the native dead-letter sub-queue. Auth is a connection string or the fully-qualified namespace + a `TokenCredential` (`DefaultAzureCredential`). ## Contract mapping (§4) | Envelope | Azure Service Bus | | :--- | :--- | | body | `Body` (byte-identical across SDKs) | | `job` (URN) | `Subject` | | `trace_id` | `CorrelationId` | | `meta.id` | `MessageId` | | `meta.schema_version` | `ApplicationProperties["bq-schema-version"]` | | `meta.lang` | `ApplicationProperties["bq-source-lang"]` | | `meta.created_at` | `ApplicationProperties["bq-created-at"]` (ms) | | `attempts` | `max(body, DeliveryCount − 1)` | | reserve / ack / retry | PeekLock → `complete` / `abandon` | The final Service Bus clients are mocked with Mockito 5 — no Azure, no network. The envelope is unchanged (`schema_version` stays `1`); Azure Service Bus is purely additive.