web/lib/Zend/Cloud/StorageService/Adapter/WindowsAzure.php
changeset 807 877f952ae2bd
parent 207 621fa6caec0c
child 1230 68c69c656a2c
equal deleted inserted replaced
805:5e7a0fedabdf 807:877f952ae2bd
    11  * to license@zend.com so we can send you a copy immediately.
    11  * to license@zend.com so we can send you a copy immediately.
    12  *
    12  *
    13  * @category   Zend
    13  * @category   Zend
    14  * @package    Zend_Cloud
    14  * @package    Zend_Cloud
    15  * @subpackage StorageService
    15  * @subpackage StorageService
    16  * @copyright  Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com)
    16  * @copyright  Copyright (c) 2005-2012 Zend Technologies USA Inc. (http://www.zend.com)
    17  * @license    http://framework.zend.com/license/new-bsd     New BSD License
    17  * @license    http://framework.zend.com/license/new-bsd     New BSD License
    18  */
    18  */
    19 
    19 
    20 require_once 'Zend/Cloud/StorageService/Adapter.php';
    20 require_once 'Zend/Cloud/StorageService/Adapter.php';
    21 require_once 'Zend/Service/WindowsAzure/Storage/Blob.php';
    21 require_once 'Zend/Service/WindowsAzure/Storage/Blob.php';
    22 require_once 'Zend/Cloud/StorageService/Exception.php';
    22 require_once 'Zend/Cloud/StorageService/Exception.php';
    23 
    23 
    24 /**
    24 /**
    25  *
    25  *
    26  * Windows Azure Blob Service abstraction
    26  * Windows Azure Blob Service abstraction
    27  * 
    27  *
    28  * @category   Zend
    28  * @category   Zend
    29  * @package    Zend_Cloud
    29  * @package    Zend_Cloud
    30  * @subpackage StorageService
    30  * @subpackage StorageService
    31  * @copyright  Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com)
    31  * @copyright  Copyright (c) 2005-2012 Zend Technologies USA Inc. (http://www.zend.com)
    32  * @license    http://framework.zend.com/license/new-bsd     New BSD License
    32  * @license    http://framework.zend.com/license/new-bsd     New BSD License
    33  */
    33  */
    34 class Zend_Cloud_StorageService_Adapter_WindowsAzure 
    34 class Zend_Cloud_StorageService_Adapter_WindowsAzure
    35     implements Zend_Cloud_StorageService_Adapter
    35     implements Zend_Cloud_StorageService_Adapter
    36 {
    36 {
    37     const ACCOUNT_NAME      = 'storage_accountname';
    37     const ACCOUNT_NAME      = 'storage_accountname';
    38     const ACCOUNT_KEY       = 'storage_accountkey';
    38     const ACCOUNT_KEY       = 'storage_accountkey';
    39     const HOST              = "storage_host";
    39     const HOST              = "storage_host";
    42     const PROXY_CREDENTIALS = "storage_proxy_credentials";
    42     const PROXY_CREDENTIALS = "storage_proxy_credentials";
    43     const CONTAINER         = "storage_container";
    43     const CONTAINER         = "storage_container";
    44     const RETURN_TYPE       = 'return_type';
    44     const RETURN_TYPE       = 'return_type';
    45     const RETURN_PATHNAME   = 'return_path';
    45     const RETURN_PATHNAME   = 'return_path';
    46     const RETURN_OPENMODE   = 'return_openmode';
    46     const RETURN_OPENMODE   = 'return_openmode';
    47     
    47 
    48     /** return types  for fetch */
    48     /** return types  for fetch */
    49     const RETURN_PATH   = 1;   // return filename
    49     const RETURN_PATH   = 1;   // return filename
    50     const RETURN_STRING = 2; // return data as string
    50     const RETURN_STRING = 2; // return data as string
    51     const RETURN_STREAM = 3; // return PHP stream
    51     const RETURN_STREAM = 3; // return PHP stream
    52 
    52 
    53     /** return types  for list */
    53     /** return types  for list */
    54     const RETURN_LIST  = 1;   // return native list
    54     const RETURN_LIST  = 1;   // return native list
    55     const RETURN_NAMES = 2;  // return only names
    55     const RETURN_NAMES = 2;  // return only names
    56     
    56 
    57     const DEFAULT_HOST = Zend_Service_WindowsAzure_Storage::URL_CLOUD_BLOB;
    57     const DEFAULT_HOST = Zend_Service_WindowsAzure_Storage::URL_CLOUD_BLOB;
    58 
    58 
    59     /**
    59     /**
    60      * Storage container to operate on
    60      * Storage container to operate on
    61      * 
    61      *
    62      * @var string
    62      * @var string
    63      */
    63      */
    64     protected $_container;
    64     protected $_container;
    65     
    65 
    66     /**
    66     /**
    67      * Storage client
    67      * Storage client
    68      * 
    68      *
    69      * @var Zend_Service_WindowsAzure_Storage_Blob
    69      * @var Zend_Service_WindowsAzure_Storage_Blob
    70      */
    70      */
    71     protected $_storageClient = null;
    71     protected $_storageClient = null;
    72 
    72 
    73     /**
    73     /**
    74      * Creates a new Zend_Cloud_Storage_WindowsAzure instance
    74      * Creates a new Zend_Cloud_Storage_WindowsAzure instance
    75      * 
    75      *
    76      * @param array|Zend_Config  $options   Options for the Zend_Cloud_Storage_WindowsAzure instance
    76      * @param array|Zend_Config  $options   Options for the Zend_Cloud_Storage_WindowsAzure instance
    77      */
    77      */
    78     public function __construct($options = array())
    78     public function __construct($options = array())
    79     {
    79     {
    80         if ($options instanceof Zend_Config) {
    80         if ($options instanceof Zend_Config) {
    89         if (!isset($options[self::HOST])) {
    89         if (!isset($options[self::HOST])) {
    90             $host = self::DEFAULT_HOST;
    90             $host = self::DEFAULT_HOST;
    91         } else {
    91         } else {
    92             $host = $options[self::HOST];
    92             $host = $options[self::HOST];
    93         }
    93         }
    94         
    94 
    95         if (!isset($options[self::ACCOUNT_NAME])) {
    95         if (!isset($options[self::ACCOUNT_NAME])) {
    96             throw new Zend_Cloud_StorageService_Exception('No Windows Azure account name provided.');
    96             throw new Zend_Cloud_StorageService_Exception('No Windows Azure account name provided.');
    97         }
    97         }
    98         if (!isset($options[self::ACCOUNT_KEY])) {
    98         if (!isset($options[self::ACCOUNT_KEY])) {
    99             throw new Zend_Cloud_StorageService_Exception('No Windows Azure account key provided.');
    99             throw new Zend_Cloud_StorageService_Exception('No Windows Azure account key provided.');
   100         }
   100         }
   101             
   101 
   102         $this->_storageClient = new Zend_Service_WindowsAzure_Storage_Blob($host,
   102         $this->_storageClient = new Zend_Service_WindowsAzure_Storage_Blob($host,
   103              $options[self::ACCOUNT_NAME], $options[self::ACCOUNT_KEY]);
   103              $options[self::ACCOUNT_NAME], $options[self::ACCOUNT_KEY]);
   104         
   104 
   105         // Parse other options
   105         // Parse other options
   106         if (!empty($options[self::PROXY_HOST])) {
   106         if (!empty($options[self::PROXY_HOST])) {
   107             $proxyHost = $options[self::PROXY_HOST];
   107             $proxyHost = $options[self::PROXY_HOST];
   108             $proxyPort = isset($options[self::PROXY_PORT]) ? $options[self::PROXY_PORT] : 8080;
   108             $proxyPort = isset($options[self::PROXY_PORT]) ? $options[self::PROXY_PORT] : 8080;
   109             $proxyCredentials = isset($options[self::PROXY_CREDENTIALS]) ? $options[self::PROXY_CREDENTIALS] : '';
   109             $proxyCredentials = isset($options[self::PROXY_CREDENTIALS]) ? $options[self::PROXY_CREDENTIALS] : '';
   110             
   110 
   111             $this->_storageClient->setProxy(true, $proxyHost, $proxyPort, $proxyCredentials);
   111             $this->_storageClient->setProxy(true, $proxyHost, $proxyPort, $proxyCredentials);
   112         }
   112         }
   113         
   113 
   114         if (isset($options[self::HTTP_ADAPTER])) {
   114         if (isset($options[self::HTTP_ADAPTER])) {
   115             $this->_storageClient->setHttpClientChannel($options[self::HTTP_ADAPTER]);
   115             $this->_storageClient->setHttpClientChannel($options[self::HTTP_ADAPTER]);
   116         }
   116         }
   117         
   117 
   118         // Set container
   118         // Set container
   119         $this->_container = $options[self::CONTAINER];
   119         $this->_container = $options[self::CONTAINER];
   120 
   120 
   121         // Make sure the container exists
   121         // Make sure the container exists
   122         if (!$this->_storageClient->containerExists($this->_container)) {
   122         if (!$this->_storageClient->containerExists($this->_container)) {
   123             $this->_storageClient->createContainer($this->_container);
   123             $this->_storageClient->createContainer($this->_container);
   124         }
   124         }
   125     }
   125     }
   126     
   126 
   127     /**
   127     /**
   128      * Get an item from the storage service.
   128      * Get an item from the storage service.
   129      *
   129      *
   130      * @param  string $path
   130      * @param  string $path
   131      * @param  array $options
   131      * @param  array $options
   132      * @return mixed
   132      * @return mixed
   133      */
   133      */
   134     public function fetchItem($path, $options = null)
   134     public function fetchItem($path, $options = null)
   135     {
   135     {
   136         // Options
   136         // Options
   137         $returnType = self::RETURN_STRING; 
   137         $returnType = self::RETURN_STRING;
   138         $returnPath = tempnam('', 'azr');
   138         $returnPath = tempnam('', 'azr');
   139         $openMode   = 'r';
   139         $openMode   = 'r';
   140         
   140 
   141         // Parse options
   141         // Parse options
   142         if (is_array($options)) {
   142         if (is_array($options)) {
   143             if (isset($options[self::RETURN_TYPE])) {
   143             if (isset($options[self::RETURN_TYPE])) {
   144                 $returnType = $options[self::RETURN_TYPE];
   144                 $returnType = $options[self::RETURN_TYPE];
   145             }
   145             }
   146                 
   146 
   147             if (isset($options[self::RETURN_PATHNAME])) {
   147             if (isset($options[self::RETURN_PATHNAME])) {
   148                 $returnPath = $options[self::RETURN_PATHNAME];
   148                 $returnPath = $options[self::RETURN_PATHNAME];
   149             }
   149             }
   150                 
   150 
   151             if (isset($options[self::RETURN_OPENMODE])) {
   151             if (isset($options[self::RETURN_OPENMODE])) {
   152                 $openMode = $options[self::RETURN_OPENMODE];
   152                 $openMode = $options[self::RETURN_OPENMODE];
   153             }
   153             }
   154         }
   154         }
   155         
   155 
   156         // Fetch the blob
   156         // Fetch the blob
   157         try {
   157         try {
   158             $this->_storageClient->getBlob(
   158             $this->_storageClient->getBlob(
   159                 $this->_container,
   159                 $this->_container,
   160                 $path,
   160                 $path,
   164             if (strpos($e->getMessage(), "does not exist") !== false) {
   164             if (strpos($e->getMessage(), "does not exist") !== false) {
   165                 return false;
   165                 return false;
   166             }
   166             }
   167             throw new Zend_Cloud_StorageService_Exception('Error on fetch: '.$e->getMessage(), $e->getCode(), $e);
   167             throw new Zend_Cloud_StorageService_Exception('Error on fetch: '.$e->getMessage(), $e->getCode(), $e);
   168         }
   168         }
   169         
   169 
   170         // Return value
   170         // Return value
   171         if ($returnType == self::RETURN_PATH) {
   171         if ($returnType == self::RETURN_PATH) {
   172             return $returnPath;
   172             return $returnPath;
   173         }
   173         }
   174         if ($returnType == self::RETURN_STRING) {
   174         if ($returnType == self::RETURN_STRING) {
   176         }
   176         }
   177         if ($returnType == self::RETURN_STREAM) {
   177         if ($returnType == self::RETURN_STREAM) {
   178             return fopen($returnPath, $openMode);
   178             return fopen($returnPath, $openMode);
   179         }
   179         }
   180     }
   180     }
   181     
   181 
   182     /**
   182     /**
   183      * Store an item in the storage service.
   183      * Store an item in the storage service.
   184      * WARNING: This operation overwrites any item that is located at 
   184      * WARNING: This operation overwrites any item that is located at
   185      * $destinationPath.
   185      * $destinationPath.
   186      * @param string $destinationPath
   186      * @param string $destinationPath
   187      * @param mixed  $data
   187      * @param mixed  $data
   188      * @param  array $options
   188      * @param  array $options
   189      * @return boolean
   189      * @return boolean
   190      */
   190      */
   191     public function storeItem($destinationPath, $data, $options = null) 
   191     public function storeItem($destinationPath, $data, $options = null)
   192     {
   192     {
   193         // Create a temporary file that will be uploaded
   193         // Create a temporary file that will be uploaded
   194         $temporaryFilePath       = '';
   194         $temporaryFilePath       = '';
   195         $removeTemporaryFilePath = false;
   195         $removeTemporaryFilePath = false;
   196 
   196 
   201             $fpSource = $data;
   201             $fpSource = $data;
   202             rewind($fpSource);
   202             rewind($fpSource);
   203             while (!feof($fpSource)) {
   203             while (!feof($fpSource)) {
   204                 fwrite($fpDestination, fread($fpSource, 8192));
   204                 fwrite($fpDestination, fread($fpSource, 8192));
   205             }
   205             }
   206             
   206 
   207             fclose($fpDestination);
   207             fclose($fpDestination);
   208             
   208 
   209             $removeTemporaryFilePath = true;
   209             $removeTemporaryFilePath = true;
   210         } elseif (file_exists($data)) {
   210         } elseif (file_exists($data)) {
   211             $temporaryFilePath       = $data;
   211             $temporaryFilePath       = $data;
   212             $removeTemporaryFilePath = false;
   212             $removeTemporaryFilePath = false;
   213         } else {
   213         } else {
   214             $temporaryFilePath = tempnam('', 'azr');
   214             $temporaryFilePath = tempnam('', 'azr');
   215             file_put_contents($temporaryFilePath, $data);
   215             file_put_contents($temporaryFilePath, $data);
   216             $removeTemporaryFilePath = true;
   216             $removeTemporaryFilePath = true;
   217         }
   217         }
   218         
   218 
   219         try {
   219         try {
   220             // Upload data
   220             // Upload data
   221             $this->_storageClient->putBlob(
   221             $this->_storageClient->putBlob(
   222                 $this->_container,
   222                 $this->_container,
   223                 $destinationPath,
   223                 $destinationPath,
   224                 $temporaryFilePath
   224                 $temporaryFilePath
   225             );
   225             );
   226         } catch(Zend_Service_WindowsAzure_Exception $e) {
   226         } catch(Zend_Service_WindowsAzure_Exception $e) {
   227             @unlink($temporaryFilePath);
   227             @unlink($temporaryFilePath);
   228             throw new Zend_Cloud_StorageService_Exception('Error on store: '.$e->getMessage(), $e->getCode(), $e);        
   228             throw new Zend_Cloud_StorageService_Exception('Error on store: '.$e->getMessage(), $e->getCode(), $e);
   229         }
   229         }
   230         if ($removeTemporaryFilePath) {
   230         if ($removeTemporaryFilePath) {
   231             @unlink($temporaryFilePath);
   231             @unlink($temporaryFilePath);
   232         }
   232         }
   233     }
   233     }
   234     
   234 
   235     /**
   235     /**
   236      * Delete an item in the storage service.
   236      * Delete an item in the storage service.
   237      *
   237      *
   238      * @param  string $path
   238      * @param  string $path
   239      * @param  array  $options
   239      * @param  array  $options
   244         try {
   244         try {
   245             $this->_storageClient->deleteBlob(
   245             $this->_storageClient->deleteBlob(
   246                 $this->_container,
   246                 $this->_container,
   247                 $path
   247                 $path
   248             );
   248             );
   249         } catch (Zend_Service_WindowsAzure_Exception $e) { 
   249         } catch (Zend_Service_WindowsAzure_Exception $e) {
   250             throw new Zend_Cloud_StorageService_Exception('Error on delete: '.$e->getMessage(), $e->getCode(), $e);
   250             throw new Zend_Cloud_StorageService_Exception('Error on delete: '.$e->getMessage(), $e->getCode(), $e);
   251         }
   251         }
   252     }
   252     }
   253     
   253 
   254     /**
   254     /**
   255      * Copy an item in the storage service to a given path.
   255      * Copy an item in the storage service to a given path.
   256      *
   256      *
   257      * @param  string $sourcePath
   257      * @param  string $sourcePath
   258      * @param  string $destinationPath
   258      * @param  string $destinationPath
   266                 $this->_container,
   266                 $this->_container,
   267                 $sourcePath,
   267                 $sourcePath,
   268                 $this->_container,
   268                 $this->_container,
   269                 $destinationPath
   269                 $destinationPath
   270             );
   270             );
   271         } catch (Zend_Service_WindowsAzure_Exception $e) { 
   271         } catch (Zend_Service_WindowsAzure_Exception $e) {
   272             throw new Zend_Cloud_StorageService_Exception('Error on copy: '.$e->getMessage(), $e->getCode(), $e);
   272             throw new Zend_Cloud_StorageService_Exception('Error on copy: '.$e->getMessage(), $e->getCode(), $e);
   273         }
   273         }
   274     }
   274     }
   275     
   275 
   276     /**
   276     /**
   277      * Move an item in the storage service to a given path.
   277      * Move an item in the storage service to a given path.
   278      *
   278      *
   279      * @param  string $sourcePath
   279      * @param  string $sourcePath
   280      * @param  string $destinationPath
   280      * @param  string $destinationPath
   288                 $this->_container,
   288                 $this->_container,
   289                 $sourcePath,
   289                 $sourcePath,
   290                 $this->_container,
   290                 $this->_container,
   291                 $destinationPath
   291                 $destinationPath
   292             );
   292             );
   293             
   293 
   294             $this->_storageClient->deleteBlob(
   294             $this->_storageClient->deleteBlob(
   295                 $this->_container,
   295                 $this->_container,
   296                 $sourcePath
   296                 $sourcePath
   297             );
   297             );
   298         } catch (Zend_Service_WindowsAzure_Exception $e) { 
   298         } catch (Zend_Service_WindowsAzure_Exception $e) {
   299             throw new Zend_Cloud_StorageService_Exception('Error on move: '.$e->getMessage(), $e->getCode(), $e);
   299             throw new Zend_Cloud_StorageService_Exception('Error on move: '.$e->getMessage(), $e->getCode(), $e);
   300         }
   300         }
   301             
   301 
   302     }
   302     }
   303     
   303 
   304     /**
   304     /**
   305      * Rename an item in the storage service to a given name.
   305      * Rename an item in the storage service to a given name.
   306      *
   306      *
   307      *
   307      *
   308      * @param  string $path
   308      * @param  string $path
   312      */
   312      */
   313     public function renameItem($path, $name, $options = null)
   313     public function renameItem($path, $name, $options = null)
   314     {
   314     {
   315         return $this->moveItem($path, $name, $options);
   315         return $this->moveItem($path, $name, $options);
   316     }
   316     }
   317     
   317 
   318     /**
   318     /**
   319      * List items in the given directory in the storage service
   319      * List items in the given directory in the storage service
   320      * 
   320      *
   321      * The $path must be a directory
   321      * The $path must be a directory
   322      *
   322      *
   323      *
   323      *
   324      * @param  string $path Must be a directory
   324      * @param  string $path Must be a directory
   325      * @param  array $options
   325      * @param  array $options
   327      */
   327      */
   328     public function listItems($path, $options = null)
   328     public function listItems($path, $options = null)
   329     {
   329     {
   330         // Options
   330         // Options
   331         $returnType = self::RETURN_NAMES; // 1: return list of paths, 2: return raw output from underlying provider
   331         $returnType = self::RETURN_NAMES; // 1: return list of paths, 2: return raw output from underlying provider
   332         
   332 
   333         // Parse options
   333         // Parse options
   334         if (is_array($options)&& isset($options[self::RETURN_TYPE])) {
   334         if (is_array($options)&& isset($options[self::RETURN_TYPE])) {
   335                $returnType = $options[self::RETURN_TYPE];
   335                $returnType = $options[self::RETURN_TYPE];
   336         }
   336         }
   337         
   337 
   338         try {
   338         try {
   339             // Fetch list
   339             // Fetch list
   340             $blobList = $this->_storageClient->listBlobs(
   340             $blobList = $this->_storageClient->listBlobs(
   341                 $this->_container,
   341                 $this->_container,
   342                 $path
   342                 $path
   343             );
   343             );
   344         } catch (Zend_Service_WindowsAzure_Exception $e) { 
   344         } catch (Zend_Service_WindowsAzure_Exception $e) {
   345             throw new Zend_Cloud_StorageService_Exception('Error on list: '.$e->getMessage(), $e->getCode(), $e);
   345             throw new Zend_Cloud_StorageService_Exception('Error on list: '.$e->getMessage(), $e->getCode(), $e);
   346         }
   346         }
   347         
   347 
   348         // Return
   348         // Return
   349         if ($returnType == self::RETURN_LIST) {
   349         if ($returnType == self::RETURN_LIST) {
   350             return $blobList;
   350             return $blobList;
   351         }
   351         }
   352         
   352 
   353         $returnValue = array();
   353         $returnValue = array();
   354         foreach ($blobList as $blob) {
   354         foreach ($blobList as $blob) {
   355             $returnValue[] = $blob->Name;
   355             $returnValue[] = $blob->Name;
   356         }
   356         }
   357             
   357 
   358         return $returnValue;
   358         return $returnValue;
   359     }
   359     }
   360 
   360 
   361     /**
   361     /**
   362      * Get a key/value array of metadata for the given path.
   362      * Get a key/value array of metadata for the given path.
   377                 return false;
   377                 return false;
   378             }
   378             }
   379             throw new Zend_Cloud_StorageService_Exception('Error on fetch: '.$e->getMessage(), $e->getCode(), $e);
   379             throw new Zend_Cloud_StorageService_Exception('Error on fetch: '.$e->getMessage(), $e->getCode(), $e);
   380         }
   380         }
   381     }
   381     }
   382     
   382 
   383     /**
   383     /**
   384      * Store a key/value array of metadata at the given path.
   384      * Store a key/value array of metadata at the given path.
   385      * WARNING: This operation overwrites any metadata that is located at 
   385      * WARNING: This operation overwrites any metadata that is located at
   386      * $destinationPath.
   386      * $destinationPath.
   387      *
   387      *
   388      * @param  string $destinationPath
   388      * @param  string $destinationPath
   389      * @param  array $options
   389      * @param  array $options
   390      * @return void
   390      * @return void
   397             if (strpos($e->getMessage(), "could not be accessed") === false) {
   397             if (strpos($e->getMessage(), "could not be accessed") === false) {
   398                 throw new Zend_Cloud_StorageService_Exception('Error on store metadata: '.$e->getMessage(), $e->getCode(), $e);
   398                 throw new Zend_Cloud_StorageService_Exception('Error on store metadata: '.$e->getMessage(), $e->getCode(), $e);
   399             }
   399             }
   400         }
   400         }
   401     }
   401     }
   402     
   402 
   403     /**
   403     /**
   404      * Delete a key/value array of metadata at the given path.
   404      * Delete a key/value array of metadata at the given path.
   405      *
   405      *
   406      * @param  string $path
   406      * @param  string $path
   407      * @param  array $options
   407      * @param  array $options
   415             if (strpos($e->getMessage(), "could not be accessed") === false) {
   415             if (strpos($e->getMessage(), "could not be accessed") === false) {
   416                 throw new Zend_Cloud_StorageService_Exception('Error on delete metadata: '.$e->getMessage(), $e->getCode(), $e);
   416                 throw new Zend_Cloud_StorageService_Exception('Error on delete metadata: '.$e->getMessage(), $e->getCode(), $e);
   417             }
   417             }
   418         }
   418         }
   419     }
   419     }
   420     
   420 
   421     /**
   421     /**
   422      * Delete container
   422      * Delete container
   423      * 
   423      *
   424      * @return void
   424      * @return void
   425      */
   425      */
   426     public function deleteContainer()
   426     public function deleteContainer()
   427     {
   427     {
   428         try {
   428         try {
   429             $this->_storageClient->deleteContainer($this->_container);
   429             $this->_storageClient->deleteContainer($this->_container);
   430         } catch (Zend_Service_WindowsAzure_Exception $e) { 
   430         } catch (Zend_Service_WindowsAzure_Exception $e) {
   431             throw new Zend_Cloud_StorageService_Exception('Error on delete: '.$e->getMessage(), $e->getCode(), $e);
   431             throw new Zend_Cloud_StorageService_Exception('Error on delete: '.$e->getMessage(), $e->getCode(), $e);
   432         }
   432         }
   433     }
   433     }
   434 
   434 
   435     /**
   435     /**
   436      * Get the concrete adapter.
   436      * Get the concrete adapter.
   437      * @return Zend_Service_Azure_Storage_Blob
   437      * @return Zend_Service_Azure_Storage_Blob
   438      */
   438      */
   439     public function getClient()
   439     public function getClient()
   440     {
   440     {
   441          return $this->_storageClient;       
   441          return $this->_storageClient;
   442     }
   442     }
   443 }
   443 }