[ Index ] |
PHP Cross Reference of Phabricator |
[Summary view] [Print] [Text view]
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 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body
Generated: Sun Nov 30 09:20:46 2014 | Cross-referenced by PHPXref 0.7.1 |