Swift.php 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134
  1. <?php
  2. /**
  3. * @copyright Copyright (c) 2016, ownCloud, Inc.
  4. *
  5. * @author Jörn Friedrich Dreyer <jfd@butonic.de>
  6. * @author Morris Jobke <hey@morrisjobke.de>
  7. * @author Robin Appelman <robin@icewind.nl>
  8. * @author William Pain <pain.william@gmail.com>
  9. *
  10. * @license AGPL-3.0
  11. *
  12. * This code is free software: you can redistribute it and/or modify
  13. * it under the terms of the GNU Affero General Public License, version 3,
  14. * as published by the Free Software Foundation.
  15. *
  16. * This program is distributed in the hope that it will be useful,
  17. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  18. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  19. * GNU Affero General Public License for more details.
  20. *
  21. * You should have received a copy of the GNU Affero General Public License, version 3,
  22. * along with this program. If not, see <http://www.gnu.org/licenses/>
  23. *
  24. */
  25. namespace OC\Files\ObjectStore;
  26. use function GuzzleHttp\Psr7\stream_for;
  27. use Icewind\Streams\RetryWrapper;
  28. use OCP\Files\NotFoundException;
  29. use OCP\Files\ObjectStore\IObjectStore;
  30. use OCP\Files\StorageAuthException;
  31. use OpenStack\Common\Error\BadResponseError;
  32. class Swift implements IObjectStore {
  33. /**
  34. * @var array
  35. */
  36. private $params;
  37. /** @var SwiftFactory */
  38. private $swiftFactory;
  39. public function __construct($params, SwiftFactory $connectionFactory = null) {
  40. $this->swiftFactory = $connectionFactory ?: new SwiftFactory(
  41. \OC::$server->getMemCacheFactory()->createDistributed('swift::'),
  42. $params,
  43. \OC::$server->getLogger()
  44. );
  45. $this->params = $params;
  46. }
  47. /**
  48. * @return \OpenStack\ObjectStore\v1\Models\Container
  49. * @throws StorageAuthException
  50. * @throws \OCP\Files\StorageNotAvailableException
  51. */
  52. private function getContainer() {
  53. return $this->swiftFactory->getContainer();
  54. }
  55. /**
  56. * @return string the container name where objects are stored
  57. */
  58. public function getStorageId() {
  59. if (isset($this->params['bucket'])) {
  60. return $this->params['bucket'];
  61. }
  62. return $this->params['container'];
  63. }
  64. /**
  65. * @param string $urn the unified resource name used to identify the object
  66. * @param resource $stream stream with the data to write
  67. * @throws \Exception from openstack lib when something goes wrong
  68. */
  69. public function writeObject($urn, $stream) {
  70. $this->getContainer()->createObject([
  71. 'name' => $urn,
  72. 'stream' => stream_for($stream)
  73. ]);
  74. }
  75. /**
  76. * @param string $urn the unified resource name used to identify the object
  77. * @return resource stream with the read data
  78. * @throws \Exception from openstack lib when something goes wrong
  79. * @throws NotFoundException if file does not exist
  80. */
  81. public function readObject($urn) {
  82. try {
  83. $object = $this->getContainer()->getObject($urn);
  84. // we need to keep a reference to objectContent or
  85. // the stream will be closed before we can do anything with it
  86. $objectContent = $object->download();
  87. } catch (BadResponseError $e) {
  88. if ($e->getResponse()->getStatusCode() === 404) {
  89. throw new NotFoundException("object $urn not found in object store");
  90. } else {
  91. throw $e;
  92. }
  93. }
  94. $objectContent->rewind();
  95. $stream = $objectContent->detach();
  96. // save the object content in the context of the stream to prevent it being gc'd until the stream is closed
  97. stream_context_set_option($stream, 'swift', 'content', $objectContent);
  98. return RetryWrapper::wrap($stream);
  99. }
  100. /**
  101. * @param string $urn Unified Resource Name
  102. * @return void
  103. * @throws \Exception from openstack lib when something goes wrong
  104. */
  105. public function deleteObject($urn) {
  106. $this->getContainer()->getObject($urn)->delete();
  107. }
  108. /**
  109. * @return void
  110. * @throws \Exception from openstack lib when something goes wrong
  111. */
  112. public function deleteContainer() {
  113. $this->getContainer()->delete();
  114. }
  115. public function objectExists($urn) {
  116. return $this->getContainer()->objectExists($urn);
  117. }
  118. }