From 9cc6a053f1e7f57c0edeb7eaccab0e9509e17123 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Szynkiewicz?= Date: Fri, 10 Sep 2021 11:17:19 +0200 Subject: [PATCH] Rest Client Reactive: Support PathParam from BeanParam fixes #20027 --- .../JaxrsClientReactiveProcessor.java | 17 ++++- .../reactive/beanparam/BeanPathParamTest.java | 74 +++++++++++++++++++ .../processor/beanparam/BeanParamParser.java | 25 ++++++- .../client/processor/beanparam/ItemType.java | 1 + .../processor/beanparam/PathParamItem.java | 15 ++++ 5 files changed, 127 insertions(+), 5 deletions(-) create mode 100644 extensions/resteasy-reactive/rest-client-reactive/deployment/src/test/java/io/quarkus/rest/client/reactive/beanparam/BeanPathParamTest.java create mode 100644 independent-projects/resteasy-reactive/client/processor/src/main/java/org/jboss/resteasy/reactive/client/processor/beanparam/PathParamItem.java 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 a59142fbb84ad..6ec043a1f8bd3 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 @@ -66,6 +66,7 @@ import org.jboss.resteasy.reactive.client.processor.beanparam.CookieParamItem; import org.jboss.resteasy.reactive.client.processor.beanparam.HeaderParamItem; import org.jboss.resteasy.reactive.client.processor.beanparam.Item; +import org.jboss.resteasy.reactive.client.processor.beanparam.PathParamItem; import org.jboss.resteasy.reactive.client.processor.beanparam.QueryParamItem; import org.jboss.resteasy.reactive.client.processor.scanning.ClientEndpointIndexer; import org.jboss.resteasy.reactive.client.spi.ClientRestHandler; @@ -486,7 +487,7 @@ A more full example of generated client (with sub-resource) can is at the bottom methodIndex++; // finding corresponding jandex method, used by enricher (MicroProfile enricher stores it in a field - // to later fill in context with corresponding java.lang.reflect.Method + // to later fill in context with corresponding java.lang.reflect.Method) String[] javaMethodParameters = new String[method.getParameters().length]; for (int i = 0; i < method.getParameters().length; i++) { MethodParameter param = method.getParameters()[i]; @@ -1636,6 +1637,12 @@ private void addBeanParamData(BytecodeCreator methodCreator, headerParam.getHeaderName(), headerParam.extract(invoEnricher, invoEnricher.getMethodParam(1))); break; + case PATH_PARAM: + PathParamItem pathParam = (PathParamItem) item; + addPathParam(creator, target, + pathParam.getPathParamName(), + pathParam.extract(creator, param)); + break; default: throw new IllegalStateException("Unimplemented"); // TODO form params, etc } @@ -1688,6 +1695,14 @@ private void addHeaderParam(BytecodeCreator invoBuilderEnricher, AssignableResul invocationBuilder, invoBuilderEnricher.load(paramName), headerParamHandle)); } + private void addPathParam(BytecodeCreator methodCreator, AssignableResultHandle methodTarget, + String paramName, ResultHandle pathParamHandle) { + methodCreator.assign(methodTarget, + methodCreator.invokeInterfaceMethod(WEB_TARGET_RESOLVE_TEMPLATE_METHOD, + methodTarget, + methodCreator.load(paramName), pathParamHandle)); + } + private void addCookieParam(BytecodeCreator invoBuilderEnricher, AssignableResultHandle invocationBuilder, String paramName, ResultHandle cookieParamHandle) { invoBuilderEnricher.assign(invocationBuilder, diff --git a/extensions/resteasy-reactive/rest-client-reactive/deployment/src/test/java/io/quarkus/rest/client/reactive/beanparam/BeanPathParamTest.java b/extensions/resteasy-reactive/rest-client-reactive/deployment/src/test/java/io/quarkus/rest/client/reactive/beanparam/BeanPathParamTest.java new file mode 100644 index 0000000000000..1c05c09c7ac23 --- /dev/null +++ b/extensions/resteasy-reactive/rest-client-reactive/deployment/src/test/java/io/quarkus/rest/client/reactive/beanparam/BeanPathParamTest.java @@ -0,0 +1,74 @@ +package io.quarkus.rest.client.reactive.beanparam; + +import static org.assertj.core.api.Assertions.assertThat; + +import java.net.URI; + +import javax.ws.rs.BeanParam; +import javax.ws.rs.GET; +import javax.ws.rs.Path; +import javax.ws.rs.PathParam; + +import org.eclipse.microprofile.rest.client.RestClientBuilder; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.RegisterExtension; + +import io.quarkus.test.QuarkusUnitTest; +import io.quarkus.test.common.http.TestHTTPResource; + +public class BeanPathParamTest { + @RegisterExtension + static final QuarkusUnitTest TEST = new QuarkusUnitTest(); + + @TestHTTPResource + URI baseUri; + + @Test + void shouldPassPathParamFromBeanParam() { + Client client = RestClientBuilder.newBuilder().baseUri(baseUri).build(Client.class); + assertThat(client.getWithBeanParam(new MyBeanParam("123"))).isEqualTo("it works!"); + } + + @Test + void shouldPassPathParamFromBeanParamAndMethod() { + Client client = RestClientBuilder.newBuilder().baseUri(baseUri).build(Client.class); + assertThat(client.getWithBeanParam("foo", new MyBeanParam("123"))).isEqualTo("it works with method too!"); + } + + @Path("/my/{id}/resource") + public interface Client { + @GET + String getWithBeanParam(@BeanParam MyBeanParam beanParam); + + @GET + @Path("/{name}") + String getWithBeanParam(@PathParam("name") String name, @BeanParam MyBeanParam beanParam); + } + + public static class MyBeanParam { + private final String id; + + public MyBeanParam(String id) { + this.id = id; + } + + @PathParam("id") + public String getId() { + return id; + } + } + + @Path("/my/123/resource") + public static class Resource { + @GET + public String get() { + return "it works!"; + } + + @Path("/foo") + @GET + public String getWithLongerPath() { + return "it works with method too!"; + } + } +} diff --git a/independent-projects/resteasy-reactive/client/processor/src/main/java/org/jboss/resteasy/reactive/client/processor/beanparam/BeanParamParser.java b/independent-projects/resteasy-reactive/client/processor/src/main/java/org/jboss/resteasy/reactive/client/processor/beanparam/BeanParamParser.java index 74739e1d61ac8..a6e66a234eb29 100644 --- a/independent-projects/resteasy-reactive/client/processor/src/main/java/org/jboss/resteasy/reactive/client/processor/beanparam/BeanParamParser.java +++ b/independent-projects/resteasy-reactive/client/processor/src/main/java/org/jboss/resteasy/reactive/client/processor/beanparam/BeanParamParser.java @@ -3,6 +3,7 @@ import static org.jboss.resteasy.reactive.common.processor.ResteasyReactiveDotNames.BEAN_PARAM; import static org.jboss.resteasy.reactive.common.processor.ResteasyReactiveDotNames.COOKIE_PARAM; import static org.jboss.resteasy.reactive.common.processor.ResteasyReactiveDotNames.HEADER_PARAM; +import static org.jboss.resteasy.reactive.common.processor.ResteasyReactiveDotNames.PATH_PARAM; import static org.jboss.resteasy.reactive.common.processor.ResteasyReactiveDotNames.QUERY_PARAM; import java.util.ArrayList; @@ -81,15 +82,31 @@ public static List parse(ClassInfo beanParamClass, IndexView index) { List headerParams = annotations.get(HEADER_PARAM); if (headerParams != null) { - for (AnnotationInstance queryParamAnnotation : headerParams) { - AnnotationTarget target = queryParamAnnotation.target(); + for (AnnotationInstance headerParamAnnotation : headerParams) { + AnnotationTarget target = headerParamAnnotation.target(); if (target.kind() == AnnotationTarget.Kind.FIELD) { FieldInfo fieldInfo = target.asField(); - resultList.add(new HeaderParamItem(queryParamAnnotation.value().asString(), + resultList.add(new HeaderParamItem(headerParamAnnotation.value().asString(), new FieldExtractor(null, fieldInfo.name(), fieldInfo.declaringClass().name().toString()))); } else if (target.kind() == AnnotationTarget.Kind.METHOD) { MethodInfo getterMethod = getGetterMethod(beanParamClass, target.asMethod()); - resultList.add(new HeaderParamItem(queryParamAnnotation.value().asString(), + resultList.add(new HeaderParamItem(headerParamAnnotation.value().asString(), + new GetterExtractor(getterMethod))); + } + } + } + + List pathParams = annotations.get(PATH_PARAM); + if (pathParams != null) { + for (AnnotationInstance pathParamAnnotation : pathParams) { + AnnotationTarget target = pathParamAnnotation.target(); + if (target.kind() == AnnotationTarget.Kind.FIELD) { + FieldInfo fieldInfo = target.asField(); + resultList.add(new PathParamItem(pathParamAnnotation.value().asString(), + new FieldExtractor(null, fieldInfo.name(), fieldInfo.declaringClass().name().toString()))); + } else if (target.kind() == AnnotationTarget.Kind.METHOD) { + MethodInfo getterMethod = getGetterMethod(beanParamClass, target.asMethod()); + resultList.add(new PathParamItem(pathParamAnnotation.value().asString(), new GetterExtractor(getterMethod))); } } diff --git a/independent-projects/resteasy-reactive/client/processor/src/main/java/org/jboss/resteasy/reactive/client/processor/beanparam/ItemType.java b/independent-projects/resteasy-reactive/client/processor/src/main/java/org/jboss/resteasy/reactive/client/processor/beanparam/ItemType.java index 747bb0a141cbd..c7c5f1d8891f3 100644 --- a/independent-projects/resteasy-reactive/client/processor/src/main/java/org/jboss/resteasy/reactive/client/processor/beanparam/ItemType.java +++ b/independent-projects/resteasy-reactive/client/processor/src/main/java/org/jboss/resteasy/reactive/client/processor/beanparam/ItemType.java @@ -5,5 +5,6 @@ public enum ItemType { QUERY_PARAM, COOKIE, HEADER_PARAM, + PATH_PARAM, // TODO: more } diff --git a/independent-projects/resteasy-reactive/client/processor/src/main/java/org/jboss/resteasy/reactive/client/processor/beanparam/PathParamItem.java b/independent-projects/resteasy-reactive/client/processor/src/main/java/org/jboss/resteasy/reactive/client/processor/beanparam/PathParamItem.java new file mode 100644 index 0000000000000..c4504962fd246 --- /dev/null +++ b/independent-projects/resteasy-reactive/client/processor/src/main/java/org/jboss/resteasy/reactive/client/processor/beanparam/PathParamItem.java @@ -0,0 +1,15 @@ +package org.jboss.resteasy.reactive.client.processor.beanparam; + +public class PathParamItem extends Item { + + private final String pathParamName; + + public PathParamItem(String pathParamName, ValueExtractor valueExtractor) { + super(ItemType.PATH_PARAM, valueExtractor); + this.pathParamName = pathParamName; + } + + public String getPathParamName() { + return pathParamName; + } +}