Merge pull request #5972 from appwrite/feat-1.4-request-response-filters

Create 1.4 request filters
This commit is contained in:
Jake Barnby 2023-08-22 17:25:13 -04:00 committed by GitHub
commit 3ff57fe33f
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
6 changed files with 116 additions and 5 deletions

View file

@ -414,7 +414,7 @@ return [
],
Exception::FUNCTION_ENTRYPOINT_MISSING => [
'name' => Exception::FUNCTION_RUNTIME_UNSUPPORTED,
'description' => 'Entrypoint missing. Specify it in function settings.',
'description' => 'Function entrypoint is not configured. Please specify it in function settings or when making deployment.',
'code' => 404,
],

View file

@ -134,14 +134,14 @@ App::post('/v1/functions')
->label('sdk.response.model', Response::MODEL_FUNCTION)
->param('functionId', '', new CustomId(), 'Function ID. Choose a custom ID or generate a random ID with `ID.unique()`. Valid chars are a-z, A-Z, 0-9, period, hyphen, and underscore. Can\'t start with a special char. Max length is 36 chars.')
->param('name', '', new Text(128), 'Function name. Max length: 128 chars.')
->param('runtime', '', new WhiteList(array_keys(Config::getParam('runtimes')), true), 'Execution runtime.')
->param('execute', [], new Roles(APP_LIMIT_ARRAY_PARAMS_SIZE), 'An array of strings with execution roles. By default no user is granted with any execute permissions. [learn more about permissions](https://appwrite.io/docs/permissions). Maximum of ' . APP_LIMIT_ARRAY_PARAMS_SIZE . ' roles are allowed, each 64 characters long.', true)
->param('runtime', '', new WhiteList(array_keys(Config::getParam('runtimes')), true), 'Execution runtime.')
->param('events', [], new ArrayList(new ValidatorEvent(), APP_LIMIT_ARRAY_PARAMS_SIZE), 'Events list. Maximum of ' . APP_LIMIT_ARRAY_PARAMS_SIZE . ' events are allowed.', true)
->param('schedule', '', new Cron(), 'Schedule CRON syntax.', true)
->param('timeout', 15, new Range(1, (int) App::getEnv('_APP_FUNCTIONS_TIMEOUT', 900)), 'Function maximum execution time in seconds.', true)
->param('enabled', true, new Boolean(), 'Is function enabled?', true)
->param('logging', true, new Boolean(), 'Do executions get logged?', true)
->param('entrypoint', '', new Text(1028), 'Entrypoint File.')
->param('entrypoint', '', new Text(1028, 0), 'Entrypoint File.', true)
->param('commands', '', new Text(8192, 0), 'Build Commands.', true)
->param('installationId', '', new Text(128, 0), 'Appwrite Installation ID for vcs deployment.', true)
->param('providerRepositoryId', '', new Text(128, 0), 'Repository ID of the repo linked to the function', true)
@ -660,14 +660,14 @@ App::put('/v1/functions/:functionId')
->label('sdk.response.model', Response::MODEL_FUNCTION)
->param('functionId', '', new UID(), 'Function ID.')
->param('name', '', new Text(128), 'Function name. Max length: 128 chars.')
->param('runtime', '', new WhiteList(array_keys(Config::getParam('runtimes')), true), 'Execution runtime.')
->param('execute', [], new Roles(APP_LIMIT_ARRAY_PARAMS_SIZE), 'An array of strings with execution roles. By default no user is granted with any execute permissions. [learn more about permissions](https://appwrite.io/docs/permissions). Maximum of ' . APP_LIMIT_ARRAY_PARAMS_SIZE . ' roles are allowed, each 64 characters long.', true)
->param('runtime', '', new WhiteList(array_keys(Config::getParam('runtimes')), true), 'Execution runtime.')
->param('events', [], new ArrayList(new ValidatorEvent(), APP_LIMIT_ARRAY_PARAMS_SIZE), 'Events list. Maximum of ' . APP_LIMIT_ARRAY_PARAMS_SIZE . ' events are allowed.', true)
->param('schedule', '', new Cron(), 'Schedule CRON syntax.', true)
->param('timeout', 15, new Range(1, (int) App::getEnv('_APP_FUNCTIONS_TIMEOUT', 900)), 'Maximum execution time in seconds.', true)
->param('enabled', true, new Boolean(), 'Is function enabled?', true)
->param('logging', true, new Boolean(), 'Do executions get logged?', true)
->param('entrypoint', '', new Text(1028), 'Entrypoint File.')
->param('entrypoint', '', new Text(1028, 0), 'Entrypoint File.', true)
->param('commands', '', new Text(8192, 0), 'Build Commands.', true)
->param('installationId', '', new Text(128, 0), 'Appwrite Installation ID for vcs deployment.', true)
->param('providerRepositoryId', '', new Text(128, 0), 'Repository ID of the repo linked to the function', true)
@ -709,6 +709,10 @@ App::put('/v1/functions/:functionId')
$repositoryId = $function->getAttribute('repositoryId', '');
$repositoryInternalId = $function->getAttribute('repositoryInternalId', '');
if (empty($entrypoint)) {
$entrypoint = $function->getAttribute('entrypoint', '');
}
$isConnected = !empty($function->getAttribute('providerRepositoryId', ''));
// Git disconnect logic

View file

@ -37,6 +37,7 @@ use Appwrite\Utopia\Request\Filters\V12 as RequestV12;
use Appwrite\Utopia\Request\Filters\V13 as RequestV13;
use Appwrite\Utopia\Request\Filters\V14 as RequestV14;
use Appwrite\Utopia\Request\Filters\V15 as RequestV15;
use Appwrite\Utopia\Request\Filters\V16 as RequestV16;
use Utopia\Validator\Text;
use Utopia\Validator\WhiteList;
@ -223,6 +224,9 @@ App::init()
case version_compare($requestFormat, '0.15.3', '<'):
Request::setFilter(new RequestV15());
break;
case version_compare($requestFormat, '1.4.0', '<'):
Request::setFilter(new RequestV16());
break;
default:
Request::setFilter(null);
}

View file

@ -86,6 +86,10 @@ class BuildsV1 extends Worker
throw new Exception('Deployment not found', 404);
}
if (empty($deployment->getAttribute('entrypoint', ''))) {
throw new Exception('Function entrypoint is not configured. Please specify it in function settings or when making deployment.', 500);
}
$runtimes = Config::getParam('runtimes', []);
$key = $function->getAttribute('runtime');
$runtime = isset($runtimes[$key]) ? $runtimes[$key] : null;

View file

@ -0,0 +1,48 @@
<?php
namespace Appwrite\Utopia\Request\Filters;
use Appwrite\Utopia\Request\Filter;
class V16 extends Filter
{
// Convert 1.3 params to 1.4
public function parse(array $content, string $model): array
{
switch ($model) {
case 'functions.create':
$content['commands'] = $this->getCommands($content['runtime']);
break;
case 'functions.update':
$content['commands'] = $this->getCommands($content['runtime']);
break;
case 'functions.createExecution':
$content['body'] = $content['data'];
unset($content['data']);
break;
}
return $content;
}
private function getCommands(string $runtime): string
{
if (\str_starts_with($runtime, 'node')) {
return 'npm install';
} elseif (\str_starts_with($runtime, 'python')) {
return 'pip install --no-cache-dir -r requirements.txt';
} elseif (\str_starts_with($runtime, 'dart')) {
return 'dart pub get';
} elseif (\str_starts_with($runtime, 'php')) {
return 'composer update --no-interaction --ignore-platform-reqs --optimize-autoloader --prefer-dist --no-dev';
} elseif (\str_starts_with($runtime, 'ruby')) {
return 'bundle install';
} elseif (\str_starts_with($runtime, 'swift')) {
return 'swift package resolve';
} elseif (\str_starts_with($runtime, 'dotnet')) {
return 'dotnet restore';
}
return '';
}
}

View file

@ -0,0 +1,51 @@
<?php
namespace Tests\Unit\Utopia\Request\Filters;
use Appwrite\Utopia\Request\Filter;
use Appwrite\Utopia\Request\Filters\V16;
use Appwrite\Utopia\Response\Model;
use PHPUnit\Framework\TestCase;
class V16Test extends TestCase
{
/**
* @var Filter
*/
protected $filter;
public function setUp(): void
{
$this->filter = new V16();
}
public function tearDown(): void
{
}
public function createExecutionProvider(): array
{
return [
'data' => [
[
'data' => 'Lorem ipsum'
],
[
'body' => 'Lorem ipsum'
],
],
];
}
/**
* @dataProvider createExecutionProvider
*/
public function testCreateExecution(array $content, array $expected): void
{
$model = 'functions.createExecution';
$result = $this->filter->parse($content, $model);
$this->assertEquals($expected, $result);
}
}