Send to a queue or topic
A service_bus destination sends each message to a queue or topic as binary data with content type x-application/hl7-v2+er7. MSH-10 becomes the message ID, so the entity's duplicate detection can drop resends. The message type, sending application and facility, and processing ID (MSH-9, 3, 4 and 11) are application properties named hl7_message_type, hl7_sending_application, hl7_sending_facility and hl7_processing_id, so subscriptions can filter on them, for example hl7_message_type = 'ORU^R01'.
# MEDITECH → MLLP → a Service Bus topic
[[route]]
name = "results-to-service-bus"
mode = "store_and_forward"
source = { type = "mllp", listen = "10.10.10.10:7894" }
[route.destination]
type = "service_bus"
namespace = "contoso.servicebus.windows.net"
topic = "hl7-results" # or queue = "…"
[route.destination.auth]
type = "managed_identity" # needs Azure Service Bus Data SenderReceive from a queue or subscription
A service_bus source receives from a queue, or from a topic's subscription, one message at a time (peek-lock), so order is kept. The gateway handles each message like one that arrived over MLLP, then settles it by the ACK:
| ACK | What happens to the Service Bus message |
|---|---|
| AA | Completed: removed from the queue or subscription. |
| AE | Abandoned: Service Bus delivers it again, and dead-letters it after the entity's max delivery count. |
| AR | Dead-lettered, with DeadLetterReason “HL7 AR” and the ACK's text as the description. |
# A Service Bus subscription → MLLP into MEDITECH
[[route]]
name = "orders-from-service-bus"
mode = "passthrough"
request_timeout = "30s" # keep it well under the lock duration
[route.source]
type = "service_bus"
namespace = "contoso.servicebus.windows.net"
topic = "hl7-orders"
subscription = "meditech" # or queue = "…" instead of topic + subscription
[route.source.auth]
type = "workload_identity" # AKS; needs Azure Service Bus Data Receiver
[route.destination]
type = "mllp"
address = "meditech.hospital.local:6661"Service Bus locks a received message for the entity's lock duration (1 minute by default, up to 5). With pass-through, the gateway delivers while the message is locked, so keep the route's request_timeout well under it. Store-and-forward settles each message as soon as it is stored.
Signing in
Prefer Entra ID: give the gateway's identity the Azure Service Bus Data Sender role for destinations and Azure Service Bus Data Receiver for sources, on the namespace or the entity. Shared access keys work too.
auth = { type = "managed_identity" } # client_id = "…" for a user-assigned identity
auth = { type = "workload_identity" } # reads AZURE_TENANT_ID, AZURE_CLIENT_ID, AZURE_FEDERATED_TOKEN_FILE
auth = { type = "client_secret", tenant_id = "…", client_id = "…", client_secret = "${SB_CLIENT_SECRET}" }
# Or a shared access key, instead of namespace + auth:
connection_string = "${SB_CONNECTION_STRING}" # Endpoint=sb://…;SharedAccessKeyName=…;SharedAccessKey=…The gateway connects over AMQP on port 5671. Where only HTTPS may leave the network, set transport = "websockets" for AMQP over WebSockets on port 443. Service Bus sources need no listening port, and in the Helm chart such a route has no port.