-->

05/05/2021

Azure Service Bus - Queues and Topics - Part 2

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 the earlier article, we have seen how we can use Azure Service Bus Queues for integration of serverless application environment. Now we will explore Service Bus Topic and how it will be used.


We have already created Azure service Bus in earlier article, you can reffer the link provoided at the top for details.

Step 1: Creating Azure Service Bus Topic

Go to azure portal, and open the Service Bus we created "DemoAZSvcBus". In left pannel under "Entities", click "Topics".

Create a new Topic, name it "CorpAnnouncements".
Once Topic is created, Open it. Now in left pannel, under "Entities", click on "Subscriptions".
Create a new Subscription , name it "NZSubscription".
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 Topic 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 CorpAnnouncementSender
CD .\CorpAnnouncementSender\
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 CorpAnnouncementSender
{
    class Program
    {
        const string ServiceBusConnectionString = "Service Bus Connecttion string goes here";
        const string TopicName = "corpannouncements";
        static ITopicClient topicClient;

        static void Main(string[] args)
        {
            Console.WriteLine("Sending a message to the corporate annpuncements topic...");
            SendCorpAnnouncementAsync().GetAwaiter().GetResult();
            Console.WriteLine("Message was sent successfully.");
        }

        static async Task SendCorpAnnouncementAsync()
        {
            topicClient = new TopicClient(ServiceBusConnectionString, TopicName);

            try
            {
                string messageBody = $"Organization X going public IPO in Jan 2022";
                var message = new Message(Encoding.UTF8.GetBytes(messageBody));
                Console.WriteLine($"Sending message: {messageBody}");
                await topicClient.SendAsync(message);
            }
            catch (Exception exception)
            {
                Console.WriteLine($"{DateTime.Now} :: Exception: {exception.Message}");
            }

            await topicClient.CloseAsync();
        }
    }
}
Save program.cs file, open shell and run 
dotnet build
and now navigate to "ServiceBus" folder, run below command.
dotnet run -p CorpAnnouncementSender
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 "CorpAnnouncements" Topic.
You can see that the message we sent has been pused to all Subscriptions. In our case "NZSubscription".


 Unlike Queue, the messages in Topics will be tunnel to subscriptions and they will stay there for the subscribers to consume. They stay there until message timeout.

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

dotnet new console -n CorpAnnouncementReceiver
CD .\CorpAnnouncementReceiver\
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 CorpAnnouncementReceiver
{
   class Program
    {

        const string ServiceBusConnectionString = "Service Bus Connection string here";
const string TopicName = "corpannouncements"; const string SubscriptionName = "NZSubscription"; static ISubscriptionClient subscriptionClient; static void Main(string[] args) { MainAsync().GetAwaiter().GetResult(); } static async Task MainAsync() { subscriptionClient = new SubscriptionClient(ServiceBusConnectionString, TopicName, SubscriptionName); Console.WriteLine("======================================================"); Console.WriteLine("Press ENTER key to exit after receiving all the messages."); Console.WriteLine("======================================================"); RegisterMessageHandler(); Console.Read(); await subscriptionClient.CloseAsync(); } static void RegisterMessageHandler() { var messageHandlerOptions = new MessageHandlerOptions(ExceptionReceivedHandler) { MaxConcurrentCalls = 1, AutoComplete = false }; subscriptionClient.RegisterMessageHandler(ProcessMessagesAsync, messageHandlerOptions); } static async Task ProcessMessagesAsync(Message message, CancellationToken token) { Console.WriteLine($"Received corp announcement message: SequenceNumber:{message.SystemProperties.SequenceNumber} Body:{Encoding.UTF8.GetString(message.Body)}"); //Uncomment below line if you want to delete the message from subscription //await subscriptionClient.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.

The Message in subcription will not be deleted unless you delete them exclusively using your code.
I have commented the line of code which deletes the message. Your programatic choice.
Lets check azure portal is the message still there even after received by the subscriber components.


Typically your messages will not be a text message like mine, but in realtime, it will be a JSON message possibley with a data object embedded into it.

I will Attach the source code for all 4 projects here. Download
 

No comments:

Post a Comment