Azure Service Bus transport

com.babelqueue:babelqueue-azure-servicebus is an Azure Service Bus transport on the Java core. It sends the canonical envelope as the message body with the §4 native projection, 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:

<dependency>
    <groupId>com.babelqueue</groupId>
    <artifactId>babelqueue-azure-servicebus</artifactId>
    <version>1.0.0</version>
</dependency>

Requirements: Java 17+. It pulls babelqueue-core and azure-messaging-servicebus transitively. You supply the Azure ServiceBusClient.

Produce

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

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 abandons 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.