【问题标题】:Checking if a queue exists检查队列是否存在
【发布时间】:2020-04-23 23:46:28
【问题描述】:

我有一个关于 Windows Azure 存储队列错误/访问的非常基本的问题。

我正在尝试找出给定的存储帐户是否已经包含一个给定名称的队列 - 例如“queue1”。如果队列不存在,我不想创建它,因此我不热衷于使用CreateIfNotExist 方法。我授予 SAS 令牌的权限是 - 处理和添加(因为我要做的就是将新消息添加到队列仅当它已经存在时,否则抛出错误)

问题是,当我尝试获取对假命名队列的引用并向其中添加消息时,我得到一个 403。当 SAS 令牌没有权限时,也可能出现 403,所以我不确定是什么导致错误。

有没有一种方法可以明确知道队列是否存在?

我尝试了BeginExistEndExist 方法,但即使我可以看到队列在那里,它们也总是返回false。

有什么建议吗?

【问题讨论】:

    标签: azure azure-storage azure-storage-queues


    【解决方案1】:

    如果队列存在,Get Queue Metadata REST API 操作将返回状态代码 200,否则返回 Queue Service Error Code

    关于授权,

    此操作可由帐户所有者和任何拥有共享访问签名且有权执行此操作的人执行。

    一个 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
    

    【讨论】:

      【解决方案2】:

      即使队列不存在,您确定会收到 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 分钟来使 SAS 令牌无效。现在,当我运行应用程序时,我得到了预期的 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
          }
      

      【讨论】:

        【解决方案3】:

        现在有ExistsExistsAsync(具有各种重载)。

        前者的使用示例:

                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 也可用)

        更多详情请看以下链接:

        【讨论】:

          【解决方案4】:

          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;
                      }
                  }
          

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 2014-06-18
            • 1970-01-01
            • 1970-01-01
            • 2014-05-06
            • 1970-01-01
            • 2023-04-08
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多