From 423dfcda2c0c9867d870c0d34e6f442457d0668f Mon Sep 17 00:00:00 2001 From: Andy Hayden Date: Wed, 15 Jan 2020 17:30:00 -0800 Subject: [PATCH 1/2] Support clientContext and identity attributes on Context --- runtime/bootstrap | 35 +++++++++++++++++++++++++++++------ tests/handlers.ts | 2 +- tests/pad.ts | 8 +++++--- tests/server.ts | 5 +++++ tests/test_config2.json | 34 ++++++++++++++++++++++++++++++++++ 5 files changed, 74 insertions(+), 10 deletions(-) create mode 100644 tests/test_config2.json diff --git a/runtime/bootstrap b/runtime/bootstrap index b1064b3d..e66b1121 100755 --- a/runtime/bootstrap +++ b/runtime/bootstrap @@ -93,23 +93,40 @@ function investigate { echo " import { $HANDLER_NAME } from '$LAMBDA_TASK_ROOT/$HANDLER_FILE'; const INVOCATION = '${API_ROOT}invocation/'; +function tryParse(headers, headerName) { + const json = headers.get(headerName); + if (json) { + try { + return JSON.parse(json) + } catch (e) { + console.error( + 'Unable to parse header \'' + headerName + '\' value as JSON: ' + json) + } + } +} + while (true) { const next = await fetch(INVOCATION + 'next'); const headers = next.headers; - const reqId = headers.get('Lambda-Runtime-Aws-Request-Id'); + const reqId = headers.get('lambda-runtime-aws-request-id'); const context = { functionName: '$AWS_LAMBDA_FUNCTION_NAME', functionVersion: '$AWS_LAMBDA_FUNCTION_VERSION', invokedFunctionArn: headers.get('lambda-runtime-invoked-function-arn'), - memoryLimitInMB: $AWS_LAMBDA_FUNCTION_MEMORY_SIZE, + memoryLimitInMB: '$AWS_LAMBDA_FUNCTION_MEMORY_SIZE', awsRequestId: headers.get('lambda-runtime-aws-request-id'), logGroupName: '$AWS_LAMBDA_LOG_GROUP_NAME', logStreamName: '$AWS_LAMBDA_LOG_STREAM_NAME', - identity: undefined, - clientContext: undefined, + identity: tryParse(headers, 'lambda-runtime-cognito-identity'), + clientContext: tryParse(headers, 'lambda-runtime-client-context'), getRemainingTimeInMillis: function() { return Number(headers.get('lambda-runtime-deadline-ms')) - Date.now(); - } + }, + // FIXME: we add these for type compatibility with Definitely Typed. + callbackWaitsForEmptyEventLoop: undefined, + done: undefined, + fail: undefined, + succeed: undefined } let res; try { @@ -170,6 +187,12 @@ cp -R $LAMBDA_TASK_ROOT/$DENO_DIR/gen/. /tmp/deno_dir/gen &> /dev/null \ && cp -R $LAMBDA_TASK_ROOT/$DENO_DIR/LAMBDA_TASK_ROOT/. /tmp/deno_dir/gen/file$LAMBDA_TASK_ROOT &> /dev/null \ || echo "warn: unable to import '$DENO_DIR/' as DENO_DIR" -# FIXME remove DENO_FLAGS=DENO_FLAGS environment variable setting. +# FIXME remove DENO_FLAGS=DENO_FLAGS environment variable setting (used in testing only). DENO_DIR=/tmp/deno_dir DENO_FLAGS=$DENO_FLAGS NO_COLOR=true $SCRIPT_DIR/amz-deno run $DENO_FLAGS /tmp/runtime.js \ || investigate; + +# For debugging purposes of the bootstrap script itself it's useful to change the extension to /tmp/runtime.ts +# and run this code instead to get more verbose and type errors during testing. +# Note: on production you will see the verbose error message anyway in cloudwatch logs. +# DENO_DIR=/tmp/deno_dir DENO_FLAGS=$DENO_FLAGS NO_COLOR=true $SCRIPT_DIR/amz-deno run $DENO_FLAGS /tmp/runtime.ts &> /tmp/fail.out \ +# || error "error: $(cat /tmp/fail.out)" diff --git a/tests/handlers.ts b/tests/handlers.ts index e5e0558b..068926e9 100644 --- a/tests/handlers.ts +++ b/tests/handlers.ts @@ -23,7 +23,7 @@ export async function withContext( event: APIGatewayProxyEvent, context: Context ) { - return { name: context.functionName, awsRequestId: context.awsRequestId }; + return { name: context.functionName, awsRequestId: context.awsRequestId, clientContext: context.clientContext, identity: context.identity }; } // TODO add a test for this behavior. diff --git a/tests/pad.ts b/tests/pad.ts index 90d6dfbb..6788d271 100644 --- a/tests/pad.ts +++ b/tests/pad.ts @@ -9,10 +9,12 @@ export function handler(event, context) { export async function assertLock(event, context) { // assert --lock was passed + // Note: This is a file with external imports in order for -lock to be used. // FIXME remove this env hack and pull out the actual cli args from Deno itself. - // (we don't necessary need to set DENO_FLAGS for deno in bootstrap.) - if (Deno.env("DENO_FLAGS").includes("--lock=lock.json")) { + // (we shouldn't need to set DENO_FLAGS for deno in bootstrap.) + const flags: string = Deno.env("DENO_FLAGS")!; + if (/--lock=lock\.json/.test(flags)) { return {}; } - throw new Error("--lock not passed to deno run"); + throw new Error("--lock=lock.json not passed to deno run " + flags); } diff --git a/tests/server.ts b/tests/server.ts index 0e469332..1aa756fc 100644 --- a/tests/server.ts +++ b/tests/server.ts @@ -65,6 +65,11 @@ export async function serveEvents(testJson) { "lambda-runtime-aws-request-id": reqId.toString(), "lambda-runtime-deadline-ms": (Date.now() + 300000).toString() }); + if (testJson.headers) { + for (let [k, v] of Object.entries(testJson.headers)) { + headers.append(k, JSON.stringify(v)); + } + } await req.respond({ body: enc.encode(JSON.stringify(e.value)), headers diff --git a/tests/test_config2.json b/tests/test_config2.json new file mode 100644 index 00000000..6cd62aa3 --- /dev/null +++ b/tests/test_config2.json @@ -0,0 +1,34 @@ +{ + "env": { "_HANDLER": "handlers.withContext" }, + "events": [{ "hello": "deno" }], + "expected": [ + { + "status": "ok", + "content": "{\"name\":\"test\",\"awsRequestId\":\"1\",\"clientContext\":{\"client\":{\"installationId\":\"installationId\",\"appTitle\":\"appTitle\",\"appVersionName\":\"versionName\",\"appVersionCode\":\"versionCode\",\"appPackageName\":\"packageName\"},\"env\":{\"platformVersion\":\"platformVersion\",\"platform\":\"platform\",\"make\":\"make\",\"model\":\"model\",\"locale\":\"locale\"}},\"identity\":{\"cognitoIdentityId\":\"us-east-1:605249a8-8fc1-40ed-bf89-23bc74ecc232\",\"cognitoIdentityPoolId\":\"us-east-1:1699ebc0-7900-4099-b910-2df94f52a030\"}}" + } + ], + "files": ["handlers.ts"], + "layer": "deno-lambda-layer.zip", + "headers": { + "Lambda-Runtime-Client-Context": { + "client": { + "installationId": "installationId", + "appTitle": "appTitle", + "appVersionName": "versionName", + "appVersionCode": "versionCode", + "appPackageName": "packageName" + }, + "env": { + "platformVersion": "platformVersion", + "platform": "platform", + "make": "make", + "model": "model", + "locale": "locale" + } + }, + "Lambda-Runtime-Cognito-Identity": { + "cognitoIdentityId": "us-east-1:605249a8-8fc1-40ed-bf89-23bc74ecc232", + "cognitoIdentityPoolId": "us-east-1:1699ebc0-7900-4099-b910-2df94f52a030" + } + } +} From 1d4f2e74095e2b2a6d4e8ddd61c35cdc87289d53 Mon Sep 17 00:00:00 2001 From: Andy Hayden Date: Wed, 15 Jan 2020 17:32:50 -0800 Subject: [PATCH 2/2] deno fmt --- tests/decorate.ts | 2 +- tests/handlers.ts | 7 ++++++- tests/importmap.json | 8 ++++---- tests/test_importmap.json | 5 ++++- tests/tsconfig.json | 2 +- 5 files changed, 16 insertions(+), 8 deletions(-) diff --git a/tests/decorate.ts b/tests/decorate.ts index 4c294943..3b9ecea6 100644 --- a/tests/decorate.ts +++ b/tests/decorate.ts @@ -1,4 +1,4 @@ -function decorate(target) { } +function decorate(target) {} @decorate class Foo {} diff --git a/tests/handlers.ts b/tests/handlers.ts index 068926e9..f3ae29a9 100644 --- a/tests/handlers.ts +++ b/tests/handlers.ts @@ -23,7 +23,12 @@ export async function withContext( event: APIGatewayProxyEvent, context: Context ) { - return { name: context.functionName, awsRequestId: context.awsRequestId, clientContext: context.clientContext, identity: context.identity }; + return { + name: context.functionName, + awsRequestId: context.awsRequestId, + clientContext: context.clientContext, + identity: context.identity + }; } // TODO add a test for this behavior. diff --git a/tests/importmap.json b/tests/importmap.json index c037f535..c77c59b0 100644 --- a/tests/importmap.json +++ b/tests/importmap.json @@ -1,5 +1,5 @@ { - "imports": { - "std/": "https://deno.land/std/" - } -} \ No newline at end of file + "imports": { + "std/": "https://deno.land/std/" + } +} diff --git a/tests/test_importmap.json b/tests/test_importmap.json index 443af596..48e431b3 100644 --- a/tests/test_importmap.json +++ b/tests/test_importmap.json @@ -1,5 +1,8 @@ { - "env": { "_HANDLER": "importmap.handler", "DENO_IMPORTMAP": "importmap.json" }, + "env": { + "_HANDLER": "importmap.handler", + "DENO_IMPORTMAP": "importmap.json" + }, "events": [{ "hello": "deno" }], "expected": [ { diff --git a/tests/tsconfig.json b/tests/tsconfig.json index 14ad0917..6dacb8cc 100644 --- a/tests/tsconfig.json +++ b/tests/tsconfig.json @@ -3,4 +3,4 @@ "experimentalDecorators": true, "emitDecoratorMetadata": true } -} \ No newline at end of file +}