Is there a way to access the BrokerProperties of a Service Bus message within a behavior pipeline?

Based on the documentation, the new transport sets the MaxDeliveryCount to the maximum (int.MaxValue). However, for our implementation, we would like to restrict the delivery count to 50. Hence, we thought to create a behavior pipeline which checks the delivery count. If it exceeds the configured count, then we throw an exception. The problem is we cannot receive the BrokerProperties of a Service Bus message in the behavior. So my question to you is, is there a way to get the BrokerProperties of a message in the behavior pipeline and extract the DeliveryCount?

We are using:
nservicebus 8.1.6
nservicebus.azurefunctions.inprocess.servicebus 4.3.1
nservicebus.transport.azureservicebus 3.2.2

See below a code sample

public class MaxDeliveryCountBehavior : Behavior<IIncomingPhysicalMessageContext>
{
    private readonly int _maxDeliveryCountThreshold = 50;
    public override async Task Invoke(IIncomingPhysicalMessageContext context, Func<Task> next)
    {       
        var transportMessage = context.Message;
        transportMessage.Headers.TryGetValue("SomeHeaders.DeliveryCount", out var deliveryCountString);
        int.TryParse(deliveryCountString, out var currentDeliveryCount);

        if (currentDeliveryCount > _maxDeliveryCountThreshold)
        {
            throw new InvalidOperationException($"Message exceeded max delivery count ({_maxDeliveryCountThreshold}).");
        }

        await next().ConfigureAwait(false);
    }
}

Thanks.

@sidiki30,

The Azure Service Bus transport exposes the native message, and you can access that in the pipeline.

Here is an example on how to use that to shortcut the retry logic when needed.

Let me know if that helps,
.m

@sidiki30 Could you share a bit more context on why you need this?

Did you run into the following issue?

If not it would help to understand why. For example, by default the total number of deliveries depends on the configured the immediate and delayed retries:

Much appreciated if you have provide feedback on why that isn’t sufficient for your environment.

– Ramon

Thank you for the reply. Indeed, I saw this in the documentation and tried the solution. However, the context.Extensions.Get<ServiceBusReceivedMessage>() line throws an exception stating “No item found in behavior context with key: Azure.Messaging.ServiceBus.ServiceBusReceivedMessage”.
I am not sure whether we are missing some configuration that could provide access to the native message.
I have also opened a non-critical issue thought the support.

We are using an service bus trigger Azure Functions, which gets triggered as soon as the message is copied into the subscription and puts a 5 minute lock on the message. If the processing is not complete within the 5 minute period, then the message will end up in infinite retries. Nevertheless, the problem remains the same. We are unable to access the BrokerProperties. However, according to the documentation, we should be able to do so.

It sounds like you are mixing the functionality available between AzureServiceBus functions and the AzureServiceBus transport. The sample code you referenced is a capability of the transport, but is not available in the functions package. Instead of using a behavior, we recommend using a Custom Azure function trigger which will allow you access to the ServiceBusReceivedMessage.

Azure Functions acts as NSB transport replacement. Depending on the Functions SDK, you’d have to implement something custom. If you’re using Isolated Worker SDK, you can control the incoming message in the middleware and prevent re-processing after 50 attempts.