Another nugget of information that I picked up at TechEd North America is a new template that ships as part of the Azure SDK 1.7 called Worker Role with Service Bus Queue.
What got me interested in this feature is some of the work that I did last year with the AppFabric Applications (Composite Apps) CTP. I was a big fan of that CTP as it allowed you to wire-up different cloud services rather seamlessly. That CTP has been officially shut-down so I can only assume that this template was introduced to address some of the problems that the AppFabric Applications CTP sought to solve.
The Worker Role with Service Bus Queue feature works in both Visual Studio 2010 or Visual Studio 2012 RC. For this post I am going to be using 2012 RC.
I am going to use a similar scenario to the one that I used in the App Fabric Applications CTP. I will build a simple Web Page that will allow a “customer” to populate a power outage form. I will then submit this message to a Service Bus Queue and will then have a Worker role dequeue this message. For the purpose of this post I will simply write a trace event to prove that I am able to pull the message off of the queue.
Building the Application
- Create a new project by clicking on File (or is it FILE) – New Project
- Select Cloud template and then you will see a blank pane with no template able to be selected. The Azure SDK is currently built on top of .Net 4.0 not 4.5. With this in mind, we need to select .Net Framework 4
- We now need to select the Cloud Services that will make up our solution. In my scenario I am going to include an ASP.Net Web Role and a Worker Role with Service Bus Queue.
Note: we do have the opportunity to rename these artifacts by hovering over the label and then clicking on the pencil. This was a gap that existed in the old AppFabric Apps CTP. After renaming my artifacts my solution looks like this:
- I want to send and receive a strongly typed message so I am going to create a Class Library and call it CustomerEntity.
- In this project I will simply have one class called Customer with the following properties
namespace CustomerEntity
{
public class Customer
{
public string Address { get; set; }
public string City { get; set; }
public string State { get; set; }
}
}
- I will then add a reference in both the Web Project and Worker Role projects to this CustomerEntity project.
- Within the PowerOutageWeb project clear out all of the default markup in the Default.aspx page and add the following controls.
<h3>Customer Information:</h3>
Address: <asp:TextBox ID="txtAddress" runat="server"></asp:TextBox><br />
City: <asp:TextBox ID="txtCity" runat="server"></asp:TextBox> <br />
State: <asp:TextBox ID="txtState" runat="server"></asp:TextBox><br />
<asp:Button ID="btnSubmit" runat="server" Text="Submit" OnClick="btnSubmit_Click" />
<asp:Label ID="lblResult" runat="server" Text=""></asp:Label>
- Also within the PowerOutageWeb project we need to add references to the Service Bus Assembly: Microsoft.ServiceBus.dll and Runtime Serialization Assembly: System.Runtime.Serialization.dll
- We now need to provide the following include statements:
using CustomerEntity;
using Microsoft.WindowsAzure;
using Microsoft.ServiceBus;
using Microsoft.ServiceBus.Messaging;
- Next we need to provide a click event for our submit button and then include the following code:
protected void btnSubmit_Click(object sender, EventArgs e)
{
Customer cs = new Customer();
cs.Address = txtAddress.Text;
cs.City = txtCity.Text;
cs.State = txtState.Text;const string QueueName = "PowerOutageQueue";
//Get the connection string from Configuration Manager
string connectionString = CloudConfigurationManager.GetSetting("Microsoft.ServiceBus.ConnectionString");
var namespaceManager = NamespaceManager.CreateFromConnectionString(connectionString);
//Check to see if Queue exists, if it doesn’t, create it
if (!namespaceManager.QueueExists(QueueName))
{
namespaceManager.CreateQueue(QueueName);
}MessagingFactory factory = MessagingFactory.CreateFromConnectionString(connectionString);
//Create Queue CLient
QueueClient myQueueClient = factory.CreateQueueClient(QueueName);BrokeredMessage bm = new BrokeredMessage(cs);
//Send Message
myQueueClient.Send(bm);
//Update Web Page
lblResult.Text = "Message sent to queue";
}
- Another new feature in this SDK that you may have noticed is the CreateFromConnectionString method that is available to the MessagingFactory and NamespaceManager classes. This allows us to retrieve our configuration settings from our project properties page. To access the project properties right mouse click on the particular role and then select Properties. Next, click on Settings where you will find Key/Value Pairings. The name of the key that we are interested in is: Microsoft.ServiceBus.ConnectionString and our value is
Endpoint=sb://[your namespace].servicebus.windows.net;SharedSecretIssuer=owner;SharedSecretValue=[your secret]
- Since both our Web and Worker Roles will be accessing the Queue we will want to ensure that both configuration files have this entry included. This will allow our code to make a connection to our Service Bus Namespace where our Queue may be found. If we edit this property here in these locations, then we do not need to modify the Cloud.cscfg and Local.cscfg configuration files because Visual Studio will take care of this for us.
- Next we want to shift focus to the Worker Role and edit the WorkerRole.cs file. Since we are going to be dequeuing our typed CustomerService message we want to include a reference to this namespace:
using CustomerEntity;
- Something that you probably noticed when you opened up the WorkerRole.cs file is that there is already some code written for us. We can leverage most of it but can delete the code that is highlighted in red below:
- Where we deleted this code, we will want to add the following:
Customer cs = receivedMessage.GetBody<Customer>();
Trace.WriteLine(receivedMessage.SequenceNumber.ToString(), "Received Message");
Trace.WriteLine(cs.Address, "Address");
Trace.WriteLine(cs.City, "City");
Trace.WriteLine(cs.State, "State");
receivedMessage.Complete();
In this code we are going to receive a typed Customer message and then simply write out the contents of this message using the Trace utility. If we wanted to save this information to a Database, this would a good place to write that code.
-
We also want to make sure that we update the name of Queue so that it matches the name that we specified in the Web Role:
// The name of your queue
const string QueueName = "PowerOutageQueue";
Creating our Queue
We have a few options when it comes to creating our Queue that is required for this solution to work. The code in our ASP.NET Web page code-behind will take care of this for us. So for our solution to work, this method is sufficient but perhaps we want to use a design-time alternative to specify some more advanced features. In this case we do have a few options:
-
Using the http://www.windowsazure.com portal.
-
Similarly we can use the Service Bus Explorer tool that was written by Paolo Salvatori. Steef-Jan Wiggers has provided an in-depth walk through of this tool so I won’t go into more details here. http://soa-thoughts.blogspot.ca/2012/06/visual-studio-service-bus-explorer.html
-
As part of the Azure 1.7 SDK release, a Visual Studio Service Bus Explorer is now included. It is accessible from the Server Explorer view from within Visual Studio. Using this tool we can perform some functions like:
-
Creating Queues/Topics
-
Set advanced properties: Queue Size, Time to Live, Lock Duration etc
-
Send and Receive Test Messages
-
Get the current Queue Depth
-
Get our Service Bus Connection string
Any of these methods will work. As I mentioned earlier, if we do nothing, the code will take care of it for us.
Testing
We are just going to test our code locally, with the exception of our ServiceBus Queue. That is going to be created in Azure. To test our example:
-
Hit the F5 and our website should be displayed
-
Since we have our Trace statements included in our Worker Role code, we need to launch our Compute Emulator. To do this right mouse click on the Azure icon that is located in your taskbar and select Show Compute Emulator UI.
- A “Console” like window will appear. We will want to click on the ServiceBusWorker label
- Switch back to our Web Application, provide some data and click the submit button. We should see that our results label is updated to indicate that our Message sent to queue.
- If we switch back to our Compute Emulator we should discover that our message has been dequeued.
Conclusion
While the experience is a little different than that of the AppFabric Applications CTP, it is effective. Especially for developers who may not be all that familiar with “integration”. This template really provides a great starter point and allows them to wire up a Service Bus queue to their Web Application very quickly.
Good post and show one of the capabilities of the Windows Azure SDK 1.7. Sample (Walkhtrough) is easy to follow and works like charm. It is a good stepping stone to further explorer the Windows Azure SDK 1.7 Integration Capabilties.