Skip to content

Commit

Permalink
wip: more azure client stuff
Browse files Browse the repository at this point in the history
  • Loading branch information
matthewhilton committed Oct 14, 2024
1 parent 75aec36 commit 6c0ff22
Show file tree
Hide file tree
Showing 2 changed files with 101 additions and 5 deletions.
20 changes: 15 additions & 5 deletions classes/local/store/azure_blob_storage/client.php
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
use local_azureblobstorage\api;
use stdClass;
use Throwable;
use tool_objectfs\local\store\azure_blob_storage\stream_wrapper;

/**
* Azure blob storage client
Expand All @@ -48,6 +49,8 @@ public function __construct($config) {
}

$this->api = new api($config->azure_accountname, $config->azure_container, $config->azure_sastoken);
$this->config = $config;
$this->maxupload = api::MAX_BLOCK_SIZE;
}

public function get_availability() {
Expand All @@ -58,6 +61,17 @@ public function get_availability() {
return !empty($info);
}

/**
* Sets the StreamWrapper to allow accessing the remote content via a blob:// path.
*/
public function register_stream_wrapper() {
if ($this->get_availability()) {
stream_wrapper::register($this->api);
} else {
parent::register_stream_wrapper();
}
}

/**
* Returns the full path for a given file by contenthash
* @param string $contenthash
Expand Down Expand Up @@ -141,10 +155,6 @@ public function get_seekable_stream_context() {
return $context;
}

// TODO test_permissions

// TODO test_connection

public function test_permissions($testdelete) {
$key = 'permissions_check_test';
$file = Utils::streamFor('test permission file');
Expand Down Expand Up @@ -176,7 +186,7 @@ public function test_permissions($testdelete) {
// If testing delete, try delete the test file.
if ($testdelete) {
try {
// TODO call delete blob, not implemented yet.
$this->api->delete_blob($key)->wait();
} catch (Throwable $e) {
return (object) [
'success' => false,
Expand Down
86 changes: 86 additions & 0 deletions classes/local/store/azure_blob_storage/stream_wrapper.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,9 @@
namespace tool_objectfs\local\store\azure_blob_storage;

use GuzzleHttp\Psr7\Stream;
use GuzzleHttp\Psr7\Utils;
use local_azureblobstorage\api;
use Throwable;

class stream_wrapper {
/** @var resource|null Stream context (this is set by PHP) */
Expand Down Expand Up @@ -330,4 +332,88 @@ private function getclient() {

return $client;
}

// TODO cleanup.
/**
* stream_write
* @param string $data
*
* @return int
*/
public function stream_write($data) {
hash_update($this->hash, $data);
return $this->body->write($data);
}

/**
* Flushes (closes) the stream. This does the actual uploading to Azure.
* @return bool
*/
public function stream_flush() {
if ($this->mode == 'r') {
return false;
}

if ($this->body->isSeekable()) {
$this->body->seek(0);
}

$hash = hash_final($this->hash);
$md5 = hex2bin($hash);
$key = $this->getOptions(true)['Key'];

// TODO boolcall.
$this->getclient()->put_blob($key, Utils::streamFor($this->body), $md5)->wait();
}

/**
* Provides information for is_dir, is_file, filesize, etc. Works on
* buckets, keys, and prefixes.
* @link http://www.php.net/manual/en/streamwrapper.url-stat.php
*
* @param string $path
* @param mixed $flags
*
* @return mixed
*/
public function url_stat($path, $flags) {
$stat = $this->getStatTemplate();

try {
$params = $this->withPath($path);
$properties = $this->getclient()->get_blob_properties($params['Key'])->wait();

$stat['size'] = $stat[7] = $bp->getContentLength();

// Set the modification time and last modified to the Last-Modified header.
$lastmodified = $bp->getLastModified()->getTimestamp();

$stat['mtime'] = $stat[9] = $lastmodified;
$stat['ctime'] = $stat[10] = $lastmodified;

// Regular file with 0777 access - see "man 2 stat".
$stat['mode'] = $stat[2] = 0100777;

return $stat;

// TODO better exception
} catch (Throwable $ex) {
// The specified blob does not exist.
return false;
}
}

/**
* Get the container and key from the passed path (e.g. blob://container/key)
*
* @param string $path Path passed to the stream wrapper
*
* @return array Hash of 'Container', 'Key', and custom params from the context
*/
private function withpath($path) {
$params = $this->getOptions(true);

// TODO rewrite
return $this->getContainerKey($path) + $params;
}
}

0 comments on commit 6c0ff22

Please sign in to comment.