Проверка наличия очереди

У меня очень простой вопрос об ошибках / доступе к очереди хранилища Windows Azure.

Я пытаюсь выяснить, содержит ли данная учетная запись хранения очередь с заданным именем - скажем, "queue1". Я не хочу создавать очередь, если она не существует, и поэтому не хочу использовать метод CreateIfNotExist. Разрешения, которые я дал токену SAS, - обработка и добавление (поскольку все, что я хочу сделать, это добавить новое сообщение в очередь , только если оно уже существует, и выдать ошибку в противном случае)

Проблема в том, что когда я пытаюсь получить ссылку на фальшивую именованную очередь и добавить к ней сообщение, я получаю 403. 403 может также возникнуть, когда у токена SAS нет разрешений, поэтому я не могу быть уверен, что вызывает ошибка.

Есть ли способ явно узнать, существует очередь или нет?

Я пробовал использовать методы BeginExist и EndExist, но они всегда возвращают false, даже если я вижу очередь.

Какие-либо предложения?


person nightcrawler    schedule 02.08.2013    source источник


Ответы (4)


Операция Get Queue Metadata REST API вернет код состояния 200, если очередь существует или код ошибки службы очередей в противном случае.

Что касается авторизации,

Эта операция может быть выполнена владельцем учетной записи и любым пользователем с подписью общего доступа, имеющим разрешение на выполнение этой операции.

Запрос GET на

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

Вернет такой ответ:

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
person Fernando Correia    schedule 03.08.2013

Вы уверены, что получаете ошибку 403, даже если очередь не существует? Основываясь на том, что вы описали выше, я создал простое консольное приложение. Очереди нет в моей учетной записи хранения. Когда я пытаюсь добавить сообщение с действующим токеном SAS, я получаю ошибку 404:

    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
    }

Затем я сделал токен SAS недействительным, установив срок его действия на 30 минут раньше текущего времени. Теперь, когда я запускаю приложение, я получаю ошибку 403, как и ожидалось.

    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
    }
person Gaurav Mantri    schedule 02.08.2013

Теперь есть Exists и ExistsAsync (с разными перегрузками).

Пример использования первого:

        CloudStorageAccount storageAccount = CloudStorageAccount.Parse(connectionString);

        CloudQueueClient queueClient = storageAccount.CreateCloudQueueClient();

        CloudQueue queue = queueClient.GetQueueReference(queueName);

        bool doesExist = queue.Exists();

Вам понадобится ссылка на Microsoft.Azure.Storage.Queue (я считаю, что более старые «облачные» сборки могли не иметь этих свойств - изначально я мог получить доступ только к ExistsAsync, прежде чем у меня была ссылка на правильный пакет, после того как я добавил вышеупомянутое через Nuget, Exists также был доступен)

Для получения дополнительной информации перейдите по следующим ссылкам:

person d219    schedule 23.04.2020

В v12 тоже нет Exists метода. Написал простой вспомогательный метод для проверки:

        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;
            }
        }
person Andrey Stukalin    schedule 21.01.2020