Java AWS Lambda using Spring Cloud Function

Upasana | December 26, 2019 | 4 min read | 4,580 views


In this tutorial we will use Spring Cloud Functions (version 2.x) to create and deploy a simple AWS Lambda.
AWS Lambda

AWS Lambda makes it incredibly easy and cost-effective (no charge when code is not running) to run your code at arbitrary scale in the cloud. Simply write the handler code for your function and upload it to Lambda. The service takes care of hosting and scaling the function for you.

For more information:

https://aws.amazon.com/lambda/

Spring Cloud Function

Spring cloud function project has following goals:

  • Promote the implementation of business logic via functions.

  • Decouple the development lifecycle of business logic from any specific runtime target so that the same code can run as a web endpoint, a stream processor, or a task.

  • Support a uniform programming model across serverless providers, as well as the ability to run standalone (locally or in a PaaS).

  • Enable Spring Boot features (auto-configuration, dependency injection, metrics) on serverless providers.

Outline of this tutorial

  1. Create Spring Cloud Function for the Number reversal program

  2. Upload Spring Cloud Function to AWS Lambda

  3. Use Java Client to invoke the Lambda Function

  4. Use Kotlin Client to invoke the Lambda Function

Create Spring Cloud Function Project

Create a new Spring Boot project using template at Spring Initializer.

start spring io scf

Problem statement

We will create a simple lambda function that takes an input number and reverses it.

Lets define the domain objects: We need wrapper methods for accepting input and providing result. Jackson will handle the JSON marshalling for these objects.

NumberInput & NumberOutput
public class NumberInput {

    private long input;

    //Getter Setters
}

public class NumberOutput {

    private long result;

    //Getter Setter
}

Now lets create a FunctionHandler: We need to specify this handler in AWS lambda configuration later on.

ReverseFunctionHandler.java
package com.shunya.reverse.handler.aws;

import org.springframework.cloud.function.adapter.aws.SpringBootRequestHandler;

import com.shunya.reverse.domain.NumberInput;
import com.shunya.reverse.domain.NumberOutput;

public class ReverseFunctionHandler extends SpringBootRequestHandler<NumberInput, NumberOutput> {
}

Now lets define the actual Function that will take care of lambda request:

ReverseFunction.java
import java.util.function.Function;

@Component
public class ReverseFunction implements Function<NumberInput, NumberOutput> {

    private final MathService mathService;

    public ReverseFunction(final MathService mathService) {
        this.mathService = mathService;
    }

    @Override
    public NumberOutput apply(final NumberInput input) {
        return new NumberOutput(mathService.reverse(input.getInput()));
    }
}

The actual service that calculates the reverse of a number is defined following:

MathService.java
@Service
public class MathService {

    public long reverse(long num) {
        long sum = 0;
        while (num != 0) {
            long lastDigit = (num % 10);
            sum = (sum * 10) + lastDigit;
            num = num / 10;
        }
        return sum;
    }
}

Finally we need to create a SpringBoot Application that will start the container.

LambdaApp.java
@SpringBootApplication
public class LambdaApp {

    public static void main(String[] args) throws Exception {
        SpringApplication.run(LambdaApp.class, args);
    }
}

Now we are almost ready with our simple Spring Cloud Function that we can deploy to AWS Lambda.

Creating the build artifact

We are using aws specific dependencies (spring-cloud-function-adapter-aws) in our project, which creates aws specific artifacts during the build:

pom.xml
<dependencies>
    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-function-adapter-aws</artifactId>
        <version>2.1.0.RELEASE</version>
    </dependency>

    <dependency>
        <groupId>com.amazonaws</groupId>
        <artifactId>aws-lambda-java-events</artifactId>
        <version>2.2.6</version>
        <scope>provided</scope>
    </dependency>
    <dependency>
        <groupId>com.amazonaws</groupId>
        <artifactId>aws-lambda-java-log4j</artifactId>
        <version>1.0.0</version>
        <scope>provided</scope>
    </dependency>
</dependencies>

Run the below command to create AWS specific package for this project:

$ mvn clean package
Output
spring-cloud-function-aws-example-1.0-SNAPSHOT-aws.jar

Now we have an artifact ready for the deployment on AWS Lambda.

Setting up AWS CLI

You will have to follow Amazon AWS official documentation to setup AWS CLI on your target platform:

Creating new Lambda Function

Login into AWS Console and select Lambda from the services section. Now create a new Java 8 lambda from scratch as shown in the below screen.

create new lambda

Click on the create function button.

On the next screen, select handler as the below text:

Handler
com.shunya.uppercase.handler.aws.ReverseFunctionHandler

Now upload the artifact created in previous step using upload button.

Create a new execution role from AWS Lambda template for this function.

Configure Test Input

Now we need to test our lambda using input:

configure input

Here we are providing the below json as the input to the lambda:

{
    "input": 12345
}

Lambda Execution

As we can see, we get a reversed number as the response from our lambda function.

lambda output

Invoking lambda using AWS CLI

We can use aws cli to invoke the lambda function, here is the syntax for the same:

$ aws lambda invoke --function-name number-reversal-java --payload '{"input": 23456}' output.txt
Response
{
    "StatusCode": 200,
    "ExecutedVersion": "$LATEST"
}

If response is successful, we can check the output

$ cat output.txt
Output
{ "result": 65432 }

That’s all for this article.

In future we can add other triggers to this lambda function, like API gateway/SQS etc.

Next

In the next article, we will invoke this lambda function from a Java Client using AWS SDK. You can use this approach to invoke AWS lambda from inside a java microservice or another aws lambda function.


Top articles in this category:
  1. AWS Lambda in Kotlin using Spring Cloud Function
  2. Invoking AWS Lambda from a Java Client
  3. Invoke AWS Lambda from a Kotlin Client
  4. Feign exception handling in Spring Cloud
  5. S3 File upload & download with AWS Java SDK v2
  6. Spring Boot Sidecar
  7. Send Gupshup SMS using Java API

Recommended books for interview preparation:

Find more on this topic:
Buy interview books

Java & Microservices interview refresher for experienced developers.