We will introduce a step-by-step example of writing an AWS Lambda function in Java8, uploading it as a Lambda Function on AWS, and calling it from a Java client.
--People who can write Java and use AWS Lambda for the first time ――I used to make Lambda functions with node.js, but for some reason I'm trying to make it with Java (= like me)
TL; DR I will write in the first part and the second part
-** [Part 1] Easy to create Lambda function (cloud side) and client (local side) in Java ** ← This article -[Part 2] Synchronous and asynchronous call types (Invocation Type) of Lambda functions (cloud side), Java client side synchronous and asynchronous calls, and disclosure on API Gateway
――It is a wonderful service that can process various requests (events) just by giving the code to AWS Lambda without having to create and manage the server yourself.
http://docs.aws.amazon.com/ja_jp/lambda/latest/dg/welcome.html https://aws.amazon.com/jp/lambda/faqs/
--Alexa's Skills is also AWS Lambda You can create it with.
--It is possible to write AWS Lambda processing (Lambda function) in Java --You can also call Lambda functions directly from a Java client --Not limited to Java, but by linking with a service called API Gateway, you can create an endpoint in a Lambda function and publish it, and you can also call it via HTTP (S) such as GET or POST like Web API.
We will carry out the following steps one by one.
aws-lambda-java-core Add the library. When using maven, add the following description
maven
<dependency>
<groupId>com.amazonaws</groupId>
<artifactId>aws-lambda-java-core</artifactId>
<version>1.1.0</version>
</dependency>
Here, we will create a RequestResponse type Lambda function that returns a result when the function is called.
This time aws-lambda-java-core ** RequestHandler ** interface provided by the library To implement a Lambda function that can input and output POJO.
Below is a sample Lambda function that will output your full name when you enter your last name and first name.
MyLambda.java
package lambda.cloud;
import com.amazonaws.services.lambda.runtime.Context;
import com.amazonaws.services.lambda.runtime.RequestHandler;
import lambda.cloud.MyLambda.Input;
import lambda.cloud.MyLambda.Output;
public class MyLambda implements RequestHandler<Input, Output> {
@Override
public Output handleRequest(Input in, Context context) {
final Output out = new Output();
out.in = in;
out.fullName = in.firstName + "_" + in.lastName;
return out;
}
public static class Input {
public String firstName;
public String lastName;
}
public static class Output {
public Input in;
public String fullName;
}
}
Just implement the ** handleRequest ** method as shown below. The argument ** Input ** is the request and the return value ** Output ** is the response.
public Output handleRequest(Input in, Context context) {
Next, in order to be able to use it with AWS Lambda as a Lambda function, you need to package the code in a jar file (or zip) and upload it to AWS Lambda.
In this jar file, in addition to the code you just created, it is necessary to integrate the dependent libraries etc. together.
Add ** maven-shade-plugin ** under plugins in maven pom.xml to create a unified jar file (that is, fat jar).
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>3.1.0</version>
<configuration>
<createDependencyReducedPom>false</createDependencyReducedPom>
</configuration>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
</execution>
</executions>
</plugin>
pom.xml
The whole pom.xml looks like this
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>lambda.cloud</groupId>
<artifactId>mylambda</artifactId>
<version>1.0.0</version>
<packaging>jar</packaging>
<name>AWS lambda example</name>
<description>example of AWS lambda
</description>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<dependencies>
<dependency>
<groupId>com.amazonaws</groupId>
<artifactId>aws-lambda-java-core</artifactId>
<version>1.1.0</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>1.8</source>
<target>1.8</target>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>3.1.0</version>
<configuration>
<createDependencyReducedPom>false</createDependencyReducedPom>
</configuration>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
The full source code of the above sample is below https://github.com/riversun/aws_lambda_example_basic_client.git
** When cloning with Eclipse **
Now that you have a ** Maven project ** on Eclipse, it will be easier to handle.
-(1) ** When making a jar on the command line **
Execute the following command in the directory containing pom.xml
mvn packgage
-(2) ** When making a jar on Eclipse **
Step 1. Select ** Run As> Maven build ** from the right-click menu
Step 2. In the ** Edit configurations ** dialog, enter ** package shade: shade ** in ** Goals ** and ** Run **
In either case (1) (2), ** mylambda-1.0.0.jar ** containing all dependent code libraries will be generated under ** / target **.
This will be the jar file for your AWS Lambda upload.
Let's take a look at the steps to register a Lambda function from the AWS console
** (1) Open AWS Lambda ** Open your Lambda service.
** (2) Create a new Lambda function ** If you haven't created a Lambda function yet, the screen will look like the one below.
Click ** Create function **.
** (3) [Create from scratch] Lambda function **
The screen for selecting from the blue print list will appear as shown below. Select ** Author from scratch **.
** (4) Set the name and role on the basic information screen **
Here, we will create a Lambda function named ** myFunction **.
--Name is "** myFunction " --Role is " Create new role from template " --Role name is " myRole **"
When you're done, click ** Create function **
** (5) Upload the jar file **
STEP 1 First, check the ARN at the top of the screen Make a note of the ** arn: aws: lambda: ap-northeast-1: 000000000000: function: myFunction ** part displayed on the screen.
As you know * ARN (Amazon Resource Name) is for uniquely identifying AWS resources and is used to identify them when executing Lambda functions. *
STEP 2 Select ** Java 8 ** from the runtime
STEP 3 Enter ** lambda.cloud.MyLambda ** in the handler The handler name is described in the format ** package name.class name :: method name **. According to the code you created earlier, the package name is ** lambda.cloud **, the class name is ** MyLambda **, and ** lambda.cloud.MyLambda ** is entered. In this example, the method name can be omitted.
STEP 4 Click ** upload ** to upload the ** mylambda-1.0.0.jar ** you just created.
Yes, up to this point, the Lambda function you created earlier has been registered in AWS Lambda.
After uploading, try testing from the console.
** (1) Preparation for test event **
There is a idea that the Lambda function is ** triggered by some event. For example, you can use it to fire a Lambda function triggered by the event ** an object is created in the S3 bucket **.
Therefore, the input for executing the Lambda function is called ** event **.
Here, fire ** event ** from the console and check the operation of the Lambda function.
Select ** Configure test events ** at the top of the screen.
Then, the ** Configure test events ** screen will open as shown below. Create a test event here.
Let ** Event name ** be ** MyEvent **, and the edit box below it is the body when requesting a Lambda function.
In the Lambda function that inputs / outputs with the POJO created earlier, the POJO is automatically mapped to JSON in the actual call, and the input / output is done in JSON.
Therefore, enter the body of the event in JSON format as shown below.
{
"firstName": "john",
"lastName": "doe"
}
After entering, press ** Create ** at the bottom of the screen.
** (2) Execution of test event **
Execute the ** MyEvent ** you just created immediately. Press ** Test ** at the top right of the screen.
By the way, ** "The file name specified in the handler does not match the file name of the deploy package, so the Lambda function" myFunction "cannot be edited inline. Don't worry if the message "**" is displayed, it's OK. The Lambda console does not provide inline editors for compiled languages such as Java and C #.
** (3) Check the execution result **
After pressing ** Test ** for a while, the result screen will be displayed.
If successful, ** Execution result: succeeded ** is displayed. You can see the details of the result by pressing ** ▼ Details ** below it to expand it.
As for the output of the Lambda function, the POJO ** Output ** class mentioned earlier is converted to JSON as shown below.
POJO for input / output
public static class Input {
public String firstName;
public String lastName;
}
public static class Output {
public Input in;
public String fullName;
}
Execution result
{
"in": {
"firstName": "john",
"lastName": "doe"
},
"fullName": "john_doe"
}
Call the Lambda function ** myFunction ** you just created from your Java program.
If you want to hit the AWS Lambda function from Java, add the aws-java-sdk-lambda library. If you use maven, add the following
maven
<dependency>
<groupId>com.amazonaws</groupId>
<artifactId>aws-java-sdk-lambda</artifactId>
<version>1.11.210</version>
</dependency>
The code looks like this: (Various setting values are dummy)
Java client
public class ExampleLambdaClient {
public static void main(String[] args) {
ExampleLambdaClient client = new ExampleLambdaClient();
client.invokeLambdaFunction();
}
private void invokeLambdaFunction() {
final String AWS_ACCESS_KEY_ID = "ANMNRR35KPTR7PLB3C7D";
final String AWS_SECRET_ACCESS_KEY = "UKA6EsKY25LJQBEpUvXyYkj8aWKEDnynEZigVPhz";
AWSCredentials credentials = new BasicAWSCredentials(AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY);
// ARN
String functionName = "arn:aws:lambda:ap-northeast-1:000000000000:function:myFunction";
String inputJSON = "{\"firstName\":\"john\",\"lastName\": \"doe\"}";
InvokeRequest lmbRequest = new InvokeRequest()
.withFunctionName(functionName)
.withPayload(inputJSON);
lmbRequest.setInvocationType(InvocationType.RequestResponse);
AWSLambda lambda = AWSLambdaClientBuilder.standard()
.withRegion(Regions.AP_NORTHEAST_1)
.withCredentials(new AWSStaticCredentialsProvider(credentials)).build();
InvokeResult lmbResult = lambda.invoke(lmbRequest);
String resultJSON = new String(lmbResult.getPayload().array(), Charset.forName("UTF-8"));
System.out.println(resultJSON);
}
}
AWSCredentials credentials = new BasicAWSCredentials(AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY);
--Create credentials using the access key ID (AWS_ACCESS_KEY_ID) and secret access key (AWS_SECRET_ACCESS_KEY).
InvokeRequest lmbRequest = new InvokeRequest()
.withFunctionName(functionName)
.withPayload(inputJSON);
--Generate a request. ** # withFunctionName ** specifies the function name. Specify ARN (** arn: aws: lambda: ap-northeast-1: 000000000000: function: myFunction ) or specify the function name ( myFunction **). I specified ** ARN ** here
-Specify the body (JSON) of the request with ** # withPayload **. Here, the JSON string ** "{" firstName \ ": " john \ ", " lastName \ ": " doe \ "}"; ** is specified.
lmbRequest.setInvocationType(InvocationType.RequestResponse);
-** Specify the invocation type ** Here, ** InvocationType.RequestResponse ** is specified. This is a call type of type ** RequestResponse **. If you set it to RequestResponse, you can receive the processing result.
InvokeResult lmbResult = lambda.invoke(lmbRequest);
String resultJSON = new String(lmbResult.getPayload().array(), Charset.forName("UTF-8"));
--Call the Lambda function and receive the result (JSON).
The full source code on the client side is below https://github.com/riversun/aws_lambda_example_basic_client.git
--It was relatively easy to write AWS lambda functions in Java --I was able to call a Lambda function directly from a Java client
The sample was created in Eclipse (Oxygen), but no special plug-in is required. (You don't even need the AWS SDK Plugin for Eclipse, which makes it easier)
--In the second part, I will write about Lambda functions and Java client side synchronization / asynchronization, and API Gateway.
――It was around 2009, but I was shocked when the original service "** Google App Engine (GAE) **", which says ** I wrote only the code and left it to me, and charged only for what I used **, appeared. Although there were many unique restrictions, it was very helpful.
――This time, the ** ancestor!? ** has introduced ** Google Cloud Functions **. Right now, I think that β is the future, but it seems that it will be an option in the future.
Recommended Posts