Skip to content

Commit

Permalink
Merge pull request #11694 from owncloud/extstorage-lazyinit
Browse files Browse the repository at this point in the history
Lazy initialize external storages
  • Loading branch information
LukasReschke committed Oct 22, 2014
2 parents a9aa784 + 075e8d8 commit fe912ca
Show file tree
Hide file tree
Showing 6 changed files with 163 additions and 107 deletions.
100 changes: 55 additions & 45 deletions apps/files_external/lib/amazons3.php
Original file line number Diff line number Diff line change
Expand Up @@ -111,34 +111,6 @@ public function __construct($params) {
$params['port'] = ($params['use_ssl'] === 'false') ? 80 : 443;
}
$base_url = $scheme . '://' . $params['hostname'] . ':' . $params['port'] . '/';

$this->connection = S3Client::factory(array(
'key' => $params['key'],
'secret' => $params['secret'],
'base_url' => $base_url,
'region' => $params['region']
));

if (!$this->connection->isValidBucketName($this->bucket)) {
throw new \Exception("The configured bucket name is invalid.");
}

if (!$this->connection->doesBucketExist($this->bucket)) {
try {
$this->connection->createBucket(array(
'Bucket' => $this->bucket
));
$this->connection->waitUntilBucketExists(array(
'Bucket' => $this->bucket,
'waiter.interval' => 1,
'waiter.max_attempts' => 15
));
$this->testTimeout();
} catch (S3Exception $e) {
\OCP\Util::logException('files_external', $e);
throw new \Exception('Creation of bucket failed. '.$e->getMessage());
}
}
}

/**
Expand Down Expand Up @@ -181,7 +153,7 @@ public function mkdir($path) {
}

try {
$this->connection->putObject(array(
$this->getConnection()->putObject(array(
'Bucket' => $this->bucket,
'Key' => $path . '/',
'ContentType' => 'httpd/unix-directory'
Expand Down Expand Up @@ -216,7 +188,7 @@ public function rmdir($path) {

protected function clearBucket() {
try {
$this->connection->clearBucket($this->bucket);
$this->getConnection()->clearBucket($this->bucket);
return true;
// clearBucket() is not working with Ceph, so if it fails we try the slower approach
} catch (\Exception $e) {
Expand All @@ -237,9 +209,9 @@ private function batchDelete ($path = null) {
// to delete all objects prefixed with the path.
do {
// instead of the iterator, manually loop over the list ...
$objects = $this->connection->listObjects($params);
$objects = $this->getConnection()->listObjects($params);
// ... so we can delete the files in batches
$this->connection->deleteObjects(array(
$this->getConnection()->deleteObjects(array(
'Bucket' => $this->bucket,
'Objects' => $objects['Contents']
));
Expand All @@ -264,7 +236,7 @@ public function opendir($path) {

try {
$files = array();
$result = $this->connection->getIterator('ListObjects', array(
$result = $this->getConnection()->getIterator('ListObjects', array(
'Bucket' => $this->bucket,
'Delimiter' => '/',
'Prefix' => $path
Expand Down Expand Up @@ -299,7 +271,7 @@ public function stat($path) {
$stat['size'] = -1; //unknown
$stat['mtime'] = time() - $this->rescanDelay * 1000;
} else {
$result = $this->connection->headObject(array(
$result = $this->getConnection()->headObject(array(
'Bucket' => $this->bucket,
'Key' => $path
));
Expand Down Expand Up @@ -328,10 +300,10 @@ public function filetype($path) {
}

try {
if ($this->connection->doesObjectExist($this->bucket, $path)) {
if ($this->getConnection()->doesObjectExist($this->bucket, $path)) {
return 'file';
}
if ($this->connection->doesObjectExist($this->bucket, $path.'/')) {
if ($this->getConnection()->doesObjectExist($this->bucket, $path.'/')) {
return 'dir';
}
} catch (S3Exception $e) {
Expand All @@ -350,7 +322,7 @@ public function unlink($path) {
}

try {
$this->connection->deleteObject(array(
$this->getConnection()->deleteObject(array(
'Bucket' => $this->bucket,
'Key' => $path
));
Expand All @@ -373,7 +345,7 @@ public function fopen($path, $mode) {
self::$tmpFiles[$tmpFile] = $path;

try {
$this->connection->getObject(array(
$this->getConnection()->getObject(array(
'Bucket' => $this->bucket,
'Key' => $path,
'SaveAs' => $tmpFile
Expand Down Expand Up @@ -421,7 +393,7 @@ public function getMimeType($path) {
return 'httpd/unix-directory';
} else if ($this->file_exists($path)) {
try {
$result = $this->connection->headObject(array(
$result = $this->getConnection()->headObject(array(
'Bucket' => $this->bucket,
'Key' => $path
));
Expand Down Expand Up @@ -449,7 +421,7 @@ public function touch($path, $mtime = null) {
if ($fileType === 'dir' && ! $this->isRoot($path)) {
$path .= '/';
}
$this->connection->copyObject(array(
$this->getConnection()->copyObject(array(
'Bucket' => $this->bucket,
'Key' => $this->cleanKey($path),
'Metadata' => $metadata,
Expand All @@ -458,7 +430,7 @@ public function touch($path, $mtime = null) {
$this->testTimeout();
} else {
$mimeType = \OC_Helper::getMimetypeDetector()->detectPath($path);
$this->connection->putObject(array(
$this->getConnection()->putObject(array(
'Bucket' => $this->bucket,
'Key' => $this->cleanKey($path),
'Metadata' => $metadata,
Expand All @@ -481,7 +453,7 @@ public function copy($path1, $path2) {

if ($this->is_file($path1)) {
try {
$this->connection->copyObject(array(
$this->getConnection()->copyObject(array(
'Bucket' => $this->bucket,
'Key' => $this->cleanKey($path2),
'CopySource' => S3Client::encodeKey($this->bucket . '/' . $path1)
Expand All @@ -495,7 +467,7 @@ public function copy($path1, $path2) {
$this->remove($path2);

try {
$this->connection->copyObject(array(
$this->getConnection()->copyObject(array(
'Bucket' => $this->bucket,
'Key' => $path2 . '/',
'CopySource' => S3Client::encodeKey($this->bucket . '/' . $path1 . '/')
Expand Down Expand Up @@ -553,7 +525,7 @@ public function rename($path1, $path2) {
}

public function test() {
$test = $this->connection->getBucketAcl(array(
$test = $this->getConnection()->getBucketAcl(array(
'Bucket' => $this->bucket,
));
if (isset($test) && !is_null($test->getPath('Owner/ID'))) {
Expand All @@ -566,7 +538,45 @@ public function getId() {
return $this->id;
}

/**
* Returns the connection
*
* @return S3Client connected client
* @throws \Exception if connection could not be made
*/
public function getConnection() {
if (!is_null($this->connection)) {
return $this->connection;
}

$this->connection = S3Client::factory(array(
'key' => $params['key'],

This comment has been minimized.

Copy link
@butonic

butonic Oct 22, 2014

Member

$params['key'] undefined variable

This comment has been minimized.

Copy link
@LukasReschke

LukasReschke Oct 22, 2014

Author Member

This comment has been minimized.

Copy link
@PVince81

PVince81 Oct 22, 2014

Contributor

Oh yes, sweet merge conflict I didn't resolve properly... and S3 is the only one I did not test

'secret' => $params['secret'],
'base_url' => $base_url,

This comment has been minimized.

Copy link
@butonic

butonic Oct 22, 2014

Member

$base_url undefined variable

This comment has been minimized.

Copy link
@LukasReschke

LukasReschke Oct 22, 2014

Author Member
'region' => $params['region']
));

if (!$this->connection->isValidBucketName($this->bucket)) {
throw new \Exception("The configured bucket name is invalid.");
}

if (!$this->connection->doesBucketExist($this->bucket)) {
try {
$this->connection->createBucket(array(
'Bucket' => $this->bucket
));
$this->connection->waitUntilBucketExists(array(
'Bucket' => $this->bucket,
'waiter.interval' => 1,
'waiter.max_attempts' => 15
));
$this->testTimeout();
} catch (S3Exception $e) {
\OCP\Util::logException('files_external', $e);
throw new \Exception('Creation of bucket failed. '.$e->getMessage());
}
}

return $this->connection;
}

Expand All @@ -576,7 +586,7 @@ public function writeBack($tmpFile) {
}

try {
$this->connection->putObject(array(
$this->getConnection()->putObject(array(
'Bucket' => $this->bucket,
'Key' => $this->cleanKey(self::$tmpFiles[$tmpFile]),
'SourceFile' => $tmpFile,
Expand Down
1 change: 1 addition & 0 deletions apps/files_external/lib/dropbox.php
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ public function __construct($params) {
$this->id = 'dropbox::'.$params['app_key'] . $params['token']. '/' . $this->root;
$oauth = new \Dropbox_OAuth_Curl($params['app_key'], $params['app_secret']);
$oauth->setToken($params['token'], $params['token_secret']);
// note: Dropbox_API connection is lazy
$this->dropbox = new \Dropbox_API($oauth, 'auto');
} else {
throw new \Exception('Creating \OC\Files\Storage\Dropbox storage failed');
Expand Down
2 changes: 1 addition & 1 deletion apps/files_external/lib/ftp.php
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ public function __construct($params) {
$this->root .= '/';
}
} else {
throw new \Exception();
throw new \Exception('Creating \OC\Files\Storage\FTP storage failed');
}

}
Expand Down
1 change: 1 addition & 0 deletions apps/files_external/lib/google.php
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ public function __construct($params) {
$client->setScopes(array('https://www.googleapis.com/auth/drive'));
$client->setUseObjects(true);
$client->setAccessToken($params['token']);
// note: API connection is lazy
$this->service = new \Google_DriveService($client);
$token = json_decode($params['token'], true);
$this->id = 'google::'.substr($params['client_id'], 0, 30).$token['created'];
Expand Down
39 changes: 26 additions & 13 deletions apps/files_external/lib/sftp.php
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,18 @@ public function __construct($params) {
if (substr($this->root, -1, 1) != '/') {
$this->root .= '/';
}
}

/**
* Returns the connection.
*
* @return \Net_SFTP connected client instance
* @throws \Exception when the connection failed
*/
public function getConnection() {
if (!is_null($this->client)) {
return $this->client;
}

$hostKeys = $this->readHostKeys();
$this->client = new \Net_SFTP($this->host);
Expand All @@ -71,6 +83,7 @@ public function __construct($params) {
if (!$this->client->login($this->user, $this->password)) {
throw new \Exception('Login failed');
}
return $this->client;
}

public function test() {
Expand All @@ -81,7 +94,7 @@ public function test() {
) {
return false;
}
return $this->client->nlist() !== false;
return $this->getConnection()->nlist() !== false;
}

public function getId(){
Expand Down Expand Up @@ -149,23 +162,23 @@ private function readHostKeys() {

public function mkdir($path) {
try {
return $this->client->mkdir($this->absPath($path));
return $this->getConnection()->mkdir($this->absPath($path));
} catch (\Exception $e) {
return false;
}
}

public function rmdir($path) {
try {
return $this->client->delete($this->absPath($path), true);
return $this->getConnection()->delete($this->absPath($path), true);
} catch (\Exception $e) {
return false;
}
}

public function opendir($path) {
try {
$list = $this->client->nlist($this->absPath($path));
$list = $this->getConnection()->nlist($this->absPath($path));
if ($list === false) {
return false;
}
Expand All @@ -186,7 +199,7 @@ public function opendir($path) {

public function filetype($path) {
try {
$stat = $this->client->stat($this->absPath($path));
$stat = $this->getConnection()->stat($this->absPath($path));
if ($stat['type'] == NET_SFTP_TYPE_REGULAR) {
return 'file';
}
Expand All @@ -202,15 +215,15 @@ public function filetype($path) {

public function file_exists($path) {
try {
return $this->client->stat($this->absPath($path)) !== false;
return $this->getConnection()->stat($this->absPath($path)) !== false;
} catch (\Exception $e) {
return false;
}
}

public function unlink($path) {
try {
return $this->client->delete($this->absPath($path), true);
return $this->getConnection()->delete($this->absPath($path), true);
} catch (\Exception $e) {
return false;
}
Expand All @@ -237,7 +250,7 @@ public function fopen($path, $mode) {
case 'x+':
case 'c':
case 'c+':
$context = stream_context_create(array('sftp' => array('session' => $this->client)));
$context = stream_context_create(array('sftp' => array('session' => $this->getConnection())));
return fopen($this->constructUrl($path), $mode, false, $context);
}
} catch (\Exception $e) {
Expand All @@ -251,7 +264,7 @@ public function touch($path, $mtime=null) {
return false;
}
if (!$this->file_exists($path)) {
$this->client->put($this->absPath($path), '');
$this->getConnection()->put($this->absPath($path), '');
} else {
return false;
}
Expand All @@ -262,19 +275,19 @@ public function touch($path, $mtime=null) {
}

public function getFile($path, $target) {
$this->client->get($path, $target);
$this->getConnection()->get($path, $target);
}

public function uploadFile($path, $target) {
$this->client->put($target, $path, NET_SFTP_LOCAL_FILE);
$this->getConnection()->put($target, $path, NET_SFTP_LOCAL_FILE);
}

public function rename($source, $target) {
try {
if (!$this->is_dir($target) && $this->file_exists($target)) {
$this->unlink($target);
}
return $this->client->rename(
return $this->getConnection()->rename(
$this->absPath($source),
$this->absPath($target)
);
Expand All @@ -285,7 +298,7 @@ public function rename($source, $target) {

public function stat($path) {
try {
$stat = $this->client->stat($this->absPath($path));
$stat = $this->getConnection()->stat($this->absPath($path));

$mtime = $stat ? $stat['mtime'] : -1;
$size = $stat ? $stat['size'] : 0;
Expand Down
Loading

0 comments on commit fe912ca

Please sign in to comment.