feat(usage): added response models for storage API
This commit is contained in:
parent
3d512e74bf
commit
6d6b0ee024
|
@ -651,6 +651,9 @@ App::get('/v1/storage/usage')
|
|||
->label('sdk.auth', [APP_AUTH_TYPE_ADMIN])
|
||||
->label('sdk.namespace', 'storage')
|
||||
->label('sdk.method', 'getUsage')
|
||||
->label('sdk.response.code', Response::STATUS_CODE_OK)
|
||||
->label('sdk.response.type', Response::CONTENT_TYPE_JSON)
|
||||
->label('sdk.response.model', Response::MODEL_STORAGE_USAGE)
|
||||
->param('range', '30d', new WhiteList(['24h', '7d', '30d', '90d'], true), 'Date range.', true)
|
||||
->inject('response')
|
||||
->inject('dbForInternal')
|
||||
|
@ -658,71 +661,11 @@ App::get('/v1/storage/usage')
|
|||
/** @var Appwrite\Utopia\Response $response */
|
||||
/** @var Utopia\Database\Database $dbForInternal */
|
||||
|
||||
$usage = [];
|
||||
if (App::getEnv('_APP_USAGE_STATS', 'enabled') == 'enabled') {
|
||||
$period = [
|
||||
'24h' => [
|
||||
'period' => '30m',
|
||||
'limit' => 48,
|
||||
],
|
||||
'7d' => [
|
||||
'period' => '1d',
|
||||
'limit' => 7,
|
||||
],
|
||||
'30d' => [
|
||||
'period' => '1d',
|
||||
'limit' => 30,
|
||||
],
|
||||
'90d' => [
|
||||
'period' => '1d',
|
||||
'limit' => 90,
|
||||
],
|
||||
];
|
||||
|
||||
Authorization::disable();
|
||||
|
||||
$storageTotal = $dbForInternal->findOne('stats', [new Query('metric', Query::TYPE_EQUAL, ['storage.total'])], 0, ['time'], [Database::ORDER_DESC]);
|
||||
$storage = $storageTotal ? $storageTotal->getAttribute('value', 0) : 0;
|
||||
|
||||
$filesCount = $dbForInternal->findOne('stats', [new Query('metric', Query::TYPE_EQUAL, ['storage.files.count'])], 0, ['time'], [Database::ORDER_DESC]);
|
||||
$filesTotal = $filesCount ? $filesCount->getAttribute('value', 0) : 0;
|
||||
|
||||
Authorization::reset();
|
||||
|
||||
$response->json([
|
||||
'range' => $range,
|
||||
'storage' => [
|
||||
'total' => $storage,
|
||||
],
|
||||
'files' => [
|
||||
'total' => $filesTotal,
|
||||
],
|
||||
]);
|
||||
} else {
|
||||
$response->json([]);
|
||||
}
|
||||
});
|
||||
|
||||
App::get('/v1/storage/:bucketId/usage')
|
||||
->desc('Get usage stats for a storage bucket')
|
||||
->groups(['api', 'storage'])
|
||||
->label('scope', 'files.read')
|
||||
->label('sdk.auth', [APP_AUTH_TYPE_ADMIN])
|
||||
->label('sdk.namespace', 'storage')
|
||||
->label('sdk.method', 'getUsage')
|
||||
->param('bucketId', '', new UID(), 'Bucket unique ID.')
|
||||
->param('range', '30d', new WhiteList(['24h', '7d', '30d', '90d'], true), 'Date range.', true)
|
||||
->inject('response')
|
||||
->inject('dbForInternal')
|
||||
->action(function ($bucketId, $range, $response, $dbForInternal) {
|
||||
/** @var Appwrite\Utopia\Response $response */
|
||||
/** @var Utopia\Database\Database $dbForInternal */
|
||||
|
||||
// TODO: Check if the storage bucket exists else throw 404
|
||||
$stats = [];
|
||||
if (App::getEnv('_APP_USAGE_STATS', 'enabled') == 'enabled') {
|
||||
$period = [
|
||||
'24h' => [
|
||||
'period' => '30m',
|
||||
'period' => '15m',
|
||||
'limit' => 48,
|
||||
],
|
||||
'7d' => [
|
||||
|
@ -742,12 +685,11 @@ App::get('/v1/storage/:bucketId/usage')
|
|||
Authorization::disable();
|
||||
|
||||
$metrics = [
|
||||
"storage.buckets.$bucketId.files.create",
|
||||
"storage.buckets.$bucketId.files.read",
|
||||
"storage.buckets.$bucketId.files.update",
|
||||
"storage.buckets.$bucketId.files.delete"
|
||||
"storage.total",
|
||||
"storage.files.count"
|
||||
];
|
||||
|
||||
$stats = [];
|
||||
foreach ($metrics as $metric) {
|
||||
$requestDocs = $dbForInternal->find('stats', [
|
||||
new Query('period', Query::TYPE_EQUAL, [$period[$range]['period']]),
|
||||
|
@ -761,68 +703,94 @@ App::get('/v1/storage/:bucketId/usage')
|
|||
'date' => $requestDoc->getAttribute('time'),
|
||||
];
|
||||
}
|
||||
|
||||
$stats[$metric] = array_reverse($stats[$metric]);
|
||||
}
|
||||
|
||||
$usage = new Document([
|
||||
'range' => $range,
|
||||
'storage' => $stats['storage.total'],
|
||||
'files' => $stats['storage.files.count']
|
||||
]);
|
||||
}
|
||||
|
||||
$response->dynamic($usage, Response::MODEL_STORAGE_USAGE);
|
||||
});
|
||||
|
||||
App::get('/v1/storage/:bucketId/usage')
|
||||
->desc('Get usage stats for a storage bucket')
|
||||
->groups(['api', 'storage'])
|
||||
->label('scope', 'files.read')
|
||||
->label('sdk.auth', [APP_AUTH_TYPE_ADMIN])
|
||||
->label('sdk.namespace', 'storage')
|
||||
->label('sdk.method', 'getUsage')
|
||||
->label('sdk.response.code', Response::STATUS_CODE_OK)
|
||||
->label('sdk.response.type', Response::CONTENT_TYPE_JSON)
|
||||
->label('sdk.response.model', Response::MODEL_BUCKETS_USAGE)
|
||||
->param('bucketId', '', new UID(), 'Bucket unique ID.')
|
||||
->param('range', '30d', new WhiteList(['24h', '7d', '30d', '90d'], true), 'Date range.', true)
|
||||
->inject('response')
|
||||
->inject('dbForInternal')
|
||||
->action(function ($bucketId, $range, $response, $dbForInternal) {
|
||||
/** @var Appwrite\Utopia\Response $response */
|
||||
/** @var Utopia\Database\Database $dbForInternal */
|
||||
|
||||
// TODO: Check if the storage bucket exists else throw 404
|
||||
|
||||
$usage = [];
|
||||
if (App::getEnv('_APP_USAGE_STATS', 'enabled') == 'enabled') {
|
||||
$period = [
|
||||
'24h' => [
|
||||
'period' => '30m',
|
||||
'limit' => 48,
|
||||
],
|
||||
'7d' => [
|
||||
'period' => '1d',
|
||||
'limit' => 7,
|
||||
],
|
||||
'30d' => [
|
||||
'period' => '1d',
|
||||
'limit' => 30,
|
||||
],
|
||||
'90d' => [
|
||||
'period' => '1d',
|
||||
'limit' => 90,
|
||||
],
|
||||
];
|
||||
|
||||
Authorization::disable();
|
||||
$metrics = [
|
||||
"storage.buckets.$bucketId.files.create",
|
||||
"storage.buckets.$bucketId.files.read",
|
||||
"storage.buckets.$bucketId.files.update",
|
||||
"storage.buckets.$bucketId.files.delete"
|
||||
];
|
||||
|
||||
$stats = [];
|
||||
foreach ($metrics as $metric) {
|
||||
$requestDocs = $dbForInternal->find('stats', [
|
||||
new Query('period', Query::TYPE_EQUAL, [$period[$range]['period']]),
|
||||
new Query('metric', Query::TYPE_EQUAL, [$metric]),
|
||||
], $period[$range]['limit'], 0, ['time'], [Database::ORDER_DESC]);
|
||||
|
||||
$stats[$metric] = [];
|
||||
foreach ($requestDocs as $requestDoc) {
|
||||
$stats[$metric][] = [
|
||||
'value' => $requestDoc->getAttribute('value'),
|
||||
'date' => $requestDoc->getAttribute('time'),
|
||||
];
|
||||
}
|
||||
$stats[$metric] = array_reverse($stats[$metric]);
|
||||
}
|
||||
Authorization::reset();
|
||||
|
||||
$create = $stats["storage.buckets.$bucketId.files.create"] ?? [];
|
||||
$read = $stats["storage.buckets.$bucketId.files.read"] ?? [];
|
||||
$update = $stats["storage.buckets.$bucketId.files.update"] ?? [];
|
||||
$delete = $stats["storage.buckets.$bucketId.files.delete"] ?? [];
|
||||
|
||||
|
||||
// 'name' => [
|
||||
// [
|
||||
// [
|
||||
// 'value' => '',
|
||||
// 'date' => 'unix timestamp'
|
||||
// ]
|
||||
// ]
|
||||
// ]
|
||||
|
||||
// $res = [
|
||||
// 'range' => '',
|
||||
// 'name' => [
|
||||
// [
|
||||
// 'value' => ,
|
||||
// 'date' =>
|
||||
// ]
|
||||
// ],
|
||||
// 'nameTotal' => [
|
||||
|
||||
// ]
|
||||
// ];
|
||||
|
||||
$response->json([
|
||||
$usage = new Document([
|
||||
'range' => $range,
|
||||
'create' => [
|
||||
'data' => $create,
|
||||
'total' => \array_sum(\array_map(function ($item) {
|
||||
return $item['value'];
|
||||
}, $create)),
|
||||
],
|
||||
'read' => [
|
||||
'data' => $read,
|
||||
'total' => \array_sum(\array_map(function ($item) {
|
||||
return $item['value'];
|
||||
}, $read)),
|
||||
],
|
||||
'update' => [
|
||||
'data' => $update,
|
||||
'total' => \array_sum(\array_map(function ($item) {
|
||||
return $item['value'];
|
||||
}, $update)),
|
||||
],
|
||||
'delete' => [
|
||||
'data' => $delete,
|
||||
'total' => \array_sum(\array_map(function ($item) {
|
||||
return $item['value'];
|
||||
}, $delete)),
|
||||
],
|
||||
'files.create' => $stats["storage.buckets.$bucketId.files.create"],
|
||||
'files.read' => $stats["storage.buckets.$bucketId.files.read"],
|
||||
'files.update' => $stats["storage.buckets.$bucketId.files.update"],
|
||||
'files.delete' => $stats["storage.buckets.$bucketId.files.delete"]
|
||||
]);
|
||||
} else {
|
||||
$response->json([]);
|
||||
}
|
||||
|
||||
$response->dynamic($usage, Response::MODEL_BUCKETS_USAGE);
|
||||
});
|
|
@ -12,6 +12,7 @@ use Appwrite\Utopia\Response\Model\None;
|
|||
use Appwrite\Utopia\Response\Model\Any;
|
||||
use Appwrite\Utopia\Response\Model\Attribute;
|
||||
use Appwrite\Utopia\Response\Model\BaseList;
|
||||
use Appwrite\Utopia\Response\Model\BucketsUsage;
|
||||
use Appwrite\Utopia\Response\Model\Collection;
|
||||
use Appwrite\Utopia\Response\Model\CollectionUsage;
|
||||
use Appwrite\Utopia\Response\Model\Continent;
|
||||
|
@ -45,6 +46,7 @@ use Appwrite\Utopia\Response\Model\Token;
|
|||
use Appwrite\Utopia\Response\Model\Webhook;
|
||||
use Appwrite\Utopia\Response\Model\Preferences;
|
||||
use Appwrite\Utopia\Response\Model\Mock; // Keep last
|
||||
use Appwrite\Utopia\Response\Model\StorageUsage;
|
||||
use stdClass;
|
||||
|
||||
/**
|
||||
|
@ -88,6 +90,8 @@ class Response extends SwooleResponse
|
|||
const MODEL_FILE = 'file';
|
||||
const MODEL_FILE_LIST = 'fileList';
|
||||
const MODEL_BUCKET = 'bucket'; // - Missing
|
||||
const MODEL_BUCKETS_USAGE = 'bucketsUsage';
|
||||
const MODEL_STORAGE_USAGE = 'storageUsage';
|
||||
|
||||
// Locale
|
||||
const MODEL_LOCALE = 'locale';
|
||||
|
@ -198,6 +202,8 @@ class Response extends SwooleResponse
|
|||
->setModel(new JWT())
|
||||
->setModel(new Locale())
|
||||
->setModel(new File())
|
||||
->setModel(new StorageUsage())
|
||||
->setModel(new BucketsUsage())
|
||||
->setModel(new Team())
|
||||
->setModel(new Membership())
|
||||
->setModel(new Func())
|
||||
|
|
70
src/Appwrite/Utopia/Response/Model/BucketsUsage.php
Normal file
70
src/Appwrite/Utopia/Response/Model/BucketsUsage.php
Normal file
|
@ -0,0 +1,70 @@
|
|||
<?php
|
||||
|
||||
namespace Appwrite\Utopia\Response\Model;
|
||||
|
||||
use Appwrite\Utopia\Response;
|
||||
use Appwrite\Utopia\Response\Model;
|
||||
use stdClass;
|
||||
|
||||
class BucketsUsage extends Model
|
||||
{
|
||||
public function __construct()
|
||||
{
|
||||
$this
|
||||
->addRule('range', [
|
||||
'type' => self::TYPE_STRING,
|
||||
'description' => 'The time range of the usage stats.',
|
||||
'default' => '',
|
||||
'example' => '30d',
|
||||
])
|
||||
->addRule('files.create', [
|
||||
'type' => Response::MODEL_METRIC_LIST,
|
||||
'description' => 'Aggregated stats for files created.',
|
||||
'default' => [],
|
||||
'example' => new stdClass,
|
||||
'array' => true
|
||||
])
|
||||
->addRule('files.read', [
|
||||
'type' => Response::MODEL_METRIC_LIST,
|
||||
'description' => 'Aggregated stats for files read.',
|
||||
'default' => [],
|
||||
'example' => new stdClass,
|
||||
'array' => true
|
||||
])
|
||||
->addRule('files.update', [
|
||||
'type' => Response::MODEL_METRIC_LIST,
|
||||
'description' => 'Aggregated stats for files updated.',
|
||||
'default' => [],
|
||||
'example' => new stdClass,
|
||||
'array' => true
|
||||
])
|
||||
->addRule('files.delete', [
|
||||
'type' => Response::MODEL_METRIC_LIST,
|
||||
'description' => 'Aggregated stats for files deleted.',
|
||||
'default' => [],
|
||||
'example' => new stdClass,
|
||||
'array' => true
|
||||
])
|
||||
;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get Name
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getName():string
|
||||
{
|
||||
return 'BucketsUsage';
|
||||
}
|
||||
|
||||
/**
|
||||
* Get Collection
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getType():string
|
||||
{
|
||||
return Response::MODEL_BUCKETS_USAGE;
|
||||
}
|
||||
}
|
|
@ -12,10 +12,10 @@ class CollectionUsage extends Model
|
|||
{
|
||||
$this
|
||||
->addRule('range', [
|
||||
'type' => self::TYPE_INTEGER,
|
||||
'description' => 'The value of this metric at a timestamp.',
|
||||
'default' => 0,
|
||||
'example' => 1,
|
||||
'type' => self::TYPE_STRING,
|
||||
'description' => 'The time range of the usage stats.',
|
||||
'default' => '',
|
||||
'example' => '30d',
|
||||
])
|
||||
->addRule('documents.count', [
|
||||
'type' => Response::MODEL_METRIC_LIST,
|
||||
|
|
|
@ -12,10 +12,10 @@ class DatabaseUsage extends Model
|
|||
{
|
||||
$this
|
||||
->addRule('range', [
|
||||
'type' => self::TYPE_INTEGER,
|
||||
'description' => 'The value of this metric at a timestamp.',
|
||||
'default' => 0,
|
||||
'example' => 1,
|
||||
'type' => self::TYPE_STRING,
|
||||
'description' => 'The time range of the usage stats.',
|
||||
'default' => '',
|
||||
'example' => '30d',
|
||||
])
|
||||
->addRule('documents.count', [
|
||||
'type' => Response::MODEL_METRIC_LIST,
|
||||
|
|
56
src/Appwrite/Utopia/Response/Model/StorageUsage.php
Normal file
56
src/Appwrite/Utopia/Response/Model/StorageUsage.php
Normal file
|
@ -0,0 +1,56 @@
|
|||
<?php
|
||||
|
||||
namespace Appwrite\Utopia\Response\Model;
|
||||
|
||||
use Appwrite\Utopia\Response;
|
||||
use Appwrite\Utopia\Response\Model;
|
||||
use stdClass;
|
||||
|
||||
class StorageUsage extends Model
|
||||
{
|
||||
public function __construct()
|
||||
{
|
||||
$this
|
||||
->addRule('range', [
|
||||
'type' => self::TYPE_STRING,
|
||||
'description' => 'The time range of the usage stats.',
|
||||
'default' => '',
|
||||
'example' => '30d',
|
||||
])
|
||||
->addRule('storage', [
|
||||
'type' => Response::MODEL_METRIC_LIST,
|
||||
'description' => 'Aggregated stats for the occupied storage size.',
|
||||
'default' => [],
|
||||
'example' => new stdClass,
|
||||
'array' => true
|
||||
])
|
||||
->addRule('files', [
|
||||
'type' => Response::MODEL_METRIC_LIST,
|
||||
'description' => 'Aggregated stats for total number of files.',
|
||||
'default' => [],
|
||||
'example' => new stdClass,
|
||||
'array' => true
|
||||
])
|
||||
;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get Name
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getName():string
|
||||
{
|
||||
return 'StorageUsage';
|
||||
}
|
||||
|
||||
/**
|
||||
* Get Collection
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getType():string
|
||||
{
|
||||
return Response::MODEL_STORAGE_USAGE;
|
||||
}
|
||||
}
|
Loading…
Reference in a new issue