Getting Started
Architecture
Transports
Persistence
ServiceInsight
ServicePulse
ServiceControl
Monitoring
Samples

Azure Functions with Service Bus (Isolated Worker)

The isolated worker model is a newer hosting option for Azure Functions. Running out-of-process decouples the function code from the Azure Functions runtime. For further information about the isolated worker, refer to the Microsoft documentation.

Usage

NServiceBus supports the isolated worker hosting model via the NServiceBus.AzureFunctions.Worker.ServiceBus NuGet package. The following configuration enables NServiceBus:

[assembly: NServiceBusTriggerFunction("WorkerDemoEndpoint")]

public class Program
{
    public static Task Main()
    {
        var host = new HostBuilder()
            .ConfigureFunctionsWorkerDefaults()
            .UseNServiceBus()
            .Build();

        return host.RunAsync();
    }
}

The Azure Service Bus trigger is automatically generated by the NServiceBusTriggerFunction attribute, which forwards incoming messages to the appropriate message handlers.

If customization of the Azure Service Bus trigger is required, it can be manually declared instead of relying on the auto-generated trigger. See the article on custom Azure Functions triggers for more information.

Dispatching outside a message handler

To send/publish messages outside a message handler, inject IFunctionEndpoint into custom triggers. This snippet shows an HTTP trigger sending a message via NServiceBus:

public class HttpTrigger
{
    readonly IFunctionEndpoint functionEndpoint;

    public HttpTrigger(IFunctionEndpoint functionEndpoint)
    {
        this.functionEndpoint = functionEndpoint;
    }

    [Function("HttpSender")]
    public async Task<HttpResponseData> Run(
        [HttpTrigger(AuthorizationLevel.Function, "get", "post", Route = null)] HttpRequestData req,
        FunctionContext executionContext)
    {
        await functionEndpoint.Send(new TriggerMessage(), executionContext);

        return req.CreateResponse(HttpStatusCode.OK);
    }
}

Configuration

ServiceBusTriggeredEndpointConfiguration loads certain configuration values from the Azure Function host environment in the following order:

  1. IConfiguration
  2. Environment variables

ServiceBus connection

Connection to Azure Service Bus can be configured in multiple ways:

  • Using just a <ConnectionName> key, with the value set to the connection string for the ServiceBus namespace to connect to.
  • Using a <CONNECTION_NAME_PREFIX>__fullyQualifiedNamespace along with other connection properties prefixed by the same <CONNECTION_NAME_PREFIX>, as specified in the Identity Based Connections for Azure Functions.

If both a connection string and Identity Based connection values are specified, the connection string will take precedence. The default <ConnectionName> or <CONNECTION_NAME_PREFIX> is AzureWebJobsServiceBus, however an alternate value can be supplied to the Connection property on the NServiceBusTriggerAttribute

Example of a connection string based connection:

{
  "IsEncrypted": false,
  "Values": {
    ...
    "AzureWebJobsServiceBus": "Endpoint=sb://<namespace>.servicebus.windows.net/;SharedAccessKeyName=RootManageSharedAccessKey;SharedAccessKey=<namespace-shared-access-key>",
  }
}

Example of an Identity Based connection:

{
  "IsEncrypted": false,
  "Values": {
    ...
    "MyConnectionName__fullyQualifiedNamespace": "<namespace>.servicebus.windows.net",
    "MyConnectionName__tenantId": "00000000-0000-0000-0000-000000000000",
    "MyConnectionName__clientId": "00000000-0000-0000-0000-000000000000",
    "MyConnectionName__clientSecret": "<client-secret>"
  }
}
[assembly: NServiceBusTriggerFunction("WorkerDemoEndpoint", Connection = "MyConnectionName")]

Other Configuration

KeyValueNotes
NSERVICEBUS_LICENSEThe NServiceBus licenseCan also be provided via serviceBusTriggeredEndpointConfig.AdvancedConfiguration.License(...).
ENDPOINT_NAMEThe name of the NServiceBus endpoint to hostOptional. By default, the endpoint name is derived from the NServiceBusTriggerFunction attribute.
WEBSITE_SITE_NAMEThe name of the Azure Function app. Provided when hosting the function in Azure.Optional. Used to set the NServiceBus host identifier. Local machine name is used if not set.

For local development, use the local.settings.json file. In Azure, specify a Function setting using the environment variable as the key.

{
  "IsEncrypted": false,
  "Values": {
    ...
    "NSERVICEBUS_LICENSE": "<?xml version=\"1.0\" encoding=\"utf-8\"?><license id=\"1222e1d1-2222-4a46-b1c6-943c442ca710\" expiration=\"2113-11-30T00:00:00.0000000\" type=\"Standard\" LicenseType=\"Standard\" LicenseVersion=\"4.0\" MaxMessageThroughputPerSecond=\"Max\" WorkerThreads=\"Max\" AllowedNumberOfWorkerNodes=\"Max\">. . .</license>"
  }
}

Transactions

Unlike the in-process hosting model, the isolated worker model does not support using TransportTransactionMode.SendsAtomicWithReceive. TransportTransactionMode.ReceiveOnly is the default option.

Custom diagnostics

NServiceBus startup diagnostics are disabled by default when using Azure Functions. Diagnostics can be written to the logs via the LogDiagnostics option:

public static Task Main()
{
    var host = new HostBuilder()
        .ConfigureFunctionsWorkerDefaults()
        .UseNServiceBus(configuration =>
        {
            configuration.LogDiagnostics();
        })
        .Build();

    return host.RunAsync();
}

Diagnostics data will be written with logger identification StartupDiagnostics with log level Informational.

Error queue

By default, repeatedly failing messages are sent to the error queue. The error queue can be configured or disabled completely to let the native Azure Service Bus dead-lettering configuration handle failures:

public static Task Main()
{
    var host = new HostBuilder()
        .ConfigureFunctionsWorkerDefaults()
        .UseNServiceBus(configuration =>
        {
            // Change the error queue name:
            configuration.AdvancedConfiguration.SendFailedMessagesTo("my-custom-error-queue");

            // Or disable the error queue to let ASB native dead-lettering handle repeated failures:
            configuration.DoNotSendMessagesToErrorQueue();
        })
        .Build();

    return host.RunAsync();
}

Known constraints and limitations

The configuration API exposes NServiceBus transport configuration options via the configuration.Transport property to allow customization. However, not all options will be applicable to execution within Azure Functions.

Use the configuration.Routing property to configure transport routing.

Preparing the Azure Service Bus namespace

Function endpoints can create queues or other infrastructure in the Azure Service Bus namespace using the configuration.AdvancedConfiguration.EnableInstallers() method.

To manually provision the entities in the namespace for the Function endpoint, use the asb-transport command line (CLI) tool.

Creating the endpoint queue

asb-transport endpoint create <queue name>

For more details, see the operation scripting documentation for the asb-transport endpoint create command.

Subscribing to events

asb-transport endpoint subscribe <queue name> <eventtype>

For more details, see the operational scripting documentation for the asb-transport endpoint subscribe command.

Samples

Related Articles