Geeks With Blogs

Daemon WA:D - Windows Azure Developer

Build 2011 announced the September release of the Windows Azure Service Bus. For those of you who have just tuned in, the WA Service Bus is part of the AppFabric middleware that enables almost seamless connectivity between applications that are restricted to limited connectivity options by their firewall or custom security protocols. By leveraging the service bus one can build distributed applications on cloud or hybrid solutions featuring on-premise and cloud apps while maintaining the worthwhile security. But this isn’t an ‘Introduction to Service Bus’ blog post and I like to stick to the title of the blogs as often as I can without trying to distract myself with other stuff that is going on around me – like the dinosaur that just walked past my window – see, there I go again. Sorry. Back to the Service Bus. So, I was just exploring the shiny-new platform, and suddenly realized that there was no possible way I could NOT blog about this. Hallowed be the texts of GeeksAndTheirInternet. Here is an attempted brief summary of the new features released in Sept 2011 and the ways to go about playing with them.

Before we delve into that, wouldn’t it be more polite to outline the basic difference between the old WASB, the May 2011 CTP WASB and the Sept 2011 WASB releases? Yes it would. Lets see if I can suppress this in a single statement! The old WASB advocated only Relay Messaging capabilities while the May 2011 one boasts of relay as well as brokered messaging powers whereas the Sept 2011 release merely tweaked a couple of API’s here and there to fool the world into thinking that the AppFabric team had been productive for the past 6 months (more later). Phew! Just kidding Microsoft. Smile with tongue out   Uhhhh. What was that about the relay and brokered messaging? God! This is like the inception of differences. In Relay Messaging, a bidirectional socket is established between the on-premise service and the Service bus, post which the client can communicate with the Service bus to pass on the message. The catch here is that for effective communication both the producer and consumer need to be online throughout the communicative period. So, MS introduced brokered messaging in its May CTP, thereby providing messaging capabilities for decoupled scenarios like either the receiver or sender being offline at the same time. Here is a more elaborate differentiation.

Now that that’s behind us, lets move on to the code battlefield which is a bit more serene as compared to what that dinosaur has done to my backyard. The first thing that we need to do to avail the Azure Service Bus functionality is to create a Service Bus Namespace in the Windows Azure Portal. An Issuer Name and Issuer Key must be provided to do the same. Once that's done whip out your VS 2010.

For starters lets take a look at Relayed Messaging. Nothing much has changed here. The steps to be followed to achieve a connection between the producer and consumer are as follows:

For the sender:

1. Create the Service contract and its implementation.

2. Create the service URI based on the service namespace
Uri address = ServiceBusEnvironment.CreateServiceUri("sb", <service namespace that you provided in the portal>, <your service name>);

3. Create the credentials object for the endpoint
TransportClientEndpointBehavior sharedSecretServiceBusCredential = new TransportClientEndpointBehavior();
sharedSecretServiceBusCredential.TokenProvider = TokenProvider.CreateSharedSecretTokenProvider(<issuer name>, <issuer key>);

This is one of the changes that have been implemented in the September release. The credentials for the service bus are provided using a special TokenProvider class instead of being provided directly to the API. This is closer to the actual connection implementation mechanism of the Service Bus wherein the access tokens required to access the SB are provided by the Access Control Service (ACS) of the AppFabric.           
           
4. Create the service host at that address
ServiceHost host = new ServiceHost(typeof(<service name>), address);

5. Create the ServiceRegistrySettings behavior for the endpoint
IEndpointBehavior serviceRegistrySettings = new ServiceRegistrySettings(DiscoveryType.Public);

The Service Bus maintains a registry for all the endpoints that connect to it. Any guesses as to what its called? Oh, Right. The ServiceRegistrySettings can specify whether the endpoint should be private or public. If the DiscoveryType is public the endpoint saved to the ServiceRegistry would be published to its ATOM feed.  

6. Add the Service Bus credentials to all endpoints specified in configuration
foreach (ServiceEndpoint endpoint in host.Description.Endpoints)
{
endpoint.Behaviors.Add(serviceRegistrySettings);
endpoint.Behaviors.Add(sharedSecretServiceBusCredential);
}
           
7. Open the service
host.Open();

For Receiver:

1. Establish a channel interface for your services                                                                   

public IYourChannel : <Your Service Contract>, IClientChannel                                                         

{}

2. Create the service URI based on the service namespace
Uri address = ServiceBusEnvironment.CreateServiceUri("sb", <service namespace that you provided in the portal>, <your service name>);           

3. Create the credentials object for the endpoint
TransportClientEndpointBehavior sharedSecretServiceBusCredential = new TransportClientEndpointBehavior();
sharedSecretServiceBusCredential.TokenProvider = TokenProvider.CreateSharedSecretTokenProvider(<issuer name>, <issuer key>);

4. Create the channel factory loading the configuration
ChannelFactory<IYourChannel> channelFactory = new ChannelFactory<IYourChannel>("RelayEndpoint", new EndpointAddress(serviceUri));                                                                  

5. Apply the Service Bus credentials 
channelFactory.Endpoint.Behaviors.Add(sharedSecretServiceBusCredential);

6. Create and open the client channel 
IYourChannel channel = channelFactory.CreateChannel(); 
channel.Open();

7. Once the channel is opened, the service is ready to be consumed.

Now lets look at the Brokered Messaging – the relatively new guy on the block. As mentioned earlier Brokered Messaging relies on the fact that both the producer and consumer need NOT be online at the same time for the successful transfer of messages. Advantages? Asynchronous messaging capabilities since the sender can issue messages without waiting for a response from the receiver using Queues model. Improved Load Balancing as multiple subscribers can be involved for a single Topic using the Topic-Subscription model (expect elaboration). 

Let us see how we can implement the Brokered Messaging using the Queue Model:

For Sender:

1. Create Tokens for the sender using TokenProvider class.
TokenProvider tkp = TokenProvider.CreateSharedSecretKeyTokenProvider(IssuerName, IssuerKey);
2. Create Service Bus URI
Uri serviceUri = ServiceBusEnvironment.CreateServiceUri("sb", Sender.ServiceNamespace, string.Empty);
3. Initialize NamespaceManager
NamespaceManager namespaceClient = new NamespaceManager(serviceUri, tkp); [NamespaceManager is another change that has been introduced in the September release.]
4. Using this NamespaceManager create a Queue
namespaceClient.CreateQueue("<any queue name>");
5. Create a MessagingFactory
MessagingFactory factory = MessagingFactory.Create(serviceUri, credentials);
6. Using this factory create a QueueClient
QueueClient myQueueClient = factory.CreateQueueClient("<same queue name as specified above>");
7. Create Brokered Message(s) which is to be sent
BrokeredMessage message = new BrokeredMessage("<message body>");
message.MessageId = "<message ID>";
8. Send the brokered message using QueueClient created above
myQueueClient.Send(message);
[If there are more than one brokered messages create a list of them and while iterating through the list send each of them via the Queue]

For Receiver:

1. Create Tokens for the sender using TokenProvider class.
TokenProvider tkp = TokenProvider.CreateSharedSecretKeyTokenProvider(IssuerName, IssuerKey);
2. Create Service Bus URI
Uri serviceUri = ServiceBusEnvironment.CreateServiceUri("sb", Sender.ServiceNamespace, string.Empty);
3. Initialize NamespaceManager
NamespaceManager namespaceClient = new NamespaceManager(serviceUri, tkp);
4. Using this NamespaceManager retrieve the queue that was created by the sender
QueueDescription queueDescription = namespaceClient.GetQueue("<same queue name as given by sender>");
5. Create a MessagingFactory
MessagingFactory factory = MessagingFactory.Create(serviceUri, credentials);
6. Using this factory create a QueueClient
QueueClient myQueueClient = factory.CreateQueueClient("<same queue name>", ReceiveMode.PeekLock);
[ReciveMode specifies the way in which the message should be handled]
7. Create Brokered Message(s) which is to be recieved and receive the same
BrokeredMessage message = myQueueClient.Receive(TimeSpan.FromSeconds(5));
[If there are more than one messages to be recieved, iterate for the queueDescription.MessageCount and then receive each message]

Now, to look into the Topic-Subscription model of communication

For Sender:

1. Create Tokens for the sender using TokenProvider class.
TokenProvider tkp = TokenProvider.CreateSharedSecretKeyTokenProvider(IssuerName, IssuerKey);
2. Create Service Bus URI
Uri serviceUri = ServiceBusEnvironment.CreateServiceUri("sb", Sender.ServiceNamespace, string.Empty);
3. Initialize NamespaceManager
NamespaceManager namespaceClient = new NamespaceManager(serviceUri, tkp);
4. Using this NamespaceManager create a Topic
TopicDescription myTopic = = namespaceClient.CreateTopic("<any topic name>");
5. Create Subscriptions using NamespaceManager
SubscriptionDescription myAuditSubscription = namespaceManager.CreateSubscription(myTopic.Path, "AuditSubscription");
SubscriptionDescription myAgentSubscription = namespaceManager.CreateSubscription(myTopic.Path, "AgentSubscription");
6. Create a MessagingFactory
MessagingFactory factory = MessagingFactory.Create(serviceUri, credentials);
7. Using this factory create a TopicClient
TopicClient myTopicClient = factory.CreateTopicClient(myTopic.Path);
8. Create Brokered Message(s) which is to be sent
BrokeredMessage message = new BrokeredMessage("<message body>");
message.MessageId = "<message ID>";
9. Send the brokered message using TopicClient created above
myTopicClient.Send(message);
[If there are more than one brokered messages create a list of them and while iterating through the list send each of them via the Topic]

For Receiver:

1. Create Tokens for the sender using TokenProvider class.
TokenProvider tkp = TokenProvider.CreateSharedSecretKeyTokenProvider(IssuerName, IssuerKey);
2. Create Service Bus URI
Uri serviceUri = ServiceBusEnvironment.CreateServiceUri("sb", Sender.ServiceNamespace, string.Empty);
3. Initialize NamespaceManager
NamespaceManager namespaceClient = new NamespaceManager(serviceUri, tkp);
4. Create a MessagingFactory
MessagingFactory factory = MessagingFactory.Create(serviceUri, credentials);
5. Create SubscriptionClients for each subscription created by the sender
SubscriptionClient agentSubscriptionClient = factory.CreateSubscriptionClient("<Topic name as specified by sender>", "AgentSubscription", ReceiveMode.PeekLock);
SubscriptionClient auditSubscriptionClient = factory.CreateSubscriptionClient("<Topic name as specified by sender>", "AuditSubscription", ReceiveMode.ReceiveAndDelete);
5. Create Brokered Message(s) which is to be recieved and receive the same
BrokeredMessage messageAgent = agentSubscriptionClient.Receive(TimeSpan.FromSeconds(5))
BrokeredMessage messageAudit = auditSubscriptionClient.Receive(TimeSpan.FromSeconds(5))
[For more than one messages you can iterate a while loop until the message recieved is null]

So, we can create as many subscriptions for a single topic. And these subscriptions can be availed by the clients at any point of time.

A more comprehensive and real life example would be the Retail web service provided by Akite which uses this new topic-sub broker model of to sync POS clients with the headquarters -http://www.akite.net/en/PosNet.aspx. This example is also outlined in the Clemens Vaster’s Build 2011 video.

Well, this just about covers the WASB Sept 2011 release. You can download the samples from the codeplex site. Alright, now if you will excuse me, I have to kick some dino butt!! Ma, where my shotgun at?

Posted on Wednesday, December 7, 2011 1:49 PM | Back to top


Comments on this post: Anyone catch the Sept 2011 WA Service Bus flick?

No comments posted yet.
Your comment:
 (will show your gravatar)


Copyright © Daemon | Powered by: GeeksWithBlogs.net