From a8fa86ee223acd7fc971876cf170b4b2e95433c7 Mon Sep 17 00:00:00 2001 From: Timm Friebe Date: Sat, 18 Nov 2023 12:15:58 +0100 Subject: [PATCH 1/4] Run lambda HTTP APIs via `xp web com.amazon.aws.lambda.Ws [class]` --- .../php/com/amazon/aws/lambda/Ws.class.php | 81 +++++++++++++++++++ 1 file changed, 81 insertions(+) create mode 100755 src/main/php/com/amazon/aws/lambda/Ws.class.php diff --git a/src/main/php/com/amazon/aws/lambda/Ws.class.php b/src/main/php/com/amazon/aws/lambda/Ws.class.php new file mode 100755 index 0000000..845ed0e --- /dev/null +++ b/src/main/php/com/amazon/aws/lambda/Ws.class.php @@ -0,0 +1,81 @@ +arguments())) { + throw new IllegalArgumentException('Need an argument'); + } + + $this->app= XPClass::forName($arguments[0]); + parent::__construct($environment); + } + + /** @return web.Routing */ + public function routes() { + + // Runtime context + $function= strtolower($this->app->getSimpleName()); + $region= $this->environment->variable('AWS_REGION') ?? self::REGION; + $functionArn= "arn:aws:lambda:{$region}:123456789012:function:{$function}"; + $headers= [ + 'Lambda-Runtime-Aws-Request-Id' => [UUID::randomUUID()->hashCode()], + 'Lambda-Runtime-Invoked-Function-Arn' => [$functionArn], + 'Lambda-Runtime-Trace-Id' => [self::TRACE], + 'Lambda-Runtime-Deadline-Ms' => [(time() + 900) * 1000], + ]; + $context= new Context($headers, $_ENV + [ + 'AWS_LAMBDA_FUNCTION_NAME' => $function, + 'AWS_REGION' => $region, + 'AWS_LOCAL' => true, + ]); + + // See https://github.com/awsdocs/aws-lambda-developer-guide/blob/main/sample-apps/nodejs-apig/event-v2.json + $lambda= function($req, $res, $inv) use($function, $context) { + $via= new RequestContext([ + 'accountId' => '123456789012', + 'apiId' => 'x17bf9mIws', + 'domainName' => 'x17bf9mIws.execute-api.test-local-1.amazonaws.com', + 'domainPrefix' => 'x17bf9mIws', + 'requestId' => 'JKJaXmPLvHcESHA=', + 'routeKey' => "ANY /{$function}-function-1G3XMPLZXVXYI", + 'stage' => 'default', + 'timeEpoch' => time() * 1000, + 'http' => [ + 'method' => $req->method(), + 'path' => $req->uri()->path(), + 'protocol' => 'HTTP/1.1', + 'sourceIp' => $req->header('Remote-Addr'), + 'userAgent' => $req->header('User-Agent'), + ] + ]); + return $inv->proceed($req->pass('context', $context)->pass('request', $via), $res); + }; + + return new Filters([$lambda], $this->app + ->newInstance(new Environment($this->environment->webroot(), Console::$out)) + ->routes($this->enviroment) + ); + } + + /** @return string */ + public function toString() { + return 'Lambda<'.$this->app->getName().'>'; + } +} \ No newline at end of file From 41995d8c5a531daf9fc0d78dde807e0a5fa2d672 Mon Sep 17 00:00:00 2001 From: Timm Friebe Date: Sat, 18 Nov 2023 12:26:33 +0100 Subject: [PATCH 2/4] Add response headers replicating the inconsistent casing AWS uses --- src/main/php/com/amazon/aws/lambda/Ws.class.php | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/main/php/com/amazon/aws/lambda/Ws.class.php b/src/main/php/com/amazon/aws/lambda/Ws.class.php index 845ed0e..89b6408 100755 --- a/src/main/php/com/amazon/aws/lambda/Ws.class.php +++ b/src/main/php/com/amazon/aws/lambda/Ws.class.php @@ -55,7 +55,7 @@ public function routes() { 'domainPrefix' => 'x17bf9mIws', 'requestId' => 'JKJaXmPLvHcESHA=', 'routeKey' => "ANY /{$function}-function-1G3XMPLZXVXYI", - 'stage' => 'default', + 'stage' => '$default', 'timeEpoch' => time() * 1000, 'http' => [ 'method' => $req->method(), @@ -65,6 +65,10 @@ public function routes() { 'userAgent' => $req->header('User-Agent'), ] ]); + + // Add response headers replicating the inconsistent casing AWS uses + $res->header('x-amzn-RequestId', $context->awsRequestId); + $res->header('X-Amzn-Trace-Id', $context->traceId); return $inv->proceed($req->pass('context', $context)->pass('request', $via), $res); }; From e48b3a4fbf5ae80a52a8f777ccc0f447fe6cf261 Mon Sep 17 00:00:00 2001 From: Timm Friebe Date: Sat, 18 Nov 2023 13:00:14 +0100 Subject: [PATCH 3/4] Add section "Development & testing" --- README.md | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 97ffe67..fd3a7e6 100755 --- a/README.md +++ b/README.md @@ -44,7 +44,24 @@ class Greet extends HttpApi { The request context is passed into a request value named *request* and contains a [RequestContext instance](https://github.com/xp-forge/lambda-ws#request-context). The [lambda context](https://github.com/xp-forge/lambda#context) is passed in *context*. -To run existing web applications, return an instance of your application subclass from the *routes()* method. This way, you can also test them locally using the `xp web` command. +To run existing web applications, return an instance of your `web.Application` subclass from the *routes()* method. + +Development & testing +--------------------- +To run the HTTP APIs locally, this library integrates with [xp-forge/web](https://github.com/xp-forge/web) via a wrapper: + +```bash +$ xp web com.amazon.aws.lambda.Ws Greet +@xp.web.srv.Standalone(HTTP @ peer.ServerSocket(Resource id #124 -> tcp://127.0.0.1:8080)) +Serving prod:Lambda[] > web.logging.ToConsole +════════════════════════════════════════════════════════════════════════ +> Server started: http://localhost:8080 in 0.057 seconds + Sat, 18 Nov 2023 12:19:32 +0100 - PID 18668; press Ctrl+C to exit + +# ... +``` + +By adding `-m develop`, these can be run in the development webserver. Setup and deployment -------------------- From 68c21a4aceb4f85622b8ad43ce87a25b939bf7aa Mon Sep 17 00:00:00 2001 From: Timm Friebe Date: Mon, 20 Nov 2023 19:58:32 +0100 Subject: [PATCH 4/4] Change class name to `xp.lambda.Web`, see xp-forge/web#104 --- .../aws/lambda/Ws.class.php => xp/lambda/Web.class.php} | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) rename src/main/php/{com/amazon/aws/lambda/Ws.class.php => xp/lambda/Web.class.php} (94%) diff --git a/src/main/php/com/amazon/aws/lambda/Ws.class.php b/src/main/php/xp/lambda/Web.class.php similarity index 94% rename from src/main/php/com/amazon/aws/lambda/Ws.class.php rename to src/main/php/xp/lambda/Web.class.php index 89b6408..b82e9e5 100755 --- a/src/main/php/com/amazon/aws/lambda/Ws.class.php +++ b/src/main/php/xp/lambda/Web.class.php @@ -1,12 +1,13 @@ -app->getName().'>'; + return nameof($this).'<'.$this->app->getName().'>'; } } \ No newline at end of file