Queue Sink: Azure Service Bus
-
Azure Service Bus is Microsoft Azure's fully managed message broker.
The broker carries messages between applications (like microservices, or a web app and its background workers) through queues or topics with subscriptions. -
RavenDB can consume messages from Azure Service Bus by running an ongoing sink task.
The task reads JSON-formatted messages from a queue or a topic subscription, runs a user-defined script over each message, and stores the documents the script produces in RavenDB collections. -
The sink task connects to an Azure Service Bus namespace using one of three authentication methods:
- a SAS (Shared Access Signature) connection string
- Entra ID application credentials
- passwordless authentication (using a managed identity)
-
This page explains how to define an Azure Service Bus sink task using the client API.
To configure this task in Studio, see the Azure Service Bus Queue Sink Task page.
To learn about RavenDB queue sinks in general, see the Queue Sink overview. -
In this article:
The Azure Service Bus Sink Task
Connecting an Azure Service Bus namespace
A RavenDB sink task is a consumer in the Azure Service Bus architecture, reading the messages that producer applications place on the broker.
The task connects to an Azure Service Bus namespace using a connection string that you register with RavenDB. The connection string identifies the namespace and holds the credentials that the task authenticates with.
Read below about adding a connection string via the client API.
Selecting message sources
Each sink script lists one or more sources.
A source is either:
- a queue, identified by its name, or
- a topic subscription, identified by its topic and subscription names.
One script can read from several sources, and a sink task can run several scripts, so a single task can consume from any mix of queues and subscriptions in the same namespace.
Learn below how to specify each source via the client API.
Retrieving enqueued messages
A running sink task prevents RavenDB from unloading its host database due to inactivity, so consumption from Azure Service Bus continues uninterrupted even when the database would otherwise go idle.
A producer places a message on a queue or publishes it to a topic, where it waits to be
consumed.
The sink task receives the messages available on each of its sources and hands
each message to a script.
Running user-defined scripts
A sink script is a JavaScript segment that turns each consumed message into one or more RavenDB documents.
The simplest script stores the message as it arrives, using the put command:
// Set the @collection metadata to store the document in a collection;
// without it, the document is stored in the @empty collection.
this['@metadata']['@collection'] = 'Orders';
// Store the message as-is, reusing its Id property as the document ID.
put(this.Id.toString(), this);
A script can also reshape a message into a different document.
e.g., for a message like this one:
{
"Id": 13,
"FirstName": "John",
"LastName": "Doe"
}
the following script adds a FullName field and stores the document in the Users
collection:
var item = {
Id: this.Id,
FirstName: this.FirstName,
LastName: this.LastName,
FullName: this.FirstName + ' ' + this.LastName,
"@metadata": {
"@collection": "Users"
}
};
// Pass the Id as a string, even when Azure Service Bus delivers it as a number.
put(this.Id.toString(), item);
Beyond put, a script can call load to read an existing RavenDB document
(e.g., to enrich a message with related data), del to delete a document, and
various other commands.
Storing documents in RavenDB collections
The sink task processes a batch of messages and stores the resulting documents in a single transaction, either the whole batch or none of it.
Some script processing errors are allowed. When such an error occurs, RavenDB skips the affected message, logs the event, and raises an alert, but continues processing the rest of the batch.
Only after the batch is stored does the task acknowledge its messages to Azure Service
Bus, which then removes them from the queue or subscription.
Because the task acknowledges a message only after its document is persisted, every message
is processed at least once, even if the sink fails partway through a batch.
The number of messages in a batch is configurable.
At-least-once processing means the same message can be delivered more than once. This happens when a producer enqueues a message more than once, or when a batch takes longer than the message's lock duration (the time Azure Service Bus reserves a message for the sink): once the lock expires, Azure Service Bus redelivers the message.
If processing each message only once matters to the consumer, it is the consumer's
responsibility to handle the duplicates. Often this needs no extra work: as long as a
message keeps the same Id, the script's put(id, ...) command overwrites the earlier
document, so only one copy remains.
Client API
Adding an Azure Service Bus connection string
Before defining a sink task, add an Azure Service Bus connection string for the task to use.
Create a QueueConnectionString object configured for Azure Service Bus, and pass it to
PutConnectionStringOperation.
An Azure Service Bus connection authenticates in one of three modes: a SAS connection string,
Entra ID application credentials, or passwordless authentication.
Set exactly one of them in the connection string's AzureServiceBusConnectionSettings object:
- SAS connection string
- Entra ID
- Passwordless
var connectionString = new QueueConnectionString
{
Name = "AzureServiceBusConStr",
BrokerType = QueueBrokerType.AzureServiceBus,
AzureServiceBusConnectionSettings = new AzureServiceBusConnectionSettings
{
// A Service Bus SAS connection string, copied from the Azure portal
ConnectionString = "Endpoint=sb://<namespace>.servicebus.windows.net/;" +
"SharedAccessKeyName=<key-name>;SharedAccessKey=<key>"
}
};
store.Maintenance.Send(
new PutConnectionStringOperation<QueueConnectionString>(connectionString));
var connectionString = new QueueConnectionString
{
Name = "AzureServiceBusConStr",
BrokerType = QueueBrokerType.AzureServiceBus,
AzureServiceBusConnectionSettings = new AzureServiceBusConnectionSettings
{
// Authenticate using an Entra ID application registration (tenant, client ID, and secret)
EntraId = new AzureServiceBusEntraId
{
Namespace = "<namespace>.servicebus.windows.net",
TenantId = "<tenant-id>",
ClientId = "<client-id>",
ClientSecret = "<client-secret>"
}
}
};
store.Maintenance.Send(
new PutConnectionStringOperation<QueueConnectionString>(connectionString));
var connectionString = new QueueConnectionString
{
Name = "AzureServiceBusConStr",
BrokerType = QueueBrokerType.AzureServiceBus,
AzureServiceBusConnectionSettings = new AzureServiceBusConnectionSettings
{
// Authenticate using the host's managed identity; no secret is stored
Passwordless = new AzureServiceBusPasswordless
{
Namespace = "<namespace>.servicebus.windows.net"
}
}
};
store.Maintenance.Send(
new PutConnectionStringOperation<QueueConnectionString>(connectionString));
For the full property reference, see the Connection string and Authentication credentials classes in the Syntax section.
Adding an Azure Service Bus sink task
To define the sink task, prepare a QueueSinkConfiguration object and pass it to
AddQueueSinkOperation.
The configuration needs to name the connection string to use, set the broker type to Azure
Service Bus, and hold one or more QueueSinkScript objects.
- Each script lists its sources in the
Queuesproperty, where each entry is a single string:- A queue source is just the queue name.
e.g.,orders - A topic-subscription source is the topic name and the subscription name joined by a semicolon.
e.g.,orders-topic;ravendb-sub
The semicolon is an unambiguous separator: Service Bus queue, topic, and subscription names can never contain a semicolon, so it cannot be mistaken for part of either name.
- A queue source is just the queue name.
AzureServiceBusSinkSourceis a helper class that builds and validates these entries, so you don't have to build thetopicName;subscriptionNameform yourself and can't pass an invalid name:- Use
AzureServiceBusSinkSource.Queue(queueName)for a queue source. - Use
AzureServiceBusSinkSource.Subscription(topicName, subscriptionName)for a topic-subscription source.
- Use
Example: Reading from a queue
// Read from a single Service Bus queue
var script = new QueueSinkScript
{
Name = "orders",
Queues = new List<string> { AzureServiceBusSinkSource.Queue("orders") },
// Store each message as an Orders document
Script = @"this['@metadata']['@collection'] = 'Orders';
put(this.Id.toString(), this)"
};
var config = new QueueSinkConfiguration
{
Name = "AzureServiceBusSink",
// The connection string added above
ConnectionStringName = "AzureServiceBusConStr",
BrokerType = QueueBrokerType.AzureServiceBus,
Scripts = { script }
};
store.Maintenance.Send(new AddQueueSinkOperation<QueueConnectionString>(config));
Example: Reading from multiple sources
A script can list any mix of queues and subscriptions in its Queues property:
Queues = new List<string>
{
AzureServiceBusSinkSource.Queue("orders"),
AzureServiceBusSinkSource.Subscription("orders-topic", "ravendb-sub")
}
For the QueueSinkConfiguration and QueueSinkScript property reference, see the
Sink task
classes in the Syntax section.
Configuration Options
Use these configuration options for finer control over the sink task:
- QueueSink.MaxBatchSize
The maximum number of messages consumed in a single batch. - QueueSink.MaxFallbackTimeInSec
The maximum time, in seconds, that the sink stays in fallback mode (suspended) after a connection failure.
Syntax
Methods
The AzureServiceBusSinkSource methods build and validate the entries stored in a script's Queues list.
- Queue
- Subscription
Validates a queue name and returns it as a sink source entry.
public static string Queue(string queueName)
Usage:
AzureServiceBusSinkSource.Queue("orders")
Parameters:
| Parameter | Type | Description |
|---|---|---|
| queueName | string | The Service Bus queue to consume from |
Return value:
| Type | Description |
|---|---|
string | The source entry to add to QueueSinkScript.Queues |
Joins a topic name and a subscription name into a sink source entry, topicName;subscriptionName.
public static string Subscription(string topicName, string subscriptionName)
Usage:
AzureServiceBusSinkSource.Subscription("orders-topic", "ravendb-sub")
Parameters:
| Parameter | Type | Description |
|---|---|---|
| topicName | string | The Service Bus topic |
| subscriptionName | string | The subscription on that topic to consume from |
Return value:
| Type | Description |
|---|---|
string | The topicName;subscriptionName source entry to add to QueueSinkScript.Queues |
Classes
Connection string
- QueueConnectionString
- AzureServiceBusConnectionSettings
The connection string a sink task uses to reach an Azure Service Bus namespace.
class QueueConnectionString
{
string Name
QueueBrokerType BrokerType
AzureServiceBusConnectionSettings AzureServiceBusConnectionSettings
}
| Property | Type | Description |
|---|---|---|
| Name | string | The connection string name |
| BrokerType | QueueBrokerType | Set to QueueBrokerType.AzureServiceBus for an Azure Service Bus connection string |
| AzureServiceBusConnectionSettings | AzureServiceBusConnectionSettings | The namespace and authentication details |
QueueConnectionString is shared by all queue brokers, so it also defines settings for the other
broker types (KafkaConnectionSettings, RabbitMqConnectionSettings,
AzureQueueStorageConnectionSettings, AmazonSqsConnectionSettings).
Set only the one matching BrokerType.
The authentication details for an Azure Service Bus connection. Set exactly one of its properties.
class AzureServiceBusConnectionSettings
{
string ConnectionString
AzureServiceBusEntraId EntraId
AzureServiceBusPasswordless Passwordless
}
| Property | Type | Description |
|---|---|---|
| ConnectionString | string | A Service Bus SAS connection string |
| EntraId | AzureServiceBusEntraId | Entra ID application credentials |
| Passwordless | AzureServiceBusPasswordless | A managed-identity connection that stores no secret |
Authentication credentials
- AzureServiceBusEntraId
- AzureServiceBusPasswordless
Entra ID application credentials for connecting to a namespace.
class AzureServiceBusEntraId
{
string Namespace
string TenantId
string ClientId
string ClientSecret
}
| Property | Type | Description |
|---|---|---|
| Namespace | string | The fully qualified namespace, e.g. mynamespace.servicebus.windows.net |
| TenantId | string | The Entra ID tenant ID |
| ClientId | string | The application (client) ID |
| ClientSecret | string | The application's client secret |
A managed-identity connection to a namespace; stores no secret.
class AzureServiceBusPasswordless
{
string Namespace
}
| Property | Type | Description |
|---|---|---|
| Namespace | string | The fully qualified namespace, e.g. mynamespace.servicebus.windows.net |
Sink task
- QueueSinkConfiguration
- QueueSinkScript
The configuration of an Azure Service Bus sink task.
class QueueSinkConfiguration
{
string Name
string ConnectionStringName
QueueBrokerType BrokerType
List<QueueSinkScript> Scripts
bool Disabled
string MentorNode
bool PinToMentorNode
long TaskId
}
| Property | Type | Description |
|---|---|---|
| Name | string | The sink task name |
| ConnectionStringName | string | The name of the Azure Service Bus connection string the task uses |
| BrokerType | QueueBrokerType | Set to QueueBrokerType.AzureServiceBus (must match the connection string's broker type) |
| Scripts | List<QueueSinkScript> | The scripts the task runs |
| Disabled | bool | Whether the task is created in a disabled state |
| MentorNode | string | The preferred responsible node for the task, if any |
| PinToMentorNode | bool | Whether to pin the task to its mentor node |
| TaskId | long | The task's identifier, assigned by the server |
A script that turns the messages from its sources into RavenDB documents.
class QueueSinkScript
{
string Name
List<string> Queues
string Script
bool Disabled
}
| Property | Type | Description |
|---|---|---|
| Name | string | The script name |
| Queues | List<string> | The sources to consume from, each built with AzureServiceBusSinkSource |
| Script | string | The JavaScript that processes each message |
| Disabled | bool | Whether the script is disabled |
Enums
- QueueBrokerType
Identifies the message broker that a connection string and sink task use.
enum QueueBrokerType
{
None,
Kafka,
RabbitMq,
AzureQueueStorage,
AmazonSqs,
AzureServiceBus
}
| Value | Description |
|---|---|
| AzureServiceBus | Selects Azure Service Bus. Use this value for an Azure Service Bus connection string and sink task. |
| None, Kafka, RabbitMq, AzureQueueStorage, AmazonSqs | The other broker types, used by the remaining Queue Sink and Queue ETL brokers. |