[ Index ]

PHP Cross Reference of Phabricator

title

Body

[close]

/src/applications/files/engine/ -> PhabricatorS3FileStorageEngine.php (source)

   1  <?php
   2  
   3  /**
   4   * Amazon S3 file storage engine. This engine scales well but is relatively
   5   * high-latency since data has to be pulled off S3.
   6   *
   7   * @task internal Internals
   8   */
   9  final class PhabricatorS3FileStorageEngine
  10    extends PhabricatorFileStorageEngine {
  11  
  12  
  13  /* -(  Implementation  )----------------------------------------------------- */
  14  
  15  
  16    /**
  17     * This engine identifies as `amazon-s3`.
  18     */
  19    public function getEngineIdentifier() {
  20      return 'amazon-s3';
  21    }
  22  
  23  
  24    /**
  25     * Writes file data into Amazon S3.
  26     */
  27    public function writeFile($data, array $params) {
  28      $s3 = $this->newS3API();
  29  
  30      // Generate a random name for this file. We add some directories to it
  31      // (e.g. 'abcdef123456' becomes 'ab/cd/ef123456') to make large numbers of
  32      // files more browsable with web/debugging tools like the S3 administration
  33      // tool.
  34      $seed = Filesystem::readRandomCharacters(20);
  35      $parts = array(
  36        substr($seed, 0, 2),
  37        substr($seed, 2, 2),
  38        substr($seed, 4),
  39      );
  40      $name = 'phabricator/'.implode('/', $parts);
  41  
  42      AphrontWriteGuard::willWrite();
  43      $profiler = PhutilServiceProfiler::getInstance();
  44      $call_id = $profiler->beginServiceCall(
  45        array(
  46          'type' => 's3',
  47          'method' => 'putObject',
  48        ));
  49      $s3->putObject(
  50        $data,
  51        $this->getBucketName(),
  52        $name,
  53        $acl = 'private');
  54      $profiler->endServiceCall($call_id, array());
  55  
  56      return $name;
  57    }
  58  
  59  
  60    /**
  61     * Load a stored blob from Amazon S3.
  62     */
  63    public function readFile($handle) {
  64      $s3 = $this->newS3API();
  65      $profiler = PhutilServiceProfiler::getInstance();
  66      $call_id = $profiler->beginServiceCall(
  67        array(
  68          'type' => 's3',
  69          'method' => 'getObject',
  70        ));
  71      $result = $s3->getObject(
  72        $this->getBucketName(),
  73        $handle);
  74      $profiler->endServiceCall($call_id, array());
  75  
  76      // NOTE: The implementation of the API that we're using may respond with
  77      // a successful result that has length 0 and no body property.
  78      if (isset($result->body)) {
  79        return $result->body;
  80      } else {
  81        return '';
  82      }
  83    }
  84  
  85  
  86    /**
  87     * Delete a blob from Amazon S3.
  88     */
  89    public function deleteFile($handle) {
  90      AphrontWriteGuard::willWrite();
  91      $s3 = $this->newS3API();
  92      $profiler = PhutilServiceProfiler::getInstance();
  93      $call_id = $profiler->beginServiceCall(
  94        array(
  95          'type' => 's3',
  96          'method' => 'deleteObject',
  97        ));
  98      $s3->deleteObject(
  99        $this->getBucketName(),
 100        $handle);
 101      $profiler->endServiceCall($call_id, array());
 102    }
 103  
 104  
 105  /* -(  Internals  )---------------------------------------------------------- */
 106  
 107  
 108    /**
 109     * Retrieve the S3 bucket name.
 110     *
 111     * @task internal
 112     */
 113    private function getBucketName() {
 114      $bucket = PhabricatorEnv::getEnvConfig('storage.s3.bucket');
 115      if (!$bucket) {
 116        throw new PhabricatorFileStorageConfigurationException(
 117          "No 'storage.s3.bucket' specified!");
 118      }
 119      return $bucket;
 120    }
 121  
 122    /**
 123     * Create a new S3 API object.
 124     *
 125     * @task internal
 126     * @phutil-external-symbol class S3
 127     */
 128    private function newS3API() {
 129      $libroot = dirname(phutil_get_library_root('phabricator'));
 130      require_once $libroot.'/externals/s3/S3.php';
 131  
 132      $access_key = PhabricatorEnv::getEnvConfig('amazon-s3.access-key');
 133      $secret_key = PhabricatorEnv::getEnvConfig('amazon-s3.secret-key');
 134      $endpoint = PhabricatorEnv::getEnvConfig('amazon-s3.endpoint');
 135  
 136      if (!$access_key || !$secret_key) {
 137        throw new PhabricatorFileStorageConfigurationException(
 138          "Specify 'amazon-s3.access-key' and 'amazon-s3.secret-key'!");
 139      }
 140  
 141      if ($endpoint !== null) {
 142        $s3 = new S3($access_key, $secret_key, $use_ssl = true, $endpoint);
 143      } else {
 144        $s3 = new S3($access_key, $secret_key, $use_ssl = true);
 145      }
 146  
 147      $s3->setExceptions(true);
 148  
 149      return $s3;
 150    }
 151  
 152  }


Generated: Sun Nov 30 09:20:46 2014 Cross-referenced by PHPXref 0.7.1