.NET On-Premises/Cloud Hybrid Application Using Service Bus Relay
INTRODUCTION
Developing hybrid cloud applications with Windows Azure is easy using Visual Studio 2010 and the free Windows Azure SDK for .NET. This guide assumes you have no prior experience using Windows Azure. In less than 30 minutes, you will have an application that uses multiple Windows Azure resources up and running in the cloud.
You will learn:
- How to create or adapt an existing web service for consumption by a web solution.
- How to use the Windows Azure Service Bus relay to share data between a Windows Azure application and a web service hosted elsewhere.
HOW THE SERVICE BUS RELAY HELPS WITH HYBRID SOLUTIONS
Business solutions are typically composed of a combination of custom code written to tackle new and unique business requirements and existing functionality provided by solutions and systems that are already in place.
Solution architects are starting to use the cloud for easier handling of scale requirements and lower operational costs. In doing so, they find that existing service assets they’d like to leverage as building blocks for their solutions are inside the corporate firewall and out of easy reach for access by the cloud solution. Many internal services are not built or hosted in a way that they can be easily exposed at the corporate network edge.
The Service Bus relay is designed for the use-case of taking existing Windows Communication Foundation (WCF) web services and making those services securely accessible to solutions that reside outside the corporate perimeter without requiring intrusive changes to the corporate network infrastructure. Such Service Bus relay services are still hosted inside their existing environment, but they delegate listening for incoming sessions and requests to the cloud-hosted Service Bus. The Service Bus also protects those services from unauthorized access by using the Windows Azure Access Control Service.
THE SOLUTION SCENARIO
In this tutorial, you will create an ASP.NET MVC 3 website that will allow you to see a list of products on the product inventory page.

The tutorial assumes that you have product information in an existing on-premises system, and uses the Service Bus relay to reach into that system. This is simulated by a web service that is running in a simple console application and is backed by an in-memory set of products. You will be able to run this console application on your own computer and deploy the web role into Windows Azure. By doing so, you will see how the web role running in the Windows Azure datacenter will indeed call into your computer, even though your computer will almost certainly reside behind at least one firewall and a network address translation (NAT) layer.
A screenshot of the start page of the completed web application is below.

SET UP THE DEVELOPMENT ENVIRONMENT
Before you can begin developing your Windows Azure application, you need to get the tools and set-up your development environment.
-
To install the Windows Azure SDK for .NET, click the button below:
Get Tools and SDK
-
When prompted to run or save WindowsAzureSDKForNet.exe, click Run:

-
Click on Install in the installer window and proceed with the installation:

- Once the installation is complete, you will have everything necessary to start developing. The SDK includes tools that let you easily develop Windows Azure applications in Visual Studio. If you do not have Visual Studio installed, it also installs the free Visual Web Developer Express.
CREATE A WINDOWS AZURE ACCOUNT
In order to set up the Service Bus Service Namespace and later deploy your application to Windows Azure, you need an account. If you do not have one you can create a free trial account.
-
Open a web browser, and browse to the http://www.windowsazure.com. To get started with a free account, click free trial in the upper right corner and follow the steps.

- Your account is now created. You are ready to deploy your application to Windows Azure!
CREATE A SERVICE NAMESPACE
To begin using Service Bus features in Windows Azure, you must first create a service namespace. A service namespace provides a scoping container for addressing Service Bus resources within your application.
To create a service namespace:
-
Log on to the Windows Azure Management Portal.
-
In the lower left navigation pane of the Management Portal, click Service Bus, Access Control & Caching.
-
In the upper left pane of the Management Portal, click the Service Bus node, and then click the New button.

-
In the Create a new Service Namespace dialog, enter a Namespace, and then to make sure that it is unique, click the Check Availability button.

-
After making sure the namespace name is available, choose the country or region in which your namespace should be hosted (make sure you use the same country/region in which you are deploying your compute resources), and then click the Create Namespace button.
The namespace you created will then appear in the Management Portal and takes a moment to activate. Wait until the status is Active before moving on.
OBTAIN THE DEFAULT MANAGEMENT CREDENTIALS FOR THE NAMESPACE
In order to perform management operations, such as creating a queue, on the new namespace, you need to obtain the management credentials for the namespace.
-
In the left navigation pane, click the Service Bus node, to display the list of available namespaces:

-
Select the namespace you just created from the list shown:

-
The right-hand Properties pane will list the properties for the new namespace:

-
The Default Key is hidden. Click the View button to display the security credentials:

-
Make a note of the Default Issuer and the Default Key as you will use this information below to perform operations with the namespace.
CREATE AN ON-PREMISES SERVER
First, you will build a (mock) on-premises product catalog system. It will be fairly simple; you can see this as representing an actual on-premises product catalog system with a complete service surface that we’re trying to integrate.
This project will start as a Visual Studio console application.
CREATE THE PROJECT
- Using administrator privileges, launch either Microsoft Visual Studio 2010 or Microsoft Visual Web Developer Express 2010. To launch Visual Studio with administrator privileges, right-click Microsoft Visual Studio 2010 (or Microsoft Visual Web Developer Express 2010) and then click Run as administrator.
-
In Visual Studio, on the File menu, click New, and then click Project.

-
From Installed Templates, under Visual C#, click Console Application. In the Name box, type the name ProductsServer:

- Click OK to create the ProductsServer project.
- In the Solution Explorer, right-click ProductsServer, then click Properties.
-
Click the Application tab on the left, then select .NET Framework 4 from the Target framework: dropdown. Click Yes when prompted to reload the project.

- In Solution Explorer, right-click References, then click Manage NuGet Packages...
-
Search for ‘WindowsAzure.ServiceBus’ and select the Windows Azure Service Bus item. Click Install to complete the installation, then close this dialog.
Note that the required client assemblies are now referenced.
-
Add a new class for your product contract. In Solution Explorer, right click ProductsServer and click Add, then click Class.

- In the Name box, type the name ProductsContract.cs. Then click Add.
-
In ProductsContract.cs, replace the namespace definition with the following code, which defines the contract for the service:
namespace ProductsServer
{
using System.Collections.Generic;
using System.Runtime.Serialization;
using System.ServiceModel;
// Define the data contract for the service
[DataContract]
// Declare the serializable properties
public class ProductData
{
[DataMember]
public string Id { get; set; }
[DataMember]
public string Name { get; set; }
[DataMember]
public string Quantity { get; set; }
}
// Define the service contract.
[ServiceContract]
interface IProducts
{
[OperationContract]
IList<ProductData> GetProducts();
}
interface IProductsChannel : IProducts, IClientChannel
{
}
}
-
In Program.cs, replace the namespace definition with the following code, which adds the profile service and the host for it:
namespace ProductsServer
{
using System;
using System.Linq;
using System.Collections.Generic;
using System.ServiceModel;
// Implement the IProducts interface
class ProductsService : IProducts
{
// Populate array of products for display on Web site
ProductData[] products =
new []
{
new ProductData{ Id = "1", Name = "Rock",
Quantity = "1"},
new ProductData{ Id = "2", Name = "Paper",
Quantity = "3"},
new ProductData{ Id = "3", Name = "Scissors",
Quantity = "5"},
new ProductData{ Id = "4", Name = "Well",
Quantity = "2500"},
};
// Display a message in the service console application
// when the list of products is retrieved
public IList<ProductData> GetProducts()
{
Console.WriteLine("GetProducts called.");
return products;
}
}
class Program
{
// Define the Main() function in the service application
static void Main(string[] args)
{
var sh = new ServiceHost(typeof(ProductsService));
sh.Open();
Console.WriteLine("Press ENTER to close");
Console.ReadLine();
sh.Close();
}
}
}
-
In Solution Explorer, double click the app.config file to open it in the Visual Studio editor. Replace the contents of <system.ServiceModel> with the following XML code. Be sure to replace yourServiceNamespace with the name of your service namespace, and yourIssuerSecret with the key you retrieved earlier from the Windows Azure Management Portal:
<system.serviceModel>
<extensions>
<behaviorExtensions>
<add name="transportClientEndpointBehavior" type="Microsoft.ServiceBus.Configuration.TransportClientEndpointBehaviorElement, Microsoft.ServiceBus, Version=1.6.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"/>
</behaviorExtensions>
<bindingExtensions>
<add name="netTcpRelayBinding" type="Microsoft.ServiceBus.Configuration.NetTcpRelayBindingCollectionElement, Microsoft.ServiceBus, Version=1.6.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"/>
</bindingExtensions>
</extensions>
<services>
<service name="ProductsServer.ProductsService">
<endpoint address="sb://yourServiceNamespace.servicebus.windows.net/products" binding="netTcpRelayBinding" contract="ProductsServer.IProducts"
behaviorConfiguration="products"/>
</service>
</services>
<behaviors>
<endpointBehaviors>
<behavior name="products">
<transportClientEndpointBehavior>
<tokenProvider>
<sharedSecret issuerName="owner" issuerSecret="yourIssuerSecret" />
</tokenProvider>
</transportClientEndpointBehavior>
</behavior>
</endpointBehaviors>
</behaviors>
</system.serviceModel>
- Press F6 to build the application to verify the accuracy of your work so far.
CREATE AN ASP.NET MVC 3 APPLICATION
In this section you will build a simple MVC 3 application that will display data retrieved from your product service.
CREATE THE PROJECT
- Using administrator privileges, launch either Microsoft Visual Studio 2010 or Microsoft Visual Web Developer Express 2010. To launch Visual Studio with administrator privileges, right-click Microsoft Visual Studio 2010 (or Microsoft Visual Web Developer Express 2010) and then click Run as administrator. The Windows Azure compute emulator, discussed later in this guide, requires that Visual Studio be launched with administrator privileges.
- In Visual Studio, on the File menu, click New, and then click Project.
-
From Installed Templates, under Visual C#, click ASP.NET MVC 3 Web Application. Name the project ProductsPortal. Then click OK.

-
From the Select a template list, click Internet Application, then click OK.

-
In Solution Explorer, right click Models and click Add, then click Class. In the Name box, type the name Product.cs. Then click Add.

MODIFY THE WEB APPLICATION
-
In the Product.cs file in Visual Studio, replace the existing namespace definition with the following code:
// Declare properties for the products inventory
namespace ProductsPortal.Models
{
public class Product
{
public string Id { get; set; }
public string Name { get; set; }
public string Quantity { get; set; }
}
}
-
In the HomeController.cs file in Visual Studio, replace the existing namespace definition with the following code:
namespace ProductsPortal.Controllers
{
using System.Collections.Generic;
using System.Web.Mvc;
using Models;
public class HomeController : Controller
{
// Return a view of the products inventory
public ActionResult Index(string Identifier, string ProductName)
{
var products = new List<Product>
{new Product {Id = Identifier, Name = ProductName}};
return View(products);
}
}
}
-
In the Solution Explorer, expand Views\Shared:

-
Next, change the page title by replacing the header text in _Layout.cshtml with the text "LITWARE'S Products". Double-click _Layout.cshtml to open it in the Visual Studio editor.
-
Within the body tag, find the title of the page enclosed in h1 tags. Change the title text from My MVC Application to LITWARE's Products. Here is where you type this in:

-
In Solution Explorer, expand Views\Home:

-
Double-click Index.cshtml to open it in the Visual Studio editor. Replace the entire contents of the file with the following code:
@model IEnumerable<ProductsPortal.Models.Product>
@{
ViewBag.Title = "Product Inventory";
}
<h2>Product Inventory</h2>
<table>
<tr>
<th>Name</th><th>Quantity</th>
</tr>
@foreach (var item in Model)
{
<tr>
<td>@item.Name</td>
<td>@item.Quantity</td>
</tr>
}
</table>
- To verify the accuracy of your work so far, you can press F6 or Ctrl+Shift+B to build the project.
RUN YOUR APPLICATION LOCALLY
Run the application to verify that it works.
- Ensure that ProductsPortal is the active project. Right-click the project name in Solution Explorer and select Set As Startup Project
- Within Visual Studio, press F5.
-
Your application should appear running in a browser:
MAKE YOUR APPLICATION READY TO DEPLOY TO WINDOWS AZURE
Now, you will prepare your application to run in a Windows Azure hosted service. Your application already includes a Windows Azure deployment project. The deployment project contains configuration information that is needed to properly run your application in the cloud.
-
To make your application deployable to the cloud, right-click the ProductsPortal project in Solution Explorer and click Add Windows Azure Deployment Project.

- To test your application, press F5.
-
This will start the Windows Azure compute emulator. The compute emulator uses the local computer to emulate your application running in Windows Azure. You can confirm the emulator has started by looking at the system tray:

- A browser will still display your application running locally, and it will look and function the same way it did when you ran it earlier as a regular ASP.NET MVC 3 application.
PUT THE PIECES TOGETHER
The next step is to hook up the on-premises products server with the ASP.NET MVC3 application.
-
If it is not already open, in Visual Studio re-open the ProductsPortal project you created in the “Creating an ASP.NET MVC 3 Application” section.
-
Similar to the step in the “Create an On-Premises Server” section, add the NuGet package to the project References. In Solution Explorer, right-click References, then click Manage NuGet Packages.
-
Search for "WindowsAzure.ServiceBus" and select the Windows Azure Service Bus item. Then complete the installation and close this dialog.
-
In Solution Explorer, right-click the ProductsPortal project, then click Add, then Existing Item.
-
Navigate to the ProductsContract.cs file from the ProductsServer console project. Click to highlight ProductsContract.cs. Click the down arrow next to Add, then click Add as Link.

-
Within the ProductsPortal project, under the Controllers directory open the HomeController.cs file. Replace the namespace definition with the following code. Be sure to replace yourServiceNamespace with the name of your service namespace, and yourIssuerSecret with your key. This will allow the client to call the on-premises service, returning the result of the call.
namespace ProductsPortal.Controllers
{
using System.Linq;
using System.ServiceModel;
using System.Web.Mvc;
using Microsoft.ServiceBus;
using Models;
using ProductsServer;
public class HomeController : Controller
{
// Declare the channel factory
static ChannelFactory<IProductsChannel> channelFactory;
static HomeController()
{
// Create shared secret token credentials for authentication
channelFactory = new ChannelFactory<IProductsChannel>(new NetTcpRelayBinding(),
"sb://yourServiceNamespace.servicebus.windows.net/products");
channelFactory.Endpoint.Behaviors.Add(new TransportClientEndpointBehavior {
TokenProvider = TokenProvider.CreateSharedSecretTokenProvider(
"owner", "yourIssuerSecret") });
}
public ActionResult Index()
{
using (IProductsChannel channel = channelFactory.CreateChannel())
{
// Return a view of the products inventory
return this.View(from prod in channel.GetProducts()
select
new Product { Id = prod.Id, Name = prod.Name,
Quantity = prod.Quantity });
}
}
}
}
-
In Solution Explorer, right-click on the ProductsPortal solution, click Add, then click Existing Project.
-
Navigate to the ProductsServer project, then double-click the ProductsServer.csproj solution file to add it.
-
In Solution Explorer, right-click the ProductsPortal solution and click Properties.
-
On the left-hand side, click Startup Project. On the right-hand side, cick Multiple startup projects. Ensure that ProductsServer, ProductsPortal.Azure, and ProductsPortal appear, in that order, with Start set as the action for ProductsServer and ProductsPortal.Azure, and None set as the action for ProductsPortal. For example:

-
Still in the Properties dialog, click ProjectDependencies on the left-hand side.
-
In the Project Dependencies dropdown, click ProductsServer. Ensure that ProductsPortal is unchecked, and ProductsPortal.Azure is checked, as shown in the screenshot below. Then click OK.

RUN THE APPLICATION
-
From the File menu in Visual Studio, click Save All.
-
Press F5 to build and run the application. The on-premises server (the ProductsServer console application) should start first, then the ProductsWeb application should start in a browser window, as shown in the screenshot below. This time, you will see that the product inventory lists data retrieved from the product service on-premises system.

DEPLOY YOUR APPLICATION TO WINDOWS AZURE
-
Right-click on the ProductsPortal project in Solution Explorer and click Publish to Windows Azure.
-
The first time you publish to Windows Azure, you will first have to download credentials via the link provided in Visual Studio.
Click Sign in to download credentials:

-
Sign-in using your Live ID:

-
Save the publish profile file to a location on your hard drive where you can retrieve it:

-
Within the publish dialog, click on Import:

- Browse for and select the file that you just downloaded, then click Next.
-
Pick the Windows Azure subscription you would like to publish to:

-
7.If your subscription doesn’t already contain any hosted services, you will be asked to create one. The hosted service acts as a container for your application within your Windows Azure subscription. Enter a name that identifies your application and choose the region for which the application should be optimized. (You can expect faster loading times for users accessing it from this region.)

-
Select the hosted service you would like to publish your application to. Keep the defaults as shown below for the remaining settings. Click Next:

-
On the last page, click Publish to start the deployment process:
This will take approximately 5-7 minutes. Since this is the first time you are publishing, Windows Azure provisions a virtual machine (VM), performs security hardening, creates a Web role on the VM to host your application, deploys your code to that Web role, and finally configures the load balancer and networking so your application is available to the public.
-
While publishing is in progress you will be able to monitor the activity in the Windows Azure Activity Log window, which is typically docked to the bottom of Visual Studio or Visual Web Developer:

-
When deployment is complete, you can view your Web site by clicking the Website URL link in the monitoring window.
Your Web site depends on your on-premises server, so you must run the ProductsServer application locally for the Web site to function properly. As you perform requests on the cloud Web site, you will see requests coming into your on-premises console application, as indicated by the "GetProducts called" output displayed in the screenshot below.

STOP AND DELETE YOUR APPLICATION
After deploying your application, you may want to disable it so you can build and deploy other applications within the free 750 hours/month (31 days/month) of server time.
Windows Azure bills web role instances per hour of server time consumed. Server time is consumed once your application is deployed, even if the instances are not running and are in the stopped state. A free account includes 750 hours/month (31 days/month) of dedicated virtual machine server time for hosting these web role instances.
The following steps show you how to stop and delete your application.
-
Login to the Windows Azure Platform Management Portal, http://windows.azure.com, and click on Hosted Sevices, Storage Accounts & CDN, then Hosted Services:

-
Click Stop to temporarily suspend your application. You can start it again by clicking on Start. Click Delete to completely remove your application from Windows Azure with no ability to restore it without redeploying the application.
