web/enmi/Zend/Cloud/StorageService/Adapter/Nirvanix.php
changeset 19 1c2f13fd785c
parent 0 4eba9c11703f
equal deleted inserted replaced
18:bd595ad770fc 19:1c2f13fd785c
       
     1 <?php
       
     2 /**
       
     3  * LICENSE
       
     4  *
       
     5  * This source file is subject to the new BSD license that is bundled
       
     6  * with this package in the file LICENSE.txt.
       
     7  * It is also available through the world-wide-web at this URL:
       
     8  * http://framework.zend.com/license/new-bsd
       
     9  * If you did not receive a copy of the license and are unable to
       
    10  * obtain it through the world-wide-web, please send an email
       
    11  * to license@zend.com so we can send you a copy immediately.
       
    12  *
       
    13  * @category   Zend
       
    14  * @package    Zend_Cloud
       
    15  * @subpackage StorageService
       
    16  * @copyright  Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com)
       
    17  * @license    http://framework.zend.com/license/new-bsd     New BSD License
       
    18  */
       
    19 
       
    20 require_once 'Zend/Cloud/StorageService/Adapter.php';
       
    21 require_once 'Zend/Cloud/StorageService/Exception.php';
       
    22 require_once 'Zend/Service/Nirvanix.php';
       
    23 
       
    24 /**
       
    25  * Adapter for Nirvanix cloud storage
       
    26  *
       
    27  * @category   Zend
       
    28  * @package    Zend_Cloud
       
    29  * @subpackage StorageService
       
    30  * @copyright  Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com)
       
    31  * @license    http://framework.zend.com/license/new-bsd     New BSD License
       
    32  */
       
    33 class Zend_Cloud_StorageService_Adapter_Nirvanix 
       
    34     implements Zend_Cloud_StorageService_Adapter
       
    35 {
       
    36     const USERNAME         = 'auth_username';
       
    37     const PASSWORD         = 'auth_password';
       
    38     const APP_KEY          = 'auth_accesskey';
       
    39     const REMOTE_DIRECTORY = 'remote_directory';
       
    40 
       
    41     /**
       
    42      * The Nirvanix adapter
       
    43      * @var Zend_Service_Nirvanix
       
    44      */
       
    45     protected $_nirvanix;
       
    46     protected $_imfNs;
       
    47     protected $_metadataNs;
       
    48     protected $_remoteDirectory;
       
    49     private $maxPageSize = 500;
       
    50 
       
    51     /**
       
    52      * Constructor
       
    53      * 
       
    54      * @param  array|Zend_Config $options 
       
    55      * @return void
       
    56      */
       
    57     function __construct($options = array()) 
       
    58     {
       
    59         if ($options instanceof Zend_Config) {
       
    60             $options = $options->toArray();
       
    61         }
       
    62 
       
    63         if (!is_array($options)) {
       
    64             throw new Zend_Cloud_StorageService_Exception('Invalid options provided');
       
    65         }
       
    66 
       
    67         $auth = array(
       
    68             'username' => $options[self::USERNAME],
       
    69             'password' => $options[self::PASSWORD],
       
    70             'appKey'   => $options[self::APP_KEY],
       
    71         );
       
    72         $nirvanix_options = array();
       
    73         if (isset($options[self::HTTP_ADAPTER])) {
       
    74             $httpc = new Zend_Http_Client();
       
    75             $httpc->setAdapter($options[self::HTTP_ADAPTER]);
       
    76             $nirvanix_options['httpClient'] = $httpc;
       
    77         } 
       
    78         try {
       
    79             $this->_nirvanix = new Zend_Service_Nirvanix($auth, $nirvanix_options);
       
    80             $this->_remoteDirectory = $options[self::REMOTE_DIRECTORY];
       
    81             $this->_imfNs = $this->_nirvanix->getService('IMFS');
       
    82             $this->_metadataNs = $this->_nirvanix->getService('Metadata');
       
    83         } catch (Zend_Service_Nirvanix_Exception  $e) { 
       
    84             throw new Zend_Cloud_StorageService_Exception('Error on create: '.$e->getMessage(), $e->getCode(), $e);
       
    85         }
       
    86     }
       
    87 
       
    88      /**
       
    89      * Get an item from the storage service.
       
    90      *
       
    91      * @param  string $path
       
    92      * @param  array $options
       
    93      * @return mixed
       
    94      */
       
    95     public function fetchItem($path, $options = null)
       
    96     {
       
    97         $path = $this->_getFullPath($path);
       
    98         try {
       
    99             $item = $this->_imfNs->getContents($path);
       
   100         } catch (Zend_Service_Nirvanix_Exception $e) {
       
   101             throw new Zend_Cloud_StorageService_Exception('Error on fetch: '.$e->getMessage(), $e->getCode(), $e);
       
   102         }
       
   103         return $item;
       
   104     }
       
   105 
       
   106     /**
       
   107      * Store an item in the storage service.
       
   108      * WARNING: This operation overwrites any item that is located at
       
   109      * $destinationPath.
       
   110      * @param string $destinationPath
       
   111      * @param mixed $data
       
   112      * @param  array $options
       
   113      * @return void
       
   114      */
       
   115     public function storeItem($destinationPath, $data, $options = null)
       
   116     {
       
   117         try {
       
   118             $path = $this->_getFullPath($destinationPath);
       
   119             $this->_imfNs->putContents($path, $data);
       
   120         } catch (Zend_Service_Nirvanix_Exception $e) {
       
   121             throw new Zend_Cloud_StorageService_Exception('Error on store: '.$e->getMessage(), $e->getCode(), $e);
       
   122         }
       
   123         return true;
       
   124     }
       
   125 
       
   126     /**
       
   127      * Delete an item in the storage service.
       
   128      *
       
   129      * @param  string $path
       
   130      * @param  array $options
       
   131      * @return void
       
   132      */
       
   133     public function deleteItem($path, $options = null)
       
   134     {
       
   135         try {
       
   136             $path = $this->_getFullPath($path);
       
   137             $this->_imfNs->unlink($path);
       
   138         } catch(Zend_Service_Nirvanix_Exception $e) {
       
   139 //            if (trim(strtoupper($e->getMessage())) != 'INVALID PATH') {
       
   140 //                // TODO Differentiate among errors in the Nirvanix adapter
       
   141             throw new Zend_Cloud_StorageService_Exception('Error on delete: '.$e->getMessage(), $e->getCode(), $e);
       
   142         }
       
   143     }
       
   144 
       
   145     /**
       
   146      * Copy an item in the storage service to a given path.
       
   147      * WARNING: This operation is *very* expensive for services that do not
       
   148      * support copying an item natively.
       
   149      *
       
   150      * @param  string $sourcePath
       
   151      * @param  string $destination path
       
   152      * @param  array $options
       
   153      * @return void
       
   154      */
       
   155     public function copyItem($sourcePath, $destinationPath, $options = null)
       
   156     {
       
   157         try {
       
   158             $sourcePath = $this->_getFullPath($sourcePath);
       
   159             $destinationPath = $this->_getFullPath($destinationPath);
       
   160             $this->_imfNs->CopyFiles(array('srcFilePath' => $sourcePath,
       
   161                                             'destFolderPath' => $destinationPath));
       
   162         } catch (Zend_Service_Nirvanix_Exception $e) {
       
   163             throw new Zend_Cloud_StorageService_Exception('Error on copy: '.$e->getMessage(), $e->getCode(), $e);
       
   164         }
       
   165     }
       
   166 
       
   167     /**
       
   168      * Move an item in the storage service to a given path.
       
   169      * WARNING: This operation is *very* expensive for services that do not
       
   170      * support moving an item natively.
       
   171      *
       
   172      * @param  string $sourcePath
       
   173      * @param  string $destination path
       
   174      * @param  array $options
       
   175      * @return void
       
   176      */
       
   177     public function moveItem($sourcePath, $destinationPath, $options = null)
       
   178     {
       
   179         try {
       
   180             $sourcePath = $this->_getFullPath($sourcePath);
       
   181             $destinationPath = $this->_getFullPath($destinationPath);
       
   182             $this->_imfNs->RenameFile(array('filePath' => $sourcePath,
       
   183                                              'newFileName' => $destinationPath));
       
   184     //        $this->_imfNs->MoveFiles(array('srcFilePath' => $sourcePath,
       
   185     //                                         'destFolderPath' => $destinationPath));
       
   186         } catch (Zend_Service_Nirvanix_Exception $e) {
       
   187             throw new Zend_Cloud_StorageService_Exception('Error on move: '.$e->getMessage(), $e->getCode(), $e);
       
   188         }
       
   189     }
       
   190 
       
   191     /**
       
   192      * Rename an item in the storage service to a given name.
       
   193      *
       
   194      *
       
   195      * @param  string $path
       
   196      * @param  string $name
       
   197      * @param  array $options
       
   198      * @return void
       
   199      */
       
   200     public function renameItem($path, $name, $options = null) 
       
   201     {
       
   202         require_once 'Zend/Cloud/OperationNotAvailableException.php';
       
   203         throw new Zend_Cloud_OperationNotAvailableException('Renaming not implemented');
       
   204     }
       
   205 
       
   206     /**
       
   207      * Get a key/value array of metadata for the given path.
       
   208      *
       
   209      * @param  string $path
       
   210      * @param  array $options
       
   211      * @return array An associative array of key/value pairs specifying the metadata for this object.
       
   212      *                  If no metadata exists, an empty array is returned.
       
   213      */
       
   214     public function fetchMetadata($path, $options = null)
       
   215     {
       
   216         $path = $this->_getFullPath($path);
       
   217         try {
       
   218             $metadataNode = $this->_metadataNs->getMetadata(array('path' => $path));
       
   219         } catch (Zend_Service_Nirvanix_Exception $e) {
       
   220             throw new Zend_Cloud_StorageService_Exception('Error on fetching metadata: '.$e->getMessage(), $e->getCode(), $e);
       
   221         }
       
   222             
       
   223         $metadata = array();
       
   224         $length = count($metadataNode->Metadata);
       
   225 
       
   226         // Need to special case this as Nirvanix returns an array if there is
       
   227         // more than one, but doesn't return an array if there is only one.
       
   228         if ($length == 1)
       
   229         {
       
   230             $metadata[(string)$metadataNode->Metadata->Type->value] = (string)$metadataNode->Metadata->Value;
       
   231         }
       
   232         else if ($length > 1)
       
   233         {
       
   234             for ($i=0; $i<$length; $i++)
       
   235             {
       
   236                 $metadata[(string)$metadataNode->Metadata[$i]->Type] = (string)$metadataNode->Metadata[$i]->Value;
       
   237             }
       
   238         }
       
   239         return $metadata;
       
   240     }
       
   241 
       
   242     /**
       
   243      * Store a key/value array of metadata at the given path.
       
   244      * WARNING: This operation overwrites any metadata that is located at
       
   245      * $destinationPath.
       
   246      *
       
   247      * @param array $metadata - An associative array specifying the key/value pairs for the metadata.
       
   248      * @param $destinationPath
       
   249      * @param  array $options
       
   250      * @return void
       
   251      */
       
   252     public function storeMetadata($destinationPath, $metadata, $options = null)
       
   253     {
       
   254         $destinationPath = $this->_getFullPath($destinationPath);
       
   255         if ($metadata != null) {
       
   256             try {
       
   257                 foreach ($metadata AS $key=>$value) {
       
   258                     $metadataString = $key . ":" . $value;
       
   259                     $this->_metadataNs->SetMetadata(array(
       
   260                         'path'     => $destinationPath,
       
   261                         'metadata' => $metadataString,
       
   262                     ));
       
   263                 }
       
   264             } catch (Zend_Service_Nirvanix_Exception $e) {
       
   265                 throw new Zend_Cloud_StorageService_Exception('Error on storing metadata: '.$e->getMessage(), $e->getCode(), $e);
       
   266             }
       
   267         }
       
   268      }
       
   269 
       
   270     /**
       
   271      * Delete a key/value array of metadata at the given path.
       
   272      *
       
   273      * @param string $path
       
   274      * @param array $metadata - An associative array specifying the key/value pairs for the metadata
       
   275      *                          to be deleted.  If null, all metadata associated with the object will
       
   276      *                          be deleted.
       
   277      * @param  array $options
       
   278      * @return void
       
   279      */
       
   280     public function deleteMetadata($path, $metadata = null, $options = null)
       
   281     {
       
   282         $path = $this->_getFullPath($path);
       
   283         try {
       
   284             if ($metadata == null) {
       
   285                 $this->_metadataNs->DeleteAllMetadata(array('path' => $path));
       
   286             } else {
       
   287                 foreach ($metadata AS $key=>$value) {
       
   288                     $this->_metadataNs->DeleteMetadata(array(
       
   289                         'path'     => $path,
       
   290                         'metadata' => $key,
       
   291                     ));
       
   292                     }
       
   293             }
       
   294         } catch (Zend_Service_Nirvanix_Exception $e) {
       
   295             throw new Zend_Cloud_StorageService_Exception('Error on deleting metadata: '.$e->getMessage(), $e->getCode(), $e);
       
   296         }            
       
   297     }
       
   298 
       
   299     /*
       
   300      * Recursively traverse all the folders and build an array that contains
       
   301      * the path names for each folder.
       
   302      *
       
   303      * @param $path - The folder path to get the list of folders from.
       
   304      * @param &$resultArray - reference to the array that contains the path names
       
   305      *                           for each folder.
       
   306      */
       
   307     private function getAllFolders($path, &$resultArray)
       
   308     {
       
   309         $response = $this->_imfNs->ListFolder(array(
       
   310             'folderPath' => $path,
       
   311                'pageNumber' => 1,
       
   312             'pageSize'   => $this->maxPageSize,
       
   313         ));
       
   314            $numFolders = $response->ListFolder->TotalFolderCount;
       
   315            if ($numFolders == 0) {
       
   316                return;
       
   317            } else {
       
   318                //Need to special case this as Nirvanix returns an array if there is
       
   319                //more than one, but doesn't return an array if there is only one.
       
   320             if ($numFolders == 1) {
       
   321                 $folderPath = $response->ListFolder->Folder->Path;
       
   322                 array_push($resultArray, $folderPath);
       
   323                 $this->getAllFolders('/' . $folderPath, $resultArray);
       
   324             } else {
       
   325                 foreach ($response->ListFolder->Folder as $arrayElem) {
       
   326                     $folderPath = $arrayElem->Path;
       
   327                     array_push($resultArray, $folderPath);
       
   328                     $this->getAllFolders('/' . $folderPath, $resultArray);
       
   329                 }
       
   330             }
       
   331            }
       
   332     }
       
   333 
       
   334     /**
       
   335      * Return an array of the items contained in the given path.  The items
       
   336      * returned are the files or objects that in the specified path.
       
   337      *
       
   338      * @param  string $path
       
   339      * @param  array  $options
       
   340      * @return array
       
   341      */
       
   342     public function listItems($path, $options = null)
       
   343     {
       
   344         $path = $this->_getFullPath($path);
       
   345         $resultArray = array();
       
   346 
       
   347         if (!isset($path)) {
       
   348             return false;
       
   349         } else {
       
   350             try {
       
   351                 $response = $this->_imfNs->ListFolder(array(
       
   352                     'folderPath' => $path,
       
   353                     'pageNumber' => 1,
       
   354                     'pageSize'   => $this->maxPageSize,
       
   355                 ));
       
   356             } catch (Zend_Service_Nirvanix_Exception $e) {
       
   357                 throw new Zend_Cloud_StorageService_Exception('Error on list: '.$e->getMessage(), $e->getCode(), $e);
       
   358             }            
       
   359                 
       
   360             $numFiles = $response->ListFolder->TotalFileCount;
       
   361 
       
   362             //Add the file names to the array
       
   363             if ($numFiles != 0) {
       
   364                 //Need to special case this as Nirvanix returns an array if there is
       
   365                 //more than one, but doesn't return an array if there is only one.
       
   366                 if ($numFiles == 1) {
       
   367                     $resultArray[] = (string)$response->ListFolder->File->Name;
       
   368                 }
       
   369                 else {
       
   370                     foreach ($response->ListFolder->File as $arrayElem) {
       
   371                         $resultArray[] = (string) $arrayElem->Name;
       
   372                     }
       
   373                 }
       
   374             }
       
   375         }
       
   376 
       
   377         return $resultArray;
       
   378     }
       
   379 
       
   380     /**
       
   381      * Get full path to an object
       
   382      * 
       
   383      * @param  string $path 
       
   384      * @return string
       
   385      */
       
   386     private function _getFullPath($path) 
       
   387     {
       
   388         return $this->_remoteDirectory . $path;
       
   389     }
       
   390 
       
   391     /**
       
   392      * Get the concrete client.
       
   393      * @return Zend_Service_Nirvanix
       
   394      */
       
   395     public function getClient()
       
   396     {
       
   397          return $this->_nirvanix;       
       
   398     }
       
   399 }