Dead Letter Queue (DLQ) Messages Handling In Azure Topic & Subscription

Dead Letter Queue (DLQ) Messages Handling In Azure Topic & Subscription

DownLoad Project:AzureTopic&Subscription

Azure service bus Queue and topic  subscription provide addition sub-queue called dead-letter queue (DLQ).All expired message move to dead letter queue from queue and subscriptions for further investigations and processing.

Dead letter queues are the safest bet when we are using Azure Service Bus. If for whatever reason message could not be processed by a receiver, we could move that such message to dead letter queue. This would mean, we may need manual intervention to determine why the message is not getting processed. Listener for the dead letter would just need to facilitate that by logging the message to some database or to a log file so that the user can take a look at that later.

No additional efforts  are required to create dead-letter sub queue for Queue and Subscription,dead letter subqueue created automatically when main entities either azure service bus queue or topics/subscription are created.

t23.jpg

Every  topic/subscription have dead letter queue and name ends with $deadletterqueue.

Naming Convention of DLQ:

<TopicName>/Subscriptions/<YourSubscriptionName>/$DeadLetterQueue

TopicName: it will be any qualified topic name created in azure server bus.

SubscrpitonName: It will be subscription name that is create under azure topic.

Let’s assume we have create a topic named as “OrderTopic” and one subscription named as “EastSubscrpption” is also created in “orderTopic” then below will be dead letter queue path.

OrderTopic/Subscriptions/EastSubscription/$DeadLetterQueue

In C# we can find this path at run time by using azure service bus sdk.there is a method “FormatDeadLetterPath” used to extract full path of DLQ.

C# Code


var Dlqpath = SubscriptionClient.FormatDeadLetterPath("OrderTopic", "EastSubscription");

Reading DLQ messages:

DLQ messages can be read by azure subscription client,that interact with dead letter sub queue for specific subscription.”$deadletterqueue” need to add at end with subscription name to create subscription client and start reading the message from sub queue.


 var DLQPath = "/$DeadLetterQueue";

SubscriptionClient sClient = SubscriptionClient.CreateFromConnectionString(TopicConfigurations.Namespace, topicName, description.Name + DLQPath);

Dead letter messages can be inspected by azure service bus explorer.Every subscription has two parts (X,X) with subscription name in service bus explorer. First part represents active messages count in subscriptions and second part represents dead letter message count. we will see this in details with example.

 

t25.jpg

Enterprise applications rely on processing every order and message that gets placed in a system. To make sure your application doesn’t miss a message when integrating with service bus, you must be sure to code for DLQs.

Let’s take a look with example,assume we have azure topic named as “orderTopic” with two subscriptions (EastSubscription & NorthSubscrpiton).There is a message publisher utility that publish some order details continuously to azure topic (OrderTopic) but at the same time receiver utility is not running or not receiving messages properly due to some reasons.To ensure reliable message delivery we have set up a separate utility that actively monitor these dead letter messages and process them or re-enque/redirect some other place.

To test above use case,we will run only publisher and dead letter message processing utility so that messages not processed by any receiver and move to Deadletter sub queue and later same messages processed by DLQ message processing utility.

Let’s capture information before executing publisher utility. below you can see (0,0) shows with subscription name that means there is no active message and no dead letter message in server bus subscriptions.

t26.jpg

Now run the publisher utility and see 4 order details publish to azure topic and verify same thing with azure service bus explorer.

t27.jpg

In below snapshot we can see (2,0) with both subscription names that means there are 2 messages in active state and no message move to dead letter sub-queue. As we have set message expiry time to 1 minute so after one minute these message got expired and move to DLQ. Wait for 1 min to expiry these messages.

t28.jpg

After one minute these message got expired as there we have not runs the receiver utility and then these messages move to DLQ and (0,2) will show with both subscription names that means there are no messages in active state and 2 messages in dead letter queue.See below snapshot that is taken after 1 min.

t29.jpg

Now execute Dead letter processing utility that reads DLQ messages and processed it,

t30.jpg

Once all messages read from DLQ by the utility then subscriptions dead letter sub-queue clears and dead letter message count reset to 0.

t31.jpg

All code together for DLQ message processor:


using System;
using Common;
using Microsoft.ServiceBus;
using Microsoft.ServiceBus.Messaging;

namespace DeadLetterQueueProcessor
{
 class DlqMessageProcessor
 {
 static NamespaceManager nameSpaceManager;

static void Main(string[] args)
 {
 nameSpaceManager = NamespaceManager.CreateFromConnectionString(TopicConfigurations.Namespace);
 ReadDLQMessages("OrderTopic");
 Console.ReadLine();
 }

public static void ReadDLQMessages(String topicName)
 {
 //Path of Deadletter queue,evey subscripiton has deadletter queue
 var DLQPath = "/$DeadLetterQueue";

foreach (SubscriptionDescription description in nameSpaceManager.GetSubscriptions(topicName))
 {
 var Dlqpath = SubscriptionClient.FormatDeadLetterPath(topicName, description.Name);

Console.ForegroundColor = ConsoleColor.Yellow;
 Console.WriteLine("=======================================");
 Console.WriteLine("---Order Recieving From DeadLetter Queue [" + Dlqpath + "]---");
 Console.WriteLine("=======================================");

//here susbcription client is created with deadletter queue
 SubscriptionClient sClient = SubscriptionClient.CreateFromConnectionString(TopicConfigurations.Namespace, topicName, description.Name + DLQPath);
 while (true)
 {
 BrokeredMessage bmessgage = sClient.Receive(TimeSpan.FromSeconds(1));
 if (bmessgage != null)
 {
 Order order = bmessgage.GetBody();
 Console.ForegroundColor = ConsoleColor.Red;
 Console.Write(" Request Recieved, ProductName: {0},Zone : {1},CustomerName: {2},DeliveryAddress: {3} \n\n",
 order.ProductName, order.Zone, order.CustomerName, order.DeliveryAddress);

Console.ForegroundColor = ConsoleColor.Yellow;

bmessgage.Complete();
 }
 else
 {
 break;
 } 
 }

sClient.Close();
 }
 }
 }
}

Sample project structure

t32.jpg

When working with the Azure Service Bus, having knowledge of the dead-letter queue can save you a lot of time and it is best practice to place dead letter queue with enterprise integration projects.

Read more about Azure service bus explorer here

 

 

Advertisements
Filtered Subscriptions with Azure Service Bus Topics

Filtered Subscriptions with Azure Service Bus Topics

Download Complete Project: AzureTopicSubscriptionfilters

Azure Service Bus topics allow multiple subscribers to receive the same messages. So if we post an message to a topic, then one subscriber might send an order confirmation email, while another subscriber to the same event might handle payments.

The way this is done is that you create multiple “subscriptions” on the topic, and then you can listen for messages on those subscriptions, in the same way that you would listen for messages on a regular queue.

But what if your subscription is only interested in a subset of messages that are posted to that topic? Well, this is where filters come in. When we create a subscription, we can specify the properties of the messages we are interested in.

What is Rule Filter

As the filter’s type implies, it allows for defining a SQL92 standard expression in its constructor that will govern what messages are filtered out.

There are following types of filters :

  1.  SQLFilter – The filter that a number of other filters derive from such TrueFilter and FalseFilter
  2. TrueFilter – This is the default filter provided through the default rule that is generated for us when a rule or filter is not explicitly provided when creating a subscription.  Ultimately, this generates the SQL92 expression 1=1 and subscribes to receive all messages of the associated topic.
  3. FalseFilter – The antithesis of a TrueFilter that generates a SQL92 expression of 1=0; a subscription with this filter will never subscript to any messages of the associated topic.
  4. CorrelationFilter – This filter subscribes the subscription to all messages of a particular CorrelationId property of the message.
    Note:Be aware that the comparison values in your SQL expression are case-sensitive, while the property names are not (e.g. “Zone= ‘East’” is not the same as “zone= ‘east’”)

In earlier post we have seen how default rules works and how same message broadcast to all subscriptions. Now we will see how custom rules works and how specific message subscribe by the subscriber with custom filtering rules.

Example:

Let’s consider order processing system where some orders need to publish to topics and some region wise subscriptions are also setup in the topic.Instead of broadcast all orders to all subscriptions,only region wise orders will broadcast to specific subscriptions.

In our case orders belongs to two regions (East and North) and two subscriptions are setup to subscribe these messages,i.e East Subscription only receives east region orders and north subscription receives north region orders.

T18

Adding rules to the subscriptions:

Subscriptions are not limited to one rule however. We can add additional rules to an existing subscription.


public static void CreateTopicUnderServiceBus()
{
var TopicName = "OrderTopic";
string[] arrSubsription = new string[] { "NorthSubscription", "EastSubscription" };

//Create Topic
if (!nameSpaceManager.TopicExists(TopicName))
{
nameSpaceManager.CreateTopic(TopicName);
}

//CreateSubscription
foreach (string subsription in arrSubsription)
{
if (!nameSpaceManager.SubscriptionExists(TopicName, subsription))
{
SubscriptionDescription subscriptionDesc = new SubscriptionDescription(TopicName, subsription)
{
EnableDeadLetteringOnMessageExpiration = true,
EnableDeadLetteringOnFilterEvaluationExceptions = true,
DefaultMessageTimeToLive = TimeSpan.FromMinutes(5),
LockDuration = TimeSpan.FromSeconds(60),
};
var zone = subsription.Replace("Subscription", "");

// Rule for EastSubsrciption to recieve those message that belongs to specific zones.
RuleDescription ruleDescForSubscriptions = new RuleDescription("ZoneFilter", new SqlFilter("Zone='" + zone + "'"));

nameSpaceManager.CreateSubscription(subscriptionDesc,ruleDescForSubscriptions);
var ss = SubscriptionClient.FormatDeadLetterPath(TopicName, subsription);
}
}

}

Here RuleDescription class is used to create a filter rules. Above code will add two filter rules  in  subscriptions which are  “Zone=’East’ and “Zone=’North'”.

An additional properties also need to send with broker message along with creating filter rules.


public static void PublishOrder(TopicClient topicClient, Order order)
{
String Displaytext = string.Format("Order : orderId={0},customerName={1},ProductName={2},DeliveryAddress={3},Zone={4} " +
" Sent To Topic Successfully \n\n",
order.OrderId, order.CustomerName, order.ProductName, order.DeliveryAddress, order.Zone);

//Create broker message for order
BrokeredMessage brokerMessage = new BrokeredMessage(order);
brokerMessage.Properties.Add("Zone", order.Zone);
topicClient.Send(brokerMessage);
Console.Write(Displaytext);

}

See the “Zone” property set in broker message.

Complete Code For Message Publisher:


using Common;
using Microsoft.ServiceBus;
using Microsoft.ServiceBus.Messaging;
using System;
using System.Threading;

namespace MessageSender
{
class Publisher
{
static NamespaceManager nameSpaceManager;

static void Main()
{
nameSpaceManager = NamespaceManager.CreateFromConnectionString(TopicConfigurations.Namespace);
CreateTopicUnderServiceBus();

TopicClient tClient = TopicClient.CreateFromConnectionString(TopicConfigurations.Namespace, "OrderTopic");

Console.ForegroundColor = ConsoleColor.Yellow;
Console.WriteLine("======================================================");
Console.WriteLine("-----------Publishing Start---------------------------");
Console.WriteLine("======================================================");

Console.ForegroundColor = ConsoleColor.Green;
PublishOrder(tClient, new Order()
{
OrderId = 5656,
CustomerName = "Vivek Jadon",
ProductName = "Iphone6",
DeliveryAddress = "MG Road Gurgaon",
Zone = "East"
});
PublishOrder(tClient, new Order()
{
OrderId = 5657,
CustomerName = "Rakesh ",
ProductName = "Samsung S8",
DeliveryAddress = "12/3 Ring Road Delhi",
Zone = "East",
});
PublishOrder(tClient, new Order()
{
OrderId = 5658,
CustomerName = "Prakash Nayal",
ProductName = "OnePlus 5T",
DeliveryAddress = "12/3 Ring Road Delhi",
Zone = "North",
});
PublishOrder(tClient, new Order()
{
OrderId = 5659,
CustomerName = "Gautom Anand",
ProductName = "Samsung S8",
DeliveryAddress = "12/3 Ring Road Delhi",
Zone = "North",
});

Console.ForegroundColor = ConsoleColor.Yellow;
Console.WriteLine("-----------Publishing End---------------------------");
Console.ReadLine();
}

public static void CreateTopicUnderServiceBus()
{
var TopicName = "OrderTopic";
string[] arrSubsription = new string[] { "NorthSubscription", "EastSubscription" };

//Create Topic
if (!nameSpaceManager.TopicExists(TopicName))
{
nameSpaceManager.CreateTopic(TopicName);
}

//CreateSubscription
foreach (string subsription in arrSubsription)
{
if (!nameSpaceManager.SubscriptionExists(TopicName, subsription))
{
SubscriptionDescription subscriptionDesc = new SubscriptionDescription(TopicName, subsription)
{
EnableDeadLetteringOnMessageExpiration = true,
EnableDeadLetteringOnFilterEvaluationExceptions = true,
DefaultMessageTimeToLive = TimeSpan.FromMinutes(5),
LockDuration = TimeSpan.FromSeconds(60),
};
var zone = subsription.Replace("Subscription", "");

// Rule for EastSubsrciption to recieve those message that belongs to specific zones.
RuleDescription ruleDescForSubscriptions = new RuleDescription("ZoneFilter", new SqlFilter("Zone='" + zone + "'"));

nameSpaceManager.CreateSubscription(subscriptionDesc,ruleDescForSubscriptions);
var ss = SubscriptionClient.FormatDeadLetterPath(TopicName, subsription);
}
}

}
public static void PublishOrder(TopicClient topicClient, Order order)
{
String Displaytext = string.Format("Order : orderId={0},customerName={1},ProductName={2},DeliveryAddress={3},Zone={4} " +
" Sent To Topic Successfully \n\n",
order.OrderId, order.CustomerName, order.ProductName, order.DeliveryAddress, order.Zone);

//Create broker message for order
BrokeredMessage brokerMessage = new BrokeredMessage(order);
brokerMessage.Properties.Add("Zone", order.Zone);
topicClient.Send(brokerMessage);
Console.Write(Displaytext);

}
}
}

Complete code for message receiver:


using Common;
using Microsoft.ServiceBus;
using Microsoft.ServiceBus.Messaging;
using System;

namespace MessageReciever
{
class Subscriber
{
static NamespaceManager nameSpaceManager;

static void Main()
{
nameSpaceManager = NamespaceManager.CreateFromConnectionString(TopicConfigurations.Namespace);
ReadMessageFromSubscription("OrderTopic");
Console.ReadLine();
}

public static void ReadMessageFromSubscription(string TopicName)
{

foreach (SubscriptionDescription description in nameSpaceManager.GetSubscriptions(TopicName))
{
SubscriptionClient sClient = SubscriptionClient.CreateFromConnectionString(TopicConfigurations.Namespace,"OrderTopic", description.Name);

Console.ForegroundColor = ConsoleColor.Yellow;
Console.WriteLine("=======================================");
Console.WriteLine("---Order Recieving From [" + description.Name + "]---");
Console.WriteLine("=======================================");
while (true)
{
BrokeredMessage bmessgage = sClient.Receive(TimeSpan.FromSeconds(2));

if (bmessgage != null)
{
Order order = bmessgage.GetBody<Order>();
Console.ForegroundColor = ConsoleColor.Green;
Console.Write(" Request Recieved, ProductName: {0},Zone : {1},CustomerName: {2},DeliveryAddress: {3} \n\n",
order.ProductName, order.Zone, order.CustomerName, order.DeliveryAddress);

Console.ForegroundColor = ConsoleColor.Yellow;

bmessgage.Complete();
}
else
{
break;
}
}
sClient.Close();
}

}
}
}

Once the messages are sent to Topic, the subscriber should start showing the appropriate message count. In our case if we send a message with East and North as Zone, as per the rules set, EastSubscriber should receive only 2 message which is East region messages and Northsubscriber should receive also 2 messages as north region has 2  messages.

Let’s run complete application and then talk about the output.

Here we can see there are 4 orders publish to order topic,there are 2 orders that belongs to East region and 2 orders for North reagion.Important thing that this time all 4 messages has not broadcast to both subscriptions because we have created 2 filters rule for both regions.

t19

Take a look on azure portal , here we can see each subscriptions received 2 messages according to their filter rule.

t20.jpg

Now see topic & subscription details with azure service bus explorer.We can see custom filters with name “ZoneFilter” has created in both subscripiton with filter rule.

t21.jpg

Of course, you can get away without using filters at all, if you just set up plain subscriptions and only respond to messages of interest in your handlers. But using the filters will reduce network traffic and save unnecessary work processing messages that aren’t of interest.

Read more about service bus explorer :Link

Microsoft Azure: Service Bus Topic & Subscription With Default Filtering Rule.

Microsoft Azure: Service Bus Topic & Subscription With Default Filtering Rule.

Download complete project : AzureTopicSubscription

In contrast to queues, in which each message is processed by a single consumer,topics and subscriptions provide a one-to-many form of communication, in publish and subscribe pattern.

Useful for scaling to very large numbers of recipients, each published message is made available to each subscription registered with the topic. Messages are sent to a topic (and delivered to one or more associated subscriptions) and received from subscriptions. Filter rules can also be set on a per-subscription basis.

t1

Default Filters in topic:

When the subscriptions were created in the topic, no filter was defined for them, and they subscribe to all messages that are sent to the topic.

True Filter  is the default filter provided through the default rule that is generated for us when a rule or filter is not explicitly provided when creating a subscription.  Ultimately, this generates the SQL92 expression 1=1 and subscribes to receive all messages of the associated topic.

Default Rule Name:  “$Default”

Default Filter Name : “True Filter”

Default Sql Expression=”Filter=1=1″

There are multiple ways to create topic and subscription in Azure service bus.

  1. Azure Portal
  2. PowerShell
  3. language specific SDK. ex: C# azure sdk

1. Create Topic & Subscription Through Azure Portal

login to azure portal and choose “New” option from left menu.

t2

once you navigate to service bus navigation pane then fill all required information like service bus name (should be unique across the global),choose appropriate price tire ,Resource group (new or existing created group) and location.

t3

Once you press create button,your newly created service bus list down in your resource list and you can go inside it for further configuration.

for this demonstration i have created service bus with name “Rakesh-ServiceBus”.As we can see below there are two options  available ,one for Queue and another is Topic.

t4

Click on “Topic option” from top menu and enter few details like topic name,topic max size( default size is 1 GB) and define number of days to message live etc.

t5

2. Create Topic & Subscription Through C# Azure Sdk:

let’s say you have already created service bus in azure account and now you have to create topics and subscriptions through C#.

Here’s a simple example of how to achieve this with C# programming.

Creating Topics:

Topic creation is straight forward approach and below are the code to create .


nameSpaceManager = NamespaceManager.CreateFromConnectionString(TopicConfigurations.Namespace);

var TopicName = "OrderTopic";
//Create Topic
if (!nameSpaceManager.TopicExists(TopicName))
{
nameSpaceManager.CreateTopic(TopicName);
}

Creating Subscriptions:

Here two subscriptions (NorthSubscription and East Subscription) will created under the topic name “OrderTopic” .


//CreateSubscription
if (!nameSpaceManager.SubscriptionExists(TopicName, "NorthSubscription"))
{
nameSpaceManager.CreateSubscription(TopicName, "NorthSubscription");
}
if (!nameSpaceManager.SubscriptionExists(topicPath: TopicName, name: "EastSubscription"))
{
nameSpaceManager.CreateSubscription(TopicName, "EastSubscription");
}

Deleting a Topic:


var TopicName = "OrderTopic";
//Create Topic
if (nameSpaceManager.TopicExists(TopicName))
{
nameSpaceManager.DeleteTopic(TopicName);
}

Deleting a Subscription:


//Delete a subscription
if (nameSpaceManager.SubscriptionExists(TopicName, "NorthSubscription"))
{
nameSpaceManager.DeleteSubscription(TopicName, "NorthSubscription");
}

Putting all together with publisher scenario:

Taking simple order processing example where publisher send the order details to the specific topic and there are multiple subscriber (receiver) that reads order details from the topic.

As i already mentioned that default filter 1=1 applied to topic and subscription then same message will sent to both subscription because we have not defined any specific filter (will see in next article in details).

t6

Sending Order Details to Topic:

A console application  named as “MessageSender” is created to send order details to azure topic.Below are the code to send message. I will show code in parts but you can download complete sample project.


using Common;
using Microsoft.ServiceBus;
using Microsoft.ServiceBus.Messaging;
using System;
using System.Threading;

namespace MessageSender
{
class Publisher
{
static NamespaceManager nameSpaceManager;

static void Main()
{
Thread.Sleep(1000);
nameSpaceManager = NamespaceManager.CreateFromConnectionString(TopicConfigurations.Namespace);
CreateTopicUnderServiceBus();

TopicClient tClient = TopicClient.CreateFromConnectionString(TopicConfigurations.Namespace, "OrderTopic");

Console.ForegroundColor = ConsoleColor.Yellow;
Console.WriteLine("======================================================");
Console.WriteLine("-----------Publishing Start---------------------------");
Console.WriteLine("======================================================");

Console.ForegroundColor = ConsoleColor.Green;
PublishOrder(tClient, new Order()
{
OrderId = 5656,
CustomerName = "Vivek Jadon",
ProductName = "Iphone6",
DeliveryAddress = "MG Road Gurgaon",
Zone = "East"
});
PublishOrder(tClient, new Order()
{
OrderId = 5657,
CustomerName = "Rakesh ",
ProductName = "Samsung S8",
DeliveryAddress = "12/3 Ring Road Delhi",
Zone = "East",
});
PublishOrder(tClient, new Order()
{
OrderId = 5658,
CustomerName = "Prakash Nayal",
ProductName = "OnePlus 5T",
DeliveryAddress = "12/3 Ring Road Delhi",
Zone = "North",
});
PublishOrder(tClient, new Order()
{
OrderId = 5659,
CustomerName = "Gautom Anand",
ProductName = "Samsung S8",
DeliveryAddress = "12/3 Ring Road Delhi",
Zone = "North",
});

Console.ForegroundColor = ConsoleColor.Yellow;
Console.WriteLine("-----------Publishing End---------------------------");
Console.ReadLine();
}

public static void CreateTopicUnderServiceBus()
{
var TopicName = "OrderTopic";
string[] arrSubsription = new string[] { "NorthSubscription", "EastSubscription" };

//Create Topic
if (!nameSpaceManager.TopicExists(TopicName))
{
nameSpaceManager.CreateTopic(TopicName);
}

//CreateSubscription
foreach (string subsription in arrSubsription)
{
if (!nameSpaceManager.SubscriptionExists(TopicName, subsription))
{
SubscriptionDescription subscriptionDesc = new SubscriptionDescription(TopicName, subsription)
{
EnableDeadLetteringOnMessageExpiration = true,
EnableDeadLetteringOnFilterEvaluationExceptions = true,
DefaultMessageTimeToLive = TimeSpan.FromMinutes(5),
LockDuration = TimeSpan.FromSeconds(30)
};

nameSpaceManager.CreateSubscription(subscriptionDesc);
}
}
}

public static void PublishOrder(TopicClient topicClient, Order order)
{

String Displaytext = string.Format("Order : orderId={0},customerName={1},ProductName={2},DeliveryAddress={3},Zone={4} " +
" Sent To Topic Successfully \n\n",
order.OrderId, order.CustomerName, order.ProductName, order.DeliveryAddress, order.Zone);

//Create broker message for order
BrokeredMessage brokerMessage = new BrokeredMessage(order);
topicClient.Send(brokerMessage);
Console.Write(Displaytext);

}

}
}

Let’s run the message sender console application only (not executing any messaging receiving application) and see what type of resources and activity happens on azure portal.

Few things captured before executing sender application,you will see there is no topic and subscription created in service bus “Rakesh-Service Bus”.

T10.jpg

Now Execute message sender application and  see what happens.

  • As you see in below snapshot ,order details successfully publish to azure topic.

t11.jpg

  • go to azure portal and you find an topic with name “OrderTopic” with two subscription “EastSubscription” and “NorthSusbcription” created successfully and one thing also noticed that both subscriptions received both 4 order details because we have created subscriptions without and filter rules and if you not create any rule then default rule (1=1) applied.

t12.jpg

let’s see more in-depth by using azure service bus explorer.Service explorer provide rich user interface to know more details about messages as compare to azure portal.we can see message state weather in active state or in dead letter queue.Create and modify filter rules.

T17.jpg

 

Subscribe message from topic:

subscribers never directly connected with azure topics.Any subscriber wants to receive the message from topic then first they have to subscribe any subscription under the same topic and read messages from these subscriptions.

Putting all together with Subscriber scenario:

Again taking console application and install necessary nuget packages to support azure service bus SDK.


using Common;
using Microsoft.ServiceBus;
using Microsoft.ServiceBus.Messaging;
using System;

namespace MessageReciever
{
class Subscriber
{
static NamespaceManager nameSpaceManager;

static void Main()
{
nameSpaceManager = NamespaceManager.CreateFromConnectionString(TopicConfigurations.Namespace);
ReadMessageFromSubscription("OrderTopic");
}

public static void ReadMessageFromSubscription(string TopicName)
{
Console.ForegroundColor = ConsoleColor.Yellow;
Console.WriteLine("======================================================");
Console.WriteLine("-----------Order Recieving Start---------------------------");
Console.WriteLine("======================================================");
foreach (SubscriptionDescription description in nameSpaceManager.GetSubscriptions(TopicName))
{
SubscriptionClient sClient = SubscriptionClient.CreateFromConnectionString(TopicConfigurations.Namespace,"OrderTopic", description.Name);
while (true)
{
BrokeredMessage bmessgage = sClient.Receive();
if (bmessgage != null)
{
Order order = bmessgage.GetBody<order>();
Console.ForegroundColor = ConsoleColor.Green;
Console.Write(" Request Recieved, ProductName: {0},Zone : {1},CustomerName: {2},DeliveryAddress: {3} \n\n",
order.ProductName, order.Zone,order.CustomerName,order.DeliveryAddress);

Console.ForegroundColor = ConsoleColor.Yellow;
bmessgage.Complete();
}
}
}
Console.WriteLine("-----------Publishing End---------------------------");
}
}
}

Now execute sender and  receiver applications together and you find that sender start publishing messages to topic and receiver application start reading those message from both subscriptions.

T15.jpg

 

We’ve learned that two of the most powerful features in Topics and Subscriptions is the ability to distribute messages to multiple interested parties (subscriptions) and those parties are able to filter out what messages they are specifically interested in.  There is still a good bit to cover on the topic of Azure Service Bus.

A full code example attached with this and you can find link at top of the blog.