Question

I'm trying to interact with an Azure Queue using a REST proxy courtesy of the Windows Azure SDK for PHP. Whilst there are plenty of code samples here, I want to check whether a queue exists so that I can create it if necessary, before adding a message to it.

try {
  // setup connection string for accessing queue storage
  $connectionString = 'DefaultEndpointsProtocol=' . PROTOCOL . ';AccountName=' . ACCOUNT_NAME . ';AccountKey=' . ACCOUNT_KEY;

  // create queue REST proxy
  $queueRestProxy = ServicesBuilder::getInstance()->createQueueService($connectionString);

  // create message
  $queueRestProxy->createMessage(QUEUE_NAME, 'Hello World!');

} catch(ServiceException $e){
  // Handle exception based on error codes and messages.
  // Error codes and messages are here: 
  // http://msdn.microsoft.com/en-us/library/windowsazure/dd179446.aspx
  $code = $e->getCode();
  $error_message = $e->getMessage();
  echo $code.": ".$error_message."<br />";
}

Creating a queue is as simple as this...

$queueRestProxy->createQueue(QUEUE_NAME);

Should I simply include the queue creation code prior to creating a message or is there a more efficient way to ascertain whether the queue exists before interacting with it?

Was it helpful?

Solution 2

I've posted an answer below for completeness and to make it easy for people to see the answer at a glance.

Should I simply include the queue creation code prior to creating a message or is there a more efficient way to ascertain whether the queue exists before interacting with it?

There are two ways to approach this...

  1. Include the createQueue statement prior to creating a message, but wrap this statement in a try-catch block as directed by Guarav Mantri's answer i.e. ignore 409 errors, but throw an exception for any other types of error.

    For information, when you include a createQueue statement prior to creating a message...

    • if a queue of the same name already exists and the metadata associated with the existing queue is the same as that passed to the createQueue statement then the queue will not be created and the Queue REST Proxy will internally receive a 204 (No Content) status code, but this response code is not made available to the programmer. So, essentially, the createQueue statement doesn't cause an error/exception to be raised in this scenario.

    • if a queue of the same name already exists and the metadata associated with the existing queue isn't the same as that passed to the createQueue statement then the queue will not be created and the Queue REST Proxy will receive a 409 (Conflict) status code and will raise an exception which allows the programmer to access this response code and the associated QueueAlreadyExists message.

    Source: Create Queue (REST API) - see Remarks section

  2. Create a queueExists function and call it to decide whether or not queue creation is necessary. Here is one way to implement such a function...

    public function queueExists($queueRestProxy, $queueName) {
      $result = FALSE;
      $listQueuesResult = $queueRestProxy->listQueues();
      $queues = $listQueuesResult->getQueues();
      foreach($queues as $queue) {
        if ($queue->getName() === $queueName) {
          $result = TRUE;
          break;
        }
      }
      return $result;        
    }
    

Hope this helps someone!

OTHER TIPS

Normally in other Windows Azure SDKs I have seen methods like createQueueIfNotExists and I'm surprised that this method is missing from PHP SDK. Basically the way this function works is that it tries to create a queue. If the queue by the same name exists in storage, storage service throws a Conflict (409) error.

Since this function is not there, you could do the same i.e. try to create the queue inside its own try/catch block and check the error code. If the error code is 409, you continue otherwise you rethrow the exception. Something like the code below:

try {
  // setup connection string for accessing queue storage
  $connectionString = 'DefaultEndpointsProtocol=' . PROTOCOL . ';AccountName=' . ACCOUNT_NAME . ';AccountKey=' . ACCOUNT_KEY;
    // create queue REST proxy
        $queueRestProxy = ServicesBuilder::getInstance()->createQueueService($connectionString);
  try {
    // now try to create the queue.
$queueRestProxy->createQueue(QUEUE_NAME);
  } catch(ServiceException $e){
    $code = $e->getCode();
    //Now check if the $code is 409 - Conflict. If the error code is indeed 409, you continue otherwise throw the error
  }
  // create message
  $queueRestProxy->createMessage(QUEUE_NAME, 'Hello World!');

} catch(ServiceException $e){
  // Handle exception based on error codes and messages.
  // Error codes and messages are here: 
  // http://msdn.microsoft.com/en-us/library/windowsazure/dd179446.aspx
  $code = $e->getCode();
  $error_message = $e->getMessage();
  echo $code.": ".$error_message."<br />";
}

P.S. I have not tried to execute the code, so it may throw errors. This is just to give you an idea.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top