nightcrawler
nightcrawler

Reputation: 347

Checking if a queue exists

I have a very basic question about Windows Azure Storage Queue errors/access.

I am trying to find out if the given storage account already contains a queue by the given name - say "queue1". I do not want to create the queue if it does not exist, and so am not keen on using the CreateIfNotExist method. The permissions I have given to the SAS token are - processing and Add (since all I want to do is to add a new message to the queue only if it already exists, and throw an error otherwise)

The problem is that when I try to get reference to a fake named queue, and add a message to it, I get a 403. 403 can also occur when the SAS token does not have permissions, so I cannot be sure what is causing the error.

Is there a way I could explicitly know if the queue exists or not?

I have tried the BeginExist, and EndExist methods but they always return false even when I can see the queue being there.

Any suggestions?

Upvotes: 1

Views: 4312

Answers (4)

d219
d219

Reputation: 2835

There is now an Exists and ExistsAsync (with various overloads).

Example of the former in use:

        CloudStorageAccount storageAccount = CloudStorageAccount.Parse(connectionString);

        CloudQueueClient queueClient = storageAccount.CreateCloudQueueClient();

        CloudQueue queue = queueClient.GetQueueReference(queueName);

        bool doesExist = queue.Exists();

You will want a reference to Microsoft.Azure.Storage.Queue (I believe older 'cloud' assemblies may not have had these properties - initially I could only access ExistsAsync before I had reference the right package, once I had added the above via Nuget Exists also was available)

For more details see the following links:

Upvotes: 1

Andrey Stukalin
Andrey Stukalin

Reputation: 5949

There is no Exists method in the v12 as well. Wrote a simple helper method to do the check:

        private async Task<bool> QueueExistsAsync(QueueClient queue)
        {
            try
            {
                await queue.GetPropertiesAsync();
                return true;
            }
            catch (RequestFailedException ex)
            {
                if (ex.Status == (int) HttpStatusCode.NotFound)
                {
                    return false;
                }

                throw;
            }
        }

Upvotes: 0

Fernando Correia
Fernando Correia

Reputation: 22385

The Get Queue Metadata REST API operation will return status code 200 if the queue exists or a Queue Service Error Code otherwise.

Regarding to authorization,

This operation can be performed by the account owner and by anyone with a shared access signature that has permission to perform this operation.

A GET request to

https://myaccount.queue.core.windows.net/myqueue?comp=metadata

Will return a response like:

Response Status:
HTTP/1.1 200 OK

Response Headers:
Transfer-Encoding: chunked
x-ms-approximate-messages-count: 0
Date: Fri, 16 Sep 2011 01:27:38 GMT
Server: Windows-Azure-Queue/1.0 Microsoft-HTTPAPI/2.0

Upvotes: 2

Gaurav Mantri
Gaurav Mantri

Reputation: 136346

Are you sure you're getting a 403 error even if the queue does not exist. Based on what you described above, I created a simple console app. The queue does not exist in my storage account. When I try to add a message with valid SAS token, I get a 404 error:

    CloudStorageAccount storageAccount = new CloudStorageAccount(new StorageCredentials("account", "key"), false);
    CloudQueueClient client = storageAccount.CreateCloudQueueClient();
    CloudQueue queue = client.GetQueueReference("non-existent-queue");
    var queuePolicy = new SharedAccessQueuePolicy();
    var sas = queue.GetSharedAccessSignature(new SharedAccessQueuePolicy()
    {
        SharedAccessExpiryTime = DateTime.UtcNow.AddMinutes(30),
        Permissions = SharedAccessQueuePermissions.Add | SharedAccessQueuePermissions.ProcessMessages | SharedAccessQueuePermissions.Update
    }, null);
    StorageCredentials creds = new StorageCredentials(sas);
    var queue1 = new CloudQueue(queue.Uri, creds);
    try
    {
        queue1.AddMessage(new CloudQueueMessage("This is a test message"));
    }
    catch (StorageException excep)
    {
        //Get 404 error here
    }

Next, I made the SAS token invalid by setting it's expiry to 30 minutes before current time. Now when I run the application, I get 403 error as expected.

    CloudStorageAccount storageAccount = new CloudStorageAccount(new StorageCredentials("account", "key"), false);
    CloudQueueClient client = storageAccount.CreateCloudQueueClient();
    CloudQueue queue = client.GetQueueReference("non-existent-queue");
    var queuePolicy = new SharedAccessQueuePolicy();
    var sas = queue.GetSharedAccessSignature(new SharedAccessQueuePolicy()
    {
        SharedAccessExpiryTime = DateTime.UtcNow.AddMinutes(-30),//-30 to ensure SAS is invalid
        Permissions = SharedAccessQueuePermissions.Add | SharedAccessQueuePermissions.ProcessMessages | SharedAccessQueuePermissions.Update
    }, null);
    StorageCredentials creds = new StorageCredentials(sas);
    var queue1 = new CloudQueue(queue.Uri, creds);
    try
    {
        queue1.AddMessage(new CloudQueueMessage("This is a test message"));
    }
    catch (StorageException excep)
    {
        //Get 403 error here
    }

Upvotes: 1

Related Questions