Bhavya

Code -> Break -> Fix -> Blog

Implementing Content Based Router Pattern using Windows Azure Service Bus

2 Comments

As covered in the blog by Stephen Kaufman,

This pattern requires the the router system inspect each message and direct that message to different channels based on data elements contained in the message.  The routing should be configurable to route based on different fields, the existence or non-existence of a specific value and the routing rules should be easily maintained as there are typically frequent changes

This pattern can be implement in Azure using a Service Bus Topic.  There are two parts that need to be implemented to put this pattern into use.  The first is that subscriptions need to be setup and the second is that a message needs to be created with the specific properties populated to match the subscription.”

Content Based Routing

Below is the implementation for the same.

Fields required:


// TODO : Set the IssueName, IssueKey and ServicebusNamespace variable with 
// proper values before running the code.
 static string IssueName = string.Empty;
 static string IssueKey = string.Empty;
 static string ServicebusNamespace = string.Empty;

 static NamespaceManager namespaceManager;
 static MessagingFactory messagingFactory;
 static TopicDescription topicDescription;

Person Class:


/// <summary>
/// Class Person
/// </summary>
[Serializable]
public class Person
{
/// <summary>
/// Initializes a new instance of the <see cref="Person" /> class.
/// </summary>
public Person()
{
}

/// <summary>
/// Initializes a new instance of the <see cref="Person" /> class.
/// </summary>
/// <param name="name">The name.</param>
/// <param name="gender">The gender.</param>
/// <param name="age">The age.</param>
public Person(string name, string gender, int age)
{
this.Name = name;
this.Gender = gender;
this.Age = age;
}

/// <summary>
/// Gets or sets the name.
/// </summary>
/// <value>The name.</value>
public string Name
{
get;
set;
}

/// <summary>
/// Gets or sets the gender.
/// </summary>
/// <value>The gender.</value>
public string Gender
{
get;
set;
}

/// <summary>
/// Gets or sets the age.
/// </summary>
/// <value>The age.</value>
public int Age
{
get;
set;
}

/// <summary>
/// Returns a <see cref="System.String" /> that represents this instance.
/// </summary>
/// <returns>A <see cref="System.String" /> that represents this instance.</returns>
public override string ToString()
{
return Name;
}
}

Utilities:


static TopicDescription CreateTopic(string topicName)
 {
 TopicDescription topicDescription = new TopicDescription(topicName);
 topicDescription.EnableFilteringMessagesBeforePublishing = true;

//Check if already exists.
 if (namespaceManager.TopicExists(topicDescription.Path))
 {
 namespaceManager.DeleteTopic(topicDescription.Path);
 }

Console.WriteLine("Creating Topic : " + topicName);
 return namespaceManager.CreateTopic(topicDescription);
 }

static void CreateSubscription(Dictionary<string, string> subscription)
 {
if (null != topicDescription)
 {
 foreach (KeyValuePair<string, string> item in subscription)
 {
 if (string.IsNullOrEmpty(item.Value))
 {
 namespaceManager.CreateSubscription(topicDescription.Path, item.Key);
 }
 else
 {
 namespaceManager.CreateSubscription(topicDescription.Path, item.Key, new SqlFilter(item.Value));
 }
 }
 }
 }

static void SendMessage(Person message, KeyValuePair<string, object> item)
 {
 TopicClient topicClient = messagingFactory.CreateTopicClient(topicDescription.Path);

BrokeredMessage brokeredMessage = new BrokeredMessage(message);

if (null != item.Key && null != item.Value)
 {
 brokeredMessage.Properties.Add(item);
 }

topicClient.Send(brokeredMessage);
 }

static Person ReceiveMessage(string subscriptionName)
 {
 SubscriptionClient subscriptionClient = messagingFactory.CreateSubscriptionClient(topicDescription.Path, subscriptionName, ReceiveMode.ReceiveAndDelete);

BrokeredMessage receivedMessage = subscriptionClient.Receive(new TimeSpan(0, 0, 5));

return (null != receivedMessage) ? receivedMessage.GetBody<Person>() : null;
 }

The main implementation:


static void Main(string[] args)
{
#region User details check
if (string.IsNullOrEmpty(IssueName) || string.IsNullOrEmpty(IssueKey) || string.IsNullOrEmpty(ServicebusNamespace))
{
Console.ForegroundColor = ConsoleColor.Red;
Console.WriteLine("One of the below 3 values are missing...");
Console.WriteLine("ServicebusNamespace");
Console.WriteLine("IssuerName");
Console.WriteLine("IssuerKey");
Console.ResetColor();
Console.WriteLine("\nPress any key to receive the message...");
Console.ReadKey();
return;
}
#endregion

#region Create Topic & Subscription
Uri serviceBusUri = ServiceBusEnvironment.CreateServiceUri("sb", ServicebusNamespace, string.Empty);
TokenProvider tokenProvider = TokenProvider.CreateSharedSecretTokenProvider(IssueName, IssueKey);

namespaceManager = new NamespaceManager(serviceBusUri, tokenProvider);
messagingFactory = MessagingFactory.Create(serviceBusUri, tokenProvider);

topicDescription = CreateTopic("ContentBasedRouterTopic");

Dictionary<string, string> subscriptionItems = new Dictionary<string, string>();
subscriptionItems.Add("Male", "Gender='Male'");
subscriptionItems.Add("Female", "Gender='Female'");

CreateSubscription(subscriptionItems);
#endregion

#region Create Messages
List<Person> personList = new List<Person>();
personList.Add(new Person("Alan", "Male", 55));
personList.Add(new Person("May", "Female", 45));
personList.Add(new Person("Siri", "Female", 49));
personList.Add(new Person("Sam", "Male", 51));
personList.Add(new Person("Nick", "Male", 60));
#endregion

#region Send Message
foreach (Person item in personList)
{
KeyValuePair<string, object> property = new KeyValuePair<string, object>("Gender", item.Gender);
SendMessage(item, property);
Console.WriteLine("Item " + item.Name + " sent to " + topicDescription.Path);
}
#endregion

Console.WriteLine("Press any key to receive the message...");
Console.ReadKey();

#region Receive Message
Console.WriteLine("Female list:");
while (true)
{
var female = ReceiveMessage("Female");
if (null != female)
{
Console.WriteLine(female.ToString());
}
else
{
break;
}
}

Console.WriteLine("\n\nMale list:");
while (true)
{
var male = ReceiveMessage("Male");
if (null != male)
{
Console.WriteLine(male.ToString());
}
else
{
break;
}
}
#endregion

Console.WriteLine("\nPress any key to exit...");
Console.ReadKey();
}

~BS

Advertisements

2 thoughts on “Implementing Content Based Router Pattern using Windows Azure Service Bus

  1. Pingback: Bhavya

  2. Pingback: Implementing Message Filter Pattern using Windows Azure Service Bus | Bhavya

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s