Hybrid on premise / cloud architectures with the azure service bus relay

In this post I’ll take you through the steps involved in exposing your on-premise database and .NET code as a simple RESTful service using the service bus relay binding. I’ve also built out a an ASP.NET MVC client to consume the service.

All the source code is available here

https://github.com/aidancasey/CloudBurster

Background

Recently I’ve been delving into the world of hybrid on premise / cloud architecture. When it comes to start-up’s and companies building out new products the decision to build out a cloud solution is often be a no-brainer. But what about companies that have a significant investment in existing desktop / on-premise solutions? As much as we’d all love to, it’s not always possible to throw the baby out with the bath water and start again from scratch, enter the service bus relay binding!

I work for a large ISV that has a significant investment in an on premise line of business accounting system. The product has taken close to a decade to develop. Even with an aggressive online strategy it will take years to migrate this system to a true cloud solution. The service bus relay binding gives us the ability to quickly expose existing business logic and data to the cloud with only a small development overhead.

“I feel that Microsoft haven’t done themselves justice selling the service bus relay to the community”

Personally, I feel that Microsoft haven’t done themselves justice selling the service bus relay to the community. Its a really clever piece of technology and I’m surprised it isn’t being adopted more widely. I put the following solution together to demonstrate to the business how they could surface on-premise reports in the cloud.

Architecture

diagram – wrap existing business logic / stored procedure calls in a RESTful API exposed as a webHttpRelayBinding endpoint.

1. Creating a service namespace on Windows Azure

a) Log on to the Windows Azure Management Portal.

b) Click Service Bus, Create and enter the name of your service bus namespace (e.g “cloudburst”). For the best performance you should ensure your RESTful client is also deployed to the same Location, in this case US-West.

c) Once created click on Access Key and take note of the default issuer (“owner“) and default key(“Rd+I2mw7CaJ4pdJ7faf4yZKzI92PkYKVnE3qAA7QOIc=“). You’ll need to enter these into the app.config file in the project OnPremise.ServiceHost to enable the serviceHost to burst out to the service bus.

2. On premise service host

The Windows Azure Service Bus NuGet package pulls in all the service bus dependencies into your project. I’ve used the WebServiceHost to expose a RESTful service definition.

string serviceNamespace = "cloudburster";

Uri address = ServiceBusEnvironment.CreateServiceUri("https", serviceNamespace, "reports");

WebServiceHost host = new WebServiceHost(typeof(ReportingService), address);

host.AddDefaultEndpoints();
host.Open();

I’ve configured the relay binding to use the access key when establishing the relay binding.

3. Exposing a RESTful API

I’m exposing an API to query contact information from a legacy database. The RESTful API takes the following format:

RESOURCE URL VERBS
all contacts https://myobconnector.servicebus.windows.net/Contact/ GET
single contact https://myobconnector.servicebus.windows.net/Contact/{id} GET

The WebGet attribute  allows me to configure a JSON response type and to overlay a logical RESTful API over the WCF service contract.

    [ServiceContract(Name = "ContactContract", Namespace = "http://samples.microsoft.com/ServiceModel/Relay/")]
     public interface IContactService
    {

        [OperationContract]
        [WebGet(ResponseFormat = WebMessageFormat.Json, UriTemplate = "/{id}")]
        ContactEntity GetContact(string id);

        [OperationContract]
        [WebGet(ResponseFormat = WebMessageFormat.Json, UriTemplate = "/")]
        List GetAllContacts();

    }

4. Beware! there be dragons when running in a secured network !

Once the service host is running your data is exposed as a RESTful endpoint. For the purposes of this code sample I haven’t secured the client endpoint and I’m using a plain WebHttpBinding. This requires that the http ports 80/443 ports are open for outbound traffic on your network. If you are running in any sort of secured corporate environment you’ll likely run into firewall problems. This link will point you on the right path. This is one area where the documentation lets you down slightly. If you just read the brochures you’ll be led to believe that the relay binding can cope with NAT devices and internal firewalls but if your network administrator is doing their job properly you’ll likely need to get some firewall rules put in place.

5. consuming the API from a REST client (ASP.NET MVC)

Consuming the RESTful services is pretty straight , please refer to Cloud.App for a working solution. NewtonSoft’s free JSON serializer does a pretty reasonable job of hydrating your JSON payloads back into .NET types

        public ContactEntity Get(int Id)
        {

            string url = "https://cloudburst.servicebus.windows.net/contact/" + Id.ToString();

            using (WebClient serviceRequest = new WebClient())
            {
                string response = serviceRequest.DownloadString(new Uri(url));

                var data = JsonConvert.DeserializeObject(response);

                return data;
            }
        }

5. bench marking, performance & latency

work in progress – I’m working on a simple test harness to benchmark performance and latency in sending different sized payloads over a relay binding. From running the MVC rest client it looks like establishing the channel can be expensive (approx 1 second),  the first time but then subsequent service calls are pretty responsive. I’ll be publishing some test results soon. The plan is to build a simple ping service and instrument the timings.

Conclusion

I’m sure you’ll agree that its a pretty painless process to pick up your existing .NET code and start to expose it using the relay binding. There wasn’t a lot of examples out there so I decided to write this post and open source the code.This hybrid on-premise-cloud architecture has lots of possibilities in the real world.

It offers a pretty compelling alternative for companies that are slow to store their data in the cloud for data sovereignty issues (remember the data is still stored on premise) or for applications that need to surface some of their functionality to the cloud.

May the source be with you !

Aidan

Advertisements

4 thoughts on “Hybrid on premise / cloud architectures with the azure service bus relay

  1. Pingback: Windows Azure Action – Community Newsletter – 7th November 2012 | MSDN Blogs

  2. Hi there,

    Just wondering if you tested using json over the Azure service bus?

    I have a service which emits both xml or json. IT works perfectly for xml both in-house and via an Azure service bus / relay binding.

    However, json only works if I hit the service directly in-house. When connecting via Azure / relay binding I get a non-descript errror “the connection was forcibly closed..”.

    I am not sure how to debug it either, as normal WCF tracing doesn’t seem to work with the relay binding, I think due to the fact the relay binding establishes it’s own socket to Azure and polls for new requests (as opposed to new requests hitting IIS).

    • Hi Ross
      I’m sending JSON and I haven’t experienced any problems but I heard anecdotal stories of problems relaying JSONcontent-type messages with some client libs.
      Can you send me the code snippet and I’ll have a look.
      Also I’ve had success in the past by posting questions to Clemens Vasters direct on twitter @clemensv , he’s a super helpful guy and may be able to help

      Aidan

      • Thanks Aidan. There isn’t any specific code I could send.

        I am pretty sure in my case it is the server side framework / webHttpRelayBinding causing the problem. I am using “WCF Data Services” for this particular service. To enable json, I just tell the client library to “UseJson()” on a particular request and it works when hitting the service directly in-house. I haven’t had to code anything server side to enable Json.

        I have done some verbose tracing on the server, and I can see a difference when the client hits with Json vs Atom, which I have posted in a question here :
        http://social.msdn.microsoft.com/Forums/en-US/servbus/thread/ae0033de-d97b-4b92-9c6e-98abe5d89321

        I think it is either not possible to implement this (but might be in a future version), or there is a hook / override I can implement to allow the content-type, or ideally it can be fixed by configuration.

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