diff --git a/aws-serverless-java-container-core/src/main/java/com/amazonaws/serverless/proxy/internal/servlet/AwsAsyncContext.java b/aws-serverless-java-container-core/src/main/java/com/amazonaws/serverless/proxy/internal/servlet/AwsAsyncContext.java index 7e3642ef0..d64af8966 100644 --- a/aws-serverless-java-container-core/src/main/java/com/amazonaws/serverless/proxy/internal/servlet/AwsAsyncContext.java +++ b/aws-serverless-java-container-core/src/main/java/com/amazonaws/serverless/proxy/internal/servlet/AwsAsyncContext.java @@ -32,23 +32,23 @@ public class AwsAsyncContext implements AsyncContext { private HttpServletRequest req; private HttpServletResponse res; - private AwsLambdaServletContainerHandler handler; private List listeners; private long timeout; private AtomicBoolean dispatched; private AtomicBoolean completed; + private AtomicBoolean dispatchStarted; private Logger log = LoggerFactory.getLogger(AwsAsyncContext.class); - public AwsAsyncContext(HttpServletRequest request, HttpServletResponse response, AwsLambdaServletContainerHandler servletHandler) { + public AwsAsyncContext(HttpServletRequest request, HttpServletResponse response) { log.debug("Initializing async context for request: " + SecurityUtils.crlf(request.getPathInfo()) + " - " + SecurityUtils.crlf(request.getMethod())); req = request; res = response; - handler = servletHandler; listeners = new ArrayList<>(); timeout = 3000; dispatched = new AtomicBoolean(false); completed = new AtomicBoolean(false); + dispatchStarted = new AtomicBoolean(false); } @Override @@ -68,16 +68,14 @@ public boolean hasOriginalRequestAndResponse() { @Override public void dispatch() { - try { - log.debug("Dispatching request"); - if (dispatched.get()) { - throw new IllegalStateException("Dispatching already started"); - } + log.debug("Dispatching request"); + + if (dispatched.get()) { + throw new IllegalStateException("Dispatching already started"); + } + if (dispatchStarted.getAndSet(true)) { dispatched.set(true); - handler.doFilter(req, res, ((AwsServletContext)req.getServletContext()).getServletForPath(req.getRequestURI())); notifyListeners(NotificationType.START_ASYNC, null); - } catch (ServletException | IOException e) { - notifyListeners(NotificationType.ERROR, e); } } @@ -154,6 +152,10 @@ public boolean isCompleted() { return completed.get(); } + public boolean isDispatchStarted() { + return dispatchStarted.get(); + } + private void notifyListeners(NotificationType type, Throwable t) { listeners.forEach((h) -> { try { diff --git a/aws-serverless-java-container-core/src/main/java/com/amazonaws/serverless/proxy/internal/servlet/AwsHttpApiV2ProxyHttpServletRequest.java b/aws-serverless-java-container-core/src/main/java/com/amazonaws/serverless/proxy/internal/servlet/AwsHttpApiV2ProxyHttpServletRequest.java index 73239a914..6fdb31f08 100644 --- a/aws-serverless-java-container-core/src/main/java/com/amazonaws/serverless/proxy/internal/servlet/AwsHttpApiV2ProxyHttpServletRequest.java +++ b/aws-serverless-java-container-core/src/main/java/com/amazonaws/serverless/proxy/internal/servlet/AwsHttpApiV2ProxyHttpServletRequest.java @@ -442,7 +442,7 @@ public boolean isAsyncStarted() { @Override public AsyncContext startAsync() throws IllegalStateException { - asyncContext = new AwsAsyncContext(this, response, containerHandler); + asyncContext = new AwsAsyncContext(this, response); setAttribute(DISPATCHER_TYPE_ATTRIBUTE, DispatcherType.ASYNC); log.debug("Starting async context for request: " + SecurityUtils.crlf(request.getRequestContext().getRequestId())); return asyncContext; @@ -450,7 +450,7 @@ public AsyncContext startAsync() throws IllegalStateException { @Override public AsyncContext startAsync(ServletRequest servletRequest, ServletResponse servletResponse) throws IllegalStateException { - asyncContext = new AwsAsyncContext((HttpServletRequest) servletRequest, (HttpServletResponse) servletResponse, containerHandler); + asyncContext = new AwsAsyncContext((HttpServletRequest) servletRequest, (HttpServletResponse) servletResponse); setAttribute(DISPATCHER_TYPE_ATTRIBUTE, DispatcherType.ASYNC); log.debug("Starting async context for request: " + SecurityUtils.crlf(request.getRequestContext().getRequestId())); return asyncContext; diff --git a/aws-serverless-java-container-core/src/main/java/com/amazonaws/serverless/proxy/internal/servlet/AwsLambdaServletContainerHandler.java b/aws-serverless-java-container-core/src/main/java/com/amazonaws/serverless/proxy/internal/servlet/AwsLambdaServletContainerHandler.java index b35bba92c..7437449e1 100644 --- a/aws-serverless-java-container-core/src/main/java/com/amazonaws/serverless/proxy/internal/servlet/AwsLambdaServletContainerHandler.java +++ b/aws-serverless-java-container-core/src/main/java/com/amazonaws/serverless/proxy/internal/servlet/AwsLambdaServletContainerHandler.java @@ -152,13 +152,25 @@ protected void doFilter(HttpServletRequest request, HttpServletResponse response FilterChain chain = getFilterChain(request, servlet); chain.doFilter(request, response); - + if(requiresAsyncReDispatch(request)) { + chain = getFilterChain(request, servlet); + chain.doFilter(request, response); + } // if for some reason the response wasn't flushed yet, we force it here unless it's being processed asynchronously (WebFlux) if (!response.isCommitted() && request.getDispatcherType() != DispatcherType.ASYNC) { response.flushBuffer(); } } + private boolean requiresAsyncReDispatch(HttpServletRequest request) { + if (request.isAsyncStarted()) { + AsyncContext asyncContext = request.getAsyncContext(); + return asyncContext instanceof AwsAsyncContext + && ((AwsAsyncContext) asyncContext).isDispatchStarted(); + } + return false; + } + @Override public void initialize() throws ContainerInitializationException { // we expect all servlets to be wrapped in an AwsServletRegistration diff --git a/aws-serverless-java-container-core/src/main/java/com/amazonaws/serverless/proxy/internal/servlet/AwsProxyHttpServletRequest.java b/aws-serverless-java-container-core/src/main/java/com/amazonaws/serverless/proxy/internal/servlet/AwsProxyHttpServletRequest.java index 280a7e308..3e92d43dc 100644 --- a/aws-serverless-java-container-core/src/main/java/com/amazonaws/serverless/proxy/internal/servlet/AwsProxyHttpServletRequest.java +++ b/aws-serverless-java-container-core/src/main/java/com/amazonaws/serverless/proxy/internal/servlet/AwsProxyHttpServletRequest.java @@ -495,7 +495,7 @@ public boolean isAsyncStarted() { @Override public AsyncContext startAsync() throws IllegalStateException { - asyncContext = new AwsAsyncContext(this, response, containerHandler); + asyncContext = new AwsAsyncContext(this, response); setAttribute(DISPATCHER_TYPE_ATTRIBUTE, DispatcherType.ASYNC); log.debug("Starting async context for request: " + SecurityUtils.crlf(request.getRequestContext().getRequestId())); return asyncContext; @@ -506,7 +506,7 @@ public AsyncContext startAsync() public AsyncContext startAsync(ServletRequest servletRequest, ServletResponse servletResponse) throws IllegalStateException { servletRequest.setAttribute(DISPATCHER_TYPE_ATTRIBUTE, DispatcherType.ASYNC); - asyncContext = new AwsAsyncContext((HttpServletRequest) servletRequest, (HttpServletResponse) servletResponse, containerHandler); + asyncContext = new AwsAsyncContext((HttpServletRequest) servletRequest, (HttpServletResponse) servletResponse); log.debug("Starting async context for request: " + SecurityUtils.crlf(request.getRequestContext().getRequestId())); return asyncContext; } diff --git a/aws-serverless-java-container-core/src/test/java/com/amazonaws/serverless/proxy/internal/servlet/AwsAsyncContextTest.java b/aws-serverless-java-container-core/src/test/java/com/amazonaws/serverless/proxy/internal/servlet/AwsAsyncContextTest.java index 2177fa8bb..a8383b5c3 100644 --- a/aws-serverless-java-container-core/src/test/java/com/amazonaws/serverless/proxy/internal/servlet/AwsAsyncContextTest.java +++ b/aws-serverless-java-container-core/src/test/java/com/amazonaws/serverless/proxy/internal/servlet/AwsAsyncContextTest.java @@ -10,6 +10,7 @@ import com.amazonaws.serverless.proxy.model.AwsProxyRequest; import com.amazonaws.serverless.proxy.model.AwsProxyResponse; import com.amazonaws.services.lambda.runtime.Context; +import org.junit.jupiter.api.Disabled; import org.junit.jupiter.api.Test; import jakarta.servlet.AsyncContext; @@ -32,48 +33,20 @@ public class AwsAsyncContextTest { private AwsServletContextTest.TestServlet srv2 = new AwsServletContextTest.TestServlet("srv2"); private AwsServletContext ctx = getCtx(); - @Test - void dispatch_sendsToCorrectServlet() { - AwsProxyHttpServletRequest req = new AwsProxyHttpServletRequest(new AwsProxyRequestBuilder("/srv1/hello", "GET").build(), lambdaCtx, null); - req.setResponse(handler.getContainerResponse(req, new CountDownLatch(1))); - req.setServletContext(ctx); - req.setContainerHandler(handler); - - AsyncContext asyncCtx = req.startAsync(); - handler.setDesiredStatus(201); - asyncCtx.dispatch(); - assertNotNull(handler.getSelectedServlet()); - assertEquals(srv1, handler.getSelectedServlet()); - assertEquals(201, handler.getResponse().getStatus()); - - req = new AwsProxyHttpServletRequest(new AwsProxyRequestBuilder("/srv5/hello", "GET").build(), lambdaCtx, null); - req.setResponse(handler.getContainerResponse(req, new CountDownLatch(1))); - req.setServletContext(ctx); - req.setContainerHandler(handler); - asyncCtx = req.startAsync(); - handler.setDesiredStatus(202); - asyncCtx.dispatch(); - assertNotNull(handler.getSelectedServlet()); - assertEquals(srv2, handler.getSelectedServlet()); - assertEquals(202, handler.getResponse().getStatus()); - } @Test - void dispatchNewPath_sendsToCorrectServlet() throws InvalidRequestEventException { + void dispatch_amendsPath() throws InvalidRequestEventException { AwsProxyHttpServletRequest req = (AwsProxyHttpServletRequest)reader.readRequest(new AwsProxyRequestBuilder("/srv1/hello", "GET").build(), null, lambdaCtx, LambdaContainerHandler.getContainerConfig()); req.setResponse(handler.getContainerResponse(req, new CountDownLatch(1))); req.setServletContext(ctx); req.setContainerHandler(handler); AsyncContext asyncCtx = req.startAsync(); - handler.setDesiredStatus(301); asyncCtx.dispatch("/srv4/hello"); - assertNotNull(handler.getSelectedServlet()); - assertEquals(srv2, handler.getSelectedServlet()); - assertNotNull(handler.getResponse()); - assertEquals(301, handler.getResponse().getStatus()); + assertEquals("/srv1/hello", req.getRequestURI()); } + private AwsServletContext getCtx() { AwsServletContext ctx = new AwsServletContext(handler); handler.setServletContext(ctx); diff --git a/aws-serverless-java-container-spring/src/test/java/com/amazonaws/serverless/proxy/spring/AsyncAppTest.java b/aws-serverless-java-container-spring/src/test/java/com/amazonaws/serverless/proxy/spring/AsyncAppTest.java new file mode 100644 index 000000000..8265e1bf4 --- /dev/null +++ b/aws-serverless-java-container-spring/src/test/java/com/amazonaws/serverless/proxy/spring/AsyncAppTest.java @@ -0,0 +1,46 @@ +package com.amazonaws.serverless.proxy.spring; + +import com.amazonaws.serverless.exceptions.ContainerInitializationException; +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.amazonaws.serverless.proxy.spring.springapp.LambdaHandler; +import com.amazonaws.serverless.proxy.spring.springapp.MessageController; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.fail; + +public class AsyncAppTest { + + private static LambdaHandler handler; + + @BeforeAll + public static void setUp() { + try { + handler = new LambdaHandler(); + } catch (ContainerInitializationException e) { + e.printStackTrace(); + fail(); + } + } + + @Test + void springApp_helloRequest_returnsCorrect() { + AwsProxyRequest req = new AwsProxyRequestBuilder("/hello", "GET").build(); + AwsProxyResponse resp = handler.handleRequest(req, new MockLambdaContext()); + assertEquals(200, resp.getStatusCode()); + assertEquals(MessageController.HELLO_MESSAGE, resp.getBody()); + } + + @Test + void springApp_asyncRequest_returnsCorrect() { + AwsProxyRequest req = new AwsProxyRequestBuilder("/async", "GET").build(); + AwsProxyResponse resp = handler.handleRequest(req, new MockLambdaContext()); + assertEquals(200, resp.getStatusCode()); + assertEquals(MessageController.HELLO_MESSAGE, resp.getBody()); + } + +} diff --git a/aws-serverless-java-container-spring/src/test/java/com/amazonaws/serverless/proxy/spring/springapp/AppConfig.java b/aws-serverless-java-container-spring/src/test/java/com/amazonaws/serverless/proxy/spring/springapp/AppConfig.java new file mode 100644 index 000000000..d3562c221 --- /dev/null +++ b/aws-serverless-java-container-spring/src/test/java/com/amazonaws/serverless/proxy/spring/springapp/AppConfig.java @@ -0,0 +1,8 @@ +package com.amazonaws.serverless.proxy.spring.springapp; + +import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.Import; + +@Configuration +@Import({MessageController.class}) +public class AppConfig { } diff --git a/aws-serverless-java-container-spring/src/test/java/com/amazonaws/serverless/proxy/spring/springapp/LambdaHandler.java b/aws-serverless-java-container-spring/src/test/java/com/amazonaws/serverless/proxy/spring/springapp/LambdaHandler.java new file mode 100644 index 000000000..f0cad13c5 --- /dev/null +++ b/aws-serverless-java-container-spring/src/test/java/com/amazonaws/serverless/proxy/spring/springapp/LambdaHandler.java @@ -0,0 +1,26 @@ +package com.amazonaws.serverless.proxy.spring.springapp; + +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.SpringLambdaContainerHandler; +import com.amazonaws.serverless.proxy.spring.SpringProxyHandlerBuilder; +import com.amazonaws.services.lambda.runtime.Context; +import com.amazonaws.services.lambda.runtime.RequestHandler; + +public class LambdaHandler implements RequestHandler { + private SpringLambdaContainerHandler handler; + + public LambdaHandler() throws ContainerInitializationException { + handler = new SpringProxyHandlerBuilder() + .defaultProxy() + .asyncInit() + .configurationClasses(AppConfig.class) + .buildAndInitialize(); + } + + @Override + public AwsProxyResponse handleRequest(AwsProxyRequest awsProxyRequest, Context context) { + return handler.proxy(awsProxyRequest, context); + } +} diff --git a/aws-serverless-java-container-spring/src/test/java/com/amazonaws/serverless/proxy/spring/springapp/MessageController.java b/aws-serverless-java-container-spring/src/test/java/com/amazonaws/serverless/proxy/spring/springapp/MessageController.java new file mode 100644 index 000000000..1f5dc83d4 --- /dev/null +++ b/aws-serverless-java-container-spring/src/test/java/com/amazonaws/serverless/proxy/spring/springapp/MessageController.java @@ -0,0 +1,25 @@ +package com.amazonaws.serverless.proxy.spring.springapp; + +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestMethod; +import org.springframework.web.bind.annotation.RestController; +import org.springframework.web.context.request.async.DeferredResult; +import org.springframework.web.servlet.config.annotation.EnableWebMvc; + +@RestController +@EnableWebMvc +public class MessageController { + public static final String HELLO_MESSAGE = "Hello"; + + @RequestMapping(path="/hello", method= RequestMethod.GET) + public String hello() { + return HELLO_MESSAGE; + } + + @RequestMapping(path="/async", method= RequestMethod.GET) + public DeferredResult asyncHello() { + DeferredResult result = new DeferredResult<>(); + result.setResult(HELLO_MESSAGE); + return result; + } +} diff --git a/aws-serverless-java-container-springboot3/pom.xml b/aws-serverless-java-container-springboot3/pom.xml index 9b4d941c9..676f13293 100644 --- a/aws-serverless-java-container-springboot3/pom.xml +++ b/aws-serverless-java-container-springboot3/pom.xml @@ -191,6 +191,46 @@ test + + org.springframework.boot + spring-boot-starter-data-jpa + 3.2.1 + test + + + org.springframework.boot + spring-boot-starter-aop + + + org.springframework.boot + spring-boot-starter-web + + + org.springframework.boot + spring-boot-starter-logging + + + org.springframework.boot + spring-boot-starter-tomcat + + + org.apache.tomcat.embed + tomcat-embed-core + + + org.apache.tomcat.embed + tomcat-embed-websocket + + + + + com.h2database + h2 + 2.2.222 + test + + + @@ -284,6 +324,14 @@ + + org.apache.maven.plugins + maven-compiler-plugin + + 10 + 10 + + diff --git a/aws-serverless-java-container-springboot3/src/test/java/com/amazonaws/serverless/proxy/spring/JpaAppTest.java b/aws-serverless-java-container-springboot3/src/test/java/com/amazonaws/serverless/proxy/spring/JpaAppTest.java new file mode 100644 index 000000000..a111e510a --- /dev/null +++ b/aws-serverless-java-container-springboot3/src/test/java/com/amazonaws/serverless/proxy/spring/JpaAppTest.java @@ -0,0 +1,52 @@ +package com.amazonaws.serverless.proxy.spring; + +import com.amazonaws.serverless.proxy.internal.testutils.AwsProxyRequestBuilder; +import com.amazonaws.serverless.proxy.internal.testutils.MockLambdaContext; +import com.amazonaws.serverless.proxy.model.AwsProxyResponse; +import com.amazonaws.serverless.proxy.spring.jpaapp.LambdaHandler; +import com.amazonaws.serverless.proxy.spring.jpaapp.MessageController; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.MethodSource; + +import java.util.Arrays; +import java.util.Collection; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +public class JpaAppTest { + + LambdaHandler handler; + MockLambdaContext lambdaContext = new MockLambdaContext(); + + private String type; + + public static Collection data() { + return Arrays.asList(new Object[]{"API_GW", "ALB", "HTTP_API"}); + } + + public void initJpaAppTest(String reqType) { + type = reqType; + handler = new LambdaHandler(type); + } + + @MethodSource("data") + @ParameterizedTest + void asyncRequest(String reqType) { + initJpaAppTest(reqType); + AwsProxyRequestBuilder req = new AwsProxyRequestBuilder("/async", "POST") + .json() + .body("{\"name\":\"kong\"}"); + AwsProxyResponse resp = handler.handleRequest(req, lambdaContext); + assertEquals("{\"name\":\"KONG\"}", resp.getBody()); + } + + @MethodSource("data") + @ParameterizedTest + void helloRequest_respondsWithSingleMessage(String reqType) { + initJpaAppTest(reqType); + AwsProxyRequestBuilder req = new AwsProxyRequestBuilder("/hello", "GET"); + AwsProxyResponse resp = handler.handleRequest(req, lambdaContext); + assertEquals(MessageController.HELLO_MESSAGE, resp.getBody()); + } + +} diff --git a/aws-serverless-java-container-springboot3/src/test/java/com/amazonaws/serverless/proxy/spring/jpaapp/DatabaseConfig.java b/aws-serverless-java-container-springboot3/src/test/java/com/amazonaws/serverless/proxy/spring/jpaapp/DatabaseConfig.java new file mode 100644 index 000000000..aeef7c65e --- /dev/null +++ b/aws-serverless-java-container-springboot3/src/test/java/com/amazonaws/serverless/proxy/spring/jpaapp/DatabaseConfig.java @@ -0,0 +1,23 @@ +package com.amazonaws.serverless.proxy.spring.jpaapp; + +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.jdbc.datasource.DriverManagerDataSource; + +import javax.sql.DataSource; + +@Configuration +public class DatabaseConfig { + + @Bean + public DataSource dataSource() { + DriverManagerDataSource dataSource = new DriverManagerDataSource(); + dataSource.setDriverClassName("org.h2.Driver"); + dataSource.setUrl("jdbc:h2:mem:testdb"); + dataSource.setUsername("sa"); + dataSource.setPassword(""); + + return dataSource; + } +} + diff --git a/aws-serverless-java-container-springboot3/src/test/java/com/amazonaws/serverless/proxy/spring/jpaapp/JpaApplication.java b/aws-serverless-java-container-springboot3/src/test/java/com/amazonaws/serverless/proxy/spring/jpaapp/JpaApplication.java new file mode 100644 index 000000000..5aced5e28 --- /dev/null +++ b/aws-serverless-java-container-springboot3/src/test/java/com/amazonaws/serverless/proxy/spring/jpaapp/JpaApplication.java @@ -0,0 +1,17 @@ +package com.amazonaws.serverless.proxy.spring.jpaapp; + +import org.springframework.beans.factory.InitializingBean; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.boot.logging.LogLevel; +import org.springframework.boot.logging.LoggingSystem; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Import; + +@SpringBootApplication(exclude = { + org.springframework.boot.autoconfigure.security.reactive.ReactiveUserDetailsServiceAutoConfiguration.class, + org.springframework.boot.autoconfigure.security.reactive.ReactiveSecurityAutoConfiguration.class, + org.springframework.boot.autoconfigure.security.servlet.UserDetailsServiceAutoConfiguration.class, + org.springframework.boot.autoconfigure.security.servlet.SecurityAutoConfiguration.class +}) +@Import(MessageController.class) +public class JpaApplication {} diff --git a/aws-serverless-java-container-springboot3/src/test/java/com/amazonaws/serverless/proxy/spring/jpaapp/LambdaHandler.java b/aws-serverless-java-container-springboot3/src/test/java/com/amazonaws/serverless/proxy/spring/jpaapp/LambdaHandler.java new file mode 100644 index 000000000..0cf67c10f --- /dev/null +++ b/aws-serverless-java-container-springboot3/src/test/java/com/amazonaws/serverless/proxy/spring/jpaapp/LambdaHandler.java @@ -0,0 +1,59 @@ +package com.amazonaws.serverless.proxy.spring.jpaapp; + +import com.amazonaws.serverless.exceptions.ContainerInitializationException; +import com.amazonaws.serverless.proxy.InitializationWrapper; +import com.amazonaws.serverless.proxy.internal.testutils.AwsProxyRequestBuilder; +import com.amazonaws.serverless.proxy.model.AwsProxyRequest; +import com.amazonaws.serverless.proxy.model.AwsProxyResponse; +import com.amazonaws.serverless.proxy.model.HttpApiV2ProxyRequest; +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; + +public class LambdaHandler implements RequestHandler { + private static SpringBootLambdaContainerHandler handler; + private static SpringBootLambdaContainerHandler httpApiHandler; + private String type; + + public LambdaHandler(String reqType) { + type = reqType; + try { + switch (type) { + case "API_GW": + case "ALB": + handler = new SpringBootProxyHandlerBuilder() + .defaultProxy() + .initializationWrapper(new InitializationWrapper()) + .servletApplication() + .springBootApplication(JpaApplication.class) + .buildAndInitialize(); + break; + case "HTTP_API": + httpApiHandler = new SpringBootProxyHandlerBuilder() + .defaultHttpApiV2Proxy() + .initializationWrapper(new InitializationWrapper()) + .servletApplication() + .springBootApplication(JpaApplication.class) + .buildAndInitialize(); + break; + } + } catch (ContainerInitializationException e) { + e.printStackTrace(); + } + } + + @Override + public AwsProxyResponse handleRequest(AwsProxyRequestBuilder awsProxyRequest, Context context) { + switch (type) { + case "API_GW": + return handler.proxy(awsProxyRequest.build(), context); + case "ALB": + return handler.proxy(awsProxyRequest.alb().build(), context); + case "HTTP_API": + return httpApiHandler.proxy(awsProxyRequest.toHttpApiV2Request(), context); + default: + throw new RuntimeException("Unknown request type: " + type); + } + } +} diff --git a/aws-serverless-java-container-springboot3/src/test/java/com/amazonaws/serverless/proxy/spring/jpaapp/MessageController.java b/aws-serverless-java-container-springboot3/src/test/java/com/amazonaws/serverless/proxy/spring/jpaapp/MessageController.java new file mode 100644 index 000000000..a85292262 --- /dev/null +++ b/aws-serverless-java-container-springboot3/src/test/java/com/amazonaws/serverless/proxy/spring/jpaapp/MessageController.java @@ -0,0 +1,31 @@ +package com.amazonaws.serverless.proxy.spring.jpaapp; + +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMethod; +import org.springframework.web.bind.annotation.ResponseBody; +import org.springframework.web.bind.annotation.RestController; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.context.request.async.DeferredResult; +import java.util.Collections; +import java.util.Map; + +@RestController +public class MessageController { + + public static final String HELLO_MESSAGE = "Hello"; + + @RequestMapping(path="/hello", method=RequestMethod.GET, produces = {"text/plain"}) + public String hello() { + return HELLO_MESSAGE; + } + + @SuppressWarnings({ "unchecked", "rawtypes" }) + @RequestMapping(path = "/async", method = RequestMethod.POST) + @ResponseBody + public DeferredResult> asyncResult(@RequestBody Map value) { + DeferredResult result = new DeferredResult<>(); + result.setResult(Collections.singletonMap("name", value.get("name").toUpperCase())); + return result; + } + +} diff --git a/aws-serverless-java-container-springboot3/src/test/java/com/amazonaws/serverless/proxy/spring/securityapp/SecurityApplication.java b/aws-serverless-java-container-springboot3/src/test/java/com/amazonaws/serverless/proxy/spring/securityapp/SecurityApplication.java index cafcd4000..d4036dcfe 100644 --- a/aws-serverless-java-container-springboot3/src/test/java/com/amazonaws/serverless/proxy/spring/securityapp/SecurityApplication.java +++ b/aws-serverless-java-container-springboot3/src/test/java/com/amazonaws/serverless/proxy/spring/securityapp/SecurityApplication.java @@ -6,7 +6,10 @@ import org.springframework.security.config.annotation.web.reactive.EnableWebFluxSecurity; import org.springframework.web.reactive.config.EnableWebFlux; -@SpringBootApplication +@SpringBootApplication(exclude = { + org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration.class, + org.springframework.boot.autoconfigure.orm.jpa.HibernateJpaAutoConfiguration.class +}) @EnableWebFluxSecurity @EnableWebFlux @Import(SecurityConfig.class) diff --git a/aws-serverless-java-container-springboot3/src/test/java/com/amazonaws/serverless/proxy/spring/servletapp/ServletApplication.java b/aws-serverless-java-container-springboot3/src/test/java/com/amazonaws/serverless/proxy/spring/servletapp/ServletApplication.java index 07ddbab43..0cb001ed1 100644 --- a/aws-serverless-java-container-springboot3/src/test/java/com/amazonaws/serverless/proxy/spring/servletapp/ServletApplication.java +++ b/aws-serverless-java-container-springboot3/src/test/java/com/amazonaws/serverless/proxy/spring/servletapp/ServletApplication.java @@ -9,7 +9,9 @@ org.springframework.boot.autoconfigure.security.reactive.ReactiveUserDetailsServiceAutoConfiguration.class, org.springframework.boot.autoconfigure.security.reactive.ReactiveSecurityAutoConfiguration.class, org.springframework.boot.autoconfigure.security.servlet.UserDetailsServiceAutoConfiguration.class, - org.springframework.boot.autoconfigure.security.servlet.SecurityAutoConfiguration.class + org.springframework.boot.autoconfigure.security.servlet.SecurityAutoConfiguration.class, + org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration.class, + org.springframework.boot.autoconfigure.orm.jpa.HibernateJpaAutoConfiguration.class }) @Import(MessageController.class) public class ServletApplication { diff --git a/aws-serverless-java-container-springboot3/src/test/java/com/amazonaws/serverless/proxy/spring/slowapp/SlowTestApplication.java b/aws-serverless-java-container-springboot3/src/test/java/com/amazonaws/serverless/proxy/spring/slowapp/SlowTestApplication.java index b3fe177a1..006e51e45 100644 --- a/aws-serverless-java-container-springboot3/src/test/java/com/amazonaws/serverless/proxy/spring/slowapp/SlowTestApplication.java +++ b/aws-serverless-java-container-springboot3/src/test/java/com/amazonaws/serverless/proxy/spring/slowapp/SlowTestApplication.java @@ -8,7 +8,9 @@ @SpringBootApplication(exclude = { org.springframework.boot.autoconfigure.security.reactive.ReactiveUserDetailsServiceAutoConfiguration.class, - org.springframework.boot.autoconfigure.security.reactive.ReactiveSecurityAutoConfiguration.class + org.springframework.boot.autoconfigure.security.reactive.ReactiveSecurityAutoConfiguration.class, + org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration.class, + org.springframework.boot.autoconfigure.orm.jpa.HibernateJpaAutoConfiguration.class }) public class SlowTestApplication { diff --git a/aws-serverless-java-container-springboot3/src/test/java/com/amazonaws/serverless/proxy/spring/webfluxapp/WebFluxTestApplication.java b/aws-serverless-java-container-springboot3/src/test/java/com/amazonaws/serverless/proxy/spring/webfluxapp/WebFluxTestApplication.java index 70e0c9934..fc6aecd6f 100644 --- a/aws-serverless-java-container-springboot3/src/test/java/com/amazonaws/serverless/proxy/spring/webfluxapp/WebFluxTestApplication.java +++ b/aws-serverless-java-container-springboot3/src/test/java/com/amazonaws/serverless/proxy/spring/webfluxapp/WebFluxTestApplication.java @@ -13,7 +13,9 @@ org.springframework.boot.autoconfigure.security.reactive.ReactiveUserDetailsServiceAutoConfiguration.class, org.springframework.boot.autoconfigure.security.reactive.ReactiveSecurityAutoConfiguration.class, org.springframework.boot.autoconfigure.security.servlet.UserDetailsServiceAutoConfiguration.class, - org.springframework.boot.autoconfigure.security.servlet.SecurityAutoConfiguration.class + org.springframework.boot.autoconfigure.security.servlet.SecurityAutoConfiguration.class, + org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration.class, + org.springframework.boot.autoconfigure.orm.jpa.HibernateJpaAutoConfiguration.class }) public class WebFluxTestApplication {