Passed
Push — master ( 1df567...eb2b1b )
by Morris
14:23 queued 12s
created

ObjectStorePreviewCacheMountProvider   A

Complexity

Total Complexity 14

Size/Duplication

Total Lines 110
Duplicated Lines 0 %

Importance

Changes 2
Bugs 1 Features 0
Metric Value
eloc 53
dl 0
loc 110
rs 10
c 2
b 1
f 0
wmc 14

4 Methods

Rating   Name   Duplication   Size   Complexity  
A getMultiBucketObjectStoreForRoot() 0 24 4
A getMultiBucketObjectStore() 0 27 4
A __construct() 0 3 1
A getRootMounts() 0 40 5
1
<?php
2
3
declare(strict_types=1);
4
/**
5
 * @copyright Copyright (c) 2020, Morris Jobke <[email protected]>
6
 *
7
 * @author Morris Jobke <[email protected]>
8
 *
9
 * @license GNU AGPL version 3 or any later version
10
 *
11
 * This program is free software: you can redistribute it and/or modify
12
 * it under the terms of the GNU Affero General Public License as
13
 * published by the Free Software Foundation, either version 3 of the
14
 * License, or (at your option) any later version.
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
22
 * along with this program. If not, see <http://www.gnu.org/licenses/>.
23
 *
24
 */
25
26
namespace OC\Files\Mount;
27
28
use OC\Files\ObjectStore\AppdataPreviewObjectStoreStorage;
29
use OC\Files\ObjectStore\ObjectStoreStorage;
30
use OC\Files\Storage\Wrapper\Jail;
31
use OCP\Files\Config\IRootMountProvider;
32
use OCP\Files\Storage\IStorageFactory;
33
use OCP\IConfig;
34
use OCP\ILogger;
35
36
/**
37
 * Mount provider for object store app data folder for previews
38
 */
39
class ObjectStorePreviewCacheMountProvider implements IRootMountProvider {
40
	/** @var ILogger */
41
	private $logger;
42
	/** @var IConfig */
43
	private $config;
44
45
	public function __construct(ILogger $logger, IConfig $config) {
46
		$this->logger = $logger;
47
		$this->config = $config;
48
	}
49
50
	/**
51
	 * @return MountPoint[]
52
	 * @throws \Exception
53
	 */
54
	public function getRootMounts(IStorageFactory $loader): array {
55
		if (!is_array($this->config->getSystemValue('objectstore_multibucket'))) {
56
			return [];
57
		}
58
		if ($this->config->getSystemValue('objectstore.multibucket.preview-distribution', false) !== true) {
59
			return [];
60
		}
61
62
		$instanceId = $this->config->getSystemValueString('instanceid', '');
63
		$mountPoints = [];
64
		$directoryRange = ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'];
65
		$i = 0;
66
		foreach ($directoryRange as $parent) {
67
			foreach ($directoryRange as $child) {
68
				$mountPoints[] = new MountPoint(
69
					AppdataPreviewObjectStoreStorage::class,
70
					'/appdata_' . $instanceId . '/preview/' . $parent . '/' . $child,
71
					$this->getMultiBucketObjectStore($i),
72
					$loader
73
				);
74
				$i++;
75
			}
76
		}
77
78
		$rootStorageArguments = $this->getMultiBucketObjectStoreForRoot();
79
		$fakeRootStorage = new ObjectStoreStorage($rootStorageArguments);
80
		$fakeRootStorageJail = new Jail([
81
			'storage' => $fakeRootStorage,
82
			'root' => '/appdata_' . $instanceId . '/preview',
83
		]);
84
85
		// add a fallback location to be able to fetch existing previews from the old bucket
86
		$mountPoints[] = new MountPoint(
87
			$fakeRootStorageJail,
88
			'/appdata_' . $instanceId . '/preview/old-multibucket',
89
			null,
90
			$loader
91
		);
92
93
		return $mountPoints;
94
	}
95
96
	protected function getMultiBucketObjectStore(int $number): array {
97
		$config = $this->config->getSystemValue('objectstore_multibucket');
98
99
		// sanity checks
100
		if (empty($config['class'])) {
101
			$this->logger->error('No class given for objectstore', ['app' => 'files']);
102
		}
103
		if (!isset($config['arguments'])) {
104
			$config['arguments'] = [];
105
		}
106
107
		/*
108
		 * Use any provided bucket argument as prefix
109
		 * and add the mapping from parent/child => bucket
110
		 */
111
		if (!isset($config['arguments']['bucket'])) {
112
			$config['arguments']['bucket'] = '';
113
		}
114
115
		$config['arguments']['bucket'] .= "-preview-$number";
116
117
		// instantiate object store implementation
118
		$config['arguments']['objectstore'] = new $config['class']($config['arguments']);
119
120
		$config['arguments']['internal-id'] = $number;
121
122
		return $config['arguments'];
123
	}
124
125
	protected function getMultiBucketObjectStoreForRoot(): array {
126
		$config = $this->config->getSystemValue('objectstore_multibucket');
127
128
		// sanity checks
129
		if (empty($config['class'])) {
130
			$this->logger->error('No class given for objectstore', ['app' => 'files']);
131
		}
132
		if (!isset($config['arguments'])) {
133
			$config['arguments'] = [];
134
		}
135
136
		/*
137
		 * Use any provided bucket argument as prefix
138
		 * and add the mapping from parent/child => bucket
139
		 */
140
		if (!isset($config['arguments']['bucket'])) {
141
			$config['arguments']['bucket'] = '';
142
		}
143
		$config['arguments']['bucket'] .= '0';
144
145
		// instantiate object store implementation
146
		$config['arguments']['objectstore'] = new $config['class']($config['arguments']);
147
148
		return $config['arguments'];
149
	}
150
}
151