Skip to content

idugalic/serverless-company

Repository files navigation

projects/serverless-company Java CI with Maven GitPitch

Table of Contents

This project is intended to demonstrate best practices for building a serverless web application with help of Spring Cloud Function project.

Serverless architectures refer to applications that significantly depend on third-party services (knows as Backend as a Service or "BaaS") or on custom code that's run in ephemeral containers (Function as a Service or "FaaS"). We will focus on FaaS.

The best known vendor host is currently AWS Lambda.

Important attributes of serverless are:

  • No management of server hosts or processes
  • Self auto provision & auto-scale based on load
  • Costs based on actual, precise, usage

FaaS in private clouds

FaaS in private clouds is not quite ready yet. Existing projects need to mature, a lot of considerations still need to be worked. Existing projects out there are:

Spring Cloud Function provides a new programming model for Spring Boot applications, abstracting away all of the transport details and infrastructure, allowing the developer to keep all the familiar tools and processes, and focus firmly on business logic. It helps you create decoupled functions for serverless hosting providers (like AWS Lambda) or any other runtime target without vendor lock-in.

Spring Cloud Function is a project with the following high-level 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.

The @Beans can be Function, Consumer or Supplier (all from java.util), and their parametric types can be String or POJO. A Function is exposed as an HTTP POST if spring-cloud-function-web is on the classpath, and as a Spring Cloud Stream Processor if spring-cloud-function-stream is on the classpath and a spring.cloud.function.stream.endpoint property is configured in the Spring environment. A Consumer is also exposed as an HTTP POST, or as a Stream Sink. A Supplier translates to an HTTP GET, or a Stream Source.

Building and Running a Function

$ cd serverless-company
$ mvn clean install

To deploy the Uppercase function as a REST endpoint only requires adding the “spring-cloud-function-web” dependency in your pom file.

You are ready now to run your function as a spring boot application:

$ cd serverless-company/serverless-company-functions
$ mvn spring-boot:run
$ curl -H "Content-Type: text/plain" localhost:8080/uppercaseFunction -d '{"input":"Hello"}'

Expected result would be:

{"result":"HELLO"}

AWS Lambda is a compute service that lets you run code without provisioning or managing servers. AWS Lambda executes your code only when needed and scales automatically, from a few requests per day to thousands per second. You pay only for the compute time you consume

This module uses an adapter layer for a Spring Cloud Function application onto AWS Lambda - spring-cloud-function-adapter-aws.

The AWS Adapter has a couple of different request handlers you can use like SpringBootRequestHandler, SpringBootStreamHandler, FunctionInvokingS3EventHandler, and so on. If you check the source code of SpringBootRequestHandler, you will see that it instead implements AWS's RequestHandler for us and also propagates the request to our function. The only reason we need to implement it is to specify the type of the input and the output parameters of the function, so AWS can serialize/deserialize them for us.

Build and package from the command line:

$ cd serverless-company/serverless-company-aws
$ ./mvnw clean package

AWS web console

After a successful build and package, if you navigate to the target directory, you will see two JARs, including one ending with -aws

Let's fire up the AWS Console and navigate to the Lambda service's page. Click on "Create a Lambda function" and select "Blank Function." We don't need any trigger for the function because it will be triggered by API Gateway and we will setup that later on so for now just click on "Next."

On the next page, you need to give a name for your function. I simply gave it "uppercase-function" but you can use anything else. But you need to remember it because it will be required for the setup of API Gateway. For the runtime set "Java 8." Drop the JAR ending with -aws on the upload button. Continue with the configuration:

  • Handler: com.idugalic.handler.UppercaseFunctionHandler
  • Role: uppercase-role
  • Runtime: Java 8
  • Advanced->Memory(MB): 320
  • Advanced->Timeout: 1 min

Input test:

{
  "input": "test"
}

Run test:

{
  "result": "TEST"
}

AWS CLI

$ aws lambda create-function --function-name uppercase-sample --role arn:aws:iam::[USERID]:role/service-role/[ROLE] --zip-file fileb://serverless-company/serverless-company-aws/target/serverless-company-aws-1.0.0.BUILD-SNAPSHOT-aws.jar --handler com.idugalic.handler.UppercaseFunctionHandler --description "Spring Cloud Function AWS Adapter Example" --runtime java8 --region eu-central-1 --timeout 30 --memory-size 1024 --publish

Apache OpenWhisk is a serverless event-based programming service and an Apache Incubator project. There is a public instance of Openwhisk hosted and run by IBM Bluemix. For the purposes of this lab we will install it locally.

This module uses an adapter layer for a Spring Cloud Function application onto Openwhisk - spring-cloud-function-adapter-openwhisk.

Install Openwhisk

Download and install VirtualBox and Vagrant for your operating system and architecture.

Follow these step to run your first OpenWhisk Action:

# Clone openwhisk
$ git clone --depth=1 https://github.com/apache/incubator-openwhisk.git openwhisk

# Change directory to tools/vagrant
$ cd openwhisk/tools/vagrant

# Run script to create vm and run hello action
$ ./hello

Build docker images via maven (optional)

Requires username and password of docker hub repository (so you can push an image). Please note that image is already publicly available here https://hub.docker.com/r/idugalic/serverless-company-openwhisk/ , and you do not need to create an image localy.

$ cd serverless-company
$ mvn clean install
$ DOCKER_HOST=unix:///var/run/docker.sock mvn docker:build -DpushImage

Create and invoke a function

$ vagrant ssh
$ wsk action create example --docker idugalic/serverless-company-openwhisk
$ wsk action invoke example --result --param uppercaseRequest '{"input":"foo"}'

Slides

https://gitpitch.com/idugalic/serverless-company/master?grs=github&t=white

References and further reading