File indexing completed on 2024-12-29 05:27:29

0001 <?php
0002 /**
0003  * LICENSE
0004  *
0005  * This source file is subject to the new BSD license that is bundled
0006  * with this package in the file LICENSE.txt.
0007  * It is also available through the world-wide-web at this URL:
0008  * http://framework.zend.com/license/new-bsd
0009  * If you did not receive a copy of the license and are unable to
0010  * obtain it through the world-wide-web, please send an email
0011  * to license@zend.com so we can send you a copy immediately.
0012  *
0013  * @category   Zend
0014  * @package    Zend_Cloud
0015  * @subpackage QueueService
0016  * @copyright  Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com)
0017  * @license    http://framework.zend.com/license/new-bsd     New BSD License
0018  */
0019 
0020 // require_once 'Zend/Cloud/QueueService/Adapter/AbstractAdapter.php';
0021 // require_once 'Zend/Cloud/QueueService/Exception.php';
0022 // require_once 'Zend/Service/WindowsAzure/Storage/Queue.php';
0023 
0024 /**
0025  * WindowsAzure adapter for simple queue service.
0026  *
0027  * @category   Zend
0028  * @package    Zend_Cloud
0029  * @subpackage QueueService
0030  * @copyright  Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com)
0031  * @license    http://framework.zend.com/license/new-bsd     New BSD License
0032  */
0033 class Zend_Cloud_QueueService_Adapter_WindowsAzure
0034     extends Zend_Cloud_QueueService_Adapter_AbstractAdapter
0035 {
0036     /**
0037      * Option array keys for the Windows Azure adapter.
0038      */
0039     const ACCOUNT_NAME      = 'storage_accountname';
0040     const ACCOUNT_KEY       = 'storage_accountkey';
0041     const HOST              = "storage_host";
0042     const PROXY_HOST        = "storage_proxy_host";
0043     const PROXY_PORT        = "storage_proxy_port";
0044     const PROXY_CREDENTIALS = "storage_proxy_credentials";
0045 
0046     /** list options */
0047     const LIST_PREFIX      = 'prefix';
0048     const LIST_MAX_RESULTS = 'max_results';
0049 
0050     /** message options */
0051     const MESSAGE_TTL = 'ttl';
0052 
0053     const DEFAULT_HOST = Zend_Service_WindowsAzure_Storage::URL_CLOUD_QUEUE;
0054 
0055     /**
0056      * Storage client
0057      *
0058      * @var Zend_Service_WindowsAzure_Storage_Queue
0059      */
0060     protected $_storageClient = null;
0061 
0062     /**
0063      * Constructor
0064      *
0065      * @param  array|Zend_Config $options
0066      * @return void
0067      */
0068     public function __construct($options = array())
0069     {
0070         if ($options instanceof Zend_Config) {
0071             $options = $options->toArray();
0072         }
0073 
0074         if (!is_array($options)) {
0075             throw new Zend_Cloud_QueueService_Exception('Invalid options provided');
0076         }
0077 
0078         if (isset($options[self::MESSAGE_CLASS])) {
0079             $this->setMessageClass($options[self::MESSAGE_CLASS]);
0080         }
0081 
0082         if (isset($options[self::MESSAGESET_CLASS])) {
0083             $this->setMessageSetClass($options[self::MESSAGESET_CLASS]);
0084         }
0085 
0086         // Build Zend_Service_WindowsAzure_Storage_Blob instance
0087         if (!isset($options[self::HOST])) {
0088             $host = self::DEFAULT_HOST;
0089         } else {
0090             $host = $options[self::HOST];
0091         }
0092         if (! isset($options[self::ACCOUNT_NAME])) {
0093             throw new Zend_Cloud_Storage_Exception('No Windows Azure account name provided.');
0094         }
0095         if (! isset($options[self::ACCOUNT_KEY])) {
0096             throw new Zend_Cloud_Storage_Exception('No Windows Azure account key provided.');
0097         }
0098         try {
0099             // TODO: support $usePathStyleUri and $retryPolicy
0100             $this->_storageClient = new Zend_Service_WindowsAzure_Storage_Queue(
0101                 $host, $options[self::ACCOUNT_NAME], $options[self::ACCOUNT_KEY]);
0102             // Parse other options
0103             if (! empty($options[self::PROXY_HOST])) {
0104                 $proxyHost = $options[self::PROXY_HOST];
0105                 $proxyPort = isset($options[self::PROXY_PORT]) ? $options[self::PROXY_PORT] : 8080;
0106                 $proxyCredentials = isset($options[self::PROXY_CREDENTIALS]) ? $options[self::PROXY_CREDENTIALS] : '';
0107                 $this->_storageClient->setProxy(true, $proxyHost, $proxyPort, $proxyCredentials);
0108             }
0109             if (isset($options[self::HTTP_ADAPTER])) {
0110                 $this->_storageClient->setHttpClientChannel($httpAdapter);
0111             }
0112         } catch(Zend_Service_WindowsAzure_Exception $e) {
0113             throw new Zend_Cloud_QueueService_Exception('Error on create: '.$e->getMessage(), $e->getCode(), $e);
0114         }
0115 
0116     }
0117 
0118     /**
0119      * Create a queue. Returns the ID of the created queue (typically the URL).
0120      * It may take some time to create the queue. Check your vendor's
0121      * documentation for details.
0122      *
0123      * @param  string $name
0124      * @param  array  $options
0125      * @return string Queue ID (typically URL)
0126      */
0127     public function createQueue($name, $options = null)
0128     {
0129         try {
0130             $queue = $this->_storageClient->createQueue($name, $options);
0131             return $queue->Name;
0132         } catch (Zend_Service_WindowsAzure_Exception $e) {
0133             throw new Zend_Cloud_QueueService_Exception('Error on queue creation: '.$e->getMessage(), $e->getCode(), $e);
0134         }
0135     }
0136 
0137     /**
0138      * Delete a queue. All messages in the queue will also be deleted.
0139      *
0140      * @param  string $queueId
0141      * @param  array  $options
0142      * @return boolean true if successful, false otherwise
0143      */
0144     public function deleteQueue($queueId, $options = null)
0145     {
0146         try {
0147             if ($queueId instanceof Zend_Service_WindowsAzure_Storage_QueueInstance) {
0148                 $queueId = $queueId->Name;
0149             }
0150             return $this->_storageClient->deleteQueue($queueId);
0151         } catch (Zend_Service_WindowsAzure_Exception $e) {
0152             throw new Zend_Cloud_QueueService_Exception('Error on queue deletion: '.$e->getMessage(), $e->getCode(), $e);
0153         }
0154     }
0155 
0156     /**
0157      * List all queues.
0158      *
0159      * @param  array $options
0160      * @return array Queue IDs
0161      */
0162     public function listQueues($options = null)
0163     {
0164         $prefix = $maxResults = null;
0165         if (is_array($options)) {
0166             isset($options[self::LIST_PREFIX]) ? $prefix = $options[self::LIST_PREFIX] : null;
0167             isset($options[self::LIST_MAX_RESULTS]) ? $maxResults = $options[self::LIST_MAX_RESULTS] : null;
0168         }
0169         try {
0170             $queues =  $this->_storageClient->listQueues($prefix, $maxResults);
0171             $result = array();
0172             foreach ($queues as $queue) {
0173                 $result[] = $queue->Name;
0174             }
0175             return $result;
0176         } catch (Zend_Service_WindowsAzure_Exception $e) {
0177             throw new Zend_Cloud_QueueService_Exception('Error on listing queues: '.$e->getMessage(), $e->getCode(), $e);
0178         }
0179     }
0180 
0181     /**
0182      * Get a key/value array of metadata for the given queue.
0183      *
0184      * @param  string $queueId
0185      * @param  array  $options
0186      * @return array
0187      */
0188     public function fetchQueueMetadata($queueId, $options = null)
0189     {
0190         try {
0191             if ($queueId instanceof Zend_Service_WindowsAzure_Storage_QueueInstance) {
0192                 $queueId = $queueId->Name;
0193             }
0194             return $this->_storageClient->getQueueMetadata($queueId);
0195         } catch (Zend_Service_WindowsAzure_Exception $e) {
0196             throw new Zend_Cloud_QueueService_Exception('Error on fetching queue metadata: '.$e->getMessage(), $e->getCode(), $e);
0197         }
0198     }
0199 
0200     /**
0201      * Store a key/value array of metadata for the specified queue.
0202      * WARNING: This operation overwrites any metadata that is located at
0203      * $destinationPath. Some adapters may not support this method.
0204      *
0205      * @param  string $queueId
0206      * @param  array  $metadata
0207      * @param  array  $options
0208      * @return void
0209      */
0210     public function storeQueueMetadata($queueId, $metadata, $options = null)
0211     {
0212         try {
0213             if ($queueId instanceof Zend_Service_WindowsAzure_Storage_QueueInstance) {
0214                 $queueId = $queueId->Name;
0215             }
0216             return $this->_storageClient->setQueueMetadata($queueId, $metadata);
0217         } catch (Zend_Service_WindowsAzure_Exception $e) {
0218             throw new Zend_Cloud_QueueService_Exception('Error on setting queue metadata: '.$e->getMessage(), $e->getCode(), $e);
0219         }
0220     }
0221 
0222     /**
0223      * Send a message to the specified queue.
0224      *
0225      * @param  string $queueId
0226      * @param  string $message
0227      * @param  array  $options
0228      * @return string Message ID
0229      */
0230     public function sendMessage($queueId, $message, $options = null)
0231     {
0232         try {
0233             if ($queueId instanceof Zend_Service_WindowsAzure_Storage_QueueInstance) {
0234                 $queueId = $queueId->Name;
0235             }
0236             return $this->_storageClient->putMessage(
0237                 $queueId, $message, $options[self::MESSAGE_TTL]
0238             );
0239         } catch (Zend_Service_WindowsAzure_Exception $e) {
0240             throw new Zend_Cloud_QueueService_Exception('Error on sending message: '.$e->getMessage(), $e->getCode(), $e);
0241         }
0242     }
0243 
0244     /**
0245      * Recieve at most $max messages from the specified queue and return the
0246      * message IDs for messages recieved.
0247      *
0248      * @param  string $queueId
0249      * @param  int    $max
0250      * @param  array  $options
0251      * @return Zend_Cloud_QueueService_Message[]
0252      */
0253     public function receiveMessages($queueId, $max = 1, $options = null)
0254     {
0255         try {
0256             if ($queueId instanceof Zend_Service_WindowsAzure_Storage_QueueInstance) {
0257                 $queueId = $queueId->Name;
0258             }
0259             if (isset($options[self::VISIBILITY_TIMEOUT])) {
0260                 $visibility = $options[self::VISIBILITY_TIMEOUT];
0261             } else {
0262                 $visibility = self::DEFAULT_TIMEOUT;
0263             }
0264             return $this->_makeMessages($this->_storageClient->getMessages($queueId, $max, $visibility, false));
0265         } catch (Zend_Service_WindowsAzure_Exception $e) {
0266             throw new Zend_Cloud_QueueService_Exception('Error on recieving messages: '.$e->getMessage(), $e->getCode(), $e);
0267         }
0268     }
0269 
0270     /**
0271      * Create Zend_Cloud_QueueService_Message array for
0272      * Azure messages.
0273      *
0274      * @param array $messages
0275      * @return Zend_Cloud_QueueService_Message[]
0276      */
0277     protected function _makeMessages($messages)
0278     {
0279         $messageClass = $this->getMessageClass();
0280         $setClass     = $this->getMessageSetClass();
0281         $result = array();
0282         foreach ($messages as $message) {
0283             $result[] = new $messageClass($message->MessageText, $message);
0284         }
0285         return new $setClass($result);
0286     }
0287 
0288     /**
0289      * Delete the specified message from the specified queue.
0290      *
0291      * @param  string $queueId
0292      * @param  Zend_Cloud_QueueService_Message $message Message ID or message
0293      * @param  array  $options
0294      * @return void
0295      */
0296     public function deleteMessage($queueId, $message, $options = null)
0297     {
0298         try {
0299             if ($queueId instanceof Zend_Service_WindowsAzure_Storage_QueueInstance) {
0300                 $queueId = $queueId->Name;
0301             }
0302             if ($message instanceof Zend_Cloud_QueueService_Message) {
0303                 $message = $message->getMessage();
0304             }
0305             if ($message instanceof Zend_Service_WindowsAzure_Storage_QueueMessage) {
0306                 return $this->_storageClient->deleteMessage($queueId, $message);
0307             } else {
0308                 throw new Zend_Cloud_QueueService_Exception('Cannot delete the message: message object required');
0309             }
0310         } catch (Zend_Service_WindowsAzure_Exception $e) {
0311             throw new Zend_Cloud_QueueService_Exception('Error on deleting a message: '.$e->getMessage(), $e->getCode(), $e);
0312         }
0313     }
0314 
0315     /**
0316      * Peek at the messages from the specified queue without removing them.
0317      *
0318      * @param  string $queueId
0319      * @param  int $num How many messages
0320      * @param  array  $options
0321      * @return Zend_Cloud_QueueService_Message[]
0322      */
0323     public function peekMessages($queueId, $num = 1, $options = null)
0324     {
0325         try {
0326             if ($queueId instanceof Zend_Service_WindowsAzure_Storage_QueueInstance) {
0327                 $queueId = $queueId->Name;
0328             }
0329             return $this->_makeMessages($this->_storageClient->peekMessages($queueId, $num));
0330         } catch (Zend_Service_WindowsAzure_Exception $e) {
0331             throw new Zend_Cloud_QueueService_Exception('Error on peeking messages: '.$e->getMessage(), $e->getCode(), $e);
0332         }
0333    }
0334 
0335     /**
0336      * Get Azure implementation
0337      * @return Zend_Service_Azure_Storage_Queue
0338      */
0339     public function getClient()
0340     {
0341         return $this->_storageClient;
0342     }
0343 }