Skip to content

Latest commit

 

History

History
188 lines (151 loc) · 7.38 KB

File metadata and controls

188 lines (151 loc) · 7.38 KB

AWS Lambda Java Runtime Interface Client

We have open-sourced a set of software packages, Runtime Interface Clients (RIC), that implement the Lambda Runtime API, allowing you to seamlessly extend your preferred base images to be Lambda compatible. The Lambda Runtime Interface Client is a lightweight interface that allows your runtime to receive requests from and send requests to the Lambda service.

You can include this package in your preferred base image to make that base image Lambda compatible.

Usage

Creating a Docker Image for Lambda with the Runtime Interface Client

Choose a preferred base image. The Runtime Interface Client is tested on Amazon Linux, Alpine, Ubuntu, Debian, and CentOS. The requirements are that the image is:

  • built for x86_64 and ARM64
  • contains Java >= 8
  • contains glibc >= 2.17 or musl

Example

The Runtime Interface Client library can be installed into the image separate from the function code, but the simplest approach to keeping the Dockerfile simple is to include the library as a part of the function's dependencies!

Dockerfile

# we'll use Amazon Linux 2 + Corretto 11 as our base
FROM public.ecr.aws/amazoncorretto/amazoncorretto:11 as base

# configure the build environment
FROM base as build
RUN yum install -y maven
WORKDIR /src

# cache and copy dependencies
ADD pom.xml .
RUN mvn dependency:go-offline dependency:copy-dependencies

# compile the function
ADD . .
RUN mvn package

# copy the function artifact and dependencies onto a clean base
FROM base
WORKDIR /function

COPY --from=build /src/target/dependency/*.jar ./
COPY --from=build /src/target/*.jar ./

# configure the runtime startup as main
ENTRYPOINT [ "/usr/bin/java", "-cp", "./*", "com.amazonaws.services.lambda.runtime.api.client.AWSLambda" ]
# pass the name of the function handler as an argument to the runtime
CMD [ "example.App::sayHello" ]

pom.xml

<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 http://maven.apache.org/maven-v4_0_0.xsd">
  <modelVersion>4.0.0</modelVersion>
  <groupId>example</groupId>
  <artifactId>hello-lambda</artifactId>
  <packaging>jar</packaging>
  <version>1.0-SNAPSHOT</version>
  <name>hello-lambda</name>
  <url>http://maven.apache.org</url>
  <properties>
    <maven.compiler.source>1.8</maven.compiler.source>
    <maven.compiler.target>1.8</maven.compiler.target>
  </properties>
  <dependencies>
    <dependency>
      <groupId>com.amazonaws</groupId>
      <artifactId>aws-lambda-java-runtime-interface-client</artifactId>
      <version>2.5.1</version>
    </dependency>
  </dependencies>
  <build>
    <plugins>
      <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-dependency-plugin</artifactId>
        <version>3.1.2</version>
        <executions>
          <execution>
            <id>copy-dependencies</id>
            <phase>package</phase>
            <goals>
              <goal>copy-dependencies</goal>
            </goals>
          </execution>
        </executions>
      </plugin>
    </plugins>
  </build>
</project>

src/main/java/example/App.java

package example;

public class App {
    public static String sayHello() {
        return "Hello λ!";
    }
}

Local Testing

To make it easy to locally test Lambda functions packaged as container images we open-sourced a lightweight web-server, Lambda Runtime Interface Emulator (RIE), which allows your function packaged as a container image to accept HTTP requests. You can install the AWS Lambda Runtime Interface Emulator on your local machine to test your function. Then when you run the image function, you set the entrypoint to be the emulator.

To install the emulator and test your Lambda function

  1. Run the following command to download the RIE from GitHub and install it on your local machine.
mkdir -p ~/.aws-lambda-rie && \
    curl -Lo ~/.aws-lambda-rie/aws-lambda-rie https://github.com/aws/aws-lambda-runtime-interface-emulator/releases/latest/download/aws-lambda-rie && \
    chmod +x ~/.aws-lambda-rie/aws-lambda-rie
  1. Run your Lambda image function using the docker run command.
docker run -d -v ~/.aws-lambda-rie:/aws-lambda -p 9000:8080 \
    --entrypoint /aws-lambda/aws-lambda-rie \
    myfunction:latest \
    /usr/bin/java -cp './*' com.amazonaws.services.lambda.runtime.api.client.AWSLambda example.App::sayHello

This runs the image as a container and starts up an endpoint locally at http://localhost:9000/2015-03-31/functions/function/invocations.

  1. Post an event to the following endpoint using a curl command:
curl -XPOST "http://localhost:9000/2015-03-31/functions/function/invocations" -d '{}'

This command invokes the function running in the container image and returns a response.

Alternately, you can also include RIE as a part of your base image. See the AWS documentation on how to Build RIE into your base image.

Troubleshooting

While running integration tests, you might encounter the Docker Hub rate limit error with the following body:

You have reached your pull rate limit. You may increase the limit by authenticating and upgrading: https://www.docker.com/increase-rate-limits

To fix the above issue, consider authenticating to a Docker Hub account by setting the Docker Hub credentials as below CodeBuild environment variables.

DOCKERHUB_USERNAME=<dockerhub username>
DOCKERHUB_PASSWORD=<dockerhub password>

Recommended way is to set the Docker Hub credentials in CodeBuild job by retrieving them from AWS Secrets Manager.

Configuration

The aws-lambda-java-runtime-interface-client JAR is a large uber jar, which contains compiled C libraries for x86_64 and aarch_64 for glibc and musl LIBC implementations. If the size is an issue, you can pick a smaller platform-specific JAR by setting the <classifier>.

<!-- Platform-specific Linux x86_64 JAR -->
<dependency>
    <groupId>com.amazonaws</groupId>
    <artifactId>aws-lambda-java-runtime-interface-client</artifactId>
    <version>2.5.1</version>
    <classifier>linux-x86_64</classifier>
</dependency>

Available platform classifiers: linux-x86_64, linux-aarch_64, linux_musl-aarch_64, linux_musl-x86_64

The Lambda runtime interface client tries to load compatible library during execution, by unpacking it to a temporary location /tmp/.libaws-lambda-jni.so. If this behaviour is not desirable, it is possible to extract the .so files during build time and specify the location via com.amazonaws.services.lambda.runtime.api.client.runtimeapi.NativeClient.JNI system property, like

ENTRYPOINT [ "/usr/bin/java",
"-Dcom.amazonaws.services.lambda.runtime.api.client.runtimeapi.NativeClient.JNI=/function/libaws-lambda-jni.linux_x86_64.so"
"-cp", "./*",
"com.amazonaws.services.lambda.runtime.api.client.AWSLambda" ]

Security

If you discover a potential security issue in this project we ask that you notify AWS/Amazon Security via our vulnerability reporting page. Please do not create a public github issue.

License

This project is licensed under the Apache-2.0 License.