Windows Azure, Microsoft .NET Services – Working with Queues (II)

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

In my previous post, Working With Queues (I), I showed how you can create a queue using a Http Post message against the Windows Azure, Microsoft .NET Services. Now that we’ve created a queue, let’s look at how you can query, renew and delete your queue.

To query for the existence of a queue (and remember that when a queue expires it is no longer available) you just need to send a Http Get to the parent url. So for example if you had a queue https://blogsample.servicebus.windows.net/application1/myqueue you would send the Get to https://blogsample.servicebus.windows.net/application1. In our case because the queue we created previously was https://blogsample.servicebus.windows.net/myqueue we need to send the Http Get to https://blogsample.servicebus.windows.net/.

public static string GetServicesListing(string token)
{
    string listingUri = "
https://blogsample.servicebus.windows.net/";

    HttpWebRequest request = (HttpWebRequest)WebRequest.Create(listingUri);
    request.Headers.Add("X-MS-Identity-Token", token);
    request.Method = "GET";
    request.ContentLength = 0;

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

When you run this code the response (assuming it is successful) should be a 200, Ok. In addition to the 200 status, the Get also returns information about services available under the url that the Get was sent to:

<feed >https://blogsample.servicebus.windows.net/", false);
    http.setRequestHeader("X-MS-Identity-Token", token);
    http.onreadystatechange = function() {
        if (http.readyState == 4 && http.status == 200) {
            output = http.responseText;
            // Do something with the service list
        }
    }
    http.send();
}

As you will have noticed, queues have an ExpirationInstant which is the instance when your queue will expire and be unavailable.  In most cases this is not that desirable so you will want to periodically renew it.  You do this by sending a Http Put to the self link address (ie https://blogsample.servicebus.windows.net/myqueue/!(queue)).  Instead of just sending a new QueuePolicy you need to get the appropriate entry out of the service feed (retrieved using the Http Get we just discussed), update the QueuePolicy with the new expiration instant and then submit the whole entry in the content of the Http Put.

 

public static string RenewQueue(string token, string queue)
{
    string listing = GetServicesListing(token);
    XElement feed = XElement.Parse(listing);
    var content = (from entry in feed.Descendants(XName.Get("entry", "
http://www.w3.org/2005/Atom"))
                  where entry.Element(XName.Get("title", "http://www.w3.org/2005/Atom")).Value == queue
                  select entry).FirstOrDefault();
    if (content == null)
    {
        return null;
    }

    // Update the expiration time
    content.Descendants(ServicesElementName("ExpirationInstant")).FirstOrDefault().SetValue(DateTime.UtcNow.AddMinutes(30));

    string queueUri = "https://blogsample.servicebus.windows.net/" + queue + "/!(queue)";

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

    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 XName ServicesElementName(string element)
{
    return XName.Get(element, "
http://schemas.microsoft.com/netservices/2009/05/servicebus/connect");
}

Here you should expect a 200, Ok response with the updated entry being returned in the response (you can use this to double-check the queue attributes were updated correctly). And now the same but in javascript:

function httpRenewQueue(token, queue, getResponse) {
    xmlDoc = new ActiveXObject("Microsoft.XMLDOM");
    xmlDoc.async = "false";
    xmlDoc.loadXML(getResponse);

    var entry;
    var entries = xmlDoc.getElementsByTagName("title");
    var i;
    for (i = 0; i < entries.length; i++) {
        if (entries[i].childNodes[0].nodeValue == queue) {
            entry = entries[i].parentNode;
        }
    }
    entry.getElementsByTagName("ExpirationInstant")[0].childNodes[0].nodeValue="2009-08-31T03:56:25.2951184Z";

    http = new XMLHttpRequest();
    http.open("PUT", "
https://blogsample.servicebus.windows.net/" + queue + "/!(queue)", false);
    http.setRequestHeader("X-MS-Identity-Token", token);
    http.setRequestHeader("Content-type", "application/atom+xml;type=entry;charset=utf-8");
    http.onreadystatechange = function() {
    if (http.readyState == 4 && http.status == 200)
        {
            var output = http.responseText;
            // Do something…
        }
    }
    http.send(entry.xml);
}

Note that in these examples there is NO error handling and the expiration is hard coded – you will need to adjust this otherwise you will get a 500 Internal Server error if the expiration is in the past.

Ok, so finally you need to be able to delete your queue.  This is done by sending a Http Delete message to the Self link, as follows:

public static string DeleteQueue(string token, string queue)
{
    string queueUri = "
https://blogsample.servicebus.windows.net/" + queue + "/!(queue)";

    HttpWebRequest request = (HttpWebRequest)WebRequest.Create(queueUri);
    request.Headers.Add("X-MS-Identity-Token", token);
    request.Method = "DELETE";
    request.ContentLength = 0;
    using (var response = request.GetResponse())
    {
        return (response as HttpWebResponse).StatusCode.ToString();
    }
}

One important point here is that you must set the ContentLength to 0.  You should expect a 200, Ok if the queue is deleted.  For both the renew (ie Http Put) and delete (ie Http Delete) if the queue has expired, you can expect a 404, Not found exception to be raised.  Lastly, let’s see the delete in javascript:

function httpDeleteQueue(token, queue) {
    http = new XMLHttpRequest();
    http.open("DELETE", "
https://blogsample.servicebus.windows.net/" + queue +"/!(queue)", false);
    http.setRequestHeader("X-MS-Identity-Token", token);
    http.onreadystatechange = function() {
        if (http.readyState == 4 && http.status == 200) {
            var output = http.responseText;
            // Do something….
        }
    }
    http.send();
}

Leave a comment