Azure WebJobs: ServiceBusTrigger

Challenge is to build a WebJob that listens or monitors a queue in the Microsoft Azure Service Bus within a certain namespace and pick of each message that is send there by a message producer and process it. The WebJob acts as a message consumer of the messages on the queue. Below a high level diagram of a scenario that will be explained in this post and how I faced the challenge.

image

You can build WebJobs inside Visual Studio by installing the WebJobs SDK. Once you have installed the SDK you have template available to build a WebJob in C# or Visual Basic.

clip_image004[6]

You can select this template specify a name for the WebJob and click Ok. You will see that a program class will be created.

clip_image006

And a Functions.cs.

clip_image008[6]
By default a method will be created for you to monitor or listen to an Azure Storage Queue, not Service Bus Queue! To have method that will be triggered/executed when a message is written to an Azure Service Bus Queue you will need to have ServiceBusTrigger. This not available in the project and you will need to add the Microsoft.Azure.WebJobs.ServiceBus NuGet package.

Now a can change to ServiceBusTrigger in method ProcessQueueMessage and specify the queue I want to listen to.

clip_image010[5]

Next change is changing the type of the message from string to BrokeredMessage type. This type is not available in your class unless you add using statement for Microsoft.ServiceBus.Messaging. The package is already in the project, because it is part of the imported NuGet package. The TextWriter object can be used to write log statements that can be viewed in the AzureWebJob Dashboard.

When a message arrives on inboundqueue it will be picked up by WebJob and enter the ProcessQueueMessage method in runtime. Here I can extract the message body and send it for instance to Redis cache as key value pair (reason of picking this example is based on a request from someone on twitter to share how to do that). To send it to Redis Cache I need to import another NuGet Package i.e. StackExchange.Redis (client library). Now the complete code for the functions class looks like below:

clip_image012

Before the WebJob can be deployed to a WebApp a few configuration settings have to be done in the app.config. The connection strings for the AzureWebJobsDashboard and AzureWebJobsStorage need to be provided in the connectionStrings Section. These are required to view the log in Azure i.e. AzureWebJobsDashboard. The connection string that needs to be specified is the connection string to an Azure Storage account. Format is as follows:

DefaultEndpointsProtocol=https;AccountName=[Storage Account Name];AccountKey=[Access Key]

The other connection string that has to be provided is for the AzureWebJobsServiceBus. Format is:

Endpoint=sb://namespace.servicebus.windows.net/;SharedAccessKeyName=RootManageSharedAccessKey;SharedAccessKey=[Access Key]

Finally in the appSettings section the connection string for the Redis needs to specified. Connection string has the format of:

namespace.redis.cache.windows.net,abortConnect=false,ssl=true,password=[password]

Once configuration is done the app.config will look like:

clip_image014

Before the deployment (Publish to Azure) of the WebJob can be done a configuration setting in WebApp has to be done to enable AzureWebJobDashboard.

clip_image015
This is an important step. In case you forget this than observing the WebJob logs will result in the following error:

clip_image017[6]

Now the WebJob can be deployed via Visual Studio to a WebApp. Right click on the project and choose Publish as Azure WebJob...

clip_image018

You will see a Publish Web dialog and here you import the publishing setting from WebApp. These settings can be downloaded from Azure Portal.

clip_image020

Next you can click Ok and you will go to next section of the dialog i.e. Connection.

clip_image022

Click Validate Connection to see if connection info is correct. When valid you can click Publish. Now the WebJob will be published to WebApp. In the output window of Visual Studio you will see that deployment went successfull.

clip_image024

In the Azure Portal you can see the WebJob in the WebApp.

clip_image025

When you click on the logs url you will be redirected to the Microsoft Azure WebJobs portal.

clip_image027

Nothing much has happen so far, only that the Job has started. In case I send a message to the queue using for instance ServiceBus Explorer, I will see some action. Send a message via the ServiceBus Explorer to the queue.

clip_image029

Refresh the AzureWebJob Portal and a new entry is available.

clip_image031

Once you click on the Functions.ProcessQueueMessage you examine the logs.

clip_image033

To explore what is in my REDIS cache I need to navigate to the service in the Azure Portal and open a console. Enter GET and messagid.

clip_image035

image

As you can see the message is now in the Cache.

It took me sometime to get the ServiceBusTrigger working. After some digging around I was able to get the ServiceBusTrigger working and see its behaviour through the Azure WebJob Portal. The trigger is not limited to queues as it will also work for Service Bus Topic/Subscription. The signature of the method would look like:

clip_image037

Resources to explore with regards to this blog post are:

· http://stackoverflow.com/questions/15441853/with-azure-brokeredmessage-get-the-body-without-knowing-the-type
· https://azure.microsoft.com/en-us/documentation/articles/websites-dotnet-webjobs-sdk-get-started/
· http://blogs.blackmarble.co.uk/blogs/sspencer/post/2014/09/22/5-Tips-for-using-Azure-Web-Jobs.aspx
· http://stackoverflow.com/questions/28077330/why-do-i-need-to-configure-connection-strings-for-webjobs-in-azure-management-po
· https://azure.microsoft.com/en-us/documentation/articles/storage-configure-connection-string/


Cheers,

Steef-Jan

Comments

SteveC said…
Excellent post
Test said…
Nice article.

I'm also looking forward that LogicApp will be able to do this in the future, so no coding needed :)
Mark Willems said…
The ServiceBus bindings are now extensions (like the rest of the external binding extensions in azure-webjobs-sdk-extensions and must now be registered explicitly.

So you must do it like this:

_servicesBusConnectionString = AmbientConnectionStringProvider.Instance.GetConnectionString(ConnectionStringNames.ServiceBus);

JobHostConfiguration config = new JobHostConfiguration();
ServiceBusConfiguration serviceBusConfig = new ServiceBusConfiguration
{
ConnectionString = _servicesBusConnectionString
};
config.UseServiceBus(serviceBusConfig);

JobHost host = new JobHost(config);
host.RunAndBlock();

Popular posts from this blog

DTAP Strategy: Pricing and Licensing

Table Operation on Oracle 11g XE with OracleDbBinding

Integration, the community blasting into 2017!