GH-530, GH-630 Improvements to AWS Custom Runtime
This commit provides initial set of improvements to executing functions in AWS Custom Runtime - Consistent invocation model for functional as well as @Bean configuration models via new CustomRuntimeEventLoop as well as AWSLambdaUtils - Clean up classpath to decrease the size of the JAR/ZIP file - Configuration simplification which no longer requires enabling of function exporter It also allows user to define functions that rely on AWS types such as APIGatewayProxyRequestEvent The existing invocation model remains in tact for the time being. Both invocation models are mutually exclusing in theit setup to avoid potential conflict. Resolves #538 Resolves #630
This commit is contained in:
@@ -0,0 +1,12 @@
|
||||
This sample uses the custom runtime type on AWS lambda using @Bean style configuration.
|
||||
However, changing configuration to functional bean registration is supported as well and shown in `function-sample-aws-custom` example.
|
||||
|
||||
To run the app in AWS choose the "Custom Runtime" runtime type, and upload the
|
||||
.zip file that gets built on the command line with `mvn package` (look
|
||||
in `target`).
|
||||
There are several functions defined in the `com.example.LambdaApplication`, so identify the selected function in "Handler"
|
||||
You can also use function composition (e.g., `uppercase|reverse`)
|
||||
|
||||
You can test any function in this example with any String as input, but the Lambda UI only allows valid JSON as
|
||||
test data, so you will have to escape the input with double quotes.
|
||||
|
||||
@@ -0,0 +1,210 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<parent>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-parent</artifactId>
|
||||
<version>2.4.2-SNAPSHOT</version>
|
||||
<relativePath /> <!-- lookup parent from repository -->
|
||||
</parent>
|
||||
<groupId>io.spring.sample</groupId>
|
||||
<artifactId>function-sample-aws-custom-bean</artifactId>
|
||||
<version>3.0.0.RELEASE</version>
|
||||
<name>AWS Custom Runtime - @Bean sample</name>
|
||||
<description>Demo project for Spring Cloud Function with custom AWS Lambda runtime using @Bean style</description>
|
||||
|
||||
<properties>
|
||||
<java.version>1.8</java.version>
|
||||
<wrapper.version>1.0.22.RELEASE</wrapper.version>
|
||||
<spring-cloud-function.version>3.1.1-SNAPSHOT</spring-cloud-function.version>
|
||||
</properties>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<!--
|
||||
We don't need this dependency unless explicitly using APIGatewayProxyRequestEvent
|
||||
(as on of the function in this example)
|
||||
-->
|
||||
<groupId>com.amazonaws</groupId>
|
||||
<artifactId>aws-lambda-java-events</artifactId>
|
||||
<version>2.2.6</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.springframework.cloud</groupId>
|
||||
<artifactId>spring-cloud-function-adapter-aws</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.slf4j</groupId>
|
||||
<artifactId>slf4j-jdk14</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-test</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.awaitility</groupId>
|
||||
<artifactId>awaitility</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.testcontainers</groupId>
|
||||
<artifactId>testcontainers</artifactId>
|
||||
<version>1.14.3</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<dependencyManagement>
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.springframework.cloud</groupId>
|
||||
<artifactId>spring-cloud-function-dependencies</artifactId>
|
||||
<version>${spring-cloud-function.version}</version>
|
||||
<type>pom</type>
|
||||
<scope>import</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</dependencyManagement>
|
||||
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<artifactId>maven-surefire-plugin</artifactId>
|
||||
<configuration>
|
||||
<excludes>
|
||||
<exclude>com/example/ContainerTests.java</exclude>
|
||||
</excludes>
|
||||
</configuration>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-deploy-plugin</artifactId>
|
||||
<configuration>
|
||||
<skip>true</skip>
|
||||
</configuration>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-maven-plugin</artifactId>
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot.experimental</groupId>
|
||||
<artifactId>spring-boot-thin-layout</artifactId>
|
||||
<version>${wrapper.version}</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<artifactId>maven-assembly-plugin</artifactId>
|
||||
<executions>
|
||||
<execution>
|
||||
<id>zip</id>
|
||||
<phase>package</phase>
|
||||
<goals>
|
||||
<goal>single</goal>
|
||||
</goals>
|
||||
<inherited>false</inherited>
|
||||
</execution>
|
||||
</executions>
|
||||
<configuration>
|
||||
<descriptors>
|
||||
<descriptor>src/assembly/zip.xml</descriptor>
|
||||
</descriptors>
|
||||
</configuration>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
<profiles>
|
||||
<profile>
|
||||
<id>integration</id>
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<artifactId>maven-surefire-plugin</artifactId>
|
||||
<version>2.22.0</version>
|
||||
<executions>
|
||||
<execution>
|
||||
<phase>integration-test</phase>
|
||||
<goals>
|
||||
<goal>test</goal>
|
||||
</goals>
|
||||
<configuration>
|
||||
<excludes>
|
||||
<exclude>none</exclude>
|
||||
</excludes>
|
||||
<includes>
|
||||
<include>com/example/ContainerTests.java</include>
|
||||
</includes>
|
||||
</configuration>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
</profile>
|
||||
</profiles>
|
||||
|
||||
<!-- <repositories> -->
|
||||
<!-- <repository> -->
|
||||
<!-- <id>spring-snapshots</id> -->
|
||||
<!-- <name>Spring Snapshots</name> -->
|
||||
<!-- <url>https://repo.spring.io/libs-snapshot-local</url> -->
|
||||
<!-- <snapshots> -->
|
||||
<!-- <enabled>true</enabled> -->
|
||||
<!-- </snapshots> -->
|
||||
<!-- <releases> -->
|
||||
<!-- <enabled>false</enabled> -->
|
||||
<!-- </releases> -->
|
||||
<!-- </repository> -->
|
||||
<!-- <repository> -->
|
||||
<!-- <id>spring-milestones</id> -->
|
||||
<!-- <name>Spring Milestones</name> -->
|
||||
<!-- <url>https://repo.spring.io/libs-milestone-local</url> -->
|
||||
<!-- <snapshots> -->
|
||||
<!-- <enabled>false</enabled> -->
|
||||
<!-- </snapshots> -->
|
||||
<!-- </repository> -->
|
||||
<!-- <repository> -->
|
||||
<!-- <id>spring-releases</id> -->
|
||||
<!-- <name>Spring Releases</name> -->
|
||||
<!-- <url>https://repo.spring.io/release</url> -->
|
||||
<!-- <snapshots> -->
|
||||
<!-- <enabled>false</enabled> -->
|
||||
<!-- </snapshots> -->
|
||||
<!-- </repository> -->
|
||||
<!-- </repositories> -->
|
||||
<!-- <pluginRepositories> -->
|
||||
<!-- <pluginRepository> -->
|
||||
<!-- <id>spring-snapshots</id> -->
|
||||
<!-- <name>Spring Snapshots</name> -->
|
||||
<!-- <url>https://repo.spring.io/libs-snapshot-local</url> -->
|
||||
<!-- <snapshots> -->
|
||||
<!-- <enabled>true</enabled> -->
|
||||
<!-- </snapshots> -->
|
||||
<!-- <releases> -->
|
||||
<!-- <enabled>false</enabled> -->
|
||||
<!-- </releases> -->
|
||||
<!-- </pluginRepository> -->
|
||||
<!-- <pluginRepository> -->
|
||||
<!-- <id>spring-milestones</id> -->
|
||||
<!-- <name>Spring Milestones</name> -->
|
||||
<!-- <url>https://repo.spring.io/libs-milestone-local</url> -->
|
||||
<!-- <snapshots> -->
|
||||
<!-- <enabled>false</enabled> -->
|
||||
<!-- </snapshots> -->
|
||||
<!-- </pluginRepository> -->
|
||||
<!-- <pluginRepository> -->
|
||||
<!-- <id>spring-releases</id> -->
|
||||
<!-- <name>Spring Releases</name> -->
|
||||
<!-- <url>https://repo.spring.io/libs-release-local</url> -->
|
||||
<!-- <snapshots> -->
|
||||
<!-- <enabled>false</enabled> -->
|
||||
<!-- </snapshots> -->
|
||||
<!-- </pluginRepository> -->
|
||||
<!-- </pluginRepositories> -->
|
||||
</project>
|
||||
@@ -0,0 +1,35 @@
|
||||
<assembly xmlns="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.2"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.2 https://maven.apache.org/xsd/assembly-1.1.2.xsd">
|
||||
<id>zip</id>
|
||||
<formats>
|
||||
<format>zip</format>
|
||||
</formats>
|
||||
<baseDirectory></baseDirectory>
|
||||
<fileSets>
|
||||
<fileSet>
|
||||
<directory>target/classes</directory>
|
||||
<outputDirectory>/</outputDirectory>
|
||||
<useDefaultExcludes>true</useDefaultExcludes>
|
||||
<excludes>
|
||||
<exclude>bootstrap</exclude>
|
||||
</excludes>
|
||||
</fileSet>
|
||||
<fileSet>
|
||||
<directory>target/classes</directory>
|
||||
<outputDirectory>/</outputDirectory>
|
||||
<useDefaultExcludes>true</useDefaultExcludes>
|
||||
<fileMode>0775</fileMode>
|
||||
<includes>
|
||||
<include>bootstrap</include>
|
||||
</includes>
|
||||
</fileSet>
|
||||
</fileSets>
|
||||
<dependencySets>
|
||||
<dependencySet>
|
||||
<outputDirectory>/lib</outputDirectory>
|
||||
<unpack>false</unpack>
|
||||
<scope>runtime</scope>
|
||||
</dependencySet>
|
||||
</dependencySets>
|
||||
</assembly>
|
||||
@@ -0,0 +1,71 @@
|
||||
package com.example;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.function.Function;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
import org.springframework.boot.SpringApplication;
|
||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.messaging.Message;
|
||||
import org.springframework.util.ObjectUtils;
|
||||
|
||||
import com.amazonaws.services.lambda.runtime.events.APIGatewayProxyRequestEvent;
|
||||
|
||||
@SpringBootApplication
|
||||
public class LambdaApplication {
|
||||
|
||||
private static Log logger = LogFactory.getLog(LambdaApplication.class);
|
||||
|
||||
@Bean
|
||||
public Function<String, String> uppercase() {
|
||||
return value -> {
|
||||
logger.info("UPPERCASING: " + value);
|
||||
return value.toUpperCase();
|
||||
};
|
||||
}
|
||||
|
||||
@Bean
|
||||
public Function<APIGatewayProxyRequestEvent, String> extractPayloadFromGatewayEvent() {
|
||||
return value -> {
|
||||
logger.info("ECHO Payload from Gateway Event: " + value.getBody());
|
||||
return value.getBody();
|
||||
};
|
||||
}
|
||||
|
||||
@Bean
|
||||
public Function<Message<String>, Message<String>> echoMessage() {
|
||||
return value -> {
|
||||
logger.info("ECHO MESSAGE: " + value);
|
||||
return value;
|
||||
};
|
||||
}
|
||||
|
||||
@Bean
|
||||
public Function<String, String> reverse() {
|
||||
return value -> {
|
||||
logger.info("REVERSING: " + value);
|
||||
return new StringBuilder(value).reverse().toString();
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
|
||||
public static void main(String[] args) {
|
||||
System.out.println("=====> ENVIRONMENT: " + System.getenv("AWS_LAMBDA_RUNTIME_API"));
|
||||
//FunctionalSpringApplication.run(LambdaApplication.class, args);
|
||||
logger.info("==> Starting: LambdaApplication");
|
||||
if (!ObjectUtils.isEmpty(args)) {
|
||||
logger.info("==> args: " + Arrays.asList(args));
|
||||
}
|
||||
SpringApplication.run(LambdaApplication.class, args);
|
||||
}
|
||||
|
||||
// @Override
|
||||
// public void initialize(GenericApplicationContext context) {
|
||||
// context.registerBean("uppercase", FunctionRegistration.class,
|
||||
// () -> new FunctionRegistration<>(uppercase()).type(
|
||||
// FunctionType.from(String.class).to(String.class)));
|
||||
// }
|
||||
}
|
||||
@@ -0,0 +1,2 @@
|
||||
spring.main.web-application-type=none
|
||||
logging.level.org.springframework.cloud=DEBUG
|
||||
@@ -0,0 +1,8 @@
|
||||
#!/bin/sh
|
||||
|
||||
cd ${LAMBDA_TASK_ROOT:-.}
|
||||
|
||||
java -Dspring.main.web-application-type=none -Dspring.jmx.enabled=false \
|
||||
-noverify -XX:TieredStopAtLevel=1 -Xss256K -XX:MaxMetaspaceSize=128M \
|
||||
-Djava.security.egd=file:/dev/./urandom \
|
||||
-cp .:`echo lib/*.jar | tr ' ' :` com.example.LambdaApplication
|
||||
@@ -0,0 +1,6 @@
|
||||
#!/bin/sh
|
||||
|
||||
while true
|
||||
do
|
||||
sleep 1
|
||||
done
|
||||
Reference in New Issue
Block a user