Creating Azure Service Bus Queues And Sending Messages To Queues

Service bus

The reason behind the use of service buses is to decouple applications and services. As we need to decouple applications and services, the data can be transferred between different applications and services using messages. The messages can be sent to the queue on the service bus.

Creating a service bus queue

Most of you might be aware of how to create a service bus queue in Azure, but let me review.

Way 1

Log in to the Azure portal and create a service bus, namespace. Once that is done, you can see the queues and topics on the left-hand side. Once we click on queue, we can click on Add and create a queue from the Azure portal.

Microsoft Azure

Way 2

If we have service Bus Explorer, we can log in to the service Bus Explorer with the connection string of the service bus and right click on the queue, and create the queue. We can have the settings enabled for the queue.

Service bus explorer

Some of the useful settings are

Enable sessions

This allows a guarantee of processing the messages sequentially. This follows the pattern of FIFO.

Enabled dead lettering

This allows the messages to be in dead letters if the receiver fails to receive the messages in time. The message will not expire in a dead letter until and unless it is viewed.

Configuring the Service Bus queue in the development environment.

Install the Microsoft.Azure.ServiceBus NuGet package to the project where you are setting up the message queue.

First, let's create a class for configuring the QueueClient and have a generic method for sending the message to the queue.

using Azure.ServiceBus;
using Microsoft.Azure.ServiceBus;
using System;
using System.Collections.Generic;
using System.Text;
namespace AzureFunctionsUnitTesting.Service_Bus
{
    public class QueueSender : IQueueSender
    {
        static Dictionary<string, IQueueClient> _queueClients;
        public QueueSender(string connectionString, List<Queue> queues)
        {
            _queueClients = new Dictionary<string, IQueueClient>();
            if (!string.IsNullOrEmpty(connectionString))
            {
                foreach (Queue queue in queues)
                {
                    string queueId = queue.Id;
                    string queueName = queue.Name;
                    _queueClients.Add(queueId, new QueueClient(connectionString, queueName));
                }
            }
        }
        public async void SendMessageAsync(string queueName, string messageItem, string messageLabel = null, Dictionary<string, object> messageProperties = null)
        {
            try
            {
                Message message = BuildMessage(messageItem, messageLabel, messageProperties);
                await _queueClients[queueName].SendAsync(message);
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }
        private Message BuildMessage(string messageItem, string messageLabel, Dictionary<string, object> messageProperties)
        {
            Message message = new Message(Encoding.UTF8.GetBytes(messageItem));
            message.UserProperties["TimeStampUTC"] = DateTime.UtcNow;
            message.Label = messageLabel;
            if (messageProperties != null)
            {
                foreach (var messageProperty in messageProperties)
                {
                    message.UserProperties[messageProperty.Key] = messageProperty.Value;
                }
            }
            return message;
        }
    }
}

I have configured the QueueClient in the constructor so that it will be loaded whenever we inject the class through dependency injection.

I have created a method (BuildMessage) to build the message which will be sent to the queue. Message is a class of Azure service bus Nugets.

Once the message is built, we will send the message through the queue client we have injected by creating a Method(SendMessageAsync). The queue client will take care of sending the message to the service bus queue.

Calling the configured queue sender for sending our custom message

I have created a class and injected the Queue sender interface. I have created a method and will be calling the sendMessageAsync Method to send the message.

using AzureFunctionsUnitTesting.Interfaces;
using AzureFunctionsUnitTesting.Service_Bus;
using Microsoft.Azure.ServiceBus;
namespace AzureFunctionsUnitTesting
{
    public class MessageQueueSender : IMessageQueueSender
    {
        private readonly IQueueSender _queueSender;
        public MessageQueueSender(IQueueSender queueSender)
        {
            _queueSender = queueSender;
        }
        public void SendMessageToQueue()
        {
            Message message = new Message();
            message.SessionId = "session1";
            string queueName = "testqueue";
            string content = "Hello Service Bus Queue";
            _queueSender.SendMessageAsync(queueName, content);
        }
    }
}

Unit testing for sending messages to the service bus queue

We can test if the configuration for setting up the service bus queue is correct or not by creating a unit test case.

I have created a unit test case where I will be mocking up all the required configurations and will be calling the SendMessageToQueue method and checking the count of messages in the queue as an assertion.

using AzureFunctionsUnitTesting.Service_Bus;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Moq;
using System.Collections.Generic;
namespace AzureFunctionsUnitTesting.Tests
{
    [TestClass]
    public class MessageQueueSenderTests
    {
        public readonly Mock<IQueueSender> _queueSender;
        public List<string> _queueMessages;
        public MessageQueueSenderTests()
        {
            _queueSender = new Mock<IQueueSender>();
            _queueMessages = new List<string>();
            _queueSender.Setup(x => x.SendMessageAsync(It.IsAny<string>(), It.IsAny<string>(), It.IsAny<string>(), It.IsAny<Dictionary<string, object>>()))
                       .Callback<string, string, string, Dictionary<string, object>>(async (a, b, d, e) =>
                       {
                           _queueMessages.Add($"{a}");
                       });
        }
        [TestInitialize()]
        public virtual void Initialise() { }
        [TestMethod]
        public void SendMessageToQueue()
        {
            MessageQueueSender messageQueueSender = new MessageQueueSender(_queueSender.Object);
            messageQueueSender.SendMessageToQueue();
            // Check if message is delivered to queue
            Assert.AreEqual(1, _queueMessages.Count, "Message sending failed");
        }
    }
}

I hope this article is helpful for everyone and please post your questions with anything related to service bus queue and topics. I have attached the solution file for reference.