Azure Functions with Azure Service Bus

Source
NuGet Package NServiceBus.AzureFunctions.InProcess.ServiceBus (1.2)
Target NServiceBus Version: 7.x

Host NServiceBus endpoints with Azure Functions and Azure Service Bus triggers.

Basic usage

Endpoint configuration

NServiceBus can be registered and configured on the host builder using the UseNServiceBus extension method in the startup class:

class Startup : FunctionsStartup
{
    public override void Configure(IFunctionsHostBuilder builder)
    {
        builder.UseNServiceBus(() => new ServiceBusTriggeredEndpointConfiguration("MyFunctionsEndpoint"));
    }
}

Any services registered via the IFunctionsHostBuilder will be available to message handlers via dependency injection. The startup class must be declared via the FunctionStartup attribute: [assembly: FunctionsStartup(typeof(Startup))].

Azure Function queue trigger for NServiceBus

The Azure Function trigger for NServiceBus is auto-generated by specifying the logical endpoint name using a custom assembly attribute:

[assembly: NServiceBusEndpointName("MyFunctionsEndpoint")]

The attribute will generate the trigger function required for NServiceBus.

An invalid endpoint name will generate an NSBFUNC001 error with the message Endpoint name is invalid and cannot be used to generate trigger function.

The Azure Service Bus trigger 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

Triggering a message using HTTP function:

public class HttpSender
{
    readonly IFunctionEndpoint functionEndpoint;

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

    [FunctionName("HttpSender")]
    public async Task<IActionResult> Run(
        [HttpTrigger(AuthorizationLevel.Function, "get", "post", Route = null)] HttpRequest request, ExecutionContext executionContext, ILogger logger)
    {
        logger.LogInformation("C# HTTP trigger function received a request.");

        var sendOptions = new SendOptions();
        sendOptions.RouteToThisEndpoint();

        await functionEndpoint.Send(new TriggerMessage(), sendOptions, executionContext, logger);

        return new OkObjectResult($"{nameof(TriggerMessage)} sent.");
    }
}

Message consistency

All transport operations behave equal to ReceiveOnly transport transaction mode. There is no support for the SendsAtomicWithReceive transport transaction mode in this version.

Configuration

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

  • IConfiguration passed in via the constructor
  • Environment variables
KeyValueNotes
AzureWebJobsServiceBusConnection string for the Azure ServiceBus namespace to connect toThis value is required for ServiceBusTriggerAttribute. An alternative key can be passed into the constructor.
ENDPOINT_NAMEThe name of the NServiceBus endpoint to hostA value can be provided directly to the constructor.
NSERVICEBUS_LICENSEThe NServiceBus licenseCan also be provided via serviceBusTriggeredEndpointConfig.EndpointConfiguration.License(...).
WEBSITE_SITE_NAMEThe name of the Azure Function app. Provided when hosting the function in Azure.Used to set the NServiceBus host identifier. Local machine name is used if not set.

For local development, use local.settings.json. 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>"
  }
}

Custom diagnostics

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

class configureErrorQueueuOnStartup : FunctionsStartup
{
    public override void Configure(IFunctionsHostBuilder builder)
    {
        builder.UseNServiceBus(() =>
        {
            var configuration = new ServiceBusTriggeredEndpointConfiguration("MyFunctionsEndpoint");
            configuration.LogDiagnostics();
            return configuration;
        });
    }
}

Error queue

For recoverability to move the continuously failing messages to the error queue rather than to the Azure Service Bus dead-letter queue, the error queue must be created in advance and configured using the following API:

class EnableDiagnosticsOnStartup : FunctionsStartup
{
    public override void Configure(IFunctionsHostBuilder builder)
    {
        builder.UseNServiceBus(() =>
        {
            var configuration = new ServiceBusTriggeredEndpointConfiguration("MyFunctionsEndpoint");
            configuration.AdvancedConfiguration.SendFailedMessagesTo("error");
            return configuration;
        });
    }
}

Known constraints and limitations

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

Preparing the Azure Service Bus namespace

Function endpoints cannot create their own queues or other infrastructure in the Azure Service Bus namespace.

Use the asb-transport command line (CLI) tool to provision the entities in the namespace for the Function endpoint.

Creating the endpoint queue

asb-transport endpoint create <queue name>

See the full documentation for the asb-transport endpoint create command for more details.

If the asb-tranport command-line tool is not used to create the queue, it is recommended to set the MaxDeliveryCount setting to the maximum value.

Subscribing to events

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

See the full documentation for the asb-transport endpoint subscribe command for more details.

Samples

Related Articles


Last modified