();
+ for(SQSMessage msg : event.getRecords()){
+ messagesFound.add(msg.getBody());
+ }
+ return messagesFound;
+ }
+}
diff --git a/sample-apps/java-events/src/main/java/example/Util.java b/sample-apps/java-events/src/main/java/example/Util.java
deleted file mode 100644
index b5e87294..00000000
--- a/sample-apps/java-events/src/main/java/example/Util.java
+++ /dev/null
@@ -1,20 +0,0 @@
-package example;
-
-import com.amazonaws.services.lambda.runtime.Context;
-import com.amazonaws.services.lambda.runtime.LambdaLogger;
-
-import com.google.gson.Gson;
-
-public class Util {
-
- public static void logEnvironment(Object event, Context context, Gson gson)
- {
- LambdaLogger logger = context.getLogger();
- // log execution details
- logger.log("ENVIRONMENT VARIABLES: " + gson.toJson(System.getenv()));
- logger.log("CONTEXT: " + gson.toJson(context));
- // log event details
- logger.log("EVENT: " + gson.toJson(event));
- logger.log("EVENT TYPE: " + event.getClass().toString());
- }
-}
\ No newline at end of file
diff --git a/sample-apps/java-events/src/test/java/example/InvokeTest.java b/sample-apps/java-events/src/test/java/example/InvokeTest.java
index cb7d949a..881519cc 100644
--- a/sample-apps/java-events/src/test/java/example/InvokeTest.java
+++ b/sample-apps/java-events/src/test/java/example/InvokeTest.java
@@ -1,33 +1,205 @@
package example;
import static org.junit.jupiter.api.Assertions.assertEquals;
-import static org.junit.jupiter.api.Assertions.assertTrue;
-import org.junit.jupiter.api.Test;
+import static org.junit.jupiter.api.Assertions.assertNotNull;
import com.amazonaws.services.lambda.runtime.Context;
-import com.amazonaws.services.lambda.runtime.RequestHandler;
-import com.amazonaws.services.lambda.runtime.events.APIGatewayV2ProxyRequestEvent;
-import com.amazonaws.services.lambda.runtime.events.APIGatewayV2ProxyResponseEvent;
+import com.amazonaws.services.lambda.runtime.events.APIGatewayProxyRequestEvent;
+import com.amazonaws.services.lambda.runtime.events.APIGatewayProxyResponseEvent;
+import com.amazonaws.services.lambda.runtime.events.APIGatewayV2HTTPEvent;
+import com.amazonaws.services.lambda.runtime.events.APIGatewayV2HTTPResponse;
+import com.amazonaws.services.lambda.runtime.events.CloudFrontEvent;
+import com.amazonaws.services.lambda.runtime.events.CloudWatchLogsEvent;
+import com.amazonaws.services.lambda.runtime.events.CodeCommitEvent;
+import com.amazonaws.services.lambda.runtime.events.CognitoEvent;
+import com.amazonaws.services.lambda.runtime.events.ConfigEvent;
+import com.amazonaws.services.lambda.runtime.events.DynamodbEvent;
+import com.amazonaws.services.lambda.runtime.events.KinesisEvent;
+import com.amazonaws.services.lambda.runtime.events.KinesisFirehoseEvent;
+import com.amazonaws.services.lambda.runtime.events.LexEvent;
+import com.amazonaws.services.lambda.runtime.events.S3Event;
+import com.amazonaws.services.lambda.runtime.events.SNSEvent;
+import com.amazonaws.services.lambda.runtime.events.SQSEvent;
+import com.amazonaws.services.lambda.runtime.events.ScheduledEvent;
+import com.amazonaws.services.lambda.runtime.tests.annotations.Event;
+import com.google.gson.Gson;
+import com.google.gson.GsonBuilder;
+
+import java.util.List;
+
+import org.junit.jupiter.params.ParameterizedTest;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-import java.util.List;
-import java.util.ArrayList;
-import java.util.HashMap;
-
class InvokeTest {
+
private static final Logger logger = LoggerFactory.getLogger(InvokeTest.class);
+ Gson gson = new GsonBuilder().setPrettyPrinting().create();
+
+ @ParameterizedTest
+ @Event(value = "events/apigateway-v1.json", type = APIGatewayProxyRequestEvent.class)
+ void testApiGatewayV1(APIGatewayProxyRequestEvent event) {
+ logger.info("Invoke TEST - ApiGatewayV1");
+ Context context = new TestContext();
+ HandlerApiGatewayV1 handler = new HandlerApiGatewayV1();
+ APIGatewayProxyResponseEvent response = handler.handleRequest(event, context);
+ String expected = "" + "Hello world!" + "" +
+ "Welcome
Page generated by a Lambda function.
" +
+ "";
+ assertEquals(expected, response.getBody());
+ }
+
+ @ParameterizedTest
+ @Event(value = "events/apigateway-v2.json", type = APIGatewayV2HTTPEvent.class)
+ void testApiGatewayV2(APIGatewayV2HTTPEvent event) {
+ logger.info("Invoke TEST - ApiGatewayV1");
+ Context context = new TestContext();
+ HandlerApiGatewayV2 handler = new HandlerApiGatewayV2();
+ APIGatewayV2HTTPResponse response = handler.handleRequest(event, context);
+ String expected = "" + "Hello world!" + "" +
+ "Welcome
Page generated by a Lambda function.
" +
+ "";
+ assertEquals(expected, response.getBody());
+ }
+
+ @ParameterizedTest
+ @Event(value = "events/cloudfront.json", type = CloudFrontEvent.class)
+ void testCloudFront(CloudFrontEvent event) {
+ logger.info("Invoke TEST - CloudFront");
+ Context context = new TestContext();
+ HandlerCloudFront handler = new HandlerCloudFront();
+ List response = handler.handleRequest(event, context);
+ assertEquals(1, response.size());
+ assertEquals("/picture.jpg", response.get(0));
+ }
+
+ @ParameterizedTest
+ @Event(value = "events/codecommit-push.json", type = CodeCommitEvent.class)
+ void testCodeCommit(CodeCommitEvent event) {
+ logger.info("Invoke TEST - CodeCommit");
+ Context context = new TestContext();
+ HandlerCodeCommit handler = new HandlerCodeCommit();
+ List response = handler.handleRequest(event, context);
+ assertEquals(1, response.size());
+ assertEquals("5c4ef1049f1d27deadbeeff313e0730018be182b", response.get(0));
+ }
+
+ @ParameterizedTest
+ @Event(value = "events/cognito-sync.json", type = CognitoEvent.class)
+ void testCognito(CognitoEvent event) {
+ logger.info("Invoke TEST - Cognito");
+ Context context = new TestContext();
+ HandlerCognito handler = new HandlerCognito();
+ List response = handler.handleRequest(event, context);
+ assertEquals(2, response.size());
+ assertEquals("replace", response.get(0));
+ assertEquals("replace", response.get(1));
+ }
+
+ @ParameterizedTest
+ @Event(value = "events/config-rule.json", type = ConfigEvent.class)
+ void testConfig(ConfigEvent event) {
+ logger.info("Invoke TEST - Config");
+ Context context = new TestContext();
+ HandlerConfig handler = new HandlerConfig();
+ String response = handler.handleRequest(event, context);
+ assertEquals("arn:aws:config:ca-central-1:123456789012:config-rule/config-rule-0123456", response);
+ }
- @Test
- void invokeTest() {
- logger.info("Invoke TEST");
- APIGatewayV2ProxyRequestEvent event = new APIGatewayV2ProxyRequestEvent();
+ @ParameterizedTest
+ @Event(value = "events/cloudwatch-scheduled.json", type = ScheduledEvent.class)
+ void testCWEvents(ScheduledEvent event) {
+ logger.info("Invoke TEST - CWEvents");
Context context = new TestContext();
- String requestId = context.getAwsRequestId();
- Handler handler = new Handler();
- APIGatewayV2ProxyResponseEvent result = handler.handleRequest(event, context);
- assertEquals(result.getStatusCode(),200);
+ HandlerCWEvents handler = new HandlerCWEvents();
+ List response = handler.handleRequest(event, context);
+ assertEquals(1, response.size());
+ assertEquals("arn:aws:events:us-east-2:123456789012:rule/my-rule", response.get(0));
}
+ @ParameterizedTest
+ @Event(value = "events/cloudwatch-logs.json", type = CloudWatchLogsEvent.class)
+ void testCWLogs(CloudWatchLogsEvent event) {
+ logger.info("Invoke TEST - CWLogs");
+ Context context = new TestContext();
+ HandlerCWLogs handler = new HandlerCWLogs();
+ String response = handler.handleRequest(event, context);
+ assertNotNull(response);
+ }
+
+ @ParameterizedTest
+ @Event(value = "events/dynamodb-record.json", type = DynamodbEvent.class)
+ void testDynamoDB(DynamodbEvent event) {
+ logger.info("Invoke TEST - DynamoDB");
+ Context context = new TestContext();
+ HandlerDynamoDB handler = new HandlerDynamoDB();
+ List response = handler.handleRequest(event, context);
+ assertEquals(2, response.size());
+ assertEquals("INSERT", response.get(0));
+ assertEquals("MODIFY", response.get(1));
+ }
+
+ @ParameterizedTest
+ @Event(value = "events/firehose-record.json", type = KinesisFirehoseEvent.class)
+ void testFirehose(KinesisFirehoseEvent event) {
+ logger.info("Invoke TEST - Firehose");
+ Context context = new TestContext();
+ HandlerFirehose handler = new HandlerFirehose();
+ List response = handler.handleRequest(event, context);
+ assertEquals(1, response.size());
+ assertEquals("49546986683135544286507457936321625675700192471156785154", response.get(0));
+ }
+
+ @ParameterizedTest
+ @Event(value = "events/kinesis-record.json", type = KinesisEvent.class)
+ void testKinesis(KinesisEvent event) {
+ logger.info("Invoke TEST - Kinesis");
+ Context context = new TestContext();
+ HandlerKinesis handler = new HandlerKinesis();
+ List response = handler.handleRequest(event, context);
+ assertEquals(2, response.size());
+ }
+
+ @ParameterizedTest
+ @Event(value = "events/lex-flowers.json", type = LexEvent.class)
+ void testLex(LexEvent event) {
+ logger.info("Invoke TEST - Lex");
+ Context context = new TestContext();
+ HandlerLex handler = new HandlerLex();
+ String response = handler.handleRequest(event, context);
+ assertEquals("OrderFlowers", response);
+ }
+
+ @ParameterizedTest
+ @Event(value = "events/s3-notification.json", type = S3Event.class)
+ void testS3(S3Event event) {
+ logger.info("Invoke TEST - S3");
+ Context context = new TestContext();
+ HandlerS3 handler = new HandlerS3();
+ String response = handler.handleRequest(event, context);
+ assertEquals("BUCKET_NAME/inbound/sample-java-s3.png", response);
+ }
+
+ @ParameterizedTest
+ @Event(value = "events/sns-notification.json", type = SNSEvent.class)
+ void testSNS(SNSEvent event) {
+ logger.info("Invoke TEST - SNS");
+ Context context = new TestContext();
+ HandlerSNS handler = new HandlerSNS();
+ List response = handler.handleRequest(event, context);
+ assertEquals(1, response.size());
+ assertEquals("Updated and expanded documentation for using Lambda with API Gateway, including support for HTTP APIs.", response.get(0));
+ }
+
+ @ParameterizedTest
+ @Event(value = "events/sqs-record.json", type = SQSEvent.class)
+ void testSQS(SQSEvent event) {
+ logger.info("Invoke TEST - SQS");
+ Context context = new TestContext();
+ HandlerSQS handler = new HandlerSQS();
+ List response = handler.handleRequest(event, context);
+ assertEquals(1, response.size());
+ assertEquals("Hello from SQS!", response.get(0));
+ }
}
diff --git a/sample-apps/java-events/template-mvn.yml b/sample-apps/java-events/template-mvn.yml
index 5fdfbe50..1e17bcbd 100644
--- a/sample-apps/java-events/template-mvn.yml
+++ b/sample-apps/java-events/template-mvn.yml
@@ -6,15 +6,15 @@ Resources:
Type: AWS::Serverless::Function
Properties:
CodeUri: target/java-events-1.0-SNAPSHOT.jar
- Handler: example.Handler
- Runtime: java8
+ Handler: example.HandlerSQS
+ Runtime: java11
Description: Java function
- MemorySize: 512
+ MemorySize: 2048
Timeout: 10
# Function's execution role
Policies:
- AWSLambdaBasicExecutionRole
- - AWSLambdaReadOnlyAccess
+ - AWSLambda_ReadOnlyAccess
- AWSXrayWriteOnlyAccess
- AWSLambdaVPCAccessExecutionRole
Tracing: Active
diff --git a/sample-apps/java-events/template.yml b/sample-apps/java-events/template.yml
index def7925a..4b8bb3d8 100644
--- a/sample-apps/java-events/template.yml
+++ b/sample-apps/java-events/template.yml
@@ -6,15 +6,15 @@ Resources:
Type: AWS::Serverless::Function
Properties:
CodeUri: build/distributions/java-events.zip
- Handler: example.Handler
- Runtime: java8
+ Handler: example.HandlerSQS
+ Runtime: java11
Description: Java function
- MemorySize: 512
+ MemorySize: 2048
Timeout: 10
# Function's execution role
Policies:
- AWSLambdaBasicExecutionRole
- - AWSLambdaReadOnlyAccess
+ - AWSLambda_ReadOnlyAccess
- AWSXrayWriteOnlyAccess
- AWSLambdaVPCAccessExecutionRole
Tracing: Active
diff --git a/sample-apps/layer-java/function/pom.xml b/sample-apps/layer-java/function/pom.xml
new file mode 100644
index 00000000..607f4152
--- /dev/null
+++ b/sample-apps/layer-java/function/pom.xml
@@ -0,0 +1,59 @@
+
+ 4.0.0
+ com.example
+ layer-java-function
+ jar
+ 1.0-SNAPSHOT
+ layer-java-function
+
+
+ UTF-8
+ 21
+ 21
+
+
+
+
+ com.example
+ layer-java-layer
+ 1.0-SNAPSHOT
+ provided
+
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-compiler-plugin
+ 3.13.0
+
+ 21
+ 21
+ 21
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/sample-apps/layer-java/function/src/main/java/example/F1Car.java b/sample-apps/layer-java/function/src/main/java/example/F1Car.java
new file mode 100644
index 00000000..06c77d22
--- /dev/null
+++ b/sample-apps/layer-java/function/src/main/java/example/F1Car.java
@@ -0,0 +1,33 @@
+package example;
+
+import com.fasterxml.jackson.annotation.JsonCreator;
+import com.fasterxml.jackson.annotation.JsonProperty;
+
+public class F1Car {
+
+ private String team;
+ private String driver;
+
+ @JsonCreator
+ public F1Car(@JsonProperty("team") String team,
+ @JsonProperty("driver") String driver) {
+ this.team = team;
+ this.driver = driver;
+ }
+
+ public String getTeam() {
+ return team;
+ }
+
+ public void setTeam(String team) {
+ this.team = team;
+ }
+
+ public String getDriver() {
+ return driver;
+ }
+
+ public void setDriver(String driver) {
+ this.driver = driver;
+ }
+}
diff --git a/sample-apps/layer-java/function/src/main/java/example/Handler.java b/sample-apps/layer-java/function/src/main/java/example/Handler.java
new file mode 100644
index 00000000..1ff1c4e9
--- /dev/null
+++ b/sample-apps/layer-java/function/src/main/java/example/Handler.java
@@ -0,0 +1,22 @@
+package example;
+
+import com.amazonaws.services.lambda.runtime.Context;
+import com.fasterxml.jackson.databind.ObjectMapper;
+
+import java.io.IOException;
+import java.util.Map;
+
+public class Handler {
+
+ public String handleRequest(Map input, Context context) throws IOException {
+ // Parse the input JSON
+ ObjectMapper objectMapper = new ObjectMapper();
+ F1Car f1Car = objectMapper.readValue(objectMapper.writeValueAsString(input), F1Car.class);
+
+ StringBuilder finalString = new StringBuilder();
+ finalString.append(f1Car.getDriver());
+ finalString.append(" is a driver for team ");
+ finalString.append(f1Car.getTeam());
+ return finalString.toString();
+ }
+}
diff --git a/sample-apps/layer-java/layer/1-install.sh b/sample-apps/layer-java/layer/1-install.sh
new file mode 100755
index 00000000..b39292ee
--- /dev/null
+++ b/sample-apps/layer-java/layer/1-install.sh
@@ -0,0 +1 @@
+mvn clean install
diff --git a/sample-apps/layer-java/layer/2-package.sh b/sample-apps/layer-java/layer/2-package.sh
new file mode 100755
index 00000000..f7a9c67b
--- /dev/null
+++ b/sample-apps/layer-java/layer/2-package.sh
@@ -0,0 +1,4 @@
+mkdir java
+mkdir java/lib
+cp -r target/layer-java-layer-1.0-SNAPSHOT.jar java/lib/
+zip -r layer_content.zip java
diff --git a/sample-apps/layer-java/layer/pom.xml b/sample-apps/layer-java/layer/pom.xml
new file mode 100644
index 00000000..ccfc9025
--- /dev/null
+++ b/sample-apps/layer-java/layer/pom.xml
@@ -0,0 +1,62 @@
+
+ 4.0.0
+ com.example
+ layer-java-layer
+ jar
+ 1.0-SNAPSHOT
+ layer-java-layer
+
+
+ UTF-8
+ 21
+ 21
+
+
+
+
+ com.amazonaws
+ aws-lambda-java-core
+ 1.2.3
+
+
+
+ com.fasterxml.jackson.core
+ jackson-databind
+ 2.17.0
+
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-compiler-plugin
+ 3.13.0
+
+ 21
+ 21
+ 21
+
+
+
+
+ org.apache.maven.plugins
+ maven-shade-plugin
+ 3.5.2
+
+ false
+
+
+
+ package
+
+ shade
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/sample-apps/layer-nodejs/function-js/index.mjs b/sample-apps/layer-nodejs/function-js/index.mjs
new file mode 100644
index 00000000..d94c925c
--- /dev/null
+++ b/sample-apps/layer-nodejs/function-js/index.mjs
@@ -0,0 +1,17 @@
+import _ from "lodash"
+
+export const handler = async (event) => {
+
+ var users = [
+ { 'user': 'Carlos', 'active': true },
+ { 'user': 'Gil-dong', 'active': false },
+ { 'user': 'Pat', 'active': false }
+ ];
+
+ let out = _.findLastIndex(users, function(o) { return o.user == 'Pat'; });
+ const response = {
+ statusCode: 200,
+ body: JSON.stringify(out + ", " + users[out].user),
+ };
+ return response;
+};
diff --git a/sample-apps/layer-nodejs/function-ts/index.ts b/sample-apps/layer-nodejs/function-ts/index.ts
new file mode 100644
index 00000000..83ecea6e
--- /dev/null
+++ b/sample-apps/layer-nodejs/function-ts/index.ts
@@ -0,0 +1,28 @@
+import { Handler } from 'aws-lambda';
+import * as _ from 'lodash';
+
+type User = {
+ user: string;
+ active: boolean;
+}
+
+type UserResult = {
+ statusCode: number;
+ body: string;
+}
+
+const users: User[] = [
+ { 'user': 'Carlos', 'active': true },
+ { 'user': 'Gil-dong', 'active': false },
+ { 'user': 'Pat', 'active': false }
+];
+
+export const handler: Handler = async (): Promise => {
+
+ let out = _.findLastIndex(users, (user: User) => { return user.user == 'Pat'; });
+ const response = {
+ statusCode: 200,
+ body: JSON.stringify(out + ", " + users[out].user),
+ };
+ return response;
+};
diff --git a/sample-apps/layer-nodejs/function-ts/package.json b/sample-apps/layer-nodejs/function-ts/package.json
new file mode 100644
index 00000000..1857273d
--- /dev/null
+++ b/sample-apps/layer-nodejs/function-ts/package.json
@@ -0,0 +1,20 @@
+{
+ "name": "lambda-typescript-layer-example",
+ "version": "1.0.0",
+ "main": "dist/index.js",
+ "scripts": {
+ "prebuild": "rm -rf dist",
+ "build": "tsc index.ts --module nodenext --lib es2020 --outDir dist/",
+ "postbuild": "cd dist && zip -r index.zip index.js",
+ "test": "echo \"Error: no test specified\" && exit 1"
+ },
+ "author": "",
+ "license": "MIT-0",
+ "description": "",
+ "devDependencies": {
+ "@types/aws-lambda": "^8.10.145",
+ "@types/lodash": "^4.17.9",
+ "lodash": "^4.17.21",
+ "typescript": "^5.6.2"
+ }
+}
diff --git a/sample-apps/layer-nodejs/layer/1-install.sh b/sample-apps/layer-nodejs/layer/1-install.sh
new file mode 100755
index 00000000..9c3be6f5
--- /dev/null
+++ b/sample-apps/layer-nodejs/layer/1-install.sh
@@ -0,0 +1 @@
+npm install .
diff --git a/sample-apps/layer-nodejs/layer/2-package.sh b/sample-apps/layer-nodejs/layer/2-package.sh
new file mode 100755
index 00000000..e8a5defc
--- /dev/null
+++ b/sample-apps/layer-nodejs/layer/2-package.sh
@@ -0,0 +1,3 @@
+mkdir -p nodejs/node20
+cp -r node_modules nodejs/node20/
+zip -r layer_content.zip nodejs
diff --git a/sample-apps/layer-nodejs/layer/package.json b/sample-apps/layer-nodejs/layer/package.json
new file mode 100644
index 00000000..d2229f35
--- /dev/null
+++ b/sample-apps/layer-nodejs/layer/package.json
@@ -0,0 +1,14 @@
+{
+ "name": "layer",
+ "version": "1.0.0",
+ "main": "index.js",
+ "scripts": {
+ "test": "echo \"Error: no test specified\" && exit 1"
+ },
+ "author": "",
+ "license": "MIT-0",
+ "description": "",
+ "dependencies": {
+ "lodash": "4.17.21"
+ }
+}
diff --git a/sample-apps/layer-python/function-numpy/lambda_function.py b/sample-apps/layer-python/function-numpy/lambda_function.py
new file mode 100644
index 00000000..f245743f
--- /dev/null
+++ b/sample-apps/layer-python/function-numpy/lambda_function.py
@@ -0,0 +1,12 @@
+import json
+import numpy as np
+
+def lambda_handler(event, context):
+
+ x = np.arange(15, dtype=np.int64).reshape(3, 5)
+ print(x)
+
+ return {
+ 'statusCode': 200,
+ 'body': json.dumps('Hello from Lambda!')
+ }
diff --git a/sample-apps/layer-python/function/lambda_function.py b/sample-apps/layer-python/function/lambda_function.py
new file mode 100644
index 00000000..11ef4b5e
--- /dev/null
+++ b/sample-apps/layer-python/function/lambda_function.py
@@ -0,0 +1,9 @@
+import requests
+
+def lambda_handler(event, context):
+ print(f"Version of requests library: {requests.__version__}")
+ request = requests.get('https://api.github.com/')
+ return {
+ 'statusCode': request.status_code,
+ 'body': request.text
+ }
diff --git a/sample-apps/layer-python/layer-numpy/1-install.sh b/sample-apps/layer-python/layer-numpy/1-install.sh
new file mode 100755
index 00000000..43172827
--- /dev/null
+++ b/sample-apps/layer-python/layer-numpy/1-install.sh
@@ -0,0 +1,3 @@
+python3.11 -m venv create_layer
+source create_layer/bin/activate
+pip install -r requirements.txt --platform=manylinux2014_x86_64 --only-binary=:all: --target ./create_layer/lib/python3.11/site-packages
diff --git a/sample-apps/layer-python/layer-numpy/2-package.sh b/sample-apps/layer-python/layer-numpy/2-package.sh
new file mode 100755
index 00000000..e552d783
--- /dev/null
+++ b/sample-apps/layer-python/layer-numpy/2-package.sh
@@ -0,0 +1,3 @@
+mkdir python
+cp -r create_layer/lib python/
+zip -r layer_content.zip python
\ No newline at end of file
diff --git a/sample-apps/layer-python/layer-numpy/requirements.txt b/sample-apps/layer-python/layer-numpy/requirements.txt
new file mode 100644
index 00000000..d4db0621
--- /dev/null
+++ b/sample-apps/layer-python/layer-numpy/requirements.txt
@@ -0,0 +1 @@
+https://files.pythonhosted.org/packages/3a/d0/edc009c27b406c4f9cbc79274d6e46d634d139075492ad055e3d68445925/numpy-1.26.4-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
diff --git a/sample-apps/layer-python/layer/1-install.sh b/sample-apps/layer-python/layer/1-install.sh
new file mode 100755
index 00000000..c9d93b81
--- /dev/null
+++ b/sample-apps/layer-python/layer/1-install.sh
@@ -0,0 +1,3 @@
+python3.13 -m venv create_layer
+source create_layer/bin/activate
+pip install -r requirements.txt
diff --git a/sample-apps/layer-python/layer/2-package.sh b/sample-apps/layer-python/layer/2-package.sh
new file mode 100755
index 00000000..b720b012
--- /dev/null
+++ b/sample-apps/layer-python/layer/2-package.sh
@@ -0,0 +1,3 @@
+mkdir python
+cp -r create_layer/lib python/
+zip -r layer_content.zip python
diff --git a/sample-apps/layer-python/layer/requirements.txt b/sample-apps/layer-python/layer/requirements.txt
new file mode 100644
index 00000000..2c24336e
--- /dev/null
+++ b/sample-apps/layer-python/layer/requirements.txt
@@ -0,0 +1 @@
+requests==2.31.0
diff --git a/sample-apps/layer-ruby/function/lambda_function.rb b/sample-apps/layer-ruby/function/lambda_function.rb
new file mode 100644
index 00000000..2c6d85d3
--- /dev/null
+++ b/sample-apps/layer-ruby/function/lambda_function.rb
@@ -0,0 +1,8 @@
+require 'json'
+require 'tzinfo'
+
+def lambda_handler(event:, context:)
+ tz = TZInfo::Timezone.get('America/New_York')
+ { statusCode: 200, body: tz.to_local(Time.utc(2018, 2, 1, 12, 30, 0)) }
+end
+
diff --git a/sample-apps/layer-ruby/layer/1-install.sh b/sample-apps/layer-ruby/layer/1-install.sh
new file mode 100755
index 00000000..eaf29ac1
--- /dev/null
+++ b/sample-apps/layer-ruby/layer/1-install.sh
@@ -0,0 +1,3 @@
+bundle config set --local path 'vendor/bundle'
+bundle install
+
diff --git a/sample-apps/layer-ruby/layer/2-package.sh b/sample-apps/layer-ruby/layer/2-package.sh
new file mode 100755
index 00000000..305a5b7b
--- /dev/null
+++ b/sample-apps/layer-ruby/layer/2-package.sh
@@ -0,0 +1,3 @@
+mkdir -p ruby/gems/3.3.0
+cp -r vendor/bundle/ruby/3.3.0/* ruby/gems/3.3.0/
+zip -r layer_content.zip ruby
diff --git a/sample-apps/layer-ruby/layer/Gemfile b/sample-apps/layer-ruby/layer/Gemfile
new file mode 100644
index 00000000..64ad6202
--- /dev/null
+++ b/sample-apps/layer-ruby/layer/Gemfile
@@ -0,0 +1,5 @@
+# frozen_string_literal: true
+
+source "https://rubygems.org"
+
+gem "tzinfo"
diff --git a/sample-apps/list-manager/1-create-bucket.sh b/sample-apps/list-manager/1-create-bucket.sh
deleted file mode 100755
index 042ebe32..00000000
--- a/sample-apps/list-manager/1-create-bucket.sh
+++ /dev/null
@@ -1,6 +0,0 @@
-#!/bin/bash
-set -eo pipefail
-BUCKET_ID=$(dd if=/dev/random bs=8 count=1 2>/dev/null | od -An -tx1 | tr -d ' \t\n')
-BUCKET_NAME=lambda-artifacts-$BUCKET_ID
-echo $BUCKET_NAME > bucket-name.txt
-aws s3 mb s3://$BUCKET_NAME
diff --git a/sample-apps/list-manager/2-create-dbpasswordsecret.sh b/sample-apps/list-manager/2-create-dbpasswordsecret.sh
deleted file mode 100755
index 10e3f236..00000000
--- a/sample-apps/list-manager/2-create-dbpasswordsecret.sh
+++ /dev/null
@@ -1,4 +0,0 @@
-#!/bin/bash
-set -eo pipefail
-DB_PASSWORD=$(dd if=/dev/random bs=8 count=1 2>/dev/null | od -An -tx1 | tr -d ' \t\n')
-aws secretsmanager create-secret --name list-manager --description "List-manager database password" --secret-string "{\"password\":\"$DB_PASSWORD\"}"
diff --git a/sample-apps/list-manager/3-deploy-vpc.sh b/sample-apps/list-manager/3-deploy-vpc.sh
deleted file mode 100755
index 69360e53..00000000
--- a/sample-apps/list-manager/3-deploy-vpc.sh
+++ /dev/null
@@ -1,3 +0,0 @@
-#!/bin/bash
-set -eo pipefail
-aws cloudformation deploy --template-file template-vpcrds.yml --stack-name list-manager-vpc
diff --git a/sample-apps/list-manager/4-deploy.sh b/sample-apps/list-manager/4-deploy.sh
deleted file mode 100755
index 599b815c..00000000
--- a/sample-apps/list-manager/4-deploy.sh
+++ /dev/null
@@ -1,6 +0,0 @@
-#!/bin/bash
-set -eo pipefail
-ARTIFACT_BUCKET=$(cat bucket-name.txt)
-cd lib/nodejs && npm install && cd ../../
-aws cloudformation package --template-file template.yml --s3-bucket $ARTIFACT_BUCKET --output-template-file out.yml
-aws cloudformation deploy --template-file out.yml --stack-name list-manager --capabilities CAPABILITY_NAMED_IAM
diff --git a/sample-apps/list-manager/5-create-dbtable.sh b/sample-apps/list-manager/5-create-dbtable.sh
deleted file mode 100755
index 213be7fb..00000000
--- a/sample-apps/list-manager/5-create-dbtable.sh
+++ /dev/null
@@ -1,4 +0,0 @@
-#!/bin/bash
-set -eo pipefail
-FUNCTION=$(aws cloudformation describe-stack-resource --stack-name list-manager --logical-resource-id dbadmin --query 'StackResourceDetail.PhysicalResourceId' --output text)
-aws lambda invoke --function-name $FUNCTION --payload file://events/db-create-table.json out.json
diff --git a/sample-apps/list-manager/6-invoke.sh b/sample-apps/list-manager/6-invoke.sh
deleted file mode 100755
index 5d507a48..00000000
--- a/sample-apps/list-manager/6-invoke.sh
+++ /dev/null
@@ -1,10 +0,0 @@
-#!/bin/bash
-set -eo pipefail
-FUNCTION=$(aws cloudformation describe-stack-resource --stack-name list-manager --logical-resource-id processor --query 'StackResourceDetail.PhysicalResourceId' --output text)
-
-while true; do
- aws lambda invoke --function-name $FUNCTION --payload file://events/kinesis.json out.json
- cat out.json
- echo ""
- sleep 2
-done
diff --git a/sample-apps/list-manager/7-put-records.sh b/sample-apps/list-manager/7-put-records.sh
deleted file mode 100755
index bdd7637b..00000000
--- a/sample-apps/list-manager/7-put-records.sh
+++ /dev/null
@@ -1,7 +0,0 @@
-#!/bin/bash
-set -eo pipefail
-STREAM=$(aws cloudformation describe-stack-resource --stack-name list-manager --logical-resource-id stream --query 'StackResourceDetail.PhysicalResourceId' --output text)
-aws kinesis put-record --stream-name $STREAM --data '{"title": "favorite movies", "user": "rdlysct", "type": "rank", "entries": {"blade runner": 2, "the empire strikes back": 3, "alien": 1}}' --partition-key 0
-aws kinesis put-record --stream-name $STREAM --data '{"title": "stats", "user": "beth", "type": "tally", "entries": {"xp": 25}}' --partition-key 0
-aws kinesis put-record --stream-name $STREAM --data '{"title": "favorite movies", "user": "mike", "type": "rank", "entries": {"blade runner": 1, "the empire strikes back": 2, "alien": 3}}' --partition-key 0
-aws kinesis put-record --stream-name $STREAM --data '{"title": "stats", "user": "bill", "type": "tally", "entries": {"xp": 83}}' --partition-key 0
\ No newline at end of file
diff --git a/sample-apps/list-manager/8-cleanup.sh b/sample-apps/list-manager/8-cleanup.sh
deleted file mode 100755
index 2dcc1ae6..00000000
--- a/sample-apps/list-manager/8-cleanup.sh
+++ /dev/null
@@ -1,38 +0,0 @@
-#!/bin/bash
-set -eo pipefail
-STACK=list-manager
-if [[ $# -eq 1 ]] ; then
- STACK=$1
- echo "Deleting stack $STACK"
-fi
-FUNCTION=$(aws cloudformation describe-stack-resource --stack-name $STACK --logical-resource-id function --query 'StackResourceDetail.PhysicalResourceId' --output text)
-aws cloudformation delete-stack --stack-name $STACK
-echo "Deleted $STACK stack."
-
-if [ -f bucket-name.txt ]; then
- ARTIFACT_BUCKET=$(cat bucket-name.txt)
- if [[ ! $ARTIFACT_BUCKET =~ lambda-artifacts-[a-z0-9]{16} ]] ; then
- echo "Bucket was not created by this application. Skipping."
- else
- while true; do
- read -p "Delete deployment artifacts and bucket ($ARTIFACT_BUCKET)? (y/n)" response
- case $response in
- [Yy]* ) aws s3 rb --force s3://$ARTIFACT_BUCKET; rm bucket-name.txt; break;;
- [Nn]* ) break;;
- * ) echo "Response must start with y or n.";;
- esac
- done
- fi
-fi
-
-while true; do
- read -p "Delete function log group (/aws/lambda/$FUNCTION)? (y/n)" response
- case $response in
- [Yy]* ) aws logs delete-log-group --log-group-name /aws/lambda/$FUNCTION; break;;
- [Nn]* ) break;;
- * ) echo "Response must start with y or n.";;
- esac
-done
-
-rm out.yml out.json
-rm -rf lib/nodejs/node_modules
\ No newline at end of file
diff --git a/sample-apps/list-manager/README.md b/sample-apps/list-manager/README.md
deleted file mode 100644
index fee53bb2..00000000
--- a/sample-apps/list-manager/README.md
+++ /dev/null
@@ -1,221 +0,0 @@
-# Processing a Kinesis stream with database resources in a VPC
-
-This sample application processes records from an Amazon Kinesis stream to create and update lists. It uses a private VPC to connect to an Amazon Relational Database Service (Amazon RDS) database. It uses a VPC endpoint to connect to Amazon DynamoDB. The application also uses AWS Secrets Manager, AWS X-Ray, and AWS CodeDeploy.
-
-
-
-The processor function doesn't read directly from the Kinesis stream. Instead, an AWS Lambda event source mapping reads records from the Kinesis stream and sends them to the processor function in batches. The processor function stores all incoming events in a MySQL database, and maintains the current state of each list in a DynamoDB table.
-
-The project source includes function code and supporting resources:
-
-- `processor` - A Node.js function that processes records from a Kinesis stream.
-- `dbadmin` - A Node.js function that runs SQL commands for administrator use.
-- `lib` - A Lambda layer with the npm modules used by the application's functions.
-- `events` - JSON documents that can be used to test the application's functions.
-- `template.yml` - An AWS CloudFormation template that creates the application.
-- `template-vpcrds.yml` - A template that creates the VPC and Amazon RDS database instance.
-- `1-create-bucket.sh`, `2-create-dbpasswordsecret.sh`, and other scripts - Shell scripts that use the AWS CLI to deploy and manage the application.
-- `bin` - Additional scripts.
-
-The processor supports the following types of lists:
-
-## Ranking
-
-A list of names with a rank or weight. For example:
-
- - Top 10 lists - Integer values 1-N.
- - Weighted rankings - Any number values.
-
-Rankings are combined into an aggregate list. When a user updates their ranking, the change (added, removed, and moved entries) is applied to the aggregate list as well.
-
-## Stats
-
-A list of fields to increment. For example:
-
- - Expenses - Amounts spent on gasoline, meals out, and so on.
- - Character state - Stats such as health, experience points, and steps walked.
-
-# Requirements
-
-To deploy the sample application, you need the following tools:
-
-- [Node.js 10 with npm](https://nodejs.org/en/download/releases/).
-- The Bash shell. For Linux and macOS, this is included by default. In Windows 10, you can install the [Windows Subsystem for Linux](https://docs.microsoft.com/en-us/windows/wsl/install-win10) to get a Windows-integrated version of Ubuntu and Bash.
-- [The AWS CLI v1](https://docs.aws.amazon.com/cli/latest/userguide/cli-chap-install.html).
-
-To run the sample application in AWS, you need permission to use Lambda and the following services:
-
-- Amazon RDS ([pricing](https://aws.amazon.com/rds/pricing/))
-- Amazon Kinesis ([pricing](https://aws.amazon.com/kinesis/pricing/))
-- Amazon DynamoDB ([pricing](https://aws.amazon.com/dynamodb/pricing/))
-- Amazon VPC ([pricing](https://aws.amazon.com/vpc/pricing/))
-- AWS Secrets Manager ([pricing](https://aws.amazon.com/secrets-manager/pricing/))
-- AWS CodeDeploy ([pricing](https://aws.amazon.com/codedeploy/pricing/))
-- AWS X-Ray ([pricing](https://aws.amazon.com/xray/pricing/))
-- AWS Identity and Access Management
-- AWS CloudFormation
-
-Standard charges apply for each service.
-
-# Setup
-
-Download or clone this repository.
-
- $ git clone https://github.com/awsdocs/aws-lambda-developer-guide.git
- $ cd aws-lambda-developer-guide/sample-apps/list-manager
-
-To create a new bucket for deployment artifacts, run `1-create-bucket.sh`.
-
- list-manager$ ./1-create-bucket.sh
- make_bucket: lambda-artifacts-a5e491dbb5b22e0d
-
-To create a database password and store it in AWS Secrets Manager, run the `2-create-dbpasswordsecret.sh` script.
-
- list-manager$ ./2-create-dbpasswordsecret.sh
-
-To create the VPC and RDS database instance, run the `3-deploy-vpc.sh` script. This process takes about 15 minutes.
-
- list-manager$ ./3-deploy-vpc.sh
-
-# Deploy
-
-To deploy the application, run `4-deploy.sh`.
-
- list-manager$ ./4-deploy.sh
- Uploading to e678bc216e6a0d510d661ca9ae2fd941 2678 / 2678.0 (100.00%)
- Successfully packaged artifacts and wrote output template to file out.yml.
- Waiting for changeset to be created..
- Waiting for stack create/update to complete
- Successfully created/updated stack - list-manager
-
-This script uses AWS CloudFormation to deploy the Lambda functions and an IAM role. If the AWS CloudFormation stack that contains the resources already exists, the script updates it with any changes to the template or function code.
-
-To create a table in the database, run the `5-create-dbtable.sh` script.
-
- list-manager$ ./5-create-dbtable.sh
-
-# Test
-
-To invoke the function with a test event, run `6-invoke.sh`.
-
- list-manager$ ./6-invoke.sh
- {
- "StatusCode": 200,
- "ExecutedVersion": "$LATEST"
- }
-
-Let the script invoke the function a few times and then press `CRTL+C` to exit.
-
-If that succeeds, send records to the Kinesis stream. The processor function's event source mapping pulls records from the stream and invokes the function.
-
- list-manager$ ./7-put-records.sh
-
-The application uses AWS X-Ray to trace requests. Open the [X-Ray console](https://console.aws.amazon.com/xray/home#/service-map) to view the service map. The following service map shows the function writing to the two DynamoDB tables and the MySQL database.
-
-
-
-Choose a node in the main function graph. Then choose **View traces** to see a list of traces. Choose any trace to view a timeline that breaks down the work done by the function.
-
-
-
-Finally, view the application in the Lambda console.
-
-*To view the application*
-1. Open the [applications page](https://console.aws.amazon.com/lambda/home#/applications) in the Lambda console.
-2. Choose **list-manager**.
-
- 
-
-# Kinesis record structure
-
-Tally list:
-
- {
- "title": "stats",
- "type": "tally",
- "user": "andy",
- "entries": [
- "xp": 20
- ]
- }
-
-Rank list:
-
- {
- "title": "favorite movie",
- "type": "rank",
- "user": "andy",
- "entries": [
- "blade runner": 1,
- "the empire strikes back": 2
- "alien": 3
- ]
- }
-
-# Table structure
-
-Per-user table:
-
- {
- "id": "#12AB",
- "aggid": "#12AB",
- "title": "stats",
- "type": "tally",
- "last updated": 1234567890123,
- "user": "andy"
- "entries": [
- {
- "xp": 100
- }
- ]
- }
-
- {
- "id": "#12AB",
- "aggid": "#12AB",
- "title": "stats",
- "type": "rank",
- "last updated": 1234567890123,
- "user": "andy"
- "entries": [
- {
- "blade runner": 1,
- "the empire strikes back": 2,
- "alien": 3
- }
- ]
- }
-
-Aggregate table:
-
- {
- "id": "#12AB",
- "title": "stats",
- "type": "tally",
- "last updated": 1234567890123,
- "entries": [
- {
- "xp": 500
- }
- ]
- }
-
- {
- "id": "#12AB",
- "title": "favorite movie",
- "type": "rank",
- "last updated": 1234567890123,
- "entries": [
- {
- "blade runner": 3,
- "the empire strikes back": 5,
- "alien": 4
- }
- ]
- }
-
-# Cleanup
-
-To delete the application, run the cleanup script.
-
- list-manager$ ./8-cleanup.sh
diff --git a/sample-apps/list-manager/bin/get-kinesis-stream.sh b/sample-apps/list-manager/bin/get-kinesis-stream.sh
deleted file mode 100755
index 8f7cebe4..00000000
--- a/sample-apps/list-manager/bin/get-kinesis-stream.sh
+++ /dev/null
@@ -1,4 +0,0 @@
-#!/bin/bash
-set -eo pipefail
-STREAM=$(aws cloudformation describe-stack-resource --stack-name list-manager --logical-resource-id stream --query 'StackResourceDetail.PhysicalResourceId' --output text)
-echo $STREAM
diff --git a/sample-apps/list-manager/bin/get-stack-event.sh b/sample-apps/list-manager/bin/get-stack-event.sh
deleted file mode 100755
index 57e468b7..00000000
--- a/sample-apps/list-manager/bin/get-stack-event.sh
+++ /dev/null
@@ -1 +0,0 @@
-aws cloudformation describe-stack-events --stack-name list-manager --max-items 1 --query 'StackEvents[0]'
diff --git a/sample-apps/list-manager/bin/get-stack-status.sh b/sample-apps/list-manager/bin/get-stack-status.sh
deleted file mode 100755
index 1f8b2b5d..00000000
--- a/sample-apps/list-manager/bin/get-stack-status.sh
+++ /dev/null
@@ -1 +0,0 @@
-aws cloudformation describe-stacks --stack-name list-manager --query 'Stacks[*].StackStatus' --output text
diff --git a/sample-apps/list-manager/dbadmin/index.js b/sample-apps/list-manager/dbadmin/index.js
deleted file mode 100644
index b0309956..00000000
--- a/sample-apps/list-manager/dbadmin/index.js
+++ /dev/null
@@ -1,37 +0,0 @@
-var AWSXRay = require('aws-xray-sdk-core')
-var captureMySQL = require('aws-xray-sdk-mysql')
-var mysql = captureMySQL(require('mysql'))
-const username = process.env.databaseUser
-const password = process.env.databasePassword
-const host = process.env.databaseHost
-
-exports.handler = async (event) => {
- var connection = mysql.createConnection({
- host : host,
- user : username,
- password : password,
- database : 'lambdadb'
- })
- var query = event.query
- var result
- connection.connect()
-
- connection.query(query, function (error, results, fields) {
- if (error) throw error
- console.log("Ran query: " + query)
- for (result in results)
- console.log(results[result])
- })
-
- return new Promise( ( resolve, reject ) => {
- connection.end( err => {
- if ( err )
- return reject( err )
- const response = {
- statusCode: 200,
- body: JSON.stringify(result),
- }
- resolve(response)
- })
- })
-}
diff --git a/sample-apps/list-manager/dbadmin/package.json b/sample-apps/list-manager/dbadmin/package.json
deleted file mode 100644
index 774c74cf..00000000
--- a/sample-apps/list-manager/dbadmin/package.json
+++ /dev/null
@@ -1,12 +0,0 @@
-{
- "name": "list-manager-processor",
- "version": "1.0.0",
- "private": true,
- "dependencies": {},
- "devDependencies": {
- "aws-xray-sdk-core": "2.4.0",
- "aws-xray-sdk-mysql": "2.4.0",
- "mysql": "2.17.1"
- },
- "scripts": {}
-}
diff --git a/sample-apps/list-manager/events/db-clear-table.json b/sample-apps/list-manager/events/db-clear-table.json
deleted file mode 100644
index 1cad4eb0..00000000
--- a/sample-apps/list-manager/events/db-clear-table.json
+++ /dev/null
@@ -1,3 +0,0 @@
-{
- "query": "DELETE FROM events"
-}
\ No newline at end of file
diff --git a/sample-apps/list-manager/events/db-create-table.json b/sample-apps/list-manager/events/db-create-table.json
deleted file mode 100644
index 9698225c..00000000
--- a/sample-apps/list-manager/events/db-create-table.json
+++ /dev/null
@@ -1,3 +0,0 @@
-{
- "query": "CREATE TABLE events ( id varchar(255), title varchar(255), timestamp BIGINT, entries varchar(32765));"
-}
\ No newline at end of file
diff --git a/sample-apps/list-manager/events/db-read-table.json b/sample-apps/list-manager/events/db-read-table.json
deleted file mode 100644
index 2b0ece0b..00000000
--- a/sample-apps/list-manager/events/db-read-table.json
+++ /dev/null
@@ -1,3 +0,0 @@
-{
- "query": "SELECT * FROM events"
-}
\ No newline at end of file
diff --git a/sample-apps/list-manager/events/kinesis.json b/sample-apps/list-manager/events/kinesis.json
deleted file mode 100644
index 1960433c..00000000
--- a/sample-apps/list-manager/events/kinesis.json
+++ /dev/null
@@ -1,68 +0,0 @@
-{
- "Records": [
- {
- "kinesis": {
- "kinesisSchemaVersion": "1.0",
- "partitionKey": "0",
- "sequenceNumber": "49598630142999655949899443842509554952738656579378741250",
- "data": "eyJ0aXRsZSI6ICJmYXZvcml0ZSBtb3ZpZXMiLCAidXNlciI6ICJyZGx5c2N0IiwgInR5cGUiOiAicmFuayIsICJlbnRyaWVzIjogeyJibGFkZSBydW5uZXIiOiAyLCAidGhlIGVtcGlyZSBzdHJpa2VzIGJhY2siOiAzLCAiYWxpZW4iOiAxfX0=",
- "approximateArrivalTimestamp": 1570667770.615
- },
- "eventSource": "aws:kinesis",
- "eventVersion": "1.0",
- "eventID": "shardId-000000000000:49598630142999655949899443842509554952738656579378741250",
- "eventName": "aws:kinesis:record",
- "invokeIdentityArn": "arn:aws:iam::123456789012:role/list-manager-processorRole-7FYXMPLH7IUS",
- "awsRegion": "us-east-2",
- "eventSourceARN": "arn:aws:kinesis:us-east-2:123456789012:stream/list-manager-stream-87B3XMPLF1AZ"
- },
- {
- "kinesis": {
- "kinesisSchemaVersion": "1.0",
- "partitionKey": "0",
- "sequenceNumber": "49598630142999655949899443843117644640004815122975424514",
- "data": "eyJ0aXRsZSI6ICJzdGF0cyIsICJ1c2VyIjogImJldGgiLCAidHlwZSI6ICJ0YWxseSIsICJlbnRyaWVzIjogeyJ4cCI6IDI1fX0=",
- "approximateArrivalTimestamp": 1570667771.753
- },
- "eventSource": "aws:kinesis",
- "eventVersion": "1.0",
- "eventID": "shardId-000000000000:49598630142999655949899443843117644640004815122975424514",
- "eventName": "aws:kinesis:record",
- "invokeIdentityArn": "arn:aws:iam::123456789012:role/list-manager-processorRole-7FYXMPLH7IUS",
- "awsRegion": "us-east-2",
- "eventSourceARN": "arn:aws:kinesis:us-east-2:123456789012:stream/list-manager-stream-87B3XMPLF1AZ"
- },
- {
- "kinesis": {
- "kinesisSchemaVersion": "1.0",
- "partitionKey": "0",
- "sequenceNumber": "49598630142999655949899443123457048701043305532981510146",
- "data": "eyJ0aXRsZSI6ICJmYXZvcml0ZSBtb3ZpZXMiLCAidXNlciI6ICJtaWtlIiwgInR5cGUiOiAicmFuayIsICJlbnRyaWVzIjogeyJibGFkZSBydW5uZXIiOiAxLCAidGhlIGVtcGlyZSBzdHJpa2VzIGJhY2siOiAyLCAiYWxpZW4iOiAzfX0=",
- "approximateArrivalTimestamp": 1570667772.81
- },
- "eventSource": "aws:kinesis",
- "eventVersion": "1.0",
- "eventID": "shardId-000000000000:49598630142999655949899443123457048701043305532981510146",
- "eventName": "aws:kinesis:record",
- "invokeIdentityArn": "arn:aws:iam::123456789012:role/list-manager-processorRole-7FYXMPLH7IUS",
- "awsRegion": "us-east-2",
- "eventSourceARN": "arn:aws:kinesis:us-east-2:123456789012:stream/list-manager-stream-87B3XMPLF1AZ"
- },
- {
- "kinesis": {
- "kinesisSchemaVersion": "1.0",
- "partitionKey": "0",
- "sequenceNumber": "49598630142999655949899443844127097699383030621294034946",
- "data": "eyJ0aXRsZSI6ICJzdGF0cyIsICJ1c2VyIjogImJpbGwiLCAidHlwZSI6ICJ0YWxseSIsICJlbnRyaWVzIjogeyJ4cCI6IDgzfX0=",
- "approximateArrivalTimestamp": 1570667773.832
- },
- "eventSource": "aws:kinesis",
- "eventVersion": "1.0",
- "eventID": "shardId-000000000000:49598630142999655949899443844127097699383030621294034946",
- "eventName": "aws:kinesis:record",
- "invokeIdentityArn": "arn:aws:iam::123456789012:role/list-manager-processorRole-7FYXMPLH7IUS",
- "awsRegion": "us-east-2",
- "eventSourceARN": "arn:aws:kinesis:us-east-2:123456789012:stream/list-manager-stream-87B3XMPLF1AZ"
- }
- ]
-}
\ No newline at end of file
diff --git a/sample-apps/list-manager/images/listmanager-application.png b/sample-apps/list-manager/images/listmanager-application.png
deleted file mode 100644
index 86521f33..00000000
Binary files a/sample-apps/list-manager/images/listmanager-application.png and /dev/null differ
diff --git a/sample-apps/list-manager/images/listmanager-servicemap.png b/sample-apps/list-manager/images/listmanager-servicemap.png
deleted file mode 100644
index 34dff816..00000000
Binary files a/sample-apps/list-manager/images/listmanager-servicemap.png and /dev/null differ
diff --git a/sample-apps/list-manager/images/listmanager-trace.png b/sample-apps/list-manager/images/listmanager-trace.png
deleted file mode 100644
index fc2e86c9..00000000
Binary files a/sample-apps/list-manager/images/listmanager-trace.png and /dev/null differ
diff --git a/sample-apps/list-manager/images/sample-listmanager.png b/sample-apps/list-manager/images/sample-listmanager.png
deleted file mode 100644
index e21efebd..00000000
Binary files a/sample-apps/list-manager/images/sample-listmanager.png and /dev/null differ
diff --git a/sample-apps/list-manager/lib/nodejs/package.json b/sample-apps/list-manager/lib/nodejs/package.json
deleted file mode 100644
index f5859d75..00000000
--- a/sample-apps/list-manager/lib/nodejs/package.json
+++ /dev/null
@@ -1,12 +0,0 @@
-{
- "name": "lib-layer",
- "version": "1.0.0",
- "private": true,
- "dependencies": {
- "aws-xray-sdk-core": "2.4.0",
- "aws-xray-sdk-mysql": "2.4.0",
- "md5": "2.2.1",
- "mysql": "2.17.1"
- },
- "scripts": {}
-}
diff --git a/sample-apps/list-manager/processor/index.js b/sample-apps/list-manager/processor/index.js
deleted file mode 100644
index 540a6104..00000000
--- a/sample-apps/list-manager/processor/index.js
+++ /dev/null
@@ -1,170 +0,0 @@
-// AWS X-Ray SDK
-var AWSXRay = require('aws-xray-sdk-core')
-var captureMySQL = require('aws-xray-sdk-mysql')
-var mysql = captureMySQL(require('mysql'))
-// AWS SDK clients
-// NOTE: Function needs permission for each service in execution role
-var AWS = AWSXRay.captureAWS(require('aws-sdk'))
-// Create client outside of handler to reuse
-var docClient = new AWS.DynamoDB.DocumentClient()
-var md5 = require('md5')
-// Read bucket name from environment variable
-const table = process.env.table
-const aggtable = process.env.aggtable
-const username = process.env.databaseUser
-const password = process.env.databasePassword
-const host = process.env.databaseHost
-const dbtable = "events"
-
-// Use Amazon DynamoDB client
-var updateList = async function(event){
- // shallow copy of event
- let item = { ... event }
- // aggregate ID (all entries with same title)
- item.aggid = md5(item.title)
- // individual ID (from same user only)
- item.id = md5(item.title + item.user)
- // TODO: check for existing documents
- // get agg item
- var aggdata = await docClient.get({TableName:aggtable, Key: { id: item.aggid }}).promise()
- console.log("AGGDATA: " + JSON.stringify(aggdata, null, 2))
-
- // get indv item
- var data = await docClient.get({TableName:table, Key: { id: item.id, aggid: item.aggid }}).promise()
- console.log("DATA: " + JSON.stringify(data, null, 2))
-
- var newEntries = JSON.parse(event.entries)
- var oldEntries = {}
- var aggItem = {}
- if (data.Item)
- oldEntries = JSON.parse(data.Item.entries)
- var aggregateEntries = {}
- if (aggdata.Item) {
- aggregateEntries = JSON.parse(aggdata.Item.entries)
- aggItem = aggdata.Item
- } else {
- aggItem.id = item.aggid
- aggItem.title = item.title
- aggItem.type = item.type
- aggItem['last updated'] = item.timestamp
- }
- // TODO: store contributor user IDs in aggregate item and confirm their presence before applying delta
- var deltaEntries = newEntries
- console.log("NEW ENTRIES: " + JSON.stringify(newEntries, null, 2))
- console.log("OLD ENTRIES: " + JSON.stringify(oldEntries, null, 2))
- if ( event.type == "rank" ) {
- // calculate changes vs existing indv list
- Object.keys(newEntries).forEach(function(key,index) {
- if (oldEntries.hasOwnProperty(key))
- deltaEntries[key] -= oldEntries[key]
- })
- Object.keys(oldEntries).forEach(function(key,index) {
- if (!newEntries.hasOwnProperty(key))
- deltaEntries[key] = -oldEntries[key]
- })
- // update aggregate list
- Object.keys(deltaEntries).forEach(function(key,index) {
- if (aggregateEntries.hasOwnProperty(key))
- aggregateEntries[key] += deltaEntries[key]
- else
- aggregateEntries[key] = newEntries[key]
- })
- }
- if ( event.type == "tally" ) {
- // update existing indv list
- Object.keys(newEntries).forEach(function(key,index) {
- //TODO: check type of value = number
- if (oldEntries.hasOwnProperty(key))
- oldEntries[key] += newEntries[key]
- else
- oldEntries[key] = newEntries[key]
- })
- Object.keys(deltaEntries).forEach(function(key,index) {
- if (aggregateEntries.hasOwnProperty(key))
- aggregateEntries[key] += deltaEntries[key]
- else
- aggregateEntries[key] = newEntries[key]
- })
- item.entries = JSON.stringify(oldEntries, null, 0)
- console.log("TALLIED ENTRIES: " + item.entries)
- }
- console.log("DELTA ENTRIES: " + JSON.stringify(deltaEntries, null, 0))
- item['last updated'] = item.timestamp
- delete item.timestamp
-
- var params = {
- TableName: table,
- Item: item
- }
-
- await docClient.put(params).promise()
-
- aggItem.entries = JSON.stringify(aggregateEntries, null, 0)
- console.log("AGGREGATE ENTRIES: " + aggItem.entries)
-
- params.Item = aggItem
- params.TableName = aggtable
- await docClient.put(params).promise()
-
-}
-
-// Use mysql client
-var storeEvent = async function(event, connection){
- // update database
- var query = "INSERT INTO " + dbtable + " (id, title, timestamp, entries) VALUES ?;"
- var values = [[event.id, event.title, event.timestamp, event.entries]]
- console.log("storing event:")
- console.log(event.id + "," + event.title + "," + event.timestamp + "," + event.entries)
- return new Promise( ( resolve, reject ) => {
- connection.query(query, [values], function (error, results, fields) {
- if (error)
- return reject(error)
- resolve(results)
- })
- })
-}
-
-var processRecords = async function(records, connection) {
- for (const record of records) {
- // Decode kinesis data
- const data = Buffer.from(record.kinesis.data, 'base64').toString('ascii')
- var event = {}
- const item = JSON.parse(data)
- event.title = item.title
- event.user = item.user
- event.type = item.type
- event.entries = JSON.stringify(item.entries, null, 0)
- event.id = record.eventID
- event.timestamp = record.kinesis.approximateArrivalTimestamp * 1000
- console.log("EVENT TIMESTAMP:" + event.timestamp)
- // update table
- await updateList(event)
- await storeEvent(event, connection)
- }
-}
-
-exports.handler = async function(kinesisEvent, context) {
- console.log("EVENT\n" + JSON.stringify(kinesisEvent, null, 2))
- var connection = mysql.createConnection({
- host : host,
- user : username,
- password : password,
- database : 'lambdadb'
- })
- console.log("connecting to db")
- connection.connect()
- var result
- // process event
- await processRecords(kinesisEvent.Records, connection)
- return new Promise( ( resolve, reject ) => {
- connection.end( err => {
- if ( err )
- return reject( err )
- const response = {
- statusCode: 200,
- body: JSON.stringify(result),
- }
- resolve(response)
- } )
- } )
-}
\ No newline at end of file
diff --git a/sample-apps/list-manager/processor/package.json b/sample-apps/list-manager/processor/package.json
deleted file mode 100644
index 1428d7bd..00000000
--- a/sample-apps/list-manager/processor/package.json
+++ /dev/null
@@ -1,14 +0,0 @@
-{
- "name": "list-manager-processor",
- "version": "1.0.0",
- "private": true,
- "dependencies": {},
- "devDependencies": {
- "aws-sdk": "2.488.0",
- "aws-xray-sdk-core": "2.4.0",
- "aws-xray-sdk-mysql": "2.4.0",
- "md5": "2.2.1",
- "mysql": "2.17.1"
- },
- "scripts": {}
-}
diff --git a/sample-apps/list-manager/template-vpcrds.yml b/sample-apps/list-manager/template-vpcrds.yml
deleted file mode 100644
index a60a3fcf..00000000
--- a/sample-apps/list-manager/template-vpcrds.yml
+++ /dev/null
@@ -1,157 +0,0 @@
-AWSTemplateFormatVersion: 2010-09-09
-Parameters:
- databaseName:
- Default: lambdadb
- Description: Database name
- Type: String
- MinLength: '1'
- MaxLength: '64'
- AllowedPattern: '[a-zA-Z][a-zA-Z0-9]*'
- ConstraintDescription: Begin with a letter and use only alphanumeric characters.
- databaseUser:
- NoEcho: 'true'
- Description: Database username
- Default: admin
- Type: String
- MinLength: '1'
- MaxLength: '16'
- AllowedPattern: '[a-zA-Z][a-zA-Z0-9]*'
- ConstraintDescription: Begin with a letter and use only alphanumeric characters.
-Resources:
- databaseSubnetGroup:
- Type: AWS::RDS::DBSubnetGroup
- Properties:
- DBSubnetGroupDescription: Subnets
- SubnetIds:
- - !Ref privateSubnetA
- - !Ref privateSubnetB
- database:
- Type: AWS::RDS::DBInstance
- Properties:
- DBName: !Ref databaseName
- AllocatedStorage: '10'
- DBInstanceClass: db.t3.small
- Engine: MySQL
- EngineVersion: 8.0.15
- MasterUsername: !Ref 'databaseUser'
- MasterUserPassword: '{{resolve:secretsmanager:list-manager:SecretString:password}}'
- DeletionProtection: true
- MultiAZ: true
- DBSubnetGroupName: !Ref databaseSubnetGroup
- VPCSecurityGroups:
- - !GetAtt privateVPC.DefaultSecurityGroup
- privateVPC:
- Type: AWS::EC2::VPC
- Properties:
- CidrBlock: 172.31.0.0/16
- Tags:
- - Key: Name
- Value: !Ref AWS::StackName
- privateSubnetA:
- Type: AWS::EC2::Subnet
- Properties:
- VpcId: !Ref privateVPC
- AvailabilityZone:
- Fn::Select:
- - 0
- - Fn::GetAZs: ""
- CidrBlock: 172.31.3.0/24
- MapPublicIpOnLaunch: false
- Tags:
- - Key: Name
- Value: !Join ["-", [!Ref "AWS::StackName","subnet-a"]]
- privateSubnetB:
- Type: AWS::EC2::Subnet
- Properties:
- VpcId: !Ref privateVPC
- AvailabilityZone:
- Fn::Select:
- - 1
- - Fn::GetAZs: ""
- CidrBlock: 172.31.2.0/24
- MapPublicIpOnLaunch: false
- Tags:
- - Key: Name
- Value: !Join ["-", [!Ref "AWS::StackName","subnet-b"]]
- privateRouteTable:
- Type: AWS::EC2::RouteTable
- Properties:
- VpcId: !Ref privateVPC
- privateSubnetARouteTableAssociation:
- Type: AWS::EC2::SubnetRouteTableAssociation
- Properties:
- SubnetId: !Ref privateSubnetA
- RouteTableId: !Ref privateRouteTable
- privateSubnetBRouteTableAssociation:
- Type: AWS::EC2::SubnetRouteTableAssociation
- Properties:
- SubnetId: !Ref privateSubnetB
- RouteTableId: !Ref privateRouteTable
- s3Endpoint:
- Type: AWS::EC2::VPCEndpoint
- Properties:
- PolicyDocument:
- Version: 2012-10-17
- Statement:
- - Effect: Allow
- Principal: "*"
- Action:
- - "s3:*"
- Resource:
- - "*"
- RouteTableIds:
- - !Ref privateRouteTable
- ServiceName: !Sub com.amazonaws.${AWS::Region}.s3
- VpcId: !Ref privateVPC
- dynamoDBEndpoint:
- Type: AWS::EC2::VPCEndpoint
- Properties:
- PolicyDocument:
- Version: 2012-10-17
- Statement:
- - Effect: Allow
- Principal: "*"
- Action:
- - "dynamodb:*"
- Resource:
- - "*"
- RouteTableIds:
- - !Ref privateRouteTable
- ServiceName: !Sub com.amazonaws.${AWS::Region}.dynamodb
- VpcId: !Ref privateVPC
-Outputs:
- privateVPCSecurityGroup:
- Description: Default security for Lambda VPC
- Value: !GetAtt privateVPC.DefaultSecurityGroup
- Export:
- Name: !Join ["-", [!Ref "AWS::StackName","vpc-sg"]]
- privateVPCID:
- Description: VPC ID
- Value: !Ref privateVPC
- Export:
- Name: !Join ["-", [!Ref "AWS::StackName","vpc"]]
- privateSubnetAID:
- Description: Private Subnet A ID
- Value: !Ref privateSubnetA
- Export:
- Name: !Join ["-", [!Ref "AWS::StackName","subnet-a"]]
- privateSubnetBID:
- Description: Private Subnet B ID
- Value: !Ref privateSubnetB
- Export:
- Name: !Join ["-", [!Ref "AWS::StackName","subnet-b"]]
- databaseHost:
- Description: Database hostname
- Value: !GetAtt database.Endpoint.Address
- Export:
- Name: !Join ["-", [!Ref "AWS::StackName","db-host"]]
- databaseName:
- Description: Database name
- Value: !Ref databaseName
- Export:
- Name: !Join ["-", [!Ref "AWS::StackName","db-name"]]
- databaseUser:
- Description: Database user
- Value: !Ref databaseUser
- Export:
- Name: !Join ["-", [!Ref "AWS::StackName","db-user"]]
diff --git a/sample-apps/list-manager/template.yml b/sample-apps/list-manager/template.yml
deleted file mode 100644
index 215bdcc3..00000000
--- a/sample-apps/list-manager/template.yml
+++ /dev/null
@@ -1,125 +0,0 @@
-AWSTemplateFormatVersion: 2010-09-09
-Description: An AWS Lambda application that uses Amazon Kinesis and Amazon RDS.
-Transform: AWS::Serverless-2016-10-31
-Parameters:
- vpcStackName:
- Default: list-manager-vpc
- Description: VPC and database stack name
- Type: String
-Globals:
- Function:
- Runtime: nodejs12.x
- Tracing: Active
- Handler: index.handler
- AutoPublishAlias: live
- Environment:
- Variables:
- table: !Ref table
- aggtable: !Ref aggtable
- databaseHost:
- Fn::ImportValue:
- !Sub "${vpcStackName}-db-host"
- databaseName:
- Fn::ImportValue:
- !Sub "${vpcStackName}-db-name"
- databaseUser:
- Fn::ImportValue:
- !Sub "${vpcStackName}-db-user"
- databasePassword: '{{resolve:secretsmanager:list-manager:SecretString:password}}'
- VpcConfig:
- SecurityGroupIds:
- - Fn::ImportValue:
- !Sub "${vpcStackName}-vpc-sg"
- SubnetIds:
- - Fn::ImportValue:
- !Sub "${vpcStackName}-subnet-a"
- - Fn::ImportValue:
- !Sub "${vpcStackName}-subnet-b"
- DeploymentPreference:
- Type: AllAtOnce
- Role: !GetAtt deployrole.Arn
- Layers:
- - !Ref libs
-Resources:
- deployrole:
- Type: AWS::IAM::Role
- Properties:
- AssumeRolePolicyDocument:
- Version: "2012-10-17"
- Statement:
- - Effect: Allow
- Principal:
- Service:
- - codedeploy.amazonaws.com
- Action:
- - sts:AssumeRole
- ManagedPolicyArns:
- - arn:aws:iam::aws:policy/service-role/AWSCodeDeployRoleForLambda
- libs:
- Type: AWS::Serverless::LayerVersion
- Properties:
- LayerName: list-manager-lib
- Description: Dependencies for the list manager sample app.
- ContentUri: lib/.
- CompatibleRuntimes:
- - nodejs12.x
- dbadmin:
- Type: AWS::Serverless::Function
- Properties:
- CodeUri: dbadmin/.
- Description: Run SQL queries.
- MemorySize: 128
- Timeout: 15
- # Function's execution role
- Policies:
- - AWSLambdaBasicExecutionRole
- - AWSLambdaVPCAccessExecutionRole
- processor:
- Type: AWS::Serverless::Function
- Properties:
- CodeUri: processor/.
- Description: Process events from Amazon Kinesis
- MemorySize: 128
- Timeout: 100
- # Function's execution role
- Policies:
- - AWSLambdaBasicExecutionRole
- - AWSLambdaKinesisExecutionRole
- - AmazonDynamoDBFullAccess
- - AWSLambdaVPCAccessExecutionRole
- Events:
- kinesis:
- Type: Kinesis
- Properties:
- Stream: !GetAtt stream.Arn
- BatchSize: 100
- StartingPosition: LATEST
- stream:
- Type: AWS::Kinesis::Stream
- Properties:
- ShardCount: 1
- table:
- Type: AWS::DynamoDB::Table
- Properties:
- AttributeDefinitions:
- - AttributeName: "id"
- AttributeType: "S"
- - AttributeName: "aggid"
- AttributeType: "S"
- KeySchema:
- - AttributeName: "aggid"
- KeyType: "HASH"
- - AttributeName: "id"
- KeyType: "RANGE"
- ProvisionedThroughput:
- ReadCapacityUnits: "2"
- WriteCapacityUnits: "2"
- aggtable:
- Type: AWS::Serverless::SimpleTable
- Properties:
- PrimaryKey:
- Name: id
- Type: String
- ProvisionedThroughput:
- ReadCapacityUnits: 2
- WriteCapacityUnits: 2
diff --git a/sample-apps/nodejs-apig/3-invoke.sh b/sample-apps/nodejs-apig/3-invoke.sh
index a5c32b1d..7838da23 100755
--- a/sample-apps/nodejs-apig/3-invoke.sh
+++ b/sample-apps/nodejs-apig/3-invoke.sh
@@ -3,7 +3,7 @@ set -eo pipefail
FUNCTION=$(aws cloudformation describe-stack-resource --stack-name nodejs-apig --logical-resource-id function --query 'StackResourceDetail.PhysicalResourceId' --output text)
while true; do
- aws lambda invoke --function-name $FUNCTION --payload file://event.json out.json
+ aws lambda invoke --function-name $FUNCTION --payload fileb://event.json out.json
cat out.json
echo ""
sleep 2
diff --git a/sample-apps/nodejs-apig/README.md b/sample-apps/nodejs-apig/README.md
index 15e689e4..cc3681b3 100644
--- a/sample-apps/nodejs-apig/README.md
+++ b/sample-apps/nodejs-apig/README.md
@@ -15,9 +15,9 @@ The project source includes function code and supporting resources:
Use the following instructions to deploy the sample application.
# Requirements
-- [Node.js 10 with npm](https://nodejs.org/en/download/releases/)
+- [Node.js 18 with npm](https://nodejs.org/en/download/releases/)
- The Bash shell. For Linux and macOS, this is included by default. In Windows 10, you can install the [Windows Subsystem for Linux](https://docs.microsoft.com/en-us/windows/wsl/install-win10) to get a Windows-integrated version of Ubuntu and Bash.
-- [The AWS CLI v1](https://docs.aws.amazon.com/cli/latest/userguide/cli-chap-install.html).
+- [The AWS CLI](https://docs.aws.amazon.com/cli/latest/userguide/cli-chap-install.html) v1.17 or newer.
# Setup
Download or clone this repository.
diff --git a/sample-apps/nodejs-apig/function/index.js b/sample-apps/nodejs-apig/function/index.mjs
similarity index 82%
rename from sample-apps/nodejs-apig/function/index.js
rename to sample-apps/nodejs-apig/function/index.mjs
index 3d5fe80a..db6019ff 100644
--- a/sample-apps/nodejs-apig/function/index.js
+++ b/sample-apps/nodejs-apig/function/index.mjs
@@ -1,14 +1,14 @@
-const AWS = require('aws-sdk')
+import {LambdaClient, GetAccountSettingsCommand} from '@aws-sdk/client-lambda';
// Create client outside of handler to reuse
-const lambda = new AWS.Lambda()
+const lambda = new LambdaClient()
// Handler
-exports.handler = async function(event, context) {
+export const handler = async (event, context) => {
console.log('## ENVIRONMENT VARIABLES: ' + serialize(process.env))
console.log('## CONTEXT: ' + serialize(context))
console.log('## EVENT: ' + serialize(event))
try {
- let accountSettings = await getAccountSettings()
+ let accountSettings = await lambda.send(new GetAccountSettingsCommand())
return formatResponse(serialize(accountSettings.AccountUsage))
} catch(error) {
return formatError(error)
diff --git a/sample-apps/nodejs-apig/package.json b/sample-apps/nodejs-apig/package.json
index 271c8428..efb1ca11 100644
--- a/sample-apps/nodejs-apig/package.json
+++ b/sample-apps/nodejs-apig/package.json
@@ -3,6 +3,6 @@
"version": "1.0.0",
"private": true,
"devDependencies": {
- "aws-sdk": "2.631.0"
+ "aws-sdk": "2.814.0"
}
}
diff --git a/sample-apps/nodejs-apig/template.yml b/sample-apps/nodejs-apig/template.yml
index 8b2d575f..e01993f3 100644
--- a/sample-apps/nodejs-apig/template.yml
+++ b/sample-apps/nodejs-apig/template.yml
@@ -12,14 +12,14 @@ Resources:
Type: AWS::Serverless::Function
Properties:
Handler: index.handler
- Runtime: nodejs12.x
+ Runtime: nodejs22.x
CodeUri: function/.
Description: Call the AWS Lambda API
Timeout: 10
# Function's execution role
Policies:
- AWSLambdaBasicExecutionRole
- - AWSLambdaReadOnlyAccess
+ - AWSLambda_ReadOnlyAccess
- AWSXrayWriteOnlyAccess
Tracing: Active
Events:
diff --git a/sample-apps/rds-mysql/1-create-bucket.sh b/sample-apps/rds-mysql/1-create-bucket.sh
deleted file mode 100755
index 55a9a5a3..00000000
--- a/sample-apps/rds-mysql/1-create-bucket.sh
+++ /dev/null
@@ -1,6 +0,0 @@
-#!/bin/bash
-set -eo pipefail
-BUCKET_ID=$(dd if=/dev/random bs=8 count=1 2>/dev/null | od -An -tx1 | tr -d ' \t\n')
-BUCKET_NAME=lambda-artifacts-$BUCKET_ID
-echo $BUCKET_NAME > bucket-name.txt
-aws s3 mb s3://$BUCKET_NAME
\ No newline at end of file
diff --git a/sample-apps/rds-mysql/2-create-dbpasswordsecret.sh b/sample-apps/rds-mysql/2-create-dbpasswordsecret.sh
deleted file mode 100755
index 2767bfcd..00000000
--- a/sample-apps/rds-mysql/2-create-dbpasswordsecret.sh
+++ /dev/null
@@ -1,4 +0,0 @@
-#!/bin/bash
-set -eo pipefail
-DB_PASSWORD=$(dd if=/dev/random bs=8 count=1 2>/dev/null | od -An -tx1 | tr -d ' \t\n')
-aws secretsmanager create-secret --name rds-mysql-admin --description "database password" --secret-string "{\"username\":\"admin\",\"password\":\"$DB_PASSWORD\"}"
diff --git a/sample-apps/rds-mysql/3-deploy-vpc.sh b/sample-apps/rds-mysql/3-deploy-vpc.sh
deleted file mode 100755
index 3c867769..00000000
--- a/sample-apps/rds-mysql/3-deploy-vpc.sh
+++ /dev/null
@@ -1,3 +0,0 @@
-#!/bin/bash
-set -eo pipefail
-aws cloudformation deploy --template-file template-vpcrds.yml --stack-name rds-mysql-vpc
diff --git a/sample-apps/rds-mysql/4-deploy.sh b/sample-apps/rds-mysql/4-deploy.sh
deleted file mode 100755
index 1ccc03a5..00000000
--- a/sample-apps/rds-mysql/4-deploy.sh
+++ /dev/null
@@ -1,14 +0,0 @@
-#!/bin/bash
-set -eo pipefail
-ARTIFACT_BUCKET=$(cat bucket-name.txt)
-STACK=rds-mysql
-if [[ $# -eq 1 ]] ; then
- STACK=$1
- echo "Deploying to stack $STACK"
-fi
-cd lib/nodejs && npm install && cd ../../
-aws cloudformation package --template-file template.yml --s3-bucket $ARTIFACT_BUCKET --output-template-file out.yml
-aws cloudformation deploy --template-file out.yml --stack-name $STACK --capabilities CAPABILITY_NAMED_IAM
-
-# attach to different VPC
-#aws cloudformation deploy --template-file out.yml --stack-name $STACK --capabilities CAPABILITY_NAMED_IAM --parameter-overrides vpcStackName=lambda-vpc secretName=lambda-db-password
\ No newline at end of file
diff --git a/sample-apps/rds-mysql/5-create-dbtable.sh b/sample-apps/rds-mysql/5-create-dbtable.sh
deleted file mode 100755
index 30f97776..00000000
--- a/sample-apps/rds-mysql/5-create-dbtable.sh
+++ /dev/null
@@ -1,4 +0,0 @@
-#!/bin/bash
-set -eo pipefail
-FUNCTION=$(aws cloudformation describe-stack-resource --stack-name rds-mysql --logical-resource-id dbadmin --query 'StackResourceDetail.PhysicalResourceId' --output text)
-aws lambda invoke --function-name $FUNCTION --payload file://events/db-create-table.json out.json
diff --git a/sample-apps/rds-mysql/6-invoke.sh b/sample-apps/rds-mysql/6-invoke.sh
deleted file mode 100755
index 73a0b68a..00000000
--- a/sample-apps/rds-mysql/6-invoke.sh
+++ /dev/null
@@ -1,10 +0,0 @@
-#!/bin/bash
-set -eo pipefail
-FUNCTION=$(aws cloudformation describe-stack-resource --stack-name rds-mysql --logical-resource-id dbadmin --query 'StackResourceDetail.PhysicalResourceId' --output text)
-
-while true; do
- aws lambda invoke --function-name $FUNCTION --payload file://events/db-read-table.json out.json
- cat out.json
- echo ""
- sleep 2
-done
diff --git a/sample-apps/rds-mysql/7-cleanup.sh b/sample-apps/rds-mysql/7-cleanup.sh
deleted file mode 100755
index c35d2a7b..00000000
--- a/sample-apps/rds-mysql/7-cleanup.sh
+++ /dev/null
@@ -1,38 +0,0 @@
-#!/bin/bash
-set -eo pipefail
-STACK=rds-mysql
-if [[ $# -eq 1 ]] ; then
- STACK=$1
- echo "Deleting stack $STACK"
-fi
-FUNCTION=$(aws cloudformation describe-stack-resource --stack-name $STACK --logical-resource-id function --query 'StackResourceDetail.PhysicalResourceId' --output text)
-aws cloudformation delete-stack --stack-name $STACK
-echo "Deleted $STACK stack."
-
-if [ -f bucket-name.txt ]; then
- ARTIFACT_BUCKET=$(cat bucket-name.txt)
- if [[ ! $ARTIFACT_BUCKET =~ lambda-artifacts-[a-z0-9]{16} ]] ; then
- echo "Bucket was not created by this application. Skipping."
- else
- while true; do
- read -p "Delete deployment artifacts and bucket ($ARTIFACT_BUCKET)? (y/n)" response
- case $response in
- [Yy]* ) aws s3 rb --force s3://$ARTIFACT_BUCKET; rm bucket-name.txt; break;;
- [Nn]* ) break;;
- * ) echo "Response must start with y or n.";;
- esac
- done
- fi
-fi
-
-while true; do
- read -p "Delete function log group (/aws/lambda/$FUNCTION)? (y/n)" response
- case $response in
- [Yy]* ) aws logs delete-log-group --log-group-name /aws/lambda/$FUNCTION; break;;
- [Nn]* ) break;;
- * ) echo "Response must start with y or n.";;
- esac
-done
-
-rm -f out.yml out.json lib/nodejs/package-lock.json
-rm -rf lib/nodejs/node_modules
diff --git a/sample-apps/rds-mysql/README.md b/sample-apps/rds-mysql/README.md
deleted file mode 100644
index b6d413c4..00000000
--- a/sample-apps/rds-mysql/README.md
+++ /dev/null
@@ -1,117 +0,0 @@
-# Managing a MySQL for RDS Database in a private VPC
-
-This sample application runs SQL queries on a MySQL database. It uses a private VPC to connect to an Amazon Relational Database Service (Amazon RDS) database. The application also uses AWS Secrets Manager and AWS X-Ray.
-
-
-
-The function takes a event with the following structure:
-
-```
-{
- "query": "CREATE TABLE events ( id varchar(255), title varchar(255), timestamp BIGINT, entries varchar(32765));"
-}
-```
-
-The function executes the query and logs the output.
-
-The project source includes function code and supporting resources:
-
-- `dbadmin` - A Node.js function that runs SQL commands for administrator use.
-- `lib` - A Lambda layer with the npm modules used by the application's functions.
-- `events` - JSON documents that can be used to test the application's functions.
-- `template.yml` - An AWS CloudFormation template that creates the application.
-- `template-vpcrds.yml` - A template that creates the VPC and Amazon RDS database instance.
-- `1-create-bucket.sh`, `3-deploy-vpc.sh`, etc. - Shell scripts that use the AWS CLI to deploy and manage the application.
-- bin - Additional scripts.
-
-Use the following instructions to deploy the sample application.
-
-# Requirements
-
-To deploy the sample application, you need the following tools:
-
-- [Node.js 10 with npm](https://nodejs.org/en/download/releases/).
-- The Bash shell. For Linux and macOS, this is included by default. In Windows 10, you can install the [Windows Subsystem for Linux](https://docs.microsoft.com/en-us/windows/wsl/install-win10) to get a Windows-integrated version of Ubuntu and Bash.
-- [The AWS CLI v1](https://docs.aws.amazon.com/cli/latest/userguide/cli-chap-install.html).
-
-To run the sample application in AWS, you need permission to use Lambda and the following services.
-
-- Amazon RDS ([pricing](https://aws.amazon.com/rds/pricing/))
-- Amazon VPC ([pricing](https://aws.amazon.com/vpc/pricing/))
-- AWS Secrets Manager ([pricing](https://aws.amazon.com/secrets-manager/pricing/))
-- AWS X-Ray ([pricing](https://aws.amazon.com/xray/pricing/))
-- AWS Identity and Access Management
-- AWS CloudFormation
-
-Standard charges apply for each service.
-
-# Setup
-
-Download or clone this repository.
-
- $ git clone https://github.com/awsdocs/aws-lambda-developer-guide.git
- $ cd aws-lambda-developer-guide/sample-apps/rds-mysql
-
-To create a new bucket for deployment artifacts, run `1-create-bucket.sh`.
-
- rds-mysql$ ./1-create-bucket.sh
- make_bucket: lambda-artifacts-a5e491dbb5b22e0d
-
-To create a database password and store it in AWS Secrets Manager, run `2-create-dbpasswordsecret.sh` script.
-
- rds-mysql$ ./2-create-dbpasswordsecret.sh
-
-To create the VPC and RDS database instance, run the `3-deploy-vpc.sh` script. This process takes about 15 minutes.
-
- rds-mysql$ ./3-deploy-vpc.sh
-
-# Deploy
-
-To deploy the application, run `4-deploy.sh`.
-
- rds-mysql$ ./4-deploy.sh
- Uploading to e678bc216e6a0d510d661ca9ae2fd941 2678 / 2678.0 (100.00%)
- Successfully packaged artifacts and wrote output template to file out.yml.
- Waiting for changeset to be created..
- Waiting for stack create/update to complete
- Successfully created/updated stack - rds-mysql
-
-This script uses AWS CloudFormation to deploy the Lambda functions and an IAM role. If the AWS CloudFormation stack that contains the resources already exists, the script updates it with any changes to the template or function code.
-
-To create a table in the database, run `5-create-dbtable.sh`.
-
- rds-mysql$ ./5-create-dbtable.sh
-
-# Test
-
-To invoke the function with a test event, use the invoke script.
-
- rds-mysql$ ./6-invoke.sh
- {
- "StatusCode": 200,
- "ExecutedVersion": "$LATEST"
- }
-
-Let the script invoke the function a few times and then press `CRTL+C` to exit.
-
-The application uses AWS X-Ray to trace requests. Open the [X-Ray console](https://console.aws.amazon.com/xray/home#/service-map) to view the service map. The following service map shows the function calling the database to run a query.
-
-
-
-Choose a node in the main function graph. Then choose **View traces** to see a list of traces. Choose any trace to view a timeline that breaks down the work done by the function.
-
-
-
-Finally, view the application in the Lambda console.
-
-*To view the application*
-1. Open the [applications page](https://console.aws.amazon.com/lambda/home#/applications) in the Lambda console.
-2. Choose **rds-mysql**.
-
- 
-
-# Cleanup
-
-To delete the application, run the cleanup script.
-
- rds-mysql$ ./8-cleanup.sh
diff --git a/sample-apps/rds-mysql/bin/get-stack-event.sh b/sample-apps/rds-mysql/bin/get-stack-event.sh
deleted file mode 100644
index 57e468b7..00000000
--- a/sample-apps/rds-mysql/bin/get-stack-event.sh
+++ /dev/null
@@ -1 +0,0 @@
-aws cloudformation describe-stack-events --stack-name list-manager --max-items 1 --query 'StackEvents[0]'
diff --git a/sample-apps/rds-mysql/bin/get-stack-status.sh b/sample-apps/rds-mysql/bin/get-stack-status.sh
deleted file mode 100644
index 1f8b2b5d..00000000
--- a/sample-apps/rds-mysql/bin/get-stack-status.sh
+++ /dev/null
@@ -1 +0,0 @@
-aws cloudformation describe-stacks --stack-name list-manager --query 'Stacks[*].StackStatus' --output text
diff --git a/sample-apps/rds-mysql/dbadmin/index.js b/sample-apps/rds-mysql/dbadmin/index.js
deleted file mode 100644
index b0309956..00000000
--- a/sample-apps/rds-mysql/dbadmin/index.js
+++ /dev/null
@@ -1,37 +0,0 @@
-var AWSXRay = require('aws-xray-sdk-core')
-var captureMySQL = require('aws-xray-sdk-mysql')
-var mysql = captureMySQL(require('mysql'))
-const username = process.env.databaseUser
-const password = process.env.databasePassword
-const host = process.env.databaseHost
-
-exports.handler = async (event) => {
- var connection = mysql.createConnection({
- host : host,
- user : username,
- password : password,
- database : 'lambdadb'
- })
- var query = event.query
- var result
- connection.connect()
-
- connection.query(query, function (error, results, fields) {
- if (error) throw error
- console.log("Ran query: " + query)
- for (result in results)
- console.log(results[result])
- })
-
- return new Promise( ( resolve, reject ) => {
- connection.end( err => {
- if ( err )
- return reject( err )
- const response = {
- statusCode: 200,
- body: JSON.stringify(result),
- }
- resolve(response)
- })
- })
-}
diff --git a/sample-apps/rds-mysql/dbadmin/package.json b/sample-apps/rds-mysql/dbadmin/package.json
deleted file mode 100644
index 774c74cf..00000000
--- a/sample-apps/rds-mysql/dbadmin/package.json
+++ /dev/null
@@ -1,12 +0,0 @@
-{
- "name": "list-manager-processor",
- "version": "1.0.0",
- "private": true,
- "dependencies": {},
- "devDependencies": {
- "aws-xray-sdk-core": "2.4.0",
- "aws-xray-sdk-mysql": "2.4.0",
- "mysql": "2.17.1"
- },
- "scripts": {}
-}
diff --git a/sample-apps/rds-mysql/events/db-add-column.json b/sample-apps/rds-mysql/events/db-add-column.json
deleted file mode 100644
index 84e11d21..00000000
--- a/sample-apps/rds-mysql/events/db-add-column.json
+++ /dev/null
@@ -1,3 +0,0 @@
-{
- "query": "ALTER TABLE test ADD type varchar(255)"
-}
\ No newline at end of file
diff --git a/sample-apps/rds-mysql/events/db-clear-table.json b/sample-apps/rds-mysql/events/db-clear-table.json
deleted file mode 100644
index 6f0695e5..00000000
--- a/sample-apps/rds-mysql/events/db-clear-table.json
+++ /dev/null
@@ -1,3 +0,0 @@
-{
- "query": "DELETE FROM test"
-}
\ No newline at end of file
diff --git a/sample-apps/rds-mysql/events/db-create-table.json b/sample-apps/rds-mysql/events/db-create-table.json
deleted file mode 100644
index 4cf6499e..00000000
--- a/sample-apps/rds-mysql/events/db-create-table.json
+++ /dev/null
@@ -1,3 +0,0 @@
-{
- "query": "CREATE TABLE test ( id varchar(255), title varchar(255), timestamp BIGINT, entries varchar(32765));"
-}
\ No newline at end of file
diff --git a/sample-apps/rds-mysql/events/db-drop-table.json b/sample-apps/rds-mysql/events/db-drop-table.json
deleted file mode 100644
index 987f8c81..00000000
--- a/sample-apps/rds-mysql/events/db-drop-table.json
+++ /dev/null
@@ -1,3 +0,0 @@
-{
- "query": "DROP TABLE test"
-}
\ No newline at end of file
diff --git a/sample-apps/rds-mysql/events/db-read-table.json b/sample-apps/rds-mysql/events/db-read-table.json
deleted file mode 100644
index fb4f42cb..00000000
--- a/sample-apps/rds-mysql/events/db-read-table.json
+++ /dev/null
@@ -1,3 +0,0 @@
-{
- "query": "SELECT * FROM test"
-}
\ No newline at end of file
diff --git a/sample-apps/rds-mysql/images/rdsmysql-application.png b/sample-apps/rds-mysql/images/rdsmysql-application.png
deleted file mode 100644
index f45ea314..00000000
Binary files a/sample-apps/rds-mysql/images/rdsmysql-application.png and /dev/null differ
diff --git a/sample-apps/rds-mysql/images/rdsmysql-servicemap.png b/sample-apps/rds-mysql/images/rdsmysql-servicemap.png
deleted file mode 100644
index b93481fa..00000000
Binary files a/sample-apps/rds-mysql/images/rdsmysql-servicemap.png and /dev/null differ
diff --git a/sample-apps/rds-mysql/images/rdsmysql-trace.png b/sample-apps/rds-mysql/images/rdsmysql-trace.png
deleted file mode 100644
index cecd81cc..00000000
Binary files a/sample-apps/rds-mysql/images/rdsmysql-trace.png and /dev/null differ
diff --git a/sample-apps/rds-mysql/images/sample-rdsmysql.png b/sample-apps/rds-mysql/images/sample-rdsmysql.png
deleted file mode 100644
index c53a7aed..00000000
Binary files a/sample-apps/rds-mysql/images/sample-rdsmysql.png and /dev/null differ
diff --git a/sample-apps/rds-mysql/lib/nodejs/package.json b/sample-apps/rds-mysql/lib/nodejs/package.json
deleted file mode 100644
index f5859d75..00000000
--- a/sample-apps/rds-mysql/lib/nodejs/package.json
+++ /dev/null
@@ -1,12 +0,0 @@
-{
- "name": "lib-layer",
- "version": "1.0.0",
- "private": true,
- "dependencies": {
- "aws-xray-sdk-core": "2.4.0",
- "aws-xray-sdk-mysql": "2.4.0",
- "md5": "2.2.1",
- "mysql": "2.17.1"
- },
- "scripts": {}
-}
diff --git a/sample-apps/rds-mysql/template-vpcrds.yml b/sample-apps/rds-mysql/template-vpcrds.yml
deleted file mode 100644
index 378952b0..00000000
--- a/sample-apps/rds-mysql/template-vpcrds.yml
+++ /dev/null
@@ -1,125 +0,0 @@
-AWSTemplateFormatVersion: 2010-09-09
-Parameters:
- databaseName:
- Default: lambdadb
- Description: Database name
- Type: String
- MinLength: '1'
- MaxLength: '64'
- AllowedPattern: '[a-zA-Z][a-zA-Z0-9]*'
- ConstraintDescription: Begin with a letter and use only alphanumeric characters.
- databaseUser:
- NoEcho: 'true'
- Description: Database username
- Default: admin
- Type: String
- MinLength: '1'
- MaxLength: '16'
- AllowedPattern: '[a-zA-Z][a-zA-Z0-9]*'
- ConstraintDescription: Begin with a letter and use only alphanumeric characters.
-Resources:
- databaseSubnetGroup:
- Type: AWS::RDS::DBSubnetGroup
- Properties:
- DBSubnetGroupDescription: Subnets
- SubnetIds:
- - !Ref privateSubnetA
- - !Ref privateSubnetB
- database:
- Type: AWS::RDS::DBInstance
- Properties:
- DBName: !Ref databaseName
- AllocatedStorage: '10'
- DBInstanceClass: db.t3.small
- Engine: MySQL
- EngineVersion: 5.7.26
- MasterUsername: !Ref 'databaseUser'
- MasterUserPassword: '{{resolve:secretsmanager:rds-mysql-admin:SecretString:password}}'
- DeletionProtection: true
- MultiAZ: true
- DBSubnetGroupName: !Ref databaseSubnetGroup
- VPCSecurityGroups:
- - !GetAtt privateVPC.DefaultSecurityGroup
- privateVPC:
- Type: AWS::EC2::VPC
- Properties:
- CidrBlock: 172.31.0.0/16
- Tags:
- - Key: Name
- Value: !Ref AWS::StackName
- privateSubnetA:
- Type: AWS::EC2::Subnet
- Properties:
- VpcId: !Ref privateVPC
- AvailabilityZone:
- Fn::Select:
- - 0
- - Fn::GetAZs: ""
- CidrBlock: 172.31.3.0/24
- MapPublicIpOnLaunch: false
- Tags:
- - Key: Name
- Value: !Join ["-", [!Ref "AWS::StackName","subnet-a"]]
- privateSubnetB:
- Type: AWS::EC2::Subnet
- Properties:
- VpcId: !Ref privateVPC
- AvailabilityZone:
- Fn::Select:
- - 1
- - Fn::GetAZs: ""
- CidrBlock: 172.31.2.0/24
- MapPublicIpOnLaunch: false
- Tags:
- - Key: Name
- Value: !Join ["-", [!Ref "AWS::StackName","subnet-b"]]
- privateRouteTable:
- Type: AWS::EC2::RouteTable
- Properties:
- VpcId: !Ref privateVPC
- privateSubnetARouteTableAssociation:
- Type: AWS::EC2::SubnetRouteTableAssociation
- Properties:
- SubnetId: !Ref privateSubnetA
- RouteTableId: !Ref privateRouteTable
- privateSubnetBRouteTableAssociation:
- Type: AWS::EC2::SubnetRouteTableAssociation
- Properties:
- SubnetId: !Ref privateSubnetB
- RouteTableId: !Ref privateRouteTable
-Outputs:
- privateVPCSecurityGroup:
- Description: Default security for Lambda VPC
- Value: !GetAtt privateVPC.DefaultSecurityGroup
- Export:
- Name: !Join ["-", [!Ref "AWS::StackName","vpc-sg"]]
- privateVPCID:
- Description: VPC ID
- Value: !Ref privateVPC
- Export:
- Name: !Join ["-", [!Ref "AWS::StackName","vpc"]]
- privateSubnetAID:
- Description: Private Subnet A ID
- Value: !Ref privateSubnetA
- Export:
- Name: !Join ["-", [!Ref "AWS::StackName","subnet-a"]]
- privateSubnetBID:
- Description: Private Subnet B ID
- Value: !Ref privateSubnetB
- Export:
- Name: !Join ["-", [!Ref "AWS::StackName","subnet-b"]]
- databaseHost:
- Description: Database hostname
- Value: !GetAtt database.Endpoint.Address
- Export:
- Name: !Join ["-", [!Ref "AWS::StackName","db-host"]]
- databaseName:
- Description: Database name
- Value: !Ref databaseName
- Export:
- Name: !Join ["-", [!Ref "AWS::StackName","db-name"]]
- databaseUser:
- Description: Database user
- Value: !Ref databaseUser
- Export:
- Name: !Join ["-", [!Ref "AWS::StackName","db-user"]]
diff --git a/sample-apps/rds-mysql/template.yml b/sample-apps/rds-mysql/template.yml
deleted file mode 100644
index a81c1f4a..00000000
--- a/sample-apps/rds-mysql/template.yml
+++ /dev/null
@@ -1,61 +0,0 @@
-AWSTemplateFormatVersion: 2010-09-09
-Description: An AWS Lambda application that connects to a MySQL database in the VPC to run SQL queries.
-Transform: AWS::Serverless-2016-10-31
-Parameters:
- vpcStackName:
- Default: rds-mysql-vpc
- Description: VPC and database stack name
- Type: String
- secretName:
- Default: rds-mysql-admin
- Description: Database password secret name
- Type: String
-Globals:
- Function:
- Runtime: nodejs12.x
- Tracing: Active
- Handler: index.handler
- Environment:
- Variables:
- databaseHost:
- Fn::ImportValue:
- !Sub "${vpcStackName}-db-host"
- databaseName:
- Fn::ImportValue:
- !Sub "${vpcStackName}-db-name"
- databaseUser:
- Fn::ImportValue:
- !Sub "${vpcStackName}-db-user"
- databasePassword: !Sub '{{resolve:secretsmanager:${secretName}:SecretString:password}}'
- VpcConfig:
- SecurityGroupIds:
- - Fn::ImportValue:
- !Sub "${vpcStackName}-vpc-sg"
- SubnetIds:
- - Fn::ImportValue:
- !Sub "${vpcStackName}-subnet-a"
- - Fn::ImportValue:
- !Sub "${vpcStackName}-subnet-b"
- Layers:
- - !Ref libs
-Resources:
- libs:
- Type: AWS::Serverless::LayerVersion
- Properties:
- LayerName: rds-mysql-lib
- Description: Dependencies for the rds-mysql sample app.
- ContentUri: lib/.
- CompatibleRuntimes:
- - nodejs10.x
- - nodejs12.x
- dbadmin:
- Type: AWS::Serverless::Function
- Properties:
- CodeUri: dbadmin/.
- Description: Run SQL queries.
- MemorySize: 128
- Timeout: 15
- # Function's execution role
- Policies:
- - AWSLambdaBasicExecutionRole
- - AWSLambdaVPCAccessExecutionRole
diff --git a/sample-apps/s3-java/2-build-layer.sh b/sample-apps/s3-java/2-build-layer.sh
index 6483568e..621eb256 100755
--- a/sample-apps/s3-java/2-build-layer.sh
+++ b/sample-apps/s3-java/2-build-layer.sh
@@ -1,4 +1,4 @@
#!/bin/bash
set -eo pipefail
-gradle -q packageLibs
+gradle -q packageJar
mv build/distributions/s3-java.zip build/s3-java-lib.zip
\ No newline at end of file
diff --git a/sample-apps/s3-java/5-invoke.sh b/sample-apps/s3-java/5-invoke.sh
index d65db099..9399b6ca 100755
--- a/sample-apps/s3-java/5-invoke.sh
+++ b/sample-apps/s3-java/5-invoke.sh
@@ -9,7 +9,7 @@ if [ ! -f event.json ]; then
fi
while true; do
- aws lambda invoke --function-name $FUNCTION --payload file://event.json out.json
+ aws lambda invoke --function-name $FUNCTION --payload fileb://event.json out.json
cat out.json
echo ""
sleep 2
diff --git a/sample-apps/s3-java/README.md b/sample-apps/s3-java/README.md
index 407063bf..55601044 100644
--- a/sample-apps/s3-java/README.md
+++ b/sample-apps/s3-java/README.md
@@ -4,7 +4,7 @@
The project source includes function code and supporting resources:
-- `src/main` - A Java function.
+- `src/main` - A Java Lambda function that scales down an image stored in S3.
- `src/test` - A unit test and helper classes.
- `template.yml` - An AWS CloudFormation template that creates an application.
- `build.gradle` - A Gradle build file.
@@ -14,10 +14,10 @@ The project source includes function code and supporting resources:
Use the following instructions to deploy the sample application.
# Requirements
-- [Java 8 runtime environment (SE JRE)](https://www.oracle.com/java/technologies/javase-downloads.html)
-- [Gradle 5](https://gradle.org/releases/)
+- [Java 21 runtime environment (SE JRE)](https://www.oracle.com/java/technologies/javase-downloads.html)
+- [Gradle 5](https://gradle.org/releases/) or [Maven 3](https://maven.apache.org/docs/history.html)
- The Bash shell. For Linux and macOS, this is included by default. In Windows 10, you can install the [Windows Subsystem for Linux](https://docs.microsoft.com/en-us/windows/wsl/install-win10) to get a Windows-integrated version of Ubuntu and Bash.
-- [The AWS CLI v1](https://docs.aws.amazon.com/cli/latest/userguide/cli-chap-install.html).
+- [The AWS CLI](https://docs.aws.amazon.com/cli/latest/userguide/cli-chap-install.html) v1.17 or newer.
# Setup
Download or clone this repository.
@@ -55,10 +55,14 @@ You can also build the application with Maven. To use maven, add `mvn` to the co
...
# Test
-To upload an image file to the application bucket and trigger the function, run `4-upload.sh`.
+This Lambda function takes an image that's currently stored in S3, and scales it down into
+a thumbnail-sized image. To upload an image file to the application bucket, run `4-upload.sh`.
s3-java$ ./4-upload.sh
+In your `s3-java-bucket-` bucket that was created in step 3, you should now see a
+key `inbound/sample-s3-java.png` file, which represents the original image.
+
To invoke the function directly, run `5-invoke.sh`.
s3-java$ ./5-invoke.sh
@@ -69,6 +73,9 @@ To invoke the function directly, run `5-invoke.sh`.
Let the script invoke the function a few times and then press `CRTL+C` to exit.
+If you look at the `s3-java-bucket-` bucket in your account, you should now see a
+key `resized-inbound/sample-s3-java.png` file, which represents the new, shrunken image.
+
The application uses AWS X-Ray to trace requests. Open the [X-Ray console](https://console.aws.amazon.com/xray/home#/service-map) to view the service map.

diff --git a/sample-apps/s3-java/build.gradle b/sample-apps/s3-java/build.gradle
index 2ab2d35a..d1029343 100644
--- a/sample-apps/s3-java/build.gradle
+++ b/sample-apps/s3-java/build.gradle
@@ -7,18 +7,15 @@ repositories {
}
dependencies {
- implementation platform('com.amazonaws:aws-xray-recorder-sdk-bom:2.4.0')
- implementation 'com.amazonaws:aws-lambda-java-core:1.2.0'
- implementation 'com.amazonaws:aws-lambda-java-events:2.2.7'
- implementation 'com.amazonaws:aws-java-sdk-s3:1.11.578'
+ implementation platform('software.amazon.awssdk:bom:2.16.1')
+ implementation platform('com.amazonaws:aws-xray-recorder-sdk-bom:2.11.0')
+ implementation 'software.amazon.awssdk:s3'
+ implementation 'com.amazonaws:aws-lambda-java-core:1.2.1'
+ implementation 'com.amazonaws:aws-lambda-java-events:3.11.0'
implementation 'com.amazonaws:aws-xray-recorder-sdk-core'
implementation 'com.amazonaws:aws-xray-recorder-sdk-aws-sdk'
- implementation 'com.amazonaws:aws-xray-recorder-sdk-aws-sdk-instrumentor'
- implementation 'com.google.code.gson:gson:2.8.6'
- implementation 'org.apache.logging.log4j:log4j-api:2.13.0'
- implementation 'org.apache.logging.log4j:log4j-core:2.13.0'
- implementation 'org.apache.logging.log4j:log4j-slf4j18-impl:2.13.0'
- runtimeOnly 'com.amazonaws:aws-lambda-java-log4j2:1.1.0'
+ implementation 'com.amazonaws:aws-xray-recorder-sdk-aws-sdk-v2-instrumentor'
+ implementation 'org.slf4j:slf4j-nop:2.0.6'
testImplementation 'org.junit.jupiter:junit-jupiter-api:5.6.0'
testRuntimeOnly 'org.junit.jupiter:junit-jupiter-engine:5.6.0'
}
@@ -27,28 +24,16 @@ test {
useJUnitPlatform()
}
-task packageBig(type: Zip) {
- from compileJava
- from processResources
+task packageJar(type: Zip) {
into('lib') {
- from configurations.runtimeClasspath
+ from(jar)
+ from(configurations.runtimeClasspath)
}
}
-task packageLibs(type: Zip) {
- into('java/lib') {
- from configurations.runtimeClasspath
- }
-}
-
-task packageSmall(type: Zip) {
- from compileJava
- from processResources
-}
-
java {
- sourceCompatibility = JavaVersion.VERSION_1_8
- targetCompatibility = JavaVersion.VERSION_1_8
+ sourceCompatibility = JavaVersion.VERSION_21
+ targetCompatibility = JavaVersion.VERSION_21
}
-build.dependsOn packageSmall
+build.dependsOn packageJar
diff --git a/sample-apps/java-events-v1sdk/event.json b/sample-apps/s3-java/event.json-e
similarity index 95%
rename from sample-apps/java-events-v1sdk/event.json
rename to sample-apps/s3-java/event.json-e
index 94c28f5c..375e90ab 100644
--- a/sample-apps/java-events-v1sdk/event.json
+++ b/sample-apps/s3-java/event.json-e
@@ -23,7 +23,7 @@
"arn": "arn:aws:s3:::BUCKET_NAME"
},
"object": {
- "key": "inbound/sample-java-s3.png",
+ "key": "inbound/sample-s3-java.png",
"size": 21476,
"eTag": "d132690b6c65b6d1629721dcfb49b883",
"versionId": "",
diff --git a/sample-apps/s3-java/pom.xml b/sample-apps/s3-java/pom.xml
index ce4b7f06..c8099a40 100644
--- a/sample-apps/s3-java/pom.xml
+++ b/sample-apps/s3-java/pom.xml
@@ -8,69 +8,60 @@
s3-java-function
UTF-8
- 1.8
- 1.8
+ 21
+ 21
+
+
+
+
+ software.amazon.awssdk
+ bom
+ 2.16.1
+ pom
+ import
+
+
+ com.amazonaws
+ aws-xray-recorder-sdk-bom
+ 2.11.0
+ pom
+ import
+
+
+
+
- com.amazonaws
- aws-lambda-java-core
- 1.2.0
+ software.amazon.awssdk
+ s3
com.amazonaws
- aws-lambda-java-events
- 2.2.7
-
-
- com.amazonaws
- aws-lambda-java-log4j2
- 1.1.0
-
-
- com.google.code.gson
- gson
- 2.8.6
-
-
- org.apache.logging.log4j
- log4j-api
- 2.13.0
-
-
- org.apache.logging.log4j
- log4j-core
- 2.13.0
-
-
- org.apache.logging.log4j
- log4j-slf4j18-impl
- 2.13.0
+ aws-lambda-java-core
+ 1.2.1
com.amazonaws
- aws-java-sdk-s3
- 1.11.578
+ aws-lambda-java-events
+ 3.11.0
com.amazonaws
aws-xray-recorder-sdk-core
- 2.4.0
com.amazonaws
- aws-xray-recorder-sdk-aws-sdk-core
- 2.4.0
+ aws-xray-recorder-sdk-aws-sdk
com.amazonaws
- aws-xray-recorder-sdk-aws-sdk
- 2.4.0
+ aws-xray-recorder-sdk-aws-sdk-v2-instrumentor
- com.amazonaws
- aws-xray-recorder-sdk-aws-sdk-instrumentor
- 2.4.0
+ org.slf4j
+ slf4j-nop
+ 2.0.13
org.junit.jupiter
@@ -95,7 +86,7 @@
org.apache.maven.plugins
maven-shade-plugin
- 3.2.2
+ 3.5.2
false
@@ -105,29 +96,17 @@
shade
-
-
-
-
-
-