From 5cae863408630aee768adf70fdb5c11f72b713fa Mon Sep 17 00:00:00 2001 From: =?utf8?q?J=C3=B6rn=20Friedrich=20Dreyer?= Date: Tue, 17 Jun 2014 22:06:56 +0200 Subject: [PATCH] change architecture from inheritance to composition --- lib/private/files/filesystem.php | 38 +++++++++-------- .../objectstore/homeobjectstorestorage.php | 34 +++++++++++++++ ...objectstore.php => objectstorestorage.php} | 41 +++++++------------ lib/private/files/objectstore/swift.php | 30 +++++++------- lib/private/util.php | 10 ++++- lib/public/files/objectstore/iobjectstore.php | 32 +++++++++++++++ tests/lib/files/objectstore/swift.php | 9 +++- 7 files changed, 130 insertions(+), 64 deletions(-) create mode 100644 lib/private/files/objectstore/homeobjectstorestorage.php rename lib/private/files/objectstore/{abstractobjectstore.php => objectstorestorage.php} (88%) create mode 100644 lib/public/files/objectstore/iobjectstore.php diff --git a/lib/private/files/filesystem.php b/lib/private/files/filesystem.php index 71d70bbf2a5..4774d25ad9e 100644 --- a/lib/private/files/filesystem.php +++ b/lib/private/files/filesystem.php @@ -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); diff --git a/lib/private/files/objectstore/homeobjectstorestorage.php b/lib/private/files/objectstore/homeobjectstorestorage.php new file mode 100644 index 00000000000..0c889725828 --- /dev/null +++ b/lib/private/files/objectstore/homeobjectstorestorage.php @@ -0,0 +1,34 @@ + + * + * 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 . + * + */ + +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'); + } + } + +} \ No newline at end of file diff --git a/lib/private/files/objectstore/abstractobjectstore.php b/lib/private/files/objectstore/objectstorestorage.php similarity index 88% rename from lib/private/files/objectstore/abstractobjectstore.php rename to lib/private/files/objectstore/objectstorestorage.php index de82003f0e8..6b48e2d78dd 100644 --- a/lib/private/files/objectstore/abstractobjectstore.php +++ b/lib/private/files/objectstore/objectstorestorage.php @@ -20,32 +20,14 @@ namespace OC\Files\ObjectStore; -abstract class AbstractObjectStore extends \OC\Files\Storage\Common { +use OCP\Files\ObjectStore\IObjectStore; - /** - * @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 - */ - abstract protected function createObject($urn, $tmpFile = null); +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 should be - * used to store the object - * @return void - * @throws Exception when something goes wrong, message will be logged + * @var \OCP\Files\ObjectStore\IObjectStore $objectStore */ - 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); diff --git a/lib/private/files/objectstore/swift.php b/lib/private/files/objectstore/swift.php index 53367367af0..f66b03889d2 100644 --- a/lib/private/files/objectstore/swift.php +++ b/lib/private/files/objectstore/swift.php @@ -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) { diff --git a/lib/private/util.php b/lib/private/util.php index f2ecdcbded6..d384eda5f7f 100755 --- a/lib/private/util.php +++ b/lib/private/util.php @@ -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(); diff --git a/lib/public/files/objectstore/iobjectstore.php b/lib/public/files/objectstore/iobjectstore.php new file mode 100644 index 00000000000..ecc35faf34a --- /dev/null +++ b/lib/public/files/objectstore/iobjectstore.php @@ -0,0 +1,32 @@ + '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? } -- 2.39.5