From ca03e79495fe4e04d3960969e90249e96c067c34 Mon Sep 17 00:00:00 2001 From: Georgios Andrianakis Date: Tue, 3 Jan 2023 08:22:41 +0200 Subject: [PATCH] Register REST Client body parameters for reflection Fixes: #30078 --- .../JaxrsClientReactiveProcessor.java | 22 +++++++++++++++++++ .../client/main/ClientCallingResource.java | 11 ++++++++++ .../it/rest/client/main/HelloClient.java | 22 +++++++++++++++++++ .../io/quarkus/it/rest/client/BasicTest.java | 6 +++++ 4 files changed, 61 insertions(+) diff --git a/extensions/resteasy-reactive/jaxrs-client-reactive/deployment/src/main/java/io/quarkus/jaxrs/client/reactive/deployment/JaxrsClientReactiveProcessor.java b/extensions/resteasy-reactive/jaxrs-client-reactive/deployment/src/main/java/io/quarkus/jaxrs/client/reactive/deployment/JaxrsClientReactiveProcessor.java index 86edc4adff49d..8f79b818fad4a 100644 --- a/extensions/resteasy-reactive/jaxrs-client-reactive/deployment/src/main/java/io/quarkus/jaxrs/client/reactive/deployment/JaxrsClientReactiveProcessor.java +++ b/extensions/resteasy-reactive/jaxrs-client-reactive/deployment/src/main/java/io/quarkus/jaxrs/client/reactive/deployment/JaxrsClientReactiveProcessor.java @@ -314,6 +314,28 @@ public void accept(EndpointIndexer.ResourceMethodCallbackData entry) { QuarkusResteasyReactiveDotNames.IGNORE_METHOD_FOR_REFLECTION_PREDICATE) .source(source) .build()); + + // if there is a body parameter type, register it for reflection + ResourceMethod resourceMethod = entry.getResourceMethod(); + MethodParameter[] methodParameters = resourceMethod.getParameters(); + if (methodParameters != null) { + for (int i = 0; i < methodParameters.length; i++) { + MethodParameter methodParameter = methodParameters[i]; + if (methodParameter.getParameterType() == ParameterType.BODY) { + reflectiveHierarchyBuildItemBuildProducer.produce(new ReflectiveHierarchyBuildItem.Builder() + .type(method.parameterType(i)) + .index(index) + .ignoreTypePredicate( + QuarkusResteasyReactiveDotNames.IGNORE_TYPE_FOR_REFLECTION_PREDICATE) + .ignoreFieldPredicate( + QuarkusResteasyReactiveDotNames.IGNORE_FIELD_FOR_REFLECTION_PREDICATE) + .ignoreMethodPredicate( + QuarkusResteasyReactiveDotNames.IGNORE_METHOD_FOR_REFLECTION_PREDICATE) + .source(source) + .build()); + } + } + } } }) .build(); diff --git a/integration-tests/rest-client-reactive/src/main/java/io/quarkus/it/rest/client/main/ClientCallingResource.java b/integration-tests/rest-client-reactive/src/main/java/io/quarkus/it/rest/client/main/ClientCallingResource.java index 9e88e5bd86c63..9e94a122f1f6b 100644 --- a/integration-tests/rest-client-reactive/src/main/java/io/quarkus/it/rest/client/main/ClientCallingResource.java +++ b/integration-tests/rest-client-reactive/src/main/java/io/quarkus/it/rest/client/main/ClientCallingResource.java @@ -118,6 +118,9 @@ void init(@Observes Router router) { router.post("/hello").handler(rc -> rc.response().putHeader("content-type", MediaType.TEXT_PLAIN) .end("Hello, " + (rc.getBodyAsString()).repeat(getCount(rc)))); + router.post("/hello/fromMessage").handler(rc -> rc.response().putHeader("content-type", MediaType.TEXT_PLAIN) + .end(rc.body().asJsonObject().getString("message"))); + router.route("/call-hello-client").blockingHandler(rc -> { String url = rc.getBody().toString(); HelloClient client = RestClientBuilder.newBuilder().baseUri(URI.create(url)) @@ -126,6 +129,14 @@ void init(@Observes Router router) { rc.response().end(greeting); }); + router.route("/call-helloFromMessage-client").blockingHandler(rc -> { + String url = rc.getBody().toString(); + HelloClient client = RestClientBuilder.newBuilder().baseUri(URI.create(url)) + .build(HelloClient.class); + String greeting = client.fromMessage(new HelloClient.Message("Hello world")); + rc.response().end(greeting); + }); + router.post("/params/param").handler(rc -> rc.response().putHeader("content-type", MediaType.TEXT_PLAIN) .end(getParam(rc))); diff --git a/integration-tests/rest-client-reactive/src/main/java/io/quarkus/it/rest/client/main/HelloClient.java b/integration-tests/rest-client-reactive/src/main/java/io/quarkus/it/rest/client/main/HelloClient.java index bc09e13d357ac..4d9ade9614667 100644 --- a/integration-tests/rest-client-reactive/src/main/java/io/quarkus/it/rest/client/main/HelloClient.java +++ b/integration-tests/rest-client-reactive/src/main/java/io/quarkus/it/rest/client/main/HelloClient.java @@ -9,6 +9,8 @@ import javax.ws.rs.core.MediaType; import javax.ws.rs.core.Response; +import com.fasterxml.jackson.annotation.JsonCreator; + import io.quarkus.rest.client.reactive.ClientExceptionMapper; @Path("") @@ -18,6 +20,12 @@ public interface HelloClient { @Consumes(MediaType.TEXT_PLAIN) String greeting(String name, @QueryParam("count") int count); + @Path("fromMessage") + @POST + @Produces(MediaType.TEXT_PLAIN) + @Consumes(MediaType.APPLICATION_JSON) + String fromMessage(Message message); + // this isn't used, but it makes sure that the generated provider can be properly instantiated in native mode @ClientExceptionMapper static RuntimeException toException(Response response) { @@ -26,4 +34,18 @@ static RuntimeException toException(Response response) { } return null; } + + class Message { + + private final String message; + + @JsonCreator + public Message(String message) { + this.message = message; + } + + public String getMessage() { + return message; + } + } } diff --git a/integration-tests/rest-client-reactive/src/test/java/io/quarkus/it/rest/client/BasicTest.java b/integration-tests/rest-client-reactive/src/test/java/io/quarkus/it/rest/client/BasicTest.java index 937d70633a9fb..bfe4f408ed506 100644 --- a/integration-tests/rest-client-reactive/src/test/java/io/quarkus/it/rest/client/BasicTest.java +++ b/integration-tests/rest-client-reactive/src/test/java/io/quarkus/it/rest/client/BasicTest.java @@ -42,6 +42,12 @@ public void shouldMakeTextRequest() { assertThat(response.asString()).isEqualTo("Hello, JohnJohn"); } + @Test + public void shouldMakeJsonRequestAndGetTextResponse() { + Response response = RestAssured.with().body(helloUrl).post("/call-helloFromMessage-client"); + assertThat(response.asString()).isEqualTo("Hello world"); + } + @Test public void restResponseShouldWorkWithNonSuccessfulResponse() { Response response = RestAssured.with().body(helloUrl).post("/rest-response");