Passed
Push — master ( e165dc...217243 )
by Roeland
12:21 queued 10s
created

Swift::deleteContainer()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 2
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 1
nc 1
nop 0
dl 0
loc 2
rs 10
c 0
b 0
f 0
1
<?php
2
/**
3
 * @copyright Copyright (c) 2016, ownCloud, Inc.
4
 *
5
 * @author Adrian Brzezinski <[email protected]>
6
 * @author Jörn Friedrich Dreyer <[email protected]>
7
 * @author Morris Jobke <[email protected]>
8
 * @author Robin Appelman <[email protected]>
9
 * @author Roeland Jago Douma <[email protected]>
10
 *
11
 * @license AGPL-3.0
12
 *
13
 * This code is free software: you can redistribute it and/or modify
14
 * it under the terms of the GNU Affero General Public License, version 3,
15
 * as published by the Free Software Foundation.
16
 *
17
 * This program is distributed in the hope that it will be useful,
18
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20
 * GNU Affero General Public License for more details.
21
 *
22
 * You should have received a copy of the GNU Affero General Public License, version 3,
23
 * along with this program. If not, see <http://www.gnu.org/licenses/>
24
 *
25
 */
26
27
namespace OC\Files\ObjectStore;
28
29
use GuzzleHttp\Client;
30
use GuzzleHttp\Exception\BadResponseException;
31
use function GuzzleHttp\Psr7\stream_for;
32
use Icewind\Streams\RetryWrapper;
33
use OCP\Files\NotFoundException;
34
use OCP\Files\ObjectStore\IObjectStore;
35
use OCP\Files\StorageAuthException;
36
37
const SWIFT_SEGMENT_SIZE = 1073741824; // 1GB
38
39
class Swift implements IObjectStore {
40
	/**
41
	 * @var array
42
	 */
43
	private $params;
44
45
	/** @var SwiftFactory */
46
	private $swiftFactory;
47
48
	public function __construct($params, SwiftFactory $connectionFactory = null) {
49
		$this->swiftFactory = $connectionFactory ?: new SwiftFactory(
50
			\OC::$server->getMemCacheFactory()->createDistributed('swift::'),
51
			$params,
52
			\OC::$server->getLogger()
53
		);
54
		$this->params = $params;
55
	}
56
57
	/**
58
	 * @return \OpenStack\ObjectStore\v1\Models\Container
59
	 * @throws StorageAuthException
60
	 * @throws \OCP\Files\StorageNotAvailableException
61
	 */
62
	private function getContainer() {
63
		return $this->swiftFactory->getContainer();
64
	}
65
66
	/**
67
	 * @return string the container name where objects are stored
68
	 */
69
	public function getStorageId() {
70
		if (isset($this->params['bucket'])) {
71
			return $this->params['bucket'];
72
		}
73
74
		return $this->params['container'];
75
	}
76
77
	/**
78
	 * @param string $urn the unified resource name used to identify the object
79
	 * @param resource $stream stream with the data to write
80
	 * @throws \Exception from openstack lib when something goes wrong
81
	 */
82
	public function writeObject($urn, $stream) {
83
		$tmpFile = \OC::$server->getTempManager()->getTemporaryFile('swiftwrite');
84
		file_put_contents($tmpFile, $stream);
85
		$handle = fopen($tmpFile, 'rb');
86
87
		if (filesize($tmpFile) < SWIFT_SEGMENT_SIZE) {
88
			$this->getContainer()->createObject([
89
				'name' => $urn,
90
				'stream' => stream_for($handle),
91
			]);
92
		} else {
93
			$this->getContainer()->createLargeObject([
94
				'name' => $urn,
95
				'stream' => stream_for($handle),
96
				'segmentSize' => SWIFT_SEGMENT_SIZE,
97
			]);
98
		}
99
	}
100
101
	/**
102
	 * @param string $urn the unified resource name used to identify the object
103
	 * @return resource stream with the read data
104
	 * @throws \Exception from openstack or GuzzleHttp libs when something goes wrong
105
	 * @throws NotFoundException if file does not exist
106
	 */
107
	public function readObject($urn) {
108
		try {
109
			$publicUri = $this->getContainer()->getObject($urn)->getPublicUri();
110
			$tokenId = $this->swiftFactory->getCachedTokenId();
111
112
			$response = (new Client())->request('GET', $publicUri,
113
				[
114
					'stream' => true,
115
					'headers' => [
116
						'X-Auth-Token' => $tokenId,
117
						'Cache-Control' => 'no-cache',
118
					],
119
				]
120
			);
121
		} catch (BadResponseException $e) {
122
			if ($e->getResponse() && $e->getResponse()->getStatusCode() === 404) {
123
				throw new NotFoundException("object $urn not found in object store");
124
			} else {
125
				throw $e;
126
			}
127
		}
128
129
		return RetryWrapper::wrap($response->getBody()->detach());
130
	}
131
132
	/**
133
	 * @param string $urn Unified Resource Name
134
	 * @return void
135
	 * @throws \Exception from openstack lib when something goes wrong
136
	 */
137
	public function deleteObject($urn) {
138
		$this->getContainer()->getObject($urn)->delete();
139
	}
140
141
	/**
142
	 * @return void
143
	 * @throws \Exception from openstack lib when something goes wrong
144
	 */
145
	public function deleteContainer() {
146
		$this->getContainer()->delete();
147
	}
148
149
	public function objectExists($urn) {
150
		return $this->getContainer()->objectExists($urn);
151
	}
152
153
	public function copyObject($from, $to) {
154
		$this->getContainer()->getObject($from)->copy([
155
			'destination' => $this->getContainer()->name . '/' . $to
156
		]);
157
	}
158
}
159