Nick's .NET Travels

Continually looking for the yellow brick road so I can catch me a wizard....

Windows Azure, Microsoft .NET Services – Working with Routers (I)

[This post is based on the Windows Azure Tools for Microsoft Visual Studio July 2009 CTP]

The last couple of posts have covered working with .NET Services queues (parts I, II and III). Now we move on to cover routers. Like I did previously I’ll cover creating and working with routers, before we move on to working with them in conjunction with queues.

To create a router you send a Http Post to the url that you want the router to reside at, supplying a RouterPolicy entry.  The url has to belong to your solution url, so for example https://blogsample.servicebus.windows.net/myrouter. An example RouterPolicy would look like the following:

<entry xmlns="http://www.w3.org/2005/Atom">
  <RouterPolicy xmlns="http://schemas.microsoft.com/netservices/2009/05/servicebus/connect">
    <Discoverability>Public</Discoverability>
    <ExpirationInstant>2009-09-01T05:18:06.9677603Z</ExpirationInstant>
    <TransportProtection>None</TransportProtection>
    <MaxSubscribers>2147483647</MaxSubscribers>
    <MessageDistribution>AllSubscribers</MessageDistribution>
  </RouterPolicy>
</entry>

Now to send this:

private static string HttpCreateRouter(string token, string router)
{
    string routerUri = "
https://blogsample.servicebus.windows.net/" + router;

    HttpWebRequest request = (HttpWebRequest)WebRequest.Create(routerUri);
    request.Headers.Add("X-MS-Identity-Token", token);
    request.Method = "POST";
    request.ContentType = "application/atom+xml;type=entry;charset=utf-8";

    XElement content = new XElement(XName.Get("entry", "http://www.w3.org/2005/Atom"),
                            ServicesElement("RouterPolicy",
                                ServicesElement("Discoverability","Public"),
                                ServicesElement("ExpirationInstant", DateTime.UtcNow.AddMinutes(30)),
                                ServicesElement("TransportProtection", "None"),
                                ServicesElement("MaxSubscribers", "2147483647"),
                                ServicesElement("MessageDistribution", "AllSubscribers")));

    using (var requestStream = request.GetRequestStream())
    using (var writer = new System.IO.StreamWriter(requestStream))
    {
            writer.Write(content);
            writer.Flush();
    }

    using (var response = request.GetResponse())
    using (var responseStream = response.GetResponseStream())
    using (var reader = new StreamReader(responseStream))
    {
        return reader.ReadToEnd();
    }
}

private static XElement ServicesElement(string element, params object[] content)
{
    return new XElement(XName.Get(element, "
http://schemas.microsoft.com/netservices/2009/05/servicebus/connect"), content);
}

A note of warning… for some reason the order of the xml elements for the RouterPolicy does matter.  Submitting them in a different order appears to cause a duplicate RouterPolicy entry. This will most likely be resolved for the production release but in the meantime if you are seeing weird RouterPolicy entries being returned this may be the cause.

When you run this code the response (assuming it is successful) should be a 201, Created. Subsequent Posts to this url will result in a 202, Accepted – note however this does not update or alter the router. In addition to the 201 status, the Post also returns information about the created router:

<entry xmlns="http://www.w3.org/2005/Atom">
   <id>uuid:0ae5cae9-6f3f-4fcc-8377-83f34c106124;id=1546</id>
   <title type="text">myrouter</title>
   <updated>2009-09-01T04:48:41Z</updated>
   <link rel="alternate" href="https://blogsample.servicebus.windows.net/myrouter/"/>
   <link rel="self" href="https://blogsample.servicebus.windows.net/myrouter/!(router)"/>
   <link rel="subscriptions" href="https://blogsample.servicebus.windows.net/myrouter/!(router/subscriptions)"/>
   <RouterPolicy xmlns="http://schemas.microsoft.com/netservices/2009/05/servicebus/connect" xmlns:i="http://www.w3.org/2001/XMLSchema-instance">
      <Discoverability>Public</Discoverability>
      <ExpirationInstant>2009-09-01T05:18:06.9677603Z</ExpirationInstant>
      <TransportProtection>None</TransportProtection>
      <MaxMessageSize>61440</MaxMessageSize>
      <BufferTimeout>PT10S</BufferTimeout>
      <MaxBufferLength>0</MaxBufferLength>
      <MaxBufferCapacity>0</MaxBufferCapacity>
      <MaxSubscribers>50</MaxSubscribers>
      <MessageDistribution>AllSubscribers</MessageDistribution>
      <PushDeliveryRetries>3</PushDeliveryRetries>
      <PushDeliveryTimeout>PT30S</PushDeliveryTimeout>
   </RouterPolicy>
</entry>

As with when you create a queue, the response contains a number of links.

alternate – This is the url you will use when placing new messages on the router. 

self – This is the url you will now use to update, renew and delete the router.

subscriptions – This is the url that you use when subscribing to the router.

As you can see the process of creating a router is roughly the same as for a queue, with the only big difference being the RouterPolicy you need to supply.  Querying, renewing and deleting a router is done exactly the same way as for a queue, with the exception you need to use the self url returned when you create the router (which ends in (router) instead of (queue)).

Comments are closed