Wednesday, June 15, 2022

Azure Functions (In Process): Output Binding to a Dynamic Queue/Topic

In this post let's see how we can set up an Output Binding in an In Process Azure Function to send messages to a dynamic target Azure Service Bus Queue or Topic.

We usually use ICollector or IAsyncCollector to write values to an output binding. And often times, the target queue/topic is set up through attributes. Something like below,

[FunctionName(FunctionNames.SomeFunction)]
public async Task Run(
    [ServiceBusTrigger("%ServiceBus_ListeningQueue%", Connection = "ServiceBus_ConnectionString")] 
        ServiceBusReceivedMessage serviceBusReceivedMessage,
    [ServiceBus("%ServiceBus_TargetQueue%", Connection = "ServiceBus_ConnectionString")] 
        IAsyncCollector<MyOutputMessage> asyncCollector)
{
    // TODO: Some code

    await asyncCollector.AddAsync(new MyOutputMessage { });
}

The above function is listening to an Azure Service Bus Queue (ServiceBus_ListeningQueue) and outputting a message to another Queue (ServiceBus_TargetQueue). Here the target Queue is static and cannot be changed. 

What if we want to route the message to a target Queue or Topic based on a property of the incoming message (most of the time based on ServiceBusReceivedMessage.ReplyTo Property).

In these cases, we can use Azure Functions imperative binding instead of declarative binding (which is done above).

[FunctionName(FunctionNames.SomeFunction)]
public async Task Run(
    [ServiceBusTrigger("%ServiceBus_ListeningQueue%", Connection = "ServiceBus_ConnectionString")]
        ServiceBusReceivedMessage serviceBusReceivedMessage,
    IBinder binder)
{
    // TODO: Some code
 
    IAsyncCollector<MyOutputMessage> asyncCollector =
        await binder.BindAsync<IAsyncCollector<MyOutputMessage>>(new ServiceBusAttribute(serviceBusReceivedMessage.ReplyTo)
        {
            // Note: This should be the App Setting Name that contains the Service Bus connection string
            Connection = "ServiceBus_ConnectionString",
        });
 
    await asyncCollector.AddAsync(new MyOutputMessage { });
}

And that's it. You can change the EntityType property of ServiceBusAttribute to ServiceBusEntityType.Topic if you want to output into a Topic (default is Queue).

Hope this helps.

Happy Coding.

Regards,
Jaliya

No comments:

Post a Comment