A few days ago I wrote a blog post about migrating code from storage client library 1.7 to 2.0 to manage Windows Azure Table Storage. You can read that post here: https://gauravmantri.com/2012/11/17/storage-client-library-2-0-migrating-table-storage-code/. In this post, I will talk about migrating code from storage client library 1.7 to 2.0 for managing Windows Azure Queue Storage. Unlike table storage changes, the queue storage changes are not that significantly different than the previous version so hopefully the exercise to migrate code would be rather a painless one.
Like the previous post, I will attempt to provide some code sample through which I will try and demonstrate how you can do some common tasks when working with Azure Queue Storage. What I did is wrote two simple console applications: one which uses storage client library version 1.7 and the other which uses version 2.0 and in those two applications I demonstrated some simple functionality.
Read These First
Since version 2.0 library is significantly different than the previous ones, before you decide to upgrade your code to make use of this version I strongly urge you to read up the following blog posts by the storage team as there’re many breaking changes.
Introducing Windows Azure Storage Client Library 2.0 for .NET and Windows Runtime
Windows Azure Storage Client Library 2.0 Breaking Changes & Migration Guide
Getting Started
Before jumping into the code, there’re a few things I would like to mention:
Storage Client Libraries
To get the reference for storage client library 1.7, you can browse your local computer and navigate to the Azure SDK installation directory (C:\Program Files\Microsoft SDKs\Windows Azure\.NET SDK\2012-10\ref – assuming you have SDK 1.8 installed) and select Microsoft.WindowsAzure.StorageClient.dll from there.
To get the reference for storage client library 2.0 (or the latest version for that matter), I would actually recommend getting this using Nuget. That way you’ll always get the latest version. You can simply get it by executing the following command in Nuget Package Manager console: Install-Package WindowsAzure.Storage. While it’s an easy way to get the latest version upgrades, one must not upgrade it before ensuring the new version won’t break anything in the existing code.
Namespaces
One good thing that is done with version 2.0 is that the functionality is now neatly segregated into different namespaces. For queue storage, following 2 namespaces are used:
using Microsoft.WindowsAzure.Storage.Queue; using Microsoft.WindowsAzure.Storage.Queue.Protocol;
Queue Request Options and Operation Context
One interesting improvement that has been done is that with every storage client library function, you can pass 2 additional optional parameters: Queue Request Options and Operation Context. Queue Request Options object allows you to control the retry policies (to take care of transient errors) and some of the server side behavior like request timeout. Operation Context provides the context for a request to the storage service and provides additional runtime information about its execution. It allows you to get more information about request/response plus it allows you to pass a client request id which gets logged by storage analytics. For the sake of simplicity, I have omitted these two parameters from the code I included below.
Operations
Now let’s see how you can perform some operations. What I’ve done is first showed how you did an operation with version 1.7 and then how would you do the same operation with version 2.0.
Create Queue
If you’re using the following code with version 1.7 to create a queue:
CloudStorageAccount storageAccount = new CloudStorageAccount(new StorageCredentialsAccountAndKey(accountName, accountKey), true); CloudQueueClient cloudQueueClient = storageAccount.CreateCloudQueueClient(); CloudQueue queue = cloudQueueClient.GetQueueReference(queueName); queue.CreateIfNotExist();
You would use something like this with version 2.0 to achieve the same:
CloudStorageAccount storageAccount = new CloudStorageAccount(new StorageCredentials(accountName, accountKey), true); CloudQueueClient cloudQueueClient = storageAccount.CreateCloudQueueClient(); CloudQueue queue = cloudQueueClient.GetQueueReference(queueName); queue.CreateIfNotExists();
Only difference that you will see in the two functions above is version 2.0 is now grammatically correct 🙂 [in 1.7, it is CreateIfNotExist() and in 2.0, it is CreateIfNotExists() –> notice an extra “s”].
Delete Queue
If you’re using the following code with version 1.7 to delete a queue:
CloudStorageAccount storageAccount = new CloudStorageAccount(new StorageCredentialsAccountAndKey(accountName, accountKey), true); CloudQueueClient cloudQueueClient = storageAccount.CreateCloudQueueClient(); CloudQueue queue = cloudQueueClient.GetQueueReference(queueName); queue.Delete();
You would use something like this with version 2.0 to achieve the same:
CloudStorageAccount storageAccount = new CloudStorageAccount(new StorageCredentials(accountName, accountKey), true); CloudQueueClient cloudQueueClient = storageAccount.CreateCloudQueueClient(); CloudQueue queue = cloudQueueClient.GetQueueReference(queueName); queue.DeleteIfExists();
One interesting improvement with 2.0 is that it now eats up “Resource Not Found (HTTP Error Code 404)” exception if you’re trying to delete a queue which does not exist when you use “DeleteIfExists()” function. With 1.7, you don’t have that option and you would need to handle 404 error in your code. Please note that “Delete()” function is still available in 2.0 on a queue.
List Queues
If you’re using the following code with version 1.7 to list queues:
CloudStorageAccount storageAccount = new CloudStorageAccount(new StorageCredentialsAccountAndKey(accountName, accountKey), true); CloudQueueClient cloudQueueClient = storageAccount.CreateCloudQueueClient(); var queues = cloudQueueClient.ListQueues();
You would use something like this with version 2.0 to achieve the same:
CloudStorageAccount storageAccount = new CloudStorageAccount(new StorageCredentials(accountName, accountKey), true); CloudQueueClient cloudQueueClient = storageAccount.CreateCloudQueueClient(); var queues = cloudQueueClient.ListQueues();
As you can see listing queues functionality is more or less the same in both versions.
Add Message
If you’re using the following code with version 1.7 to add a message to the queue:
CloudStorageAccount storageAccount = new CloudStorageAccount(new StorageCredentialsAccountAndKey(accountName, accountKey), true); CloudQueueClient cloudQueueClient = storageAccount.CreateCloudQueueClient(); CloudQueue queue = cloudQueueClient.GetQueueReference(queueName); string messageContents = "This is a test message"; CloudQueueMessage message = new CloudQueueMessage(messageContents); queue.AddMessage(message);
You would use something like this with version 2.0 to achieve the same:
CloudStorageAccount storageAccount = new CloudStorageAccount(new StorageCredentials(accountName, accountKey), true); CloudQueueClient cloudQueueClient = storageAccount.CreateCloudQueueClient(); CloudQueue queue = cloudQueueClient.GetQueueReference(queueName); string messageContents = "This is a test message"; CloudQueueMessage message = new CloudQueueMessage(messageContents); queue.AddMessage(message);
As you can see add message functionality is same in both versions.
Peek Messages
As you know, peek messages functionality allows you to fetch up to 32 messages from a queue without altering their visibility. If you’re using the following code with version 1.7 to peek messages from a queue:
CloudStorageAccount storageAccount = new CloudStorageAccount(new StorageCredentialsAccountAndKey(accountName, accountKey), true); CloudQueueClient cloudQueueClient = storageAccount.CreateCloudQueueClient(); CloudQueue queue = cloudQueueClient.GetQueueReference(queueName); int numMessagesToFetch = 32;//Max messages which can be fetched at a time is 32 IEnumerable<CloudQueueMessage> messages = queue.PeekMessages(numMessagesToFetch);
You would use something like this with version 2.0 to achieve the same:
CloudStorageAccount storageAccount = new CloudStorageAccount(new StorageCredentials(accountName, accountKey), true); CloudQueueClient cloudQueueClient = storageAccount.CreateCloudQueueClient(); CloudQueue queue = cloudQueueClient.GetQueueReference(queueName); int numMessagesToFetch = 32;//Max messages which can be fetched at a time is 32 IEnumerable<CloudQueueMessage> messages = queue.PeekMessages(numMessagesToFetch);
As you can see peek messages functionality is same in both versions.
Peek Message
While peek messages functionality allows you to fetch multiple messages from a queue, you can use peek message functionality to fetch a single message without altering its visibility. If you’re using the following code with version 1.7 to peek at a message from a queue:
CloudStorageAccount storageAccount = new CloudStorageAccount(new StorageCredentialsAccountAndKey(accountName, accountKey), true); CloudQueueClient cloudQueueClient = storageAccount.CreateCloudQueueClient(); CloudQueue queue = cloudQueueClient.GetQueueReference(queueName); CloudQueueMessage message = queue.PeekMessage();
You would use something like this with version 2.0 to achieve the same:
CloudStorageAccount storageAccount = new CloudStorageAccount(new StorageCredentials(accountName, accountKey), true); CloudQueueClient cloudQueueClient = storageAccount.CreateCloudQueueClient(); CloudQueue queue = cloudQueueClient.GetQueueReference(queueName); CloudQueueMessage message = queue.PeekMessage();
As you can see peek message functionality is same in both versions.
Get Messages
Like peek messages functionality, get message functionality allows you to fetch up to 32 messages from a queue. The difference is that when you “get” messages from a queue, they become invisible to all other applications for some amount of time specified by you. Or in other words, a message gets “de-queued”. If you’re using the following code with version 1.7 to get messages from a queue:
CloudStorageAccount storageAccount = new CloudStorageAccount(new StorageCredentialsAccountAndKey(accountName, accountKey), true); CloudQueueClient cloudQueueClient = storageAccount.CreateCloudQueueClient(); CloudQueue queue = cloudQueueClient.GetQueueReference(queueName); int numMessagesToFetch = 32;//Max messages which can be fetched at a time is 32 TimeSpan visibilityTimeout = TimeSpan.FromSeconds(30);//Message will be invisible for 30 seconds. IEnumerable<CloudQueueMessage> messages = queue.GetMessages(numMessagesToFetch, visibilityTimeout);
You would use something like this with version 2.0 to achieve the same:
CloudStorageAccount storageAccount = new CloudStorageAccount(new StorageCredentials(accountName, accountKey), true); CloudQueueClient cloudQueueClient = storageAccount.CreateCloudQueueClient(); CloudQueue queue = cloudQueueClient.GetQueueReference(queueName); int numMessagesToFetch = 32;//Max messages which can be fetched at a time is 32 TimeSpan visibilityTimeout = TimeSpan.FromSeconds(30);//Message will be invisible for 30 seconds. IEnumerable<CloudQueueMessage> messages = queue.GetMessages(numMessagesToFetch, visibilityTimeout);
As you can see get messages functionality is same in both versions.
Get Message
While get messages functionality allows you to fetch multiple messages from a queue, you can use get message functionality to fetch a single message and making it invisible to other applications for a certain amount of time. If you’re using the following code with version 1.7 to get a message from a queue:
CloudStorageAccount storageAccount = new CloudStorageAccount(new StorageCredentialsAccountAndKey(accountName, accountKey), true); CloudQueueClient cloudQueueClient = storageAccount.CreateCloudQueueClient(); CloudQueue queue = cloudQueueClient.GetQueueReference(queueName); TimeSpan visibilityTimeout = TimeSpan.FromSeconds(30);//Message will be invisible for 30 seconds. CloudQueueMessage message = queue.GetMessage(visibilityTimeout);
You would use something like this with version 2.0 to achieve the same:
CloudStorageAccount storageAccount = new CloudStorageAccount(new StorageCredentials(accountName, accountKey), true); CloudQueueClient cloudQueueClient = storageAccount.CreateCloudQueueClient(); CloudQueue queue = cloudQueueClient.GetQueueReference(queueName); TimeSpan visibilityTimeout = TimeSpan.FromSeconds(30);//Message will be invisible for 30 seconds. CloudQueueMessage message = queue.GetMessage(visibilityTimeout);
As you can see get message functionality is same in both versions.
Delete Message
If you’re using the following code with version 1.7 to delete a message from a queue:
CloudStorageAccount storageAccount = new CloudStorageAccount(new StorageCredentialsAccountAndKey(accountName, accountKey), true); CloudQueueClient cloudQueueClient = storageAccount.CreateCloudQueueClient(); CloudQueue queue = cloudQueueClient.GetQueueReference(queueName); CloudQueueMessage message = queue.GetMessage(); queue.DeleteMessage(message); //Or you could use something like this //queue.DeleteMessage(message.Id, message.PopReceipt);
You would use something like this with version 2.0 to achieve the same:
CloudStorageAccount storageAccount = new CloudStorageAccount(new StorageCredentials(accountName, accountKey), true); CloudQueueClient cloudQueueClient = storageAccount.CreateCloudQueueClient(); CloudQueue queue = cloudQueueClient.GetQueueReference(queueName); CloudQueueMessage message = queue.GetMessage(); queue.DeleteMessage(message); //Or you could use something like this //queue.DeleteMessage(message.Id, message.PopReceipt);
As you can see delete message functionality is same in both versions.
Get Approximate Messages Count
A queue can contain very large number of messages however you can only fetch up to 32 messages at a time for processing (or peeking). As the name suggests, using this functionality you can find out the approximate number of messages in a queue. If you’re using the following code with version 1.7 to get approximate messages count in a queue:
CloudStorageAccount storageAccount = new CloudStorageAccount(new StorageCredentialsAccountAndKey(accountName, accountKey), true); CloudQueueClient cloudQueueClient = storageAccount.CreateCloudQueueClient(); CloudQueue queue = cloudQueueClient.GetQueueReference(queueName); int approximateMessagesCount = queue.RetrieveApproximateMessageCount(); //or you could use something like this //queue.FetchAttributes(); //int approximateMessagesCount = queue.ApproximateMessageCount.Value;
You would use something like this with version 2.0 to achieve the same:
CloudStorageAccount storageAccount = new CloudStorageAccount(new StorageCredentials(accountName, accountKey), true); CloudQueueClient cloudQueueClient = storageAccount.CreateCloudQueueClient(); CloudQueue queue = cloudQueueClient.GetQueueReference(queueName); queue.FetchAttributes(); int approximateMessagesCount = queue.ApproximateMessageCount.Value;
Please note that “RetrieveApproximateMessageCount()” method is not available in version 2.0.
Clear Queue
Clear queue functionality allows you to delete all messages from a queue without deleting the queue. If you’re using the following code with version 1.7 to clear a queue:
CloudStorageAccount storageAccount = new CloudStorageAccount(new StorageCredentialsAccountAndKey(accountName, accountKey), true); CloudQueueClient cloudQueueClient = storageAccount.CreateCloudQueueClient(); CloudQueue queue = cloudQueueClient.GetQueueReference(queueName); queue.Clear();
You would use something like this with version 2.0 to achieve the same:
CloudStorageAccount storageAccount = new CloudStorageAccount(new StorageCredentials(accountName, accountKey), true); CloudQueueClient cloudQueueClient = storageAccount.CreateCloudQueueClient(); CloudQueue queue = cloudQueueClient.GetQueueReference(queueName); queue.Clear();
As you can see clear queue functionality is same in both versions.
Closing Thoughts
As I mentioned above and demonstrated through examples, there are a few differences in storage client library 1.7 and 2.0 as far as managing queues are concerned. However in my opinion they are not as drastic as with the tables and the migration should be considerably smooth.
Finally, don’t give up on Storage Client Library 1.7 just yet. There’re still some components which depend on 1.7 version. Good example is Windows Azure Diagnostics which still depends on the older version at the time of writing this blog. Good thing is that both version 1.7 and 2.0 can co-exist in a project.
Source Code
You can download the source code for this project from here: Sample Project Source Code
Summary
The examples I presented in this post are quite basic but hopefully they should give you an idea about how to use the latest version of storage client library. In general, I am quite pleased with the changes the team has done. Please feel free to share your experience with migration exercise by providing comments. This will help me and the readers of this blog immensely. Finally, if you find any issues with this post please let me know and I will try and fix them ASAP.
Happy Coding!