In this post, I wrote about how you might read a message from the service bus queue. However, with Azure Functions (and WebJobs), comes the ability to have Microsoft do some of this plumbing code for you.
I have a queue here (taken from the service bus explorer):
I can read this in an Azure function; let’s create a new Azure Functions App:
This time, we’ll create a Service Bus Queue Triggered function:
Out of the box, that will give you this:
public static class Function1 { [FunctionName("Function1")] public static void Run([ServiceBusTrigger("testqueue", AccessRights.Listen, Connection = "")]string myQueueItem, TraceWriter log) { log.Info($"C# ServiceBus queue trigger function processed message: {myQueueItem}"); } }
There’s a few things that we’ll probably want to change here. The first is “Connection”. We can remove that parameter altogether, and then add a row to the local.settings.json file (which can be overridden later inside Azure). Out of the box, you get AzureWebJobsStorage and AzureWebJobsDashboard, which both accept a connection string to a Azure Storage Account. You can also add AzureWebJobsServiceBus, which accepts a connection string to the service bus:
"Values": { "AzureWebJobsStorage": "DefaultEndpointsProtocol=https;AccountName=teststorage1…", "AzureWebJobsDashboard": "DefaultEndpointsProtocol=https;AccountName=teststorage1…", "AzureWebJobsServiceBus": "Endpoint=sb://pcm-servicebustest.servicebus.windows.net/;SharedAccessKeyName=RootManageSharedAccessKey;SharedAccessKey=…" }
If you run the job, it will now pick up any outstanding entries in that queue. But, what if you don’t know the queue name; for example, what if you find out the queue name is different. To illustrate the point; here, I’m looking for “testqueue1”, but the queue name (as you saw earlier) is “testqueue”:
public static class Function1 { [FunctionName("Function1")] public static void Run([ServiceBusTrigger("testqueue1", AccessRights.Listen)]string myQueueItem, TraceWriter log) { log.Info($"C# ServiceBus queue trigger function processed message: {myQueueItem}"); } }
Obviously, if you’re looking for a queue that doesn’t exist, bad things happen:
To fix this, I have to change the code… which is broadly speaking a bad thing. What we can do, is configure the queue name in the config file; like this:
"Values": { "AzureWebJobsStorage": " . . . ", . . ., "queue-name": "testqueue" }
And we can have the function look in the config file by changing the queue name:
[FunctionName("Function1")] public static void Run([ServiceBusTrigger("%queue-name%", AccessRights.Listen)]string myQueueItem, TraceWriter log) { log.Info($"C# ServiceBus queue trigger function processed message: {myQueueItem}"); }
The pattern of supplying a variable name in the format “%variable-name%” seems to work across other triggers and bindings for Azure Functions.
Deployment
That’s now looking much better, but what happens when the function gets deployed? Let’s see:
We can now see that the function is deployed:
At the minute, it won’t do anything, because it’s looking for a queue name in a setting that only exists locally. Let’s fix that:
Remember to save the changes.
Looking at the logs confirms that this now runs correctly.