Azure Simplified Part 5: Using REST API for Azure Queue Storage
May 21, 2010 1 Comment
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,
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),