change architecture from inheritance to composition
This commit is contained in:
parent
9335a5f07f
commit
5cae863408
7 changed files with 131 additions and 65 deletions
|
@ -325,32 +325,36 @@ class Filesystem {
|
|||
$userObject = \OC_User::getManager()->get($user);
|
||||
|
||||
if (!is_null($userObject)) {
|
||||
$homeStorage = \OC_Config::getValue( 'objectstore', array(
|
||||
//default home storage configuration:
|
||||
'class' => '\OC\Files\Storage\Home',
|
||||
'arguments' => array()
|
||||
));
|
||||
// sanity checks
|
||||
if (empty($homeStorage['class'])) {
|
||||
\OCP\Util::writeLog('files', 'No class given for objectstore', \OCP\Util::ERROR);
|
||||
}
|
||||
if (!isset($homeStorage['arguments'])) {
|
||||
$homeStorage['arguments'] = array();
|
||||
$homeStorage = \OC_Config::getValue( 'objectstore' );
|
||||
if (!empty($homeStorage)) {
|
||||
// sanity checks
|
||||
if (empty($homeStorage['class'])) {
|
||||
\OCP\Util::writeLog('files', 'No class given for objectstore', \OCP\Util::ERROR);
|
||||
}
|
||||
if (!isset($homeStorage['arguments'])) {
|
||||
$homeStorage['arguments'] = array();
|
||||
}
|
||||
// instantiate object store implementation
|
||||
$homeStorage['arguments']['objectstore'] = new $homeStorage['class']($homeStorage['arguments']);
|
||||
// mount with home object store implementation
|
||||
$homeStorage['class'] = '\OC\Files\ObjectStore\HomeObjectStoreStorage';
|
||||
} else {
|
||||
$homeStorage = array(
|
||||
//default home storage configuration:
|
||||
'class' => '\OC\Files\Storage\Home',
|
||||
'arguments' => array()
|
||||
);
|
||||
}
|
||||
$homeStorage['arguments']['user'] = $userObject;
|
||||
|
||||
// check for legacy home id (<= 5.0.12)
|
||||
if (\OC\Files\Cache\Storage::exists('local::' . $root . '/')) {
|
||||
$homeStorage['arguments']['legacy'] = true;
|
||||
}
|
||||
|
||||
self::mount($homeStorage['class'], $homeStorage['arguments'], $user);
|
||||
|
||||
$home = \OC\Files\Filesystem::getStorage($user);
|
||||
if ( $home->instanceOfStorage('\OC\Files\ObjectStore\AbstractObjectStore') ) {
|
||||
//create the files folder in the cache when mounting the objectstore for a user
|
||||
if ( ! $home->is_dir('files') ) {
|
||||
$home->mkdir('files');
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
self::mount('\OC\Files\Storage\Local', array('datadir' => $root), $user);
|
||||
|
|
34
lib/private/files/objectstore/homeobjectstorestorage.php
Normal file
34
lib/private/files/objectstore/homeobjectstorestorage.php
Normal file
|
@ -0,0 +1,34 @@
|
|||
<?php
|
||||
/**
|
||||
* @author Jörn Friedrich Dreyer
|
||||
* @copyright (c) 2014 Jörn Friedrich Dreyer <jfd@owncloud.com>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 3 of the License, or any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU AFFERO GENERAL PUBLIC LICENSE for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public
|
||||
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
namespace OC\Files\ObjectStore;
|
||||
|
||||
class HomeObjectStoreStorage extends ObjectStoreStorage {
|
||||
|
||||
public function __construct($params) {
|
||||
parent::__construct($params);
|
||||
|
||||
//initialize cache with root directory in cache
|
||||
if ( ! $this->is_dir('files') ) {
|
||||
$this->mkdir('files');
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -20,32 +20,14 @@
|
|||
|
||||
namespace OC\Files\ObjectStore;
|
||||
|
||||
abstract class AbstractObjectStore extends \OC\Files\Storage\Common {
|
||||
use OCP\Files\ObjectStore\IObjectStore;
|
||||
|
||||
class ObjectStoreStorage extends \OC\Files\Storage\Common {
|
||||
|
||||
/**
|
||||
* @param string $urn the unified resource name used to identify the object
|
||||
* @param string $tmpFile path to the local temporary file that the object
|
||||
* should be loaded from
|
||||
* @return void
|
||||
* @throws Exception when something goes wrong, message will be logged
|
||||
* @var \OCP\Files\ObjectStore\IObjectStore $objectStore
|
||||
*/
|
||||
abstract protected function createObject($urn, $tmpFile = null);
|
||||
|
||||
/**
|
||||
* @param string $urn the unified resource name used to identify the object
|
||||
* @param string $tmpFile path to the local temporary file that should be
|
||||
* used to store the object
|
||||
* @return void
|
||||
* @throws Exception when something goes wrong, message will be logged
|
||||
*/
|
||||
abstract protected function getObject($urn, $tmpFile);
|
||||
|
||||
/**
|
||||
* @param string $urn the unified resource name used to identify the object
|
||||
* @return void
|
||||
* @throws Exception when something goes wrong, message will be logged
|
||||
*/
|
||||
abstract protected function deleteObject($urn);
|
||||
protected $objectStore;
|
||||
|
||||
/**
|
||||
* @var \OC\User\User $user
|
||||
|
@ -58,11 +40,16 @@ abstract class AbstractObjectStore extends \OC\Files\Storage\Common {
|
|||
private static $tmpFiles = array();
|
||||
|
||||
public function __construct($params) {
|
||||
if (isset($params['user']) && is_object($params['user'])) {
|
||||
if (isset($params['user']) && $params['user'] instanceof \OC\User\User) {
|
||||
$this->user = $params['user'];
|
||||
} else {
|
||||
$this->user = null;
|
||||
}
|
||||
if (isset($params['objectstore']) && $params['objectstore'] instanceof IObjectStore) {
|
||||
$this->objectStore = $params['objectstore'];
|
||||
} else {
|
||||
throw new \Exception('missing IObjectStore instance');
|
||||
}
|
||||
//initialize cache with root directory in cache
|
||||
if ( ! $this->is_dir('/') ) {
|
||||
$this->mkdir('/');
|
||||
|
@ -243,7 +230,7 @@ abstract class AbstractObjectStore extends \OC\Files\Storage\Common {
|
|||
return $this->rmdir($path);
|
||||
}
|
||||
try {
|
||||
$this->deleteObject($this->getURN($stat['fileid']));
|
||||
$this->objectStore->deleteObject($this->getURN($stat['fileid']));
|
||||
} catch (\Exception $ex) {
|
||||
if ($ex->getCode() !== 404) {
|
||||
\OCP\Util::writeLog('objectstore', 'Could not delete object: '.$ex->getMessage(), \OCP\Util::ERROR);
|
||||
|
@ -269,7 +256,7 @@ abstract class AbstractObjectStore extends \OC\Files\Storage\Common {
|
|||
$tmpFile = \OC_Helper::tmpFile();
|
||||
self::$tmpFiles[$tmpFile] = $path;
|
||||
try {
|
||||
$this->getObject($this->getURN($stat['fileid']), $tmpFile);
|
||||
$this->objectStore->getObject($this->getURN($stat['fileid']), $tmpFile);
|
||||
} catch (\Exception $ex) {
|
||||
\OCP\Util::writeLog('objectstore', 'Could not get object: '.$ex->getMessage(), \OCP\Util::ERROR);
|
||||
return false;
|
||||
|
@ -376,7 +363,7 @@ abstract class AbstractObjectStore extends \OC\Files\Storage\Common {
|
|||
);
|
||||
$fileId = $this->getCache()->put($path, $stat);
|
||||
try {
|
||||
$this->createObject($this->getURN($fileId));
|
||||
$this->objectStore->updateObject($this->getURN($fileId));
|
||||
} catch (\Exception $ex) {
|
||||
$this->getCache()->remove($path);
|
||||
\OCP\Util::writeLog('objectstore', 'Could not create object: '.$ex->getMessage(), \OCP\Util::ERROR);
|
||||
|
@ -424,7 +411,7 @@ abstract class AbstractObjectStore extends \OC\Files\Storage\Common {
|
|||
$fileId = $this->getCache()->put($path, $stat);
|
||||
try {
|
||||
//upload to object storage
|
||||
$this->createObject($this->getURN($fileId), $tmpFile);
|
||||
$this->objectStore->updateObject($this->getURN($fileId), $tmpFile);
|
||||
} catch (\Exception $ex) {
|
||||
$this->getCache()->remove($path);
|
||||
\OCP\Util::writeLog('objectstore', 'Could not create object: '.$ex->getMessage(), \OCP\Util::ERROR);
|
|
@ -23,7 +23,7 @@ namespace OC\Files\ObjectStore;
|
|||
use Guzzle\Http\Exception\ClientErrorResponseException;
|
||||
use OpenCloud\OpenStack;
|
||||
|
||||
class Swift extends AbstractObjectStore {
|
||||
class Swift implements \OCP\Files\ObjectStore\IObjectStore {
|
||||
|
||||
/**
|
||||
* @var \OpenCloud\ObjectStore\Service
|
||||
|
@ -78,19 +78,22 @@ class Swift extends AbstractObjectStore {
|
|||
throw $ex;
|
||||
}
|
||||
}
|
||||
|
||||
//set the user via parent constructor, also initializes the root of the filecache
|
||||
parent::__construct($params);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param string $urn Unified Resource Name
|
||||
* @param string $tmpFile
|
||||
* @return void
|
||||
* @throws Exception from openstack lib when something goes wrong
|
||||
*/
|
||||
protected function deleteObject($urn) {
|
||||
$object = $this->container->getObject($urn);
|
||||
$object->delete();
|
||||
public function updateObject($urn, $tmpFile = null) {
|
||||
$fileData = '';
|
||||
if ($tmpFile) {
|
||||
$fileData = fopen($tmpFile, 'r');
|
||||
}
|
||||
|
||||
$this->container->uploadObject($urn, $fileData);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -99,7 +102,7 @@ class Swift extends AbstractObjectStore {
|
|||
* @return void
|
||||
* @throws Exception from openstack lib when something goes wrong
|
||||
*/
|
||||
protected function getObject($urn, $tmpFile) {
|
||||
public function getObject($urn, $tmpFile) {
|
||||
$object = $this->container->getObject($urn);
|
||||
|
||||
/** @var $objectContent \Guzzle\Http\EntityBody **/
|
||||
|
@ -112,17 +115,12 @@ class Swift extends AbstractObjectStore {
|
|||
|
||||
/**
|
||||
* @param string $urn Unified Resource Name
|
||||
* @param string $tmpFile
|
||||
* @return void
|
||||
* @throws Exception from openstack lib when something goes wrong
|
||||
*/
|
||||
protected function createObject($urn, $tmpFile = null) {
|
||||
$fileData = '';
|
||||
if ($tmpFile) {
|
||||
$fileData = fopen($tmpFile, 'r');
|
||||
}
|
||||
|
||||
$this->container->uploadObject($urn, $fileData);
|
||||
public function deleteObject($urn) {
|
||||
$object = $this->container->getObject($urn);
|
||||
$object->delete();
|
||||
}
|
||||
|
||||
public function deleteContainer($recursive = false) {
|
||||
|
|
|
@ -32,11 +32,17 @@ class OC_Util {
|
|||
private static function initObjectStoreRootFS($config) {
|
||||
// check misconfiguration
|
||||
if (empty($config['class'])) {
|
||||
//FIXME log error?
|
||||
\OCP\Util::writeLog('files', 'No class given for objectstore', \OCP\Util::ERROR);
|
||||
}
|
||||
if (!isset($config['arguments'])) {
|
||||
$config['arguments'] = array();
|
||||
}
|
||||
|
||||
// instantiate object store implementation
|
||||
$config['arguments']['objectstore'] = new $config['class']($config['arguments']);
|
||||
// mount with plain / root object store implementation
|
||||
$config['class'] = '\OC\Files\ObjectStore\ObjectStoreStorage';
|
||||
|
||||
// mount object storage as root
|
||||
\OC\Files\Filesystem::initMounts();
|
||||
if(!self::$rootMounted) {
|
||||
|
@ -94,7 +100,7 @@ class OC_Util {
|
|||
* @var \OC\Files\Storage\Storage $storage
|
||||
*/
|
||||
if ($storage->instanceOfStorage('\OC\Files\Storage\Home')
|
||||
|| $storage->instanceOfStorage('\OC\Files\ObjectStore\AbstractObjectStore')
|
||||
|| $storage->instanceOfStorage('\OC\Files\ObjectStore\HomeObjectStoreStorage')
|
||||
) {
|
||||
if (is_object($storage->getUser())) {
|
||||
$user = $storage->getUser()->getUID();
|
||||
|
|
32
lib/public/files/objectstore/iobjectstore.php
Normal file
32
lib/public/files/objectstore/iobjectstore.php
Normal file
|
@ -0,0 +1,32 @@
|
|||
<?php
|
||||
|
||||
namespace OCP\Files\ObjectStore;
|
||||
|
||||
interface IObjectStore {
|
||||
|
||||
/**
|
||||
* @param string $urn the unified resource name used to identify the object
|
||||
* @param string $tmpFile path to the local temporary file that should be
|
||||
* used to store the object
|
||||
* @return void
|
||||
* @throws Exception when something goes wrong, message will be logged
|
||||
*/
|
||||
function getObject($urn, $tmpFile);
|
||||
/**
|
||||
* @param string $urn the unified resource name used to identify the object
|
||||
* @param string $tmpFile path to the local temporary file that the object
|
||||
* should be loaded from
|
||||
* @return void
|
||||
* @throws Exception when something goes wrong, message will be logged
|
||||
*/
|
||||
function updateObject($urn, $tmpFile = null);
|
||||
|
||||
|
||||
/**
|
||||
* @param string $urn the unified resource name used to identify the object
|
||||
* @return void
|
||||
* @throws Exception when something goes wrong, message will be logged
|
||||
*/
|
||||
function deleteObject($urn);
|
||||
|
||||
}
|
|
@ -20,6 +20,7 @@
|
|||
|
||||
namespace OCA\ObjectStore\Tests\Unit;
|
||||
|
||||
use OC\Files\ObjectStore\ObjectStoreStorage;
|
||||
use OC\Files\ObjectStore\Swift as ObjectStoreToTest;
|
||||
|
||||
use PHPUnit_Framework_TestCase;
|
||||
|
@ -30,6 +31,8 @@ class Swift extends PHPUnit_Framework_TestCase {
|
|||
* @var \OC\Files\ObjectStore\Swift $storage
|
||||
*/
|
||||
private $storage;
|
||||
|
||||
private $objectStorage;
|
||||
|
||||
public function setUp() {
|
||||
|
||||
|
@ -67,14 +70,16 @@ class Swift extends PHPUnit_Framework_TestCase {
|
|||
'serviceName' => 'swift', //trystack uses swift by default, the lib defaults to 'cloudFiles' if omitted
|
||||
'user' => \OC_User::getManager()->get($userName)
|
||||
);
|
||||
$this->storage = new ObjectStoreToTest($params);
|
||||
$this->objectStorage = new ObjectStoreToTest($params);
|
||||
$params['objectstore'] = $this->objectStorage;
|
||||
$this->storage = new ObjectStoreStorage($params);
|
||||
}
|
||||
|
||||
public function tearDown() {
|
||||
if (is_null($this->storage)) {
|
||||
return;
|
||||
}
|
||||
$this->storage->deleteContainer(true);
|
||||
$this->objectStorage->deleteContainer(true);
|
||||
$this->storage->getCache()->clear();
|
||||
//TODO how do I clear hooks?
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue