Azure Function are very popular now. I explain how to create Azure Function with F# with Visual Studio. Now, I want to explain how to use the Azure Portal and create inline an Azure Function with C# Script and reading and writing a Service Bus Queue.
With this post, I want to cover a simple scenario: I want to create an Azure Function that it is triggered with a message in a Service Bus Queue, convert the body of the message in another object and send to another queue the result.
Service Bus Queue
This part is quite straightforward. In your Azure Portal, create a new Service Bus. In this example, my bad, the name of the bus is enricobus. Then, create two queues: message-in and message-out.
In message-in I send the message to trigger the function whereas in message-out the function will put a message in the queue after changing the original message.
Now, the Service Bus and the Queues are ready to use. Azure shows an overview of the Service Bus like in the following image.
To explore this brand-new Service Bus, I download Service Bus Explorer from Github, a really good project. If you don’t want to source code, the installer is here.
Then I have to connect Service Bus Explorer with the Service Bus. For the Service Bus page, on the left, there is an option called “Shared access policies“: click there and click on “RootManageSharedAccessKey“. Now, copy the “Primary Connection String“.
In Service Bus Explore, click on File > Connect. Paste the “Primary Connection String” in the connection string textbox and then press Ok.
Finally, I find my queues and I browse them.
First thing to do is to send a message to the message-in in Service Bus to test later the Azure Function with C# Script. Right click on message-in under Queues and click “Send Messages“.
Definitely, I’m a bit lazy and I use a very easy json. Copy this json and paste it in the Message Text and press Send.
{
"PersonName": "Enrico",
"Title": "Mr"
}
In the Log I see the message is posted successfully in the queue. As a double check for me, I see there is one message in the message-in queue. First step done!
Add a new Azure Function
I can start to create a new Azure Function in the portal. Nothing really exciting in this part: follow the wizard. I created a function called fnzinout2020. Now, what I see is the following screen:
Finally, I can start to create the Azure Function I wanted with C# Script and Service Bus. Click on the + on the right of Functions option. In the next screen, choose “Azure Service Bus Queue trigger“.
So, I can define some parameters for this function:
- name of the function
- Azure Service Bus Trigger
- Service Bus Connection (select one from the dropdown list)
- Queue name replace the default one with message-in
Then, click Create. Function create and, probably, it already has consumed the message in the queue.
Monitor
It is easy to verify if the function started already, I expand the function details and I find Monitor. Ok, in the following image I cheat a bit just because I want to show you that here there are all runs of your function and a bit more (I’ll tell you in a moment).
Integrate
It is the moment to add the output to out function. Now, click on Integrate on the same menu than before. As in the following screenshot, Integrate page has 3 sections:
- Trigger
- Inputs
- Outputs
Trigger is the Service Bus as I selected before. Input is to select other source for your data but I don’t need it now. Output is what I look for. Click on + New Output and then select Azure Service Bus. Click Select.
In the new screen I have to choose:
- Message type: type of Service Bus message, either Queues or Topics
- Message parameter name: the name used to identify this binding in your code
- Service Bus connection: the name of the app setting containing your Service Bus connection string. The connection string must have Send rights. Select one connection from the dropdown list.
- Queue name: The queue to which the message will be sent
For this example, I use the following data:
- Message type: I choose Service Bus Queue.
- Message parameter name: I use outputSbMsg.
- Queue name: I type message-out.
Double check and press Save.
Inspect Azure Function files
I inspect the files for this function with the tab on the right. I see two files:
- function.json
- fun.csx
It is possible to add more files such as HOST.json but I won’t explain how, look this post.
In a script function directory, there should be a companion function.json file that contains the configuration metadata for the function. A function can only have a single trigger binding, and can have multiple input/output bindings. The file looks like:
function.json
{
"bindings": [
{
"name": "myQueueItem",
"type": "serviceBusTrigger",
"direction": "in",
"queueName": "message-in",
"connection": "enricobus_RootManageSharedAccessKey_SERVICEBUS"
},
{
"type": "serviceBus",
"connection": "enricobus_RootManageSharedAccessKey_SERVICEBUS",
"name": "outputSbMsg",
"queueName": "message-out",
"direction": "out"
}
],
"disabled": false
}
For more details about this file and its schema, take a look to the Microsoft documentation. I notice the json file is easy to understand. What I care more now is the name of the bindings, myQueueItem and outputSbMsg.
I have to use those names in the signature of the function if I want to receive and send messages from and to the Service Bus. myQueueItem is already in the signature because the wizard put it there.
Finally, this code
Just for test, in my Azure Function with C# script I want to read the body of the message on message-in from Service Bus, read and convert this body and push a new json in the message-out.
First, I have to define the class for the incoming json and the result. User
is the class of the message in the message-in, NewUser
is the class for the message I want to send.
public class User
{
public string PersonName { get; set; }
public string Title { get; set; }
}
public class NewUser
{
public string Name { get; set; }
public string Title { get; set; }
}
After that, I have to change the signature of the Azure Function adding the outputSbMsg
for using the output Service Bus.
public static void Run(string myQueueItem, ILogger log,
ICollector<string> outputSbMsg)
{
}
In ILogger
the Azure Function injects the logger that we can use. What I added is ICollector<string> outputSbMsg
. This represents the output in my function. So, I can use the Service Bus to send messages.
Next, I need to import in some way Newtonsoft.Json for converting the string in a json. At the very top of the function, I add this code:
#r "Newtonsoft.Json"
using Newtonsoft.Json;
With NewtonSoft I can deserialize the message in a json and, also, I want to show in the log what the function has received from the Service Bus. I add the following code for that:
var user = JsonConvert.DeserializeObject<User>(myQueueItem);
log.LogInformation($"Body: {user}");
Nothing particular exciting: I convert the body of the message in myQueueItem in a User
object. Then, I’m going to create a NewUser
with the User
object and convert it in a string.
var newBody = new NewUser() { Name = user.PersonName, Title = user.Title };
var json = JsonConvert.SerializeObject(newBody);
Finally, I have to send a message to the message-out queue with the NewUser
in the body. For this reason, I create a small function called SendMessages
.
static void SendMessages(string message, ILogger log, ICollector<string> outputSbQueue)
{
log.LogInformation("About to iterate messages");
outputSbQueue.Add(message.ToString());
log.LogInformation($"Send to the queue: {message}");
}
Now I can run the function. And it is working!
run.csx
#r "Newtonsoft.Json"
using System;
using System.Threading.Tasks;
using Newtonsoft.Json;
public static void Run(string myQueueItem, ILogger log, ICollector<string> outputSbMsg)
{
log.LogInformation($"C# ServiceBus queue trigger function processed message: {myQueueItem}");
var user = JsonConvert.DeserializeObject<User>(myQueueItem);
log.LogInformation($"Body: {user}");
var newBody = new NewUser() { Name = user.PersonName, Title = user.Title };
var json = JsonConvert.SerializeObject(newBody);
log.LogInformation($"New body: {json}");
SendMessages(json, log, outputSbMsg);
}
static void SendMessages(string message, ILogger log, ICollector<string> outputSbQueue)
{
log.LogInformation("About to iterate messages");
outputSbQueue.Add(message.ToString());
log.LogInformation($"Send to the queue: {message}");
}
public class User
{
public string PersonName { get; set; }
public string Title { get; set; }
}
public class NewUser
{
public string Name { get; set; }
public string Title { get; set; }
}
One last look at the Monitor. If I click on a line, I have all details step by step: this is a mix between my log and Azure Function own log.
Important note: the log is not always in a chronological order. If the execution of the Azure Function is fast, the log is mixed up because it is sorted by date time.
2 thoughts on “Create Azure Function in C# Script and Service Bus”