Azure Simplified Part 5: Using REST API for Azure Queue Storage

Up until now we were looking at how to use the Azure storage with Azure Managed API. Windows Azure also provides REST API to interact with Azure storage. The managed API is actually a wrapper around the the REST API. Today we’ll use the REST API to put/get a message from the queue.

1. Start the Azure queue we built here. The reason we are doing this is because we’ll use the managed API to create a queue called ‘myqueue’, and we’ll use the REST API to post and get messages from this queue. You can obviously also create a queue using the REST API.

2. Open Visual Studio 2008 and create a WPF application. For the XAML use this,

<Grid>
    <Grid.RowDefinitions>
        <RowDefinition Height="30" />
        <RowDefinition Height="Auto" />
    </Grid.RowDefinitions>
    <Grid.ColumnDefinitions>
        <ColumnDefinition />
        <ColumnDefinition />
    </Grid.ColumnDefinitions>
    
    <TextBox x:Name="PostMsg" />
    <Button Grid.Column="1" Height="25" Width="80" Content="Post Message" Click="PostButtonClick" />

    <Button Grid.Row="1" Height="25" Width="80" Content="Get Message" Click="GetButtonClick" />
    <TextBlock Grid.Column="1" Grid.Row="1" Height="Auto" TextWrapping="Wrap" x:Name="GetMsg" />
</Grid>

3. For the code behind, the method to post a message to the queue,

// For the Queue REST API URI syntax
// (see http://msdn.microsoft.com/en-us/library/dd179409.aspx)
private void PostButtonClick(object sender, RoutedEventArgs e)
{
    // The URI path is the same as what we had in
    // https://soumya.wordpress.com/2010/05/20/azure-simplified-part-4-using-azure-queue-storage/
    HttpWebRequest request = (HttpWebRequest)HttpWebRequest.Create("http://127.0.0.1:10001/devstoreaccount1/myqueue/messages");

    // Set request timeouts
    request.Timeout = (int)TimeSpan.FromSeconds(30).TotalMilliseconds;
    request.ReadWriteTimeout = request.Timeout;
    
    // POST because we want to put a message onto the queue
    // (see http://msdn.microsoft.com/en-us/library/dd179346(v=MSDN.10).aspx)
    request.Method = "POST";

    // Always have to use UTC date/time
    request.Headers.Add("x-ms-date", DateTime.UtcNow.ToString("R", CultureInfo.InvariantCulture));

    // NOTE: The message posted to the queue MUST be base64 encoded!
    string postMessage = this.PostMsg.Text;
    System.Text.ASCIIEncoding enc = new System.Text.ASCIIEncoding();
    byte[] postMessageByteArray = enc.GetBytes(postMessage);
    string postMessageBase64 = System.Convert.ToBase64String(postMessageByteArray);

    // Create the message that we'll POST to the queue
    // (see http://msdn.microsoft.com/en-us/library/dd179346(v=MSDN.10).aspx)
    byte[] baMessage = enc.GetBytes("<QueueMessage><MessageText>" + postMessageBase64 + "</MessageText></QueueMessage>");

    // Set the request content length and content type
    request.ContentLength = baMessage.Length;
    request.ContentType = "text/plain; charset=UTF-8";

    // Create the string that will be signed
    // (see http://msdn.microsoft.com/en-us/library/dd179428.aspx)
    string stringToSign = request.Method + "\n" +
        String.Empty + "\n" +
        request.ContentType + "\n" +
        String.Empty + "\n" +
        "x-ms-date:" + request.Headers["x-ms-date"] + "\n" +
        "/" + "devstoreaccount1" + "/devstoreaccount1/myqueue/messages";

    // The account key for development storage is the same for everybody
    // (see http://msdn.microsoft.com/en-us/library/dd179339.aspx)
    string accountKey = "Eby8vdM02xNOcqFlqUwJPLlmEtlCDXJ1OUzFT50uSRZ6IFsuFq2UVErCz4I6tq/K1SZFPTOtr/KBHBeksoGMGw==";

    // Sign the request
    var hmac = new HMACSHA256(Convert.FromBase64String(accountKey));
    request.Headers["Authorization"] = "SharedKey " + "devstoreaccount1" + ":" 
                                        + Convert.ToBase64String(hmac.ComputeHash(Encoding.UTF8.GetBytes(stringToSign)));

    // Send the request to the queue
    try {
        using (Stream requestStream = request.GetRequestStream()) {
            requestStream.Write(baMessage, 0, baMessage.Length);
            requestStream.Close();
            using (HttpWebResponse response = (HttpWebResponse)request.GetResponse()) {
                // Check that (response.StatusCode == HttpStatusCode.Created)
                response.Close();
            }
        }
    }
    catch (WebException ex) { MessageBox.Show(ex.Message); }
}

4. And the method to get a message from the queue, is similar,

// For the Queue REST API URI syntax
// (see http://msdn.microsoft.com/en-us/library/dd179409.aspx)
private void GetButtonClick(object sender, RoutedEventArgs e)
{
    // The URI path is the same as what we had in
    // https://soumya.wordpress.com/2010/05/20/azure-simplified-part-4-using-azure-queue-storage/
    HttpWebRequest request = (HttpWebRequest)HttpWebRequest.Create("http://127.0.0.1:10001/devstoreaccount1/myqueue/messages");

    // Set request timeouts
    request.Timeout = (int)TimeSpan.FromSeconds(30).TotalMilliseconds;
    request.ReadWriteTimeout = request.Timeout;

    // GET because we want to get a message from the queue
    // (see http://msdn.microsoft.com/en-us/library/dd179474(v=MSDN.10).aspx)
    request.Method = "GET";

    // Always have to use UTC date/time
    request.Headers.Add("x-ms-date", DateTime.UtcNow.ToString("R", CultureInfo.InvariantCulture));

    // Set the request content length and content type
    request.ContentLength = 0;
    request.ContentType = "text/plain; charset=UTF-8";

    // Create the string that will be signed
    // (see http://msdn.microsoft.com/en-us/library/dd179428.aspx)
    string stringToSign = request.Method + "\n" +
        String.Empty + "\n" +
        request.ContentType + "\n" +
        String.Empty + "\n" +
        "x-ms-date:" + request.Headers["x-ms-date"] + "\n" +
        "/" + "devstoreaccount1" + "/devstoreaccount1/myqueue/messages";

    // The account key for development storage is the same for everybody
    // (see http://msdn.microsoft.com/en-us/library/dd179339.aspx)
    string accountKey = "Eby8vdM02xNOcqFlqUwJPLlmEtlCDXJ1OUzFT50uSRZ6IFsuFq2UVErCz4I6tq/K1SZFPTOtr/KBHBeksoGMGw==";

    // Sign the request
    var hmac = new HMACSHA256(Convert.FromBase64String(accountKey));
    request.Headers["Authorization"] = "SharedKey " + "devstoreaccount1" + ":"
                                        + Convert.ToBase64String(hmac.ComputeHash(Encoding.UTF8.GetBytes(stringToSign)));

    // Send the request to the queue
    try {
        using (HttpWebResponse response = (HttpWebResponse)request.GetResponse()) {
            if (response.StatusCode == HttpStatusCode.OK) {
                using (Stream stream = response.GetResponseStream()) {
                    XmlDocument doc = new XmlDocument();
                    doc.Load(stream);
                    this.GetMsg.Text = doc.InnerXml;
                    stream.Close();
                    response.Close();
                }
            }
        }
    }
    catch (WebException ex) { MessageBox.Show(ex.Message); }
}

5. Now make sure you run the sample in Step 1 first. That will ensure that you have a queue called ‘myqueue’ in the development storage. Running this app now, you should see something like this,

image

Remember the message is base64 encoded, which is why you see gibberish between the MessageText tags.

6. Now you can post a message from the WPF app (using REST API) and see the message from the ASP.NET WebRole  app (using the managed API). Just refresh the webpage that opened when you ran the code in Step 1, (the managed API converts from base64),

image

Digg This
Advertisements

About soumya chattopadhyay
I live and work in Seattle, WA. I work with Microsoft technologies, and I'm especially interested in C#.

One Response to Azure Simplified Part 5: Using REST API for Azure Queue Storage

  1. Tripuramallu says:

    Good article, very detailed steps.

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

%d bloggers like this: