← Knowledge Center Native-SDK conformance · case study

Running Azure messaging locally with the native SDK: AMQP vs HTTPS

When you build against Azure messaging, your code uses an official SDK and your tests should too — unmodified, config-only. The catch is the wire protocol. Azure Service Bus speaks AMQP 1.0, and AMQP is the one transport a local simulator can't cheaply fake. This is how we kept the native Azure SDK working as-is for local queue development by building around HTTP instead — and exactly what that does and doesn't buy you.

1. The wall — AMQP

The native azure-messaging-servicebus SDK speaks AMQP 1.0: long-lived stateful sessions and links, credit-based flow control, CBS (claims-based-security) auth over a dedicated link, and a separate management link for entity operations. That's not an HTTP request/response you can serve with a route handler — it's a stateful binary protocol with its own connection lifecycle.

The obvious escape hatch — Microsoft's Service Bus emulator — is a dead end for an embeddable, cross-platform appliance, for three independent reasons:

  • Java entity management is .NET-only. Runtime create/delete of queues/topics via the Administration client runs over a custom, non-TLS management port that the non-.NET SDKs won't drive — fatal for a create → send → receive → delete test from Java.
  • amd64-only SQL sidecar. The emulator requires MS SQL Server 2022 (amd64). The ARM-capable Azure SQL Edge was retired 2025-09-30, so there's no clean ARM path.
  • Footprint + license. ~1.6 GB SQL image, ~2 GB RAM, under a dev/test-only, non-redistributable EULA — too heavy and too restricted to ship inside a runtime.

2. The tech choice — build around HTTP

Azure has a messaging service that speaks plain HTTP/REST and ships with a real, embeddable emulator: Storage Queues, served by Azurite (the same container that already backs Azure Blob in the appliance). So Azure messaging conformance is delivered through the native azure-storage-queue SDK — full runtime create → send → receive → delete against Azurite, no AMQP, no SQL sidecar.

// Native azure-storage-queue — unchanged from production except the connection string.
QueueClient queue = new QueueClientBuilder()
    .connectionString(System.getenv("AZURE_QUEUE_CONNECTION_STRING")) // Azurite/local
    .queueName("orders")
    .buildClient();

queue.create();
queue.sendMessage("order-42");

QueueMessageItem msg = queue.receiveMessage();
process(msg.getBody().toString());
queue.deleteMessage(msg.getMessageId(), msg.getPopReceipt()); // ack

queue.delete();

The only line that differs from production is the connection string — and even that is a standard Azure connection string, just pointing at the local queue endpoint. The Azurite backing is invisible to your code and swappable for real Azure Storage.

Under the hood (you don't need this to use it): because the azure-storage-queue SDK rebuilds request URLs from the host (dropping any path prefix), the appliance gives each storage account its own hostname — {account}.queue.localtest.me (resolves to 127.0.0.1, no hosts-file edits) — and a tiny middleware maps that back to the queue handler. Same trick real Azure uses: one hostname per account.

3. The trade-off, stated plainly

Storage Queue is a different service from Service Bus. We label the substitution; we never imply parity.

You keepYou give up (for now)
A real native Azure queue SDK, unmodifiedService Bus topics / subscriptions (pub-sub fan-out)
Real create → send → receive → delete round-tripsSessions (ordered, stateful message groups)
ARM-native, no SQL sidecar, ARM + amd64Transactions and AMQP-only delivery semantics
Persistent state, offlineDead-letter / auto-forward niceties

If your app genuinely depends on Service Bus topics or sessions, this stub won't model them — and we say so, out loud, rather than returning a green that lies.

4. SDK conformance

The snippet above is the whole point: it's the same client classes, the same calls you ship to production. There is no Vyomi SDK, no shim, no wrapper. You configure one endpoint (via the connection string) and the unmodified azure-storage-queue SDK does real work. Swap the connection string for a production Azure Storage account and the identical code runs against the real cloud.

5. What is guaranteed (Azure messaging)

  • Guaranteed: the official azure-storage-queue SDK, unmodified and config-only; a real create → send → receive → delete round-trip with visibility-timeout semantics; portable code; backing tech (Azurite) invisible and swappable.
  • Not guaranteed (said out loud): AMQP-only Service Bus features — topics, subscriptions, sessions, transactions; cloud-scale throughput / quotas / billing. The substituted service is labeled — Storage Queue is not Service Bus.

Part of the Vyomi Knowledge Center series on native-SDK conformance. Companion: “gRPC vs HTTPS” — GCP KMS / Secret Manager. Verified on a live appliance (2026-06-22): native azure-storage-queue create→send→receive→delete, green.