From 3103dc6212c0e3563a56c6482df4f403c1c1889f Mon Sep 17 00:00:00 2001 From: Oleg Zhurakousky Date: Wed, 14 Jun 2023 14:10:28 +0200 Subject: [PATCH 1/2] GH-577 Ensure listeners are notified after dispatch Resolves #577 --- .../serverless/proxy/internal/servlet/AwsAsyncContext.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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 4a46a70fa..7e3642ef0 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 @@ -74,8 +74,8 @@ public void dispatch() { throw new IllegalStateException("Dispatching already started"); } dispatched.set(true); - notifyListeners(NotificationType.START_ASYNC, null); handler.doFilter(req, res, ((AwsServletContext)req.getServletContext()).getServletForPath(req.getRequestURI())); + notifyListeners(NotificationType.START_ASYNC, null); } catch (ServletException | IOException e) { notifyListeners(NotificationType.ERROR, e); } From 55be6718a78b56ca08bafc59c5796a57a5267882 Mon Sep 17 00:00:00 2001 From: Oleg Zhurakousky Date: Thu, 22 Jun 2023 15:09:14 +0200 Subject: [PATCH 2/2] Add test --- .../servlet/AwsHttpServletResponse.java | 4 ++++ .../proxy/spring/ServletAppTest.java | 11 ++++++++++ .../spring/servletapp/MessageController.java | 20 +++++++++++++++++++ 3 files changed, 35 insertions(+) diff --git a/aws-serverless-java-container-core/src/main/java/com/amazonaws/serverless/proxy/internal/servlet/AwsHttpServletResponse.java b/aws-serverless-java-container-core/src/main/java/com/amazonaws/serverless/proxy/internal/servlet/AwsHttpServletResponse.java index c46af7a9b..f82d062a7 100644 --- a/aws-serverless-java-container-core/src/main/java/com/amazonaws/serverless/proxy/internal/servlet/AwsHttpServletResponse.java +++ b/aws-serverless-java-container-core/src/main/java/com/amazonaws/serverless/proxy/internal/servlet/AwsHttpServletResponse.java @@ -322,6 +322,10 @@ public void write(int b) throws IOException { } } + @Override + public void flush() throws IOException { + flushBuffer(); + } @Override public void close() diff --git a/aws-serverless-java-container-springboot3/src/test/java/com/amazonaws/serverless/proxy/spring/ServletAppTest.java b/aws-serverless-java-container-springboot3/src/test/java/com/amazonaws/serverless/proxy/spring/ServletAppTest.java index aacf5444c..b87c80ce6 100644 --- a/aws-serverless-java-container-springboot3/src/test/java/com/amazonaws/serverless/proxy/spring/ServletAppTest.java +++ b/aws-serverless-java-container-springboot3/src/test/java/com/amazonaws/serverless/proxy/spring/ServletAppTest.java @@ -38,6 +38,17 @@ public void initServletAppTest(String reqType) { handler = new LambdaHandler(type); } + @MethodSource("data") + @ParameterizedTest + void asyncRequest(String reqType) { + initServletAppTest(reqType); + AwsProxyRequestBuilder req = new AwsProxyRequestBuilder("/async", "POST") + .json() + .body("{\"name\":\"bob\"}"); + AwsProxyResponse resp = handler.handleRequest(req, lambdaContext); + assertEquals("{\"name\":\"BOB\"}", resp.getBody()); + } + @MethodSource("data") @ParameterizedTest void helloRequest_respondsWithSingleMessage(String reqType) { diff --git a/aws-serverless-java-container-springboot3/src/test/java/com/amazonaws/serverless/proxy/spring/servletapp/MessageController.java b/aws-serverless-java-container-springboot3/src/test/java/com/amazonaws/serverless/proxy/spring/servletapp/MessageController.java index 927822a4e..a40d2c206 100644 --- a/aws-serverless-java-container-springboot3/src/test/java/com/amazonaws/serverless/proxy/spring/servletapp/MessageController.java +++ b/aws-serverless-java-container-springboot3/src/test/java/com/amazonaws/serverless/proxy/spring/servletapp/MessageController.java @@ -5,9 +5,13 @@ import org.springframework.http.ResponseEntity; import org.springframework.validation.Errors; import org.springframework.web.bind.annotation.*; +import org.springframework.web.context.request.async.DeferredResult; import org.springframework.web.server.ResponseStatusException; import jakarta.validation.Valid; +import reactor.core.publisher.Mono; + +import java.util.Collections; import java.util.HashMap; import java.util.Map; @@ -18,6 +22,22 @@ public class MessageController { public static final String UTF8_RESPONSE = "öüäß фрыцшщ"; public static final String EX_MESSAGE = "404 exception message"; + + @RequestMapping(path="/hi", method=RequestMethod.GET, produces = {"text/plain"}) + public Mono hi() { + return Mono.just(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; + } + + @RequestMapping(path="/hello", method=RequestMethod.GET, produces = {"text/plain"}) public String hello() { return HELLO_MESSAGE;