From 06d24d4c8d1dda51725c65fce156b63a0d206d30 Mon Sep 17 00:00:00 2001 From: Michael Hamburger Date: Sun, 5 May 2024 19:06:48 +0200 Subject: [PATCH] Fix correct parsing of collections in AmazonLambdaRecorder with CollectionInputReader --- .../deployment/testing/LambdaHandlerET.java | 3 +- .../lambda/deployment/testing/Person.java | 7 ++++ .../deployment/testing/PersonListLambda.java | 15 ++++++++ .../testing/PersonListLambdaTest.java | 38 +++++++++++++++++++ .../lambda/runtime/AmazonLambdaRecorder.java | 6 +++ .../handlers/CollectionInputReader.java | 28 ++++++++++++++ 6 files changed, 95 insertions(+), 2 deletions(-) create mode 100644 extensions/amazon-lambda/deployment/src/test/java/io/quarkus/amazon/lambda/deployment/testing/PersonListLambda.java create mode 100644 extensions/amazon-lambda/deployment/src/test/java/io/quarkus/amazon/lambda/deployment/testing/PersonListLambdaTest.java create mode 100644 extensions/amazon-lambda/runtime/src/main/java/io/quarkus/amazon/lambda/runtime/handlers/CollectionInputReader.java diff --git a/extensions/amazon-lambda/deployment/src/test/java/io/quarkus/amazon/lambda/deployment/testing/LambdaHandlerET.java b/extensions/amazon-lambda/deployment/src/test/java/io/quarkus/amazon/lambda/deployment/testing/LambdaHandlerET.java index 135b02bac0547e..4e3737d92b2ebc 100644 --- a/extensions/amazon-lambda/deployment/src/test/java/io/quarkus/amazon/lambda/deployment/testing/LambdaHandlerET.java +++ b/extensions/amazon-lambda/deployment/src/test/java/io/quarkus/amazon/lambda/deployment/testing/LambdaHandlerET.java @@ -15,8 +15,7 @@ public void testSimpleLambdaSuccess() throws Exception { // you test your lambdas by invoking on http://localhost:8081 // this works in dev mode too - Person in = new Person(); - in.setName("Stu"); + Person in = new Person("Stu"); given() .contentType("application/json") .accept("application/json") diff --git a/extensions/amazon-lambda/deployment/src/test/java/io/quarkus/amazon/lambda/deployment/testing/Person.java b/extensions/amazon-lambda/deployment/src/test/java/io/quarkus/amazon/lambda/deployment/testing/Person.java index d2a4066a77dc29..b419cbce90c8ad 100644 --- a/extensions/amazon-lambda/deployment/src/test/java/io/quarkus/amazon/lambda/deployment/testing/Person.java +++ b/extensions/amazon-lambda/deployment/src/test/java/io/quarkus/amazon/lambda/deployment/testing/Person.java @@ -2,6 +2,13 @@ public class Person { + public Person() { + } + + public Person(String name) { + this.name = name; + } + private String name; public String getName() { diff --git a/extensions/amazon-lambda/deployment/src/test/java/io/quarkus/amazon/lambda/deployment/testing/PersonListLambda.java b/extensions/amazon-lambda/deployment/src/test/java/io/quarkus/amazon/lambda/deployment/testing/PersonListLambda.java new file mode 100644 index 00000000000000..e873d3c600d694 --- /dev/null +++ b/extensions/amazon-lambda/deployment/src/test/java/io/quarkus/amazon/lambda/deployment/testing/PersonListLambda.java @@ -0,0 +1,15 @@ +package io.quarkus.amazon.lambda.deployment.testing; + +import java.util.List; +import java.util.stream.Collectors; + +import com.amazonaws.services.lambda.runtime.Context; +import com.amazonaws.services.lambda.runtime.RequestHandler; + +public class PersonListLambda implements RequestHandler, String> { + + @Override + public String handleRequest(List people, Context context) { + return people.stream().map(Person::getName).collect(Collectors.joining(" ")); + } +} diff --git a/extensions/amazon-lambda/deployment/src/test/java/io/quarkus/amazon/lambda/deployment/testing/PersonListLambdaTest.java b/extensions/amazon-lambda/deployment/src/test/java/io/quarkus/amazon/lambda/deployment/testing/PersonListLambdaTest.java new file mode 100644 index 00000000000000..0e37d6a34ad03e --- /dev/null +++ b/extensions/amazon-lambda/deployment/src/test/java/io/quarkus/amazon/lambda/deployment/testing/PersonListLambdaTest.java @@ -0,0 +1,38 @@ +package io.quarkus.amazon.lambda.deployment.testing; + +import static io.restassured.RestAssured.given; +import static org.hamcrest.CoreMatchers.containsString; + +import java.util.ArrayList; +import java.util.List; + +import org.jboss.shrinkwrap.api.ShrinkWrap; +import org.jboss.shrinkwrap.api.spec.JavaArchive; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.RegisterExtension; + +import io.quarkus.test.QuarkusUnitTest; + +public class PersonListLambdaTest { + + @RegisterExtension + static final QuarkusUnitTest test = new QuarkusUnitTest().setArchiveProducer(() -> ShrinkWrap + .create(JavaArchive.class) + .addClasses(PersonListLambda.class, Person.class)); + + @Test + void testFruitsLambda() throws Exception { + + List personList = new ArrayList<>(); + personList.add(new Person("Chris")); + personList.add(new Person("Fred")); + + given() + .body(personList) + .when() + .post() + .then() + .statusCode(200) + .body(containsString("Chris Fred")); + } +} diff --git a/extensions/amazon-lambda/runtime/src/main/java/io/quarkus/amazon/lambda/runtime/AmazonLambdaRecorder.java b/extensions/amazon-lambda/runtime/src/main/java/io/quarkus/amazon/lambda/runtime/AmazonLambdaRecorder.java index f8fb6d5b765684..49dc6d9d92a2bf 100644 --- a/extensions/amazon-lambda/runtime/src/main/java/io/quarkus/amazon/lambda/runtime/AmazonLambdaRecorder.java +++ b/extensions/amazon-lambda/runtime/src/main/java/io/quarkus/amazon/lambda/runtime/AmazonLambdaRecorder.java @@ -4,6 +4,7 @@ import java.io.InputStream; import java.io.OutputStream; import java.lang.reflect.Method; +import java.util.Collection; import java.util.List; import java.util.Map; import java.util.Set; @@ -16,6 +17,7 @@ import com.amazonaws.services.lambda.runtime.events.S3Event; import com.fasterxml.jackson.databind.ObjectMapper; +import io.quarkus.amazon.lambda.runtime.handlers.CollectionInputReader; import io.quarkus.amazon.lambda.runtime.handlers.S3EventInputReader; import io.quarkus.arc.runtime.BeanContainer; import io.quarkus.runtime.LaunchMode; @@ -53,11 +55,15 @@ static void initializeHandlerClass(Class> handler ObjectMapper objectMapper = AmazonLambdaMapperRecorder.objectMapper; Method handlerMethod = discoverHandlerMethod(handlerClass); Class parameterType = handlerMethod.getParameterTypes()[0]; + if (parameterType.equals(S3Event.class)) { objectReader = new S3EventInputReader(objectMapper); + } else if (Collection.class.isAssignableFrom(parameterType)) { + objectReader = new CollectionInputReader<>(objectMapper, handlerMethod); } else { objectReader = new JacksonInputReader(objectMapper.readerFor(parameterType)); } + objectWriter = new JacksonOutputWriter(objectMapper.writerFor(handlerMethod.getReturnType())); } diff --git a/extensions/amazon-lambda/runtime/src/main/java/io/quarkus/amazon/lambda/runtime/handlers/CollectionInputReader.java b/extensions/amazon-lambda/runtime/src/main/java/io/quarkus/amazon/lambda/runtime/handlers/CollectionInputReader.java new file mode 100644 index 00000000000000..a698bcdbf400f9 --- /dev/null +++ b/extensions/amazon-lambda/runtime/src/main/java/io/quarkus/amazon/lambda/runtime/handlers/CollectionInputReader.java @@ -0,0 +1,28 @@ +package io.quarkus.amazon.lambda.runtime.handlers; + +import java.io.IOException; +import java.io.InputStream; +import java.lang.reflect.Method; +import java.lang.reflect.Type; +import java.util.Collection; + +import com.fasterxml.jackson.databind.JavaType; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.ObjectReader; + +import io.quarkus.amazon.lambda.runtime.LambdaInputReader; + +public class CollectionInputReader implements LambdaInputReader> { + final ObjectReader reader; + + public CollectionInputReader(ObjectMapper mapper, Method handler) { + Type genericParameterType = handler.getGenericParameterTypes()[0]; + JavaType constructParameterType = mapper.getTypeFactory().constructType(genericParameterType); + this.reader = mapper.readerFor(constructParameterType); + } + + @Override + public Collection readValue(InputStream is) throws IOException { + return this.reader.readValue(is); + } +}