diff --git a/spring-cloud-function-adapters/spring-cloud-function-adapter-aws/src/main/java/org/springframework/cloud/function/adapter/aws/SpringBootApiGatewayRequestHandler.java b/spring-cloud-function-adapters/spring-cloud-function-adapter-aws/src/main/java/org/springframework/cloud/function/adapter/aws/SpringBootApiGatewayRequestHandler.java index 97496d569..3cb2ecb51 100644 --- a/spring-cloud-function-adapters/spring-cloud-function-adapter-aws/src/main/java/org/springframework/cloud/function/adapter/aws/SpringBootApiGatewayRequestHandler.java +++ b/spring-cloud-function-adapters/spring-cloud-function-adapter-aws/src/main/java/org/springframework/cloud/function/adapter/aws/SpringBootApiGatewayRequestHandler.java @@ -18,6 +18,7 @@ package org.springframework.cloud.function.adapter.aws; import java.util.HashMap; import java.util.Map; +import java.util.Optional; import com.amazonaws.services.lambda.runtime.Context; import com.amazonaws.services.lambda.runtime.events.APIGatewayProxyRequestEvent; @@ -36,6 +37,7 @@ import org.springframework.messaging.support.GenericMessage; * @author Dave Syer * @author Oleg Zhurakousky * @author Semyon Fishman + * @author Markus Gulden */ public class SpringBootApiGatewayRequestHandler extends SpringBootRequestHandler { @@ -56,12 +58,22 @@ public class SpringBootApiGatewayRequestHandler extends @Override protected Object convertEvent(APIGatewayProxyRequestEvent event) { - Object body = deserializeBody(event.getBody()); - if (functionAcceptsMessage()) { - return new GenericMessage<>(body, getHeaders(event)); + + if (event.getBody() != null) { + if (functionAcceptsMessage()) { + return new GenericMessage<>(deserializeBody(event.getBody()), getHeaders(event)); + } + else { + return deserializeBody(event.getBody()); + } } else { - return body; + if (functionAcceptsMessage()) { + return new GenericMessage>(Optional.empty(), getHeaders(event)); + } + else { + return Optional.empty(); + } } } @@ -83,6 +95,13 @@ public class SpringBootApiGatewayRequestHandler extends if (event.getHeaders() != null) { headers.putAll(event.getHeaders()); } + if (event.getQueryStringParameters() != null) { + headers.putAll(event.getQueryStringParameters()); + } + if (event.getPathParameters() != null) { + headers.putAll(event.getPathParameters()); + } + headers.put("httpMethod", event.getHttpMethod()); headers.put("request", event); return new MessageHeaders(headers); } diff --git a/spring-cloud-function-adapters/spring-cloud-function-adapter-aws/src/test/java/org/springframework/cloud/function/adapter/aws/SpringBootApiGatewayRequestHandlerTests.java b/spring-cloud-function-adapters/spring-cloud-function-adapter-aws/src/test/java/org/springframework/cloud/function/adapter/aws/SpringBootApiGatewayRequestHandlerTests.java index 6f606858d..94334afa3 100644 --- a/spring-cloud-function-adapters/spring-cloud-function-adapter-aws/src/test/java/org/springframework/cloud/function/adapter/aws/SpringBootApiGatewayRequestHandlerTests.java +++ b/spring-cloud-function-adapters/spring-cloud-function-adapter-aws/src/test/java/org/springframework/cloud/function/adapter/aws/SpringBootApiGatewayRequestHandlerTests.java @@ -17,6 +17,7 @@ package org.springframework.cloud.function.adapter.aws; import java.util.Collections; +import java.util.HashMap; import java.util.Map; import java.util.function.Consumer; import java.util.function.Function; @@ -37,7 +38,8 @@ import org.springframework.messaging.support.GenericMessage; import static org.assertj.core.api.Assertions.assertThat; /** - * + * @author Dimitry Declercq + * @author Markus Gulden */ public class SpringBootApiGatewayRequestHandlerTests { @@ -102,6 +104,47 @@ public class SpringBootApiGatewayRequestHandlerTests { .isEqualTo("{\"value\":\"FOO\"}"); } + + @Test + public void functionMessageBeanWithRequestParameters() { + this.handler = new SpringBootApiGatewayRequestHandler( + FunctionMessageEchoReqParametersConfig.class); + APIGatewayProxyRequestEvent request = new APIGatewayProxyRequestEvent(); + request.setPathParameters(Collections.singletonMap("path", "pathValue")); + request.setQueryStringParameters(Collections.singletonMap("query", "queryValue")); + request.setHeaders(Collections.singletonMap("test-header", "headerValue")); + request.setHttpMethod("GET"); + + Object output = this.handler.handleRequest(request, null); + assertThat(output).isInstanceOf(APIGatewayProxyResponseEvent.class); + assertThat(((APIGatewayProxyResponseEvent) output).getStatusCode()) + .isEqualTo(200); + assertThat(((APIGatewayProxyResponseEvent) output).getHeaders().get("path")) + .isEqualTo("pathValue"); + assertThat(((APIGatewayProxyResponseEvent) output).getHeaders().get("query")) + .isEqualTo("queryValue"); + assertThat( + ((APIGatewayProxyResponseEvent) output).getHeaders().get("test-header")) + .isEqualTo("headerValue"); + assertThat(((APIGatewayProxyResponseEvent) output).getHeaders().get("httpMethod")) + .isEqualTo("GET"); + assertThat(((APIGatewayProxyResponseEvent) output).getBody()) + .isEqualTo("{\"value\":\"body\"}"); + } + + @Test + public void functionMessageBeanWithEmptyResponse() { + this.handler = new SpringBootApiGatewayRequestHandler( + FunctionMessageConsumerConfig.class); + APIGatewayProxyRequestEvent request = new APIGatewayProxyRequestEvent(); + + Object output = this.handler.handleRequest(request, null); + assertThat(output).isInstanceOf(APIGatewayProxyResponseEvent.class); + assertThat(((APIGatewayProxyResponseEvent) output).getStatusCode()) + .isEqualTo(200); + assertThat(((APIGatewayProxyResponseEvent) output).getBody()).isNull(); + } + @Configuration @Import({ ContextFunctionCatalogAutoConfiguration.class, JacksonAutoConfiguration.class }) @@ -140,6 +183,38 @@ public class SpringBootApiGatewayRequestHandlerTests { } + @Configuration + @Import({ ContextFunctionCatalogAutoConfiguration.class, + JacksonAutoConfiguration.class }) + protected static class FunctionMessageEchoReqParametersConfig { + + @Bean + public Function, Message> function() { + return (message -> { + Map headers = new HashMap<>(); + headers.put("path", message.getHeaders().get("path")); + headers.put("query", message.getHeaders().get("query")); + headers.put("test-header", message.getHeaders().get("test-header")); + headers.put("httpMethod", message.getHeaders().get("httpMethod")); + return new GenericMessage<>(new Bar("body"), headers); + }); + } + + } + + @Configuration + @Import({ ContextFunctionCatalogAutoConfiguration.class, + JacksonAutoConfiguration.class }) + protected static class FunctionMessageConsumerConfig { + + @Bean + public Consumer> function() { + return (foo -> { + }); + } + + } + protected static class Foo { private String value;