-->

05/05/2021

Azure Service Bus - Queues and Topics - Part 1

Use Case: Organization X has a large-scale distributed serverless application environment. There are some azure components that sends a private messages which need to be accessed only once by other components using RoleBasedAccessControls. There are some messages that need to Fan-Out(one-to-many) to large number of systems, where sender doesnt need to know the receiver's details. The message should stay until time out, for receiving components to consume when they are avilable.


In this article, we will learn what is Azure Service Bus, Service Bus Queues, Service Bus Topics, How to access them programatically using .Net. Once you do it practically following my instrctions, you will understand the theory behind it. So follow me.

Why Azure Service Bus?
Service Bus is a message broker which handles Integrity, Security, Communication protocols of Messages at Enterprise level.

It has both Queues and Topics for message transmission. We will see each of it using .Net Console apps as both sender and receiver.

Use Service Bus queues if you:

  • Need an At-Most-Once delivery guarantee.
  • Need a FIFO guarantee.
  • Need to group messages into transactions.
  • Want to receive messages without polling the queue.
  • Need to provide a role-based access model to the queues.
  • Need to handle messages larger than 64 KB but less than 256 KB.
  • Queue size will not grow larger than 80 GB.
  • Want to publish and consume batches of messages.

Step 1: Create Azure Service Bus 

Go to Azure portal, always start with a resource group. I named it "DefaultRG".
Next Create a Service Bus, i named it "DemoAZSvcBus".
Once Service Bus is created, in the left pannel, under "Entities", click on Queues.
Create a new Queue, name it "CorpMessages".

This is the queue we will use to send the private messages to other intended receiving systems.

For all the following steps, you need to install Azure CLI, .Net, Powershell 7, VS Code on your dev machines.

Step 2: Get Connection string for Azure Service Bus Namespace.
It costs money to create a storage account in azure, especially when you are using free tier or experimenting on your own. Thats why i use Azure CLI on Powershell 7.

Open Power shell and run below commands. After first command, you may need to authenticate to Azure console via browser, then close the browser. Make sure you check update Resource group name and Service Bus name in your command.
az login 
az servicebus namespace authorization-rule keys list --resource-group DefaultRG --name RootManageSharedAccessKey --query primaryConnectionString --output tsv --namespace-name DemoAZSvcBus
This command will bring back the connection string which you need to keep it aside for following steps. It will be in this formatt.

Step 3: Create CorpMessageSender (Service Bus Queue Message Sender)
Lets start with a folder "ServiceBus". All the projects from here on will be created inside it.
Open Shell, navigate to "ServiceBus" folder. Run below commands one after another.

dotnet new console -n CorpMessageSender
CD .\CorpMessageSender\
dotnet add package Microsoft.Azure.ServiceBus
Code .

These command will create a new .Net Console application, then install Azure Service Bus package and open the project in VS Code.

Copy below code to program.cs. You may need to write similar code in your azure component which is sending out secured, transcation bound messages to other systems.

using System;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.Azure.ServiceBus;

namespace CorpMessageSender
{
    class Program
    {
        const string ServiceBusConnectionString = "Service Bus Connection string here";
        const string QueueName = "corpmessages";
        static IQueueClient queueClient;

        static void Main(string[] args)
        {
            Console.WriteLine("Sending a message to the Corporate Messages queue...");
            SendCorpMessageAsync().GetAwaiter().GetResult();
            Console.WriteLine("Message was sent successfully.");
        }

        static async Task SendCorpMessageAsync()
        {
	    //Creating Service Bus Queue client 
            queueClient = new QueueClient(ServiceBusConnectionString, QueueName);

            try
            {
                string messageBody = $"Private message from CEO: Q1 Results: $1bn Profit";
                var message = new Message(Encoding.UTF8.GetBytes(messageBody));
                Console.WriteLine($"Sending message: {messageBody}");
		//Sending the private message to Service bus Queue
                await queueClient.SendAsync(message);
            }
            catch (Exception exception)
            {
                Console.WriteLine($"{DateTime.Now} :: Exception: {exception.Message}");
            }
			
            await queueClient.CloseAsync();
        }
    }
}
Save program.cs file, open shell and run 
dotnet build
and now navigate to "ServiceBus" folder, run below command.
dotnet run -p CorpMessageSender
You will see the result like this.

Lets explore Azure portal to see if the message has arrived.
Go to Service Bus "DemoAZSvcBus", select Queues and open "CorpMessages" Queue.


Step 4: Create CorpMessageReceiver (Service Bus Queue Message Receiver)
Open Shell, navigate to "ServiceBus" folder. Run below commands.

dotnet new console -n CorpMessageSender
CD .\CorpMessageSender\
dotnet add package Microsoft.Azure.ServiceBus
Code .
Now copy below code in program.cs file.
using System;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.Azure.ServiceBus;

namespace CorpMessageReceiver
{
   class Program
    {

        const string ServiceBusConnectionString = "Service Bus Connection string here";
const string QueueName = "corpmessages"; static IQueueClient queueClient; static void Main(string[] args) { ReceiveCorpMessageAsync().GetAwaiter().GetResult(); } static async Task ReceiveCorpMessageAsync() { queueClient = new QueueClient(ServiceBusConnectionString, QueueName); Console.WriteLine("======================================================"); Console.WriteLine("Press ENTER key to exit after receiving all the messages."); Console.WriteLine("======================================================"); RegisterMessageHandler(); Console.Read(); await queueClient.CloseAsync(); } static void RegisterMessageHandler() { var messageHandlerOptions = new MessageHandlerOptions(ExceptionReceivedHandler) { MaxConcurrentCalls = 1, AutoComplete = false }; queueClient.RegisterMessageHandler(ProcessMessagesAsync, messageHandlerOptions); } static async Task ProcessMessagesAsync(Message message, CancellationToken token) { Console.WriteLine($"Received message: SequenceNumber:{message.SystemProperties.SequenceNumber} Body:{Encoding.UTF8.GetString(message.Body)}"); await queueClient.CompleteAsync(message.SystemProperties.LockToken); } static Task ExceptionReceivedHandler(ExceptionReceivedEventArgs exceptionReceivedEventArgs) { Console.WriteLine($"Message handler encountered an exception {exceptionReceivedEventArgs.Exception}."); var context = exceptionReceivedEventArgs.ExceptionReceivedContext; Console.WriteLine("Exception context for troubleshooting:"); Console.WriteLine($"- Endpoint: {context.Endpoint}"); Console.WriteLine($"- Entity Path: {context.EntityPath}"); Console.WriteLine($"- Executing Action: {context.Action}"); return Task.CompletedTask; } } }
Save program.cs file, open shell and run 
dotnet build
and now navigate to "ServiceBus" folder, run below command.
dotnet run -p CorpMessageReceiverr
You will see the result like this.

Message received, and this message will be deleted from Service Bus Queue, since the intended receiver have consumed the message.
You may need to write similar code in your receiving component.


We have finished Azure Service Bus Queues. In nest article Part-2, we will programatically send and recieve messages to Azure Service Topics and observe thier behaviour.



No comments:

Post a Comment