From d621f8dab3d1ddecbb9d4726ba5fb9d9c445477c Mon Sep 17 00:00:00 2001 From: Georgios Andrianakis Date: Thu, 29 Apr 2021 16:27:46 +0300 Subject: [PATCH] Fix generic type handling of body parameter in RESTEasy Reactive Fixes: #16905 --- .../jackson/deployment/test/DataItem.java | 14 +++++++++++ .../jackson/deployment/test/Item.java | 23 +++++++++++++++++++ .../deployment/test/SimpleJsonResource.java | 6 +++++ .../deployment/test/SimpleJsonTest.java | 15 ++++++++++++ .../jsonb/deployment/test/DataItem.java | 14 +++++++++++ .../reactive/jsonb/deployment/test/Item.java | 23 +++++++++++++++++++ .../deployment/test/SimpleJsonResource.java | 6 +++++ .../jsonb/deployment/test/SimpleJsonTest.java | 16 ++++++++++++- .../common/processor/EndpointIndexer.java | 6 +++++ .../processor/ResteasyReactiveDotNames.java | 2 ++ .../resteasy/reactive/DummyElementType.java | 7 ++++++ 11 files changed, 131 insertions(+), 1 deletion(-) create mode 100644 extensions/resteasy-reactive/quarkus-resteasy-reactive-jackson/deployment/src/test/java/io/quarkus/resteasy/reactive/jackson/deployment/test/DataItem.java create mode 100644 extensions/resteasy-reactive/quarkus-resteasy-reactive-jackson/deployment/src/test/java/io/quarkus/resteasy/reactive/jackson/deployment/test/Item.java create mode 100644 extensions/resteasy-reactive/quarkus-resteasy-reactive-jsonb/deployment/src/test/java/io/quarkus/resteasy/reactive/jsonb/deployment/test/DataItem.java create mode 100644 extensions/resteasy-reactive/quarkus-resteasy-reactive-jsonb/deployment/src/test/java/io/quarkus/resteasy/reactive/jsonb/deployment/test/Item.java create mode 100644 independent-projects/resteasy-reactive/common/runtime/src/main/java/org/jboss/resteasy/reactive/DummyElementType.java diff --git a/extensions/resteasy-reactive/quarkus-resteasy-reactive-jackson/deployment/src/test/java/io/quarkus/resteasy/reactive/jackson/deployment/test/DataItem.java b/extensions/resteasy-reactive/quarkus-resteasy-reactive-jackson/deployment/src/test/java/io/quarkus/resteasy/reactive/jackson/deployment/test/DataItem.java new file mode 100644 index 0000000000000..83c660300629f --- /dev/null +++ b/extensions/resteasy-reactive/quarkus-resteasy-reactive-jackson/deployment/src/test/java/io/quarkus/resteasy/reactive/jackson/deployment/test/DataItem.java @@ -0,0 +1,14 @@ +package io.quarkus.resteasy.reactive.jackson.deployment.test; + +public class DataItem { + + private T content; + + public T getContent() { + return content; + } + + public void setContent(T content) { + this.content = content; + } +} diff --git a/extensions/resteasy-reactive/quarkus-resteasy-reactive-jackson/deployment/src/test/java/io/quarkus/resteasy/reactive/jackson/deployment/test/Item.java b/extensions/resteasy-reactive/quarkus-resteasy-reactive-jackson/deployment/src/test/java/io/quarkus/resteasy/reactive/jackson/deployment/test/Item.java new file mode 100644 index 0000000000000..1d43c516a9893 --- /dev/null +++ b/extensions/resteasy-reactive/quarkus-resteasy-reactive-jackson/deployment/src/test/java/io/quarkus/resteasy/reactive/jackson/deployment/test/Item.java @@ -0,0 +1,23 @@ +package io.quarkus.resteasy.reactive.jackson.deployment.test; + +public class Item { + + private String name; + private String email; + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getEmail() { + return email; + } + + public void setEmail(String email) { + this.email = email; + } +} diff --git a/extensions/resteasy-reactive/quarkus-resteasy-reactive-jackson/deployment/src/test/java/io/quarkus/resteasy/reactive/jackson/deployment/test/SimpleJsonResource.java b/extensions/resteasy-reactive/quarkus-resteasy-reactive-jackson/deployment/src/test/java/io/quarkus/resteasy/reactive/jackson/deployment/test/SimpleJsonResource.java index 9df7219b1292a..0a03af52e09a4 100644 --- a/extensions/resteasy-reactive/quarkus-resteasy-reactive-jackson/deployment/src/test/java/io/quarkus/resteasy/reactive/jackson/deployment/test/SimpleJsonResource.java +++ b/extensions/resteasy-reactive/quarkus-resteasy-reactive-jackson/deployment/src/test/java/io/quarkus/resteasy/reactive/jackson/deployment/test/SimpleJsonResource.java @@ -235,6 +235,12 @@ public Multi getMulti0() { return Multi.createFrom().empty(); } + @POST + @Path("/genericInput") + public String genericInputTest(DataItem item) { + return item.getContent().getName(); + } + public static class UnquotedFieldsPersonBiFunction implements BiFunction { public static final AtomicInteger count = new AtomicInteger(); diff --git a/extensions/resteasy-reactive/quarkus-resteasy-reactive-jackson/deployment/src/test/java/io/quarkus/resteasy/reactive/jackson/deployment/test/SimpleJsonTest.java b/extensions/resteasy-reactive/quarkus-resteasy-reactive-jackson/deployment/src/test/java/io/quarkus/resteasy/reactive/jackson/deployment/test/SimpleJsonTest.java index 493650f4034f9..83bc00d3b309f 100644 --- a/extensions/resteasy-reactive/quarkus-resteasy-reactive-jackson/deployment/src/test/java/io/quarkus/resteasy/reactive/jackson/deployment/test/SimpleJsonTest.java +++ b/extensions/resteasy-reactive/quarkus-resteasy-reactive-jackson/deployment/src/test/java/io/quarkus/resteasy/reactive/jackson/deployment/test/SimpleJsonTest.java @@ -1,6 +1,7 @@ package io.quarkus.resteasy.reactive.jackson.deployment.test; import static org.hamcrest.Matchers.containsString; +import static org.hamcrest.Matchers.is; import static org.hamcrest.Matchers.not; import static org.hamcrest.Matchers.notNullValue; import static org.hamcrest.Matchers.nullValue; @@ -26,6 +27,7 @@ public class SimpleJsonTest { public JavaArchive get() { return ShrinkWrap.create(JavaArchive.class) .addClasses(Person.class, SimpleJsonResource.class, User.class, Views.class, SuperClass.class, + DataItem.class, Item.class, NoopReaderInterceptor.class); } }); @@ -293,4 +295,17 @@ public void testCustomSerialization() { // a new instance should have been created assertEquals(3, SimpleJsonResource.UnquotedFieldsPersonBiFunction.count.intValue()); } + + @Test + public void testGenericInput() { + RestAssured + .with() + .body("{\"content\": {\"name\":\"foo\", \"email\":\"bar\"}}") + .contentType("application/json; charset=utf-8") + .post("/simple/genericInput") + .then() + .statusCode(200) + .contentType("text/plain") + .body(is("foo")); + } } diff --git a/extensions/resteasy-reactive/quarkus-resteasy-reactive-jsonb/deployment/src/test/java/io/quarkus/resteasy/reactive/jsonb/deployment/test/DataItem.java b/extensions/resteasy-reactive/quarkus-resteasy-reactive-jsonb/deployment/src/test/java/io/quarkus/resteasy/reactive/jsonb/deployment/test/DataItem.java new file mode 100644 index 0000000000000..80710dff681d6 --- /dev/null +++ b/extensions/resteasy-reactive/quarkus-resteasy-reactive-jsonb/deployment/src/test/java/io/quarkus/resteasy/reactive/jsonb/deployment/test/DataItem.java @@ -0,0 +1,14 @@ +package io.quarkus.resteasy.reactive.jsonb.deployment.test; + +public class DataItem { + + private T content; + + public T getContent() { + return content; + } + + public void setContent(T content) { + this.content = content; + } +} diff --git a/extensions/resteasy-reactive/quarkus-resteasy-reactive-jsonb/deployment/src/test/java/io/quarkus/resteasy/reactive/jsonb/deployment/test/Item.java b/extensions/resteasy-reactive/quarkus-resteasy-reactive-jsonb/deployment/src/test/java/io/quarkus/resteasy/reactive/jsonb/deployment/test/Item.java new file mode 100644 index 0000000000000..6e7db280ba19f --- /dev/null +++ b/extensions/resteasy-reactive/quarkus-resteasy-reactive-jsonb/deployment/src/test/java/io/quarkus/resteasy/reactive/jsonb/deployment/test/Item.java @@ -0,0 +1,23 @@ +package io.quarkus.resteasy.reactive.jsonb.deployment.test; + +public class Item { + + private String name; + private String email; + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getEmail() { + return email; + } + + public void setEmail(String email) { + this.email = email; + } +} diff --git a/extensions/resteasy-reactive/quarkus-resteasy-reactive-jsonb/deployment/src/test/java/io/quarkus/resteasy/reactive/jsonb/deployment/test/SimpleJsonResource.java b/extensions/resteasy-reactive/quarkus-resteasy-reactive-jsonb/deployment/src/test/java/io/quarkus/resteasy/reactive/jsonb/deployment/test/SimpleJsonResource.java index 63b61561e6bd8..991dfa0548b73 100644 --- a/extensions/resteasy-reactive/quarkus-resteasy-reactive-jsonb/deployment/src/test/java/io/quarkus/resteasy/reactive/jsonb/deployment/test/SimpleJsonResource.java +++ b/extensions/resteasy-reactive/quarkus-resteasy-reactive-jsonb/deployment/src/test/java/io/quarkus/resteasy/reactive/jsonb/deployment/test/SimpleJsonResource.java @@ -167,4 +167,10 @@ public Multi getMulti2() { public Multi getMulti0() { return Multi.createFrom().empty(); } + + @POST + @Path("/genericInput") + public String genericInputTest(DataItem item) { + return item.getContent().getName(); + } } diff --git a/extensions/resteasy-reactive/quarkus-resteasy-reactive-jsonb/deployment/src/test/java/io/quarkus/resteasy/reactive/jsonb/deployment/test/SimpleJsonTest.java b/extensions/resteasy-reactive/quarkus-resteasy-reactive-jsonb/deployment/src/test/java/io/quarkus/resteasy/reactive/jsonb/deployment/test/SimpleJsonTest.java index 2a2bfc677e052..9337212cb9509 100644 --- a/extensions/resteasy-reactive/quarkus-resteasy-reactive-jsonb/deployment/src/test/java/io/quarkus/resteasy/reactive/jsonb/deployment/test/SimpleJsonTest.java +++ b/extensions/resteasy-reactive/quarkus-resteasy-reactive-jsonb/deployment/src/test/java/io/quarkus/resteasy/reactive/jsonb/deployment/test/SimpleJsonTest.java @@ -1,5 +1,6 @@ package io.quarkus.resteasy.reactive.jsonb.deployment.test; +import static org.hamcrest.Matchers.is; import static org.hamcrest.Matchers.notNullValue; import static org.hamcrest.Matchers.nullValue; @@ -22,7 +23,7 @@ public class SimpleJsonTest { @Override public JavaArchive get() { return ShrinkWrap.create(JavaArchive.class) - .addClasses(Person.class, SimpleJsonResource.class, SuperClass.class); + .addClasses(Person.class, SimpleJsonResource.class, SuperClass.class, DataItem.class, Item.class); } }); @@ -200,4 +201,17 @@ public void testJsonMulti() { .contentType("application/json") .body(Matchers.equalTo("[]")); } + + @Test + public void testGenericInput() { + RestAssured + .with() + .body("{\"content\": {\"name\":\"foo\", \"email\":\"bar\"}}") + .contentType("application/json; charset=utf-8") + .post("/simple/genericInput") + .then() + .statusCode(200) + .contentType("text/plain") + .body(is("foo")); + } } diff --git a/independent-projects/resteasy-reactive/common/processor/src/main/java/org/jboss/resteasy/reactive/common/processor/EndpointIndexer.java b/independent-projects/resteasy-reactive/common/processor/src/main/java/org/jboss/resteasy/reactive/common/processor/EndpointIndexer.java index 2552f813d50bd..523b27228c10a 100644 --- a/independent-projects/resteasy-reactive/common/processor/src/main/java/org/jboss/resteasy/reactive/common/processor/EndpointIndexer.java +++ b/independent-projects/resteasy-reactive/common/processor/src/main/java/org/jboss/resteasy/reactive/common/processor/EndpointIndexer.java @@ -12,6 +12,7 @@ import static org.jboss.resteasy.reactive.common.processor.ResteasyReactiveDotNames.COOKIE_PARAM; import static org.jboss.resteasy.reactive.common.processor.ResteasyReactiveDotNames.DEFAULT_VALUE; import static org.jboss.resteasy.reactive.common.processor.ResteasyReactiveDotNames.DOUBLE; +import static org.jboss.resteasy.reactive.common.processor.ResteasyReactiveDotNames.DUMMY_ELEMENT_TYPE; import static org.jboss.resteasy.reactive.common.processor.ResteasyReactiveDotNames.FLOAT; import static org.jboss.resteasy.reactive.common.processor.ResteasyReactiveDotNames.FORM_PARAM; import static org.jboss.resteasy.reactive.common.processor.ResteasyReactiveDotNames.HEADER_PARAM; @@ -945,6 +946,11 @@ && isContextType(paramType.asClassType())) { builder.setOptional(true); } else if (convertible) { throw new RuntimeException("Invalid parameter type '" + pt + "' used on method " + errorLocation); + } else { + // the "element" type is not of importance as in this case the signature is used at runtime to determine the proper types + elementType = DUMMY_ELEMENT_TYPE.toString(); + addReaderForType(additionalReaders, pt); + typeHandled = true; } } else if ((paramType.name().equals(PATH_SEGMENT)) && (type == ParameterType.PATH)) { elementType = paramType.name().toString(); diff --git a/independent-projects/resteasy-reactive/common/processor/src/main/java/org/jboss/resteasy/reactive/common/processor/ResteasyReactiveDotNames.java b/independent-projects/resteasy-reactive/common/processor/src/main/java/org/jboss/resteasy/reactive/common/processor/ResteasyReactiveDotNames.java index db9d9f3f0f206..b664f4a8c8f53 100644 --- a/independent-projects/resteasy-reactive/common/processor/src/main/java/org/jboss/resteasy/reactive/common/processor/ResteasyReactiveDotNames.java +++ b/independent-projects/resteasy-reactive/common/processor/src/main/java/org/jboss/resteasy/reactive/common/processor/ResteasyReactiveDotNames.java @@ -73,6 +73,7 @@ import javax.ws.rs.sse.Sse; import javax.ws.rs.sse.SseEventSink; import org.jboss.jandex.DotName; +import org.jboss.resteasy.reactive.DummyElementType; import org.jboss.resteasy.reactive.MultipartForm; import org.jboss.resteasy.reactive.RestCookie; import org.jboss.resteasy.reactive.RestForm; @@ -163,6 +164,7 @@ public final class ResteasyReactiveDotNames { public static final DotName SET = DotName.createSimple(Set.class.getName()); public static final DotName SORTED_SET = DotName.createSimple(SortedSet.class.getName()); public static final DotName MAP = DotName.createSimple(Map.class.getName()); + public static final DotName DUMMY_ELEMENT_TYPE = DotName.createSimple(DummyElementType.class.getName()); public static final DotName MULTI_VALUED_MAP = DotName.createSimple(MultivaluedMap.class.getName()); public static final DotName PATH_SEGMENT = DotName.createSimple(PathSegment.class.getName()); public static final DotName LOCAL_DATE = DotName.createSimple(LocalDate.class.getName()); diff --git a/independent-projects/resteasy-reactive/common/runtime/src/main/java/org/jboss/resteasy/reactive/DummyElementType.java b/independent-projects/resteasy-reactive/common/runtime/src/main/java/org/jboss/resteasy/reactive/DummyElementType.java new file mode 100644 index 0000000000000..a89663f017b5d --- /dev/null +++ b/independent-projects/resteasy-reactive/common/runtime/src/main/java/org/jboss/resteasy/reactive/DummyElementType.java @@ -0,0 +1,7 @@ +package org.jboss.resteasy.reactive; + +/** + * Used only to aid with generic types of endpoint parameters + */ +public final class DummyElementType { +}