From f3dcd6a79f145e9e3c0dcc0152f9286989173c9b Mon Sep 17 00:00:00 2001 From: shimon Date: Sun, 25 Dec 2022 13:06:25 +0200 Subject: [PATCH 01/18] add internalId to collections --- app/config/collections.php | 66 +++++++++++++++++++++++++++++++ app/controllers/api/functions.php | 4 ++ app/workers/builds.php | 4 +- app/workers/functions.php | 3 +- 4 files changed, 75 insertions(+), 2 deletions(-) diff --git a/app/config/collections.php b/app/config/collections.php index a8c7a46b18..d6c56fac93 100644 --- a/app/config/collections.php +++ b/app/config/collections.php @@ -785,6 +785,17 @@ $collections = [ 'array' => false, 'filters' => [], ], + [ + '$id' => ID::custom('resourceInternalId'), + 'type' => Database::VAR_STRING, + 'format' => '', + 'size' => Database::LENGTH_KEY, + 'signed' => true, + 'required' => false, + 'default' => null, + 'array' => false, + 'filters' => [], + ], [ '$id' => ID::custom('resourceId'), 'type' => Database::VAR_STRING, @@ -2370,6 +2381,17 @@ $collections = [ '$id' => ID::custom('deployments'), 'name' => 'Deployments', 'attributes' => [ + [ + '$id' => ID::custom('resourceInternalId'), + 'type' => Database::VAR_STRING, + 'format' => '', + 'size' => Database::LENGTH_KEY, + 'signed' => true, + 'required' => false, + 'default' => null, + 'array' => false, + 'filters' => [], + ], [ '$id' => ID::custom('resourceId'), 'type' => Database::VAR_STRING, @@ -2392,6 +2414,17 @@ $collections = [ 'array' => false, 'filters' => [], ], + [ + '$id' => ID::custom('buildInternalId'), + 'type' => Database::VAR_STRING, + 'format' => '', + 'size' => Database::LENGTH_KEY, + 'signed' => true, + 'required' => false, + 'default' => null, + 'array' => false, + 'filters' => [], + ], [ '$id' => ID::custom('buildId'), 'type' => Database::VAR_STRING, @@ -2572,6 +2605,17 @@ $collections = [ 'array' => false, 'filters' => [], ], + [ + '$id' => 'deploymentInternalId', + 'type' => Database::VAR_STRING, + 'format' => '', + 'size' => Database::LENGTH_KEY, + 'signed' => true, + 'required' => false, + 'default' => null, + 'array' => false, + 'filters' => [], + ], [ '$id' => ID::custom('deploymentId'), 'type' => Database::VAR_STRING, @@ -2688,6 +2732,17 @@ $collections = [ '$id' => ID::custom('executions'), 'name' => 'Executions', 'attributes' => [ + [ + '$id' => ID::custom('functionInternalId'), + 'type' => Database::VAR_STRING, + 'format' => '', + 'size' => Database::LENGTH_KEY, + 'signed' => true, + 'required' => false, + 'default' => null, + 'array' => false, + 'filters' => [], + ], [ '$id' => ID::custom('functionId'), 'type' => Database::VAR_STRING, @@ -2699,6 +2754,17 @@ $collections = [ 'array' => false, 'filters' => [], ], + [ + '$id' => ID::custom('deploymentInternalId'), + 'type' => Database::VAR_STRING, + 'format' => '', + 'size' => Database::LENGTH_KEY, + 'signed' => true, + 'required' => false, + 'default' => null, + 'array' => false, + 'filters' => [], + ], [ '$id' => ID::custom('deploymentId'), 'type' => Database::VAR_STRING, diff --git a/app/controllers/api/functions.php b/app/controllers/api/functions.php index 4c84795712..25a4541ca0 100644 --- a/app/controllers/api/functions.php +++ b/app/controllers/api/functions.php @@ -740,6 +740,7 @@ App::post('/v1/functions/:functionId/deployments') Permission::update(Role::any()), Permission::delete(Role::any()), ], + 'resourceInternalId' => $function->getInternalId(), 'resourceId' => $function->getId(), 'resourceType' => 'functions', 'entrypoint' => $entrypoint, @@ -770,6 +771,7 @@ App::post('/v1/functions/:functionId/deployments') Permission::update(Role::any()), Permission::delete(Role::any()), ], + 'resourceInternalId' => $function->getInternalId(), 'resourceId' => $function->getId(), 'resourceType' => 'functions', 'entrypoint' => $entrypoint, @@ -1116,7 +1118,9 @@ App::post('/v1/functions/:functionId/executions') $execution = Authorization::skip(fn () => $dbForProject->createDocument('executions', new Document([ '$id' => $executionId, '$permissions' => !$user->isEmpty() ? [Permission::read(Role::user($user->getId()))] : [], + 'functionInternalId' => $function->getInternalId(), 'functionId' => $function->getId(), + 'deploymentInternalId' => $deployment->getInternalId(), 'deploymentId' => $deployment->getId(), 'trigger' => 'http', // http / schedule / event 'status' => $async ? 'waiting' : 'processing', // waiting / processing / completed / failed diff --git a/app/workers/builds.php b/app/workers/builds.php index 081537fdfb..fc0d40251c 100644 --- a/app/workers/builds.php +++ b/app/workers/builds.php @@ -97,6 +97,7 @@ class BuildsV1 extends Worker '$id' => $buildId, '$permissions' => [], 'startTime' => $startTime, + 'deploymentInternalId' => $deployment->getInternalId(), 'deploymentId' => $deployment->getId(), 'status' => 'processing', 'path' => '', @@ -108,7 +109,8 @@ class BuildsV1 extends Worker 'stderr' => '', 'duration' => 0 ])); - $deployment->setAttribute('buildId', $buildId); + $deployment->setAttribute('buildId', $build->getId()); + $deployment->setAttribute('buildInternalId', $build->getInternalId()); $deployment = $dbForProject->updateDocument('deployments', $deployment->getId(), $deployment); } else { $build = $dbForProject->getDocument('builds', $buildId); diff --git a/app/workers/functions.php b/app/workers/functions.php index 2e8dccc7aa..07fef99750 100644 --- a/app/workers/functions.php +++ b/app/workers/functions.php @@ -209,7 +209,8 @@ Server::setResource('execute', function () { $usage ->setParam('projectId', $project->getId()) ->setParam('projectInternalId', $project->getInternalId()) - ->setParam('functionId', $function->getId()) // TODO: We should use functionInternalId in usage stats + ->setParam('functionId', $function->getId()) + ->setParam('functionInternalId', $function->getInternalId()) ->setParam('executions.{scope}.compute', 1) ->setParam('executionStatus', $execution->getAttribute('status', '')) ->setParam('executionTime', $execution->getAttribute('duration')) From f96a9c3618447927504f376a5b621d8d1f1bb9e7 Mon Sep 17 00:00:00 2001 From: shimon Date: Sun, 25 Dec 2022 13:07:27 +0200 Subject: [PATCH 02/18] add internalId to collections --- app/console | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/console b/app/console index 43891a526e..b1a81a390a 160000 --- a/app/console +++ b/app/console @@ -1 +1 @@ -Subproject commit 43891a526e061454617cbb13def3c4901d99a7f1 +Subproject commit b1a81a390a05746701651fca49e0d853f430677c From 586c7fac7c6d93ed6aaa1b4b3540e0582a2d62a2 Mon Sep 17 00:00:00 2001 From: shimon Date: Sun, 25 Dec 2022 14:07:54 +0200 Subject: [PATCH 03/18] add internalId to collections --- app/config/collections.php | 22 ++++++++++++++++++++++ app/controllers/api/functions.php | 4 ++++ app/workers/builds.php | 1 + 3 files changed, 27 insertions(+) diff --git a/app/config/collections.php b/app/config/collections.php index d6c56fac93..b9142f36de 100644 --- a/app/config/collections.php +++ b/app/config/collections.php @@ -2234,6 +2234,17 @@ $collections = [ 'array' => false, 'filters' => [], ], + [ + '$id' => ID::custom('deploymentInternalId'), + 'type' => Database::VAR_STRING, + 'format' => '', + 'size' => Database::LENGTH_KEY, + 'signed' => true, + 'required' => false, + 'default' => null, + 'array' => false, + 'filters' => [], + ], [ '$id' => ID::custom('deployment'), 'type' => Database::VAR_STRING, @@ -2267,6 +2278,17 @@ $collections = [ 'array' => true, 'filters' => [], ], + [ + '$id' => ID::custom('scheduleInternalId'), + 'type' => Database::VAR_STRING, + 'format' => '', + 'size' => Database::LENGTH_KEY, + 'signed' => true, + 'required' => false, + 'default' => null, + 'array' => false, + 'filters' => [], + ], [ '$id' => ID::custom('scheduleId'), 'type' => Database::VAR_STRING, diff --git a/app/controllers/api/functions.php b/app/controllers/api/functions.php index 25a4541ca0..a88b727b37 100644 --- a/app/controllers/api/functions.php +++ b/app/controllers/api/functions.php @@ -81,6 +81,7 @@ App::post('/v1/functions') 'enabled' => $enabled, 'name' => $name, 'runtime' => $runtime, + 'deploymentInternalId' => '', 'deployment' => '', 'events' => $events, 'schedule' => $schedule, @@ -102,6 +103,7 @@ App::post('/v1/functions') ); $function->setAttribute('scheduleId', $schedule->getId()); + $function->setAttribute('scheduleInternalId', $schedule->getInternalId()); $dbForProject->updateDocument('functions', $function->getId(), $function); $eventsInstance->setParam('functionId', $function->getId()); @@ -534,6 +536,7 @@ App::patch('/v1/functions/:functionId/deployments/:deploymentId') } $function = $dbForProject->updateDocument('functions', $function->getId(), new Document(array_merge($function->getArrayCopy(), [ + 'deploymentInternalId' => $deployment->getInternalId(), 'deployment' => $deployment->getId() ]))); @@ -969,6 +972,7 @@ App::delete('/v1/functions/:functionId/deployments/:deploymentId') if ($function->getAttribute('deployment') === $deployment->getId()) { // Reset function deployment $function = $dbForProject->updateDocument('functions', $function->getId(), new Document(array_merge($function->getArrayCopy(), [ 'deployment' => '', + 'deploymentInternalId' => '', ]))); } diff --git a/app/workers/builds.php b/app/workers/builds.php index fc0d40251c..598181a9c1 100644 --- a/app/workers/builds.php +++ b/app/workers/builds.php @@ -206,6 +206,7 @@ class BuildsV1 extends Worker /** Set auto deploy */ if ($deployment->getAttribute('activate') === true) { + $function->setAttribute('deploymentInternalId', $deployment->getInternalId()); $function->setAttribute('deployment', $deployment->getId()); $function = $dbForProject->updateDocument('functions', $function->getId(), $function); } From 7d40488724e245e9d744b6bbe15d1a63f5cfc6e3 Mon Sep 17 00:00:00 2001 From: shimon Date: Mon, 16 Jan 2023 20:52:46 +0200 Subject: [PATCH 04/18] test adjustments --- app/realtime.php | 2 +- .../Functions/FunctionsCustomServerTest.php | 3 +-- .../Realtime/RealtimeCustomClientTest.php | 25 +++---------------- 3 files changed, 5 insertions(+), 25 deletions(-) diff --git a/app/realtime.php b/app/realtime.php index 4b40e2a9dd..a7095ea505 100644 --- a/app/realtime.php +++ b/app/realtime.php @@ -432,7 +432,7 @@ $server->onOpen(function (int $connection, SwooleRequest $request) use ($server, } $roles = Auth::getRoles($user); - + var_dump($request->getQuery('channels', [])); $channels = Realtime::convertChannels($request->getQuery('channels', []), $user->getId()); /** diff --git a/tests/e2e/Services/Functions/FunctionsCustomServerTest.php b/tests/e2e/Services/Functions/FunctionsCustomServerTest.php index e2d7b8482b..e97c1412b6 100644 --- a/tests/e2e/Services/Functions/FunctionsCustomServerTest.php +++ b/tests/e2e/Services/Functions/FunctionsCustomServerTest.php @@ -635,7 +635,7 @@ class FunctionsCustomServerTest extends Scope $this->assertStringContainsString('8.0', $execution['body']['response']); $this->assertStringContainsString('êä', $execution['body']['response']); // tests unknown utf-8 chars $this->assertEquals('', $execution['body']['stderr']); - $this->assertLessThan(1.500, $execution['body']['duration']); + $this->assertLessThan(3, $execution['body']['duration']); /** * Test for FAILURE @@ -915,7 +915,6 @@ class FunctionsCustomServerTest extends Scope $this->assertEquals($executions['body']['executions'][0]['statusCode'], 500); $this->assertGreaterThan(2, $executions['body']['executions'][0]['duration']); $this->assertLessThan(6, $executions['body']['executions'][0]['duration']); - $this->assertGreaterThan(4, $executions['body']['executions'][0]['duration']); $this->assertEquals($executions['body']['executions'][0]['response'], ''); $this->assertEquals($executions['body']['executions'][0]['stderr'], 'An internal curl error has occurred within the executor! Error Msg: Operation timed out'); diff --git a/tests/e2e/Services/Realtime/RealtimeCustomClientTest.php b/tests/e2e/Services/Realtime/RealtimeCustomClientTest.php index 7f09cb5703..be8f81f445 100644 --- a/tests/e2e/Services/Realtime/RealtimeCustomClientTest.php +++ b/tests/e2e/Services/Realtime/RealtimeCustomClientTest.php @@ -211,25 +211,6 @@ class RealtimeCustomClientTest extends Scope $this->assertEquals(1003, $response['data']['code']); $this->assertEquals('Message format is not valid.', $response['data']['message']); - - $client->close(); - } - - public function testConnectionPlatform() - { - /** - * Test for FAILURE - */ - $client = $this->getWebsocket(['documents'], ['origin' => 'http://appwrite.unknown']); - $payload = json_decode($client->receive(), true); - - $this->assertArrayHasKey('type', $payload); - $this->assertArrayHasKey('data', $payload); - $this->assertEquals('error', $payload['type']); - $this->assertEquals(1008, $payload['data']['code']); - $this->assertEquals('Invalid Origin. Register your new client (appwrite.unknown) as a new Web platform on your project console dashboard', $payload['data']['message']); - \usleep(250000); // 250ms - $this->expectException(ConnectionException::class); // Check if server disconnnected client $client->close(); } @@ -459,8 +440,8 @@ class RealtimeCustomClientTest extends Scope $this->assertNotEmpty($response['data']['payload']); /** - * Test Account Session Create - */ +// * Test Account Session Create +// */ $response = $this->client->call(Client::METHOD_POST, '/account/sessions/email', array_merge([ 'origin' => 'http://localhost', 'content-type' => 'application/json', @@ -1248,7 +1229,7 @@ class RealtimeCustomClientTest extends Scope $this->assertNotEmpty($deployment['body']['$id']); // Wait for deployment to be built. - sleep(5); + sleep(10); $response = $this->client->call(Client::METHOD_PATCH, '/functions/' . $functionId . '/deployments/' . $deploymentId, array_merge([ 'content-type' => 'application/json', From abf67f846931856103431c16f1ec2f5f8996d13d Mon Sep 17 00:00:00 2001 From: shimon Date: Tue, 17 Jan 2023 15:10:05 +0200 Subject: [PATCH 05/18] test adjustments --- tests/e2e/General/UsageTest.php | 27 +++++++++++++++++---------- 1 file changed, 17 insertions(+), 10 deletions(-) diff --git a/tests/e2e/General/UsageTest.php b/tests/e2e/General/UsageTest.php index 4dddaf1535..59e80fdb04 100644 --- a/tests/e2e/General/UsageTest.php +++ b/tests/e2e/General/UsageTest.php @@ -85,7 +85,7 @@ class UsageTest extends Scope #[Retry(count: 1)] public function testUsersStats(array $data): array { - sleep(20); + sleep(30); $projectId = $data['projectId']; $headers = $data['headers']; @@ -112,11 +112,15 @@ class UsageTest extends Scope $this->assertEquals($requestsCount, $res['requests'][array_key_last($res['requests'])]['value']); $this->validateDates($res['requests']); + $requestsCount++; + $res = $this->client->call(Client::METHOD_GET, '/users/usage?range=30d', array_merge($headers, [ 'x-appwrite-project' => $projectId, 'x-appwrite-mode' => 'admin' ])); + $requestsCount++; + $res = $res['body']; $this->assertEquals(10, $res['usersCreate'][array_key_last($res['usersCreate'])]['value']); $this->validateDates($res['usersCreate']); @@ -266,7 +270,7 @@ class UsageTest extends Scope $filesCreate = $data['filesCreate']; $filesDelete = $data['filesDelete']; - sleep(20); + sleep(30); // console request $headers = [ @@ -279,7 +283,6 @@ class UsageTest extends Scope $res = $this->client->call(Client::METHOD_GET, '/project/usage?range=30d', $headers); $res = $res['body']; - $this->assertEquals(9, count($res)); $this->assertEquals(30, count($res['requests'])); $this->assertEquals(30, count($res['storage'])); @@ -287,12 +290,13 @@ class UsageTest extends Scope $this->validateDates($res['requests']); $this->assertEquals($storageTotal, $res['storage'][array_key_last($res['storage'])]['value']); $this->validateDates($res['storage']); + $requestsCount++; $res = $this->client->call(Client::METHOD_GET, '/storage/usage?range=30d', array_merge($headers, [ 'x-appwrite-project' => $projectId, 'x-appwrite-mode' => 'admin' ])); - $requestsCount++; + $res = $res['body']; $this->assertEquals($storageTotal, $res['storage'][array_key_last($res['storage'])]['value']); $this->validateDates($res['storage']); @@ -312,19 +316,20 @@ class UsageTest extends Scope $this->validateDates($res['filesCreate']); $this->assertEquals($filesDelete, $res['filesDelete'][array_key_last($res['filesDelete'])]['value']); $this->validateDates($res['filesDelete']); + $requestsCount++; $res = $this->client->call(Client::METHOD_GET, '/storage/' . $bucketId . '/usage?range=30d', array_merge($headers, [ 'x-appwrite-project' => $projectId, 'x-appwrite-mode' => 'admin' ])); - $requestsCount++; + $res = $res['body']; $this->assertEquals($storageTotal, $res['filesStorage'][array_key_last($res['filesStorage'])]['value']); $this->assertEquals($filesCount, $res['filesCount'][array_key_last($res['filesCount'])]['value']); $this->assertEquals($filesRead, $res['filesRead'][array_key_last($res['filesRead'])]['value']); $this->assertEquals($filesCreate, $res['filesCreate'][array_key_last($res['filesCreate'])]['value']); $this->assertEquals($filesDelete, $res['filesDelete'][array_key_last($res['filesDelete'])]['value']); - + $requestsCount++; $data['requestsCount'] = $requestsCount; return $data; } @@ -361,6 +366,7 @@ class UsageTest extends Scope 'databaseId' => 'unique()', 'name' => $name, ]); + $this->assertEquals($name, $res['body']['name']); $this->assertNotEmpty($res['body']['$id']); $databaseId = $res['body']['$id']; @@ -382,7 +388,7 @@ class UsageTest extends Scope $requestsCount += 2; } } - + exit; for ($i = 0; $i < 10; $i++) { $name = uniqid() . ' collection'; $res = $this->client->call(Client::METHOD_POST, '/databases/' . $databaseId . '/collections', $headers, [ @@ -426,7 +432,8 @@ class UsageTest extends Scope $this->assertEquals('name', $res['body']['key']); $collectionsUpdate++; $requestsCount++; - sleep(20); + + sleep(30); for ($i = 0; $i < 10; $i++) { $name = uniqid() . ' collection'; @@ -508,7 +515,7 @@ class UsageTest extends Scope $documentsRead = $data['documentsRead']; $documentsDelete = $data['documentsDelete']; - sleep(20); + sleep(30); // check datbase stats $headers = [ @@ -738,7 +745,7 @@ class UsageTest extends Scope $executions = $data['executions']; $failures = $data['failures']; - sleep(20); + sleep(30); $response = $this->client->call(Client::METHOD_GET, '/functions/' . $functionId . '/usage', $headers, [ 'range' => '30d' From 61f4fedbb3e269574c09449bd85250b48b3d4662 Mon Sep 17 00:00:00 2001 From: shimon Date: Sun, 22 Jan 2023 17:21:00 +0200 Subject: [PATCH 06/18] test adjustments --- app/controllers/shared/api.php | 56 ++++++++++--- composer.lock | 138 ++++++++++++++++---------------- docker-compose.yml | 1 + tests/e2e/General/UsageTest.php | 17 ++-- 4 files changed, 126 insertions(+), 86 deletions(-) diff --git a/app/controllers/shared/api.php b/app/controllers/shared/api.php index db35cebc65..fa247b8e78 100644 --- a/app/controllers/shared/api.php +++ b/app/controllers/shared/api.php @@ -5,14 +5,13 @@ use Appwrite\Event\Audit; use Appwrite\Event\Database as EventDatabase; use Appwrite\Event\Delete; use Appwrite\Event\Event; -use Appwrite\Event\Func; use Appwrite\Event\Mail; +use Appwrite\Extend\Exception; use Appwrite\Messaging\Adapter\Realtime; use Appwrite\Usage\Stats; use Appwrite\Utopia\Response; use Appwrite\Utopia\Request; use Utopia\App; -use Appwrite\Extend\Exception; use Utopia\Abuse\Abuse; use Utopia\Abuse\Adapters\TimeLimit; use Utopia\Cache\Adapter\Filesystem; @@ -171,9 +170,9 @@ App::init() } } - /* - * Background Jobs - */ + /* + * Background Jobs + */ $events ->setEvent($route->getLabel('event', '')) ->setProject($project) @@ -319,6 +318,45 @@ App::init() } }); +/** + * Limit user session + * + * Delete older sessions if the number of sessions have crossed + * the session limit set for the project + */ +App::shutdown() + ->groups(['session']) + ->inject('utopia') + ->inject('request') + ->inject('response') + ->inject('project') + ->inject('dbForProject') + ->action(function (App $utopia, Request $request, Response $response, Document $project, Database $dbForProject) { + $sessionLimit = $project->getAttribute('auths', [])['maxSessions'] ?? APP_LIMIT_USER_SESSIONS_DEFAULT; + $session = $response->getPayload(); + $userId = $session['userId'] ?? ''; + if (empty($userId)) { + return; + } + + $user = $dbForProject->getDocument('users', $userId); + if ($user->isEmpty()) { + return; + } + + $sessions = $user->getAttribute('sessions', []); + $count = \count($sessions); + if ($count <= $sessionLimit) { + return; + } + + for ($i = 0; $i < ($count - $sessionLimit); $i++) { + $session = array_shift($sessions); + $dbForProject->deleteDocument('sessions', $session->getId()); + } + $dbForProject->deleteCachedDocument('users', $userId); + }); + App::shutdown() ->groups(['api']) ->inject('utopia') @@ -332,8 +370,7 @@ App::shutdown() ->inject('database') ->inject('mode') ->inject('dbForProject') - ->inject('queueForFunctions') - ->action(function (App $utopia, Request $request, Response $response, Document $project, Event $events, Audit $audits, Stats $usage, Delete $deletes, EventDatabase $database, string $mode, Database $dbForProject, Func $queueForFunctions) use ($parseLabel) { + ->action(function (App $utopia, Request $request, Response $response, Document $project, Event $events, Audit $audits, Stats $usage, Delete $deletes, EventDatabase $database, string $mode, Database $dbForProject) use ($parseLabel) { $responsePayload = $response->getPayload(); @@ -344,8 +381,9 @@ App::shutdown() /** * Trigger functions. */ - $queueForFunctions - ->from($events) + $events + ->setClass(Event::FUNCTIONS_CLASS_NAME) + ->setQueue(Event::FUNCTIONS_QUEUE_NAME) ->trigger(); /** diff --git a/composer.lock b/composer.lock index c8b627849e..cea427821e 100644 --- a/composer.lock +++ b/composer.lock @@ -801,20 +801,21 @@ "issues": "https://github.com/influxdata/influxdb-php/issues", "source": "https://github.com/influxdata/influxdb-php/tree/1.15.2" }, + "abandoned": true, "time": "2020-12-26T17:45:17+00:00" }, { "name": "laravel/pint", - "version": "v1.2.0", + "version": "v1.2.1", "source": { "type": "git", "url": "https://github.com/laravel/pint.git", - "reference": "1d276e4c803397a26cc337df908f55c2a4e90d86" + "reference": "e60e2112ee779ce60f253695b273d1646a17d6f1" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/laravel/pint/zipball/1d276e4c803397a26cc337df908f55c2a4e90d86", - "reference": "1d276e4c803397a26cc337df908f55c2a4e90d86", + "url": "https://api.github.com/repos/laravel/pint/zipball/e60e2112ee779ce60f253695b273d1646a17d6f1", + "reference": "e60e2112ee779ce60f253695b273d1646a17d6f1", "shasum": "" }, "require": { @@ -826,10 +827,10 @@ }, "require-dev": { "friendsofphp/php-cs-fixer": "^3.11.0", - "illuminate/view": "^9.27", - "laravel-zero/framework": "^9.1.3", - "mockery/mockery": "^1.5.0", - "nunomaduro/larastan": "^2.2", + "illuminate/view": "^9.32.0", + "laravel-zero/framework": "^9.2.0", + "mockery/mockery": "^1.5.1", + "nunomaduro/larastan": "^2.2.0", "nunomaduro/termwind": "^1.14.0", "pestphp/pest": "^1.22.1" }, @@ -867,7 +868,7 @@ "issues": "https://github.com/laravel/pint/issues", "source": "https://github.com/laravel/pint" }, - "time": "2022-09-13T15:07:15+00:00" + "time": "2022-11-29T16:25:20+00:00" }, { "name": "matomo/device-detector", @@ -1461,16 +1462,16 @@ }, { "name": "symfony/deprecation-contracts", - "version": "v3.1.1", + "version": "v3.2.0", "source": { "type": "git", "url": "https://github.com/symfony/deprecation-contracts.git", - "reference": "07f1b9cc2ffee6aaafcf4b710fbc38ff736bd918" + "reference": "1ee04c65529dea5d8744774d474e7cbd2f1206d3" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/deprecation-contracts/zipball/07f1b9cc2ffee6aaafcf4b710fbc38ff736bd918", - "reference": "07f1b9cc2ffee6aaafcf4b710fbc38ff736bd918", + "url": "https://api.github.com/repos/symfony/deprecation-contracts/zipball/1ee04c65529dea5d8744774d474e7cbd2f1206d3", + "reference": "1ee04c65529dea5d8744774d474e7cbd2f1206d3", "shasum": "" }, "require": { @@ -1479,7 +1480,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-main": "3.1-dev" + "dev-main": "3.3-dev" }, "thanks": { "name": "symfony/contracts", @@ -1508,7 +1509,7 @@ "description": "A generic function and convention to trigger deprecation notices", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/deprecation-contracts/tree/v3.1.1" + "source": "https://github.com/symfony/deprecation-contracts/tree/v3.2.0" }, "funding": [ { @@ -1524,7 +1525,7 @@ "type": "tidelift" } ], - "time": "2022-02-25T11:15:52+00:00" + "time": "2022-11-25T10:21:52+00:00" }, { "name": "utopia-php/abuse", @@ -2574,16 +2575,16 @@ }, { "name": "utopia-php/storage", - "version": "0.13.0", + "version": "0.13.2", "source": { "type": "git", "url": "https://github.com/utopia-php/storage.git", - "reference": "f34c010e4f8394a6b4aff70b6de55041d9a145d3" + "reference": "ad1c00f24ca56e73888acc2af3deee4919b1194b" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/utopia-php/storage/zipball/f34c010e4f8394a6b4aff70b6de55041d9a145d3", - "reference": "f34c010e4f8394a6b4aff70b6de55041d9a145d3", + "url": "https://api.github.com/repos/utopia-php/storage/zipball/ad1c00f24ca56e73888acc2af3deee4919b1194b", + "reference": "ad1c00f24ca56e73888acc2af3deee4919b1194b", "shasum": "" }, "require": { @@ -2623,9 +2624,9 @@ ], "support": { "issues": "https://github.com/utopia-php/storage/issues", - "source": "https://github.com/utopia-php/storage/tree/0.13.0" + "source": "https://github.com/utopia-php/storage/tree/0.13.2" }, - "time": "2022-11-17T15:10:18+00:00" + "time": "2022-12-20T11:11:35+00:00" }, { "name": "utopia-php/swoole", @@ -2905,30 +2906,30 @@ }, { "name": "doctrine/instantiator", - "version": "1.4.1", + "version": "1.5.0", "source": { "type": "git", "url": "https://github.com/doctrine/instantiator.git", - "reference": "10dcfce151b967d20fde1b34ae6640712c3891bc" + "reference": "0a0fa9780f5d4e507415a065172d26a98d02047b" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/doctrine/instantiator/zipball/10dcfce151b967d20fde1b34ae6640712c3891bc", - "reference": "10dcfce151b967d20fde1b34ae6640712c3891bc", + "url": "https://api.github.com/repos/doctrine/instantiator/zipball/0a0fa9780f5d4e507415a065172d26a98d02047b", + "reference": "0a0fa9780f5d4e507415a065172d26a98d02047b", "shasum": "" }, "require": { "php": "^7.1 || ^8.0" }, "require-dev": { - "doctrine/coding-standard": "^9", + "doctrine/coding-standard": "^9 || ^11", "ext-pdo": "*", "ext-phar": "*", "phpbench/phpbench": "^0.16 || ^1", "phpstan/phpstan": "^1.4", "phpstan/phpstan-phpunit": "^1", "phpunit/phpunit": "^7.5 || ^8.5 || ^9.5", - "vimeo/psalm": "^4.22" + "vimeo/psalm": "^4.30 || ^5.4" }, "type": "library", "autoload": { @@ -2955,7 +2956,7 @@ ], "support": { "issues": "https://github.com/doctrine/instantiator/issues", - "source": "https://github.com/doctrine/instantiator/tree/1.4.1" + "source": "https://github.com/doctrine/instantiator/tree/1.5.0" }, "funding": [ { @@ -2971,20 +2972,20 @@ "type": "tidelift" } ], - "time": "2022-03-03T08:28:38+00:00" + "time": "2022-12-30T00:15:36+00:00" }, { "name": "matthiasmullie/minify", - "version": "1.3.69", + "version": "1.3.70", "source": { "type": "git", "url": "https://github.com/matthiasmullie/minify.git", - "reference": "a61c949cccd086808063611ef9698eabe42ef22f" + "reference": "2807d9f9bece6877577ad44acb5c801bb3ae536b" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/matthiasmullie/minify/zipball/a61c949cccd086808063611ef9698eabe42ef22f", - "reference": "a61c949cccd086808063611ef9698eabe42ef22f", + "url": "https://api.github.com/repos/matthiasmullie/minify/zipball/2807d9f9bece6877577ad44acb5c801bb3ae536b", + "reference": "2807d9f9bece6877577ad44acb5c801bb3ae536b", "shasum": "" }, "require": { @@ -2993,9 +2994,10 @@ "php": ">=5.3.0" }, "require-dev": { - "friendsofphp/php-cs-fixer": "~2.0", - "matthiasmullie/scrapbook": "dev-master", - "phpunit/phpunit": ">=4.8" + "friendsofphp/php-cs-fixer": ">=2.0", + "matthiasmullie/scrapbook": ">=1.3", + "phpunit/phpunit": ">=4.8", + "squizlabs/php_codesniffer": ">=3.0" }, "suggest": { "psr/cache-implementation": "Cache implementation to use with Minify::cache" @@ -3018,12 +3020,12 @@ { "name": "Matthias Mullie", "email": "minify@mullie.eu", - "homepage": "http://www.mullie.eu", + "homepage": "https://www.mullie.eu", "role": "Developer" } ], "description": "CSS & JavaScript minifier, in PHP. Removes whitespace, strips comments, combines files (incl. @import statements and small assets in CSS files), and optimizes/shortens a few common programming patterns.", - "homepage": "http://www.minifier.org", + "homepage": "https://github.com/matthiasmullie/minify", "keywords": [ "JS", "css", @@ -3033,7 +3035,7 @@ ], "support": { "issues": "https://github.com/matthiasmullie/minify/issues", - "source": "https://github.com/matthiasmullie/minify/tree/1.3.69" + "source": "https://github.com/matthiasmullie/minify/tree/1.3.70" }, "funding": [ { @@ -3041,7 +3043,7 @@ "type": "github" } ], - "time": "2022-08-01T09:00:18+00:00" + "time": "2022-12-09T12:56:44+00:00" }, { "name": "matthiasmullie/path-converter", @@ -3157,16 +3159,16 @@ }, { "name": "nikic/php-parser", - "version": "v4.15.2", + "version": "v4.15.3", "source": { "type": "git", "url": "https://github.com/nikic/PHP-Parser.git", - "reference": "f59bbe44bf7d96f24f3e2b4ddc21cd52c1d2adbc" + "reference": "570e980a201d8ed0236b0a62ddf2c9cbb2034039" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/f59bbe44bf7d96f24f3e2b4ddc21cd52c1d2adbc", - "reference": "f59bbe44bf7d96f24f3e2b4ddc21cd52c1d2adbc", + "url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/570e980a201d8ed0236b0a62ddf2c9cbb2034039", + "reference": "570e980a201d8ed0236b0a62ddf2c9cbb2034039", "shasum": "" }, "require": { @@ -3207,9 +3209,9 @@ ], "support": { "issues": "https://github.com/nikic/PHP-Parser/issues", - "source": "https://github.com/nikic/PHP-Parser/tree/v4.15.2" + "source": "https://github.com/nikic/PHP-Parser/tree/v4.15.3" }, - "time": "2022-11-12T15:38:23+00:00" + "time": "2023-01-16T22:05:37+00:00" }, { "name": "phar-io/manifest", @@ -3489,21 +3491,21 @@ }, { "name": "phpspec/prophecy", - "version": "v1.15.0", + "version": "v1.16.0", "source": { "type": "git", "url": "https://github.com/phpspec/prophecy.git", - "reference": "bbcd7380b0ebf3961ee21409db7b38bc31d69a13" + "reference": "be8cac52a0827776ff9ccda8c381ac5b71aeb359" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpspec/prophecy/zipball/bbcd7380b0ebf3961ee21409db7b38bc31d69a13", - "reference": "bbcd7380b0ebf3961ee21409db7b38bc31d69a13", + "url": "https://api.github.com/repos/phpspec/prophecy/zipball/be8cac52a0827776ff9ccda8c381ac5b71aeb359", + "reference": "be8cac52a0827776ff9ccda8c381ac5b71aeb359", "shasum": "" }, "require": { "doctrine/instantiator": "^1.2", - "php": "^7.2 || ~8.0, <8.2", + "php": "^7.2 || 8.0.* || 8.1.* || 8.2.*", "phpdocumentor/reflection-docblock": "^5.2", "sebastian/comparator": "^3.0 || ^4.0", "sebastian/recursion-context": "^3.0 || ^4.0" @@ -3550,22 +3552,22 @@ ], "support": { "issues": "https://github.com/phpspec/prophecy/issues", - "source": "https://github.com/phpspec/prophecy/tree/v1.15.0" + "source": "https://github.com/phpspec/prophecy/tree/v1.16.0" }, - "time": "2021-12-08T12:19:24+00:00" + "time": "2022-11-29T15:06:56+00:00" }, { "name": "phpunit/php-code-coverage", - "version": "9.2.19", + "version": "9.2.23", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/php-code-coverage.git", - "reference": "c77b56b63e3d2031bd8997fcec43c1925ae46559" + "reference": "9f1f0f9a2fbb680b26d1cf9b61b6eac43a6e4e9c" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/c77b56b63e3d2031bd8997fcec43c1925ae46559", - "reference": "c77b56b63e3d2031bd8997fcec43c1925ae46559", + "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/9f1f0f9a2fbb680b26d1cf9b61b6eac43a6e4e9c", + "reference": "9f1f0f9a2fbb680b26d1cf9b61b6eac43a6e4e9c", "shasum": "" }, "require": { @@ -3621,7 +3623,7 @@ ], "support": { "issues": "https://github.com/sebastianbergmann/php-code-coverage/issues", - "source": "https://github.com/sebastianbergmann/php-code-coverage/tree/9.2.19" + "source": "https://github.com/sebastianbergmann/php-code-coverage/tree/9.2.23" }, "funding": [ { @@ -3629,7 +3631,7 @@ "type": "github" } ], - "time": "2022-11-18T07:47:47+00:00" + "time": "2022-12-28T12:41:10+00:00" }, { "name": "phpunit/php-file-iterator", @@ -5303,16 +5305,16 @@ }, { "name": "twig/twig", - "version": "v3.4.3", + "version": "v3.5.0", "source": { "type": "git", "url": "https://github.com/twigphp/Twig.git", - "reference": "c38fd6b0b7f370c198db91ffd02e23b517426b58" + "reference": "3ffcf4b7d890770466da3b2666f82ac054e7ec72" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/twigphp/Twig/zipball/c38fd6b0b7f370c198db91ffd02e23b517426b58", - "reference": "c38fd6b0b7f370c198db91ffd02e23b517426b58", + "url": "https://api.github.com/repos/twigphp/Twig/zipball/3ffcf4b7d890770466da3b2666f82ac054e7ec72", + "reference": "3ffcf4b7d890770466da3b2666f82ac054e7ec72", "shasum": "" }, "require": { @@ -5327,7 +5329,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "3.4-dev" + "dev-master": "3.5-dev" } }, "autoload": { @@ -5363,7 +5365,7 @@ ], "support": { "issues": "https://github.com/twigphp/Twig/issues", - "source": "https://github.com/twigphp/Twig/tree/v3.4.3" + "source": "https://github.com/twigphp/Twig/tree/v3.5.0" }, "funding": [ { @@ -5375,7 +5377,7 @@ "type": "tidelift" } ], - "time": "2022-09-28T08:42:51+00:00" + "time": "2022-12-27T12:28:18+00:00" } ], "aliases": [], @@ -5404,5 +5406,5 @@ "platform-overrides": { "php": "8.0" }, - "plugin-api-version": "2.3.0" + "plugin-api-version": "2.2.0" } diff --git a/docker-compose.yml b/docker-compose.yml index a7c1ddf97c..afaaef2f6b 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -37,6 +37,7 @@ services: - /var/run/docker.sock:/var/run/docker.sock - appwrite-config:/storage/config:ro - appwrite-certificates:/storage/certificates:ro + #- ./vendor/utopia-php/framework:/usr/src/code/vendor/utopia-php/framework depends_on: - appwrite networks: diff --git a/tests/e2e/General/UsageTest.php b/tests/e2e/General/UsageTest.php index 59e80fdb04..711c9bf017 100644 --- a/tests/e2e/General/UsageTest.php +++ b/tests/e2e/General/UsageTest.php @@ -362,11 +362,10 @@ class UsageTest extends Scope for ($i = 0; $i < 10; $i++) { $name = uniqid() . ' database'; - $res = $this->client->call(Client::METHOD_POST, '/databases', $headers, [ + $res = $this->client->call(Client::METHOD_POST, '/databases', array_merge($headers, ['content-type' => 'multipart/form-data']), [ 'databaseId' => 'unique()', 'name' => $name, ]); - $this->assertEquals($name, $res['body']['name']); $this->assertNotEmpty($res['body']['$id']); $databaseId = $res['body']['$id']; @@ -388,10 +387,10 @@ class UsageTest extends Scope $requestsCount += 2; } } - exit; + for ($i = 0; $i < 10; $i++) { $name = uniqid() . ' collection'; - $res = $this->client->call(Client::METHOD_POST, '/databases/' . $databaseId . '/collections', $headers, [ + $res = $this->client->call(Client::METHOD_POST, '/databases/' . $databaseId . '/collections', array_merge($headers, ['content-type' => 'multipart/form-data']), [ 'collectionId' => 'unique()', 'name' => $name, 'documentSecurity' => false, @@ -424,7 +423,7 @@ class UsageTest extends Scope } } - $res = $this->client->call(Client::METHOD_POST, '/databases/' . $databaseId . '/collections/' . $collectionId . '/attributes' . '/string', $headers, [ + $res = $this->client->call(Client::METHOD_POST, '/databases/' . $databaseId . '/collections/' . $collectionId . '/attributes' . '/string', array_merge($headers, ['content-type' => 'multipart/form-data']), [ 'key' => 'name', 'size' => 255, 'required' => true, @@ -437,7 +436,7 @@ class UsageTest extends Scope for ($i = 0; $i < 10; $i++) { $name = uniqid() . ' collection'; - $res = $this->client->call(Client::METHOD_POST, '/databases/' . $databaseId . '/collections/' . $collectionId . '/documents', $headers, [ + $res = $this->client->call(Client::METHOD_POST, '/databases/' . $databaseId . '/collections/' . $collectionId . '/documents', array_merge($headers, ['content-type' => 'multipart/form-data']), [ 'documentId' => 'unique()', 'data' => ['name' => $name] ]); @@ -629,7 +628,7 @@ class UsageTest extends Scope $executions = 0; $failures = 0; - $response1 = $this->client->call(Client::METHOD_POST, '/functions', $headers, [ + $response1 = $this->client->call(Client::METHOD_POST, '/functions', array_merge($headers, ['content-type' => 'multipart/form-data']), [ 'functionId' => 'unique()', 'name' => 'Test', 'runtime' => 'php-8.0', @@ -678,7 +677,7 @@ class UsageTest extends Scope $this->assertEquals(true, DateTime::isValid($response['body']['$updatedAt'])); $this->assertEquals($deploymentId, $response['body']['deployment']); - $execution = $this->client->call(Client::METHOD_POST, '/functions/' . $functionId . '/executions', $headers, [ + $execution = $this->client->call(Client::METHOD_POST, '/functions/' . $functionId . '/executions', array_merge($headers, ['content-type' => 'multipart/form-data']), [ 'async' => false, ]); @@ -692,7 +691,7 @@ class UsageTest extends Scope $executions++; } - $execution = $this->client->call(Client::METHOD_POST, '/functions/' . $functionId . '/executions', $headers, [ + $execution = $this->client->call(Client::METHOD_POST, '/functions/' . $functionId . '/executions', array_merge($headers, ['content-type' => 'multipart/form-data']), [ 'async' => false, ]); From d33f8cc910d97c0d425ff98188a1fce11c4e2aeb Mon Sep 17 00:00:00 2001 From: shimon Date: Tue, 31 Jan 2023 20:49:26 +0200 Subject: [PATCH 07/18] Migration v17 --- src/Appwrite/Migration/Version/V17.php | 84 +++++++++++++++++++++++++- 1 file changed, 81 insertions(+), 3 deletions(-) diff --git a/src/Appwrite/Migration/Version/V17.php b/src/Appwrite/Migration/Version/V17.php index e6877e7225..f841fcab52 100644 --- a/src/Appwrite/Migration/Version/V17.php +++ b/src/Appwrite/Migration/Version/V17.php @@ -90,12 +90,90 @@ class V17 extends Migration try { /** - * Create 'size' + * Create 'deploymentInternalId' attribute */ - $this->createAttributeFromCollection($this->projectDB, $id, 'size'); + $this->createAttributeFromCollection($this->projectDB, $id, 'deploymentInternalId'); $this->projectDB->deleteCachedCollection($id); } catch (\Throwable $th) { - Console::warning("'size' from {$id}: {$th->getMessage()}"); + Console::warning("'deploymentInternalId' from {$id}: {$th->getMessage()}"); + } + break; + + case 'schedules': + try { + /** + * Create 'resourceInternalId' attribute + */ + $this->createAttributeFromCollection($this->projectDB, $id, 'resourceInternalId'); + $this->projectDB->deleteCachedCollection($id); + } catch (\Throwable $th) { + Console::warning("'resourceInternalId' from {$id}: {$th->getMessage()}"); + } + break; + + case 'functions': + try { + /** + * Create 'deploymentInternalId' attribute + */ + $this->createAttributeFromCollection($this->projectDB, $id, 'deploymentInternalId'); + $this->projectDB->deleteCachedCollection($id); + } catch (\Throwable $th) { + Console::warning("'deploymentInternalId' from {$id}: {$th->getMessage()}"); + } + + try { + /** + * Create 'scheduleInternalId' attribute + */ + $this->createAttributeFromCollection($this->projectDB, $id, 'scheduleInternalId'); + $this->projectDB->deleteCachedCollection($id); + } catch (\Throwable $th) { + Console::warning("'scheduleInternalId' from {$id}: {$th->getMessage()}"); + } + break; + + case 'deployments': + try { + /** + * Create 'resourceInternalId' attribute + */ + $this->createAttributeFromCollection($this->projectDB, $id, 'resourceInternalId'); + $this->projectDB->deleteCachedCollection($id); + } catch (\Throwable $th) { + Console::warning("'resourceInternalId' from {$id}: {$th->getMessage()}"); + } + + try { + /** + * Create 'buildInternalId' attribute + */ + $this->createAttributeFromCollection($this->projectDB, $id, 'buildInternalId'); + $this->projectDB->deleteCachedCollection($id); + } catch (\Throwable $th) { + Console::warning("'buildInternalId' from {$id}: {$th->getMessage()}"); + } + break; + + case 'executions': + try { + /** + * Create 'functionInternalId' attribute + */ + $this->createAttributeFromCollection($this->projectDB, $id, 'functionInternalId'); + $this->projectDB->deleteCachedCollection($id); + } catch (\Throwable $th) { + Console::warning("'functionInternalId' from {$id}: {$th->getMessage()}"); + } + + try { + /** + * Create 'deploymentInternalId' attribute + */ + $this->createAttributeFromCollection($this->projectDB, $id, 'deploymentInternalId'); + $this->projectDB->deleteCachedCollection($id); + } catch (\Throwable $th) { + Console::warning("'deploymentInternalId' from {$id}: {$th->getMessage()}"); } break; default: From ff78bf86851b5b7090bc650f7057b7e6b9591ec8 Mon Sep 17 00:00:00 2001 From: shimon Date: Thu, 2 Feb 2023 15:43:19 +0200 Subject: [PATCH 08/18] addressing comments --- app/console | 2 +- tests/e2e/General/UsageTest.php | 21 +++++++-------- .../Functions/FunctionsCustomServerTest.php | 3 ++- .../Realtime/RealtimeCustomClientTest.php | 26 ++++++++++++++++--- 4 files changed, 36 insertions(+), 16 deletions(-) diff --git a/app/console b/app/console index b1a81a390a..fae048b917 160000 --- a/app/console +++ b/app/console @@ -1 +1 @@ -Subproject commit b1a81a390a05746701651fca49e0d853f430677c +Subproject commit fae048b91787d0b372c13caf27f14fc8b780ef60 diff --git a/tests/e2e/General/UsageTest.php b/tests/e2e/General/UsageTest.php index 711c9bf017..e21164804a 100644 --- a/tests/e2e/General/UsageTest.php +++ b/tests/e2e/General/UsageTest.php @@ -111,14 +111,12 @@ class UsageTest extends Scope $this->validateDates($res['users']); $this->assertEquals($requestsCount, $res['requests'][array_key_last($res['requests'])]['value']); $this->validateDates($res['requests']); - $requestsCount++; $res = $this->client->call(Client::METHOD_GET, '/users/usage?range=30d', array_merge($headers, [ 'x-appwrite-project' => $projectId, 'x-appwrite-mode' => 'admin' ])); - $requestsCount++; $res = $res['body']; @@ -270,7 +268,7 @@ class UsageTest extends Scope $filesCreate = $data['filesCreate']; $filesDelete = $data['filesDelete']; - sleep(30); + sleep(20); // console request $headers = [ @@ -390,7 +388,7 @@ class UsageTest extends Scope for ($i = 0; $i < 10; $i++) { $name = uniqid() . ' collection'; - $res = $this->client->call(Client::METHOD_POST, '/databases/' . $databaseId . '/collections', array_merge($headers, ['content-type' => 'multipart/form-data']), [ + $res = $this->client->call(Client::METHOD_POST, '/databases/' . $databaseId . '/collections', $headers, [ 'collectionId' => 'unique()', 'name' => $name, 'documentSecurity' => false, @@ -423,11 +421,12 @@ class UsageTest extends Scope } } - $res = $this->client->call(Client::METHOD_POST, '/databases/' . $databaseId . '/collections/' . $collectionId . '/attributes' . '/string', array_merge($headers, ['content-type' => 'multipart/form-data']), [ + $res = $this->client->call(Client::METHOD_POST, '/databases/' . $databaseId . '/collections/' . $collectionId . '/attributes' . '/string', $headers, [ 'key' => 'name', 'size' => 255, 'required' => true, ]); + $this->assertEquals('name', $res['body']['key']); $collectionsUpdate++; $requestsCount++; @@ -436,7 +435,7 @@ class UsageTest extends Scope for ($i = 0; $i < 10; $i++) { $name = uniqid() . ' collection'; - $res = $this->client->call(Client::METHOD_POST, '/databases/' . $databaseId . '/collections/' . $collectionId . '/documents', array_merge($headers, ['content-type' => 'multipart/form-data']), [ + $res = $this->client->call(Client::METHOD_POST, '/databases/' . $databaseId . '/collections/' . $collectionId . '/documents', $headers, [ 'documentId' => 'unique()', 'data' => ['name' => $name] ]); @@ -514,7 +513,7 @@ class UsageTest extends Scope $documentsRead = $data['documentsRead']; $documentsDelete = $data['documentsDelete']; - sleep(30); + sleep(20); // check datbase stats $headers = [ @@ -628,7 +627,7 @@ class UsageTest extends Scope $executions = 0; $failures = 0; - $response1 = $this->client->call(Client::METHOD_POST, '/functions', array_merge($headers, ['content-type' => 'multipart/form-data']), [ + $response1 = $this->client->call(Client::METHOD_POST, '/functions', $headers, [ 'functionId' => 'unique()', 'name' => 'Test', 'runtime' => 'php-8.0', @@ -653,7 +652,7 @@ class UsageTest extends Scope $code = realpath(__DIR__ . '/../../resources/functions') . "/php/code.tar.gz"; $this->packageCode('php'); - $deployment = $this->client->call(Client::METHOD_POST, '/functions/' . $functionId . '/deployments', array_merge($headers, ['content-type' => 'multipart/form-data',]), [ + $deployment = $this->client->call(Client::METHOD_POST, '/functions/' . $functionId . '/deployments', $headers, [ 'entrypoint' => 'index.php', 'code' => new CURLFile($code, 'application/x-gzip', \basename($code)), 'activate' => true @@ -677,7 +676,7 @@ class UsageTest extends Scope $this->assertEquals(true, DateTime::isValid($response['body']['$updatedAt'])); $this->assertEquals($deploymentId, $response['body']['deployment']); - $execution = $this->client->call(Client::METHOD_POST, '/functions/' . $functionId . '/executions', array_merge($headers, ['content-type' => 'multipart/form-data']), [ + $execution = $this->client->call(Client::METHOD_POST, '/functions/' . $functionId . '/executions', $headers, [ 'async' => false, ]); @@ -744,7 +743,7 @@ class UsageTest extends Scope $executions = $data['executions']; $failures = $data['failures']; - sleep(30); + sleep(20); $response = $this->client->call(Client::METHOD_GET, '/functions/' . $functionId . '/usage', $headers, [ 'range' => '30d' diff --git a/tests/e2e/Services/Functions/FunctionsCustomServerTest.php b/tests/e2e/Services/Functions/FunctionsCustomServerTest.php index e97c1412b6..03cf910dda 100644 --- a/tests/e2e/Services/Functions/FunctionsCustomServerTest.php +++ b/tests/e2e/Services/Functions/FunctionsCustomServerTest.php @@ -635,7 +635,7 @@ class FunctionsCustomServerTest extends Scope $this->assertStringContainsString('8.0', $execution['body']['response']); $this->assertStringContainsString('êä', $execution['body']['response']); // tests unknown utf-8 chars $this->assertEquals('', $execution['body']['stderr']); - $this->assertLessThan(3, $execution['body']['duration']); + $this->assertLessThan(1.500, $execution['body']['duration']); /** * Test for FAILURE @@ -915,6 +915,7 @@ class FunctionsCustomServerTest extends Scope $this->assertEquals($executions['body']['executions'][0]['statusCode'], 500); $this->assertGreaterThan(2, $executions['body']['executions'][0]['duration']); $this->assertLessThan(6, $executions['body']['executions'][0]['duration']); + $this->assertLessThan(4, $executions['body']['executions'][0]['duration']); $this->assertEquals($executions['body']['executions'][0]['response'], ''); $this->assertEquals($executions['body']['executions'][0]['stderr'], 'An internal curl error has occurred within the executor! Error Msg: Operation timed out'); diff --git a/tests/e2e/Services/Realtime/RealtimeCustomClientTest.php b/tests/e2e/Services/Realtime/RealtimeCustomClientTest.php index be8f81f445..86832f99e1 100644 --- a/tests/e2e/Services/Realtime/RealtimeCustomClientTest.php +++ b/tests/e2e/Services/Realtime/RealtimeCustomClientTest.php @@ -211,6 +211,26 @@ class RealtimeCustomClientTest extends Scope $this->assertEquals(1003, $response['data']['code']); $this->assertEquals('Message format is not valid.', $response['data']['message']); + + + $client->close(); + } + + public function testConnectionPlatform() + { + /** + * Test for FAILURE + */ + $client = $this->getWebsocket(['documents'], ['origin' => 'http://appwrite.unknown']); + $payload = json_decode($client->receive(), true); + + $this->assertArrayHasKey('type', $payload); + $this->assertArrayHasKey('data', $payload); + $this->assertEquals('error', $payload['type']); + $this->assertEquals(1008, $payload['data']['code']); + $this->assertEquals('Invalid Origin. Register your new client (appwrite.unknown) as a new Web platform on your project console dashboard', $payload['data']['message']); + \usleep(250000); // 250ms + $this->expectException(ConnectionException::class); // Check if server disconnnected client $client->close(); } @@ -440,8 +460,8 @@ class RealtimeCustomClientTest extends Scope $this->assertNotEmpty($response['data']['payload']); /** -// * Test Account Session Create -// */ + * Test Account Session Create + */ $response = $this->client->call(Client::METHOD_POST, '/account/sessions/email', array_merge([ 'origin' => 'http://localhost', 'content-type' => 'application/json', @@ -1229,7 +1249,7 @@ class RealtimeCustomClientTest extends Scope $this->assertNotEmpty($deployment['body']['$id']); // Wait for deployment to be built. - sleep(10); + sleep(5); $response = $this->client->call(Client::METHOD_PATCH, '/functions/' . $functionId . '/deployments/' . $deploymentId, array_merge([ 'content-type' => 'application/json', From aca960b7eb937de8f5afbaf045ee4be2d2c457e3 Mon Sep 17 00:00:00 2001 From: shimon Date: Thu, 2 Feb 2023 15:48:14 +0200 Subject: [PATCH 09/18] addressing comments --- tests/e2e/General/UsageTest.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tests/e2e/General/UsageTest.php b/tests/e2e/General/UsageTest.php index e21164804a..7ef80edb73 100644 --- a/tests/e2e/General/UsageTest.php +++ b/tests/e2e/General/UsageTest.php @@ -85,7 +85,7 @@ class UsageTest extends Scope #[Retry(count: 1)] public function testUsersStats(array $data): array { - sleep(30); + sleep(20); $projectId = $data['projectId']; $headers = $data['headers']; @@ -431,7 +431,7 @@ class UsageTest extends Scope $collectionsUpdate++; $requestsCount++; - sleep(30); + sleep(20); for ($i = 0; $i < 10; $i++) { $name = uniqid() . ' collection'; @@ -652,7 +652,7 @@ class UsageTest extends Scope $code = realpath(__DIR__ . '/../../resources/functions') . "/php/code.tar.gz"; $this->packageCode('php'); - $deployment = $this->client->call(Client::METHOD_POST, '/functions/' . $functionId . '/deployments', $headers, [ + $deployment = $this->client->call(Client::METHOD_POST, '/functions/' . $functionId . '/deployments', array_merge($headers, ['content-type' => 'multipart/form-data']), [ 'entrypoint' => 'index.php', 'code' => new CURLFile($code, 'application/x-gzip', \basename($code)), 'activate' => true From c91588307f269e610f44d893ca0f16f2933a6bcc Mon Sep 17 00:00:00 2001 From: shimon Date: Thu, 2 Feb 2023 15:52:06 +0200 Subject: [PATCH 10/18] addressing comments --- tests/e2e/General/UsageTest.php | 4 ++-- tests/e2e/Services/Functions/FunctionsCustomServerTest.php | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/tests/e2e/General/UsageTest.php b/tests/e2e/General/UsageTest.php index 7ef80edb73..8c1da12ae6 100644 --- a/tests/e2e/General/UsageTest.php +++ b/tests/e2e/General/UsageTest.php @@ -652,7 +652,7 @@ class UsageTest extends Scope $code = realpath(__DIR__ . '/../../resources/functions') . "/php/code.tar.gz"; $this->packageCode('php'); - $deployment = $this->client->call(Client::METHOD_POST, '/functions/' . $functionId . '/deployments', array_merge($headers, ['content-type' => 'multipart/form-data']), [ + $deployment = $this->client->call(Client::METHOD_POST, '/functions/' . $functionId . '/deployments', array_merge($headers, ['content-type' => 'multipart/form-data',]), [ 'entrypoint' => 'index.php', 'code' => new CURLFile($code, 'application/x-gzip', \basename($code)), 'activate' => true @@ -690,7 +690,7 @@ class UsageTest extends Scope $executions++; } - $execution = $this->client->call(Client::METHOD_POST, '/functions/' . $functionId . '/executions', array_merge($headers, ['content-type' => 'multipart/form-data']), [ + $execution = $this->client->call(Client::METHOD_POST, '/functions/' . $functionId . '/executions', $headers, [ 'async' => false, ]); diff --git a/tests/e2e/Services/Functions/FunctionsCustomServerTest.php b/tests/e2e/Services/Functions/FunctionsCustomServerTest.php index 03cf910dda..e2d7b8482b 100644 --- a/tests/e2e/Services/Functions/FunctionsCustomServerTest.php +++ b/tests/e2e/Services/Functions/FunctionsCustomServerTest.php @@ -915,7 +915,7 @@ class FunctionsCustomServerTest extends Scope $this->assertEquals($executions['body']['executions'][0]['statusCode'], 500); $this->assertGreaterThan(2, $executions['body']['executions'][0]['duration']); $this->assertLessThan(6, $executions['body']['executions'][0]['duration']); - $this->assertLessThan(4, $executions['body']['executions'][0]['duration']); + $this->assertGreaterThan(4, $executions['body']['executions'][0]['duration']); $this->assertEquals($executions['body']['executions'][0]['response'], ''); $this->assertEquals($executions['body']['executions'][0]['stderr'], 'An internal curl error has occurred within the executor! Error Msg: Operation timed out'); From dbc5266d7d6b49af01098a06c3f9a6c7970e429d Mon Sep 17 00:00:00 2001 From: shimon Date: Thu, 2 Feb 2023 15:55:50 +0200 Subject: [PATCH 11/18] addressing comments --- tests/e2e/General/UsageTest.php | 6 ++---- tests/e2e/Services/Realtime/RealtimeCustomClientTest.php | 3 +-- 2 files changed, 3 insertions(+), 6 deletions(-) diff --git a/tests/e2e/General/UsageTest.php b/tests/e2e/General/UsageTest.php index 8c1da12ae6..5a4e512a54 100644 --- a/tests/e2e/General/UsageTest.php +++ b/tests/e2e/General/UsageTest.php @@ -118,7 +118,6 @@ class UsageTest extends Scope 'x-appwrite-mode' => 'admin' ])); $requestsCount++; - $res = $res['body']; $this->assertEquals(10, $res['usersCreate'][array_key_last($res['usersCreate'])]['value']); $this->validateDates($res['usersCreate']); @@ -289,7 +288,6 @@ class UsageTest extends Scope $this->assertEquals($storageTotal, $res['storage'][array_key_last($res['storage'])]['value']); $this->validateDates($res['storage']); $requestsCount++; - $res = $this->client->call(Client::METHOD_GET, '/storage/usage?range=30d', array_merge($headers, [ 'x-appwrite-project' => $projectId, 'x-appwrite-mode' => 'admin' @@ -315,7 +313,6 @@ class UsageTest extends Scope $this->assertEquals($filesDelete, $res['filesDelete'][array_key_last($res['filesDelete'])]['value']); $this->validateDates($res['filesDelete']); $requestsCount++; - $res = $this->client->call(Client::METHOD_GET, '/storage/' . $bucketId . '/usage?range=30d', array_merge($headers, [ 'x-appwrite-project' => $projectId, 'x-appwrite-mode' => 'admin' @@ -327,6 +324,7 @@ class UsageTest extends Scope $this->assertEquals($filesRead, $res['filesRead'][array_key_last($res['filesRead'])]['value']); $this->assertEquals($filesCreate, $res['filesCreate'][array_key_last($res['filesCreate'])]['value']); $this->assertEquals($filesDelete, $res['filesDelete'][array_key_last($res['filesDelete'])]['value']); + $requestsCount++; $data['requestsCount'] = $requestsCount; return $data; @@ -360,7 +358,7 @@ class UsageTest extends Scope for ($i = 0; $i < 10; $i++) { $name = uniqid() . ' database'; - $res = $this->client->call(Client::METHOD_POST, '/databases', array_merge($headers, ['content-type' => 'multipart/form-data']), [ + $res = $this->client->call(Client::METHOD_POST, '/databases', $headers, [ 'databaseId' => 'unique()', 'name' => $name, ]); diff --git a/tests/e2e/Services/Realtime/RealtimeCustomClientTest.php b/tests/e2e/Services/Realtime/RealtimeCustomClientTest.php index 86832f99e1..db4c1b9517 100644 --- a/tests/e2e/Services/Realtime/RealtimeCustomClientTest.php +++ b/tests/e2e/Services/Realtime/RealtimeCustomClientTest.php @@ -106,7 +106,6 @@ class RealtimeCustomClientTest extends Scope $this->assertContains('collections.1.documents.1', $response['data']['channels']); $this->assertContains('collections.2.documents.2', $response['data']['channels']); $this->assertEquals($userId, $response['data']['user']['$id']); - $client->close(); } @@ -461,7 +460,7 @@ class RealtimeCustomClientTest extends Scope /** * Test Account Session Create - */ + */ $response = $this->client->call(Client::METHOD_POST, '/account/sessions/email', array_merge([ 'origin' => 'http://localhost', 'content-type' => 'application/json', From 19e37ba3fd8ac668ef64327b46c6bd8d8bffe22a Mon Sep 17 00:00:00 2001 From: shimon Date: Thu, 2 Feb 2023 16:01:33 +0200 Subject: [PATCH 12/18] addressing comments --- tests/e2e/General/UsageTest.php | 10 +++++----- .../e2e/Services/Realtime/RealtimeCustomClientTest.php | 2 +- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/tests/e2e/General/UsageTest.php b/tests/e2e/General/UsageTest.php index 5a4e512a54..0718aad2e2 100644 --- a/tests/e2e/General/UsageTest.php +++ b/tests/e2e/General/UsageTest.php @@ -280,6 +280,7 @@ class UsageTest extends Scope $res = $this->client->call(Client::METHOD_GET, '/project/usage?range=30d', $headers); $res = $res['body']; + $this->assertEquals(9, count($res)); $this->assertEquals(30, count($res['requests'])); $this->assertEquals(30, count($res['storage'])); @@ -287,12 +288,13 @@ class UsageTest extends Scope $this->validateDates($res['requests']); $this->assertEquals($storageTotal, $res['storage'][array_key_last($res['storage'])]['value']); $this->validateDates($res['storage']); + $requestsCount++; $res = $this->client->call(Client::METHOD_GET, '/storage/usage?range=30d', array_merge($headers, [ 'x-appwrite-project' => $projectId, 'x-appwrite-mode' => 'admin' ])); - + $requestsCount++; $res = $res['body']; $this->assertEquals($storageTotal, $res['storage'][array_key_last($res['storage'])]['value']); $this->validateDates($res['storage']); @@ -312,12 +314,13 @@ class UsageTest extends Scope $this->validateDates($res['filesCreate']); $this->assertEquals($filesDelete, $res['filesDelete'][array_key_last($res['filesDelete'])]['value']); $this->validateDates($res['filesDelete']); + $requestsCount++; $res = $this->client->call(Client::METHOD_GET, '/storage/' . $bucketId . '/usage?range=30d', array_merge($headers, [ 'x-appwrite-project' => $projectId, 'x-appwrite-mode' => 'admin' ])); - + $requestsCount++; $res = $res['body']; $this->assertEquals($storageTotal, $res['filesStorage'][array_key_last($res['filesStorage'])]['value']); $this->assertEquals($filesCount, $res['filesCount'][array_key_last($res['filesCount'])]['value']); @@ -325,7 +328,6 @@ class UsageTest extends Scope $this->assertEquals($filesCreate, $res['filesCreate'][array_key_last($res['filesCreate'])]['value']); $this->assertEquals($filesDelete, $res['filesDelete'][array_key_last($res['filesDelete'])]['value']); - $requestsCount++; $data['requestsCount'] = $requestsCount; return $data; } @@ -424,11 +426,9 @@ class UsageTest extends Scope 'size' => 255, 'required' => true, ]); - $this->assertEquals('name', $res['body']['key']); $collectionsUpdate++; $requestsCount++; - sleep(20); for ($i = 0; $i < 10; $i++) { diff --git a/tests/e2e/Services/Realtime/RealtimeCustomClientTest.php b/tests/e2e/Services/Realtime/RealtimeCustomClientTest.php index db4c1b9517..7f09cb5703 100644 --- a/tests/e2e/Services/Realtime/RealtimeCustomClientTest.php +++ b/tests/e2e/Services/Realtime/RealtimeCustomClientTest.php @@ -106,6 +106,7 @@ class RealtimeCustomClientTest extends Scope $this->assertContains('collections.1.documents.1', $response['data']['channels']); $this->assertContains('collections.2.documents.2', $response['data']['channels']); $this->assertEquals($userId, $response['data']['user']['$id']); + $client->close(); } @@ -211,7 +212,6 @@ class RealtimeCustomClientTest extends Scope $this->assertEquals('Message format is not valid.', $response['data']['message']); - $client->close(); } From cdbc6a1d2278b08a0314c242b90f7a73a128105f Mon Sep 17 00:00:00 2001 From: shimon Date: Thu, 2 Feb 2023 16:03:11 +0200 Subject: [PATCH 13/18] addressing comments --- tests/e2e/General/UsageTest.php | 3 --- 1 file changed, 3 deletions(-) diff --git a/tests/e2e/General/UsageTest.php b/tests/e2e/General/UsageTest.php index 0718aad2e2..4dddaf1535 100644 --- a/tests/e2e/General/UsageTest.php +++ b/tests/e2e/General/UsageTest.php @@ -111,7 +111,6 @@ class UsageTest extends Scope $this->validateDates($res['users']); $this->assertEquals($requestsCount, $res['requests'][array_key_last($res['requests'])]['value']); $this->validateDates($res['requests']); - $requestsCount++; $res = $this->client->call(Client::METHOD_GET, '/users/usage?range=30d', array_merge($headers, [ 'x-appwrite-project' => $projectId, @@ -289,7 +288,6 @@ class UsageTest extends Scope $this->assertEquals($storageTotal, $res['storage'][array_key_last($res['storage'])]['value']); $this->validateDates($res['storage']); - $requestsCount++; $res = $this->client->call(Client::METHOD_GET, '/storage/usage?range=30d', array_merge($headers, [ 'x-appwrite-project' => $projectId, 'x-appwrite-mode' => 'admin' @@ -315,7 +313,6 @@ class UsageTest extends Scope $this->assertEquals($filesDelete, $res['filesDelete'][array_key_last($res['filesDelete'])]['value']); $this->validateDates($res['filesDelete']); - $requestsCount++; $res = $this->client->call(Client::METHOD_GET, '/storage/' . $bucketId . '/usage?range=30d', array_merge($headers, [ 'x-appwrite-project' => $projectId, 'x-appwrite-mode' => 'admin' From 75c7d946335a8be2d21048795151b7d2a36d44c7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matej=20Ba=C4=8Do?= Date: Thu, 2 Feb 2023 19:21:00 +0000 Subject: [PATCH 14/18] Implement Open Runtimes v3 support --- app/config/collections.php | 11 +++ app/config/runtimes.php | 4 +- app/controllers/api/functions.php | 14 +-- app/workers/builds.php | 3 +- app/workers/functions.php | 11 ++- composer.lock | 139 +++++++++++++++--------------- docker-compose.yml | 2 +- src/Executor/Executor.php | 4 + 8 files changed, 108 insertions(+), 80 deletions(-) diff --git a/app/config/collections.php b/app/config/collections.php index a8c7a46b18..7b8c35e104 100644 --- a/app/config/collections.php +++ b/app/config/collections.php @@ -2311,6 +2311,17 @@ $collections = [ 'array' => false, 'filters' => [], ], + [ + '$id' => ID::custom('version'), + 'type' => Database::VAR_STRING, + 'format' => '', + 'size' => 8, + 'signed' => true, + 'required' => false, + 'default' => 'v3', + 'array' => false, + 'filters' => [], + ], ], 'indexes' => [ [ diff --git a/app/config/runtimes.php b/app/config/runtimes.php index c24aaa109e..b226e295b2 100644 --- a/app/config/runtimes.php +++ b/app/config/runtimes.php @@ -7,10 +7,12 @@ use Utopia\App; use Appwrite\Runtimes\Runtimes; -$runtimes = new Runtimes('v2'); +$runtimes = new Runtimes('v3'); $allowList = empty(App::getEnv('_APP_FUNCTIONS_RUNTIMES')) ? [] : \explode(',', App::getEnv('_APP_FUNCTIONS_RUNTIMES')); $runtimes = $runtimes->getAll(true, $allowList); +$runtimes['php-8.1']['image'] = 'meldiron/php:v3-8.1'; + return $runtimes; diff --git a/app/controllers/api/functions.php b/app/controllers/api/functions.php index 4c84795712..b237888a9a 100644 --- a/app/controllers/api/functions.php +++ b/app/controllers/api/functions.php @@ -86,7 +86,8 @@ App::post('/v1/functions') 'schedule' => $schedule, 'scheduleUpdatedAt' => DateTime::now(), 'timeout' => $timeout, - 'search' => implode(' ', [$functionId, $name, $runtime]) + 'search' => implode(' ', [$functionId, $name, $runtime]), + 'version' => 'v3' ])); $schedule = Authorization::skip( @@ -1193,6 +1194,7 @@ App::post('/v1/functions/:functionId/executions') $executionResponse = $executor->createExecution( projectId: $project->getId(), deploymentId: $deployment->getId(), + version: $function->getAttribute('version'), payload: $data, variables: $vars, timeout: $function->getAttribute('timeout', 0), @@ -1201,12 +1203,14 @@ App::post('/v1/functions/:functionId/executions') entrypoint: $deployment->getAttribute('entrypoint', ''), ); + /** Update execution status */ - $execution->setAttribute('status', $executionResponse['status']); + $status = $executionResponse['statusCode'] >= 500 ? 'failed' : 'completed'; + $execution->setAttribute('status', $status); $execution->setAttribute('statusCode', $executionResponse['statusCode']); - $execution->setAttribute('response', $executionResponse['response']); - $execution->setAttribute('stdout', $executionResponse['stdout']); - $execution->setAttribute('stderr', $executionResponse['stderr']); + $execution->setAttribute('response', $executionResponse['body']); + $execution->setAttribute('stdout', $executionResponse['logs']); + $execution->setAttribute('stderr', $executionResponse['errors']); $execution->setAttribute('duration', $executionResponse['duration']); } catch (\Throwable $th) { $interval = (new \DateTime())->diff(new \DateTime($execution->getCreatedAt())); diff --git a/app/workers/builds.php b/app/workers/builds.php index 081537fdfb..e188e33e2c 100644 --- a/app/workers/builds.php +++ b/app/workers/builds.php @@ -173,6 +173,7 @@ class BuildsV1 extends Worker projectId: $project->getId(), deploymentId: $deployment->getId(), source: $source, + version: $function->getAttribute('version'), image: $runtime['image'], remove: true, entrypoint: $deployment->getAttribute('entrypoint'), @@ -189,7 +190,7 @@ class BuildsV1 extends Worker /** Update the build document */ $build->setAttribute('startTime', DateTime::format((new \DateTime())->setTimestamp($response['startTime']))); $build->setAttribute('duration', \intval($response['duration'])); - $build->setAttribute('status', $response['status']); + $build->setAttribute('status', 'ready'); $build->setAttribute('path', $response['path']); $build->setAttribute('size', $response['size']); $build->setAttribute('stderr', $response['stderr']); diff --git a/app/workers/functions.php b/app/workers/functions.php index 2e8dccc7aa..51659a4c70 100644 --- a/app/workers/functions.php +++ b/app/workers/functions.php @@ -129,6 +129,7 @@ Server::setResource('execute', function () { $executionResponse = $client->createExecution( projectId: $project->getId(), deploymentId: $deploymentId, + version: $function->getAttribute('version'), payload: $vars['APPWRITE_FUNCTION_DATA'] ?? '', variables: $vars, timeout: $function->getAttribute('timeout', 0), @@ -137,13 +138,15 @@ Server::setResource('execute', function () { entrypoint: $deployment->getAttribute('entrypoint', ''), ); + $status = $executionResponse['statusCode'] >= 500 ? 'failed' : 'completed'; + /** Update execution status */ $execution - ->setAttribute('status', $executionResponse['status']) + ->setAttribute('status', $status) ->setAttribute('statusCode', $executionResponse['statusCode']) - ->setAttribute('response', $executionResponse['response']) - ->setAttribute('stdout', $executionResponse['stdout']) - ->setAttribute('stderr', $executionResponse['stderr']) + ->setAttribute('response', $executionResponse['body']) + ->setAttribute('stdout', $executionResponse['logs']) + ->setAttribute('stderr', $executionResponse['errors']) ->setAttribute('duration', $executionResponse['duration']); } catch (\Throwable $th) { $interval = (new \DateTime())->diff(new \DateTime($execution->getCreatedAt())); diff --git a/composer.lock b/composer.lock index c8b627849e..4ee60140ac 100644 --- a/composer.lock +++ b/composer.lock @@ -801,20 +801,21 @@ "issues": "https://github.com/influxdata/influxdb-php/issues", "source": "https://github.com/influxdata/influxdb-php/tree/1.15.2" }, + "abandoned": true, "time": "2020-12-26T17:45:17+00:00" }, { "name": "laravel/pint", - "version": "v1.2.0", + "version": "v1.2.1", "source": { "type": "git", "url": "https://github.com/laravel/pint.git", - "reference": "1d276e4c803397a26cc337df908f55c2a4e90d86" + "reference": "e60e2112ee779ce60f253695b273d1646a17d6f1" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/laravel/pint/zipball/1d276e4c803397a26cc337df908f55c2a4e90d86", - "reference": "1d276e4c803397a26cc337df908f55c2a4e90d86", + "url": "https://api.github.com/repos/laravel/pint/zipball/e60e2112ee779ce60f253695b273d1646a17d6f1", + "reference": "e60e2112ee779ce60f253695b273d1646a17d6f1", "shasum": "" }, "require": { @@ -826,10 +827,10 @@ }, "require-dev": { "friendsofphp/php-cs-fixer": "^3.11.0", - "illuminate/view": "^9.27", - "laravel-zero/framework": "^9.1.3", - "mockery/mockery": "^1.5.0", - "nunomaduro/larastan": "^2.2", + "illuminate/view": "^9.32.0", + "laravel-zero/framework": "^9.2.0", + "mockery/mockery": "^1.5.1", + "nunomaduro/larastan": "^2.2.0", "nunomaduro/termwind": "^1.14.0", "pestphp/pest": "^1.22.1" }, @@ -867,7 +868,7 @@ "issues": "https://github.com/laravel/pint/issues", "source": "https://github.com/laravel/pint" }, - "time": "2022-09-13T15:07:15+00:00" + "time": "2022-11-29T16:25:20+00:00" }, { "name": "matomo/device-detector", @@ -1461,16 +1462,16 @@ }, { "name": "symfony/deprecation-contracts", - "version": "v3.1.1", + "version": "v3.2.0", "source": { "type": "git", "url": "https://github.com/symfony/deprecation-contracts.git", - "reference": "07f1b9cc2ffee6aaafcf4b710fbc38ff736bd918" + "reference": "1ee04c65529dea5d8744774d474e7cbd2f1206d3" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/deprecation-contracts/zipball/07f1b9cc2ffee6aaafcf4b710fbc38ff736bd918", - "reference": "07f1b9cc2ffee6aaafcf4b710fbc38ff736bd918", + "url": "https://api.github.com/repos/symfony/deprecation-contracts/zipball/1ee04c65529dea5d8744774d474e7cbd2f1206d3", + "reference": "1ee04c65529dea5d8744774d474e7cbd2f1206d3", "shasum": "" }, "require": { @@ -1479,7 +1480,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-main": "3.1-dev" + "dev-main": "3.3-dev" }, "thanks": { "name": "symfony/contracts", @@ -1508,7 +1509,7 @@ "description": "A generic function and convention to trigger deprecation notices", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/deprecation-contracts/tree/v3.1.1" + "source": "https://github.com/symfony/deprecation-contracts/tree/v3.2.0" }, "funding": [ { @@ -1524,7 +1525,7 @@ "type": "tidelift" } ], - "time": "2022-02-25T11:15:52+00:00" + "time": "2022-11-25T10:21:52+00:00" }, { "name": "utopia-php/abuse", @@ -2574,16 +2575,16 @@ }, { "name": "utopia-php/storage", - "version": "0.13.0", + "version": "0.13.2", "source": { "type": "git", "url": "https://github.com/utopia-php/storage.git", - "reference": "f34c010e4f8394a6b4aff70b6de55041d9a145d3" + "reference": "ad1c00f24ca56e73888acc2af3deee4919b1194b" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/utopia-php/storage/zipball/f34c010e4f8394a6b4aff70b6de55041d9a145d3", - "reference": "f34c010e4f8394a6b4aff70b6de55041d9a145d3", + "url": "https://api.github.com/repos/utopia-php/storage/zipball/ad1c00f24ca56e73888acc2af3deee4919b1194b", + "reference": "ad1c00f24ca56e73888acc2af3deee4919b1194b", "shasum": "" }, "require": { @@ -2623,9 +2624,9 @@ ], "support": { "issues": "https://github.com/utopia-php/storage/issues", - "source": "https://github.com/utopia-php/storage/tree/0.13.0" + "source": "https://github.com/utopia-php/storage/tree/0.13.2" }, - "time": "2022-11-17T15:10:18+00:00" + "time": "2022-12-20T11:11:35+00:00" }, { "name": "utopia-php/swoole", @@ -2905,30 +2906,30 @@ }, { "name": "doctrine/instantiator", - "version": "1.4.1", + "version": "1.5.0", "source": { "type": "git", "url": "https://github.com/doctrine/instantiator.git", - "reference": "10dcfce151b967d20fde1b34ae6640712c3891bc" + "reference": "0a0fa9780f5d4e507415a065172d26a98d02047b" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/doctrine/instantiator/zipball/10dcfce151b967d20fde1b34ae6640712c3891bc", - "reference": "10dcfce151b967d20fde1b34ae6640712c3891bc", + "url": "https://api.github.com/repos/doctrine/instantiator/zipball/0a0fa9780f5d4e507415a065172d26a98d02047b", + "reference": "0a0fa9780f5d4e507415a065172d26a98d02047b", "shasum": "" }, "require": { "php": "^7.1 || ^8.0" }, "require-dev": { - "doctrine/coding-standard": "^9", + "doctrine/coding-standard": "^9 || ^11", "ext-pdo": "*", "ext-phar": "*", "phpbench/phpbench": "^0.16 || ^1", "phpstan/phpstan": "^1.4", "phpstan/phpstan-phpunit": "^1", "phpunit/phpunit": "^7.5 || ^8.5 || ^9.5", - "vimeo/psalm": "^4.22" + "vimeo/psalm": "^4.30 || ^5.4" }, "type": "library", "autoload": { @@ -2955,7 +2956,7 @@ ], "support": { "issues": "https://github.com/doctrine/instantiator/issues", - "source": "https://github.com/doctrine/instantiator/tree/1.4.1" + "source": "https://github.com/doctrine/instantiator/tree/1.5.0" }, "funding": [ { @@ -2971,20 +2972,20 @@ "type": "tidelift" } ], - "time": "2022-03-03T08:28:38+00:00" + "time": "2022-12-30T00:15:36+00:00" }, { "name": "matthiasmullie/minify", - "version": "1.3.69", + "version": "1.3.70", "source": { "type": "git", "url": "https://github.com/matthiasmullie/minify.git", - "reference": "a61c949cccd086808063611ef9698eabe42ef22f" + "reference": "2807d9f9bece6877577ad44acb5c801bb3ae536b" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/matthiasmullie/minify/zipball/a61c949cccd086808063611ef9698eabe42ef22f", - "reference": "a61c949cccd086808063611ef9698eabe42ef22f", + "url": "https://api.github.com/repos/matthiasmullie/minify/zipball/2807d9f9bece6877577ad44acb5c801bb3ae536b", + "reference": "2807d9f9bece6877577ad44acb5c801bb3ae536b", "shasum": "" }, "require": { @@ -2993,9 +2994,10 @@ "php": ">=5.3.0" }, "require-dev": { - "friendsofphp/php-cs-fixer": "~2.0", - "matthiasmullie/scrapbook": "dev-master", - "phpunit/phpunit": ">=4.8" + "friendsofphp/php-cs-fixer": ">=2.0", + "matthiasmullie/scrapbook": ">=1.3", + "phpunit/phpunit": ">=4.8", + "squizlabs/php_codesniffer": ">=3.0" }, "suggest": { "psr/cache-implementation": "Cache implementation to use with Minify::cache" @@ -3018,12 +3020,12 @@ { "name": "Matthias Mullie", "email": "minify@mullie.eu", - "homepage": "http://www.mullie.eu", + "homepage": "https://www.mullie.eu", "role": "Developer" } ], "description": "CSS & JavaScript minifier, in PHP. Removes whitespace, strips comments, combines files (incl. @import statements and small assets in CSS files), and optimizes/shortens a few common programming patterns.", - "homepage": "http://www.minifier.org", + "homepage": "https://github.com/matthiasmullie/minify", "keywords": [ "JS", "css", @@ -3033,7 +3035,7 @@ ], "support": { "issues": "https://github.com/matthiasmullie/minify/issues", - "source": "https://github.com/matthiasmullie/minify/tree/1.3.69" + "source": "https://github.com/matthiasmullie/minify/tree/1.3.70" }, "funding": [ { @@ -3041,7 +3043,7 @@ "type": "github" } ], - "time": "2022-08-01T09:00:18+00:00" + "time": "2022-12-09T12:56:44+00:00" }, { "name": "matthiasmullie/path-converter", @@ -3157,16 +3159,16 @@ }, { "name": "nikic/php-parser", - "version": "v4.15.2", + "version": "v4.15.3", "source": { "type": "git", "url": "https://github.com/nikic/PHP-Parser.git", - "reference": "f59bbe44bf7d96f24f3e2b4ddc21cd52c1d2adbc" + "reference": "570e980a201d8ed0236b0a62ddf2c9cbb2034039" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/f59bbe44bf7d96f24f3e2b4ddc21cd52c1d2adbc", - "reference": "f59bbe44bf7d96f24f3e2b4ddc21cd52c1d2adbc", + "url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/570e980a201d8ed0236b0a62ddf2c9cbb2034039", + "reference": "570e980a201d8ed0236b0a62ddf2c9cbb2034039", "shasum": "" }, "require": { @@ -3207,9 +3209,9 @@ ], "support": { "issues": "https://github.com/nikic/PHP-Parser/issues", - "source": "https://github.com/nikic/PHP-Parser/tree/v4.15.2" + "source": "https://github.com/nikic/PHP-Parser/tree/v4.15.3" }, - "time": "2022-11-12T15:38:23+00:00" + "time": "2023-01-16T22:05:37+00:00" }, { "name": "phar-io/manifest", @@ -3489,27 +3491,28 @@ }, { "name": "phpspec/prophecy", - "version": "v1.15.0", + "version": "v1.17.0", "source": { "type": "git", "url": "https://github.com/phpspec/prophecy.git", - "reference": "bbcd7380b0ebf3961ee21409db7b38bc31d69a13" + "reference": "15873c65b207b07765dbc3c95d20fdf4a320cbe2" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpspec/prophecy/zipball/bbcd7380b0ebf3961ee21409db7b38bc31d69a13", - "reference": "bbcd7380b0ebf3961ee21409db7b38bc31d69a13", + "url": "https://api.github.com/repos/phpspec/prophecy/zipball/15873c65b207b07765dbc3c95d20fdf4a320cbe2", + "reference": "15873c65b207b07765dbc3c95d20fdf4a320cbe2", "shasum": "" }, "require": { - "doctrine/instantiator": "^1.2", - "php": "^7.2 || ~8.0, <8.2", + "doctrine/instantiator": "^1.2 || ^2.0", + "php": "^7.2 || 8.0.* || 8.1.* || 8.2.*", "phpdocumentor/reflection-docblock": "^5.2", "sebastian/comparator": "^3.0 || ^4.0", "sebastian/recursion-context": "^3.0 || ^4.0" }, "require-dev": { "phpspec/phpspec": "^6.0 || ^7.0", + "phpstan/phpstan": "^1.9", "phpunit/phpunit": "^8.0 || ^9.0" }, "type": "library", @@ -3550,22 +3553,22 @@ ], "support": { "issues": "https://github.com/phpspec/prophecy/issues", - "source": "https://github.com/phpspec/prophecy/tree/v1.15.0" + "source": "https://github.com/phpspec/prophecy/tree/v1.17.0" }, - "time": "2021-12-08T12:19:24+00:00" + "time": "2023-02-02T15:41:36+00:00" }, { "name": "phpunit/php-code-coverage", - "version": "9.2.19", + "version": "9.2.24", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/php-code-coverage.git", - "reference": "c77b56b63e3d2031bd8997fcec43c1925ae46559" + "reference": "2cf940ebc6355a9d430462811b5aaa308b174bed" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/c77b56b63e3d2031bd8997fcec43c1925ae46559", - "reference": "c77b56b63e3d2031bd8997fcec43c1925ae46559", + "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/2cf940ebc6355a9d430462811b5aaa308b174bed", + "reference": "2cf940ebc6355a9d430462811b5aaa308b174bed", "shasum": "" }, "require": { @@ -3621,7 +3624,7 @@ ], "support": { "issues": "https://github.com/sebastianbergmann/php-code-coverage/issues", - "source": "https://github.com/sebastianbergmann/php-code-coverage/tree/9.2.19" + "source": "https://github.com/sebastianbergmann/php-code-coverage/tree/9.2.24" }, "funding": [ { @@ -3629,7 +3632,7 @@ "type": "github" } ], - "time": "2022-11-18T07:47:47+00:00" + "time": "2023-01-26T08:26:55+00:00" }, { "name": "phpunit/php-file-iterator", @@ -5303,16 +5306,16 @@ }, { "name": "twig/twig", - "version": "v3.4.3", + "version": "v3.5.0", "source": { "type": "git", "url": "https://github.com/twigphp/Twig.git", - "reference": "c38fd6b0b7f370c198db91ffd02e23b517426b58" + "reference": "3ffcf4b7d890770466da3b2666f82ac054e7ec72" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/twigphp/Twig/zipball/c38fd6b0b7f370c198db91ffd02e23b517426b58", - "reference": "c38fd6b0b7f370c198db91ffd02e23b517426b58", + "url": "https://api.github.com/repos/twigphp/Twig/zipball/3ffcf4b7d890770466da3b2666f82ac054e7ec72", + "reference": "3ffcf4b7d890770466da3b2666f82ac054e7ec72", "shasum": "" }, "require": { @@ -5327,7 +5330,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "3.4-dev" + "dev-master": "3.5-dev" } }, "autoload": { @@ -5363,7 +5366,7 @@ ], "support": { "issues": "https://github.com/twigphp/Twig/issues", - "source": "https://github.com/twigphp/Twig/tree/v3.4.3" + "source": "https://github.com/twigphp/Twig/tree/v3.5.0" }, "funding": [ { @@ -5375,7 +5378,7 @@ "type": "tidelift" } ], - "time": "2022-09-28T08:42:51+00:00" + "time": "2022-12-27T12:28:18+00:00" } ], "aliases": [], diff --git a/docker-compose.yml b/docker-compose.yml index d09e5649af..780d79c475 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -659,7 +659,7 @@ services: hostname: exc1 <<: *x-logging stop_signal: SIGINT - image: openruntimes/executor:0.2.0 + image: meldiron/executor:v3 networks: - appwrite - runtimes diff --git a/src/Executor/Executor.php b/src/Executor/Executor.php index 43b2228e1f..d83516122f 100644 --- a/src/Executor/Executor.php +++ b/src/Executor/Executor.php @@ -64,6 +64,7 @@ class Executor string $projectId, string $source, string $image, + string $version, bool $remove = false, string $entrypoint = '', string $workdir = '', @@ -86,6 +87,7 @@ class Executor 'commands' => $commands, 'cpus' => $this->cpus, 'memory' => $this->memory, + 'version' => $version, ]; $timeout = (int) App::getEnv('_APP_FUNCTIONS_BUILD_TIMEOUT', 900); @@ -124,6 +126,7 @@ class Executor string $image, string $source, string $entrypoint, + string $version ) { $runtimeId = "$projectId-$deploymentId"; $route = '/runtimes/' . $runtimeId . '/execution'; @@ -139,6 +142,7 @@ class Executor 'entrypoint' => $entrypoint, 'cpus' => $this->cpus, 'memory' => $this->memory, + 'version' => $version, ]; $timeout = (int) App::getEnv('_APP_FUNCTIONS_BUILD_TIMEOUT', 900); From d1a18a36b3f3ca732a3dc3f333b2af34053b8172 Mon Sep 17 00:00:00 2001 From: shimon Date: Mon, 6 Feb 2023 09:43:02 +0200 Subject: [PATCH 15/18] addressing comments --- app/realtime.php | 1 - composer.lock | 65 +++++++++++++++++++++++----------------------- docker-compose.yml | 1 - 3 files changed, 33 insertions(+), 34 deletions(-) diff --git a/app/realtime.php b/app/realtime.php index a7095ea505..37590348d2 100644 --- a/app/realtime.php +++ b/app/realtime.php @@ -432,7 +432,6 @@ $server->onOpen(function (int $connection, SwooleRequest $request) use ($server, } $roles = Auth::getRoles($user); - var_dump($request->getQuery('channels', [])); $channels = Realtime::convertChannels($request->getQuery('channels', []), $user->getId()); /** diff --git a/composer.lock b/composer.lock index cea427821e..fe84868f15 100644 --- a/composer.lock +++ b/composer.lock @@ -3491,20 +3491,20 @@ }, { "name": "phpspec/prophecy", - "version": "v1.16.0", + "version": "v1.17.0", "source": { "type": "git", "url": "https://github.com/phpspec/prophecy.git", - "reference": "be8cac52a0827776ff9ccda8c381ac5b71aeb359" + "reference": "15873c65b207b07765dbc3c95d20fdf4a320cbe2" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpspec/prophecy/zipball/be8cac52a0827776ff9ccda8c381ac5b71aeb359", - "reference": "be8cac52a0827776ff9ccda8c381ac5b71aeb359", + "url": "https://api.github.com/repos/phpspec/prophecy/zipball/15873c65b207b07765dbc3c95d20fdf4a320cbe2", + "reference": "15873c65b207b07765dbc3c95d20fdf4a320cbe2", "shasum": "" }, "require": { - "doctrine/instantiator": "^1.2", + "doctrine/instantiator": "^1.2 || ^2.0", "php": "^7.2 || 8.0.* || 8.1.* || 8.2.*", "phpdocumentor/reflection-docblock": "^5.2", "sebastian/comparator": "^3.0 || ^4.0", @@ -3512,6 +3512,7 @@ }, "require-dev": { "phpspec/phpspec": "^6.0 || ^7.0", + "phpstan/phpstan": "^1.9", "phpunit/phpunit": "^8.0 || ^9.0" }, "type": "library", @@ -3552,22 +3553,22 @@ ], "support": { "issues": "https://github.com/phpspec/prophecy/issues", - "source": "https://github.com/phpspec/prophecy/tree/v1.16.0" + "source": "https://github.com/phpspec/prophecy/tree/v1.17.0" }, - "time": "2022-11-29T15:06:56+00:00" + "time": "2023-02-02T15:41:36+00:00" }, { "name": "phpunit/php-code-coverage", - "version": "9.2.23", + "version": "9.2.24", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/php-code-coverage.git", - "reference": "9f1f0f9a2fbb680b26d1cf9b61b6eac43a6e4e9c" + "reference": "2cf940ebc6355a9d430462811b5aaa308b174bed" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/9f1f0f9a2fbb680b26d1cf9b61b6eac43a6e4e9c", - "reference": "9f1f0f9a2fbb680b26d1cf9b61b6eac43a6e4e9c", + "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/2cf940ebc6355a9d430462811b5aaa308b174bed", + "reference": "2cf940ebc6355a9d430462811b5aaa308b174bed", "shasum": "" }, "require": { @@ -3623,7 +3624,7 @@ ], "support": { "issues": "https://github.com/sebastianbergmann/php-code-coverage/issues", - "source": "https://github.com/sebastianbergmann/php-code-coverage/tree/9.2.23" + "source": "https://github.com/sebastianbergmann/php-code-coverage/tree/9.2.24" }, "funding": [ { @@ -3631,7 +3632,7 @@ "type": "github" } ], - "time": "2022-12-28T12:41:10+00:00" + "time": "2023-01-26T08:26:55+00:00" }, { "name": "phpunit/php-file-iterator", @@ -4343,16 +4344,16 @@ }, { "name": "sebastian/environment", - "version": "5.1.4", + "version": "5.1.5", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/environment.git", - "reference": "1b5dff7bb151a4db11d49d90e5408e4e938270f7" + "reference": "830c43a844f1f8d5b7a1f6d6076b784454d8b7ed" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/environment/zipball/1b5dff7bb151a4db11d49d90e5408e4e938270f7", - "reference": "1b5dff7bb151a4db11d49d90e5408e4e938270f7", + "url": "https://api.github.com/repos/sebastianbergmann/environment/zipball/830c43a844f1f8d5b7a1f6d6076b784454d8b7ed", + "reference": "830c43a844f1f8d5b7a1f6d6076b784454d8b7ed", "shasum": "" }, "require": { @@ -4394,7 +4395,7 @@ ], "support": { "issues": "https://github.com/sebastianbergmann/environment/issues", - "source": "https://github.com/sebastianbergmann/environment/tree/5.1.4" + "source": "https://github.com/sebastianbergmann/environment/tree/5.1.5" }, "funding": [ { @@ -4402,7 +4403,7 @@ "type": "github" } ], - "time": "2022-04-03T09:37:03+00:00" + "time": "2023-02-03T06:03:51+00:00" }, { "name": "sebastian/exporter", @@ -4716,16 +4717,16 @@ }, { "name": "sebastian/recursion-context", - "version": "4.0.4", + "version": "4.0.5", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/recursion-context.git", - "reference": "cd9d8cf3c5804de4341c283ed787f099f5506172" + "reference": "e75bd0f07204fec2a0af9b0f3cfe97d05f92efc1" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/recursion-context/zipball/cd9d8cf3c5804de4341c283ed787f099f5506172", - "reference": "cd9d8cf3c5804de4341c283ed787f099f5506172", + "url": "https://api.github.com/repos/sebastianbergmann/recursion-context/zipball/e75bd0f07204fec2a0af9b0f3cfe97d05f92efc1", + "reference": "e75bd0f07204fec2a0af9b0f3cfe97d05f92efc1", "shasum": "" }, "require": { @@ -4764,10 +4765,10 @@ } ], "description": "Provides functionality to recursively process PHP variables", - "homepage": "http://www.github.com/sebastianbergmann/recursion-context", + "homepage": "https://github.com/sebastianbergmann/recursion-context", "support": { "issues": "https://github.com/sebastianbergmann/recursion-context/issues", - "source": "https://github.com/sebastianbergmann/recursion-context/tree/4.0.4" + "source": "https://github.com/sebastianbergmann/recursion-context/tree/4.0.5" }, "funding": [ { @@ -4775,7 +4776,7 @@ "type": "github" } ], - "time": "2020-10-26T13:17:30+00:00" + "time": "2023-02-03T06:07:39+00:00" }, { "name": "sebastian/resource-operations", @@ -4834,16 +4835,16 @@ }, { "name": "sebastian/type", - "version": "3.2.0", + "version": "3.2.1", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/type.git", - "reference": "fb3fe09c5f0bae6bc27ef3ce933a1e0ed9464b6e" + "reference": "75e2c2a32f5e0b3aef905b9ed0b179b953b3d7c7" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/type/zipball/fb3fe09c5f0bae6bc27ef3ce933a1e0ed9464b6e", - "reference": "fb3fe09c5f0bae6bc27ef3ce933a1e0ed9464b6e", + "url": "https://api.github.com/repos/sebastianbergmann/type/zipball/75e2c2a32f5e0b3aef905b9ed0b179b953b3d7c7", + "reference": "75e2c2a32f5e0b3aef905b9ed0b179b953b3d7c7", "shasum": "" }, "require": { @@ -4878,7 +4879,7 @@ "homepage": "https://github.com/sebastianbergmann/type", "support": { "issues": "https://github.com/sebastianbergmann/type/issues", - "source": "https://github.com/sebastianbergmann/type/tree/3.2.0" + "source": "https://github.com/sebastianbergmann/type/tree/3.2.1" }, "funding": [ { @@ -4886,7 +4887,7 @@ "type": "github" } ], - "time": "2022-09-12T14:47:03+00:00" + "time": "2023-02-03T06:13:03+00:00" }, { "name": "sebastian/version", diff --git a/docker-compose.yml b/docker-compose.yml index 882c890425..d09e5649af 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -37,7 +37,6 @@ services: - /var/run/docker.sock:/var/run/docker.sock - appwrite-config:/storage/config:ro - appwrite-certificates:/storage/certificates:ro - #- ./vendor/utopia-php/framework:/usr/src/code/vendor/utopia-php/framework depends_on: - appwrite networks: From bab2c02d56112e67222b32c81152b204a3cba286 Mon Sep 17 00:00:00 2001 From: shimon Date: Mon, 6 Feb 2023 09:58:10 +0200 Subject: [PATCH 16/18] addressing comments --- app/controllers/shared/api.php | 56 ++++++---------------------------- app/realtime.php | 1 + 2 files changed, 10 insertions(+), 47 deletions(-) diff --git a/app/controllers/shared/api.php b/app/controllers/shared/api.php index fa247b8e78..db35cebc65 100644 --- a/app/controllers/shared/api.php +++ b/app/controllers/shared/api.php @@ -5,13 +5,14 @@ use Appwrite\Event\Audit; use Appwrite\Event\Database as EventDatabase; use Appwrite\Event\Delete; use Appwrite\Event\Event; +use Appwrite\Event\Func; use Appwrite\Event\Mail; -use Appwrite\Extend\Exception; use Appwrite\Messaging\Adapter\Realtime; use Appwrite\Usage\Stats; use Appwrite\Utopia\Response; use Appwrite\Utopia\Request; use Utopia\App; +use Appwrite\Extend\Exception; use Utopia\Abuse\Abuse; use Utopia\Abuse\Adapters\TimeLimit; use Utopia\Cache\Adapter\Filesystem; @@ -170,9 +171,9 @@ App::init() } } - /* - * Background Jobs - */ + /* + * Background Jobs + */ $events ->setEvent($route->getLabel('event', '')) ->setProject($project) @@ -318,45 +319,6 @@ App::init() } }); -/** - * Limit user session - * - * Delete older sessions if the number of sessions have crossed - * the session limit set for the project - */ -App::shutdown() - ->groups(['session']) - ->inject('utopia') - ->inject('request') - ->inject('response') - ->inject('project') - ->inject('dbForProject') - ->action(function (App $utopia, Request $request, Response $response, Document $project, Database $dbForProject) { - $sessionLimit = $project->getAttribute('auths', [])['maxSessions'] ?? APP_LIMIT_USER_SESSIONS_DEFAULT; - $session = $response->getPayload(); - $userId = $session['userId'] ?? ''; - if (empty($userId)) { - return; - } - - $user = $dbForProject->getDocument('users', $userId); - if ($user->isEmpty()) { - return; - } - - $sessions = $user->getAttribute('sessions', []); - $count = \count($sessions); - if ($count <= $sessionLimit) { - return; - } - - for ($i = 0; $i < ($count - $sessionLimit); $i++) { - $session = array_shift($sessions); - $dbForProject->deleteDocument('sessions', $session->getId()); - } - $dbForProject->deleteCachedDocument('users', $userId); - }); - App::shutdown() ->groups(['api']) ->inject('utopia') @@ -370,7 +332,8 @@ App::shutdown() ->inject('database') ->inject('mode') ->inject('dbForProject') - ->action(function (App $utopia, Request $request, Response $response, Document $project, Event $events, Audit $audits, Stats $usage, Delete $deletes, EventDatabase $database, string $mode, Database $dbForProject) use ($parseLabel) { + ->inject('queueForFunctions') + ->action(function (App $utopia, Request $request, Response $response, Document $project, Event $events, Audit $audits, Stats $usage, Delete $deletes, EventDatabase $database, string $mode, Database $dbForProject, Func $queueForFunctions) use ($parseLabel) { $responsePayload = $response->getPayload(); @@ -381,9 +344,8 @@ App::shutdown() /** * Trigger functions. */ - $events - ->setClass(Event::FUNCTIONS_CLASS_NAME) - ->setQueue(Event::FUNCTIONS_QUEUE_NAME) + $queueForFunctions + ->from($events) ->trigger(); /** diff --git a/app/realtime.php b/app/realtime.php index 37590348d2..4b40e2a9dd 100644 --- a/app/realtime.php +++ b/app/realtime.php @@ -432,6 +432,7 @@ $server->onOpen(function (int $connection, SwooleRequest $request) use ($server, } $roles = Auth::getRoles($user); + $channels = Realtime::convertChannels($request->getQuery('channels', []), $user->getId()); /** From e4d784c871b57968ea2134445ef9d7e760ab2710 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matej=20Ba=C4=8Do?= Date: Tue, 14 Feb 2023 11:01:38 +0000 Subject: [PATCH 17/18] Add new V3 parameters --- app/config/collections.php | 17 +++- app/config/runtimes.php | 2 - app/controllers/api/functions.php | 46 +++++---- app/workers/functions.php | 35 +++++-- composer.lock | 99 ++++++++----------- docker-compose.yml | 2 +- src/Appwrite/Event/Func.php | 57 +++++++++-- src/Appwrite/Utopia/Response.php | 3 + .../Utopia/Response/Model/Execution.php | 12 ++- .../Utopia/Response/Model/Headers.php | 28 ++++++ src/Executor/Executor.php | 20 ++-- .../Functions/FunctionsCustomClientTest.php | 4 +- .../Functions/FunctionsCustomServerTest.php | 9 +- 13 files changed, 223 insertions(+), 111 deletions(-) create mode 100644 src/Appwrite/Utopia/Response/Model/Headers.php diff --git a/app/config/collections.php b/app/config/collections.php index 7b8c35e104..bc4db6bce6 100644 --- a/app/config/collections.php +++ b/app/config/collections.php @@ -2744,7 +2744,7 @@ $collections = [ 'filters' => [], ], [ - '$id' => ID::custom('response'), + '$id' => ID::custom('body'), 'type' => Database::VAR_STRING, 'format' => '', 'size' => 1000000, @@ -2755,7 +2755,7 @@ $collections = [ 'filters' => [], ], [ - '$id' => ID::custom('stderr'), + '$id' => ID::custom('errors'), 'type' => Database::VAR_STRING, 'format' => '', 'size' => 1000000, @@ -2766,7 +2766,7 @@ $collections = [ 'filters' => [], ], [ - '$id' => ID::custom('stdout'), + '$id' => ID::custom('logs'), 'type' => Database::VAR_STRING, 'format' => '', 'size' => 1000000, @@ -2787,6 +2787,17 @@ $collections = [ 'array' => false, 'filters' => [], ], + [ + '$id' => ID::custom('headers'), + 'type' => Database::VAR_STRING, + 'format' => '', + 'size' => 16384, + 'signed' => true, + 'required' => false, + 'default' => [], + 'array' => false, + 'filters' => ['json'], + ], [ '$id' => ID::custom('duration'), 'type' => Database::VAR_FLOAT, diff --git a/app/config/runtimes.php b/app/config/runtimes.php index b226e295b2..2cd73c1b70 100644 --- a/app/config/runtimes.php +++ b/app/config/runtimes.php @@ -13,6 +13,4 @@ $allowList = empty(App::getEnv('_APP_FUNCTIONS_RUNTIMES')) ? [] : \explode(',', $runtimes = $runtimes->getAll(true, $allowList); -$runtimes['php-8.1']['image'] = 'meldiron/php:v3-8.1'; - return $runtimes; diff --git a/app/controllers/api/functions.php b/app/controllers/api/functions.php index b237888a9a..83bb63dc43 100644 --- a/app/controllers/api/functions.php +++ b/app/controllers/api/functions.php @@ -13,6 +13,7 @@ use Utopia\Database\ID; use Utopia\Database\Permission; use Utopia\Database\Role; use Utopia\Database\Validator\UID; +use Utopia\Validator\Assoc; use Appwrite\Usage\Stats; use Utopia\Storage\Device; use Utopia\Storage\Validator\File; @@ -1057,8 +1058,11 @@ App::post('/v1/functions/:functionId/executions') ->label('abuse-limit', APP_LIMIT_WRITE_RATE_DEFAULT) ->label('abuse-time', APP_LIMIT_WRITE_RATE_PERIOD_DEFAULT) ->param('functionId', '', new UID(), 'Function ID.') - ->param('data', '', new Text(8192), 'String of custom data to send to function.', true) + ->param('body', '', new Text(8192), 'HTTP body of execution. Default value is empty string.', true) ->param('async', false, new Boolean(), 'Execute code in the background. Default value is false.', true) + ->param('path', '/', new Text(2048), 'HTTP path of execution. Default value is /', true) + ->param('method', 'GET', new Whitelist([ 'GET', 'POST', 'PUT', 'PATCH', 'DELETE', 'OPTIONS' ], true), 'HTTP method of execution. Default value is GET.', true) + ->param('headers', [], new Assoc(), 'HTP headers of execution. Defaults to empty.', true) ->inject('response') ->inject('project') ->inject('dbForProject') @@ -1067,7 +1071,7 @@ App::post('/v1/functions/:functionId/executions') ->inject('usage') ->inject('mode') ->inject('queueForFunctions') - ->action(function (string $functionId, string $data, bool $async, Response $response, Document $project, Database $dbForProject, Document $user, Event $events, Stats $usage, string $mode, Func $queueForFunctions) { + ->action(function (string $functionId, string $body, bool $async, string $path, string $method, array $headers, Response $response, Document $project, Database $dbForProject, Document $user, Event $events, Stats $usage, string $mode, Func $queueForFunctions) { $function = Authorization::skip(fn () => $dbForProject->getDocument('functions', $functionId)); @@ -1122,8 +1126,10 @@ App::post('/v1/functions/:functionId/executions') 'trigger' => 'http', // http / schedule / event 'status' => $async ? 'waiting' : 'processing', // waiting / processing / completed / failed 'statusCode' => 0, - 'response' => '', - 'stderr' => '', + 'body' => '', + 'headers' => [], + 'errors' => '', + 'logs' => '', 'duration' => 0.0, 'search' => implode(' ', [$functionId, $executionId]), ]))); @@ -1159,7 +1165,10 @@ App::post('/v1/functions/:functionId/executions') ->setType('http') ->setExecution($execution) ->setFunction($function) - ->setData($data) + ->setBody($body) + ->setHeaders($headers) + ->setPath($path) + ->setMethod($method) ->setJWT($jwt) ->setProject($project) ->setUser($user) @@ -1195,22 +1204,25 @@ App::post('/v1/functions/:functionId/executions') projectId: $project->getId(), deploymentId: $deployment->getId(), version: $function->getAttribute('version'), - payload: $data, + body: $body, variables: $vars, timeout: $function->getAttribute('timeout', 0), image: $runtime['image'], source: $build->getAttribute('path', ''), entrypoint: $deployment->getAttribute('entrypoint', ''), + path: $path, + method: $method, + headers: $headers, ); - /** Update execution status */ $status = $executionResponse['statusCode'] >= 500 ? 'failed' : 'completed'; $execution->setAttribute('status', $status); $execution->setAttribute('statusCode', $executionResponse['statusCode']); - $execution->setAttribute('response', $executionResponse['body']); - $execution->setAttribute('stdout', $executionResponse['logs']); - $execution->setAttribute('stderr', $executionResponse['errors']); + $execution->setAttribute('headers', $executionResponse['headers']); + $execution->setAttribute('body', $executionResponse['body']); + $execution->setAttribute('logs', $executionResponse['logs']); + $execution->setAttribute('errors', $executionResponse['errors']); $execution->setAttribute('duration', $executionResponse['duration']); } catch (\Throwable $th) { $interval = (new \DateTime())->diff(new \DateTime($execution->getCreatedAt())); @@ -1218,7 +1230,7 @@ App::post('/v1/functions/:functionId/executions') ->setAttribute('duration', (float)$interval->format('%s.%f')) ->setAttribute('status', 'failed') ->setAttribute('statusCode', $th->getCode()) - ->setAttribute('stderr', $th->getMessage()); + ->setAttribute('errors', $th->getMessage()); Console::error($th->getMessage()); } @@ -1236,8 +1248,8 @@ App::post('/v1/functions/:functionId/executions') $isAppUser = Auth::isAppUser($roles); if (!$isPrivilegedUser && !$isAppUser) { - $execution->setAttribute('stdout', ''); - $execution->setAttribute('stderr', ''); + $execution->setAttribute('logs', ''); + $execution->setAttribute('errors', ''); } $response @@ -1306,8 +1318,8 @@ App::get('/v1/functions/:functionId/executions') $isAppUser = Auth::isAppUser($roles); if (!$isPrivilegedUser && !$isAppUser) { $results = array_map(function ($execution) { - $execution->setAttribute('stdout', ''); - $execution->setAttribute('stderr', ''); + $execution->setAttribute('logs', ''); + $execution->setAttribute('errors', ''); return $execution; }, $results); } @@ -1358,8 +1370,8 @@ App::get('/v1/functions/:functionId/executions/:executionId') $isPrivilegedUser = Auth::isPrivilegedUser($roles); $isAppUser = Auth::isAppUser($roles); if (!$isPrivilegedUser && !$isAppUser) { - $execution->setAttribute('stdout', ''); - $execution->setAttribute('stderr', ''); + $execution->setAttribute('logs', ''); + $execution->setAttribute('errors', ''); } $response->dynamic($execution, Response::MODEL_EXECUTION); diff --git a/app/workers/functions.php b/app/workers/functions.php index 51659a4c70..6145c9e31e 100644 --- a/app/workers/functions.php +++ b/app/workers/functions.php @@ -34,6 +34,9 @@ Server::setResource('execute', function () { Document $function, string $trigger, string $data = null, + string $path, + string $method, + array $headers, ?Document $user = null, string $jwt = null, string $event = null, @@ -86,8 +89,10 @@ Server::setResource('execute', function () { 'trigger' => $trigger, 'status' => 'waiting', 'statusCode' => 0, - 'response' => '', - 'stderr' => '', + 'body' => '', + 'headers' => [], + 'errors' => '', + 'logs' => '', 'duration' => 0.0, 'search' => implode(' ', [$functionId, $executionId]), ])); @@ -125,17 +130,21 @@ Server::setResource('execute', function () { /** Execute function */ try { + \var_dump($build->getAttribute('path', '')); $client = new Executor(App::getEnv('_APP_EXECUTOR_HOST')); $executionResponse = $client->createExecution( projectId: $project->getId(), deploymentId: $deploymentId, version: $function->getAttribute('version'), - payload: $vars['APPWRITE_FUNCTION_DATA'] ?? '', + body: $vars['APPWRITE_FUNCTION_DATA'] ?? '', variables: $vars, timeout: $function->getAttribute('timeout', 0), image: $runtime['image'], source: $build->getAttribute('path', ''), entrypoint: $deployment->getAttribute('entrypoint', ''), + path: $path, + method: $method, + headers: $headers, ); $status = $executionResponse['statusCode'] >= 500 ? 'failed' : 'completed'; @@ -144,9 +153,10 @@ Server::setResource('execute', function () { $execution ->setAttribute('status', $status) ->setAttribute('statusCode', $executionResponse['statusCode']) - ->setAttribute('response', $executionResponse['body']) - ->setAttribute('stdout', $executionResponse['logs']) - ->setAttribute('stderr', $executionResponse['errors']) + ->setAttribute('headers', $executionResponse['headers']) + ->setAttribute('body', $executionResponse['body']) + ->setAttribute('logs', $executionResponse['logs']) + ->setAttribute('errors', $executionResponse['errors']) ->setAttribute('duration', $executionResponse['duration']); } catch (\Throwable $th) { $interval = (new \DateTime())->diff(new \DateTime($execution->getCreatedAt())); @@ -154,7 +164,7 @@ Server::setResource('execute', function () { ->setAttribute('duration', (float)$interval->format('%s.%f')) ->setAttribute('status', 'failed') ->setAttribute('statusCode', $th->getCode()) - ->setAttribute('stderr', $th->getMessage()); + ->setAttribute('errors', $th->getMessage()); Console::error($th->getTraceAsString()); Console::error($th->getFile()); @@ -283,7 +293,10 @@ $server->job() user: $user, data: null, executionId: null, - jwt: null + jwt: null, + path: $payload['path'], + method: $payload['method'], + headers: $payload['headers'], ); Console::success('Triggered function: ' . $events[0]); } @@ -312,6 +325,9 @@ $server->job() user: $user, jwt: $jwt, statsd: $statsd, + path: $payload['path'], + method: $payload['method'], + headers: $payload['headers'], ); break; case 'schedule': @@ -328,6 +344,9 @@ $server->job() user: null, jwt: null, statsd: $statsd, + path: $payload['path'], + method: $payload['method'], + headers: $payload['headers'], ); break; } diff --git a/composer.lock b/composer.lock index 4ee60140ac..dc33c8026a 100644 --- a/composer.lock +++ b/composer.lock @@ -2140,22 +2140,23 @@ }, { "name": "utopia-php/logger", - "version": "0.3.0", + "version": "0.3.1", "source": { "type": "git", "url": "https://github.com/utopia-php/logger.git", - "reference": "079656cb5169ca9600861eda0b6819199e3d4a57" + "reference": "de623f1ec1c672c795d113dd25c5bf212f7ef4fc" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/utopia-php/logger/zipball/079656cb5169ca9600861eda0b6819199e3d4a57", - "reference": "079656cb5169ca9600861eda0b6819199e3d4a57", + "url": "https://api.github.com/repos/utopia-php/logger/zipball/de623f1ec1c672c795d113dd25c5bf212f7ef4fc", + "reference": "de623f1ec1c672c795d113dd25c5bf212f7ef4fc", "shasum": "" }, "require": { "php": ">=8.0" }, "require-dev": { + "phpstan/phpstan": "1.9.x-dev", "phpunit/phpunit": "^9.3", "vimeo/psalm": "4.0.1" }, @@ -2169,20 +2170,6 @@ "license": [ "MIT" ], - "authors": [ - { - "name": "Eldad Fux", - "email": "eldad@appwrite.io" - }, - { - "name": "Matej Bačo", - "email": "matej@appwrite.io" - }, - { - "name": "Christy Jacob", - "email": "christy@appwrite.io" - } - ], "description": "Utopia Logger library is simple and lite library for logging information, such as errors or warnings. This library is aiming to be as simple and easy to learn and use.", "keywords": [ "appsignal", @@ -2200,22 +2187,22 @@ ], "support": { "issues": "https://github.com/utopia-php/logger/issues", - "source": "https://github.com/utopia-php/logger/tree/0.3.0" + "source": "https://github.com/utopia-php/logger/tree/0.3.1" }, - "time": "2022-03-18T10:56:57+00:00" + "time": "2023-02-10T15:52:50+00:00" }, { "name": "utopia-php/messaging", - "version": "0.1.0", + "version": "0.1.1", "source": { "type": "git", "url": "https://github.com/utopia-php/messaging.git", - "reference": "501272fad666f06bec8f130076862e7981a73f8c" + "reference": "a75d66ddd59b834ab500a4878a2c084e6572604a" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/utopia-php/messaging/zipball/501272fad666f06bec8f130076862e7981a73f8c", - "reference": "501272fad666f06bec8f130076862e7981a73f8c", + "url": "https://api.github.com/repos/utopia-php/messaging/zipball/a75d66ddd59b834ab500a4878a2c084e6572604a", + "reference": "a75d66ddd59b834ab500a4878a2c084e6572604a", "shasum": "" }, "require": { @@ -2223,9 +2210,9 @@ "php": ">=8.0.0" }, "require-dev": { + "laravel/pint": "^1.2", "phpmailer/phpmailer": "6.6.*", - "phpunit/phpunit": "9.5.*", - "squizlabs/php_codesniffer": "^3.6" + "phpunit/phpunit": "9.5.*" }, "type": "library", "autoload": { @@ -2237,12 +2224,6 @@ "license": [ "MIT" ], - "authors": [ - { - "name": "Jake Barnby", - "email": "jake@appwrite.io" - } - ], "description": "A simple, light and advanced PHP messaging library", "keywords": [ "library", @@ -2254,9 +2235,9 @@ ], "support": { "issues": "https://github.com/utopia-php/messaging/issues", - "source": "https://github.com/utopia-php/messaging/tree/0.1.0" + "source": "https://github.com/utopia-php/messaging/tree/0.1.1" }, - "time": "2022-09-29T11:22:48+00:00" + "time": "2023-02-07T05:42:46+00:00" }, { "name": "utopia-php/orchestration", @@ -4344,16 +4325,16 @@ }, { "name": "sebastian/environment", - "version": "5.1.4", + "version": "5.1.5", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/environment.git", - "reference": "1b5dff7bb151a4db11d49d90e5408e4e938270f7" + "reference": "830c43a844f1f8d5b7a1f6d6076b784454d8b7ed" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/environment/zipball/1b5dff7bb151a4db11d49d90e5408e4e938270f7", - "reference": "1b5dff7bb151a4db11d49d90e5408e4e938270f7", + "url": "https://api.github.com/repos/sebastianbergmann/environment/zipball/830c43a844f1f8d5b7a1f6d6076b784454d8b7ed", + "reference": "830c43a844f1f8d5b7a1f6d6076b784454d8b7ed", "shasum": "" }, "require": { @@ -4395,7 +4376,7 @@ ], "support": { "issues": "https://github.com/sebastianbergmann/environment/issues", - "source": "https://github.com/sebastianbergmann/environment/tree/5.1.4" + "source": "https://github.com/sebastianbergmann/environment/tree/5.1.5" }, "funding": [ { @@ -4403,7 +4384,7 @@ "type": "github" } ], - "time": "2022-04-03T09:37:03+00:00" + "time": "2023-02-03T06:03:51+00:00" }, { "name": "sebastian/exporter", @@ -4717,16 +4698,16 @@ }, { "name": "sebastian/recursion-context", - "version": "4.0.4", + "version": "4.0.5", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/recursion-context.git", - "reference": "cd9d8cf3c5804de4341c283ed787f099f5506172" + "reference": "e75bd0f07204fec2a0af9b0f3cfe97d05f92efc1" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/recursion-context/zipball/cd9d8cf3c5804de4341c283ed787f099f5506172", - "reference": "cd9d8cf3c5804de4341c283ed787f099f5506172", + "url": "https://api.github.com/repos/sebastianbergmann/recursion-context/zipball/e75bd0f07204fec2a0af9b0f3cfe97d05f92efc1", + "reference": "e75bd0f07204fec2a0af9b0f3cfe97d05f92efc1", "shasum": "" }, "require": { @@ -4765,10 +4746,10 @@ } ], "description": "Provides functionality to recursively process PHP variables", - "homepage": "http://www.github.com/sebastianbergmann/recursion-context", + "homepage": "https://github.com/sebastianbergmann/recursion-context", "support": { "issues": "https://github.com/sebastianbergmann/recursion-context/issues", - "source": "https://github.com/sebastianbergmann/recursion-context/tree/4.0.4" + "source": "https://github.com/sebastianbergmann/recursion-context/tree/4.0.5" }, "funding": [ { @@ -4776,7 +4757,7 @@ "type": "github" } ], - "time": "2020-10-26T13:17:30+00:00" + "time": "2023-02-03T06:07:39+00:00" }, { "name": "sebastian/resource-operations", @@ -4835,16 +4816,16 @@ }, { "name": "sebastian/type", - "version": "3.2.0", + "version": "3.2.1", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/type.git", - "reference": "fb3fe09c5f0bae6bc27ef3ce933a1e0ed9464b6e" + "reference": "75e2c2a32f5e0b3aef905b9ed0b179b953b3d7c7" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/type/zipball/fb3fe09c5f0bae6bc27ef3ce933a1e0ed9464b6e", - "reference": "fb3fe09c5f0bae6bc27ef3ce933a1e0ed9464b6e", + "url": "https://api.github.com/repos/sebastianbergmann/type/zipball/75e2c2a32f5e0b3aef905b9ed0b179b953b3d7c7", + "reference": "75e2c2a32f5e0b3aef905b9ed0b179b953b3d7c7", "shasum": "" }, "require": { @@ -4879,7 +4860,7 @@ "homepage": "https://github.com/sebastianbergmann/type", "support": { "issues": "https://github.com/sebastianbergmann/type/issues", - "source": "https://github.com/sebastianbergmann/type/tree/3.2.0" + "source": "https://github.com/sebastianbergmann/type/tree/3.2.1" }, "funding": [ { @@ -4887,7 +4868,7 @@ "type": "github" } ], - "time": "2022-09-12T14:47:03+00:00" + "time": "2023-02-03T06:13:03+00:00" }, { "name": "sebastian/version", @@ -5306,16 +5287,16 @@ }, { "name": "twig/twig", - "version": "v3.5.0", + "version": "v3.5.1", "source": { "type": "git", "url": "https://github.com/twigphp/Twig.git", - "reference": "3ffcf4b7d890770466da3b2666f82ac054e7ec72" + "reference": "a6e0510cc793912b451fd40ab983a1d28f611c15" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/twigphp/Twig/zipball/3ffcf4b7d890770466da3b2666f82ac054e7ec72", - "reference": "3ffcf4b7d890770466da3b2666f82ac054e7ec72", + "url": "https://api.github.com/repos/twigphp/Twig/zipball/a6e0510cc793912b451fd40ab983a1d28f611c15", + "reference": "a6e0510cc793912b451fd40ab983a1d28f611c15", "shasum": "" }, "require": { @@ -5366,7 +5347,7 @@ ], "support": { "issues": "https://github.com/twigphp/Twig/issues", - "source": "https://github.com/twigphp/Twig/tree/v3.5.0" + "source": "https://github.com/twigphp/Twig/tree/v3.5.1" }, "funding": [ { @@ -5378,7 +5359,7 @@ "type": "tidelift" } ], - "time": "2022-12-27T12:28:18+00:00" + "time": "2023-02-08T07:49:20+00:00" } ], "aliases": [], diff --git a/docker-compose.yml b/docker-compose.yml index 780d79c475..97abe3eaaf 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -659,7 +659,7 @@ services: hostname: exc1 <<: *x-logging stop_signal: SIGINT - image: meldiron/executor:v3 + image: meldiron/executor:0.3.0 networks: - appwrite - runtimes diff --git a/src/Appwrite/Event/Func.php b/src/Appwrite/Event/Func.php index 5f8b4c80c6..469c7eda29 100644 --- a/src/Appwrite/Event/Func.php +++ b/src/Appwrite/Event/Func.php @@ -10,7 +10,10 @@ class Func extends Event { protected string $jwt = ''; protected string $type = ''; - protected string $data = ''; + protected string $body = ''; + protected string $path = ''; + protected string $method = ''; + protected array $headers = []; protected ?Document $function = null; protected ?Document $execution = null; @@ -89,14 +92,53 @@ class Func extends Event } /** - * Sets custom data for the function event. + * Sets custom body for the function event. * - * @param string $data + * @param string $body * @return self */ - public function setData(string $data): self + public function setBody(string $body): self { - $this->data = $data; + $this->body = $body; + + return $this; + } + + /** + * Sets custom method for the function event. + * + * @param string $method + * @return self + */ + public function setMethod(string $method): self + { + $this->method = $method; + + return $this; + } + + /** + * Sets custom path for the function event. + * + * @param string $path + * @return self + */ + public function setPath(string $path): self + { + $this->path = $path; + + return $this; + } + + /** + * Sets custom headers for the function event. + * + * @param string $headers + * @return self + */ + public function setHeaders(array $headers): self + { + $this->headers = $headers; return $this; } @@ -155,7 +197,10 @@ class Func extends Event 'jwt' => $this->jwt, 'payload' => $this->payload, 'events' => $events, - 'data' => $this->data, + 'body' => $this->body, + 'path' => $this->path, + 'headers' => $this->headers, + 'method' => $this->method, ]); } diff --git a/src/Appwrite/Utopia/Response.php b/src/Appwrite/Utopia/Response.php index 092f8eb230..a7d1bf4555 100644 --- a/src/Appwrite/Utopia/Response.php +++ b/src/Appwrite/Utopia/Response.php @@ -61,6 +61,7 @@ use Appwrite\Utopia\Response\Model\Platform; use Appwrite\Utopia\Response\Model\Project; use Appwrite\Utopia\Response\Model\Rule; use Appwrite\Utopia\Response\Model\Deployment; +use Appwrite\Utopia\Response\Model\Headers; use Appwrite\Utopia\Response\Model\Token; use Appwrite\Utopia\Response\Model\Webhook; use Appwrite\Utopia\Response\Model\Preferences; @@ -187,6 +188,7 @@ class Response extends SwooleResponse public const MODEL_BUILD = 'build'; public const MODEL_BUILD_LIST = 'buildList'; // Not used anywhere yet public const MODEL_FUNC_PERMISSIONS = 'funcPermissions'; + public const MODEL_HEADERS = 'headers'; // Project public const MODEL_PROJECT = 'project'; @@ -341,6 +343,7 @@ class Response extends SwooleResponse ->setModel(new UsageFunctions()) ->setModel(new UsageFunction()) ->setModel(new UsageProject()) + ->setModel(new Headers()) // Verification // Recovery // Tests (keep last) diff --git a/src/Appwrite/Utopia/Response/Model/Execution.php b/src/Appwrite/Utopia/Response/Model/Execution.php index 13011a24b7..223000385f 100644 --- a/src/Appwrite/Utopia/Response/Model/Execution.php +++ b/src/Appwrite/Utopia/Response/Model/Execution.php @@ -60,19 +60,25 @@ class Execution extends Model 'default' => 0, 'example' => 0, ]) - ->addRule('response', [ + ->addRule('body', [ 'type' => self::TYPE_STRING, 'description' => 'The script response output string. Logs the last 4,000 characters of the execution response output.', 'default' => '', 'example' => '', ]) - ->addRule('stdout', [ + ->addRule('headers', [ + 'type' => Response::MODEL_HEADERS, + 'description' => 'Response headers as a key-value object', + 'default' => new \stdClass(), + 'example' => ['x-internal-timezone' => 'UTC'], + ]) + ->addRule('logs', [ 'type' => self::TYPE_STRING, 'description' => 'The script stdout output string. Logs the last 4,000 characters of the execution stdout output. This will return an empty string unless the response is returned using an API key or as part of a webhook payload.', 'default' => '', 'example' => '', ]) - ->addRule('stderr', [ + ->addRule('errors', [ 'type' => self::TYPE_STRING, 'description' => 'The script stderr output string. Logs the last 4,000 characters of the execution stderr output. This will return an empty string unless the response is returned using an API key or as part of a webhook payload.', 'default' => '', diff --git a/src/Appwrite/Utopia/Response/Model/Headers.php b/src/Appwrite/Utopia/Response/Model/Headers.php new file mode 100644 index 0000000000..5cfc9e8891 --- /dev/null +++ b/src/Appwrite/Utopia/Response/Model/Headers.php @@ -0,0 +1,28 @@ + $runtimeId ]; + $reqHeaders = [ 'x-opr-runtime-id' => $runtimeId ]; $params = [ 'runtimeId' => $runtimeId, 'source' => $source, @@ -92,7 +92,7 @@ class Executor $timeout = (int) App::getEnv('_APP_FUNCTIONS_BUILD_TIMEOUT', 900); - $response = $this->call(self::METHOD_POST, $route, $headers, $params, true, $timeout); + $response = $this->call(self::METHOD_POST, $route, $reqHeaders, $params, true, $timeout); $status = $response['headers']['status-code']; if ($status >= 400) { @@ -120,22 +120,28 @@ class Executor public function createExecution( string $projectId, string $deploymentId, - string $payload, + string $body, array $variables, int $timeout, string $image, string $source, string $entrypoint, - string $version + string $version, + string $path, + string $method, + array $headers, ) { $runtimeId = "$projectId-$deploymentId"; $route = '/runtimes/' . $runtimeId . '/execution'; - $headers = [ 'x-opr-runtime-id' => $runtimeId ]; + $reqHeaders = [ 'x-opr-runtime-id' => $runtimeId ]; $params = [ 'runtimeId' => $runtimeId, 'variables' => $variables, - 'payload' => $payload, + 'body' => $body, 'timeout' => $timeout, + 'path' => $path, + 'method' => $method, + 'headers' => $headers, 'image' => $image, 'source' => $source, @@ -147,7 +153,7 @@ class Executor $timeout = (int) App::getEnv('_APP_FUNCTIONS_BUILD_TIMEOUT', 900); - $response = $this->call(self::METHOD_POST, $route, $headers, $params, true, $timeout); + $response = $this->call(self::METHOD_POST, $route, $reqHeaders, $params, true, $timeout); $status = $response['headers']['status-code']; if ($status >= 400) { diff --git a/tests/e2e/Services/Functions/FunctionsCustomClientTest.php b/tests/e2e/Services/Functions/FunctionsCustomClientTest.php index 56b72e4468..8416b5d804 100644 --- a/tests/e2e/Services/Functions/FunctionsCustomClientTest.php +++ b/tests/e2e/Services/Functions/FunctionsCustomClientTest.php @@ -590,8 +590,8 @@ class FunctionsCustomClientTest extends Scope $this->assertNotEmpty($output['APPWRITE_FUNCTION_JWT']); $this->assertEquals($projectId, $output['APPWRITE_FUNCTION_PROJECT_ID']); // Client should never see logs and errors - $this->assertEmpty($execution['body']['stdout']); - $this->assertEmpty($execution['body']['stderr']); + $this->assertEmpty($execution['body']['logs']); + $this->assertEmpty($execution['body']['errors']); // Cleanup : Delete function $response = $this->client->call(Client::METHOD_DELETE, '/functions/' . $functionId, [ diff --git a/tests/e2e/Services/Functions/FunctionsCustomServerTest.php b/tests/e2e/Services/Functions/FunctionsCustomServerTest.php index e2d7b8482b..2eea5268ed 100644 --- a/tests/e2e/Services/Functions/FunctionsCustomServerTest.php +++ b/tests/e2e/Services/Functions/FunctionsCustomServerTest.php @@ -611,7 +611,8 @@ class FunctionsCustomServerTest extends Scope $this->assertEquals('waiting', $execution['body']['status']); $this->assertEquals(0, $execution['body']['statusCode']); $this->assertEquals('', $execution['body']['response']); - $this->assertEquals('', $execution['body']['stderr']); + $this->assertEquals('', $execution['body']['errors']); + $this->assertEquals('', $execution['body']['logs']); $this->assertEquals(0, $execution['body']['duration']); sleep(10); @@ -634,7 +635,8 @@ class FunctionsCustomServerTest extends Scope $this->assertStringContainsString('PHP', $execution['body']['response']); $this->assertStringContainsString('8.0', $execution['body']['response']); $this->assertStringContainsString('êä', $execution['body']['response']); // tests unknown utf-8 chars - $this->assertEquals('', $execution['body']['stderr']); + $this->assertEquals('', $execution['body']['errors']); + $this->assertEquals('', $execution['body']['logs']); $this->assertLessThan(1.500, $execution['body']['duration']); /** @@ -917,7 +919,8 @@ class FunctionsCustomServerTest extends Scope $this->assertLessThan(6, $executions['body']['executions'][0]['duration']); $this->assertGreaterThan(4, $executions['body']['executions'][0]['duration']); $this->assertEquals($executions['body']['executions'][0]['response'], ''); - $this->assertEquals($executions['body']['executions'][0]['stderr'], 'An internal curl error has occurred within the executor! Error Msg: Operation timed out'); + $this->assertEquals($executions['body']['executions'][0]['logs'], ''); + $this->assertEquals($executions['body']['executions'][0]['errors'], 'An internal curl error has occurred within the executor! Error Msg: Operation timed out'); // Cleanup : Delete function $response = $this->client->call(Client::METHOD_DELETE, '/functions/' . $functionId, [ From d2ffa3e7c6090a65e1a81d5838fca1d423d875ab Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matej=20Ba=C4=8Do?= Date: Tue, 14 Feb 2023 11:35:49 +0000 Subject: [PATCH 18/18] Fix cold-start bug --- app/controllers/api/functions.php | 2 +- app/workers/functions.php | 3 +-- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/app/controllers/api/functions.php b/app/controllers/api/functions.php index cdd1acf1dd..8952aaf517 100644 --- a/app/controllers/api/functions.php +++ b/app/controllers/api/functions.php @@ -1216,7 +1216,7 @@ App::post('/v1/functions/:functionId/executions') variables: $vars, timeout: $function->getAttribute('timeout', 0), image: $runtime['image'], - source: $build->getAttribute('path', ''), + source: $deployment->getAttribute('path', ''), entrypoint: $deployment->getAttribute('entrypoint', ''), path: $path, method: $method, diff --git a/app/workers/functions.php b/app/workers/functions.php index b4d94ade9d..f496fe36b6 100644 --- a/app/workers/functions.php +++ b/app/workers/functions.php @@ -130,7 +130,6 @@ Server::setResource('execute', function () { /** Execute function */ try { - \var_dump($build->getAttribute('path', '')); $client = new Executor(App::getEnv('_APP_EXECUTOR_HOST')); $executionResponse = $client->createExecution( projectId: $project->getId(), @@ -140,7 +139,7 @@ Server::setResource('execute', function () { variables: $vars, timeout: $function->getAttribute('timeout', 0), image: $runtime['image'], - source: $build->getAttribute('path', ''), + source: $deployment->getAttribute('path', ''), entrypoint: $deployment->getAttribute('entrypoint', ''), path: $path, method: $method,