BAEL-6255 - Run a Spring Boot application in AWS Lambda (#13629)

* BAEL-6255 - Run a Spring Boot application in AWS Lambda

* BAEL-6255 - Run a Spring Boot application in AWS Lambda

* fix on template.yaml

* fix on template.yaml

* removed log from test

* resolved issues reported on PR

---------

Co-authored-by: Cesare <cesare.valenti@hotmail.com>
This commit is contained in:
cesarevalenti90
2023-03-23 21:43:34 +01:00
committed by GitHub
parent f8b5874b78
commit 2fbe46bc19
11 changed files with 297 additions and 0 deletions

View File

@@ -0,0 +1,12 @@
package com.baeldung.aws;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}

View File

@@ -0,0 +1,21 @@
package com.baeldung.aws.controller;
import java.util.List;
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import com.baeldung.aws.data.User;
@RestController
@RequestMapping("/api/v1/")
public class ProfileController {
@GetMapping(value = "users", produces = MediaType.APPLICATION_JSON_VALUE)
public List<User> getUser() {
return List.of(new User("John", "Doe", "john.doe@baeldung.com"), new User("John", "Doe", "john.doe-2@baeldung.com"));
}
}

View File

@@ -0,0 +1,38 @@
package com.baeldung.aws.data;
public class User {
private String name;
private String surname;
private String emailAddress;
public User(String name, String surname, String emailAddress) {
this.name = name;
this.surname = surname;
this.emailAddress = emailAddress;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getSurname() {
return surname;
}
public void setSurname(String surname) {
this.surname = surname;
}
public String getEmailAddress() {
return emailAddress;
}
public void setEmailAddress(String emailAddress) {
this.emailAddress = emailAddress;
}
}

View File

@@ -0,0 +1,25 @@
package com.baeldung.aws.handler;
import com.amazonaws.serverless.exceptions.ContainerInitializationException;
import com.amazonaws.serverless.proxy.model.AwsProxyRequest;
import com.amazonaws.serverless.proxy.model.AwsProxyResponse;
import com.amazonaws.serverless.proxy.spring.SpringBootLambdaContainerHandler;
import com.amazonaws.serverless.proxy.spring.SpringBootProxyHandlerBuilder;
import com.amazonaws.services.lambda.runtime.Context;
import com.amazonaws.services.lambda.runtime.RequestHandler;
import com.baeldung.aws.Application;
public class AsynchronousLambdaHandler implements RequestHandler<AwsProxyRequest, AwsProxyResponse> {
private SpringBootLambdaContainerHandler<AwsProxyRequest, AwsProxyResponse> handler;
public AsynchronousLambdaHandler() throws ContainerInitializationException {
handler = (SpringBootLambdaContainerHandler<AwsProxyRequest, AwsProxyResponse>) new SpringBootProxyHandlerBuilder().springBootApplication(Application.class)
.asyncInit()
.buildAndInitialize();
}
@Override
public AwsProxyResponse handleRequest(AwsProxyRequest input, Context context) {
return handler.proxy(input, context);
}
}

View File

@@ -0,0 +1,26 @@
package com.baeldung.aws.handler;
import com.amazonaws.serverless.exceptions.ContainerInitializationException;
import com.amazonaws.serverless.proxy.model.AwsProxyResponse;
import com.amazonaws.serverless.proxy.model.HttpApiV2ProxyRequest;
import com.amazonaws.serverless.proxy.spring.SpringBootLambdaContainerHandler;
import com.amazonaws.services.lambda.runtime.Context;
import com.amazonaws.services.lambda.runtime.RequestHandler;
import com.baeldung.aws.Application;
public class HttpV2LambdaHandler implements RequestHandler<HttpApiV2ProxyRequest, AwsProxyResponse> {
private static SpringBootLambdaContainerHandler<HttpApiV2ProxyRequest, AwsProxyResponse> handler;
static {
try {
handler = SpringBootLambdaContainerHandler.getHttpApiV2ProxyHandler(Application.class);
} catch (ContainerInitializationException ex) {
throw new RuntimeException("Unable to load spring boot application", ex);
}
}
@Override
public AwsProxyResponse handleRequest(HttpApiV2ProxyRequest input, Context context) {
return handler.proxy(input, context);
}
}

View File

@@ -0,0 +1,26 @@
package com.baeldung.aws.handler;
import com.amazonaws.serverless.exceptions.ContainerInitializationException;
import com.amazonaws.serverless.proxy.model.AwsProxyRequest;
import com.amazonaws.serverless.proxy.model.AwsProxyResponse;
import com.amazonaws.serverless.proxy.spring.SpringBootLambdaContainerHandler;
import com.amazonaws.services.lambda.runtime.Context;
import com.amazonaws.services.lambda.runtime.RequestHandler;
import com.baeldung.aws.Application;
public class LambdaHandler implements RequestHandler<AwsProxyRequest, AwsProxyResponse> {
private static SpringBootLambdaContainerHandler<AwsProxyRequest, AwsProxyResponse> handler;
static {
try {
handler = SpringBootLambdaContainerHandler.getAwsProxyHandler(Application.class);
} catch (ContainerInitializationException ex) {
throw new RuntimeException("Unable to load spring boot application", ex);
}
}
@Override
public AwsProxyResponse handleRequest(AwsProxyRequest input, Context context) {
return handler.proxy(input, context);
}
}

View File

@@ -0,0 +1,3 @@
spring.datasource.url=jdbc:mysql://localhost:3306/mydatabase
spring.datasource.username=myusername
spring.datasource.password=mypassword

View File

@@ -0,0 +1,36 @@
package com.baeldung;
import java.io.IOException;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import com.amazonaws.serverless.proxy.internal.testutils.AwsProxyRequestBuilder;
import com.amazonaws.serverless.proxy.internal.testutils.MockLambdaContext;
import com.amazonaws.serverless.proxy.model.AwsProxyRequest;
import com.amazonaws.serverless.proxy.model.AwsProxyResponse;
import com.baeldung.aws.handler.LambdaHandler;
@SpringBootApplication
public class ProfileIntegrationTest {
MockLambdaContext lambdaContext = new MockLambdaContext();
@Test
void whenTheUsersPathIsInvokedViaLambda_thenShouldReturnAList() throws IOException {
LambdaHandler lambdaHandler = new LambdaHandler();
AwsProxyRequest req = new AwsProxyRequestBuilder("/api/v1/users", "GET").build();
AwsProxyResponse resp = lambdaHandler.handleRequest(req, lambdaContext);
Assertions.assertNotNull(resp.getBody());
Assertions.assertEquals(200, resp.getStatusCode());
}
@Test
void whenWrongPathPathIsInvokedViaLambda_thenShouldNotFound() throws IOException {
LambdaHandler lambdaHandler = new LambdaHandler();
AwsProxyRequest req = new AwsProxyRequestBuilder("/api/v1/users/plus-one-level", "GET").build();
AwsProxyResponse resp = lambdaHandler.handleRequest(req, lambdaContext);
Assertions.assertEquals(404, resp.getStatusCode());
}
}